<commit_before><?php
/**
 * This file is part of RSS-Bridge, a PHP project capable of generating RSS and
 * Atom feeds for websites that don't have one.
 *
 * For the full license information, please view the UNLICENSE file distributed
 * with this source code.
 *
 * @package	Core
 * @license	http://unlicense.org/ UNLICENSE
 * @link	https://github.com/rss-bridge/rss-bridge
 */

/**
 * An abstract class for bridges that need to transform existing RSS or Atom
 * feeds.
 *
 * This class extends {@see BridgeAbstract} with functions to extract contents
 * from existing RSS or Atom feeds. Bridges that need to transform existing feeds
 * should inherit from this class instead of {@see BridgeAbstract}.
 *
 * Bridges that extend this class don't need to concern themselves with getting
 * contents from existing feeds, but can focus on adding additional contents
 * (i.e. by downloading additional data), filtering or just transforming a feed
 * into another format.
 *
 * @link http://www.rssboard.org/rss-0-9-1 RSS 0.91 Specification
 * @link http://web.resource.org/rss/1.0/spec RDF Site Summary (RSS) 1.0
 * @link http://www.rssboard.org/rss-specification RSS 2.0 Specification
 * @link https://tools.ietf.org/html/rfc4287 The Atom Syndication Format
 *
 * @todo Return `self` on more functions to allow chaining
 * @todo The parsing functions should all be private. This class is complicated
 * enough without having to consider children overriding functions.
 */
abstract class FeedExpander extends BridgeAbstract {

	/**
	 * Holds the title of the current feed
	 *
	 * @var string
	 * @todo Rename this parameter to $title for clarity
	 */
	private $name;

	/**
	 * Holds the URI of the feed
	 *
	 * @var string
	 */
	private $uri;

	/**
	 * Holds the feed type during internal operations.
	 *
	 * @var string
	 * @todo Define possible values as constant instead of static strings
	 */
	private $feedType;

	/**
	 * Collects data from an existing feed.
	 *
	 * Children should call this function in {@see BridgeInterface::collectData()}
	 * to extract a feed.
	 *
	 * @param string $url URL to the feed.
	 * @param int $maxItems Maximum number of items to collect from the feed
	 * (`-1`: no limit).
	 * @return void
	 */
	public function collectExpandableDatas($url, $maxItems = -1){
		if(empty($url)) {
			returnServerError('There is no $url for this RSS expander');
		}

		Debug::log('Loading from ' . $url);

		/* Notice we do not use cache here on purpose:
		 * we want a fresh view of the RSS stream each time
		 */
		$content = getContents($url)
			or returnServerError('Could not request ' . $url);
		$rssContent = simplexml_load_string(trim($content));

		Debug::log('Detecting feed format/version');
		switch(true) {
		case isset($rssContent->item[0]):
			Debug::log('Detected RSS 1.0 format');
			$this->feedType = 'RSS_1_0';
			break;
		case isset($rssContent->channel[0]):
			Debug::log('Detected RSS 0.9x or 2.0 format');
			$this->feedType = 'RSS_2_0';
			break;
		case isset($rssContent->entry[0]):
			Debug::log('Detected ATOM format');
			$this->feedType = 'ATOM_1_0';
			break;
		default:
			Debug::log('Unknown feed format/version');
			returnServerError('The feed format is unknown!');
			break;
		}

		Debug::log('Calling function "collect_' . $this->feedType . '_data"');
		$this->{'collect_' . $this->feedType . '_data'}($rssContent, $maxItems);
	}

