Passed
Push — master ( 0074a9...40aac8 )
by Jakub
01:56
created

Generator::generate()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 25
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 3

Importance

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