Completed
Push — master ( 34bf3a...81db04 )
by Jakub
02:52
created

Generator::setTemplate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Nexendrie\Rss;
5
6
/**
7
 * RSS Channel Generator
8
 *
9
 * @author Jakub Konečný
10
 * @property string $title
11
 * @property string $description
12
 * @property string $link
13
 * @property callable $dataSource
14
 * @property int $shortenDescription
15
 * @property string $dateTimeFormat
16
 * @property callable $lastBuildDate
17
 * @property string $template
18
 * @method void onBeforeGenerate(Generator $generator)
19
 * @method void onAddItem(Generator $generator, \SimpleXMLElement $channel, RssChannelItem $itemDefinition, \SimpleXMLElement $item)
0 ignored issues
show
introduced by
Line exceeds 120 characters; contains 132 characters
Loading history...
20
 * @method void onAfterGenerate(Generator $generator)
21
 */
22 1
final class Generator {
23 1
  use \Nette\SmartObject;
24
  
25
  /** @var string */
26
  protected $title = "";
27
  /** @var string */
28
  protected $description = "";
29
  /** @var string */
30
  protected $link = "";
31
  /** @var string */
32
  protected $dateTimeFormat = "Y-m-d H:i:s";
33
  /** @var callable|null */
34
  protected $dataSource = NULL;
35
  /** @var int */
36
  protected $shortenDescription = 150;
37
  /** @var callable */
38
  protected $lastBuildDate = "time";
39
  /** @var string */
40
  protected $template = __DIR__ . "/template.xml";
41
  /** @var callable[] */
42
  public $onBeforeGenerate = [];
43
  /** @var callable[] */
44
  public $onAddItem = [];
45
  /** @var callable[] */
46
  public $onAfterGenerate = [];
47
  
48
  public function getTitle(): string {
49 1
    return $this->title;
50
  }
51
  
52
  public function setTitle(string $title) {
53 1
    $this->title = $title;
54 1
  }
55
  
56
  public function getDescription(): string {
57 1
    return $this->description;
58
  }
59
  
60
  public function setDescription(string $description) {
61 1
    $this->description = $description;
62 1
  }
63
  
64
  public function getLink(): string {
65 1
    return $this->link;
66
  }
67
  
68
  public function setLink(string $link) {
69 1
    $this->link = $link;
70 1
  }
71
  
72
  public function setDataSource(callable $dataSource) {
73 1
    $this->dataSource = $dataSource;
74 1
  }
75
  
76
  public function getShortenDescription(): int {
77 1
    return $this->shortenDescription;
78
  }
79
  
80
  public function setShortenDescription(int $value) {
81 1
    $this->shortenDescription = $value;
82 1
  }
83
  
84
  public function getDateTimeFormat(): string {
85 1
    return $this->dateTimeFormat;
86
  }
87
  
88
  public function setDateTimeFormat(string $format) {
89 1
    $this->dateTimeFormat = $format;
90 1
  }
91
  
92
  public function getLastBuildDate() {
93 1
    return $this->lastBuildDate;
94
  }
95
  
96
  public function setLastBuildDate(callable $lastBuildDate) {
97 1
    $this->lastBuildDate = $lastBuildDate;
98 1
  }
99
  
100
  public function getTemplate(): string {
101 1
    return $this->template;
102
  }
103
  
104
  /**
105
   * @throws \RuntimeException
106
   */
107
  public function setTemplate(string $template): void {
108 1
    if(!is_file($template)) {
109 1
      throw new \RuntimeException("File $template does not exist.");
110
    }
111 1
    $this->template = $template;
112 1
  }
113
  
114
  /**
115
   * @throws InvalidStateException
116
   * @throws \InvalidArgumentException
117
   */
118
  protected function getData(): Collection {
119 1
    if(is_null($this->dataSource)) {
120 1
      throw new InvalidStateException("Data source for RSS generator is not set.");
121
    }
122 1
    $items = call_user_func($this->dataSource);
123 1
    if(!$items instanceof Collection) {
124 1
      throw new \InvalidArgumentException("Callback for data source for RSS generator has to return " . Collection::class . ".");
0 ignored issues
show
introduced by
Line exceeds 120 characters; contains 129 characters
Loading history...
125
    }
126 1
    return $items;
127
  }
128
  
129
  protected function shortenDescription(string $description): string {
130 1
    if($this->shortenDescription < 1) {
131 1
      return $description;
132
    }
133 1
    $originalDescription = $description;
134 1
    $description = substr($description, 0, $this->shortenDescription);
135 1
    if($description !== $originalDescription) {
136 1
      $description .= "...";
137
    }
138 1
    return $description;
139
  }
140
  
141
  protected function writeProperty(\SimpleXMLElement &$channel, string $property): void {
142 1
    if(isset($this->$property) AND $this->$property !== "") {
143 1
      $channel->channel->{$property}[0][0] = $this->$property;
144
    }
145 1
  }
146
  
147
  /**
148
   * @throws InvalidStateException
149
   * @throws \InvalidArgumentException
150
   */
151
  public function generate(): \SimpleXMLElement {
152 1
    $this->onBeforeGenerate($this);
153 1
    $items = $this->getData();
154 1
    $lastBuildDate = call_user_func($this->lastBuildDate);
155 1
    if(!is_int($lastBuildDate)) {
156 1
      throw new \InvalidArgumentException("Callback for last build date for RSS generator has to return integer.");
157
    }
158 1
    $channel = simplexml_load_file($this->template);
159 1
    $channel->channel->lastBuildDate[0][0] = date($this->dateTimeFormat, $lastBuildDate);
160 1
    $this->writeProperty($channel, "link");
161 1
    $this->writeProperty($channel, "title");
162 1
    $this->writeProperty($channel, "description");
163
    /** @var RssChannelItem $item */
164 1
    foreach($items as $item) {
165
      /** @var \SimpleXMLElement $i */
166 1
      $i = $channel->channel->addChild("item");
167 1
      $i->addChild("title", $item->title);
168 1
      $i->addChild("link", $item->link);
169 1
      $i->addChild("pubDate", $item->pubDate);
170 1
      $i->addChild("description", $this->shortenDescription($item->description));
171 1
      $this->onAddItem($this, $channel, $item, $i);
172
    }
173 1
    $this->onAfterGenerate($this);
174 1
    return $channel;
175
  }
176
  
177
  /**
178
   * @throws InvalidStateException
179
   * @throws \InvalidArgumentException
180
   */
181
  public function response(): RssResponse {
182
    try {
183 1
      return new RssResponse($this->generate());
184 1
    } catch(InvalidStateException | \InvalidArgumentException $e) {
185 1
      throw $e;
186
    }
187
  }
188
}
189
?>