2013-12-23 02:55:53 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Model\Item;
|
|
|
|
|
2014-12-24 16:47:24 +01:00
|
|
|
use Model\Service;
|
2014-05-20 20:20:27 +02:00
|
|
|
use Model\Config;
|
2015-08-05 01:01:21 +02:00
|
|
|
use Model\Group;
|
2014-02-08 20:13:14 +01:00
|
|
|
use PicoDb\Database;
|
2014-12-24 03:28:26 +01:00
|
|
|
use PicoFeed\Logging\Logger;
|
2015-04-28 18:08:42 +02:00
|
|
|
use PicoFeed\Scraper\Scraper;
|
2013-12-23 02:55:53 +01:00
|
|
|
|
2014-02-15 20:09:50 +01:00
|
|
|
// Get all items without filtering
|
2015-04-19 08:08:31 +02:00
|
|
|
function get_all()
|
2014-02-15 20:09:50 +01:00
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2014-02-15 20:09:50 +01:00
|
|
|
->table('items')
|
|
|
|
->columns(
|
|
|
|
'items.id',
|
|
|
|
'items.title',
|
|
|
|
'items.updated',
|
|
|
|
'items.url',
|
2014-02-17 19:41:22 +01:00
|
|
|
'items.enclosure',
|
2014-02-18 04:04:49 +01:00
|
|
|
'items.enclosure_type',
|
2014-02-15 20:09:50 +01:00
|
|
|
'items.bookmark',
|
|
|
|
'items.feed_id',
|
|
|
|
'items.status',
|
|
|
|
'items.content',
|
2014-03-17 02:35:57 +01:00
|
|
|
'items.language',
|
2014-02-15 20:09:50 +01:00
|
|
|
'feeds.site_url',
|
2014-10-20 01:14:33 +02:00
|
|
|
'feeds.title AS feed_title',
|
|
|
|
'feeds.rtl'
|
2014-02-15 20:09:50 +01:00
|
|
|
)
|
|
|
|
->join('feeds', 'id', 'feed_id')
|
|
|
|
->in('status', array('read', 'unread'))
|
|
|
|
->orderBy('updated', 'desc')
|
|
|
|
->findAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get everthing since date (timestamp)
|
2015-04-19 08:08:31 +02:00
|
|
|
function get_all_since($timestamp)
|
2014-02-15 20:09:50 +01:00
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2014-02-15 20:09:50 +01:00
|
|
|
->table('items')
|
|
|
|
->columns(
|
|
|
|
'items.id',
|
|
|
|
'items.title',
|
|
|
|
'items.updated',
|
|
|
|
'items.url',
|
2014-02-17 19:41:22 +01:00
|
|
|
'items.enclosure',
|
2014-02-18 04:04:49 +01:00
|
|
|
'items.enclosure_type',
|
2014-02-15 20:09:50 +01:00
|
|
|
'items.bookmark',
|
|
|
|
'items.feed_id',
|
|
|
|
'items.status',
|
|
|
|
'items.content',
|
2014-03-17 02:35:57 +01:00
|
|
|
'items.language',
|
2014-02-15 20:09:50 +01:00
|
|
|
'feeds.site_url',
|
2014-10-20 01:14:33 +02:00
|
|
|
'feeds.title AS feed_title',
|
|
|
|
'feeds.rtl'
|
2014-02-15 20:09:50 +01:00
|
|
|
)
|
|
|
|
->join('feeds', 'id', 'feed_id')
|
|
|
|
->in('status', array('read', 'unread'))
|
|
|
|
->gte('updated', $timestamp)
|
|
|
|
->orderBy('updated', 'desc')
|
|
|
|
->findAll();
|
|
|
|
}
|
|
|
|
|
2016-05-04 02:15:20 +02:00
|
|
|
function search_all($text, $offset = null, $limit = null)
|
|
|
|
{
|
|
|
|
return Database::getInstance('db')
|
|
|
|
->table('items')
|
|
|
|
->columns(
|
|
|
|
'items.id',
|
|
|
|
'items.title',
|
|
|
|
'items.updated',
|
|
|
|
'items.url',
|
|
|
|
'items.enclosure',
|
|
|
|
'items.enclosure_type',
|
|
|
|
'items.bookmark',
|
|
|
|
'items.feed_id',
|
|
|
|
'items.status',
|
|
|
|
'items.content',
|
|
|
|
'items.language',
|
|
|
|
'items.author',
|
|
|
|
'feeds.site_url',
|
|
|
|
'feeds.title AS feed_title',
|
|
|
|
'feeds.rtl'
|
|
|
|
)
|
|
|
|
->join('feeds', 'id', 'feed_id')
|
|
|
|
->neq('status', 'removed')
|
|
|
|
->ilike('items.title', '%' . $text . '%')
|
|
|
|
->orderBy('updated', 'desc')
|
|
|
|
->offset($offset)
|
|
|
|
->limit($limit)
|
|
|
|
->findAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
function count_by_search($text)
|
|
|
|
{
|
|
|
|
return Database::getInstance('db')
|
|
|
|
->table('items')
|
|
|
|
->neq('status', 'removed')
|
|
|
|
->ilike('title', '%' . $text . '%')
|
|
|
|
->count();
|
|
|
|
}
|
|
|
|
|
implement frontend autoupdate
Only the unread counter is updated right know.
The AutoUpdate Feature is designed on the premise of don't wasting resources. A
distinction is made between updates when Miniflux is visible or hidden.
To determine the visibility status, the Page Visibility API is used. The API is
available starting with Chrome 33, Firefox 18 and IE10. [https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API]
As IE9 returns an undefined, it doesn't break the compatibility at least.
If Miniflux is visible, the unread counter on the web page is updated as soon as
a mismatch between the counter and the number of unread articles in the database
is found.
If Miniflux is hidden, the timestamp of the most recent article from each feed
is compared with the value from the last run. We have an update If the timestamp
of the latest article is greater than the stored one and the latest article is
unread. The web page title is updated with a ? symbol to notify the user and the
update check pauses till Miniflux gets visible again. If Miniflux gets visible
again, the number of unread articles is queried from the database, the unread
counter on the web page is updated and finally the ? symbol is removed from the
web page title.
This way I can use my fever API client to read new articles (or at least the
latest article) while Miniflux is hidden and as I've seen the new articles
already a new articles notification is prevented.
It's intentionally that the page does not reload automatically as long as
articles are visible. If I'm in hurry, I only scroll through the articles to
spot something interesting. Most of the time I don't reach the last article.
If the page is reloaded while I'm away, I would have to scan from the top again.
If we're on a nothing_to_read page and have unread articles in the database, a
redirect to the unread page will be done.
The default update check interval is 10 minutes and can be changed on the
settings page. A zero value disables the update check entirely.
fixes #213
2014-11-27 22:36:04 +01:00
|
|
|
function get_latest_feeds_items()
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
implement frontend autoupdate
Only the unread counter is updated right know.
The AutoUpdate Feature is designed on the premise of don't wasting resources. A
distinction is made between updates when Miniflux is visible or hidden.
To determine the visibility status, the Page Visibility API is used. The API is
available starting with Chrome 33, Firefox 18 and IE10. [https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API]
As IE9 returns an undefined, it doesn't break the compatibility at least.
If Miniflux is visible, the unread counter on the web page is updated as soon as
a mismatch between the counter and the number of unread articles in the database
is found.
If Miniflux is hidden, the timestamp of the most recent article from each feed
is compared with the value from the last run. We have an update If the timestamp
of the latest article is greater than the stored one and the latest article is
unread. The web page title is updated with a ? symbol to notify the user and the
update check pauses till Miniflux gets visible again. If Miniflux gets visible
again, the number of unread articles is queried from the database, the unread
counter on the web page is updated and finally the ? symbol is removed from the
web page title.
This way I can use my fever API client to read new articles (or at least the
latest article) while Miniflux is hidden and as I've seen the new articles
already a new articles notification is prevented.
It's intentionally that the page does not reload automatically as long as
articles are visible. If I'm in hurry, I only scroll through the articles to
spot something interesting. Most of the time I don't reach the last article.
If the page is reloaded while I'm away, I would have to scan from the top again.
If we're on a nothing_to_read page and have unread articles in the database, a
redirect to the unread page will be done.
The default update check interval is 10 minutes and can be changed on the
settings page. A zero value disables the update check entirely.
fixes #213
2014-11-27 22:36:04 +01:00
|
|
|
->table('feeds')
|
|
|
|
->columns(
|
|
|
|
'feeds.id',
|
|
|
|
'MAX(items.updated) as updated',
|
|
|
|
'items.status'
|
|
|
|
)
|
|
|
|
->join('items', 'feed_id', 'id')
|
|
|
|
->groupBy('feeds.id')
|
|
|
|
->orderBy('feeds.id')
|
|
|
|
->findAll();
|
|
|
|
}
|
|
|
|
|
2014-02-15 20:09:50 +01:00
|
|
|
// Get a list of [item_id => status,...]
|
|
|
|
function get_all_status()
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2015-01-28 02:13:16 +01:00
|
|
|
->hashtable('items')
|
2014-02-15 20:09:50 +01:00
|
|
|
->in('status', array('read', 'unread'))
|
|
|
|
->orderBy('updated', 'desc')
|
2015-01-28 02:13:16 +01:00
|
|
|
->getAll('id', 'status');
|
2014-02-15 20:09:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get all items by status
|
2015-08-15 03:33:39 +02:00
|
|
|
function get_all_by_status($status, $feed_ids = array(), $offset = null, $limit = null, $order_column = 'updated', $order_direction = 'desc')
|
2013-12-23 02:55:53 +01:00
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->columns(
|
|
|
|
'items.id',
|
|
|
|
'items.title',
|
|
|
|
'items.updated',
|
|
|
|
'items.url',
|
2014-02-17 19:41:22 +01:00
|
|
|
'items.enclosure',
|
2014-02-18 04:04:49 +01:00
|
|
|
'items.enclosure_type',
|
2013-12-23 02:55:53 +01:00
|
|
|
'items.bookmark',
|
|
|
|
'items.feed_id',
|
|
|
|
'items.status',
|
|
|
|
'items.content',
|
2014-03-17 02:35:57 +01:00
|
|
|
'items.language',
|
2015-12-09 20:25:13 +01:00
|
|
|
'items.author',
|
2013-12-23 02:55:53 +01:00
|
|
|
'feeds.site_url',
|
2014-10-20 01:14:33 +02:00
|
|
|
'feeds.title AS feed_title',
|
|
|
|
'feeds.rtl'
|
2013-12-23 02:55:53 +01:00
|
|
|
)
|
|
|
|
->join('feeds', 'id', 'feed_id')
|
|
|
|
->eq('status', $status)
|
2015-08-05 01:01:21 +02:00
|
|
|
->in('feed_id', $feed_ids)
|
2013-12-23 02:55:53 +01:00
|
|
|
->orderBy($order_column, $order_direction)
|
|
|
|
->offset($offset)
|
|
|
|
->limit($limit)
|
|
|
|
->findAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the number of items per status
|
2015-08-15 03:33:39 +02:00
|
|
|
function count_by_status($status, $feed_ids = array())
|
2013-12-23 02:55:53 +01:00
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('status', $status)
|
2015-08-05 01:01:21 +02:00
|
|
|
->in('feed_id', $feed_ids)
|
2013-12-23 02:55:53 +01:00
|
|
|
->count();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the number of items per feed
|
|
|
|
function count_by_feed($feed_id)
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('feed_id', $feed_id)
|
|
|
|
->in('status', array('unread', 'read'))
|
|
|
|
->count();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get all items per feed
|
|
|
|
function get_all_by_feed($feed_id, $offset = null, $limit = null, $order_column = 'updated', $order_direction = 'desc')
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->columns(
|
|
|
|
'items.id',
|
|
|
|
'items.title',
|
|
|
|
'items.updated',
|
|
|
|
'items.url',
|
2014-02-17 19:41:22 +01:00
|
|
|
'items.enclosure',
|
2014-02-18 04:04:49 +01:00
|
|
|
'items.enclosure_type',
|
2013-12-23 02:55:53 +01:00
|
|
|
'items.feed_id',
|
|
|
|
'items.status',
|
|
|
|
'items.content',
|
|
|
|
'items.bookmark',
|
2014-03-17 02:35:57 +01:00
|
|
|
'items.language',
|
2015-12-09 20:25:13 +01:00
|
|
|
'items.author',
|
2014-10-20 01:14:33 +02:00
|
|
|
'feeds.site_url',
|
|
|
|
'feeds.rtl'
|
2013-12-23 02:55:53 +01:00
|
|
|
)
|
|
|
|
->join('feeds', 'id', 'feed_id')
|
|
|
|
->in('status', array('unread', 'read'))
|
|
|
|
->eq('feed_id', $feed_id)
|
|
|
|
->orderBy($order_column, $order_direction)
|
|
|
|
->offset($offset)
|
|
|
|
->limit($limit)
|
|
|
|
->findAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get one item by id
|
|
|
|
function get($id)
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
|
|
|
->findOne();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get item naviguation (next/prev items)
|
2015-11-19 16:31:31 +01:00
|
|
|
function get_nav($item, $status = array('unread'), $bookmark = array(1, 0), $feed_id = null, $group_id = null)
|
2013-12-23 02:55:53 +01:00
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
$query = Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->columns('id', 'status', 'title', 'bookmark')
|
|
|
|
->neq('status', 'removed')
|
2014-05-20 20:20:27 +02:00
|
|
|
->orderBy('updated', Config\get('items_sorting_direction'));
|
2013-12-23 02:55:53 +01:00
|
|
|
|
2016-04-18 01:44:45 +02:00
|
|
|
if ($feed_id) {
|
|
|
|
$query->eq('feed_id', $feed_id);
|
|
|
|
}
|
2013-12-23 02:55:53 +01:00
|
|
|
|
2016-04-18 01:44:45 +02:00
|
|
|
if ($group_id) {
|
|
|
|
$query->in('feed_id', Group\get_feeds_by_group($group_id));
|
|
|
|
}
|
2015-11-19 16:31:31 +01:00
|
|
|
|
2013-12-23 02:55:53 +01:00
|
|
|
$items = $query->findAll();
|
|
|
|
|
|
|
|
$next_item = null;
|
|
|
|
$previous_item = null;
|
|
|
|
|
2016-05-03 10:45:07 +02:00
|
|
|
for ($i = 0, $ilen = count($items); $i < $ilen; ++$i) {
|
2013-12-23 02:55:53 +01:00
|
|
|
if ($items[$i]['id'] == $item['id']) {
|
|
|
|
if ($i > 0) {
|
|
|
|
$j = $i - 1;
|
|
|
|
|
|
|
|
while ($j >= 0) {
|
|
|
|
if (in_array($items[$j]['status'], $status) && in_array($items[$j]['bookmark'], $bookmark)) {
|
|
|
|
$previous_item = $items[$j];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-05-03 10:45:07 +02:00
|
|
|
--$j;
|
2013-12-23 02:55:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($i < ($ilen - 1)) {
|
|
|
|
$j = $i + 1;
|
|
|
|
|
|
|
|
while ($j < $ilen) {
|
|
|
|
if (in_array($items[$j]['status'], $status) && in_array($items[$j]['bookmark'], $bookmark)) {
|
|
|
|
$next_item = $items[$j];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-05-03 10:45:07 +02:00
|
|
|
++$j;
|
2013-12-23 02:55:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return array(
|
|
|
|
'next' => $next_item,
|
|
|
|
'previous' => $previous_item
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change item status to removed and clear content
|
|
|
|
function set_removed($id)
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
|
|
|
->save(array('status' => 'removed', 'content' => ''));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change item status to read
|
|
|
|
function set_read($id)
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
|
|
|
->save(array('status' => 'read'));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change item status to unread
|
|
|
|
function set_unread($id)
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
|
|
|
->save(array('status' => 'unread'));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change item status to "read", "unread" or "removed"
|
|
|
|
function set_status($status, array $items)
|
|
|
|
{
|
2016-04-18 01:44:45 +02:00
|
|
|
if (! in_array($status, array('read', 'unread', 'removed'))) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-12-23 02:55:53 +01:00
|
|
|
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->in('id', $items)
|
|
|
|
->save(array('status' => $status));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mark all unread items as read
|
|
|
|
function mark_all_as_read()
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('status', 'unread')
|
|
|
|
->save(array('status' => 'read'));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mark all read items to removed
|
|
|
|
function mark_all_as_removed()
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('status', 'read')
|
|
|
|
->eq('bookmark', 0)
|
|
|
|
->save(array('status' => 'removed', 'content' => ''));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mark all items of a feed as read
|
|
|
|
function mark_feed_as_read($feed_id)
|
|
|
|
{
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('status', 'unread')
|
|
|
|
->eq('feed_id', $feed_id)
|
|
|
|
->update(array('status' => 'read'));
|
|
|
|
}
|
|
|
|
|
2015-08-05 01:01:21 +02:00
|
|
|
// Mark all items of a group as read
|
|
|
|
function mark_group_as_read($group_id)
|
|
|
|
{
|
|
|
|
// workaround for missing update with join
|
|
|
|
$feed_ids = Group\get_feeds_by_group($group_id);
|
|
|
|
|
2015-08-15 03:33:39 +02:00
|
|
|
return Database::getInstance('db')
|
2015-08-05 01:01:21 +02:00
|
|
|
->table('items')
|
|
|
|
->eq('status', 'unread')
|
|
|
|
->in('feed_id', $feed_ids)
|
|
|
|
->update(array('status' => 'read'));
|
|
|
|
}
|
|
|
|
|
2016-02-28 14:58:07 +01:00
|
|
|
// Mark all items of a group as removed
|
|
|
|
function mark_group_as_removed($group_id)
|
|
|
|
{
|
|
|
|
$feed_ids = Group\get_feeds_by_group($group_id);
|
|
|
|
|
|
|
|
return Database::getInstance('db')
|
|
|
|
->table('items')
|
|
|
|
->eq('status', 'read')
|
|
|
|
->eq('bookmark', 0)
|
|
|
|
->in('feed_id', $feed_ids)
|
|
|
|
->save(array('status' => 'removed', 'content' => ''));
|
|
|
|
}
|
|
|
|
|
2013-12-23 02:55:53 +01:00
|
|
|
// Mark all read items to removed after X days
|
2014-12-16 02:38:35 +01:00
|
|
|
function autoflush_read()
|
2013-12-23 02:55:53 +01:00
|
|
|
{
|
2014-05-20 20:20:27 +02:00
|
|
|
$autoflush = (int) Config\get('autoflush');
|
2013-12-23 02:55:53 +01:00
|
|
|
|
2013-12-23 03:25:54 +01:00
|
|
|
if ($autoflush > 0) {
|
2013-12-23 02:55:53 +01:00
|
|
|
|
2013-12-23 03:25:54 +01:00
|
|
|
// Mark read items removed after X days
|
2015-08-15 03:33:39 +02:00
|
|
|
Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('bookmark', 0)
|
|
|
|
->eq('status', 'read')
|
|
|
|
->lt('updated', strtotime('-'.$autoflush.'day'))
|
2013-12-23 03:25:54 +01:00
|
|
|
->save(array('status' => 'removed', 'content' => ''));
|
2016-04-18 01:44:45 +02:00
|
|
|
} elseif ($autoflush === -1) {
|
2013-12-23 03:25:54 +01:00
|
|
|
|
|
|
|
// Mark read items removed immediately
|
2015-08-15 03:33:39 +02:00
|
|
|
Database::getInstance('db')
|
2013-12-23 03:25:54 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('bookmark', 0)
|
|
|
|
->eq('status', 'read')
|
2013-12-23 02:55:53 +01:00
|
|
|
->save(array('status' => 'removed', 'content' => ''));
|
2014-12-16 02:38:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mark all unread items to removed after X days
|
|
|
|
function autoflush_unread()
|
|
|
|
{
|
|
|
|
$autoflush = (int) Config\get('autoflush_unread');
|
|
|
|
|
|
|
|
if ($autoflush > 0) {
|
|
|
|
|
|
|
|
// Mark read items removed after X days
|
2015-08-15 03:33:39 +02:00
|
|
|
Database::getInstance('db')
|
2014-12-16 02:38:35 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('bookmark', 0)
|
|
|
|
->eq('status', 'unread')
|
|
|
|
->lt('updated', strtotime('-'.$autoflush.'day'))
|
|
|
|
->save(array('status' => 'removed', 'content' => ''));
|
2013-12-23 02:55:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update all items
|
2014-12-24 03:28:26 +01:00
|
|
|
function update_all($feed_id, array $items)
|
2013-12-23 02:55:53 +01:00
|
|
|
{
|
2014-05-20 20:20:27 +02:00
|
|
|
$nocontent = (bool) Config\get('nocontent');
|
2013-12-23 02:55:53 +01:00
|
|
|
|
|
|
|
$items_in_feed = array();
|
|
|
|
|
2015-08-15 03:33:39 +02:00
|
|
|
$db = Database::getInstance('db');
|
2013-12-23 02:55:53 +01:00
|
|
|
$db->startTransaction();
|
|
|
|
|
|
|
|
foreach ($items as $item) {
|
2014-12-24 03:28:26 +01:00
|
|
|
Logger::setMessage('Item => '.$item->getId().' '.$item->getUrl());
|
2014-02-12 03:26:55 +01:00
|
|
|
|
2013-12-23 02:55:53 +01:00
|
|
|
// Item parsed correctly?
|
2014-05-20 20:20:27 +02:00
|
|
|
if ($item->getId() && $item->getUrl()) {
|
2014-12-24 03:28:26 +01:00
|
|
|
Logger::setMessage('Item parsed correctly');
|
2014-02-12 03:26:55 +01:00
|
|
|
|
2014-05-17 15:58:56 +02:00
|
|
|
// Get item record in database, if any
|
|
|
|
$itemrec = $db
|
|
|
|
->table('items')
|
|
|
|
->columns('enclosure')
|
2014-05-20 20:20:27 +02:00
|
|
|
->eq('id', $item->getId())
|
|
|
|
->findOne();
|
2014-05-17 15:58:56 +02:00
|
|
|
|
|
|
|
// Insert a new item
|
|
|
|
if ($itemrec === null) {
|
2014-12-24 03:28:26 +01:00
|
|
|
Logger::setMessage('Item added to the database');
|
2013-12-23 02:55:53 +01:00
|
|
|
|
|
|
|
$db->table('items')->save(array(
|
2014-05-20 20:20:27 +02:00
|
|
|
'id' => $item->getId(),
|
|
|
|
'title' => $item->getTitle(),
|
|
|
|
'url' => $item->getUrl(),
|
2015-03-01 19:56:11 +01:00
|
|
|
'updated' => $item->getDate()->getTimestamp(),
|
2014-05-20 20:20:27 +02:00
|
|
|
'author' => $item->getAuthor(),
|
|
|
|
'content' => $nocontent ? '' : $item->getContent(),
|
2013-12-23 02:55:53 +01:00
|
|
|
'status' => 'unread',
|
2014-02-17 19:41:22 +01:00
|
|
|
'feed_id' => $feed_id,
|
2014-05-20 20:20:27 +02:00
|
|
|
'enclosure' => $item->getEnclosureUrl(),
|
|
|
|
'enclosure_type' => $item->getEnclosureType(),
|
|
|
|
'language' => $item->getLanguage(),
|
2013-12-23 02:55:53 +01:00
|
|
|
));
|
2016-04-18 01:44:45 +02:00
|
|
|
} elseif (! $itemrec['enclosure'] && $item->getEnclosureUrl()) {
|
2014-12-24 03:28:26 +01:00
|
|
|
Logger::setMessage('Update item enclosure');
|
2014-05-17 15:58:56 +02:00
|
|
|
|
2014-05-20 20:20:27 +02:00
|
|
|
$db->table('items')->eq('id', $item->getId())->save(array(
|
2014-05-17 15:58:56 +02:00
|
|
|
'status' => 'unread',
|
2014-05-20 20:20:27 +02:00
|
|
|
'enclosure' => $item->getEnclosureUrl(),
|
|
|
|
'enclosure_type' => $item->getEnclosureType(),
|
2014-05-17 15:58:56 +02:00
|
|
|
));
|
2016-04-18 01:44:45 +02:00
|
|
|
} else {
|
2014-12-24 03:28:26 +01:00
|
|
|
Logger::setMessage('Item already in the database');
|
2014-02-12 03:26:55 +01:00
|
|
|
}
|
2013-12-23 02:55:53 +01:00
|
|
|
|
|
|
|
// Items inside this feed
|
|
|
|
$items_in_feed[] = $item->id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-20 20:20:27 +02:00
|
|
|
// Cleanup old items
|
|
|
|
cleanup($feed_id, $items_in_feed);
|
|
|
|
|
|
|
|
$db->closeTransaction();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove from the database items marked as "removed"
|
|
|
|
// and not present inside the feed
|
|
|
|
function cleanup($feed_id, array $items_in_feed)
|
|
|
|
{
|
2013-12-23 02:55:53 +01:00
|
|
|
if (! empty($items_in_feed)) {
|
2015-08-15 03:33:39 +02:00
|
|
|
$db = Database::getInstance('db');
|
2014-05-20 20:20:27 +02:00
|
|
|
|
2014-02-12 03:26:55 +01:00
|
|
|
$removed_items = $db
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->columns('id')
|
2016-07-31 00:41:42 +02:00
|
|
|
->notIn('id', $items_in_feed)
|
2013-12-23 02:55:53 +01:00
|
|
|
->eq('status', 'removed')
|
|
|
|
->eq('feed_id', $feed_id)
|
|
|
|
->desc('updated')
|
|
|
|
->findAllByColumn('id');
|
|
|
|
|
|
|
|
// Keep a buffer of 2 items
|
|
|
|
// It's workaround for buggy feeds (cache issue with some Wordpress plugins)
|
|
|
|
if (is_array($removed_items)) {
|
|
|
|
$items_to_remove = array_slice($removed_items, 2);
|
|
|
|
|
|
|
|
if (! empty($items_to_remove)) {
|
2014-02-12 03:26:55 +01:00
|
|
|
$nb_items = count($items_to_remove);
|
2014-12-24 03:28:26 +01:00
|
|
|
Logger::setMessage('There is '.$nb_items.' items to remove');
|
2014-02-12 03:26:55 +01:00
|
|
|
|
|
|
|
// Handle the case when there is a huge number of items to remove
|
|
|
|
// Sqlite have a limit of 1000 sql variables by default
|
|
|
|
// Avoid the error message "too many SQL variables"
|
|
|
|
// We remove old items by batch of 500 items
|
|
|
|
$chunks = array_chunk($items_to_remove, 500);
|
|
|
|
|
|
|
|
foreach ($chunks as $chunk) {
|
|
|
|
$db->table('items')
|
|
|
|
->in('id', $chunk)
|
|
|
|
->eq('status', 'removed')
|
|
|
|
->eq('feed_id', $feed_id)
|
|
|
|
->remove();
|
|
|
|
}
|
2013-12-23 02:55:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Download content from an URL
|
|
|
|
function download_content_url($url)
|
|
|
|
{
|
2014-05-20 20:20:27 +02:00
|
|
|
$content = '';
|
2013-12-23 02:55:53 +01:00
|
|
|
|
2015-04-28 18:08:42 +02:00
|
|
|
$grabber = new Scraper(Config\get_reader_config());
|
|
|
|
$grabber->setUrl($url);
|
|
|
|
$grabber->execute();
|
2013-12-23 02:55:53 +01:00
|
|
|
|
2015-04-28 18:08:42 +02:00
|
|
|
if ($grabber->hasRelevantContent()) {
|
|
|
|
$content = $grabber->getFilteredContent();
|
2014-05-20 20:20:27 +02:00
|
|
|
}
|
2013-12-23 02:55:53 +01:00
|
|
|
|
2014-05-20 20:20:27 +02:00
|
|
|
return $content;
|
2013-12-23 02:55:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Download content from item ID
|
|
|
|
function download_content_id($item_id)
|
|
|
|
{
|
|
|
|
$item = get($item_id);
|
|
|
|
$content = download_content_url($item['url']);
|
|
|
|
|
|
|
|
if (! empty($content)) {
|
2014-05-20 20:20:27 +02:00
|
|
|
if (! Config\get('nocontent')) {
|
2013-12-23 02:55:53 +01:00
|
|
|
|
|
|
|
// Save content
|
2015-08-15 03:33:39 +02:00
|
|
|
Database::getInstance('db')
|
2013-12-23 02:55:53 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('id', $item['id'])
|
|
|
|
->save(array('content' => $content));
|
|
|
|
}
|
|
|
|
|
2014-05-20 20:20:27 +02:00
|
|
|
Config\write_debug();
|
2013-12-23 02:55:53 +01:00
|
|
|
|
|
|
|
return array(
|
|
|
|
'result' => true,
|
|
|
|
'content' => $content
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2014-05-20 20:20:27 +02:00
|
|
|
Config\write_debug();
|
2013-12-23 02:55:53 +01:00
|
|
|
|
|
|
|
return array(
|
|
|
|
'result' => false,
|
|
|
|
'content' => ''
|
|
|
|
);
|
|
|
|
}
|