From e6ff532bbccbde0dd79b65ed9c6db9ad3c9b1185 Mon Sep 17 00:00:00 2001 From: GodMod Date: Fri, 28 Dec 2018 08:46:42 +0100 Subject: [PATCH] Updates RSS module --- language/english.php | 24 +-- language/german.php | 16 +- rssfeed_portal.class.php | 130 ++++++++------- rssfeed_rss.class.php | 336 +++++++++++++++++++++++++++++++++++++++ update.php | 29 ++++ 5 files changed, 449 insertions(+), 86 deletions(-) create mode 100644 rssfeed_rss.class.php create mode 100644 update.php diff --git a/language/english.php b/language/english.php index c04b5c6..f61a076 100644 --- a/language/english.php +++ b/language/english.php @@ -19,26 +19,26 @@ * along with this program. If not, see . */ - + if (!defined('EQDKP_INC')) { die('You cannot access this file directly.'); } -//Language: English +//Language: English //Created by EQdkp Plus Translation Tool on 2014-12-17 23:17 //File: portal/rssfeed/language/english.php //Source-Language: german -$lang = array( - "rssfeed" => 'RSS Feeds', - "rssfeed_name" => 'RSS Feed Module', - "rssfeed_desc" => 'Shows an RSS Feed in portal', - "rssfeed_f_limit" => 'Amount of feed items to show', - "rssfeed_f_url" => 'URL of the RSS Feed', - "pk_rssfeed_nourl" => 'Please setup a Feed first', - "rssfeed_f_length" => 'Number of chars that should be displayed from the text', - "rssfeed_f_help_length" => 'If the feed-module becomes extreme wide, the problem may be a destroyed HTML-Tag, because of the limited characters. If there are many characters without a white-space in that tag, there will be no new line and so the whole left-column becomes very wide.', - +$lang = array( + "rssfeed" => 'RSS Feeds', + "rssfeed_name" => 'RSS Feed Module', + "rssfeed_desc" => 'Shows an RSS Feed in portal', + "rssfeed_f_limit" => 'Amount of feed items to show', + "rssfeed_f_url" => 'URL of the RSS Feed', + "pk_rssfeed_nourl" => 'Please setup a Feed first', + "rssfeed_f_length" => 'Number of chars that should be displayed from the text', + "rssfeed_f_help_length" => 'If the feed-module becomes extreme wide, the problem may be a destroyed HTML-Tag, because of the limited characters. If there are many characters without a white-space in that tag, there will be no new line and so the whole left-column becomes very wide.', + 'rssfeed_f_layout' => 'Layout', ); ?> \ No newline at end of file diff --git a/language/german.php b/language/german.php index ba7c97d..7553717 100644 --- a/language/german.php +++ b/language/german.php @@ -24,13 +24,13 @@ } $lang = array( - 'rssfeed' => 'RSS Feeds', - 'rssfeed_name' => 'RSS Feed Module', - 'rssfeed_desc' => 'Zeigt einen RSS Feed im Portal an', - 'rssfeed_f_limit' => 'Anzahl der Feedeinträge zur Anzeige', - 'rssfeed_f_url' => 'URL des RSS Feeds', - 'pk_rssfeed_nourl' => 'Es wurde kein Feed angegeben', - 'rssfeed_f_length' => 'Anzahl Zeichen vom Feed zur Anzeige', - 'rssfeed_f_help_length' => 'Wenn das Feed-Modul extrem breit wird, liegt es unter Umständen daran, dass durch die Anzahl Zeichen ein HTML-Tag zerstört wird. Wenn in dem Tag sehr viele Zeichen stehen, kann kein Zeilenumbruch erfolgen und die linke Spalte wird sehr breit.', + 'rssfeed' => 'RSS Feeds', + 'rssfeed_name' => 'RSS Feed Module', + 'rssfeed_desc' => 'Zeigt einen RSS Feed im Portal an', + 'rssfeed_f_limit' => 'Anzahl der Feedeinträge zur Anzeige', + 'rssfeed_f_url' => 'URL des RSS Feeds', + 'pk_rssfeed_nourl' => 'Es wurde kein Feed angegeben', + 'rssfeed_f_length' => 'Anzahl Zeichen vom Feed zur Anzeige', + 'rssfeed_f_layout' => 'Darstellung', ); ?> \ No newline at end of file diff --git a/rssfeed_portal.class.php b/rssfeed_portal.class.php index 7e42e2a..90e1ad8 100644 --- a/rssfeed_portal.class.php +++ b/rssfeed_portal.class.php @@ -1,9 +1,9 @@ 'RSS Feed', - 'version' => '3.0.0', - 'author' => 'WalleniuM', - 'icon' => 'fa-rss-square', - 'contact' => EQDKP_PROJECT_URL, - 'description' => 'Shows an RSS Feed in portal', - 'lang_prefix' => 'rssfeed_' + 'name' => 'RSS Feed', + 'version' => '4.0.0', + 'author' => 'GodMod', + 'icon' => 'fa-rss-square', + 'contact' => EQDKP_PROJECT_URL, + 'description' => 'Shows an RSS Feed in portal', + 'lang_prefix' => 'rssfeed_', + 'multiple' => true, ); protected static $positions = array('left1', 'left2', 'right'); protected $settings = array( - 'url' => array( - 'type' => 'text', - 'size' => '40', - ), - 'limit' => array( - 'type' => 'text', - 'size' => '5', - ), - 'length' => array( - 'type' => 'text', - 'size' => '3', - ) + 'url' => array( + 'type' => 'text', + 'size' => '40', + ), + 'limit' => array( + 'type' => 'text', + 'size' => '5', + ), + 'length' => array( + 'type' => 'text', + 'size' => '3', + ), + 'layout' => array( + 'type' => 'dropdown', + 'options' => array('direct' => 'Direct', 'accordion' => 'Accordion'), + ) ); protected static $install = array( - 'autoenable' => '1', - 'defaultposition' => 'left2', - 'defaultnumber' => '9', + 'autoenable' => '1', + 'defaultposition' => 'left2', + 'defaultnumber' => '9', ); protected static $apiLevel = 20; public function output() { - if($this->config('url')){ - $pk_rssfeed_limit = ($this->config('limit')) ? $this->config('limit') : 5; - $pk_rssfeed_length = ($this->config('length')) ? $this->config('length') : 80; - $this->tpl->add_css(" - #rssfeed_module{ - margin:0; - padding:5px; - height:200px; - overflow: auto; - } - #rssfeed_module a { - color:#FF9900; - margin-bottom: 3px; - } - #rssfeed_module .rss_readmore{ - font-size:10px; - margin-bottom: 5px; - } - #rssfeed_module .date{ - color:#999999; - font-size:9px; - margin: 3px 0 3px 0; - } - #rssfeed_module .description{ - margin:0; - padding:0; - } - #rssfeed_module .description p { - font-size:10px; - } - .mf-viral {display:none;} - .loading{ - margin:25% 0% 0% 25%; - float:left; - }"); - $output = '
'; - - // JS Part - $this->jquery->rssFeeder('rssfeed_module', $this->server_path."portal/rssfeed/load.php".$this->SID."&loadrss=true&moduleid=".$this->id, $pk_rssfeed_limit, $pk_rssfeed_length); - }else{ - $output = $this->user->lang('pk_rssfeed_nourl'); + //Calculate Max Width + if($this->user->style['column_left_width'] != ""){ + if(strpos($this->user->style['column_left_width'], 'px') !== false){ + $max_width = (intval($this->user->style['column_left_width']) - 30).'px'; + } else { + $max_width = '97%'; + } + + } else { + $max_width = "180px"; } + + $this->tpl->add_css( + '.rssfeed_portal .ui-accordion .ui-accordion-content { + padding: 4px; + } + + .rssfeed-wrapper { + height:250px; + overflow: auto; + } + + .rssfeed-content { + max-width: '.$max_width.'; + word-wrap:break-word; + padding-top: 5px; + } + + ' + ); + + include_once($this->root_path .'portal/rssfeed/rssfeed_rss.class.php'); + $class = registry::register('rssfeed_rss', array($this->id)); + $output = $class->output; + return $output; } } -?> +?> \ No newline at end of file diff --git a/rssfeed_rss.class.php b/rssfeed_rss.class.php new file mode 100644 index 0000000..304417f --- /dev/null +++ b/rssfeed_rss.class.php @@ -0,0 +1,336 @@ +. + */ + +if ( !defined('EQDKP_INC') ){ + header('HTTP/1.0 404 Not Found');exit; +} + +class rssfeed_rss extends gen_class { + public static $shortcuts = array('puf'=>'urlfetcher'); + + //Config + var $cachetime = 600; + var $checkURL_first = true ; + var $blnWideContent = false; + var $moduleID = 0; + var $count = 5; + + //return vars + var $title = null; + var $link = null; + var $description = null; + var $lastcreate = null; + var $feed = null; + var $news = null; + var $updated = null; + var $header = ''; + var $output_left = ''; + var $rssurl = false; + + + /** + * Constructor + * + */ + public function __construct($intModuleID){ + + $this->output = 'RSS Feed not available.'; + + $this->moduleID = $intModuleID; + + $this->count = $this->config->get('limit', 'pmod_'.$this->moduleID); + $this->rssurl = $this->config->get('url', 'pmod_'.$this->moduleID); + $this->layout = $this->config->get('layout', 'pmod_'.$this->moduleID); + $this->length = $this->config->get('length', 'pmod_'.$this->moduleID); + + $this->parseXML($this->GetRSS($this->rssurl)); + if ($this->news){ + $this->createOutput(); + } + } + + /** + * GetRSS get the RSS Feed from an given URL + * Check if an refresh is needed + * + * @param String $url must be an valid RSS Feed + * @return String + */ + private function GetRSS($url){ + $rss_string = $this->pdc->get('portal.rssfeed.rss.'.$this->moduleID); + if ($rss_string == null) { + //nothing cached or expired + $this->tpl->add_js('$.get("'.$this->server_path.'portal/rssfeed/update.php'.$this->SID.'&mid='.$this->moduleID.'");'); + //Is there some expired data? + $expiredData = $this->pdc->get('portal.rssfeed.rss.'.$this->moduleID, false, false, true); + $rss_string = ($expiredData != null) ? $expiredData : ""; + } + + return $this->decodeRSS($rss_string); + } + + public function updateRSS(){ + $this->puf->checkURL_first = $this->checkURL_first; + $rss_string = $this->puf->fetch($this->rssurl); + $rss_string = is_utf8($rss_string) ? $rss_string : utf8_encode($rss_string); + if ($rss_string && strlen($rss_string)>1){ + $this->pdc->put('portal.rssfeed.rss.'.$this->moduleID, @base64_encode($rss_string), $this->cachetime); + } else { + $this->pdc->put('portal.rssfeed.rss.'.$this->moduleID, "", $this->cachetime); + } + } + + private function decodeRSS($rss){ + if (!strlen($rss)) return ''; + $rss_string = @base64_decode($rss); + return $rss_string; + } + + /** + * parseXML + * parse the XML Data into an Array + * + * @param RSS-XML $rss + */ + private function parseXML($strContent){ + try{ + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->preserveWhiteSpace = false; + + $document->loadXML($strContent); + + $xpath = new \DOMXPath($document); + + if($document->documentElement !== null && $document->documentElement !== false && is_object($document->documentElement)){ + $namespace = $document->documentElement->getAttribute('xmlns'); + $xpath->registerNamespace('ns', $namespace); + } else { + + return; + } + + $rootNode = $xpath->query('/*')->item(0); + + if ($rootNode === null) { + return; + } + + if ($rootNode->nodeName == 'feed') { + $data = $this->readAtomFeed($xpath); + } else if ($rootNode->nodeName == 'rss') { + $data = $this->readRssFeed($xpath); + } else { + return; + } + + if (empty($data)) return; + + $this->news = $data; + + } catch(Exception $e){ + + } + + } # end function + + public function createOutput(){ + if (is_array($this->news)){ + + if($this->layout == 'accordion'){ + $newstick_array = array(); + + foreach ($this->news as $key => $value){ + + // Generate an array fo an accordion + // array style: title => content + $newstick_array[(string)$value['title']] = $this->createBody( + $value['description'], + $value['link'], + $value['time'] + ); + + }# end foreach + + $this->output = '
'.$this->jquery->accordion('rssfeed_'.$this->moduleID,$newstick_array).'
'; + } else { + $table = '
'; + + foreach ($this->news as $key => $value){ + $desc = ($this->length != "") ? truncate($value['description'], $this->length, '…', false) : $value['description']; + + $table .= '
'; + $table .= '

'.sanitize($value['title']).'

'; + $table .= '
'.$this->time->user_date($value['time'], true).'
'; + $table .= ''; + $table .= '
'; + } + + $table .= '
'; + + $this->output = $table; + } + + + + } + } + + /** + * createBody + * + * @param String $disc + * @param String $author + * @param String $date + * @return String + */ + private function createBody($desc, $link, $date=""){ + $desc = ($this->length != "") ? truncate($desc, $this->length, '…', false) : $desc; + + $content = ''.sanitize($desc).''; + $footer = '
'.$this->time->user_date($date, true).'
'; + return $content.'
'.$footer; + } + + protected function readAtomFeed($xpath) { + // get items + $items = $xpath->query('//ns:entry'); + $data = array(); + $i = 0; + foreach ($items as $item) { + $strAlternateLink = ""; + $childNodes = $xpath->query('child::*', $item); + $itemData = array(); + foreach ($childNodes as $childNode) { + // && $childNode->getAttribute('rel') == 'alternate' + if($childNode->nodeName == 'link'){ + $rel = $childNode->getAttribute('rel'); + if($rel && $rel != "" && $rel == 'alternate'){ + $strAlternateLink = $childNode->getAttribute('href'); + } elseif(!$rel || $rel == ''){ + if($strAlternateLink == "") $strAlternateLink = $childNode->getAttribute('href'); + } + } else { + $itemData[$childNode->nodeName] = $childNode->nodeValue; + } + } + + // validate item data + if (empty($itemData['title']) || empty($itemData['id']) || (empty($itemData['content']) && empty($itemData['summary']))) { + continue; + } + + $hash = sha1($itemData['id']); + if (isset($itemData['published'])) { + $time = strtotime($itemData['published']); + if ($time > $this->time->time) continue; + } elseif(isset($itemData['updated'])) { + $time = strtotime($itemData['updated']); + if ($time > $this->time->time) continue; + } else { + $time = $this->time->time; + } + + if (!empty($itemData['textContent'])) { + $description = $itemData['textContent']; + }elseif (!empty($itemData['content'])) { + $description = $itemData['content']; + } else { + $description = $itemData['summary']; + } + + // get data + $data[$hash] = array( + 'title' => $itemData['title'], + 'link' => (strlen($strAlternateLink)) ? $strAlternateLink : $itemData['id'], + 'description' => strip_tags($description), + 'time' => $time, + 'hash' => $hash, + ); + + // check max results + $i++; + if ($i == $this->count) { + break; + } + } + + return $data; + } + + protected function readRssFeed($xpath) { + // get items + $items = $xpath->query('//channel/item'); + $data = array(); + $i = 0; + foreach ($items as $item) { + $childNodes = $xpath->query('child::*', $item); + $itemData = array(); + foreach ($childNodes as $childNode) { + if ($childNode->nodeName != 'category') { + $itemData[$childNode->nodeName] = $childNode->nodeValue; + } + } + + // validate item data + if (empty($itemData['title']) || empty($itemData['link']) || (empty($itemData['description']) && empty($itemData['content:encoded']))) { + continue; + } + if (!empty($itemData['guid'])) { + $hash = sha1($itemData['guid']); + } + else { + $hash = sha1($itemData['link']); + } + if (isset($itemData['pubDate'])) { + $time = strtotime($itemData['pubDate']); + if ($time > $this->time->time) continue; + } + else { + $time = $this->time->time; + } + + + if(!empty($itemData['description'])){ + $description = strip_tags($itemData['description']); + } elseif(!empty($itemData['content:encoded'])){ + $description = strip_tags($itemData['content:encoded']); + } + + // get data + $data[$hash] = array( + 'title' => $itemData['title'], + 'link' => $itemData['link'], + 'description' => $description, + 'time' => $time, + 'hash' => $hash, + ); + + // check max results + $i++; + if ($i == $this->count) { + break; + } + } + + return $data; + } +} +?> diff --git a/update.php b/update.php new file mode 100644 index 0000000..c958582 --- /dev/null +++ b/update.php @@ -0,0 +1,29 @@ +. + */ + +define('EQDKP_INC', true); + +$eqdkp_root_path = './../../'; +include_once($eqdkp_root_path.'common.php'); +include_once($eqdkp_root_path . 'portal/rssfeed/rssfeed_rss.class.php'); +$rssfeed = registry::register('rssfeed_rss', array(registry::register('input')->get('mid'))); +$rssfeed->updateRSS(); +?> \ No newline at end of file