	/**
	 * Collect data from a RSS 1.0 compatible feed
	 *
	 * @link http://web.resource.org/rss/1.0/spec RDF Site Summary (RSS) 1.0
	 *
	 * @param string $rssContent The RSS content
	 * @param int $maxItems Maximum number of items to collect from the feed
	 * (`-1`: no limit).
	 * @return void
	 *
	 * @todo Instead of passing $maxItems to all functions, just add all items
	 * and remove excessive items later.
	 */
	protected function collect_RSS_1_0_data($rssContent, $maxItems){
		$this->load_RSS_2_0_feed_data($rssContent->channel[0]);
		foreach($rssContent->item as $item) {<commit_msg>[FeedExpander] Let collectExpandableDatas() return self<commit_after><?php
/**
 * This file is part of RSS-Bridge, a PHP project capable of generating RSS and
 * Atom feeds for websites that don't have one.
 *
 * For the full license information, please view the UNLICENSE file distributed
 * with this source code.
 *
 * @package	Core
 * @license	http://unlicense.org/ UNLICENSE
 * @link	https://github.com/rss-bridge/rss-bridge
 */

/**
 * An abstract class for bridges that need to transform existing RSS or Atom
 * feeds.
 *
 * This class extends {@see BridgeAbstract} with functions to extract contents
 * from existing RSS or Atom feeds. Bridges that need to transform existing feeds
 * should inherit from this class instead of {@see BridgeAbstract}.
 *
 * Bridges that extend this class don't need to concern themselves with getting
 * contents from existing feeds, but can focus on adding additional contents
 * (i.e. by downloading additional data), filtering or just transforming a feed
 * into another format.
 *
 * @link http://www.rssboard.org/rss-0-9-1 RSS 0.91 Specification
 * @link http://web.resource.org/rss/1.0/spec RDF Site Summary (RSS) 1.0
 * @link http://www.rssboard.org/rss-specification RSS 2.0 Specification
 * @link https://tools.ietf.org/html/rfc4287 The Atom Syndication Format
 *
 * @todo The parsing functions should all be private. This class is complicated
 * enough without having to consider children overriding functions.
 */
abstract class FeedExpander extends BridgeAbstract {

	/**
	 * Holds the title of the current feed
	 *
	 * @var string
	 * @todo Rename this parameter to $title for clarity
	 */
	private $name;

	/**
	 * Holds the URI of the feed
	 *
	 * @var string
	 */
	private $uri;

	/**
	 * Holds the feed type during internal operations.
	 *
	 * @var string
	 * @todo Define possible values as constant instead of static strings
	 */
	private $feedType;

	/**
	 * Collects data from an existing feed.
	 *
	 * Children should call this function in {@see BridgeInterface::collectData()}
	 * to extract a feed.
	 *
	 * @param string $url URL to the feed.
	 * @param int $maxItems Maximum number of items to collect from the feed
	 * (`-1`: no limit).
	 * @return self
	 */
	public function collectExpandableDatas($url, $maxItems = -1){
		if(empty($url)) {
			returnServerError('There is no $url for this RSS expander');
		}

		Debug::log('Loading from ' . $url);

		/* Notice we do not use cache here on purpose:
		 * we want a fresh view of the RSS stream each time
		 */
		$content = getContents($url)
			or returnServerError('Could not request ' . $url);
		$rssContent = simplexml_load_string(trim($content));

		Debug::log('Detecting feed format/version');
		switch(true) {
		case isset($rssContent->item[0]):
			Debug::log('Detected RSS 1.0 format');
			$this->feedType = 'RSS_1_0';
			break;
		case isset($rssContent->channel[0]):
			Debug::log('Detected RSS 0.9x or 2.0 format');
			$this->feedType = 'RSS_2_0';
			break;
		case isset($rssContent->entry[0]):
			Debug::log('Detected ATOM format');
			$this->feedType = 'ATOM_1_0';
			break;
		default:
			Debug::log('Unknown feed format/version');
			returnServerError('The feed format is unknown!');
			break;
		}

		Debug::log('Calling function "collect_' . $this->feedType . '_data"');
		$this->{'collect_' . $this->feedType . '_data'}($rssContent, $maxItems);

		return $this;
	}

	/**
	 * Collect data from a RSS 1.0 compatible feed
	 *
	 * @link http://web.resource.org/rss/1.0/spec RDF Site Summary (RSS) 1.0
	 *
	 * @param string $rssContent The RSS content
	 * @param int $maxItems Maximum number of items to collect from the feed
	 * (`-1`: no limit).
	 * @return void
	 *
	 * @todo Instead of passing $maxItems to all functions, just add all items
	 * and remove excessive items later.
	 */
	protected function collect_RSS_1_0_data($rssContent, $maxItems){
		$this->load_RSS_2_0_feed_data($rssContent->channel[0]);
		foreach($rssContent->item as $item) {
{'fraction_non_alphanumeric': 0.1182687468545546, 'fraction_numerical': 0.01132360342224459, 'mean_word_length': 3.6676453317674693, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 27, 'https://': 4, 'lorem ipsum': 0, 'www.': 4, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5790684', 'n_tokens_mistral': 2629, 'n_tokens_neox': 2338, 'n_words': 871}