/** * BlogFeedConsumer constructor. * @param ClientInterface $httpClient * @param Cache\Cache $feedCache * @param Cache\ClearableCache $templatesCache * @param BlogOptions $blogOptions * * @Inject({GuzzleClient::class, "Acelaya\Website\FeedCache", Cache\Cache::class, BlogOptions::class}) */ public function __construct(ClientInterface $httpClient, Cache\Cache $feedCache, Cache\ClearableCache $templatesCache, BlogOptions $blogOptions) { Reader::setHttpClient($httpClient); $this->feedCache = $feedCache; $this->blogOptions = $blogOptions; $this->templatesCache = $templatesCache; }
public function __invoke($services) { $http = $services->get('http'); FeedReader::setHttpClient($http); FeedReader::setExtensionManager($this->createExtensionManager()); $config = $services->get('Config'); $config = $config['github']; $reader = new AtomReader($config['user']); $reader->setLimit($config['limit']); return $reader; }
public function rssProxyAction() { $overrideFeedUrl = $this->getEvent()->getRequest()->getQuery()->get('urlOverride'); $limit = $this->getEvent()->getRequest()->getQuery()->get('limit'); $instanceId = $this->getEvent()->getRequest()->getQuery()->get('instanceId'); /** @var \Rcm\Service\PluginManager $pluginManager */ $pluginManager = $this->serviceLocator->get('\\Rcm\\Service\\PluginManager'); if ($instanceId > 0) { $instanceConfig = $pluginManager->getInstanceConfig($instanceId); } else { $instanceConfig = $pluginManager->getDefaultInstanceConfig('RcmRssFeed'); } $feedUrl = $instanceConfig['rssFeedUrl']; $cacheKey = 'rcmrssfeed-' . md5($feedUrl); if ($this->cacheMgr->hasItem($cacheKey)) { $viewRssData = json_decode($this->cacheMgr->getItem($cacheKey)); $this->sendJson($viewRssData); } if (!empty($overrideFeedUrl) && $overrideFeedUrl != 'null') { //$permissions = $this->userMgr->getLoggedInAdminPermissions(); $permissions = null; /** * Only admins can override the url. This prevents people from using * our proxy to DDOS other sites. */ $allowed = $this->rcmIsAllowed('sites.' . $this->siteId, 'admin'); if ($allowed) { $feedUrl = $overrideFeedUrl; } } if (empty($limit)) { $limit = $instanceConfig['rssFeedLimit']; } $rssReader = new Reader(); //Tried to add a timeout like this but it didnt work $httpClient = new Client($feedUrl, ['timeout' => 5]); $rssReader->setHttpClient($httpClient); try { $feedData = $rssReader->import($feedUrl); } catch (\Exception $e) { $feedData = []; } $feedCount = 0; $viewRssData = []; foreach ($feedData as $entry) { if ($feedCount == $limit) { break; } $viewRssData[] = ['feedtitle' => $entry->getTitle(), 'description' => $entry->getDescription(), 'dateModified' => $entry->getDateModified(), 'authors' => $entry->getAuthors(), 'feedlink' => $entry->getLink()]; $feedCount++; } $this->cacheMgr->addItem($cacheKey, json_encode($viewRssData)); $this->sendJson($viewRssData); }
public function __invoke(ContainerInterface $container) : AtomReader { $http = $container->get(FeedReaderHttpClientInterface::class); FeedReader::setHttpClient($http); FeedReader::setExtensionManager(new StandaloneExtensionManager()); $config = $container->get('config'); $config = $config['github']; $reader = new AtomReader($config['user']); $reader->setLimit($config['limit']); $reader->addFilter(function ($entry) { if (false !== strpos($entry->getLink(), 'weierophinney/mwop.net')) { return false; } return true; }); return $reader; }
/** * @param string $url * @param int $limit * @return array */ public function read($url, $limit = 5) { $data = []; $this->client->setUri($url)->setOptions(['adapter' => 'Zend\\Http\\Client\\Adapter\\Curl']); try { \Zend\Feed\Reader\Reader::setHttpClient($this->client); $feed = \Zend\Feed\Reader\Reader::import($url); if ($feed) { $i = 0; foreach ($feed as $entry) { $edata = ['title' => $entry->getTitle(), 'description' => preg_replace("/<img(.+?)>/", "", $entry->getDescription()), 'dateModified' => $entry->getDateModified(), 'authors' => $entry->getAuthors(), 'link' => $entry->getLink(), 'content' => $entry->getContent()]; $data[] = (object) $edata; $i++; if ($i == $limit) { break; } } } } catch (RuntimeException $exception) { $data[] = []; } return $data; }
/** * @group ZF-8330 */ public function testGetsFeedLinksAndNormalisesRelativeUrlsOnUriWithPath() { try { $currClient = Reader\Reader::getHttpClient(); $response = new \Zend\Http\Response(); $response->setContent('<!DOCTYPE html><html><head><link rel="alternate" type="application/rss+xml" href="../test.rss"><link rel="alternate" type="application/atom+xml" href="/test.atom"></head><body></body></html>'); $response->setStatusCode(200); $testAdapter = new \Zend\Http\Client\Adapter\Test(); $testAdapter->setResponse($response); Reader\Reader::setHttpClient(new \Zend\Http\Client(null, array('adapter' => $testAdapter))); $links = Reader\Reader::findFeedLinks('http://foo/bar'); Reader\Reader::setHttpClient($currClient); } catch (\Exception $e) { $this->fail($e->getMessage()); } $this->assertEquals('http://foo/test.rss', $links->rss); $this->assertEquals('http://foo/test.atom', $links->atom); }
/** * @group ZF-8330 */ public function testGetsFeedLinksAndNormalisesRelativeUrlsOnUriWithPath() { $this->markTestIncomplete('Pending fix to \\Zend\\URI\\URL::validate()'); try { $currClient = Reader\Reader::getHttpClient(); $testAdapter = new \Zend\HTTP\Client\Adapter\Test(); $testAdapter->setResponse(new \Zend\HTTP\Response\Response(200, array(), '<!DOCTYPE html><html><head><link rel="alternate" type="application/rss+xml" href="../test.rss"><link rel="alternate" type="application/atom+xml" href="/test.atom"></head><body></body></html>')); Reader\Reader::setHttpClient(new \Zend\HTTP\Client(null, array('adapter' => $testAdapter))); $links = Reader\Reader::findFeedLinks('http://foo/bar'); Reader\Reader::setHttpClient($currClient); } catch (\Exception $e) { $this->fail($e->getMessage()); } $this->assertEquals('http://foo/test.rss', $links->rss); $this->assertEquals('http://foo/test.atom', $links->atom); }
/** * Return feed content and settings in JSON format. * * @return mixed */ public function getFeedAjax() { if (!($id = $this->params()->fromQuery('id'))) { return $this->output('Missing feed id', self::STATUS_ERROR); } $touchDevice = $this->params()->fromQuery('touch-device') !== null ? $this->params()->fromQuery('touch-device') === '1' : false; $config = $this->getServiceLocator()->get('VuFind\\Config')->get('rss'); if (!isset($config[$id])) { return $this->output('Missing feed configuration', self::STATUS_ERROR); } $config = $config[$id]; if (!$config->active) { return $this->output('Feed inactive', self::STATUS_ERROR); } if (!($url = $config->url)) { return $this->output('Missing feed URL', self::STATUS_ERROR); } $translator = $this->getServiceLocator()->get('VuFind\\Translator'); $language = $translator->getLocale(); if (isset($url[$language])) { $url = trim($url[$language]); } else { if (isset($url['*'])) { $url = trim($url['*']); } else { return $this->output('Missing feed URL', self::STATUS_ERROR); } } $type = $config->type; $channel = null; // Check for cached version $cacheEnabled = false; $cacheDir = $this->getServiceLocator()->get('VuFind\\CacheManager')->getCache('feed')->getOptions()->getCacheDir(); $cacheKey = $config->toArray(); $cacheKey['language'] = $language; $localFile = "{$cacheDir}/" . md5(var_export($cacheKey, true)) . '.xml'; $cacheConfig = $this->getServiceLocator()->get('VuFind\\Config')->get('config'); $maxAge = isset($cacheConfig->Content->feedcachetime) ? $cacheConfig->Content->feedcachetime : false; $httpService = $this->getServiceLocator()->get('VuFind\\Http'); Reader::setHttpClient($httpService->createClient()); if ($maxAge) { $cacheEnabled = true; if (is_readable($localFile) && time() - filemtime($localFile) < $maxAge * 60) { $channel = Reader::importFile($localFile); } } if (!$channel) { // No cache available, read from source. if (preg_match('/^http(s)?:\\/\\//', $url)) { // Absolute URL $channel = Reader::import($url); } else { if (substr($url, 0, 1) === '/') { // Relative URL $url = substr($this->getServerUrl('home'), 0, -1) . $url; $channel = Reader::import($url); } else { // Local file if (!is_file($url)) { return $this->output("File {$url} could not be found", self::STATUS_ERROR); } $channel = Reader::importFile($url); } } } if (!$channel) { return $this->output('Parsing failed', self::STATUS_ERROR); } if ($cacheEnabled) { file_put_contents($localFile, $channel->saveXml()); } $content = ['title' => 'getTitle', 'text' => 'getContent', 'image' => 'getEnclosure', 'link' => 'getLink', 'date' => 'getDateCreated']; $dateFormat = isset($config->dateFormat) ? $config->dateFormat : 'j.n.'; $itemsCnt = isset($config->items) ? $config->items : null; $items = []; foreach ($channel as $item) { $data = []; foreach ($content as $setting => $method) { if (!isset($config->content[$setting]) || $config->content[$setting] != 0) { $tmp = $item->{$method}(); if (is_object($tmp)) { $tmp = get_object_vars($tmp); } if ($setting == 'image') { if (!$tmp || stripos($tmp['type'], 'image') === false) { // Attempt to parse image URL from content if ($tmp = $this->extractImage($item->getContent())) { $tmp = ['url' => $tmp]; } } } else { if ($setting == 'date') { if (isset($tmp['date'])) { $tmp = new \DateTime($tmp['date']); $tmp = $tmp->format($dateFormat); } } else { if (is_string($tmp)) { $tmp = strip_tags($tmp); } } } if ($tmp) { $data[$setting] = $tmp; } } } // Make sure that we have something to display $accept = $data['title'] && trim($data['title']) != '' || $data['text'] && trim($data['text']) != '' || $data['image']; if (!$accept) { continue; } $items[] = $data; if ($itemsCnt !== null) { if (--$itemsCnt === 0) { break; } } } $images = isset($config->content['image']) ? $config->content['image'] : true; $moreLink = !isset($config->moreLink) || $config->moreLink ? $channel->getLink() : null; $key = $touchDevice ? 'touch' : 'desktop'; $linkText = null; if (isset($config->linkText[$key])) { $linkText = $config->linkText[$key]; } else { if (isset($config->linkText) && is_string($config->linkText)) { $linkText = $config->linkText; } } $feed = ['linkText' => $linkText, 'moreLink' => $moreLink, 'type' => $type, 'items' => $items, 'touchDevice' => $touchDevice, 'images' => $images]; if (isset($config->title)) { if ($config->title == 'rss') { $feed['title'] = $channel->getTitle(); } else { $feed['translateTitle'] = $config->title; } } if (isset($config->linkTarget)) { $feed['linkTarget'] = $config->linkTarget; } $template = $type == 'list' ? 'list' : 'carousel'; $html = $this->getViewRenderer()->partial("ajax/feed-{$template}.phtml", $feed); $settings = []; $settings['type'] = $type; if (isset($config->height)) { $settings['height'] = $config->height; } if ($type == 'carousel' || $type == 'carousel-vertical') { $settings['images'] = $images; $settings['autoplay'] = isset($config->autoplay) ? $config->autoplay : false; $settings['dots'] = isset($config->dots) ? $config->dots == true : true; $breakPoints = ['desktop' => 4, 'desktop-small' => 3, 'tablet' => 2, 'mobile' => 1]; foreach ($breakPoints as $breakPoint => $default) { $settings['slidesToShow'][$breakPoint] = isset($config->itemsPerPage[$breakPoint]) ? (int) $config->itemsPerPage[$breakPoint] : $default; $settings['scrolledItems'][$breakPoint] = isset($config->scrolledItems[$breakPoint]) ? (int) $config->scrolledItems[$breakPoint] : $settings['slidesToShow'][$breakPoint]; } if ($type == 'carousel') { $settings['titlePosition'] = isset($config->titlePosition) ? $config->titlePosition : null; } } $res = ['html' => $html, 'settings' => $settings]; return $this->output($res, self::STATUS_OK); }
/** * Import a feed by providing a URI * * @param string $uri * The URI to the feed * @param string $format * The output format. Possible values xml or json (default). * @return array */ public function feedRead($uri, $format = "json", $fixencoding = true) { $zuri = \Zend\Uri\UriFactory::factory($uri); if (!$zuri->isValid()) { $this->logger->logWarn("Invalid Uri ({$uri})"); return false; } $cache = \Zend\Cache\StorageFactory::factory(array('adapter' => array('name' => 'filesystem', 'options' => array('cache_dir' => __DIR__ . DIRECTORY_SEPARATOR . 'cache', 'ttl' => 3600)), 'plugins' => array(array('name' => 'serializer', 'options' => array())))); \Zend\Feed\Reader\Reader::setCache($cache); \Zend\Feed\Reader\Reader::useHttpConditionalGet(); // Change to firefox agent $httpClient = \Zend\Feed\Reader\Reader::getHttpClient(); $httpClient->setOptions(array('useragent' => 'Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0', 'timeout' => 25)); \Zend\Feed\Reader\Reader::setHttpClient($httpClient); // Import feed try { $feed = \Zend\Feed\Reader\Reader::import($uri); $httpClient = \Zend\Feed\Reader\Reader::getHttpClient(); $httpClientResponse = $httpClient->getResponse(); $feedencoding = $feed->getEncoding(); if (!$feedencoding) { $feedencoding = 'utf-8'; } $feedResponse = array('feed' => $uri, 'statuscode' => $httpClientResponse->getStatusCode(), 'headers' => $httpClientResponse->getHeaders()->toArray(), 'encoding' => $feedencoding); } catch (\Exception $e) { $this->logger->logWarn("Zend feed reader cannot fetch: ({$uri}) because : " . $e->getMessage() . " trying casperjs"); $command = 'casperjs ' . __DIR__ . '/html.js --cookies-file=cookies.txt --url=' . escapeshellarg($uri); exec($command, $response, $return_var); $response = $this->strip_json($response); if ($return_var !== 0 || !isset($response['content']) || empty($response['content'])) { $this->logger->logWarn("Cannot fetch: ({$uri}) exit code {$return_var}", array('command' => $command, 'response' => $response)); $failed = new \Rss\Feed\Reader\ReadFailures($this->postgresql); $failed->update_failure($uri, json_encode(array('zend' => $e->getMessage(), 'casper' => $response))); return false; } try { $feed = \Zend\Feed\Reader\Reader::importString($response['content']); $feedencoding = $feed->getEncoding(); if (!$feedencoding) { $feedencoding = 'utf-8'; } $feedResponse = array('feed' => $uri, 'statuscode' => $response['http']['status'], 'headers' => $response['http'], 'encoding' => $feedencoding); } catch (\Exception $e) { $this->logger->logWarn("Cannot parse feed content from ({$uri}) because " . $e->getMessage()); // $failed = new \Rss\Feed\Reader\ReadFailures ( $this->postgresql ); // $failed->update_failure ( $uri ); return false; } } // Fix relative links $newdata = $this->fix_links($feed, $uri); // Fix encoding errors if ($fixencoding) { $newdata = $this->fix_encoding($newdata); } // Return XML if ($format === "xml") { $feedResponse['data'] = $newdata; return $feedResponse; } // Reload fixed data try { $feed = \Zend\Feed\Reader\Reader::importString($newdata); } catch (\Exception $e) { $this->logger->logWarn("Cannot parse corrected feed content from ({$uri}) because " . $e->getMessage()); return false; } $data = array('title' => $feed->getTitle(), 'link' => $feed->getLink(), 'date' => $this->get_feed_date($feed), 'description' => $feed->getDescription(), 'language' => $feed->getLanguage(), 'entries' => array()); foreach ($feed as $entry) { if (is_object($entry)) { $DateCreated = $entry->getDateCreated(); if (is_object($DateCreated)) { $DateCreated = $DateCreated->getTimestamp(); } else { $DateCreated = $data['date']; } $DateModified = $entry->getDateModified(); if (is_object($DateModified)) { $DateModified = $DateModified->getTimestamp(); } else { $DateModified = $data['date']; } if (empty($DateModified)) { $DateModified = time(); } if (empty($DateCreated)) { $DateCreated = time(); } $description = $entry->getDescription(); $content = $entry->getContent(); if (empty($description)) { $description = $content; } if (empty($content)) { $content = $description; } $edata = array('title' => $entry->getTitle(), 'description' => $description, 'dateCreated' => $DateCreated, 'dateModified' => $DateModified, 'link' => $entry->getLink(), 'content' => $content, 'feed' => $uri); if ($this->check_missing($edata)) { $data['entries'][] = $edata; } else { $this->logger->logTrace("Missing data from feed {$uri} " . json_encode($edata, JSON_UNESCAPED_UNICODE)); } } } // Return array $feedResponse['data'] = $data; return $feedResponse; }
/** * Called after the Search Results object has performed its main search. This * may be used to extract necessary information from the Search Results object * or to perform completely unrelated processing. * * @param \VuFind\Search\Base\Results $results Search results object * * @return void */ public function process($results) { $this->debug('Pulling feed from ' . $this->targetUrl); if (null !== $this->httpService) { FeedReader::setHttpClient($this->httpService->createClient($this->targetUrl)); } $parsedFeed = FeedReader::import($this->targetUrl); $resultsProcessed = []; foreach ($parsedFeed as $value) { $link = $value->getLink(); if (!empty($link)) { $resultsProcessed[] = ['title' => $value->getTitle(), 'link' => substr($link, 0, strpos($link, '.srw')) . '.html', 'enclosure' => $value->getEnclosure()['url']]; } if (count($resultsProcessed) == $this->limit) { break; } } if (!empty($resultsProcessed)) { $this->results = ['worksArray' => $resultsProcessed, 'feedTitle' => $this->searchSite, 'sourceLink' => $this->sitePath]; } else { $this->results = false; } }
/** * Utility function for processing a feed (see readFeed, readFeedFromUrl). * * @param array $feedConfig Configuration * @param Zend\Mvc\Controller\Plugin\Url $urlHelper Url helper * @param string $viewUrl View URL * @param string $id Feed id (needed when the * feed content is shown on a content page or in a modal) * * @return mixed null|array */ protected function processReadFeed($feedConfig, $urlHelper, $viewUrl, $id = null) { $config = $feedConfig['result']; $url = $feedConfig['url']; $type = $config->type; $cacheKey = $config->toArray(); $cacheKey['language'] = $this->translator->getLocale(); $modal = false; $showFullContentOnSite = isset($config->linkTo) && in_array($config->linkTo, ['modal', 'content-page']); $modal = $config->linkTo == 'modal'; $contentPage = $config->linkTo == 'content-page'; $dateFormat = isset($config->dateFormat) ? $config->dateFormat : 'j.n.'; $contentDateFormat = isset($config->contentDateFormat) ? $config->contentDateFormat : 'j.n.Y'; $itemsCnt = isset($config->items) ? $config->items : null; $elements = isset($config->content) ? $config->content : []; $channel = null; // Check for cached version $cacheDir = $this->cacheManager->getCache('feed')->getOptions()->getCacheDir(); $localFile = "{$cacheDir}/" . md5(var_export($cacheKey, true)) . '.xml'; $maxAge = isset($this->mainConfig->Content->feedcachetime) ? $this->mainConfig->Content->feedcachetime : 10; Reader::setHttpClient($this->http->createClient()); if ($maxAge) { if (is_readable($localFile) && time() - filemtime($localFile) < $maxAge * 60) { $channel = Reader::importFile($localFile); } } if (!$channel) { // No cache available, read from source. if (preg_match('/^http(s)?:\\/\\//', $url)) { // Absolute URL $channel = Reader::import($url); } else { if (substr($url, 0, 1) === '/') { // Relative URL $url = substr($viewUrl, 0, -1) . $url; try { $channel = Reader::import($url); } catch (\Exception $e) { $this->logError("Error importing feed from url {$url}"); $this->logError(" " . $e->getMessage()); } } else { // Local file if (!is_file($url)) { $this->logError("File {$url} could not be found"); throw new \Exception('Error reading feed'); } $channel = Reader::importFile($url); } } if ($channel) { file_put_contents($localFile, $channel->saveXml()); } } if (!$channel) { return false; } $content = ['title' => 'getTitle', 'text' => 'getContent', 'image' => 'getEnclosure', 'link' => 'getLink', 'date' => 'getDateCreated', 'contentDate' => 'getDateCreated']; $xpathContent = ['html' => '//item/content:encoded']; $items = []; $cnt = 0; $xpath = null; $cnt = 0; foreach ($channel as $item) { if (!$xpath) { $xpath = $item->getXpath(); } $data = []; $data['modal'] = $modal; foreach ($content as $setting => $method) { if (!isset($elements[$setting]) || $elements[$setting] != 0) { $value = $item->{$method}(); if (is_object($value)) { $value = get_object_vars($value); } if ($setting == 'image') { if (!$value || stripos($value['type'], 'image') === false) { // Attempt to parse image URL from content if ($value = $this->extractImage($item->getContent())) { $value = ['url' => $value]; } } } else { if ($setting == 'date') { if (isset($value['date'])) { $value = new \DateTime($value['date']); if ($dateFormat) { $value = $value->format($dateFormat); } } } else { if ($setting == 'contentDate') { if (isset($value['date'])) { $value = new \DateTime($value['date']); if ($contentDateFormat) { $value = $value->format($contentDateFormat); } } } else { if ($setting == 'link' && $showFullContentOnSite) { $link = $urlHelper->fromRoute('feed-content-page', ['page' => $id, 'element' => $cnt]); $value = $link; } else { if (is_string($value)) { $value = strip_tags($value); } } } } } if ($value) { $data[$setting] = $value; } } } // Make sure that we have something to display $accept = $data['title'] && trim($data['title']) != '' || $data['text'] && trim($data['text']) != '' || $data['image']; if (!$accept) { continue; } $items[] = $data; $cnt++; if ($itemsCnt !== null && $cnt == $itemsCnt) { break; } } if ($xpath && !empty($xpathContent)) { if ($xpathItem = $xpath->query('//item/content:encoded')->item(0)) { $contentSearch = isset($config->htmlContentSearch) ? $config->htmlContentSearch->toArray() : []; $contentReplace = isset($config->htmlContentReplace) ? $config->htmlContentReplace->toArray() : []; $searchReplace = array_combine($contentSearch, $contentReplace); $cnt = 0; foreach ($items as &$item) { foreach ($xpathContent as $setting => $xpathElement) { $content = $xpath->query($xpathElement, $xpathItem)->item($cnt++)->nodeValue; // Remove width & height declarations from style // attributes in div & p elements $dom = new \DOMDocument(); libxml_use_internal_errors(true); $dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8')); $domx = new \DOMXPath($dom); $elements = $domx->query('//div[@style]|//p[@style]'); foreach ($elements as $el) { $styleProperties = []; $styleAttr = $el->getAttribute('style'); $properties = explode(';', $styleAttr); foreach ($properties as $prop) { list($field, $val) = explode(':', $prop); if (stristr($field, 'width') === false && stristr($field, 'height') === false && stristr($field, 'margin') === false) { $styleProperties[] = $prop; } } $el->removeAttribute("style"); $el->setAttribute('style', implode(';', $styleProperties)); } $content = $dom->saveHTML(); // Process feed specific search-replace regexes foreach ($searchReplace as $search => $replace) { $pattern = "/{$search}/"; $replaced = preg_replace($pattern, $replace, $content); if ($replaced !== null) { $content = $replaced; } } $item[$setting] = $content; } } } } return compact('channel', 'items', 'config', 'modal', 'contentPage'); }
/** * process * * Called after the Search Results object has performed its main search. This * may be used to extract necessary information from the Search Results object * or to perform completely unrelated processing. * * @param \VuFind\Search\Base\Results $results Search results object * * @return void */ public function process($results) { FeedReader::setHttpClient(new \VuFind\Http\Client()); $parsedFeed = FeedReader::import($this->targetUrl); $resultsProcessed = array(); foreach ($parsedFeed as $key => $value) { $link = (string) $value->link; if (!empty($link)) { $resultsProcessed[] = array('title' => (string) $value->title, 'link' => substr($link, 0, strpos($link, '.srw')) . '.html', 'enclosure' => (string) $value->enclosure['url']); } if (count($resultsProcessed) == $this->limit) { break; } } if (!empty($resultsProcessed)) { $this->results = array('worksArray' => $resultsProcessed, 'feedTitle' => $this->searchSite, 'sourceLink' => $this->sitePath); } else { $this->results = false; } }