mirror of
https://github.com/FreshRSS/FreshRSS.git
synced 2026-07-20 12:03:02 -04:00
Contribue à https://github.com/marienfressinaud/FreshRSS/issues/351#issuecomment-31755012 Les flux non-modifiés et en cache ne coûtent maintenant presque plus rien (304, ou délai de cache SimplePie non expiré), alors qu'avant toutes les entrées étaient rechargées
279 lines
7.0 KiB
PHP
279 lines
7.0 KiB
PHP
<?php
|
|
|
|
class FreshRSS_Feed extends Minz_Model {
|
|
private $id = 0;
|
|
private $url;
|
|
private $category = 1;
|
|
private $nbEntries = -1;
|
|
private $nbNotRead = -1;
|
|
private $entries = null;
|
|
private $name = '';
|
|
private $website = '';
|
|
private $description = '';
|
|
private $lastUpdate = 0;
|
|
private $priority = 10;
|
|
private $pathEntries = '';
|
|
private $httpAuth = '';
|
|
private $error = false;
|
|
private $keep_history = -2;
|
|
private $hash = null;
|
|
|
|
public function __construct ($url, $validate=true) {
|
|
if ($validate) {
|
|
$this->_url ($url);
|
|
} else {
|
|
$this->url = $url;
|
|
}
|
|
}
|
|
|
|
public function id () {
|
|
return $this->id;
|
|
}
|
|
|
|
public function hash() {
|
|
if ($this->hash === null) {
|
|
$this->hash = hash('crc32b', Minz_Configuration::salt() . $this->url);
|
|
}
|
|
return $this->hash;
|
|
}
|
|
|
|
public function url () {
|
|
return $this->url;
|
|
}
|
|
public function category () {
|
|
return $this->category;
|
|
}
|
|
public function entries () {
|
|
return $this->entries === null ? array() : $this->entries;
|
|
}
|
|
public function name () {
|
|
return $this->name;
|
|
}
|
|
public function website () {
|
|
return $this->website;
|
|
}
|
|
public function description () {
|
|
return $this->description;
|
|
}
|
|
public function lastUpdate () {
|
|
return $this->lastUpdate;
|
|
}
|
|
public function priority () {
|
|
return $this->priority;
|
|
}
|
|
public function pathEntries () {
|
|
return $this->pathEntries;
|
|
}
|
|
public function httpAuth ($raw = true) {
|
|
if ($raw) {
|
|
return $this->httpAuth;
|
|
} else {
|
|
$pos_colon = strpos ($this->httpAuth, ':');
|
|
$user = substr ($this->httpAuth, 0, $pos_colon);
|
|
$pass = substr ($this->httpAuth, $pos_colon + 1);
|
|
|
|
return array (
|
|
'username' => $user,
|
|
'password' => $pass
|
|
);
|
|
}
|
|
}
|
|
public function inError () {
|
|
return $this->error;
|
|
}
|
|
public function keepHistory () {
|
|
return $this->keep_history;
|
|
}
|
|
public function nbEntries () {
|
|
if ($this->nbEntries < 0) {
|
|
$feedDAO = new FreshRSS_FeedDAO ();
|
|
$this->nbEntries = $feedDAO->countEntries ($this->id ());
|
|
}
|
|
|
|
return $this->nbEntries;
|
|
}
|
|
public function nbNotRead () {
|
|
if ($this->nbNotRead < 0) {
|
|
$feedDAO = new FreshRSS_FeedDAO ();
|
|
$this->nbNotRead = $feedDAO->countNotRead ($this->id ());
|
|
}
|
|
|
|
return $this->nbNotRead;
|
|
}
|
|
public function faviconPrepare() {
|
|
$file = DATA_PATH . '/favicons/' . $this->hash() . '.txt';
|
|
if (!file_exists ($file)) {
|
|
$t = $this->website;
|
|
if (empty($t)) {
|
|
$t = $this->url;
|
|
}
|
|
file_put_contents($file, $t);
|
|
}
|
|
}
|
|
public static function faviconDelete($hash) {
|
|
$path = DATA_PATH . '/favicons/' . $hash;
|
|
@unlink($path . '.ico');
|
|
@unlink($path . '.txt');
|
|
}
|
|
public function favicon () {
|
|
return Minz_Url::display ('/f.php?' . $this->hash());
|
|
}
|
|
|
|
public function _id ($value) {
|
|
$this->id = $value;
|
|
}
|
|
public function _url ($value, $validate=true) {
|
|
if ($validate) {
|
|
$value = checkUrl($value);
|
|
}
|
|
if (empty ($value)) {
|
|
throw new FreshRSS_BadUrl_Exception ($value);
|
|
}
|
|
$this->url = $value;
|
|
}
|
|
public function _category ($value) {
|
|
$value = intval($value);
|
|
$this->category = $value >= 0 ? $value : 0;
|
|
}
|
|
public function _name ($value) {
|
|
$this->name = $value === null ? '' : $value;
|
|
}
|
|
public function _website ($value, $validate=true) {
|
|
if ($validate) {
|
|
$value = checkUrl($value);
|
|
}
|
|
if (empty ($value)) {
|
|
$value = '';
|
|
}
|
|
$this->website = $value;
|
|
}
|
|
public function _description ($value) {
|
|
$this->description = $value === null ? '' : $value;
|
|
}
|
|
public function _lastUpdate ($value) {
|
|
$this->lastUpdate = $value;
|
|
}
|
|
public function _priority ($value) {
|
|
$value = intval($value);
|
|
$this->priority = $value >= 0 ? $value : 10;
|
|
}
|
|
public function _pathEntries ($value) {
|
|
$this->pathEntries = $value;
|
|
}
|
|
public function _httpAuth ($value) {
|
|
$this->httpAuth = $value;
|
|
}
|
|
public function _error ($value) {
|
|
$this->error = (bool)$value;
|
|
}
|
|
public function _keepHistory ($value) {
|
|
$value = intval($value);
|
|
$value = min($value, 1000000);
|
|
$value = max($value, -2);
|
|
$this->keep_history = $value;
|
|
}
|
|
public function _nbNotRead ($value) {
|
|
$this->nbNotRead = intval($value);
|
|
}
|
|
public function _nbEntries ($value) {
|
|
$this->nbEntries = intval($value);
|
|
}
|
|
|
|
public function load ($loadDetails = false) {
|
|
if ($this->url !== null) {
|
|
if (CACHE_PATH === false) {
|
|
throw new Minz_FileNotExistException (
|
|
'CACHE_PATH',
|
|
Minz_Exception::ERROR
|
|
);
|
|
} else {
|
|
$url = htmlspecialchars_decode ($this->url, ENT_QUOTES);
|
|
if ($this->httpAuth != '') {
|
|
$url = preg_replace ('#((.+)://)(.+)#', '${1}' . $this->httpAuth . '@${3}', $url);
|
|
}
|
|
$feed = customSimplePie();
|
|
$feed->set_feed_url ($url);
|
|
$initResult = $feed->init ();
|
|
|
|
if ((!$initResult) || $feed->error()) {
|
|
throw new FreshRSS_Feed_Exception ($feed->error() . ' [' . $url . ']');
|
|
}
|
|
|
|
// si on a utilisé l'auto-discover, notre url va avoir changé
|
|
$subscribe_url = $feed->subscribe_url ();
|
|
if ($subscribe_url !== null && $subscribe_url !== $this->url) {
|
|
if ($this->httpAuth != '') {
|
|
// on enlève les id si authentification HTTP
|
|
$subscribe_url = preg_replace ('#((.+)://)((.+)@)(.+)#', '${1}${5}', $subscribe_url);
|
|
}
|
|
$this->_url ($subscribe_url);
|
|
}
|
|
|
|
if ($loadDetails) {
|
|
$title = htmlspecialchars(html_only_entity_decode($feed->get_title()), ENT_COMPAT, 'UTF-8');
|
|
$this->_name ($title === null ? $this->url : $title);
|
|
|
|
$this->_website(html_only_entity_decode($feed->get_link()));
|
|
$this->_description(html_only_entity_decode($feed->get_description()));
|
|
}
|
|
|
|
if (($initResult == SIMPLEPIE_INIT_SUCCESS) || $loadDetails) {
|
|
$this->loadEntries($feed); // et on charge les articles du flux
|
|
} else {
|
|
$this->entries = array();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private function loadEntries ($feed) {
|
|
$entries = array ();
|
|
|
|
foreach ($feed->get_items () as $item) {
|
|
$title = html_only_entity_decode (strip_tags ($item->get_title ()));
|
|
$author = $item->get_author ();
|
|
$link = $item->get_permalink ();
|
|
$date = @strtotime ($item->get_date ());
|
|
|
|
// gestion des tags (catégorie == tag)
|
|
$tags_tmp = $item->get_categories ();
|
|
$tags = array ();
|
|
if ($tags_tmp !== null) {
|
|
foreach ($tags_tmp as $tag) {
|
|
$tags[] = html_only_entity_decode ($tag->get_label ());
|
|
}
|
|
}
|
|
|
|
$content = html_only_entity_decode ($item->get_content ());
|
|
|
|
$elinks = array();
|
|
foreach ($item->get_enclosures() as $enclosure) {
|
|
$elink = $enclosure->get_link();
|
|
if (array_key_exists($elink, $elinks)) continue;
|
|
$elinks[$elink] = '1';
|
|
$mime = strtolower($enclosure->get_type());
|
|
if (strpos($mime, 'image/') === 0) {
|
|
$content .= '<br /><img src="' . $elink . '" alt="" />';
|
|
}
|
|
}
|
|
|
|
$entry = new FreshRSS_Entry (
|
|
$this->id (),
|
|
$item->get_id (),
|
|
$title === null ? '' : $title,
|
|
$author === null ? '' : html_only_entity_decode ($author->name),
|
|
$content === null ? '' : $content,
|
|
$link === null ? '' : $link,
|
|
$date ? $date : time ()
|
|
);
|
|
$entry->_tags ($tags);
|
|
// permet de récupérer le contenu des flux tronqués
|
|
$entry->loadCompleteContent($this->pathEntries());
|
|
|
|
$entries[] = $entry;
|
|
}
|
|
|
|
$this->entries = $entries;
|
|
}
|
|
}
|