@ -2,23 +2,27 @@
class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
public function isCompressed(): bool {
public static function isCompressed(): bool {
return true;
}
public function hasNativeHex(): bool {
public static function hasNativeHex(): bool {
return true;
}
public function sqlHexDecode(string $x): string {
protected static function sqlConcat($s1, $s2) {
return 'CONCAT(' . $s1 . ',' . $s2 . ')'; //MySQL
}
public static function sqlHexDecode(string $x): string {
return 'unhex(' . $x . ')';
}
public function sqlHexEncode(string $x): string {
public static function sqlHexEncode(string $x): string {
return 'hex(' . $x . ')';
}
public function sqlIgnoreConflict(string $sql): string {
public static function sqlIgnoreConflict(string $sql): string {
return str_replace('INSERT INTO ', 'INSERT IGNORE INTO ', $sql);
}
@ -90,14 +94,14 @@ SQL;
public function addEntry(array $valuesTmp, bool $useTmpTable = true) {
if ($this->addEntryPrepared == null) {
$sql = $this-> sqlIgnoreConflict(
$sql = static:: sqlIgnoreConflict(
'INSERT INTO `_' . ($useTmpTable ? 'entrytmp' : 'entry') . '` (id, guid, title, author, '
. ($this-> isCompressed() ? 'content_bin' : 'content')
. (static:: isCompressed() ? 'content_bin' : 'content')
. ', link, date, `lastSeen`, hash, is_read, is_favorite, id_feed, tags) '
. 'VALUES(:id, :guid, :title, :author, '
. ($this-> isCompressed() ? 'COMPRESS(:content)' : ':content')
. (static:: isCompressed() ? 'COMPRESS(:content)' : ':content')
. ', :link, :date, :last_seen, '
. $this-> sqlHexDecode(':hash')
. static:: sqlHexDecode(':hash')
. ', :is_read, :is_favorite, :id_feed, :tags)');
$this->addEntryPrepared = $this->pdo->prepare($sql);
}
@ -132,7 +136,7 @@ SQL;
$valuesTmp['tags'] = safe_utf8($valuesTmp['tags']);
$this->addEntryPrepared->bindParam(':tags', $valuesTmp['tags']);
if ($this-> hasNativeHex()) {
if (static:: hasNativeHex()) {
$this->addEntryPrepared->bindParam(':hash', $valuesTmp['hash']);
} else {
$valuesTmp['hashBin'] = hex2bin($valuesTmp['hash']);
@ -189,9 +193,9 @@ SQL;
if ($this->updateEntryPrepared === null) {
$sql = 'UPDATE `_entry` '
. 'SET title=:title, author=:author, '
. ($this-> isCompressed() ? 'content_bin=COMPRESS(:content)' : 'content=:content')
. (static:: isCompressed() ? 'content_bin=COMPRESS(:content)' : 'content=:content')
. ', link=:link, date=:date, `lastSeen`=:last_seen'
. ', hash=' . $this-> sqlHexDecode(':hash')
. ', hash=' . static:: sqlHexDecode(':hash')
. ', is_read=COALESCE(:is_read, is_read)'
. ', tags=:tags '
. 'WHERE id_feed=:id_feed AND guid=:guid';
@ -226,7 +230,7 @@ SQL;
$valuesTmp['tags'] = safe_utf8($valuesTmp['tags']);
$this->updateEntryPrepared->bindParam(':tags', $valuesTmp['tags']);
if ($this-> hasNativeHex()) {
if (static:: hasNativeHex()) {
$this->updateEntryPrepared->bindParam(':hash', $valuesTmp['hash']);
} else {
$valuesTmp['hashBin'] = hex2bin($valuesTmp['hash']);
@ -649,8 +653,8 @@ SQL;
public function selectAll() {
$sql = 'SELECT id, guid, title, author, '
. ($this-> isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
. ', link, date, `lastSeen`, ' . $this-> sqlHexEncode('hash') . ' AS hash, is_read, is_favorite, id_feed, tags '
. (static:: isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
. ', link, date, `lastSeen`, ' . static:: sqlHexEncode('hash') . ' AS hash, is_read, is_favorite, id_feed, tags '
. 'FROM `_entry`';
$stm = $this->pdo->query($sql);
while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
@ -662,7 +666,7 @@ SQL;
public function searchByGuid($id_feed, $guid) {
// un guid est unique pour un flux donné
$sql = 'SELECT id, guid, title, author, '
. ($this-> isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
. (static:: isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
. ', link, date, is_read, is_favorite, id_feed, tags '
. 'FROM `_entry` WHERE id_feed=:id_feed AND guid=:guid';
$stm = $this->pdo->prepare($sql);
@ -676,7 +680,7 @@ SQL;
/** @return FreshRSS_Entry|null */
public function searchById($id) {
$sql = 'SELECT id, guid, title, author, '
. ($this-> isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
. (static:: isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
. ', link, date, is_read, is_favorite, id_feed, tags '
. 'FROM `_entry` WHERE id=:id';
$stm = $this->pdo->prepare($sql);
@ -696,281 +700,301 @@ SQL;
return isset($res[0]) ? $res[0] : null;
}
protected function sqlConcat($s1, $s2) {
return 'CONCAT(' . $s1 . ',' . $s2 . ')'; //MySQL
}
/** @param FreshRSS_BooleanSearch $filters */
public static function sqlBooleanSearch(string $alias, $filters, int $level = 0) {
$search = '';
$values = [];
/**
* @param FreshRSS_BooleanSearch|null $filters
*/
protected function sqlListEntriesWhere(string $alias = '', $filters = null, int $state = FreshRSS_Entry::STATE_ALL,
string $order = 'DESC', string $firstId = '', int $date_min = 0) {
$search = ' ';
$values = array();
if ($state & FreshRSS_Entry::STATE_NOT_READ) {
if (!($state & FreshRSS_Entry::STATE_READ)) {
$search .= 'AND ' . $alias . 'is_read=0 ';
$isOpen = false;
foreach ($filters->searches() as $filter) {
if ($filter == null) {
continue;
}
} elseif ($state & FreshRSS_Entry::STATE_READ) {
$search .= 'AND ' . $alias . 'is_read=1 ';
}
if ($state & FreshRSS_Entry::STATE_FAVORITE) {
if (!($state & FreshRSS_Entry::STATE_NOT_FAVORITE)) {
$search .= 'AND ' . $alias . 'is_favorite=1 ';
}
} elseif ($state & FreshRSS_Entry::STATE_NOT_FAVORITE) {
$search .= 'AND ' . $alias . 'is_favorite=0 ';
}
switch ($order) {
case 'DESC':
case 'ASC':
break;
default:
throw new FreshRSS_EntriesGetter_Exception('Bad order in Entry->listByType: [' . $order . ']!');
}
if ($firstId !== '') {
$search .= 'AND ' . $alias . 'id ' . ($order === 'DESC' ? '< =' : '>=') . ' ? ';
$values[] = $firstId;
}
if ($date_min > 0) {
$search .= 'AND ' . $alias . 'id >= ? ';
$values[] = $date_min . '000000';
}
if ($filters & & count($filters->searches()) > 0) {
$isOpen = false;
foreach ($filters->searches() as $filter) {
if ($filter == null) {
continue;
if ($filter instanceof FreshRSS_BooleanSearch) {
// BooleanSearches are combined by AND (default) or OR (special case) operator and are recursive
list($filterValues, $filterSearch) = self::sqlBooleanSearch($alias, $filter, $level + 1);
$filterSearch = trim($filterSearch);
if ($filterSearch !== '') {
if ($search !== '') {
$search .= $filter->operator();
}
$search .= ' (' . $filterSearch . ') ';
$values = array_merge($values, $filterValues);
}
$sub_search = '';
if ($filter->getEntryIds()) {
foreach ($filter->getEntryIds() as $entry_ids) {
$sub_search .= 'AND ' . $alias . 'id IN (';
foreach ($entry_ids as $entry_id) {
$sub_search .= '?,';
$values[] = $entry_id;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ') ';
continue;
}
// Searches are combined by OR and are not recursive
$sub_search = '';
if ($filter->getEntryIds()) {
foreach ($filter->getEntryIds() as $entry_ids) {
$sub_search .= 'AND ' . $alias . 'id IN (';
foreach ($entry_ids as $entry_id) {
$sub_search .= '?,';
$values[] = $entry_id;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ') ';
}
if ($filter->getNotEntryIds()) {
foreach ($filter->getNotEntryIds() as $entry_ids) {
$sub_search .= 'AND ' . $alias . 'id NOT IN (';
foreach ($entry_ids as $entry_id) {
$sub_search .= '?,';
$values[] = $entry_id;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ') ';
}
if ($filter->getNotEntryIds()) {
foreach ($filter->getNotEntryIds() as $entry_ids) {
$sub_search .= 'AND ' . $alias . 'id NOT IN (';
foreach ($entry_ids as $entry_id) {
$sub_search .= '?,';
$values[] = $entry_id;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ') ';
}
}
if ($filter->getMinDate()) {
$sub_search .= 'AND ' . $alias . 'id >= ? ';
$values[] = "{$filter->getMinDate()}000000";
}
if ($filter->getMaxDate()) {
$sub_search .= 'AND ' . $alias . 'id < = ? ';
$values[] = "{$filter->getMaxDate()}000000";
}
if ($filter->getMinPubdate()) {
$sub_search .= 'AND ' . $alias . 'date >= ? ';
$values[] = $filter->getMinPubdate();
}
if ($filter->getMaxPubdate()) {
$sub_search .= 'AND ' . $alias . 'date < = ? ';
$values[] = $filter->getMaxPubdate();
}
if ($filter->getMinDate()) {
$sub_search .= 'AND ' . $alias . 'id >= ? ';
$values[] = "{$filter->getMinDate()}000000";
}
if ($filter->getMaxDate()) {
$sub_search .= 'AND ' . $alias . 'id < = ? ';
$values[] = "{$filter->getMaxDate()}000000";
}
if ($filter->getMinPubdate()) {
$sub_search .= 'AND ' . $alias . 'date >= ? ';
$values[] = $filter->getMinPubdate();
}
if ($filter->getMaxPubdate()) {
$sub_search .= 'AND ' . $alias . 'date < = ? ';
$values[] = $filter->getMaxPubdate();
}
//Negation of date intervals must be combined by OR
if ($filter->getNotMinDate() || $filter->getNotMaxDate()) {
$sub_search .= 'AND (';
if ($filter->getNotMinDate()) {
$sub_search .= $alias . 'id < ?';
$values[] = "{$filter->getNotMinDate()}000000";
if ($filter->getNotMaxDate()) {
$sub_search .= ' OR ';
}
}
//Negation of date intervals must be combined by OR
if ($filter->getNotMinDate() || $filter->getNotMaxDate()) {
$sub_search .= 'AND (';
if ($filter->getNotMinDate()) {
$sub_search .= $alias . 'id < ?';
$values[] = "{$filter->getNotMinDate()}000000";
if ($filter->getNotMaxDate()) {
$sub_search .= $alias . 'id > ?';
$values[] = "{$filter->getNotMaxDate()}000000";
$sub_search .= ' OR ';
}
$sub_search .= ') ';
}
if ($filter->getNotMinPubdate() || $filter->getNotMaxPubdate()) {
$sub_search .= 'AND (';
if ($filter->getNotMinPubdate()) {
$sub_search .= $alias . 'date < ?';
$values[] = $filter->getNotMinPubdate();
if ($filter->getNotMaxPubdate()) {
$sub_search .= ' OR ';
}
}
if ($filter->getNotMaxPubdate()) {
$sub_search .= $alias . 'date > ?';
$values[] = $filter->getNotMaxPubdate();
}
$sub_search .= ') ';
if ($filter->getNotMaxDate()) {
$sub_search .= $alias . 'id > ?';
$values[] = "{$filter->getNotMaxDate()}000000";
}
if ($filter->getFeedIds()) {
foreach ($filter->getFeedIds() as $feed_ids) {
$sub_search .= 'AND ' . $alias . 'id_feed IN (';
foreach ($feed_ids as $feed_id) {
$sub_search .= '?,';
$values[] = $feed_id;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ') ';
$sub_search .= ') ';
}
if ($filter->getNotMinPubdate() || $filter->getNotMaxPubdate()) {
$sub_search .= 'AND (';
if ($filter->getNotMinPubdate()) {
$sub_search .= $alias . 'date < ?';
$values[] = $filter->getNotMinPubdate();
if ($filter->getNotMaxPubdate()) {
$sub_search .= ' OR ';
}
}
if ($filter->getNotFeedIds()) {
foreach ($filter->getNotFeedIds() as $feed_ids) {
$sub_search .= 'AND ' . $alias . 'id_feed NOT IN (';
foreach ($feed_ids as $feed_id) {
$sub_search .= '?,';
$values[] = $feed_id;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ') ';
}
if ($filter->getNotMaxPubdate()) {
$sub_search .= $alias . 'date > ?';
$values[] = $filter->getNotMaxPubdate();
}
$sub_search .= ') ';
}
if ($filter->getLabelIds()) {
foreach ($filter->getLabelIds() as $label_ids) {
if ($label_ids === '*') {
$sub_search .= 'AND EXISTS (SELECT et.id_tag FROM `_entrytag` et WHERE et.id_entry = ' . $alias . 'id) ';
} else {
$sub_search .= 'AND ' . $alias . 'id IN (SELECT et.id_entry FROM `_entrytag` et WHERE et.id_tag IN (';
foreach ($label_ids as $label_id) {
$sub_search .= '?,';
$values[] = $label_id;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ')) ';
}
if ($filter->getFeedIds()) {
foreach ($filter->getFeedIds() as $feed_ids) {
$sub_search .= 'AND ' . $alias . 'id_feed IN (';
foreach ($feed_ids as $feed_id) {
$sub_search .= '?,';
$values[] = $feed_id;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ') ';
}
if ($filter->getNotLabelIds()) {
foreach ($filter->getNotLabelIds() as $label_ids) {
if ($label_ids === '*') {
$sub_search .= 'AND NOT EXISTS (SELECT et.id_tag FROM `_entrytag` et WHERE et.id_entry = ' . $alias . 'id) ';
} else {
$sub_search .= 'AND ' . $alias . 'id NOT IN (SELECT et.id_entry FROM `_entrytag` et WHERE et.id_tag IN (';
foreach ($label_ids as $label_id) {
$sub_search .= '?,';
$values[] = $label_id;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ')) ';
}
}
if ($filter->getNotFeedIds()) {
foreach ($filter->getNotFeedIds() as $feed_ids) {
$sub_search .= 'AND ' . $alias . 'id_feed NOT IN (';
foreach ($feed_ids as $feed_id) {
$sub_search .= '?,';
$values[] = $feed_id;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ') ';
}
}
if ($filter->getLabelNames()) {
foreach ($filter->getLabelNames() as $label_names) {
$sub_search .= 'AND ' . $alias . 'id IN (SELECT et.id_entry FROM `_entrytag` et, `_tag` t WHERE et.id_tag = t.id AND t.name IN (';
foreach ($label_names as $label_name) {
if ($filter->getLabelIds()) {
foreach ($filter->getLabelIds() as $label_ids) {
if ($label_ids === '*') {
$sub_search .= 'AND EXISTS (SELECT et.id_tag FROM `_entrytag` et WHERE et.id_entry = ' . $alias . 'id) ';
} else {
$sub_search .= 'AND ' . $alias . 'id IN (SELECT et.id_entry FROM `_entrytag` et WHERE et.id_tag IN (';
foreach ($label_ids as $label_id) {
$sub_search .= '?,';
$values[] = $label_name;
$values[] = $label_id ;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ')) ';
}
}
if ($filter->getNotLabelNames()) {
foreach ($filter->getNotLabelNames() as $label_names) {
$sub_search .= 'AND ' . $alias . 'id NOT IN (SELECT et.id_entry FROM `_entrytag` et, `_tag` t WHERE et.id_tag = t.id AND t.name IN (';
foreach ($label_names as $label_name) {
}
if ($filter->getNotLabelIds()) {
foreach ($filter->getNotLabelIds() as $label_ids) {
if ($label_ids === '*') {
$sub_search .= 'AND NOT EXISTS (SELECT et.id_tag FROM `_entrytag` et WHERE et.id_entry = ' . $alias . 'id) ';
} else {
$sub_search .= 'AND ' . $alias . 'id NOT IN (SELECT et.id_entry FROM `_entrytag` et WHERE et.id_tag IN (';
foreach ($label_ids as $label_id) {
$sub_search .= '?,';
$values[] = $label_name;
$values[] = $label_id ;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ')) ';
}
}
}
if ($filter->getAuthor()) {
foreach ($filter->getAuthor() as $author) {
$sub_search .= 'AND ' . $alias . 'author LIKE ? ';
$values[] = "%{$author}%";
if ($filter->getLabelNames()) {
foreach ($filter->getLabelNames() as $label_names) {
$sub_search .= 'AND ' . $alias . 'id IN (SELECT et.id_entry FROM `_entrytag` et, `_tag` t WHERE et.id_tag = t.id AND t.name IN (';
foreach ($label_names as $label_name) {
$sub_search .= '?,';
$values[] = $label_name;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ')) ';
}
if ($filter->getIntitle()) {
foreach ($filter->getIntitle() as $title) {
$sub_search .= 'AND ' . $alias . 'title LIKE ? ';
$values[] = "%{$title}%";
}
if ($filter->getNotLabelNames()) {
foreach ($filter->getNotLabelNames() as $label_names) {
$sub_search .= 'AND ' . $alias . 'id NOT IN (SELECT et.id_entry FROM `_entrytag` et, `_tag` t WHERE et.id_tag = t.id AND t.name IN (';
foreach ($label_names as $label_name) {
$sub_search .= '?,';
$values[] = $label_name;
}
$sub_search = rtrim($sub_search, ',');
$sub_search .= ')) ';
}
if ($filter->getTags()) {
foreach ($filter->getTags() as $tag) {
$sub_search .= 'AND ' . $alias . 'tags LIKE ? ';
$values[] = "%{$tag}%";
}
}
if ($filter->getAuthor()) {
foreach ($filter->getAuthor() as $author) {
$sub_search .= 'AND ' . $alias . 'author LIKE ? ';
$values[] = "%{$author}%";
}
if ($filter->getInurl()) {
foreach ($filter->getInurl() as $url ) {
$sub_search .= 'AND ' . $this->sqlConcat($alias . 'link', $alias . 'guid') . ' LIKE ? ';
$values[] = "%{$url}%" ;
}
}
if ($filter->getIntitle() ) {
foreach ($filter->getIntitle() as $title) {
$sub_search .= 'AND ' . $alias . 'title LIKE ? ' ;
$values[] = "%{$title }%";
}
}
if ($filter->getTags()) {
foreach ($filter->getTags() as $tag) {
$sub_search .= 'AND ' . $alias . 'tags LIKE ? ';
$values[] = "%{$tag}%";
}
}
if ($filter->getInurl()) {
foreach ($filter->getInurl() as $url) {
$sub_search .= 'AND ' . static::sqlConcat($alias . 'link', $alias . 'guid') . ' LIKE ? ';
$values[] = "%{$url}%";
}
}
if ($filter->getNotAuthor()) {
foreach ($filter->getNotAuthor() as $author) {
$sub_search .= 'AND (NOT ' . $alias . 'author LIKE ?) ';
$values[] = "%{$author}%";
}
if ($filter->getNotAuthor()) {
foreach ($filter->getNotAuthor() as $author) {
$sub_search .= 'AND (NOT ' . $alias . 'author LIKE ?) ';
$values[] = "%{$author}%";
}
if ($filter->getNotIntitle()) {
foreach ($filter->getNotIntitle() as $title) {
$sub_search .= 'AND (NOT ' . $alias . 'title LIKE ?) ';
$values[] = "%{$title}%";
}
}
if ($filter->getNotIntitle() ) {
foreach ($filter->getNotIntitle() as $title) {
$sub_search .= 'AND (NOT ' . $alias . 'title LIKE ?) ' ;
$values[] = "%{$title }%";
}
if ($filter->getNotTags()) {
foreach ($filter->getNotTags() as $tag ) {
$sub_search .= 'AND (NOT ' . $alias . 'tags LIKE ?) ';
$values[] = "%{$tag}%" ;
}
}
if ($filter->getNotTags() ) {
foreach ($filter->getNotTags() as $tag) {
$sub_search .= 'AND (NOT ' . $alias . 'tags LIKE ?) ' ;
$values[] = "%{$tag }%";
}
if ($filter->getNotInurl()) {
foreach ($filter->getNotInurl() as $url ) {
$sub_search .= 'AND (NOT ' . $this->sqlConcat($alias . 'link', $alias . 'guid') . ' LIKE ?) ';
$values[] = "%{$url}%" ;
}
}
if ($filter->getNotInurl() ) {
foreach ($filter->getNotInurl() as $url) {
$sub_search .= 'AND (NOT ' . static::sqlConcat($alias . 'link', $alias . 'guid') . ' LIKE ?) ' ;
$values[] = "%{$url }%";
}
}
if ($filter->getSearch()) {
foreach ($filter->getSearch() as $search_value) {
$sub_search .= 'AND ' . $this->sqlConcat($alias . 'title',
$this->isCompressed() ? 'UNCOMPRESS(' . $alias . 'content_bin)' : '' . $alias . 'content') . ' LIKE ? ';
$values[] = "%{$search_value}%";
}
if ($filter->getSearch()) {
foreach ($filter->getSearch() as $search_value) {
$sub_search .= 'AND ' . static::sqlConcat($alias . 'title',
static::isCompressed() ? 'UNCOMPRESS(' . $alias . 'content_bin)' : '' . $alias . 'content') . ' LIKE ? ';
$values[] = "%{$search_value}%";
}
if ($filter->getNotSearch()) {
foreach ($filter->getNotSearch() as $search_value ) {
$sub_search .= 'AND (NOT ' . $this->sqlConcat($alias . 'title',
$this->isCompressed() ? 'UNCOMPRESS(' . $alias . 'content_bin)' : '' . $alias . 'content') . ' LIKE ?) ';
$values[] = "%{$search_value}%" ;
}
}
if ($filter->getNotSearch() ) {
foreach ($filter->getNotSearch() as $search_value) {
$sub_search .= 'AND (NOT ' . static::sqlConcat($alias . 'title',
static::isCompressed() ? 'UNCOMPRESS(' . $alias . 'content_bin)' : '' . $alias . 'content') . ' LIKE ?) ' ;
$values[] = "%{$search_value }%";
}
}
if ($sub_search != '') {
if ($isOpen) {
$search .= 'OR ';
} else {
$search .= 'AND (';
$isOpen = true;
}
$search .= '(' . substr($sub_search, 4) . ') ';
if ($sub_search != '') {
if ($isOpen) {
$search .= ' OR ';
} else {
$isOpen = true;
}
// Remove superfluous leading 'AND '
$search .= '(' . substr($sub_search, 4) . ')';
}
if ($isOpen) {
$search .= ') ';
}
return [ $values, $search ];
}
/** @param FreshRSS_BooleanSearch|null $filters */
protected function sqlListEntriesWhere(string $alias = '', $filters = null, int $state = FreshRSS_Entry::STATE_ALL,
string $order = 'DESC', string $firstId = '', int $date_min = 0) {
$search = ' ';
$values = array();
if ($state & FreshRSS_Entry::STATE_NOT_READ) {
if (!($state & FreshRSS_Entry::STATE_READ)) {
$search .= 'AND ' . $alias . 'is_read=0 ';
}
} elseif ($state & FreshRSS_Entry::STATE_READ) {
$search .= 'AND ' . $alias . 'is_read=1 ';
}
if ($state & FreshRSS_Entry::STATE_FAVORITE) {
if (!($state & FreshRSS_Entry::STATE_NOT_FAVORITE)) {
$search .= 'AND ' . $alias . 'is_favorite=1 ';
}
} elseif ($state & FreshRSS_Entry::STATE_NOT_FAVORITE) {
$search .= 'AND ' . $alias . 'is_favorite=0 ';
}
switch ($order) {
case 'DESC':
case 'ASC':
break;
default:
throw new FreshRSS_EntriesGetter_Exception('Bad order in Entry->listByType: [' . $order . ']!');
}
if ($firstId !== '') {
$search .= 'AND ' . $alias . 'id ' . ($order === 'DESC' ? '< =' : '>=') . ' ? ';
$values[] = $firstId;
}
if ($date_min > 0) {
$search .= 'AND ' . $alias . 'id >= ? ';
$values[] = $date_min . '000000';
}
if ($filters & & count($filters->searches()) > 0) {
list($filterValues, $filterSearch) = self::sqlBooleanSearch($alias, $filters);
$filterSearch = trim($filterSearch);
if ($filterSearch !== '') {
$search .= 'AND (' . $filterSearch . ') ';
$values = array_merge($values, $filterValues);
}
}
return array($values, $search);
@ -1040,7 +1064,7 @@ SQL;
list($values, $sql) = $this->sqlListWhere($type, $id, $state, $order, $limit, $firstId, $filters, $date_min);
$sql = 'SELECT e0.id, e0.guid, e0.title, e0.author, '
. ($this-> isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
. (static:: isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
. ', e0.link, e0.date, e0.is_read, e0.is_favorite, e0.id_feed, e0.tags '
. 'FROM `_entry` e0 '
. 'INNER JOIN ('
@ -1085,7 +1109,7 @@ SQL;
}
$sql = 'SELECT id, guid, title, author, '
. ($this-> isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
. (static:: isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
. ', link, date, is_read, is_favorite, id_feed, tags '
. 'FROM `_entry` '
. 'WHERE id IN (' . str_repeat('?,', count($ids) - 1). '?) '
@ -1124,7 +1148,7 @@ SQL;
return $result;
}
$guids = array_unique($guids);
$sql = 'SELECT guid, ' . $this-> sqlHexEncode('hash') .
$sql = 'SELECT guid, ' . static:: sqlHexEncode('hash') .
' AS hex_hash FROM `_entry` WHERE id_feed=? AND guid IN (' . str_repeat('?,', count($guids) - 1). '?)';
$stm = $this->pdo->prepare($sql);
$values = array($id_feed);