| <?php | |
| /** | |
| * ***************************************************************************** | |
| * Copyright (c) 2014 Eclipse Foundation and others. | |
| * All rights reserved. This program and the accompanying materials | |
| * are made available under the terms of the Eclipse Public License v1.0 | |
| * which accompanies this distribution, and is available at | |
| * http://eclipse.org/legal/epl-v10.html | |
| * | |
| * Contributors: | |
| * Christopher Guindon (Eclipse Foundation) - Initial implementation | |
| * ***************************************************************************** | |
| */ | |
| class FeedParser { | |
| /** | |
| * List of rss paths | |
| * | |
| * @var string | |
| */ | |
| private $path = array(); | |
| /** | |
| * Default display count | |
| * | |
| * @var integer | |
| */ | |
| private $count = 4; | |
| /** | |
| * Feed object | |
| * | |
| * @var object | |
| */ | |
| private $feeds = array(); | |
| /** | |
| * Flag to match height on items | |
| * | |
| * @var bool | |
| */ | |
| private $match_height = FALSE; | |
| /** | |
| * Flag to only display press_releases | |
| * | |
| * @var string | |
| */ | |
| private $press_release = FALSE; | |
| /** | |
| * Array of news item | |
| * | |
| * @var array | |
| */ | |
| private $items = array(); | |
| /** | |
| * View more link values | |
| * | |
| * @var string | |
| */ | |
| private $view_more = array(); | |
| /** | |
| * Link to feedburner feed | |
| * | |
| * @var string | |
| */ | |
| private $rss_link = ""; | |
| /** | |
| * Default date_format | |
| * | |
| * @var string | |
| */ | |
| private $date_format = "Y/m/d"; | |
| /** | |
| * Default news item limit | |
| * | |
| * @var integer | |
| */ | |
| private $limit = 200; | |
| /** | |
| * Set date format | |
| * | |
| * @param string $format | |
| */ | |
| public function setDateFormat($format = "Y/m/d") { | |
| $this->date_format = $format; | |
| return TRUE; | |
| } | |
| /** | |
| * Get date format | |
| * | |
| * @return string | |
| */ | |
| public function getDateFormat() { | |
| return $this->date_format; | |
| } | |
| /** | |
| * Set path for RSS feed | |
| * | |
| * @param string $url | |
| */ | |
| public function addPath($path = "") { | |
| if (is_string($path)) { | |
| $this->path[] = $path; | |
| $this->_setFeeds($path); | |
| return TRUE; | |
| } | |
| return FALSE; | |
| } | |
| /** | |
| * Get path for RSS feed | |
| * | |
| * @return string | |
| */ | |
| public function getPath() { | |
| return $this->path; | |
| } | |
| /** | |
| * Set RSS link | |
| * | |
| * @param string $url | |
| */ | |
| public function setRssLink($url = "") { | |
| if (is_string($url)) { | |
| $this->rss_link = $url; | |
| return TRUE; | |
| } | |
| return FALSE; | |
| } | |
| /** | |
| * Get RSS link | |
| * | |
| * @param string $html | |
| * | |
| * @return string | |
| */ | |
| public function getRssLink() { | |
| return $this->rss_link; | |
| } | |
| /** | |
| * Get RSS link | |
| * | |
| * @param string $html | |
| * | |
| * @return string | |
| */ | |
| public function getRssLinkHTML() { | |
| $url = $this->getRssLink(); | |
| if (empty($url)) { | |
| return ""; | |
| } | |
| return '<a href="' . $url . '" class="link-rss-feed orange" title="Subscribe to our RSS-feed"><i class="fa fa-rss"></i> <span>Subscribe to our RSS-feed</span></a>'; | |
| } | |
| /** | |
| * Set Press Release Flag | |
| * | |
| * @param string $flag | |
| */ | |
| public function setPressRelease($flag = FALSE) { | |
| if (is_bool($flag)) { | |
| $this->press_release = $flag; | |
| return TRUE; | |
| } | |
| return FALSE; | |
| } | |
| /** | |
| * Get Press Release Flag | |
| * | |
| * @return string | |
| */ | |
| public function getPressRelease() { | |
| return $this->press_release; | |
| } | |
| /** | |
| * Set item count | |
| * | |
| * @param number $count | |
| */ | |
| public function setCount($count = 4) { | |
| if (is_numeric($count)) { | |
| $this->count = $count; | |
| return TRUE; | |
| } | |
| return FALSE; | |
| } | |
| /** | |
| * Get item count | |
| * | |
| * @return number $count | |
| */ | |
| public function getCount() { | |
| return $this->count; | |
| } | |
| /** | |
| * Get page number | |
| * | |
| * @return string | |
| */ | |
| public function getPage() { | |
| if (!empty($_GET['page']) && is_numeric($_GET['page'])) { | |
| return $_GET['page']; | |
| } | |
| return 1; | |
| } | |
| /** | |
| * Set description limit | |
| * | |
| * @param number $limit | |
| */ | |
| public function setLimit($limit = 200) { | |
| if (is_numeric($limit)) { | |
| $this->limit = $limit; | |
| return TRUE; | |
| } | |
| return FALSE; | |
| } | |
| /** | |
| * Get description limit | |
| * | |
| * @return number $limit | |
| */ | |
| public function getLimit() { | |
| return $this->limit; | |
| } | |
| /** | |
| * Set view_more link | |
| * | |
| * @param string $url | |
| * @param string $caption | |
| * @param string $prefix | |
| */ | |
| public function setViewMoreLink($url = "", $caption = 'View all', $prefix = '> ') { | |
| if (is_string($url) && is_string($caption) && is_string($prefix)) { | |
| $this->view_more = array( | |
| 'url' => $url, | |
| 'caption' => $caption, | |
| 'prefix' => $prefix | |
| ); | |
| return TRUE; | |
| } | |
| return FALSE; | |
| } | |
| /** | |
| * Set Match Height | |
| * | |
| * @param bool $match_height | |
| */ | |
| public function setMatchHeight($match_height) { | |
| if (is_bool($match_height)) { | |
| $this->match_height = $match_height; | |
| } | |
| } | |
| /** | |
| * Get Match Height | |
| * | |
| * @return bool | |
| */ | |
| public function getMatchHeight() { | |
| return $this->match_height; | |
| } | |
| /** | |
| * Get ViewMore link | |
| * | |
| * @return string | |
| */ | |
| public function getViewMoreLink() { | |
| $view_more = $this->view_more; | |
| if (empty($view_more['url']) || empty($view_more['caption'])) { | |
| return array(); | |
| } | |
| if (!isset($view_more['prefix'])) { | |
| $view_more['prefix'] = ""; | |
| } | |
| return $view_more; | |
| } | |
| /** | |
| * Get view_more link (HTML) | |
| * | |
| * @return string | |
| */ | |
| public function getViewMoreLinkHTML() { | |
| $view_more = $this->getViewMoreLink(); | |
| if (empty($view_more)) { | |
| return ""; | |
| } | |
| return $view_more['prefix'] . '<a href="' . $view_more['url'] . '">' . $view_more['caption'] . '</a>'; | |
| } | |
| /** | |
| * Html Output | |
| * | |
| * @return string | |
| */ | |
| public function output() { | |
| if (!$this->_parseFeeds()) { | |
| return '<p>This news feed is currently empty. Please try again later.</p>'; | |
| } | |
| $output = ''; | |
| if (!empty($this->items)) { | |
| $output .= '<div class="block-summary">'; | |
| foreach ($this->items as $item) { | |
| $output .= '<div class="block-summary-item '. ($this->getMatchHeight() ? 'match-height-item' : "") .'">'; | |
| $output .= '<p>' . $item['date'] . '</p>'; | |
| $output .= '<h4><a href="'. $item['link'] .'">' . $item['title'] . '</a></h4>'; | |
| if ($this->getLimit() > 0) { | |
| $output .= '<p>' . $item['description'] . '</p>'; | |
| } | |
| $output .= '</div>'; | |
| } | |
| $output .= '</div>'; | |
| } | |
| return $output; | |
| } | |
| /** | |
| * Get the Next page link | |
| * | |
| * @return string | |
| */ | |
| public function getPagination() { | |
| $feeds = $this->_getFeeds(); | |
| if (empty($feeds)) { | |
| return ""; | |
| } | |
| // Count all the items of all feeds | |
| $feed_items = 0; | |
| foreach ($feeds as $feed) { | |
| $feed_items += count($feed->channel->item); | |
| } | |
| // If the feed contains less items than the maximum allowed, | |
| // we don't need pagination | |
| if ($feed_items < $this->getCount()) { | |
| return ""; | |
| } | |
| $current_page = $this->getPage(); | |
| if (empty($current_page)) { | |
| $current_page = 1; | |
| } | |
| $url_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) . '?'; | |
| $url_queries = array( | |
| 'page' => 1 | |
| ); | |
| $links = array(); | |
| // Add the previous page link if needed | |
| $previous_page = $current_page - 1; | |
| if ($previous_page > 1) { | |
| $url_queries['page'] = $previous_page; | |
| $links[] = '<li><a aria-label="Previous" href="' . $url_path . http_build_query($url_queries) . '"><span aria-hidden="true">«</span></a></li>'; | |
| } | |
| // Get the number of pages | |
| $number_of_pages = ceil($feed_items / $this->count); | |
| // Put the current page at the center of the pagination items | |
| $start_pagination = $current_page - 5; | |
| // Or make it the first item if its within the first 5 items | |
| if ($start_pagination <= 0) { | |
| $start_pagination = 1; | |
| } | |
| // Add the numerical links | |
| for ($i = $start_pagination; $i <= $start_pagination + 9; $i++) { | |
| $active = ""; | |
| if ($current_page == $i) { | |
| $active = ' class="active"'; | |
| } | |
| $url_queries['page'] = $i; | |
| $links[] = '<li'. $active .'><a aria-label="Previous" href="' . $url_path . http_build_query($url_queries) . '">' . $i . '</a></li>'; | |
| if ($i >= $number_of_pages) { | |
| break; | |
| } | |
| } | |
| // Add the next page link if needed | |
| $next_page = $current_page + 1; | |
| if (!empty($feed_items) && $next_page <= $number_of_pages) { | |
| $url_queries['page'] = $next_page; | |
| $links[] = '<li><a aria-label="Next" href="' . $url_path . http_build_query($url_queries). '"><span aria-hidden="true">»</span></a></li>'; | |
| } | |
| return '<nav aria-label="Page navigation"><ul class="pagination">' . implode($links) . '</ul></nav>'; | |
| } | |
| /** | |
| * Parse the Feed | |
| * | |
| * @return boolean | |
| */ | |
| private function _parseFeeds() { | |
| $feeds = $this->_getFeeds(); | |
| if (empty($feeds)) { | |
| return FALSE; | |
| } | |
| $count = 0; | |
| foreach ($feeds as $feed) { | |
| $start_range = 0; | |
| $page = $this->getPage(); | |
| if (!empty($page) && $page > 1) { | |
| $start_range = ($page - 1) * $this->count; | |
| } | |
| if (isset($feed) && $feed != FALSE) { | |
| foreach ($feed->channel->item as $item) { | |
| // Skip the items that are part of the previous page | |
| if ($count < $start_range) { | |
| $count++; | |
| continue; | |
| } | |
| // Break if we have enough feed items in the array | |
| if (count($this->items) >= $this->count) { | |
| break; | |
| } | |
| if ($this->getPressRelease() && $item->pressrelease != 1) { | |
| continue; | |
| } | |
| $date = strtotime((string) $item->pubDate); | |
| $date = date($this->getDateFormat(), $date); | |
| $description = (string) strip_tags($item->description); | |
| if (strlen($description) > $this->getLimit()) { | |
| $description = substr($description, 0, $this->limit); | |
| $description .= "..."; | |
| } | |
| $item_array = array( | |
| 'title' => (string) $item->title, | |
| 'description' => $description, | |
| 'link' => (string) $item->link, | |
| 'date' => $date | |
| ); | |
| $this->items[] = $item_array; | |
| } | |
| } | |
| } | |
| if (!empty($this->items)) { | |
| return TRUE; | |
| } | |
| return FALSE; | |
| } | |
| /** | |
| * Set the feeds based on the path | |
| */ | |
| private function _setFeeds($path = "") { | |
| if (empty($path)) { | |
| return FALSE; | |
| } | |
| $feed = simplexml_load_file($path); | |
| if (empty($feed)) { | |
| return FALSE; | |
| } | |
| $this->feeds[] = $feed; | |
| } | |
| /** | |
| * Get the feeds | |
| * | |
| * @return array | |
| */ | |
| private function _getFeeds() { | |
| return $this->feeds; | |
| } | |
| } |