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