diff options
| author | 2018-06-16 09:59:46 +0200 | |
|---|---|---|
| committer | 2018-06-16 09:59:46 +0200 | |
| commit | 3306a1679c2570c30d4b662c887b4a71ce147398 (patch) | |
| tree | 35fb1616c1166723676c789d6127a98db3260148 /app/Models | |
| parent | c0122003fe3031926546012b86a38b5187082613 (diff) | |
| parent | 8fcacc8cf41c14dd7d9712329d75ff4f041f3caf (diff) | |
Merge pull request #1921 from FreshRSS/dev1.11.1
FreshRSS 1.11.1
Diffstat (limited to 'app/Models')
| -rw-r--r-- | app/Models/Entry.php | 101 | ||||
| -rw-r--r-- | app/Models/EntryDAO.php | 17 | ||||
| -rw-r--r-- | app/Models/Feed.php | 72 |
3 files changed, 152 insertions, 38 deletions
diff --git a/app/Models/Entry.php b/app/Models/Entry.php index c6b26a7cc..2b6059638 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -17,10 +17,11 @@ class FreshRSS_Entry extends Minz_Model { private $hash = null; private $is_read; //Nullable boolean private $is_favorite; + private $feedId; private $feed; private $tags; - public function __construct($feed = '', $guid = '', $title = '', $author = '', $content = '', + public function __construct($feedId = '', $guid = '', $title = '', $author = '', $content = '', $link = '', $pubdate = 0, $is_read = false, $is_favorite = false, $tags = '') { $this->_title($title); $this->_author($author); @@ -29,7 +30,7 @@ class FreshRSS_Entry extends Minz_Model { $this->_date($pubdate); $this->_isRead($is_read); $this->_isFavorite($is_favorite); - $this->_feed($feed); + $this->_feedId($feedId); $this->_tags(preg_split('/[\s#]/', $tags)); $this->_guid($guid); } @@ -75,10 +76,13 @@ class FreshRSS_Entry extends Minz_Model { } public function feed($object = false) { if ($object) { - $feedDAO = FreshRSS_Factory::createFeedDao(); - return $feedDAO->searchById($this->feed); - } else { + if ($this->feed == null) { + $feedDAO = FreshRSS_Factory::createFeedDao(); + $this->feed = $feedDAO->searchById($this->feedId); + } return $this->feed; + } else { + return $this->feedId; } } public function tags($inString = false) { @@ -145,7 +149,14 @@ class FreshRSS_Entry extends Minz_Model { $this->is_favorite = $value; } public function _feed($value) { - $this->feed = $value; + if ($value != null) { + $this->feed = $value; + $this->feedId = $this->feed->id(); + } + } + private function _feedId($value) { + $this->feed = null; + $this->feedId = $value; } public function _tags($value) { $this->hash = null; @@ -179,12 +190,74 @@ class FreshRSS_Entry extends Minz_Model { } } - public function loadCompleteContent($pathEntries) { + private static function get_content_by_parsing($url, $path, $attributes = array()) { + require_once(LIB_PATH . '/lib_phpQuery.php'); + $system_conf = Minz_Configuration::get('system'); + $limits = $system_conf->limits; + $feed_timeout = empty($attributes['timeout']) ? 0 : intval($attributes['timeout']); + + if ($system_conf->simplepie_syslog_enabled) { + syslog(LOG_INFO, 'FreshRSS GET ' . SimplePie_Misc::url_remove_credentials($url)); + } + + $ch = curl_init(); + curl_setopt_array($ch, array( + CURLOPT_URL => $url, + CURLOPT_REFERER => SimplePie_Misc::url_remove_credentials($url), + CURLOPT_HTTPHEADER => array('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'), + CURLOPT_USERAGENT => FRESHRSS_USERAGENT, + CURLOPT_CONNECTTIMEOUT => $feed_timeout > 0 ? $feed_timeout : $limits['timeout'], + CURLOPT_TIMEOUT => $feed_timeout > 0 ? $feed_timeout : $limits['timeout'], + //CURLOPT_FAILONERROR => true; + CURLOPT_MAXREDIRS => 4, + CURLOPT_RETURNTRANSFER => true, + )); + if (version_compare(PHP_VERSION, '5.6.0') >= 0 || ini_get('open_basedir') == '') { + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //Keep option separated for open_basedir PHP bug 65646 + } + if (defined('CURLOPT_ENCODING')) { + curl_setopt($ch, CURLOPT_ENCODING, ''); //Enable all encodings + } + curl_setopt_array($ch, $system_conf->curl_options); + if (isset($attributes['ssl_verify'])) { + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $attributes['ssl_verify'] ? 2 : 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $attributes['ssl_verify'] ? true : false); + } + $html = curl_exec($ch); + $c_status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $c_error = curl_error($ch); + curl_close($ch); + + if ($c_status != 200 || $c_error != '') { + Minz_Log::warning('Error fetching content: HTTP code ' . $c_status . ': ' . $c_error . ' ' . $url); + } + + if ($html) { + $doc = phpQuery::newDocument($html); + $content = $doc->find($path); + + foreach (pq('img[data-src]') as $img) { + $imgP = pq($img); + $dataSrc = $imgP->attr('data-src'); + if (strlen($dataSrc) > 4) { + $imgP->attr('src', $dataSrc); + $imgP->removeAttr('data-src'); + } + } + + return trim(sanitizeHTML($content->__toString(), $url)); + } else { + throw new Exception(); + } + } + + public function loadCompleteContent() { // Gestion du contenu // On cherche à récupérer les articles en entier... même si le flux ne le propose pas - if ($pathEntries) { + $feed = $this->feed(true); + if ($feed != null && trim($feed->pathEntries()) != '') { $entryDAO = FreshRSS_Factory::createEntryDao(); - $entry = $entryDAO->searchByGuid($this->feed, $this->guid); + $entry = $entryDAO->searchByGuid($this->feedId, $this->guid); if ($entry) { // l'article existe déjà en BDD, en se contente de recharger ce contenu @@ -192,10 +265,14 @@ class FreshRSS_Entry extends Minz_Model { } else { try { // l'article n'est pas en BDD, on va le chercher sur le site - $this->content = get_content_by_parsing( - htmlspecialchars_decode($this->link(), ENT_QUOTES), $pathEntries, - $this->feed->attributes() + $fullContent = self::get_content_by_parsing( + htmlspecialchars_decode($this->link(), ENT_QUOTES), + $feed->pathEntries(), + $feed->attributes() ); + if ($fullContent != '') { + $this->content = $fullContent; + } } catch (Exception $e) { // rien à faire, on garde l'ancien contenu(requête a échoué) Minz_Log::warning($e->getMessage()); diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index a3bca3727..59f826c3e 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -904,8 +904,8 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { } public function countUnreadRead() { - $sql = 'SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id WHERE priority > 0' - . ' UNION SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id WHERE priority > 0 AND is_read=0'; + $sql = 'SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id WHERE f.priority > 0' + . ' UNION SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id WHERE f.priority > 0 AND e.is_read=0'; $stm = $this->bd->prepare($sql); $stm->execute(); $res = $stm->fetchAll(PDO::FETCH_COLUMN, 0); @@ -914,9 +914,10 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { return array('all' => $all, 'unread' => $unread, 'read' => $all - $unread); } public function count($minPriority = null) { - $sql = 'SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id'; + $sql = 'SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e'; if ($minPriority !== null) { - $sql = ' WHERE priority > ' . intval($minPriority); + $sql .= ' INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id'; + $sql .= ' WHERE f.priority > ' . intval($minPriority); } $stm = $this->bd->prepare($sql); $stm->execute(); @@ -924,9 +925,13 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { return $res[0]; } public function countNotRead($minPriority = null) { - $sql = 'SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id WHERE is_read=0'; + $sql = 'SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e'; if ($minPriority !== null) { - $sql = ' AND priority > ' . intval($minPriority); + $sql .= ' INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id'; + } + $sql .= ' WHERE e.is_read=0'; + if ($minPriority !== null) { + $sql .= ' AND f.priority > ' . intval($minPriority); } $stm = $this->bd->prepare($sql); $stm->execute(); diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 7eb079f15..89eb0a53c 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -286,6 +286,7 @@ class FreshRSS_Feed extends Minz_Model { if (!$loadDetails) { //Only activates auto-discovery when adding a new feed $feed->set_autodiscovery_level(SIMPLEPIE_LOCATOR_NONE); } + Minz_ExtensionManager::callHook('simplepie_before_init', $feed, $this); $mtime = $feed->init(); if ((!$mtime) || $feed->error()) { @@ -355,24 +356,52 @@ class FreshRSS_Feed extends Minz_Model { $content = html_only_entity_decode($item->get_content()); - $elinks = array(); - foreach ($item->get_enclosures() as $enclosure) { - $elink = $enclosure->get_link(); - if ($elink != '' && empty($elinks[$elink])) { - $elinks[$elink] = '1'; - $mime = strtolower($enclosure->get_type()); - if (strpos($mime, 'image/') === 0) { - $content .= '<p class="enclosure"><img src="' . $elink . '" alt="" /></p>'; - } elseif (strpos($mime, 'audio/') === 0) { - $content .= '<p class="enclosure"><audio preload="none" src="' . $elink - . '" controls="controls"></audio> <a download="" href="' . $elink . '">💾</a></p>'; - } elseif (strpos($mime, 'video/') === 0) { - $content .= '<p class="enclosure"><video preload="none" src="' . $elink - . '" controls="controls"></video> <a download="" href="' . $elink . '">💾</a></p>'; - } elseif (strpos($mime, 'application/') === 0 || strpos($mime, 'text/') === 0) { - $content .= '<p class="enclosure"><a download="" href="' . $elink . '">💾</a></p>'; - } else { - unset($elinks[$elink]); + if ($item->get_enclosures() != null) { + $elinks = array(); + foreach ($item->get_enclosures() as $enclosure) { + $elink = $enclosure->get_link(); + if ($elink != '' && empty($elinks[$elink])) { + $content .= '<div class="enclosure">'; + + if ($enclosure->get_title() != '') { + $content .= '<p class="enclosure-title">' . $enclosure->get_title() . '</p>'; + } + + $enclosureContent = ''; + $elinks[$elink] = true; + $mime = strtolower($enclosure->get_type()); + $medium = strtolower($enclosure->get_medium()); + if ($medium === 'image' || strpos($mime, 'image/') === 0) { + $enclosureContent .= '<p class="enclosure-content"><img src="' . $elink . '" alt="" /></p>'; + } elseif ($medium === 'audio' || strpos($mime, 'audio/') === 0) { + $enclosureContent .= '<p class="enclosure-content"><audio preload="none" src="' . $elink + . '" controls="controls"></audio> <a download="" href="' . $elink . '">💾</a></p>'; + } elseif ($medium === 'video' || strpos($mime, 'video/') === 0) { + $enclosureContent .= '<p class="enclosure-content"><video preload="none" src="' . $elink + . '" controls="controls"></video> <a download="" href="' . $elink . '">💾</a></p>'; + } elseif ($medium != '' || strpos($mime, 'application/') === 0 || strpos($mime, 'text/') === 0) { + $enclosureContent .= '<p class="enclosure-content"><a download="" href="' . $elink . '">💾</a></p>'; + } else { + unset($elinks[$elink]); + } + + $thumbnailContent = ''; + if ($enclosure->get_thumbnails() != null) { + foreach ($enclosure->get_thumbnails() as $thumbnail) { + if (empty($elinks[$thumbnail])) { + $elinks[$thumbnail] = true; + $thumbnailContent .= '<p><img class="enclosure-thumbnail" src="' . $thumbnail . '" alt="" /></p>'; + } + } + } + + $content .= $thumbnailContent; + $content .= $enclosureContent; + + if ($enclosure->get_description() != '') { + $content .= '<pre class="enclosure-description">' . $enclosure->get_description() . '</pre>'; + } + $content .= "</div>\n"; } } } @@ -391,8 +420,11 @@ class FreshRSS_Feed extends Minz_Model { $date ? $date : time() ); $entry->_tags($tags); - // permet de récupérer le contenu des flux tronqués - $entry->loadCompleteContent($this->pathEntries()); + $entry->_feed($this); + if ($this->pathEntries != '') { + // Optionally load full content for truncated feeds + $entry->loadCompleteContent(); + } $entries[] = $entry; unset($item); |
