wp/wp-includes/SimplePie/Item.php
changeset 16 a86126ab1dd4
parent 0 d970ebf37754
child 19 3d72ae0968f4
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
     3  * SimplePie
     3  * SimplePie
     4  *
     4  *
     5  * A PHP-Based RSS and Atom Feed Framework.
     5  * A PHP-Based RSS and Atom Feed Framework.
     6  * Takes the hard work out of managing a complete RSS/Atom solution.
     6  * Takes the hard work out of managing a complete RSS/Atom solution.
     7  *
     7  *
     8  * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
     8  * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
     9  * All rights reserved.
     9  * All rights reserved.
    10  *
    10  *
    11  * Redistribution and use in source and binary forms, with or without modification, are
    11  * Redistribution and use in source and binary forms, with or without modification, are
    12  * permitted provided that the following conditions are met:
    12  * permitted provided that the following conditions are met:
    13  *
    13  *
    31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    32  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    32  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    33  * POSSIBILITY OF SUCH DAMAGE.
    33  * POSSIBILITY OF SUCH DAMAGE.
    34  *
    34  *
    35  * @package SimplePie
    35  * @package SimplePie
    36  * @version 1.3.1
    36  * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
    37  * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
       
    38  * @author Ryan Parman
    37  * @author Ryan Parman
    39  * @author Geoffrey Sneddon
    38  * @author Sam Sneddon
    40  * @author Ryan McCue
    39  * @author Ryan McCue
    41  * @link http://simplepie.org/ SimplePie
    40  * @link http://simplepie.org/ SimplePie
    42  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
    41  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
    43  */
    42  */
    44 
    43 
   120 	/**
   119 	/**
   121 	 * Remove items that link back to this before destroying this object
   120 	 * Remove items that link back to this before destroying this object
   122 	 */
   121 	 */
   123 	public function __destruct()
   122 	public function __destruct()
   124 	{
   123 	{
   125 		if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
   124 		if (!gc_enabled())
   126 		{
   125 		{
   127 			unset($this->feed);
   126 			unset($this->feed);
   128 		}
   127 		}
   129 	}
   128 	}
   130 
   129 
   146 	{
   145 	{
   147 		if (isset($this->data['child'][$namespace][$tag]))
   146 		if (isset($this->data['child'][$namespace][$tag]))
   148 		{
   147 		{
   149 			return $this->data['child'][$namespace][$tag];
   148 			return $this->data['child'][$namespace][$tag];
   150 		}
   149 		}
   151 		else
   150 
   152 		{
   151 		return null;
   153 			return null;
       
   154 		}
       
   155 	}
   152 	}
   156 
   153 
   157 	/**
   154 	/**
   158 	 * Get the base URL value from the parent feed
   155 	 * Get the base URL value from the parent feed
   159 	 *
   156 	 *
   201 	 *
   198 	 *
   202 	 * This is usually used when writing code to check for new items in a feed.
   199 	 * This is usually used when writing code to check for new items in a feed.
   203 	 *
   200 	 *
   204 	 * Uses `<atom:id>`, `<guid>`, `<dc:identifier>` or the `about` attribute
   201 	 * Uses `<atom:id>`, `<guid>`, `<dc:identifier>` or the `about` attribute
   205 	 * for RDF. If none of these are supplied (or `$hash` is true), creates an
   202 	 * for RDF. If none of these are supplied (or `$hash` is true), creates an
   206 	 * MD5 hash based on the permalink and title. If either of those are not
   203 	 * MD5 hash based on the permalink, title and content.
   207 	 * supplied, creates a hash based on the full feed data.
       
   208 	 *
   204 	 *
   209 	 * @since Beta 2
   205 	 * @since Beta 2
   210 	 * @param boolean $hash Should we force using a hash instead of the supplied ID?
   206 	 * @param boolean $hash Should we force using a hash instead of the supplied ID?
   211 	 * @return string
   207 	 * @param string|false $fn User-supplied function to generate an hash
   212 	 */
   208 	 * @return string|null
   213 	public function get_id($hash = false)
   209 	 */
       
   210 	public function get_id($hash = false, $fn = 'md5')
   214 	{
   211 	{
   215 		if (!$hash)
   212 		if (!$hash)
   216 		{
   213 		{
   217 			if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
   214 			if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
   218 			{
   215 			{
   236 			}
   233 			}
   237 			elseif (isset($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about']))
   234 			elseif (isset($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about']))
   238 			{
   235 			{
   239 				return $this->sanitize($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about'], SIMPLEPIE_CONSTRUCT_TEXT);
   236 				return $this->sanitize($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about'], SIMPLEPIE_CONSTRUCT_TEXT);
   240 			}
   237 			}
   241 			elseif (($return = $this->get_permalink()) !== null)
   238 		}
   242 			{
   239 		if ($fn === false)
   243 				return $return;
   240 		{
   244 			}
   241 			return null;
   245 			elseif (($return = $this->get_title()) !== null)
   242 		}
   246 			{
   243 		elseif (!is_callable($fn))
   247 				return $return;
   244 		{
   248 			}
   245 			trigger_error('User-supplied function $fn must be callable', E_USER_WARNING);
   249 		}
   246 			$fn = 'md5';
   250 		if ($this->get_permalink() !== null || $this->get_title() !== null)
   247 		}
   251 		{
   248 		return call_user_func($fn,
   252 			return md5($this->get_permalink() . $this->get_title());
   249 		       $this->get_permalink().$this->get_title().$this->get_content());
   253 		}
       
   254 		else
       
   255 		{
       
   256 			return md5(serialize($this->data));
       
   257 		}
       
   258 	}
   250 	}
   259 
   251 
   260 	/**
   252 	/**
   261 	 * Get the title of the item
   253 	 * Get the title of the item
   262 	 *
   254 	 *
   320 	 * @param boolean $description_only Should we avoid falling back to the content?
   312 	 * @param boolean $description_only Should we avoid falling back to the content?
   321 	 * @return string|null
   313 	 * @return string|null
   322 	 */
   314 	 */
   323 	public function get_description($description_only = false)
   315 	public function get_description($description_only = false)
   324 	{
   316 	{
   325 		if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
   317 		if (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary')) &&
   326 		{
   318 		    ($return = $this->sanitize($tags[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($tags[0]['attribs'])), $this->get_base($tags[0]))))
   327 			return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
   319 		{
   328 		}
   320 			return $return;
   329 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
   321 		}
   330 		{
   322 		elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary')) &&
   331 			return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
   323 		        ($return = $this->sanitize($tags[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($tags[0]['attribs'])), $this->get_base($tags[0]))))
   332 		}
   324 		{
   333 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
   325 			return $return;
   334 		{
   326 		}
   335 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
   327 		elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) &&
   336 		}
   328 		        ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($tags[0]))))
   337 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
   329 		{
   338 		{
   330 			return $return;
   339 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
   331 		}
   340 		}
   332 		elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) &&
   341 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
   333 		        ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($tags[0]))))
   342 		{
   334 		{
   343 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
   335 			return $return;
   344 		}
   336 		}
   345 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
   337 		elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) &&
   346 		{
   338 		        ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)))
   347 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
   339 		{
   348 		}
   340 			return $return;
   349 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
   341 		}
   350 		{
   342 		elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) &&
   351 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
   343 		        ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)))
   352 		}
   344 		{
   353 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
   345 			return $return;
   354 		{
   346 		}
   355 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
   347 		elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) &&
   356 		}
   348 		        ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($tags[0]))))
   357 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
   349 		{
   358 		{
   350 			return $return;
   359 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
   351 		}
       
   352 		elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) &&
       
   353 		        ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)))
       
   354 		{
       
   355 			return $return;
       
   356 		}
       
   357 		elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) &&
       
   358 		        ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_HTML)))
       
   359 		{
       
   360 			return $return;
   360 		}
   361 		}
   361 
   362 
   362 		elseif (!$description_only)
   363 		elseif (!$description_only)
   363 		{
   364 		{
   364 			return $this->get_content(true);
   365 			return $this->get_content(true);
   365 		}
   366 		}
   366 		else
   367 
   367 		{
   368 		return null;
   368 			return null;
       
   369 		}
       
   370 	}
   369 	}
   371 
   370 
   372 	/**
   371 	/**
   373 	 * Get the content for the item
   372 	 * Get the content for the item
   374 	 *
   373 	 *
   383 	 * @param boolean $content_only Should we avoid falling back to the description?
   382 	 * @param boolean $content_only Should we avoid falling back to the description?
   384 	 * @return string|null
   383 	 * @return string|null
   385 	 */
   384 	 */
   386 	public function get_content($content_only = false)
   385 	public function get_content($content_only = false)
   387 	{
   386 	{
   388 		if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
   387 		if (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content')) &&
   389 		{
   388 		    ($return = $this->sanitize($tags[0]['data'], $this->registry->call('Misc', 'atom_10_content_construct_type', array($tags[0]['attribs'])), $this->get_base($tags[0]))))
   390 			return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_content_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
   389 		{
   391 		}
   390 			return $return;
   392 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
   391 		}
   393 		{
   392 		elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content')) &&
   394 			return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
   393 		        ($return = $this->sanitize($tags[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($tags[0]['attribs'])), $this->get_base($tags[0]))))
   395 		}
   394 		{
   396 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
   395 			return $return;
   397 		{
   396 		}
   398 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
   397 		elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded')) &&
       
   398 		        ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($tags[0]))))
       
   399 		{
       
   400 			return $return;
   399 		}
   401 		}
   400 		elseif (!$content_only)
   402 		elseif (!$content_only)
   401 		{
   403 		{
   402 			return $this->get_description(true);
   404 			return $this->get_description(true);
   403 		}
   405 		}
   404 		else
   406 
   405 		{
   407 		return null;
   406 			return null;
   408 	}
   407 		}
   409 
       
   410 	/**
       
   411 	 * Get the media:thumbnail of the item
       
   412 	 *
       
   413 	 * Uses `<media:thumbnail>`
       
   414 	 *
       
   415 	 *
       
   416 	 * @return array|null
       
   417 	 */
       
   418 	public function get_thumbnail()
       
   419 	{
       
   420 		if (!isset($this->data['thumbnail']))
       
   421 		{
       
   422 			if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
       
   423 			{
       
   424 				$this->data['thumbnail'] = $return[0]['attribs'][''];
       
   425 			}
       
   426 			else
       
   427 			{
       
   428 				$this->data['thumbnail'] = null;
       
   429 			}
       
   430 		}
       
   431 		return $this->data['thumbnail'];
   408 	}
   432 	}
   409 
   433 
   410 	/**
   434 	/**
   411 	 * Get a category for the item
   435 	 * Get a category for the item
   412 	 *
   436 	 *
   419 		$categories = $this->get_categories();
   443 		$categories = $this->get_categories();
   420 		if (isset($categories[$key]))
   444 		if (isset($categories[$key]))
   421 		{
   445 		{
   422 			return $categories[$key];
   446 			return $categories[$key];
   423 		}
   447 		}
   424 		else
   448 
   425 		{
   449 		return null;
   426 			return null;
       
   427 		}
       
   428 	}
   450 	}
   429 
   451 
   430 	/**
   452 	/**
   431 	 * Get all categories for the item
   453 	 * Get all categories for the item
   432 	 *
   454 	 *
   433 	 * Uses `<atom:category>`, `<category>` or `<dc:subject>`
   455 	 * Uses `<atom:category>`, `<category>` or `<dc:subject>`
   434 	 *
   456 	 *
   435 	 * @since Beta 3
   457 	 * @since Beta 3
   436 	 * @return array|null List of {@see SimplePie_Category} objects
   458 	 * @return SimplePie_Category[]|null List of {@see SimplePie_Category} objects
   437 	 */
   459 	 */
   438 	public function get_categories()
   460 	public function get_categories()
   439 	{
   461 	{
   440 		$categories = array();
   462 		$categories = array();
   441 
   463 
   442 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
   464 		$type = 'category';
       
   465 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, $type) as $category)
   443 		{
   466 		{
   444 			$term = null;
   467 			$term = null;
   445 			$scheme = null;
   468 			$scheme = null;
   446 			$label = null;
   469 			$label = null;
   447 			if (isset($category['attribs']['']['term']))
   470 			if (isset($category['attribs']['']['term']))
   454 			}
   477 			}
   455 			if (isset($category['attribs']['']['label']))
   478 			if (isset($category['attribs']['']['label']))
   456 			{
   479 			{
   457 				$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
   480 				$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
   458 			}
   481 			}
   459 			$categories[] = $this->registry->create('Category', array($term, $scheme, $label));
   482 			$categories[] = $this->registry->create('Category', array($term, $scheme, $label, $type));
   460 		}
   483 		}
   461 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
   484 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, $type) as $category)
   462 		{
   485 		{
   463 			// This is really the label, but keep this as the term also for BC.
   486 			// This is really the label, but keep this as the term also for BC.
   464 			// Label will also work on retrieving because that falls back to term.
   487 			// Label will also work on retrieving because that falls back to term.
   465 			$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
   488 			$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
   466 			if (isset($category['attribs']['']['domain']))
   489 			if (isset($category['attribs']['']['domain']))
   469 			}
   492 			}
   470 			else
   493 			else
   471 			{
   494 			{
   472 				$scheme = null;
   495 				$scheme = null;
   473 			}
   496 			}
   474 			$categories[] = $this->registry->create('Category', array($term, $scheme, null));
   497 			$categories[] = $this->registry->create('Category', array($term, $scheme, null, $type));
   475 		}
   498 		}
   476 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
   499 
   477 		{
   500 		$type = 'subject';
   478 			$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
   501 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, $type) as $category)
   479 		}
   502 		{
   480 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
   503 			$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null, $type));
   481 		{
   504 		}
   482 			$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
   505 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, $type) as $category)
       
   506 		{
       
   507 			$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null, $type));
   483 		}
   508 		}
   484 
   509 
   485 		if (!empty($categories))
   510 		if (!empty($categories))
   486 		{
   511 		{
   487 			return array_unique($categories);
   512 			return array_unique($categories);
   488 		}
   513 		}
   489 		else
   514 
   490 		{
   515 		return null;
   491 			return null;
       
   492 		}
       
   493 	}
   516 	}
   494 
   517 
   495 	/**
   518 	/**
   496 	 * Get an author for the item
   519 	 * Get an author for the item
   497 	 *
   520 	 *
   504 		$authors = $this->get_authors();
   527 		$authors = $this->get_authors();
   505 		if (isset($authors[$key]))
   528 		if (isset($authors[$key]))
   506 		{
   529 		{
   507 			return $authors[$key];
   530 			return $authors[$key];
   508 		}
   531 		}
   509 		else
   532 
   510 		{
   533 		return null;
   511 			return null;
       
   512 		}
       
   513 	}
   534 	}
   514 
   535 
   515 	/**
   536 	/**
   516 	 * Get a contributor for the item
   537 	 * Get a contributor for the item
   517 	 *
   538 	 *
   524 		$contributors = $this->get_contributors();
   545 		$contributors = $this->get_contributors();
   525 		if (isset($contributors[$key]))
   546 		if (isset($contributors[$key]))
   526 		{
   547 		{
   527 			return $contributors[$key];
   548 			return $contributors[$key];
   528 		}
   549 		}
   529 		else
   550 
   530 		{
   551 		return null;
   531 			return null;
       
   532 		}
       
   533 	}
   552 	}
   534 
   553 
   535 	/**
   554 	/**
   536 	 * Get all contributors for the item
   555 	 * Get all contributors for the item
   537 	 *
   556 	 *
   538 	 * Uses `<atom:contributor>`
   557 	 * Uses `<atom:contributor>`
   539 	 *
   558 	 *
   540 	 * @since 1.1
   559 	 * @since 1.1
   541 	 * @return array|null List of {@see SimplePie_Author} objects
   560 	 * @return SimplePie_Author[]|null List of {@see SimplePie_Author} objects
   542 	 */
   561 	 */
   543 	public function get_contributors()
   562 	public function get_contributors()
   544 	{
   563 	{
   545 		$contributors = array();
   564 		$contributors = array();
   546 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
   565 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
   590 
   609 
   591 		if (!empty($contributors))
   610 		if (!empty($contributors))
   592 		{
   611 		{
   593 			return array_unique($contributors);
   612 			return array_unique($contributors);
   594 		}
   613 		}
   595 		else
   614 
   596 		{
   615 		return null;
   597 			return null;
       
   598 		}
       
   599 	}
   616 	}
   600 
   617 
   601 	/**
   618 	/**
   602 	 * Get all authors for the item
   619 	 * Get all authors for the item
   603 	 *
   620 	 *
   604 	 * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
   621 	 * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
   605 	 *
   622 	 *
   606 	 * @since Beta 2
   623 	 * @since Beta 2
   607 	 * @return array|null List of {@see SimplePie_Author} objects
   624 	 * @return SimplePie_Author[]|null List of {@see SimplePie_Author} objects
   608 	 */
   625 	 */
   609 	public function get_authors()
   626 	public function get_authors()
   610 	{
   627 	{
   611 		$authors = array();
   628 		$authors = array();
   612 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
   629 		foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
   680 		}
   697 		}
   681 		elseif ($authors = $this->feed->get_authors())
   698 		elseif ($authors = $this->feed->get_authors())
   682 		{
   699 		{
   683 			return $authors;
   700 			return $authors;
   684 		}
   701 		}
   685 		else
   702 
   686 		{
   703 		return null;
   687 			return null;
       
   688 		}
       
   689 	}
   704 	}
   690 
   705 
   691 	/**
   706 	/**
   692 	 * Get the copyright info for the item
   707 	 * Get the copyright info for the item
   693 	 *
   708 	 *
   708 		}
   723 		}
   709 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
   724 		elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
   710 		{
   725 		{
   711 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
   726 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
   712 		}
   727 		}
   713 		else
   728 
   714 		{
   729 		return null;
   715 			return null;
       
   716 		}
       
   717 	}
   730 	}
   718 
   731 
   719 	/**
   732 	/**
   720 	 * Get the posting date/time for the item
   733 	 * Get the posting date/time for the item
   721 	 *
   734 	 *
   736 		{
   749 		{
   737 			if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
   750 			if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
   738 			{
   751 			{
   739 				$this->data['date']['raw'] = $return[0]['data'];
   752 				$this->data['date']['raw'] = $return[0]['data'];
   740 			}
   753 			}
       
   754 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
       
   755 			{
       
   756 				$this->data['date']['raw'] = $return[0]['data'];
       
   757 			}
       
   758 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
       
   759 			{
       
   760 				$this->data['date']['raw'] = $return[0]['data'];
       
   761 			}
       
   762 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
       
   763 			{
       
   764 				$this->data['date']['raw'] = $return[0]['data'];
       
   765 			}
   741 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
   766 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
   742 			{
   767 			{
   743 				$this->data['date']['raw'] = $return[0]['data'];
   768 				$this->data['date']['raw'] = $return[0]['data'];
   744 			}
   769 			}
   745 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
   770 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
   749 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
   774 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
   750 			{
   775 			{
   751 				$this->data['date']['raw'] = $return[0]['data'];
   776 				$this->data['date']['raw'] = $return[0]['data'];
   752 			}
   777 			}
   753 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
   778 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
   754 			{
       
   755 				$this->data['date']['raw'] = $return[0]['data'];
       
   756 			}
       
   757 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
       
   758 			{
       
   759 				$this->data['date']['raw'] = $return[0]['data'];
       
   760 			}
       
   761 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
       
   762 			{
       
   763 				$this->data['date']['raw'] = $return[0]['data'];
       
   764 			}
       
   765 			elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
       
   766 			{
   779 			{
   767 				$this->data['date']['raw'] = $return[0]['data'];
   780 				$this->data['date']['raw'] = $return[0]['data'];
   768 			}
   781 			}
   769 
   782 
   770 			if (!empty($this->data['date']['raw']))
   783 			if (!empty($this->data['date']['raw']))
   790 
   803 
   791 				default:
   804 				default:
   792 					return date($date_format, $this->data['date']['parsed']);
   805 					return date($date_format, $this->data['date']['parsed']);
   793 			}
   806 			}
   794 		}
   807 		}
   795 		else
   808 
   796 		{
   809 		return null;
   797 			return null;
       
   798 		}
       
   799 	}
   810 	}
   800 
   811 
   801 	/**
   812 	/**
   802 	 * Get the update date/time for the item
   813 	 * Get the update date/time for the item
   803 	 *
   814 	 *
   819 			}
   830 			}
   820 
   831 
   821 			if (!empty($this->data['updated']['raw']))
   832 			if (!empty($this->data['updated']['raw']))
   822 			{
   833 			{
   823 				$parser = $this->registry->call('Parse_Date', 'get');
   834 				$parser = $this->registry->call('Parse_Date', 'get');
   824 				$this->data['updated']['parsed'] = $parser->parse($this->data['date']['raw']);
   835 				$this->data['updated']['parsed'] = $parser->parse($this->data['updated']['raw']);
   825 			}
   836 			}
   826 			else
   837 			else
   827 			{
   838 			{
   828 				$this->data['updated'] = null;
   839 				$this->data['updated'] = null;
   829 			}
   840 			}
   841 
   852 
   842 				default:
   853 				default:
   843 					return date($date_format, $this->data['updated']['parsed']);
   854 					return date($date_format, $this->data['updated']['parsed']);
   844 			}
   855 			}
   845 		}
   856 		}
   846 		else
   857 
   847 		{
   858 		return null;
   848 			return null;
       
   849 		}
       
   850 	}
   859 	}
   851 
   860 
   852 	/**
   861 	/**
   853 	 * Get the localized posting date/time for the item
   862 	 * Get the localized posting date/time for the item
   854 	 *
   863 	 *
   870 		}
   879 		}
   871 		elseif (($date = $this->get_date('U')) !== null && $date !== false)
   880 		elseif (($date = $this->get_date('U')) !== null && $date !== false)
   872 		{
   881 		{
   873 			return strftime($date_format, $date);
   882 			return strftime($date_format, $date);
   874 		}
   883 		}
   875 		else
   884 
   876 		{
   885 		return null;
   877 			return null;
       
   878 		}
       
   879 	}
   886 	}
   880 
   887 
   881 	/**
   888 	/**
   882 	 * Get the posting date/time for the item (UTC time)
   889 	 * Get the posting date/time for the item (UTC time)
   883 	 *
   890 	 *
   934 		}
   941 		}
   935 		elseif ($enclosure !== null)
   942 		elseif ($enclosure !== null)
   936 		{
   943 		{
   937 			return $enclosure->get_link();
   944 			return $enclosure->get_link();
   938 		}
   945 		}
   939 		else
   946 
   940 		{
   947 		return null;
   941 			return null;
       
   942 		}
       
   943 	}
   948 	}
   944 
   949 
   945 	/**
   950 	/**
   946 	 * Get a single link for the item
   951 	 * Get a single link for the item
   947 	 *
   952 	 *
   951 	 * @return string|null Link URL
   956 	 * @return string|null Link URL
   952 	 */
   957 	 */
   953 	public function get_link($key = 0, $rel = 'alternate')
   958 	public function get_link($key = 0, $rel = 'alternate')
   954 	{
   959 	{
   955 		$links = $this->get_links($rel);
   960 		$links = $this->get_links($rel);
   956 		if ($links[$key] !== null)
   961 		if ($links && $links[$key] !== null)
   957 		{
   962 		{
   958 			return $links[$key];
   963 			return $links[$key];
   959 		}
   964 		}
   960 		else
   965 
   961 		{
   966 		return null;
   962 			return null;
       
   963 		}
       
   964 	}
   967 	}
   965 
   968 
   966 	/**
   969 	/**
   967 	 * Get all links for the item
   970 	 * Get all links for the item
   968 	 *
   971 	 *
  1038 		}
  1041 		}
  1039 		if (isset($this->data['links'][$rel]))
  1042 		if (isset($this->data['links'][$rel]))
  1040 		{
  1043 		{
  1041 			return $this->data['links'][$rel];
  1044 			return $this->data['links'][$rel];
  1042 		}
  1045 		}
  1043 		else
  1046 
  1044 		{
  1047 		return null;
  1045 			return null;
       
  1046 		}
       
  1047 	}
  1048 	}
  1048 
  1049 
  1049 	/**
  1050 	/**
  1050 	 * Get an enclosure from the item
  1051 	 * Get an enclosure from the item
  1051 	 *
  1052 	 *
  1061 		$enclosures = $this->get_enclosures();
  1062 		$enclosures = $this->get_enclosures();
  1062 		if (isset($enclosures[$key]))
  1063 		if (isset($enclosures[$key]))
  1063 		{
  1064 		{
  1064 			return $enclosures[$key];
  1065 			return $enclosures[$key];
  1065 		}
  1066 		}
  1066 		else
  1067 
  1067 		{
  1068 		return null;
  1068 			return null;
       
  1069 		}
       
  1070 	}
  1069 	}
  1071 
  1070 
  1072 	/**
  1071 	/**
  1073 	 * Get all available enclosures (podcasts, etc.)
  1072 	 * Get all available enclosures (podcasts, etc.)
  1074 	 *
  1073 	 *
  1078 	 * are the same content.  Anything else is too complicated to
  1077 	 * are the same content.  Anything else is too complicated to
  1079 	 * properly support.
  1078 	 * properly support.
  1080 	 *
  1079 	 *
  1081 	 * @since Beta 2
  1080 	 * @since Beta 2
  1082 	 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
  1081 	 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
  1083 	 * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists).
  1082 	 * @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).
  1084 	 * @return array|null List of SimplePie_Enclosure items
  1083 	 * @return SimplePie_Enclosure[]|null List of SimplePie_Enclosure items
  1085 	 */
  1084 	 */
  1086 	public function get_enclosures()
  1085 	public function get_enclosures()
  1087 	{
  1086 	{
  1088 		if (!isset($this->data['enclosures']))
  1087 		if (!isset($this->data['enclosures']))
  1089 		{
  1088 		{
  2656 						}
  2655 						}
  2657 
  2656 
  2658 						// PLAYER
  2657 						// PLAYER
  2659 						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  2658 						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
  2660 						{
  2659 						{
  2661 							$player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  2660 							if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'])) {
       
  2661 								$player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
       
  2662 							}
  2662 						}
  2663 						}
  2663 						else
  2664 						else
  2664 						{
  2665 						{
  2665 							$player = $player_parent;
  2666 							$player = $player_parent;
  2666 						}
  2667 						}
  2731 						// THUMBNAILS
  2732 						// THUMBNAILS
  2732 						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  2733 						if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
  2733 						{
  2734 						{
  2734 							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  2735 							foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
  2735 							{
  2736 							{
  2736 								$thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
  2737 								if (isset($thumbnail['attribs']['']['url'])) {
       
  2738 									$thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
       
  2739 								}
  2737 							}
  2740 							}
  2738 							if (is_array($thumbnails))
  2741 							if (is_array($thumbnails))
  2739 							{
  2742 							{
  2740 								$thumbnails = array_values(array_unique($thumbnails));
  2743 								$thumbnails = array_values(array_unique($thumbnails));
  2741 							}
  2744 							}
  2787 					}
  2790 					}
  2788 					if (isset($link['attribs']['']['length']))
  2791 					if (isset($link['attribs']['']['length']))
  2789 					{
  2792 					{
  2790 						$length = ceil($link['attribs']['']['length']);
  2793 						$length = ceil($link['attribs']['']['length']);
  2791 					}
  2794 					}
       
  2795 					if (isset($link['attribs']['']['title']))
       
  2796 					{
       
  2797 						$title = $this->sanitize($link['attribs']['']['title'], SIMPLEPIE_CONSTRUCT_TEXT);
       
  2798 					}
       
  2799 					else
       
  2800 					{
       
  2801 						$title = $title_parent;
       
  2802 					}
  2792 
  2803 
  2793 					// Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  2804 					// Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
  2794 					$this->data['enclosures'][] = $this->registry->create('Enclosure', array($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));
  2805 					$this->data['enclosures'][] = $this->registry->create('Enclosure', array($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));
  2795 				}
  2806 				}
  2796 			}
  2807 			}
  2797 
  2808 
  2798 			foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  2809 			foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
  2799 			{
  2810 			{
  2875 		}
  2886 		}
  2876 		if (!empty($this->data['enclosures']))
  2887 		if (!empty($this->data['enclosures']))
  2877 		{
  2888 		{
  2878 			return $this->data['enclosures'];
  2889 			return $this->data['enclosures'];
  2879 		}
  2890 		}
  2880 		else
  2891 
  2881 		{
  2892 		return null;
  2882 			return null;
       
  2883 		}
       
  2884 	}
  2893 	}
  2885 
  2894 
  2886 	/**
  2895 	/**
  2887 	 * Get the latitude coordinates for the item
  2896 	 * Get the latitude coordinates for the item
  2888 	 *
  2897 	 *
  2903 		}
  2912 		}
  2904 		elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  2913 		elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  2905 		{
  2914 		{
  2906 			return (float) $match[1];
  2915 			return (float) $match[1];
  2907 		}
  2916 		}
  2908 		else
  2917 
  2909 		{
  2918 		return null;
  2910 			return null;
       
  2911 		}
       
  2912 	}
  2919 	}
  2913 
  2920 
  2914 	/**
  2921 	/**
  2915 	 * Get the longitude coordinates for the item
  2922 	 * Get the longitude coordinates for the item
  2916 	 *
  2923 	 *
  2935 		}
  2942 		}
  2936 		elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  2943 		elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
  2937 		{
  2944 		{
  2938 			return (float) $match[2];
  2945 			return (float) $match[2];
  2939 		}
  2946 		}
  2940 		else
  2947 
  2941 		{
  2948 		return null;
  2942 			return null;
       
  2943 		}
       
  2944 	}
  2949 	}
  2945 
  2950 
  2946 	/**
  2951 	/**
  2947 	 * Get the `<atom:source>` for the item
  2952 	 * Get the `<atom:source>` for the item
  2948 	 *
  2953 	 *
  2953 	{
  2958 	{
  2954 		if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
  2959 		if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
  2955 		{
  2960 		{
  2956 			return $this->registry->create('Source', array($this, $return[0]));
  2961 			return $this->registry->create('Source', array($this, $return[0]));
  2957 		}
  2962 		}
  2958 		else
  2963 
  2959 		{
  2964 		return null;
  2960 			return null;
       
  2961 		}
       
  2962 	}
  2965 	}
  2963 }
  2966 }
  2964