run:R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
1.86 KB
2026-03-11 16:18:52
R W Run
3.17 KB
2026-03-11 16:18:52
R W Run
3.03 KB
2026-03-11 16:18:52
R W Run
2.41 KB
2026-03-11 16:18:52
R W Run
1.67 KB
2026-03-11 16:18:52
R W Run
2.09 KB
2026-03-11 16:18:52
R W Run
31.39 KB
2026-03-11 16:18:52
R W Run
355 By
2026-03-11 16:18:52
R W Run
18.94 KB
2026-03-11 16:18:52
R W Run
8.31 KB
2026-03-11 16:18:52
R W Run
33.99 KB
2026-03-11 16:18:52
R W Run
128.54 KB
2026-03-11 16:18:52
R W Run
16.31 KB
2026-03-11 16:18:52
R W Run
68.16 KB
2026-03-11 16:18:52
R W Run
34.05 KB
2026-03-11 16:18:52
R W Run
1.75 KB
2026-03-11 16:18:52
R W Run
7.71 KB
2026-03-11 16:18:52
R W Run
447 By
2026-03-11 16:18:52
R W Run
2.31 KB
2026-03-11 16:18:52
R W Run
29.64 KB
2026-03-11 16:18:52
R W Run
125.05 KB
2026-03-11 16:18:52
R W Run
23.18 KB
2026-03-11 16:18:52
R W Run
error_log
📄Item.php
1<?php
2
3// SPDX-FileCopyrightText: 2004-2023 Ryan Parman, Sam Sneddon, Ryan McCue
4// SPDX-License-Identifier: BSD-3-Clause
5
6declare(strict_types=1);
7
8namespace SimplePie;
9
10/**
11 * Manages all item-related data
12 *
13 * Used by {@see \SimplePie\SimplePie::get_item()} and {@see \SimplePie\SimplePie::get_items()}
14 *
15 * This class can be overloaded with {@see \SimplePie\SimplePie::set_item_class()}
16 */
17class Item implements RegistryAware
18{
19 /**
20 * Parent feed
21 *
22 * @access private
23 * @var \SimplePie\SimplePie
24 */
25 public $feed;
26
27 /**
28 * Raw data
29 *
30 * @access private
31 * @var array<string, mixed>
32 */
33 public $data = [];
34
35 /**
36 * Registry object
37 *
38 * @see set_registry
39 * @var \SimplePie\Registry
40 */
41 protected $registry;
42
43 /**
44 * @var Sanitize|null
45 */
46 private $sanitize = null;
47
48 /**
49 * Create a new item object
50 *
51 * This is usually used by {@see \SimplePie\SimplePie::get_items} and
52 * {@see \SimplePie\SimplePie::get_item}. Avoid creating this manually.
53 *
54 * @param \SimplePie\SimplePie $feed Parent feed
55 * @param array<string, mixed> $data Raw data
56 */
57 public function __construct(\SimplePie\SimplePie $feed, array $data)
58 {
59 $this->feed = $feed;
60 $this->data = $data;
61 }
62
63 /**
64 * Set the registry handler
65 *
66 * This is usually used by {@see \SimplePie\Registry::create}
67 *
68 * @since 1.3
69 * @param \SimplePie\Registry $registry
70 * @return void
71 */
72 public function set_registry(\SimplePie\Registry $registry)
73 {
74 $this->registry = $registry;
75 }
76
77 /**
78 * Get a string representation of the item
79 *
80 * @return string
81 */
82 public function __toString()
83 {
84 return md5(serialize($this->data));
85 }
86
87 /**
88 * Remove items that link back to this before destroying this object
89 */
90 public function __destruct()
91 {
92 if (!gc_enabled()) {
93 unset($this->feed);
94 }
95 }
96
97 /**
98 * Get data for an item-level element
99 *
100 * This method allows you to get access to ANY element/attribute that is a
101 * sub-element of the item/entry tag.
102 *
103 * See {@see \SimplePie\SimplePie::get_feed_tags()} for a description of the return value
104 *
105 * @since 1.0
106 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
107 * @param string $namespace The URL of the XML namespace of the elements you're trying to access
108 * @param string $tag Tag name
109 * @return array<array<string, mixed>>|null
110 */
111 public function get_item_tags(string $namespace, string $tag)
112 {
113 if (isset($this->data['child'][$namespace][$tag])) {
114 return $this->data['child'][$namespace][$tag];
115 }
116
117 return null;
118 }
119
120 /**
121 * Get base URL of the item itself.
122 * Returns `<xml:base>` or feed base URL.
123 * Similar to `Item::get_base()` but can safely be used during initialisation methods
124 * such as `Item::get_links()` (`Item::get_base()` and `Item::get_links()` call each-other)
125 * and is not affected by enclosures.
126 *
127 * @param array<string, mixed> $element
128 * @see get_base
129 */
130 private function get_own_base(array $element = []): string
131 {
132 if (!empty($element['xml_base_explicit']) && isset($element['xml_base'])) {
133 return $element['xml_base'];
134 }
135 return $this->feed->get_base();
136 }
137
138 /**
139 * Get the base URL value.
140 * Uses `<xml:base>`, or item link, or enclosure link, or feed base URL.
141 *
142 * @param array<string, mixed> $element
143 * @return string
144 */
145 public function get_base(array $element = [])
146 {
147 if (!empty($element['xml_base_explicit']) && isset($element['xml_base'])) {
148 return $element['xml_base'];
149 }
150 $link = $this->get_permalink();
151 if ($link != null) {
152 return $link;
153 }
154 return $this->feed->get_base($element);
155 }
156
157 /**
158 * Sanitize feed data
159 *
160 * @access private
161 * @see \SimplePie\SimplePie::sanitize()
162 * @param string $data Data to sanitize
163 * @param int-mask-of<SimplePie::CONSTRUCT_*> $type
164 * @param string $base Base URL to resolve URLs against
165 * @return string Sanitized data
166 */
167 public function sanitize(string $data, int $type, string $base = '')
168 {
169 // This really returns string|false but changing encoding is uncommon and we are going to deprecate it, so let’s just lie to PHPStan in the interest of cleaner annotations.
170 return $this->feed->sanitize($data, $type, $base);
171 }
172
173 /**
174 * Get the parent feed
175 *
176 * Note: this may not work as you think for multifeeds!
177 *
178 * @link http://simplepie.org/faq/typical_multifeed_gotchas#missing_data_from_feed
179 * @since 1.0
180 * @return \SimplePie\SimplePie
181 */
182 public function get_feed()
183 {
184 return $this->feed;
185 }
186
187 /**
188 * Get the unique identifier for the item
189 *
190 * This is usually used when writing code to check for new items in a feed.
191 *
192 * Uses `<atom:id>`, `<guid>`, `<dc:identifier>` or the `about` attribute
193 * for RDF. If none of these are supplied (or `$hash` is true), creates an
194 * MD5 hash based on the permalink, title and content.
195 *
196 * @since Beta 2
197 * @param bool $hash Should we force using a hash instead of the supplied ID?
198 * @param string|false $fn User-supplied function to generate an hash
199 * @return string|null
200 */
201 public function get_id(bool $hash = false, $fn = 'md5')
202 {
203 if (!$hash) {
204 if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'id')) {
205 return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
206 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'id')) {
207 return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
208 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'guid')) {
209 return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
210 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'identifier')) {
211 return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
212 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'identifier')) {
213 return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
214 } elseif (isset($this->data['attribs'][\SimplePie\SimplePie::NAMESPACE_RDF]['about'])) {
215 return $this->sanitize($this->data['attribs'][\SimplePie\SimplePie::NAMESPACE_RDF]['about'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
216 }
217 }
218 if ($fn === false) {
219 return null;
220 } elseif (!is_callable($fn)) {
221 trigger_error('User-supplied function $fn must be callable', E_USER_WARNING);
222 $fn = 'md5';
223 }
224 return call_user_func(
225 $fn,
226 $this->get_permalink().$this->get_title().$this->get_content()
227 );
228 }
229
230 /**
231 * Get the title of the item
232 *
233 * Uses `<atom:title>`, `<title>` or `<dc:title>`
234 *
235 * @since Beta 2 (previously called `get_item_title` since 0.8)
236 * @return string|null
237 */
238 public function get_title()
239 {
240 if (!isset($this->data['title'])) {
241 if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'title')) {
242 $this->data['title'] = $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
243 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'title')) {
244 $this->data['title'] = $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
245 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10, 'title')) {
246 $this->data['title'] = $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
247 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_090, 'title')) {
248 $this->data['title'] = $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
249 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'title')) {
250 $this->data['title'] = $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
251 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'title')) {
252 $this->data['title'] = $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
253 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'title')) {
254 $this->data['title'] = $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
255 } else {
256 $this->data['title'] = null;
257 }
258 }
259 return $this->data['title'];
260 }
261
262 /**
263 * Get the content for the item
264 *
265 * Prefers summaries over full content , but will return full content if a
266 * summary does not exist.
267 *
268 * To prefer full content instead, use {@see get_content}
269 *
270 * Uses `<atom:summary>`, `<description>`, `<dc:description>` or
271 * `<itunes:subtitle>`
272 *
273 * @since 0.8
274 * @param bool $description_only Should we avoid falling back to the content?
275 * @return string|null
276 */
277 public function get_description(bool $description_only = false)
278 {
279 if (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'summary')) &&
280 ($return = $this->sanitize($tags[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$tags[0]['attribs']]), $this->get_base($tags[0])))) {
281 return $return;
282 } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'summary')) &&
283 ($return = $this->sanitize($tags[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$tags[0]['attribs']]), $this->get_base($tags[0])))) {
284 return $return;
285 } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10, 'description')) &&
286 ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($tags[0])))) {
287 return $return;
288 } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'description')) &&
289 ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_HTML, $this->get_base($tags[0])))) {
290 return $return;
291 } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'description')) &&
292 ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT))) {
293 return $return;
294 } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'description')) &&
295 ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT))) {
296 return $return;
297 } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'summary')) &&
298 ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_HTML, $this->get_base($tags[0])))) {
299 return $return;
300 } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'subtitle')) &&
301 ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT))) {
302 return $return;
303 } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_090, 'description')) &&
304 ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_HTML))) {
305 return $return;
306 } elseif (!$description_only) {
307 return $this->get_content(true);
308 }
309
310 return null;
311 }
312
313 /**
314 * Get the content for the item
315 *
316 * Prefers full content over summaries, but will return a summary if full
317 * content does not exist.
318 *
319 * To prefer summaries instead, use {@see get_description}
320 *
321 * Uses `<atom:content>` or `<content:encoded>` (RSS 1.0 Content Module)
322 *
323 * @since 1.0
324 * @param bool $content_only Should we avoid falling back to the description?
325 * @return string|null
326 */
327 public function get_content(bool $content_only = false)
328 {
329 if (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'content')) &&
330 ($return = $this->sanitize($tags[0]['data'], $this->registry->call(Misc::class, 'atom_10_content_construct_type', [$tags[0]['attribs']]), $this->get_base($tags[0])))) {
331 return $return;
332 } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'content')) &&
333 ($return = $this->sanitize($tags[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$tags[0]['attribs']]), $this->get_base($tags[0])))) {
334 return $return;
335 } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded')) &&
336 ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_HTML, $this->get_base($tags[0])))) {
337 return $return;
338 } elseif (!$content_only) {
339 return $this->get_description(true);
340 }
341
342 return null;
343 }
344
345 /**
346 * Get the media:thumbnail of the item
347 *
348 * Uses `<media:thumbnail>`
349 *
350 *
351 * @return array{url: string, height?: string, width?: string, time?: string}|null
352 */
353 public function get_thumbnail()
354 {
355 if (!isset($this->data['thumbnail'])) {
356 if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'thumbnail')) {
357 $thumbnail = $return[0]['attribs'][''];
358 if (empty($thumbnail['url'])) {
359 $this->data['thumbnail'] = null;
360 } else {
361 $thumbnail['url'] = $this->sanitize($thumbnail['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($return[0]));
362 $this->data['thumbnail'] = $thumbnail;
363 }
364 } else {
365 $this->data['thumbnail'] = null;
366 }
367 }
368 return $this->data['thumbnail'];
369 }
370
371 /**
372 * Get a category for the item
373 *
374 * @since Beta 3 (previously called `get_categories()` since Beta 2)
375 * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1
376 * @return \SimplePie\Category|null
377 */
378 public function get_category(int $key = 0)
379 {
380 $categories = $this->get_categories();
381 if (isset($categories[$key])) {
382 return $categories[$key];
383 }
384
385 return null;
386 }
387
388 /**
389 * Get all categories for the item
390 *
391 * Uses `<atom:category>`, `<category>` or `<dc:subject>`
392 *
393 * @since Beta 3
394 * @return \SimplePie\Category[]|null List of {@see \SimplePie\Category} objects
395 */
396 public function get_categories()
397 {
398 $categories = [];
399
400 $type = 'category';
401 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, $type) as $category) {
402 $term = null;
403 $scheme = null;
404 $label = null;
405 if (isset($category['attribs']['']['term'])) {
406 $term = $this->sanitize($category['attribs']['']['term'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
407 }
408 if (isset($category['attribs']['']['scheme'])) {
409 $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
410 }
411 if (isset($category['attribs']['']['label'])) {
412 $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
413 }
414 $categories[] = $this->registry->create(Category::class, [$term, $scheme, $label, $type]);
415 }
416 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, $type) as $category) {
417 // This is really the label, but keep this as the term also for BC.
418 // Label will also work on retrieving because that falls back to term.
419 $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
420 if (isset($category['attribs']['']['domain'])) {
421 $scheme = $this->sanitize($category['attribs']['']['domain'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
422 } else {
423 $scheme = null;
424 }
425 $categories[] = $this->registry->create(Category::class, [$term, $scheme, null, $type]);
426 }
427
428 $type = 'subject';
429 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, $type) as $category) {
430 $categories[] = $this->registry->create(Category::class, [$this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null, $type]);
431 }
432 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, $type) as $category) {
433 $categories[] = $this->registry->create(Category::class, [$this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null, $type]);
434 }
435
436 if (!empty($categories)) {
437 return array_unique($categories);
438 }
439
440 return null;
441 }
442
443 /**
444 * Get an author for the item
445 *
446 * @since Beta 2
447 * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1
448 * @return \SimplePie\Author|null
449 */
450 public function get_author(int $key = 0)
451 {
452 $authors = $this->get_authors();
453 if (isset($authors[$key])) {
454 return $authors[$key];
455 }
456
457 return null;
458 }
459
460 /**
461 * Get a contributor for the item
462 *
463 * @since 1.1
464 * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1
465 * @return \SimplePie\Author|null
466 */
467 public function get_contributor(int $key = 0)
468 {
469 $contributors = $this->get_contributors();
470 if (isset($contributors[$key])) {
471 return $contributors[$key];
472 }
473
474 return null;
475 }
476
477 /**
478 * Get all contributors for the item
479 *
480 * Uses `<atom:contributor>`
481 *
482 * @since 1.1
483 * @return \SimplePie\Author[]|null List of {@see \SimplePie\Author} objects
484 */
485 public function get_contributors()
486 {
487 $contributors = [];
488 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'contributor') as $contributor) {
489 $name = null;
490 $uri = null;
491 $email = null;
492 if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'])) {
493 $name = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
494 }
495 if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]['data'])) {
496 $uri = $contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0];
497 $uri = $this->sanitize($uri['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($uri));
498 }
499 if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'])) {
500 $email = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
501 }
502 if ($name !== null || $email !== null || $uri !== null) {
503 $contributors[] = $this->registry->create(Author::class, [$name, $uri, $email]);
504 }
505 }
506 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'contributor') as $contributor) {
507 $name = null;
508 $url = null;
509 $email = null;
510 if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'])) {
511 $name = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
512 }
513 if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]['data'])) {
514 $url = $contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0];
515 $url = $this->sanitize($url['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($url));
516 }
517 if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'])) {
518 $email = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
519 }
520 if ($name !== null || $email !== null || $url !== null) {
521 $contributors[] = $this->registry->create(Author::class, [$name, $url, $email]);
522 }
523 }
524
525 if (!empty($contributors)) {
526 return array_unique($contributors);
527 }
528
529 return null;
530 }
531
532 /**
533 * Get all authors for the item
534 *
535 * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
536 *
537 * @since Beta 2
538 * @return \SimplePie\Author[]|null List of {@see \SimplePie\Author} objects
539 */
540 public function get_authors()
541 {
542 $authors = [];
543 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'author') as $author) {
544 $name = null;
545 $uri = null;
546 $email = null;
547 if (isset($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'])) {
548 $name = $this->sanitize($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
549 }
550 if (isset($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]['data'])) {
551 $uri = $author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0];
552 $uri = $this->sanitize($uri['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($uri));
553 }
554 if (isset($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'])) {
555 $email = $this->sanitize($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
556 }
557 if ($name !== null || $email !== null || $uri !== null) {
558 $authors[] = $this->registry->create(Author::class, [$name, $uri, $email]);
559 }
560 }
561 if ($author = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'author')) {
562 $name = null;
563 $url = null;
564 $email = null;
565 if (isset($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'])) {
566 $name = $this->sanitize($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
567 }
568 if (isset($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]['data'])) {
569 $url = $author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0];
570 $url = $this->sanitize($url['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($url));
571 }
572 if (isset($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'])) {
573 $email = $this->sanitize($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
574 }
575 if ($name !== null || $email !== null || $url !== null) {
576 $authors[] = $this->registry->create(Author::class, [$name, $url, $email]);
577 }
578 }
579 if ($author = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'author')) {
580 $authors[] = $this->registry->create(Author::class, [null, null, $this->sanitize($author[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT)]);
581 }
582 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'creator') as $author) {
583 $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
584 }
585 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'creator') as $author) {
586 $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
587 }
588 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'author') as $author) {
589 $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
590 }
591
592 if (!empty($authors)) {
593 return array_unique($authors);
594 } elseif (($source = $this->get_source()) && ($authors = $source->get_authors())) {
595 return $authors;
596 } elseif ($authors = $this->feed->get_authors()) {
597 return $authors;
598 }
599
600 return null;
601 }
602
603 /**
604 * Get the copyright info for the item
605 *
606 * Uses `<atom:rights>` or `<dc:rights>`
607 *
608 * @since 1.1
609 * @return string|null
610 */
611 public function get_copyright()
612 {
613 if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'rights')) {
614 return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
615 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'rights')) {
616 return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
617 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'rights')) {
618 return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
619 }
620
621 return null;
622 }
623
624 /**
625 * Get the posting date/time for the item
626 *
627 * Uses `<atom:published>`, `<atom:updated>`, `<atom:issued>`,
628 * `<atom:modified>`, `<pubDate>` or `<dc:date>`
629 *
630 * Note: obeys PHP's timezone setting. To get a UTC date/time, use
631 * {@see get_gmdate}
632 *
633 * @since Beta 2 (previously called `get_item_date` since 0.8)
634 *
635 * @param string $date_format Supports any PHP date format from {@see http://php.net/date} (empty for the raw data)
636 * @return ($date_format is 'U' ? ?int : ?string)
637 */
638 public function get_date(string $date_format = 'j F Y, g:i a')
639 {
640 if (!isset($this->data['date'])) {
641 if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'published')) {
642 $this->data['date']['raw'] = $return[0]['data'];
643 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'pubDate')) {
644 $this->data['date']['raw'] = $return[0]['data'];
645 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'date')) {
646 $this->data['date']['raw'] = $return[0]['data'];
647 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'date')) {
648 $this->data['date']['raw'] = $return[0]['data'];
649 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'updated')) {
650 $this->data['date']['raw'] = $return[0]['data'];
651 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'issued')) {
652 $this->data['date']['raw'] = $return[0]['data'];
653 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'created')) {
654 $this->data['date']['raw'] = $return[0]['data'];
655 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'modified')) {
656 $this->data['date']['raw'] = $return[0]['data'];
657 }
658
659 if (!empty($this->data['date']['raw'])) {
660 $parser = $this->registry->call(Parse\Date::class, 'get');
661 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']) ?: null;
662 } else {
663 $this->data['date'] = null;
664 }
665 }
666 if ($this->data['date']) {
667 switch ($date_format) {
668 case '':
669 return $this->sanitize($this->data['date']['raw'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
670
671 case 'U':
672 return $this->data['date']['parsed'];
673
674 default:
675 return date($date_format, $this->data['date']['parsed']);
676 }
677 }
678
679 return null;
680 }
681
682 /**
683 * Get the update date/time for the item
684 *
685 * Uses `<atom:updated>`
686 *
687 * Note: obeys PHP's timezone setting. To get a UTC date/time, use
688 * {@see get_gmdate}
689 *
690 * @param string $date_format Supports any PHP date format from {@see http://php.net/date} (empty for the raw data)
691 * @return ($date_format is 'U' ? ?int : ?string)
692 */
693 public function get_updated_date(string $date_format = 'j F Y, g:i a')
694 {
695 if (!isset($this->data['updated'])) {
696 if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'updated')) {
697 $this->data['updated']['raw'] = $return[0]['data'];
698 }
699
700 if (!empty($this->data['updated']['raw'])) {
701 $parser = $this->registry->call(Parse\Date::class, 'get');
702 $this->data['updated']['parsed'] = $parser->parse($this->data['updated']['raw']) ?: null;
703 } else {
704 $this->data['updated'] = null;
705 }
706 }
707 if ($this->data['updated']) {
708 switch ($date_format) {
709 case '':
710 return $this->sanitize($this->data['updated']['raw'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
711
712 case 'U':
713 return $this->data['updated']['parsed'];
714
715 default:
716 return date($date_format, $this->data['updated']['parsed']);
717 }
718 }
719
720 return null;
721 }
722
723 /**
724 * Get the localized posting date/time for the item
725 *
726 * Returns the date formatted in the localized language. To display in
727 * languages other than the server's default, you need to change the locale
728 * with {@link http://php.net/setlocale setlocale()}. The available
729 * localizations depend on which ones are installed on your web server.
730 *
731 * @since 1.0
732 *
733 * @param string $date_format Supports any PHP date format from {@see http://php.net/strftime} (empty for the raw data)
734 * @return string|null|false see `strftime` for when this can return `false`
735 */
736 public function get_local_date(string $date_format = '%c')
737 {
738 if ($date_format === '') {
739 if (($raw_date = $this->get_date('')) === null) {
740 return null;
741 }
742
743 return $this->sanitize($raw_date, \SimplePie\SimplePie::CONSTRUCT_TEXT);
744 } elseif (($date = $this->get_date('U')) !== null && $date !== false) {
745 return strftime($date_format, $date);
746 }
747
748 return null;
749 }
750
751 /**
752 * Get the posting date/time for the item (UTC time)
753 *
754 * @see get_date
755 * @param string $date_format Supports any PHP date format from {@see http://php.net/date}
756 * @return string|null
757 */
758 public function get_gmdate(string $date_format = 'j F Y, g:i a')
759 {
760 $date = $this->get_date('U');
761 if ($date === null) {
762 return null;
763 }
764
765 return gmdate($date_format, $date);
766 }
767
768 /**
769 * Get the update date/time for the item (UTC time)
770 *
771 * @see get_updated_date
772 * @param string $date_format Supports any PHP date format from {@see http://php.net/date}
773 * @return string|null
774 */
775 public function get_updated_gmdate(string $date_format = 'j F Y, g:i a')
776 {
777 $date = $this->get_updated_date('U');
778 if ($date === null) {
779 return null;
780 }
781
782 return gmdate($date_format, $date);
783 }
784
785 /**
786 * Get the permalink for the item
787 *
788 * Returns the first link available with a relationship of "alternate".
789 * Identical to {@see get_link()} with key 0
790 *
791 * @see get_link
792 * @since 0.8
793 * @return string|null Permalink URL
794 */
795 public function get_permalink()
796 {
797 $link = $this->get_link();
798 $enclosure = $this->get_enclosure(0);
799 if ($link !== null) {
800 return $link;
801 } elseif ($enclosure !== null) {
802 return $enclosure->get_link();
803 }
804
805 return null;
806 }
807
808 /**
809 * Get a single link for the item
810 *
811 * @since Beta 3
812 * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1
813 * @param string $rel The relationship of the link to return
814 * @return string|null Link URL
815 */
816 public function get_link(int $key = 0, string $rel = 'alternate')
817 {
818 $links = $this->get_links($rel);
819 if ($links && $links[$key] !== null) {
820 return $links[$key];
821 }
822
823 return null;
824 }
825
826 /**
827 * Get all links for the item
828 *
829 * Uses `<atom:link>`, `<link>` or `<guid>`
830 *
831 * @since Beta 2
832 * @param string $rel The relationship of links to return
833 * @return array<string>|null Links found for the item (strings)
834 */
835 public function get_links(string $rel = 'alternate')
836 {
837 if (!isset($this->data['links'])) {
838 $this->data['links'] = [];
839 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'link') as $link) {
840 if (isset($link['attribs']['']['href'])) {
841 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
842 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($link));
843 }
844 }
845 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'link') as $link) {
846 if (isset($link['attribs']['']['href'])) {
847 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
848 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($link));
849 }
850 }
851 if ($links = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10, 'link')) {
852 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($links[0]));
853 }
854 if ($links = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_090, 'link')) {
855 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($links[0]));
856 }
857 if ($links = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'link')) {
858 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($links[0]));
859 }
860 if ($links = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'guid')) {
861 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true') {
862 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($links[0]));
863 }
864 }
865
866 $keys = array_keys($this->data['links']);
867 foreach ($keys as $key) {
868 if ($this->registry->call(Misc::class, 'is_isegment_nz_nc', [$key])) {
869 if (isset($this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key])) {
870 $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key]);
871 $this->data['links'][$key] = &$this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key];
872 } else {
873 $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key] = &$this->data['links'][$key];
874 }
875 } elseif (substr((string) $key, 0, 41) === \SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY) {
876 $this->data['links'][substr((string) $key, 41)] = &$this->data['links'][$key];
877 }
878 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
879 }
880 }
881 if (isset($this->data['links'][$rel])) {
882 return $this->data['links'][$rel];
883 }
884
885 return null;
886 }
887
888 /**
889 * Get an enclosure from the item
890 *
891 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
892 *
893 * @since Beta 2
894 * @todo Add ability to prefer one type of content over another (in a media group).
895 * @param int $key The enclosure that you want to return. Remember that arrays begin with 0, not 1
896 * @return \SimplePie\Enclosure|null
897 */
898 public function get_enclosure(int $key = 0)
899 {
900 $enclosures = $this->get_enclosures();
901 if (isset($enclosures[$key])) {
902 return $enclosures[$key];
903 }
904
905 return null;
906 }
907
908 /**
909 * Get all available enclosures (podcasts, etc.)
910 *
911 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
912 *
913 * At this point, we're pretty much assuming that all enclosures for an item
914 * are the same content. Anything else is too complicated to
915 * properly support.
916 *
917 * @since Beta 2
918 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
919 * @todo If an element exists at a level, but its value is empty, we should fall back to the value from the parent (if it exists).
920 * @return \SimplePie\Enclosure[]|null List of \SimplePie\Enclosure items
921 */
922 public function get_enclosures()
923 {
924 if (!isset($this->data['enclosures'])) {
925 $this->data['enclosures'] = [];
926
927 // Elements
928 $captions_parent = null;
929 $categories_parent = null;
930 $copyrights_parent = null;
931 $credits_parent = null;
932 $description_parent = null;
933 $duration_parent = null;
934 $hashes_parent = null;
935 $keywords_parent = null;
936 $player_parent = null;
937 $ratings_parent = null;
938 $restrictions_parent = [];
939 $thumbnails_parent = null;
940 $title_parent = null;
941
942 // Let's do the channel and item-level ones first, and just re-use them if we need to.
943 $parent = $this->get_feed();
944
945 // CAPTIONS
946 if ($captions = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'text')) {
947 foreach ($captions as $caption) {
948 $caption_type = null;
949 $caption_lang = null;
950 $caption_startTime = null;
951 $caption_endTime = null;
952 $caption_text = null;
953 if (isset($caption['attribs']['']['type'])) {
954 $caption_type = $this->sanitize($caption['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
955 }
956 if (isset($caption['attribs']['']['lang'])) {
957 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
958 }
959 if (isset($caption['attribs']['']['start'])) {
960 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
961 }
962 if (isset($caption['attribs']['']['end'])) {
963 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
964 }
965 if (isset($caption['data'])) {
966 $caption_text = $this->sanitize($caption['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
967 }
968 $captions_parent[] = $this->registry->create(Caption::class, [$caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text]);
969 }
970 } elseif ($captions = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'text')) {
971 foreach ($captions as $caption) {
972 $caption_type = null;
973 $caption_lang = null;
974 $caption_startTime = null;
975 $caption_endTime = null;
976 $caption_text = null;
977 if (isset($caption['attribs']['']['type'])) {
978 $caption_type = $this->sanitize($caption['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
979 }
980 if (isset($caption['attribs']['']['lang'])) {
981 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
982 }
983 if (isset($caption['attribs']['']['start'])) {
984 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
985 }
986 if (isset($caption['attribs']['']['end'])) {
987 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
988 }
989 if (isset($caption['data'])) {
990 $caption_text = $this->sanitize($caption['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
991 }
992 $captions_parent[] = $this->registry->create(Caption::class, [$caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text]);
993 }
994 }
995 if (is_array($captions_parent)) {
996 $captions_parent = array_values(array_unique($captions_parent));
997 }
998
999 // CATEGORIES
1000 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'category') as $category) {
1001 $term = null;
1002 $scheme = null;
1003 $label = null;
1004 if (isset($category['data'])) {
1005 $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1006 }
1007 if (isset($category['attribs']['']['scheme'])) {
1008 $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1009 } else {
1010 $scheme = 'http://search.yahoo.com/mrss/category_schema';
1011 }
1012 if (isset($category['attribs']['']['label'])) {
1013 $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1014 }
1015 $categories_parent[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
1016 }
1017 foreach ((array) $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'category') as $category) {
1018 $term = null;
1019 $scheme = null;
1020 $label = null;
1021 if (isset($category['data'])) {
1022 $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1023 }
1024 if (isset($category['attribs']['']['scheme'])) {
1025 $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1026 } else {
1027 $scheme = 'http://search.yahoo.com/mrss/category_schema';
1028 }
1029 if (isset($category['attribs']['']['label'])) {
1030 $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1031 }
1032 $categories_parent[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
1033 }
1034 foreach ((array) $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'category') as $category) {
1035 $term = null;
1036 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
1037 $label = null;
1038 if (isset($category['attribs']['']['text'])) {
1039 $label = $this->sanitize($category['attribs']['']['text'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1040 }
1041 $categories_parent[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
1042
1043 if (isset($category['child'][\SimplePie\SimplePie::NAMESPACE_ITUNES]['category'])) {
1044 foreach ((array) $category['child'][\SimplePie\SimplePie::NAMESPACE_ITUNES]['category'] as $subcategory) {
1045 if (isset($subcategory['attribs']['']['text'])) {
1046 $label = $this->sanitize($subcategory['attribs']['']['text'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1047 }
1048 $categories_parent[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
1049 }
1050 }
1051 }
1052 if (is_array($categories_parent)) {
1053 $categories_parent = array_values(array_unique($categories_parent));
1054 }
1055
1056 // COPYRIGHT
1057 if ($copyright = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'copyright')) {
1058 $copyright_url = null;
1059 $copyright_label = null;
1060 if (isset($copyright[0]['attribs']['']['url'])) {
1061 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1062 }
1063 if (isset($copyright[0]['data'])) {
1064 $copyright_label = $this->sanitize($copyright[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1065 }
1066 $copyrights_parent = $this->registry->create(Copyright::class, [$copyright_url, $copyright_label]);
1067 } elseif ($copyright = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'copyright')) {
1068 $copyright_url = null;
1069 $copyright_label = null;
1070 if (isset($copyright[0]['attribs']['']['url'])) {
1071 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1072 }
1073 if (isset($copyright[0]['data'])) {
1074 $copyright_label = $this->sanitize($copyright[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1075 }
1076 $copyrights_parent = $this->registry->create(Copyright::class, [$copyright_url, $copyright_label]);
1077 }
1078
1079 // CREDITS
1080 if ($credits = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'credit')) {
1081 foreach ($credits as $credit) {
1082 $credit_role = null;
1083 $credit_scheme = null;
1084 $credit_name = null;
1085 if (isset($credit['attribs']['']['role'])) {
1086 $credit_role = $this->sanitize($credit['attribs']['']['role'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1087 }
1088 if (isset($credit['attribs']['']['scheme'])) {
1089 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1090 } else {
1091 $credit_scheme = 'urn:ebu';
1092 }
1093 if (isset($credit['data'])) {
1094 $credit_name = $this->sanitize($credit['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1095 }
1096 $credits_parent[] = $this->registry->create(Credit::class, [$credit_role, $credit_scheme, $credit_name]);
1097 }
1098 } elseif ($credits = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'credit')) {
1099 foreach ($credits as $credit) {
1100 $credit_role = null;
1101 $credit_scheme = null;
1102 $credit_name = null;
1103 if (isset($credit['attribs']['']['role'])) {
1104 $credit_role = $this->sanitize($credit['attribs']['']['role'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1105 }
1106 if (isset($credit['attribs']['']['scheme'])) {
1107 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1108 } else {
1109 $credit_scheme = 'urn:ebu';
1110 }
1111 if (isset($credit['data'])) {
1112 $credit_name = $this->sanitize($credit['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1113 }
1114 $credits_parent[] = $this->registry->create(Credit::class, [$credit_role, $credit_scheme, $credit_name]);
1115 }
1116 }
1117 if (is_array($credits_parent)) {
1118 $credits_parent = array_values(array_unique($credits_parent));
1119 }
1120
1121 // DESCRIPTION
1122 if ($description_parent = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'description')) {
1123 if (isset($description_parent[0]['data'])) {
1124 $description_parent = $this->sanitize($description_parent[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1125 }
1126 } elseif ($description_parent = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'description')) {
1127 if (isset($description_parent[0]['data'])) {
1128 $description_parent = $this->sanitize($description_parent[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1129 }
1130 }
1131
1132 // DURATION
1133 $duration_tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'duration');
1134 if ($duration_tags !== null) {
1135 $seconds = null;
1136 $minutes = null;
1137 $hours = null;
1138 if (isset($duration_tags[0]['data'])) {
1139 $temp = explode(':', $this->sanitize($duration_tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
1140 $seconds = (int) array_pop($temp);
1141 if (count($temp) > 0) {
1142 $minutes = (int) array_pop($temp);
1143 $seconds += $minutes * 60;
1144 }
1145 if (count($temp) > 0) {
1146 $hours = (int) array_pop($temp);
1147 $seconds += $hours * 3600;
1148 }
1149 unset($temp);
1150 $duration_parent = $seconds;
1151 }
1152 }
1153
1154 // HASHES
1155 if ($hashes_iterator = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'hash')) {
1156 foreach ($hashes_iterator as $hash) {
1157 $value = null;
1158 $algo = null;
1159 if (isset($hash['data'])) {
1160 $value = $this->sanitize($hash['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1161 }
1162 if (isset($hash['attribs']['']['algo'])) {
1163 $algo = $this->sanitize($hash['attribs']['']['algo'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1164 } else {
1165 $algo = 'md5';
1166 }
1167 $hashes_parent[] = $algo.':'.$value;
1168 }
1169 } elseif ($hashes_iterator = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'hash')) {
1170 foreach ($hashes_iterator as $hash) {
1171 $value = null;
1172 $algo = null;
1173 if (isset($hash['data'])) {
1174 $value = $this->sanitize($hash['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1175 }
1176 if (isset($hash['attribs']['']['algo'])) {
1177 $algo = $this->sanitize($hash['attribs']['']['algo'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1178 } else {
1179 $algo = 'md5';
1180 }
1181 $hashes_parent[] = $algo.':'.$value;
1182 }
1183 }
1184 if (is_array($hashes_parent)) {
1185 $hashes_parent = array_values(array_unique($hashes_parent));
1186 }
1187
1188 // KEYWORDS
1189 if ($keywords = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'keywords')) {
1190 if (isset($keywords[0]['data'])) {
1191 $temp = explode(',', $this->sanitize($keywords[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
1192 foreach ($temp as $word) {
1193 $keywords_parent[] = trim($word);
1194 }
1195 }
1196 unset($temp);
1197 } elseif ($keywords = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'keywords')) {
1198 if (isset($keywords[0]['data'])) {
1199 $temp = explode(',', $this->sanitize($keywords[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
1200 foreach ($temp as $word) {
1201 $keywords_parent[] = trim($word);
1202 }
1203 }
1204 unset($temp);
1205 } elseif ($keywords = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'keywords')) {
1206 if (isset($keywords[0]['data'])) {
1207 $temp = explode(',', $this->sanitize($keywords[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
1208 foreach ($temp as $word) {
1209 $keywords_parent[] = trim($word);
1210 }
1211 }
1212 unset($temp);
1213 } elseif ($keywords = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'keywords')) {
1214 if (isset($keywords[0]['data'])) {
1215 $temp = explode(',', $this->sanitize($keywords[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
1216 foreach ($temp as $word) {
1217 $keywords_parent[] = trim($word);
1218 }
1219 }
1220 unset($temp);
1221 }
1222 if (is_array($keywords_parent)) {
1223 $keywords_parent = array_values(array_unique($keywords_parent));
1224 }
1225
1226 // PLAYER
1227 if ($player_parent = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'player')) {
1228 if (isset($player_parent[0]['attribs']['']['url'])) {
1229 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($player_parent[0]));
1230 }
1231 } elseif ($player_parent = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'player')) {
1232 if (isset($player_parent[0]['attribs']['']['url'])) {
1233 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($player_parent[0]));
1234 }
1235 }
1236
1237 // RATINGS
1238 if ($ratings = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'rating')) {
1239 foreach ($ratings as $rating) {
1240 $rating_scheme = null;
1241 $rating_value = null;
1242 if (isset($rating['attribs']['']['scheme'])) {
1243 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1244 } else {
1245 $rating_scheme = 'urn:simple';
1246 }
1247 if (isset($rating['data'])) {
1248 $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1249 }
1250 $ratings_parent[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
1251 }
1252 } elseif ($ratings = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'explicit')) {
1253 foreach ($ratings as $rating) {
1254 $rating_scheme = 'urn:itunes';
1255 $rating_value = null;
1256 if (isset($rating['data'])) {
1257 $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1258 }
1259 $ratings_parent[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
1260 }
1261 } elseif ($ratings = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'rating')) {
1262 foreach ($ratings as $rating) {
1263 $rating_scheme = null;
1264 $rating_value = null;
1265 if (isset($rating['attribs']['']['scheme'])) {
1266 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1267 } else {
1268 $rating_scheme = 'urn:simple';
1269 }
1270 if (isset($rating['data'])) {
1271 $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1272 }
1273 $ratings_parent[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
1274 }
1275 } elseif ($ratings = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'explicit')) {
1276 foreach ($ratings as $rating) {
1277 $rating_scheme = 'urn:itunes';
1278 $rating_value = null;
1279 if (isset($rating['data'])) {
1280 $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1281 }
1282 $ratings_parent[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
1283 }
1284 }
1285 if (is_array($ratings_parent)) {
1286 $ratings_parent = array_values(array_unique($ratings_parent));
1287 }
1288
1289 // RESTRICTIONS
1290 if ($restrictions = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'restriction')) {
1291 foreach ($restrictions as $restriction) {
1292 $restriction_relationship = null;
1293 $restriction_type = null;
1294 $restriction_value = null;
1295 if (isset($restriction['attribs']['']['relationship'])) {
1296 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1297 }
1298 if (isset($restriction['attribs']['']['type'])) {
1299 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1300 }
1301 if (isset($restriction['data'])) {
1302 $restriction_value = $this->sanitize($restriction['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1303 }
1304 $restrictions_parent[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
1305 }
1306 } elseif ($restrictions = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'block')) {
1307 foreach ($restrictions as $restriction) {
1308 $restriction_relationship = Restriction::RELATIONSHIP_ALLOW;
1309 $restriction_type = null;
1310 $restriction_value = 'itunes';
1311 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes') {
1312 $restriction_relationship = Restriction::RELATIONSHIP_DENY;
1313 }
1314 $restrictions_parent[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
1315 }
1316 } elseif ($restrictions = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'restriction')) {
1317 foreach ($restrictions as $restriction) {
1318 $restriction_relationship = null;
1319 $restriction_type = null;
1320 $restriction_value = null;
1321 if (isset($restriction['attribs']['']['relationship'])) {
1322 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1323 }
1324 if (isset($restriction['attribs']['']['type'])) {
1325 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1326 }
1327 if (isset($restriction['data'])) {
1328 $restriction_value = $this->sanitize($restriction['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1329 }
1330 $restrictions_parent[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
1331 }
1332 } elseif ($restrictions = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'block')) {
1333 foreach ($restrictions as $restriction) {
1334 $restriction_relationship = Restriction::RELATIONSHIP_ALLOW;
1335 $restriction_type = null;
1336 $restriction_value = 'itunes';
1337 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes') {
1338 $restriction_relationship = Restriction::RELATIONSHIP_DENY;
1339 }
1340 $restrictions_parent[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
1341 }
1342 }
1343 if (count($restrictions_parent) > 0) {
1344 $restrictions_parent = array_values(array_unique($restrictions_parent));
1345 } else {
1346 $restrictions_parent = [new \SimplePie\Restriction(Restriction::RELATIONSHIP_ALLOW, null, 'default')];
1347 }
1348
1349 // THUMBNAILS
1350 if ($thumbnails = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'thumbnail')) {
1351 foreach ($thumbnails as $thumbnail) {
1352 if (isset($thumbnail['attribs']['']['url'])) {
1353 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($thumbnail));
1354 }
1355 }
1356 } elseif ($thumbnails = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'thumbnail')) {
1357 foreach ($thumbnails as $thumbnail) {
1358 if (isset($thumbnail['attribs']['']['url'])) {
1359 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($thumbnail));
1360 }
1361 }
1362 }
1363
1364 // TITLES
1365 if ($title_parent = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'title')) {
1366 if (isset($title_parent[0]['data'])) {
1367 $title_parent = $this->sanitize($title_parent[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1368 }
1369 } elseif ($title_parent = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'title')) {
1370 if (isset($title_parent[0]['data'])) {
1371 $title_parent = $this->sanitize($title_parent[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1372 }
1373 }
1374
1375 // Clear the memory
1376 unset($parent);
1377
1378 // Attributes
1379 $bitrate = null;
1380 $channels = null;
1381 $duration = null;
1382 $expression = null;
1383 $framerate = null;
1384 $height = null;
1385 $javascript = null;
1386 $lang = null;
1387 $length = null;
1388 $medium = null;
1389 $samplingrate = null;
1390 $type = null;
1391 $url = null;
1392 $width = null;
1393
1394 // Elements
1395 $captions = null;
1396 $categories = null;
1397 $copyrights = null;
1398 $credits = null;
1399 $description = null;
1400 $hashes = null;
1401 $keywords = null;
1402 $player = null;
1403 $ratings = null;
1404 $restrictions = null;
1405 $thumbnails = null;
1406 $title = null;
1407
1408 // If we have media:group tags, loop through them.
1409 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'group') as $group) {
1410 if (isset($group['child']) && isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['content'])) {
1411 // If we have media:content tags, loop through them.
1412 foreach ((array) $group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['content'] as $content) {
1413 if (isset($content['attribs']['']['url'])) {
1414 // Attributes
1415 $bitrate = null;
1416 $channels = null;
1417 $duration = null;
1418 $expression = null;
1419 $framerate = null;
1420 $height = null;
1421 $javascript = null;
1422 $lang = null;
1423 $length = null;
1424 $medium = null;
1425 $samplingrate = null;
1426 $type = null;
1427 $url = null;
1428 $width = null;
1429
1430 // Elements
1431 $captions = null;
1432 $categories = null;
1433 $copyrights = null;
1434 $credits = null;
1435 $description = null;
1436 $hashes = null;
1437 $keywords = null;
1438 $player = null;
1439 $ratings = null;
1440 $restrictions = null;
1441 $thumbnails = null;
1442 $title = null;
1443
1444 // Start checking the attributes of media:content
1445 if (isset($content['attribs']['']['bitrate'])) {
1446 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1447 }
1448 if (isset($content['attribs']['']['channels'])) {
1449 $channels = $this->sanitize($content['attribs']['']['channels'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1450 }
1451 if (isset($content['attribs']['']['duration'])) {
1452 $duration = $this->sanitize($content['attribs']['']['duration'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1453 } else {
1454 $duration = $duration_parent;
1455 }
1456 if (isset($content['attribs']['']['expression'])) {
1457 $expression = $this->sanitize($content['attribs']['']['expression'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1458 }
1459 if (isset($content['attribs']['']['framerate'])) {
1460 $framerate = $this->sanitize($content['attribs']['']['framerate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1461 }
1462 if (isset($content['attribs']['']['height'])) {
1463 $height = $this->sanitize($content['attribs']['']['height'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1464 }
1465 if (isset($content['attribs']['']['lang'])) {
1466 $lang = $this->sanitize($content['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1467 }
1468 if (isset($content['attribs']['']['fileSize'])) {
1469 $length = intval($content['attribs']['']['fileSize']);
1470 }
1471 if (isset($content['attribs']['']['medium'])) {
1472 $medium = $this->sanitize($content['attribs']['']['medium'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1473 }
1474 if (isset($content['attribs']['']['samplingrate'])) {
1475 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1476 }
1477 if (isset($content['attribs']['']['type'])) {
1478 $type = $this->sanitize($content['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1479 }
1480 if (isset($content['attribs']['']['width'])) {
1481 $width = $this->sanitize($content['attribs']['']['width'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1482 }
1483 $url = $this->sanitize($content['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($content));
1484
1485 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
1486
1487 // CAPTIONS
1488 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'])) {
1489 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'] as $caption) {
1490 $caption_type = null;
1491 $caption_lang = null;
1492 $caption_startTime = null;
1493 $caption_endTime = null;
1494 $caption_text = null;
1495 if (isset($caption['attribs']['']['type'])) {
1496 $caption_type = $this->sanitize($caption['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1497 }
1498 if (isset($caption['attribs']['']['lang'])) {
1499 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1500 }
1501 if (isset($caption['attribs']['']['start'])) {
1502 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1503 }
1504 if (isset($caption['attribs']['']['end'])) {
1505 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1506 }
1507 if (isset($caption['data'])) {
1508 $caption_text = $this->sanitize($caption['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1509 }
1510 $captions[] = $this->registry->create(Caption::class, [$caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text]);
1511 }
1512 if (is_array($captions)) {
1513 $captions = array_values(array_unique($captions));
1514 }
1515 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'])) {
1516 foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'] as $caption) {
1517 $caption_type = null;
1518 $caption_lang = null;
1519 $caption_startTime = null;
1520 $caption_endTime = null;
1521 $caption_text = null;
1522 if (isset($caption['attribs']['']['type'])) {
1523 $caption_type = $this->sanitize($caption['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1524 }
1525 if (isset($caption['attribs']['']['lang'])) {
1526 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1527 }
1528 if (isset($caption['attribs']['']['start'])) {
1529 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1530 }
1531 if (isset($caption['attribs']['']['end'])) {
1532 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1533 }
1534 if (isset($caption['data'])) {
1535 $caption_text = $this->sanitize($caption['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1536 }
1537 $captions[] = $this->registry->create(Caption::class, [$caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text]);
1538 }
1539 if (is_array($captions)) {
1540 $captions = array_values(array_unique($captions));
1541 }
1542 } else {
1543 $captions = $captions_parent;
1544 }
1545
1546 // CATEGORIES
1547 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'])) {
1548 foreach ((array) $content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'] as $category) {
1549 $term = null;
1550 $scheme = null;
1551 $label = null;
1552 if (isset($category['data'])) {
1553 $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1554 }
1555 if (isset($category['attribs']['']['scheme'])) {
1556 $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1557 } else {
1558 $scheme = 'http://search.yahoo.com/mrss/category_schema';
1559 }
1560 if (isset($category['attribs']['']['label'])) {
1561 $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1562 }
1563 $categories[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
1564 }
1565 }
1566 if (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'])) {
1567 foreach ((array) $group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'] as $category) {
1568 $term = null;
1569 $scheme = null;
1570 $label = null;
1571 if (isset($category['data'])) {
1572 $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1573 }
1574 if (isset($category['attribs']['']['scheme'])) {
1575 $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1576 } else {
1577 $scheme = 'http://search.yahoo.com/mrss/category_schema';
1578 }
1579 if (isset($category['attribs']['']['label'])) {
1580 $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1581 }
1582 $categories[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
1583 }
1584 }
1585 if (is_array($categories) && is_array($categories_parent)) {
1586 $categories = array_values(array_unique(array_merge($categories, $categories_parent)));
1587 } elseif (is_array($categories)) {
1588 $categories = array_values(array_unique($categories));
1589 } elseif (is_array($categories_parent)) {
1590 $categories = array_values(array_unique($categories_parent));
1591 }
1592
1593 // COPYRIGHTS
1594 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'])) {
1595 $copyright_url = null;
1596 $copyright_label = null;
1597 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) {
1598 $copyright_url = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1599 }
1600 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'])) {
1601 $copyright_label = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1602 }
1603 $copyrights = $this->registry->create(Copyright::class, [$copyright_url, $copyright_label]);
1604 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'])) {
1605 $copyright_url = null;
1606 $copyright_label = null;
1607 if (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) {
1608 $copyright_url = $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1609 }
1610 if (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'])) {
1611 $copyright_label = $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1612 }
1613 $copyrights = $this->registry->create(Copyright::class, [$copyright_url, $copyright_label]);
1614 } else {
1615 $copyrights = $copyrights_parent;
1616 }
1617
1618 // CREDITS
1619 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'])) {
1620 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'] as $credit) {
1621 $credit_role = null;
1622 $credit_scheme = null;
1623 $credit_name = null;
1624 if (isset($credit['attribs']['']['role'])) {
1625 $credit_role = $this->sanitize($credit['attribs']['']['role'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1626 }
1627 if (isset($credit['attribs']['']['scheme'])) {
1628 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1629 } else {
1630 $credit_scheme = 'urn:ebu';
1631 }
1632 if (isset($credit['data'])) {
1633 $credit_name = $this->sanitize($credit['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1634 }
1635 $credits[] = $this->registry->create(Credit::class, [$credit_role, $credit_scheme, $credit_name]);
1636 }
1637 if (is_array($credits)) {
1638 $credits = array_values(array_unique($credits));
1639 }
1640 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'])) {
1641 foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'] as $credit) {
1642 $credit_role = null;
1643 $credit_scheme = null;
1644 $credit_name = null;
1645 if (isset($credit['attribs']['']['role'])) {
1646 $credit_role = $this->sanitize($credit['attribs']['']['role'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1647 }
1648 if (isset($credit['attribs']['']['scheme'])) {
1649 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1650 } else {
1651 $credit_scheme = 'urn:ebu';
1652 }
1653 if (isset($credit['data'])) {
1654 $credit_name = $this->sanitize($credit['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1655 }
1656 $credits[] = $this->registry->create(Credit::class, [$credit_role, $credit_scheme, $credit_name]);
1657 }
1658 if (is_array($credits)) {
1659 $credits = array_values(array_unique($credits));
1660 }
1661 } else {
1662 $credits = $credits_parent;
1663 }
1664
1665 // DESCRIPTION
1666 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'])) {
1667 $description = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1668 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'])) {
1669 $description = $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1670 } else {
1671 $description = $description_parent;
1672 }
1673
1674 // HASHES
1675 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'])) {
1676 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'] as $hash) {
1677 $value = null;
1678 $algo = null;
1679 if (isset($hash['data'])) {
1680 $value = $this->sanitize($hash['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1681 }
1682 if (isset($hash['attribs']['']['algo'])) {
1683 $algo = $this->sanitize($hash['attribs']['']['algo'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1684 } else {
1685 $algo = 'md5';
1686 }
1687 $hashes[] = $algo.':'.$value;
1688 }
1689 if (is_array($hashes)) {
1690 $hashes = array_values(array_unique($hashes));
1691 }
1692 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'])) {
1693 foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'] as $hash) {
1694 $value = null;
1695 $algo = null;
1696 if (isset($hash['data'])) {
1697 $value = $this->sanitize($hash['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1698 }
1699 if (isset($hash['attribs']['']['algo'])) {
1700 $algo = $this->sanitize($hash['attribs']['']['algo'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1701 } else {
1702 $algo = 'md5';
1703 }
1704 $hashes[] = $algo.':'.$value;
1705 }
1706 if (is_array($hashes)) {
1707 $hashes = array_values(array_unique($hashes));
1708 }
1709 } else {
1710 $hashes = $hashes_parent;
1711 }
1712
1713 // KEYWORDS
1714 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'])) {
1715 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'])) {
1716 $temp = explode(',', $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
1717 foreach ($temp as $word) {
1718 $keywords[] = trim($word);
1719 }
1720 unset($temp);
1721 }
1722 if (is_array($keywords)) {
1723 $keywords = array_values(array_unique($keywords));
1724 }
1725 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'])) {
1726 if (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'])) {
1727 $temp = explode(',', $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
1728 foreach ($temp as $word) {
1729 $keywords[] = trim($word);
1730 }
1731 unset($temp);
1732 }
1733 if (is_array($keywords)) {
1734 $keywords = array_values(array_unique($keywords));
1735 }
1736 } else {
1737 $keywords = $keywords_parent;
1738 }
1739
1740 // PLAYER
1741 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
1742 $playerElem = $content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0];
1743 $player = $this->sanitize($playerElem['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($playerElem));
1744 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
1745 $playerElem = $group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0];
1746 $player = $this->sanitize($playerElem['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($playerElem));
1747 } else {
1748 $player = $player_parent;
1749 }
1750
1751 // RATINGS
1752 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'])) {
1753 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'] as $rating) {
1754 $rating_scheme = null;
1755 $rating_value = null;
1756 if (isset($rating['attribs']['']['scheme'])) {
1757 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1758 } else {
1759 $rating_scheme = 'urn:simple';
1760 }
1761 if (isset($rating['data'])) {
1762 $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1763 }
1764 $ratings[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
1765 }
1766 if (is_array($ratings)) {
1767 $ratings = array_values(array_unique($ratings));
1768 }
1769 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'])) {
1770 foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'] as $rating) {
1771 $rating_scheme = null;
1772 $rating_value = null;
1773 if (isset($rating['attribs']['']['scheme'])) {
1774 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1775 } else {
1776 $rating_scheme = 'urn:simple';
1777 }
1778 if (isset($rating['data'])) {
1779 $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1780 }
1781 $ratings[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
1782 }
1783 if (is_array($ratings)) {
1784 $ratings = array_values(array_unique($ratings));
1785 }
1786 } else {
1787 $ratings = $ratings_parent;
1788 }
1789
1790 // RESTRICTIONS
1791 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'])) {
1792 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'] as $restriction) {
1793 $restriction_relationship = null;
1794 $restriction_type = null;
1795 $restriction_value = null;
1796 if (isset($restriction['attribs']['']['relationship'])) {
1797 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1798 }
1799 if (isset($restriction['attribs']['']['type'])) {
1800 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1801 }
1802 if (isset($restriction['data'])) {
1803 $restriction_value = $this->sanitize($restriction['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1804 }
1805 $restrictions[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
1806 }
1807 if (is_array($restrictions)) {
1808 $restrictions = array_values(array_unique($restrictions));
1809 }
1810 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'])) {
1811 foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'] as $restriction) {
1812 $restriction_relationship = null;
1813 $restriction_type = null;
1814 $restriction_value = null;
1815 if (isset($restriction['attribs']['']['relationship'])) {
1816 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1817 }
1818 if (isset($restriction['attribs']['']['type'])) {
1819 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1820 }
1821 if (isset($restriction['data'])) {
1822 $restriction_value = $this->sanitize($restriction['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1823 }
1824 $restrictions[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
1825 }
1826 if (is_array($restrictions)) {
1827 $restrictions = array_values(array_unique($restrictions));
1828 }
1829 } else {
1830 $restrictions = $restrictions_parent;
1831 }
1832
1833 // THUMBNAILS
1834 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'])) {
1835 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) {
1836 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($thumbnail));
1837 }
1838 if (is_array($thumbnails)) {
1839 $thumbnails = array_values(array_unique($thumbnails));
1840 }
1841 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'])) {
1842 foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) {
1843 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($thumbnail));
1844 }
1845 if (is_array($thumbnails)) {
1846 $thumbnails = array_values(array_unique($thumbnails));
1847 }
1848 } else {
1849 $thumbnails = $thumbnails_parent;
1850 }
1851
1852 // TITLES
1853 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'])) {
1854 $title = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1855 } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'])) {
1856 $title = $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1857 } else {
1858 $title = $title_parent;
1859 }
1860
1861 $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width]);
1862 }
1863 }
1864 }
1865 }
1866
1867 // If we have standalone media:content tags, loop through them.
1868 if (isset($this->data['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['content'])) {
1869 foreach ((array) $this->data['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['content'] as $content) {
1870 if (isset($content['attribs']['']['url']) || isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
1871 // Attributes
1872 $bitrate = null;
1873 $channels = null;
1874 $duration = null;
1875 $expression = null;
1876 $framerate = null;
1877 $height = null;
1878 $javascript = null;
1879 $lang = null;
1880 $length = null;
1881 $medium = null;
1882 $samplingrate = null;
1883 $type = null;
1884 $url = null;
1885 $width = null;
1886
1887 // Elements
1888 $captions = null;
1889 $categories = null;
1890 $copyrights = null;
1891 $credits = null;
1892 $description = null;
1893 $hashes = null;
1894 $keywords = null;
1895 $player = null;
1896 $ratings = null;
1897 $restrictions = null;
1898 $thumbnails = null;
1899 $title = null;
1900
1901 // Start checking the attributes of media:content
1902 if (isset($content['attribs']['']['bitrate'])) {
1903 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1904 }
1905 if (isset($content['attribs']['']['channels'])) {
1906 $channels = $this->sanitize($content['attribs']['']['channels'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1907 }
1908 if (isset($content['attribs']['']['duration'])) {
1909 $duration = $this->sanitize($content['attribs']['']['duration'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1910 } else {
1911 $duration = $duration_parent;
1912 }
1913 if (isset($content['attribs']['']['expression'])) {
1914 $expression = $this->sanitize($content['attribs']['']['expression'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1915 }
1916 if (isset($content['attribs']['']['framerate'])) {
1917 $framerate = $this->sanitize($content['attribs']['']['framerate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1918 }
1919 if (isset($content['attribs']['']['height'])) {
1920 $height = $this->sanitize($content['attribs']['']['height'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1921 }
1922 if (isset($content['attribs']['']['lang'])) {
1923 $lang = $this->sanitize($content['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1924 }
1925 if (isset($content['attribs']['']['fileSize'])) {
1926 $length = intval($content['attribs']['']['fileSize']);
1927 }
1928 if (isset($content['attribs']['']['medium'])) {
1929 $medium = $this->sanitize($content['attribs']['']['medium'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1930 }
1931 if (isset($content['attribs']['']['samplingrate'])) {
1932 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1933 }
1934 if (isset($content['attribs']['']['type'])) {
1935 $type = $this->sanitize($content['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1936 }
1937 if (isset($content['attribs']['']['width'])) {
1938 $width = $this->sanitize($content['attribs']['']['width'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1939 }
1940 if (isset($content['attribs']['']['url'])) {
1941 $url = $this->sanitize($content['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($content));
1942 }
1943 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
1944
1945 // CAPTIONS
1946 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'])) {
1947 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'] as $caption) {
1948 $caption_type = null;
1949 $caption_lang = null;
1950 $caption_startTime = null;
1951 $caption_endTime = null;
1952 $caption_text = null;
1953 if (isset($caption['attribs']['']['type'])) {
1954 $caption_type = $this->sanitize($caption['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1955 }
1956 if (isset($caption['attribs']['']['lang'])) {
1957 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1958 }
1959 if (isset($caption['attribs']['']['start'])) {
1960 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1961 }
1962 if (isset($caption['attribs']['']['end'])) {
1963 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1964 }
1965 if (isset($caption['data'])) {
1966 $caption_text = $this->sanitize($caption['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1967 }
1968 $captions[] = $this->registry->create(Caption::class, [$caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text]);
1969 }
1970 if (is_array($captions)) {
1971 $captions = array_values(array_unique($captions));
1972 }
1973 } else {
1974 $captions = $captions_parent;
1975 }
1976
1977 // CATEGORIES
1978 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'])) {
1979 foreach ((array) $content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'] as $category) {
1980 $term = null;
1981 $scheme = null;
1982 $label = null;
1983 if (isset($category['data'])) {
1984 $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1985 }
1986 if (isset($category['attribs']['']['scheme'])) {
1987 $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1988 } else {
1989 $scheme = 'http://search.yahoo.com/mrss/category_schema';
1990 }
1991 if (isset($category['attribs']['']['label'])) {
1992 $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
1993 }
1994 $categories[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
1995 }
1996 }
1997 if (is_array($categories) && is_array($categories_parent)) {
1998 $categories = array_values(array_unique(array_merge($categories, $categories_parent)));
1999 } elseif (is_array($categories)) {
2000 $categories = array_values(array_unique($categories));
2001 } elseif (is_array($categories_parent)) {
2002 $categories = array_values(array_unique($categories_parent));
2003 } else {
2004 $categories = null;
2005 }
2006
2007 // COPYRIGHTS
2008 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'])) {
2009 $copyright_url = null;
2010 $copyright_label = null;
2011 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) {
2012 $copyright_url = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2013 }
2014 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'])) {
2015 $copyright_label = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2016 }
2017 $copyrights = $this->registry->create(Copyright::class, [$copyright_url, $copyright_label]);
2018 } else {
2019 $copyrights = $copyrights_parent;
2020 }
2021
2022 // CREDITS
2023 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'])) {
2024 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'] as $credit) {
2025 $credit_role = null;
2026 $credit_scheme = null;
2027 $credit_name = null;
2028 if (isset($credit['attribs']['']['role'])) {
2029 $credit_role = $this->sanitize($credit['attribs']['']['role'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2030 }
2031 if (isset($credit['attribs']['']['scheme'])) {
2032 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2033 } else {
2034 $credit_scheme = 'urn:ebu';
2035 }
2036 if (isset($credit['data'])) {
2037 $credit_name = $this->sanitize($credit['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2038 }
2039 $credits[] = $this->registry->create(Credit::class, [$credit_role, $credit_scheme, $credit_name]);
2040 }
2041 if (is_array($credits)) {
2042 $credits = array_values(array_unique($credits));
2043 }
2044 } else {
2045 $credits = $credits_parent;
2046 }
2047
2048 // DESCRIPTION
2049 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'])) {
2050 $description = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2051 } else {
2052 $description = $description_parent;
2053 }
2054
2055 // HASHES
2056 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'])) {
2057 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'] as $hash) {
2058 $value = null;
2059 $algo = null;
2060 if (isset($hash['data'])) {
2061 $value = $this->sanitize($hash['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2062 }
2063 if (isset($hash['attribs']['']['algo'])) {
2064 $algo = $this->sanitize($hash['attribs']['']['algo'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2065 } else {
2066 $algo = 'md5';
2067 }
2068 $hashes[] = $algo.':'.$value;
2069 }
2070 if (is_array($hashes)) {
2071 $hashes = array_values(array_unique($hashes));
2072 }
2073 } else {
2074 $hashes = $hashes_parent;
2075 }
2076
2077 // KEYWORDS
2078 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'])) {
2079 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'])) {
2080 $temp = explode(',', $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
2081 foreach ($temp as $word) {
2082 $keywords[] = trim($word);
2083 }
2084 unset($temp);
2085 }
2086 if (is_array($keywords)) {
2087 $keywords = array_values(array_unique($keywords));
2088 }
2089 } else {
2090 $keywords = $keywords_parent;
2091 }
2092
2093 // PLAYER
2094 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
2095 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'])) {
2096 $playerElem = $content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0];
2097 $player = $this->sanitize($playerElem['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($playerElem));
2098 }
2099 } else {
2100 $player = $player_parent;
2101 }
2102
2103 // RATINGS
2104 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'])) {
2105 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'] as $rating) {
2106 $rating_scheme = null;
2107 $rating_value = null;
2108 if (isset($rating['attribs']['']['scheme'])) {
2109 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2110 } else {
2111 $rating_scheme = 'urn:simple';
2112 }
2113 if (isset($rating['data'])) {
2114 $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2115 }
2116 $ratings[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
2117 }
2118 if (is_array($ratings)) {
2119 $ratings = array_values(array_unique($ratings));
2120 }
2121 } else {
2122 $ratings = $ratings_parent;
2123 }
2124
2125 // RESTRICTIONS
2126 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'])) {
2127 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'] as $restriction) {
2128 $restriction_relationship = null;
2129 $restriction_type = null;
2130 $restriction_value = null;
2131 if (isset($restriction['attribs']['']['relationship'])) {
2132 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2133 }
2134 if (isset($restriction['attribs']['']['type'])) {
2135 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2136 }
2137 if (isset($restriction['data'])) {
2138 $restriction_value = $this->sanitize($restriction['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2139 }
2140 $restrictions[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
2141 }
2142 if (is_array($restrictions)) {
2143 $restrictions = array_values(array_unique($restrictions));
2144 }
2145 } else {
2146 $restrictions = $restrictions_parent;
2147 }
2148
2149 // THUMBNAILS
2150 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'])) {
2151 foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) {
2152 if (isset($thumbnail['attribs']['']['url'])) {
2153 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($thumbnail));
2154 }
2155 }
2156 if (is_array($thumbnails)) {
2157 $thumbnails = array_values(array_unique($thumbnails));
2158 }
2159 } else {
2160 $thumbnails = $thumbnails_parent;
2161 }
2162
2163 // TITLES
2164 if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'])) {
2165 $title = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2166 } else {
2167 $title = $title_parent;
2168 }
2169
2170 $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width]);
2171 }
2172 }
2173 }
2174
2175 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'link') as $link) {
2176 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure') {
2177 // Attributes
2178 $bitrate = null;
2179 $channels = null;
2180 $duration = null;
2181 $expression = null;
2182 $framerate = null;
2183 $height = null;
2184 $javascript = null;
2185 $lang = null;
2186 $length = null;
2187 $medium = null;
2188 $samplingrate = null;
2189 $type = null;
2190 $url = null;
2191 $width = null;
2192
2193 $url = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($link));
2194 if (isset($link['attribs']['']['type'])) {
2195 $type = $this->sanitize($link['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2196 }
2197 if (isset($link['attribs']['']['length'])) {
2198 $length = intval($link['attribs']['']['length']);
2199 }
2200 if (isset($link['attribs']['']['title'])) {
2201 $title = $this->sanitize($link['attribs']['']['title'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2202 } else {
2203 $title = $title_parent;
2204 }
2205
2206 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
2207 $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title, $width]);
2208 }
2209 }
2210
2211 foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'link') as $link) {
2212 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure') {
2213 // Attributes
2214 $bitrate = null;
2215 $channels = null;
2216 $duration = null;
2217 $expression = null;
2218 $framerate = null;
2219 $height = null;
2220 $javascript = null;
2221 $lang = null;
2222 $length = null;
2223 $medium = null;
2224 $samplingrate = null;
2225 $type = null;
2226 $url = null;
2227 $width = null;
2228
2229 $url = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($link));
2230 if (isset($link['attribs']['']['type'])) {
2231 $type = $this->sanitize($link['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2232 }
2233 if (isset($link['attribs']['']['length'])) {
2234 $length = intval($link['attribs']['']['length']);
2235 }
2236
2237 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
2238 $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width]);
2239 }
2240 }
2241
2242 foreach ($this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'enclosure') ?? [] as $enclosure) {
2243 if (isset($enclosure['attribs']['']['url'])) {
2244 // Attributes
2245 $bitrate = null;
2246 $channels = null;
2247 $duration = null;
2248 $expression = null;
2249 $framerate = null;
2250 $height = null;
2251 $javascript = null;
2252 $lang = null;
2253 $length = null;
2254 $medium = null;
2255 $samplingrate = null;
2256 $type = null;
2257 $url = null;
2258 $width = null;
2259
2260 $url = $this->sanitize($enclosure['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($enclosure));
2261 $url = $this->get_sanitize()->https_url($url);
2262 if (isset($enclosure['attribs']['']['type'])) {
2263 $type = $this->sanitize($enclosure['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
2264 }
2265 if (isset($enclosure['attribs']['']['length'])) {
2266 $length = intval($enclosure['attribs']['']['length']);
2267 }
2268
2269 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
2270 $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width]);
2271 }
2272 }
2273
2274 if (count($this->data['enclosures']) === 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $samplingrate || $thumbnails_parent || $title_parent || $width)) {
2275 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
2276 $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width]);
2277 }
2278
2279 $this->data['enclosures'] = array_values(array_unique($this->data['enclosures']));
2280 }
2281 if (!empty($this->data['enclosures'])) {
2282 return $this->data['enclosures'];
2283 }
2284
2285 return null;
2286 }
2287
2288 /**
2289 * Get the latitude coordinates for the item
2290 *
2291 * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
2292 *
2293 * Uses `<geo:lat>` or `<georss:point>`
2294 *
2295 * @since 1.0
2296 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
2297 * @link http://www.georss.org/ GeoRSS
2298 * @return float|null
2299 */
2300 public function get_latitude()
2301 {
2302 if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_W3C_BASIC_GEO, 'lat')) {
2303 return (float) $return[0]['data'];
2304 } elseif (($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) {
2305 return (float) $match[1];
2306 }
2307
2308 return null;
2309 }
2310
2311 /**
2312 * Get the longitude coordinates for the item
2313 *
2314 * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
2315 *
2316 * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>`
2317 *
2318 * @since 1.0
2319 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
2320 * @link http://www.georss.org/ GeoRSS
2321 * @return float|null
2322 */
2323 public function get_longitude()
2324 {
2325 if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_W3C_BASIC_GEO, 'long')) {
2326 return (float) $return[0]['data'];
2327 } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_W3C_BASIC_GEO, 'lon')) {
2328 return (float) $return[0]['data'];
2329 } elseif (($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) {
2330 return (float) $match[2];
2331 }
2332
2333 return null;
2334 }
2335
2336 /**
2337 * Get the `<atom:source>` for the item
2338 *
2339 * @since 1.1
2340 * @return \SimplePie\Source|null
2341 */
2342 public function get_source()
2343 {
2344 if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'source')) {
2345 return $this->registry->create(Source::class, [$this, $return[0]]);
2346 }
2347
2348 return null;
2349 }
2350
2351 public function set_sanitize(Sanitize $sanitize): void
2352 {
2353 $this->sanitize = $sanitize;
2354 }
2355
2356 protected function get_sanitize(): Sanitize
2357 {
2358 if ($this->sanitize === null) {
2359 $this->sanitize = new Sanitize();
2360 }
2361
2362 return $this->sanitize;
2363 }
2364}
2365
2366class_alias('SimplePie\Item', 'SimplePie_Item');
2367
Ui Ux Design – Teachers Night Out

Get in Touch

© 2024 Teachers Night Out. All Rights Reserved.