aboutsummaryrefslogtreecommitdiffhomepage
path: root/application/feed
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2020-05-18 13:03:13 +0200
committerArthurHoaro <arthur@hoa.ro>2020-07-23 21:19:21 +0200
commitf4929b1188b4bc5e92b925ebc44f5ad40bb1a4ed (patch)
tree63c83dc7b5e4663f8e976485f0478eb37b0f77b6 /application/feed
parentc56a540c6ef211cd9cb0189ba09911bb77696f28 (diff)
downloadShaarli-f4929b1188b4bc5e92b925ebc44f5ad40bb1a4ed.tar.gz
Shaarli-f4929b1188b4bc5e92b925ebc44f5ad40bb1a4ed.tar.zst
Shaarli-f4929b1188b4bc5e92b925ebc44f5ad40bb1a4ed.zip
Make FeedBuilder instance creation independant of the request stack
Diffstat (limited to 'application/feed')
-rw-r--r--application/feed/FeedBuilder.php139
1 files changed, 66 insertions, 73 deletions
diff --git a/application/feed/FeedBuilder.php b/application/feed/FeedBuilder.php
index 40bd4f15..bcf27c2c 100644
--- a/application/feed/FeedBuilder.php
+++ b/application/feed/FeedBuilder.php
@@ -43,22 +43,10 @@ class FeedBuilder
43 */ 43 */
44 protected $formatter; 44 protected $formatter;
45 45
46 /** 46 /** @var mixed[] $_SERVER */
47 * @var string RSS or ATOM feed.
48 */
49 protected $feedType;
50
51 /**
52 * @var array $_SERVER
53 */
54 protected $serverInfo; 47 protected $serverInfo;
55 48
56 /** 49 /**
57 * @var array $_GET
58 */
59 protected $userInput;
60
61 /**
62 * @var boolean True if the user is currently logged in, false otherwise. 50 * @var boolean True if the user is currently logged in, false otherwise.
63 */ 51 */
64 protected $isLoggedIn; 52 protected $isLoggedIn;
@@ -77,7 +65,6 @@ class FeedBuilder
77 * @var string server locale. 65 * @var string server locale.
78 */ 66 */
79 protected $locale; 67 protected $locale;
80
81 /** 68 /**
82 * @var DateTime Latest item date. 69 * @var DateTime Latest item date.
83 */ 70 */
@@ -88,37 +75,36 @@ class FeedBuilder
88 * 75 *
89 * @param BookmarkServiceInterface $linkDB LinkDB instance. 76 * @param BookmarkServiceInterface $linkDB LinkDB instance.
90 * @param BookmarkFormatter $formatter instance. 77 * @param BookmarkFormatter $formatter instance.
91 * @param string $feedType Type of feed.
92 * @param array $serverInfo $_SERVER. 78 * @param array $serverInfo $_SERVER.
93 * @param array $userInput $_GET.
94 * @param boolean $isLoggedIn True if the user is currently logged in, false otherwise. 79 * @param boolean $isLoggedIn True if the user is currently logged in, false otherwise.
95 */ 80 */
96 public function __construct($linkDB, $formatter, $feedType, $serverInfo, $userInput, $isLoggedIn) 81 public function __construct($linkDB, $formatter, array $serverInfo, $isLoggedIn)
97 { 82 {
98 $this->linkDB = $linkDB; 83 $this->linkDB = $linkDB;
99 $this->formatter = $formatter; 84 $this->formatter = $formatter;
100 $this->feedType = $feedType;
101 $this->serverInfo = $serverInfo; 85 $this->serverInfo = $serverInfo;
102 $this->userInput = $userInput;
103 $this->isLoggedIn = $isLoggedIn; 86 $this->isLoggedIn = $isLoggedIn;
104 } 87 }
105 88
106 /** 89 /**
107 * Build data for feed templates. 90 * Build data for feed templates.
108 * 91 *
92 * @param string $feedType Type of feed (RSS/ATOM).
93 * @param array $userInput $_GET.
94 *
109 * @return array Formatted data for feeds templates. 95 * @return array Formatted data for feeds templates.
110 */ 96 */
111 public function buildData() 97 public function buildData(string $feedType, ?array $userInput)
112 { 98 {
113 // Search for untagged bookmarks 99 // Search for untagged bookmarks
114 if (isset($this->userInput['searchtags']) && empty($this->userInput['searchtags'])) { 100 if (isset($this->userInput['searchtags']) && empty($userInput['searchtags'])) {
115 $this->userInput['searchtags'] = false; 101 $userInput['searchtags'] = false;
116 } 102 }
117 103
118 // Optionally filter the results: 104 // Optionally filter the results:
119 $linksToDisplay = $this->linkDB->search($this->userInput); 105 $linksToDisplay = $this->linkDB->search($userInput);
120 106
121 $nblinksToDisplay = $this->getNbLinks(count($linksToDisplay)); 107 $nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput);
122 108
123 // Can't use array_keys() because $link is a LinkDB instance and not a real array. 109 // Can't use array_keys() because $link is a LinkDB instance and not a real array.
124 $keys = array(); 110 $keys = array();
@@ -130,11 +116,11 @@ class FeedBuilder
130 $this->formatter->addContextData('index_url', $pageaddr); 116 $this->formatter->addContextData('index_url', $pageaddr);
131 $linkDisplayed = array(); 117 $linkDisplayed = array();
132 for ($i = 0; $i < $nblinksToDisplay && $i < count($keys); $i++) { 118 for ($i = 0; $i < $nblinksToDisplay && $i < count($keys); $i++) {
133 $linkDisplayed[$keys[$i]] = $this->buildItem($linksToDisplay[$keys[$i]], $pageaddr); 119 $linkDisplayed[$keys[$i]] = $this->buildItem($feedType, $linksToDisplay[$keys[$i]], $pageaddr);
134 } 120 }
135 121
136 $data['language'] = $this->getTypeLanguage(); 122 $data['language'] = $this->getTypeLanguage($feedType);
137 $data['last_update'] = $this->getLatestDateFormatted(); 123 $data['last_update'] = $this->getLatestDateFormatted($feedType);
138 $data['show_dates'] = !$this->hideDates || $this->isLoggedIn; 124 $data['show_dates'] = !$this->hideDates || $this->isLoggedIn;
139 // Remove leading slash from REQUEST_URI. 125 // Remove leading slash from REQUEST_URI.
140 $data['self_link'] = escape(server_url($this->serverInfo)) 126 $data['self_link'] = escape(server_url($this->serverInfo))
@@ -147,14 +133,45 @@ class FeedBuilder
147 } 133 }
148 134
149 /** 135 /**
136 * Set this to true to use permalinks instead of direct bookmarks.
137 *
138 * @param boolean $usePermalinks true to force permalinks.
139 */
140 public function setUsePermalinks($usePermalinks)
141 {
142 $this->usePermalinks = $usePermalinks;
143 }
144
145 /**
146 * Set this to true to hide timestamps in feeds.
147 *
148 * @param boolean $hideDates true to enable.
149 */
150 public function setHideDates($hideDates)
151 {
152 $this->hideDates = $hideDates;
153 }
154
155 /**
156 * Set the locale. Used to show feed language.
157 *
158 * @param string $locale The locale (eg. 'fr_FR.UTF8').
159 */
160 public function setLocale($locale)
161 {
162 $this->locale = strtolower($locale);
163 }
164
165 /**
150 * Build a feed item (one per shaare). 166 * Build a feed item (one per shaare).
151 * 167 *
168 * @param string $feedType Type of feed (RSS/ATOM).
152 * @param Bookmark $link Single link array extracted from LinkDB. 169 * @param Bookmark $link Single link array extracted from LinkDB.
153 * @param string $pageaddr Index URL. 170 * @param string $pageaddr Index URL.
154 * 171 *
155 * @return array Link array with feed attributes. 172 * @return array Link array with feed attributes.
156 */ 173 */
157 protected function buildItem($link, $pageaddr) 174 protected function buildItem(string $feedType, $link, $pageaddr)
158 { 175 {
159 $data = $this->formatter->format($link); 176 $data = $this->formatter->format($link);
160 $data['guid'] = $pageaddr . '?' . $data['shorturl']; 177 $data['guid'] = $pageaddr . '?' . $data['shorturl'];
@@ -165,13 +182,13 @@ class FeedBuilder
165 } 182 }
166 $data['description'] .= PHP_EOL . PHP_EOL . '<br>&#8212; ' . $permalink; 183 $data['description'] .= PHP_EOL . PHP_EOL . '<br>&#8212; ' . $permalink;
167 184
168 $data['pub_iso_date'] = $this->getIsoDate($data['created']); 185 $data['pub_iso_date'] = $this->getIsoDate($feedType, $data['created']);
169 186
170 // atom:entry elements MUST contain exactly one atom:updated element. 187 // atom:entry elements MUST contain exactly one atom:updated element.
171 if (!empty($link->getUpdated())) { 188 if (!empty($link->getUpdated())) {
172 $data['up_iso_date'] = $this->getIsoDate($data['updated'], DateTime::ATOM); 189 $data['up_iso_date'] = $this->getIsoDate($feedType, $data['updated'], DateTime::ATOM);
173 } else { 190 } else {
174 $data['up_iso_date'] = $this->getIsoDate($data['created'], DateTime::ATOM); 191 $data['up_iso_date'] = $this->getIsoDate($feedType, $data['created'], DateTime::ATOM);
175 } 192 }
176 193
177 // Save the more recent item. 194 // Save the more recent item.
@@ -186,51 +203,23 @@ class FeedBuilder
186 } 203 }
187 204
188 /** 205 /**
189 * Set this to true to use permalinks instead of direct bookmarks.
190 *
191 * @param boolean $usePermalinks true to force permalinks.
192 */
193 public function setUsePermalinks($usePermalinks)
194 {
195 $this->usePermalinks = $usePermalinks;
196 }
197
198 /**
199 * Set this to true to hide timestamps in feeds.
200 *
201 * @param boolean $hideDates true to enable.
202 */
203 public function setHideDates($hideDates)
204 {
205 $this->hideDates = $hideDates;
206 }
207
208 /**
209 * Set the locale. Used to show feed language.
210 *
211 * @param string $locale The locale (eg. 'fr_FR.UTF8').
212 */
213 public function setLocale($locale)
214 {
215 $this->locale = strtolower($locale);
216 }
217
218 /**
219 * Get the language according to the feed type, based on the locale: 206 * Get the language according to the feed type, based on the locale:
220 * 207 *
221 * - RSS format: en-us (default: 'en-en'). 208 * - RSS format: en-us (default: 'en-en').
222 * - ATOM format: fr (default: 'en'). 209 * - ATOM format: fr (default: 'en').
223 * 210 *
211 * @param string $feedType Type of feed (RSS/ATOM).
212 *
224 * @return string The language. 213 * @return string The language.
225 */ 214 */
226 public function getTypeLanguage() 215 protected function getTypeLanguage(string $feedType)
227 { 216 {
228 // Use the locale do define the language, if available. 217 // Use the locale do define the language, if available.
229 if (!empty($this->locale) && preg_match('/^\w{2}[_\-]\w{2}/', $this->locale)) { 218 if (!empty($this->locale) && preg_match('/^\w{2}[_\-]\w{2}/', $this->locale)) {
230 $length = ($this->feedType === self::$FEED_RSS) ? 5 : 2; 219 $length = ($feedType === self::$FEED_RSS) ? 5 : 2;
231 return str_replace('_', '-', substr($this->locale, 0, $length)); 220 return str_replace('_', '-', substr($this->locale, 0, $length));
232 } 221 }
233 return ($this->feedType === self::$FEED_RSS) ? 'en-en' : 'en'; 222 return ($feedType === self::$FEED_RSS) ? 'en-en' : 'en';
234 } 223 }
235 224
236 /** 225 /**
@@ -238,32 +227,35 @@ class FeedBuilder
238 * 227 *
239 * Return an empty string if invalid DateTime is passed. 228 * Return an empty string if invalid DateTime is passed.
240 * 229 *
230 * @param string $feedType Type of feed (RSS/ATOM).
231 *
241 * @return string Formatted date. 232 * @return string Formatted date.
242 */ 233 */
243 protected function getLatestDateFormatted() 234 protected function getLatestDateFormatted(string $feedType)
244 { 235 {
245 if (empty($this->latestDate) || !$this->latestDate instanceof DateTime) { 236 if (empty($this->latestDate) || !$this->latestDate instanceof DateTime) {
246 return ''; 237 return '';
247 } 238 }
248 239
249 $type = ($this->feedType == self::$FEED_RSS) ? DateTime::RSS : DateTime::ATOM; 240 $type = ($feedType == self::$FEED_RSS) ? DateTime::RSS : DateTime::ATOM;
250 return $this->latestDate->format($type); 241 return $this->latestDate->format($type);
251 } 242 }
252 243
253 /** 244 /**
254 * Get ISO date from DateTime according to feed type. 245 * Get ISO date from DateTime according to feed type.
255 * 246 *
247 * @param string $feedType Type of feed (RSS/ATOM).
256 * @param DateTime $date Date to format. 248 * @param DateTime $date Date to format.
257 * @param string|bool $format Force format. 249 * @param string|bool $format Force format.
258 * 250 *
259 * @return string Formatted date. 251 * @return string Formatted date.
260 */ 252 */
261 protected function getIsoDate(DateTime $date, $format = false) 253 protected function getIsoDate(string $feedType, DateTime $date, $format = false)
262 { 254 {
263 if ($format !== false) { 255 if ($format !== false) {
264 return $date->format($format); 256 return $date->format($format);
265 } 257 }
266 if ($this->feedType == self::$FEED_RSS) { 258 if ($feedType == self::$FEED_RSS) {
267 return $date->format(DateTime::RSS); 259 return $date->format(DateTime::RSS);
268 } 260 }
269 return $date->format(DateTime::ATOM); 261 return $date->format(DateTime::ATOM);
@@ -275,21 +267,22 @@ class FeedBuilder
275 * If 'nb' not set or invalid, default value: $DEFAULT_NB_LINKS. 267 * If 'nb' not set or invalid, default value: $DEFAULT_NB_LINKS.
276 * If 'nb' is set to 'all', display all filtered bookmarks (max parameter). 268 * If 'nb' is set to 'all', display all filtered bookmarks (max parameter).
277 * 269 *
278 * @param int $max maximum number of bookmarks to display. 270 * @param int $max maximum number of bookmarks to display.
271 * @param array $userInput $_GET.
279 * 272 *
280 * @return int number of bookmarks to display. 273 * @return int number of bookmarks to display.
281 */ 274 */
282 public function getNbLinks($max) 275 protected function getNbLinks($max, ?array $userInput)
283 { 276 {
284 if (empty($this->userInput['nb'])) { 277 if (empty($userInput['nb'])) {
285 return self::$DEFAULT_NB_LINKS; 278 return self::$DEFAULT_NB_LINKS;
286 } 279 }
287 280
288 if ($this->userInput['nb'] == 'all') { 281 if ($userInput['nb'] == 'all') {
289 return $max; 282 return $max;
290 } 283 }
291 284
292 $intNb = intval($this->userInput['nb']); 285 $intNb = intval($userInput['nb']);
293 if (!is_int($intNb) || $intNb == 0) { 286 if (!is_int($intNb) || $intNb == 0) {
294 return self::$DEFAULT_NB_LINKS; 287 return self::$DEFAULT_NB_LINKS;
295 } 288 }