2013-02-18 03:48:21 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Model;
|
|
|
|
|
2013-07-29 02:10:07 +02:00
|
|
|
require_once 'vendor/PicoFeed/Filter.php';
|
2013-02-18 03:48:21 +01:00
|
|
|
require_once 'vendor/PicoFeed/Export.php';
|
|
|
|
require_once 'vendor/PicoFeed/Import.php';
|
|
|
|
require_once 'vendor/PicoFeed/Reader.php';
|
|
|
|
require_once 'vendor/SimpleValidator/Validator.php';
|
|
|
|
require_once 'vendor/SimpleValidator/Base.php';
|
|
|
|
require_once 'vendor/SimpleValidator/Validators/Required.php';
|
|
|
|
require_once 'vendor/SimpleValidator/Validators/Unique.php';
|
|
|
|
require_once 'vendor/SimpleValidator/Validators/MaxLength.php';
|
|
|
|
require_once 'vendor/SimpleValidator/Validators/MinLength.php';
|
|
|
|
require_once 'vendor/SimpleValidator/Validators/Integer.php';
|
|
|
|
require_once 'vendor/SimpleValidator/Validators/Equals.php';
|
2013-07-06 16:50:37 +02:00
|
|
|
require_once 'vendor/SimpleValidator/Validators/Integer.php';
|
2013-02-18 03:48:21 +01:00
|
|
|
|
|
|
|
use SimpleValidator\Validator;
|
|
|
|
use SimpleValidator\Validators;
|
|
|
|
use PicoFeed\Import;
|
|
|
|
use PicoFeed\Reader;
|
|
|
|
use PicoFeed\Export;
|
|
|
|
|
|
|
|
|
2013-09-19 03:02:46 +02:00
|
|
|
const DB_VERSION = 17;
|
2013-07-06 16:50:37 +02:00
|
|
|
const HTTP_USERAGENT = 'Miniflux - http://miniflux.net';
|
2013-08-31 17:05:45 +02:00
|
|
|
const HTTP_FAKE_USERAGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36';
|
2013-07-06 16:50:37 +02:00
|
|
|
const LIMIT_ALL = -1;
|
|
|
|
|
|
|
|
|
2013-09-19 03:02:46 +02:00
|
|
|
function get_sorting_directions()
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
'asc' => t('Older items first'),
|
|
|
|
'desc' => t('Most recent first'),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-13 03:08:55 +02:00
|
|
|
function get_languages()
|
|
|
|
{
|
2013-10-01 03:30:23 +02:00
|
|
|
$languages = array(
|
2013-07-13 10:36:21 +02:00
|
|
|
'cs_CZ' => t('Czech'),
|
2013-10-01 03:30:23 +02:00
|
|
|
'de_DE' => t('German'),
|
2013-04-13 03:08:55 +02:00
|
|
|
'en_US' => t('English'),
|
2013-10-01 03:30:23 +02:00
|
|
|
'es_ES' => t('Spanish'),
|
2013-07-02 00:02:47 +02:00
|
|
|
'fr_FR' => t('French'),
|
2013-07-09 00:16:01 +02:00
|
|
|
'it_IT' => t('Italian'),
|
2013-10-02 00:47:33 +02:00
|
|
|
'pt_BR' => t('Portuguese'),
|
2013-07-09 00:16:01 +02:00
|
|
|
'zh_CN' => t('Simplified Chinese'),
|
2013-04-13 03:08:55 +02:00
|
|
|
);
|
2013-10-01 03:30:23 +02:00
|
|
|
|
|
|
|
asort($languages);
|
|
|
|
|
|
|
|
return $languages;
|
2013-04-13 03:08:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-17 03:58:11 +02:00
|
|
|
function get_themes()
|
|
|
|
{
|
|
|
|
$themes = array(
|
|
|
|
'original' => t('Original')
|
|
|
|
);
|
|
|
|
|
|
|
|
if (file_exists(THEME_DIRECTORY)) {
|
|
|
|
|
|
|
|
$dir = new \DirectoryIterator(THEME_DIRECTORY);
|
|
|
|
|
|
|
|
foreach ($dir as $fileinfo) {
|
|
|
|
|
|
|
|
if (! $fileinfo->isDot() && $fileinfo->isDir()) {
|
|
|
|
$themes[$dir->getFilename()] = ucfirst($dir->getFilename());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $themes;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-26 19:09:34 +02:00
|
|
|
function get_autoflush_options()
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
'0' => t('Never'),
|
|
|
|
'1' => t('After %d day', 1),
|
|
|
|
'5' => t('After %d days', 5),
|
|
|
|
'15' => t('After %d days', 15),
|
|
|
|
'30' => t('After %d days', 30)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-06 16:50:37 +02:00
|
|
|
function get_paging_options()
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
50 => 50,
|
|
|
|
100 => 100,
|
|
|
|
150 => 150,
|
|
|
|
200 => 200,
|
|
|
|
250 => 250,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-06 20:29:45 +02:00
|
|
|
function write_debug()
|
|
|
|
{
|
|
|
|
if (DEBUG) {
|
|
|
|
|
2013-08-30 01:34:11 +02:00
|
|
|
$data = '';
|
|
|
|
|
|
|
|
foreach (\PicoFeed\Logging::$messages as $line) {
|
|
|
|
$data .= $line.PHP_EOL;
|
|
|
|
}
|
|
|
|
|
|
|
|
file_put_contents(DEBUG_FILENAME, $data);
|
2013-07-06 20:29:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-15 03:08:01 +02:00
|
|
|
function generate_token()
|
2013-07-28 21:44:51 +02:00
|
|
|
{
|
2013-08-15 03:08:01 +02:00
|
|
|
if (ini_get('open_basedir') === '') {
|
|
|
|
return substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function new_tokens()
|
|
|
|
{
|
|
|
|
$values = array(
|
|
|
|
'api_token' => generate_token(),
|
|
|
|
'feed_token' => generate_token(),
|
|
|
|
);
|
|
|
|
|
|
|
|
return \PicoTools\singleton('db')->table('config')->update($values);
|
2013-07-28 21:44:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-07 04:57:09 +02:00
|
|
|
function save_auth_token($type, $value)
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('config')
|
|
|
|
->update(array(
|
|
|
|
'auth_'.$type.'_token' => $value
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function remove_auth_token($type)
|
|
|
|
{
|
|
|
|
\PicoTools\singleton('db')
|
|
|
|
->table('config')
|
|
|
|
->update(array(
|
|
|
|
'auth_'.$type.'_token' => ''
|
|
|
|
));
|
|
|
|
|
|
|
|
$_SESSION['config'] = get_config();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
function export_feeds()
|
|
|
|
{
|
|
|
|
$opml = new Export(get_feeds());
|
|
|
|
return $opml->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-06 03:23:46 +01:00
|
|
|
function save_feed(array $values)
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('feeds')
|
|
|
|
->eq('id', $values['id'])
|
|
|
|
->save(array(
|
|
|
|
'title' => $values['title'],
|
|
|
|
'site_url' => $values['site_url'],
|
|
|
|
'feed_url' => $values['feed_url']
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
function import_feeds($content)
|
|
|
|
{
|
|
|
|
$import = new Import($content);
|
|
|
|
$feeds = $import->execute();
|
|
|
|
|
|
|
|
if ($feeds) {
|
|
|
|
|
|
|
|
$db = \PicoTools\singleton('db');
|
|
|
|
|
|
|
|
$db->startTransaction();
|
|
|
|
|
|
|
|
foreach ($feeds as $feed) {
|
|
|
|
|
|
|
|
if (! $db->table('feeds')->eq('feed_url', $feed->feed_url)->count()) {
|
|
|
|
|
|
|
|
$db->table('feeds')->save(array(
|
|
|
|
'title' => $feed->title,
|
|
|
|
'site_url' => $feed->site_url,
|
|
|
|
'feed_url' => $feed->feed_url
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$db->closeTransaction();
|
|
|
|
|
2013-08-30 01:34:11 +02:00
|
|
|
write_debug();
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-08-30 01:34:11 +02:00
|
|
|
write_debug();
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
function import_feed($url, $grabber = false)
|
2013-02-18 03:48:21 +01:00
|
|
|
{
|
|
|
|
$reader = new Reader;
|
2013-07-06 16:50:37 +02:00
|
|
|
$resource = $reader->download($url, '', '', HTTP_TIMEOUT, HTTP_USERAGENT);
|
2013-02-18 03:48:21 +01:00
|
|
|
|
|
|
|
$parser = $reader->getParser();
|
|
|
|
|
|
|
|
if ($parser !== false) {
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
$parser->grabber = $grabber;
|
2013-02-18 03:48:21 +01:00
|
|
|
$feed = $parser->execute();
|
|
|
|
|
2013-11-13 04:30:40 +01:00
|
|
|
if ($feed === false) {
|
|
|
|
write_debug();
|
|
|
|
return false;
|
2013-11-12 03:04:42 +01:00
|
|
|
}
|
|
|
|
|
2013-11-13 04:30:40 +01:00
|
|
|
if (! $feed->url) $feed->url = $reader->getUrl();
|
|
|
|
|
|
|
|
if (! $feed->title) {
|
2013-08-30 02:52:44 +02:00
|
|
|
write_debug();
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-04 03:19:02 +02:00
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
$db = \PicoTools\singleton('db');
|
|
|
|
|
|
|
|
if (! $db->table('feeds')->eq('feed_url', $reader->getUrl())->count()) {
|
|
|
|
|
2013-04-07 03:15:42 +02:00
|
|
|
// Etag and LastModified are added the next update
|
2013-02-18 03:48:21 +01:00
|
|
|
$rs = $db->table('feeds')->save(array(
|
|
|
|
'title' => $feed->title,
|
|
|
|
'site_url' => $feed->url,
|
2013-08-31 17:05:45 +02:00
|
|
|
'feed_url' => $reader->getUrl(),
|
|
|
|
'download_content' => $grabber ? 1 : 0
|
2013-02-18 03:48:21 +01:00
|
|
|
));
|
|
|
|
|
|
|
|
if ($rs) {
|
|
|
|
|
|
|
|
$feed_id = $db->getConnection()->getLastId();
|
2013-08-31 17:05:45 +02:00
|
|
|
update_items($feed_id, $feed->items, $grabber);
|
2013-08-30 01:34:11 +02:00
|
|
|
write_debug();
|
2013-07-28 21:44:51 +02:00
|
|
|
|
|
|
|
return (int) $feed_id;
|
2013-02-18 03:48:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-30 01:34:11 +02:00
|
|
|
write_debug();
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-05-21 12:25:13 +02:00
|
|
|
|
2013-05-18 20:35:16 +02:00
|
|
|
function update_feeds($limit = LIMIT_ALL)
|
2013-04-07 03:15:42 +02:00
|
|
|
{
|
2013-05-18 20:35:16 +02:00
|
|
|
$feeds_id = get_feeds_id($limit);
|
|
|
|
|
|
|
|
foreach ($feeds_id as $feed_id) {
|
2013-04-07 03:15:42 +02:00
|
|
|
update_feed($feed_id);
|
|
|
|
}
|
2013-04-24 03:41:04 +02:00
|
|
|
|
|
|
|
// Auto-vacuum for people using the cronjob
|
|
|
|
\PicoTools\singleton('db')->getConnection()->exec('VACUUM');
|
2013-08-30 01:34:11 +02:00
|
|
|
|
|
|
|
return true;
|
2013-04-07 03:15:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function update_feed($feed_id)
|
|
|
|
{
|
|
|
|
$feed = get_feed($feed_id);
|
2013-07-28 21:44:51 +02:00
|
|
|
if (empty($feed)) return false;
|
2013-04-07 03:15:42 +02:00
|
|
|
|
|
|
|
$reader = new Reader;
|
|
|
|
|
|
|
|
$resource = $reader->download(
|
|
|
|
$feed['feed_url'],
|
|
|
|
$feed['last_modified'],
|
|
|
|
$feed['etag'],
|
|
|
|
HTTP_TIMEOUT,
|
2013-07-06 16:50:37 +02:00
|
|
|
HTTP_USERAGENT
|
2013-04-07 03:15:42 +02:00
|
|
|
);
|
|
|
|
|
2013-05-21 12:25:13 +02:00
|
|
|
// Update the `last_checked` column each time, HTTP cache or not
|
2013-05-18 20:35:16 +02:00
|
|
|
update_feed_last_checked($feed_id);
|
|
|
|
|
2013-08-30 01:34:11 +02:00
|
|
|
if (! $resource->isModified()) {
|
|
|
|
write_debug();
|
|
|
|
return true;
|
|
|
|
}
|
2013-04-07 03:15:42 +02:00
|
|
|
|
|
|
|
$parser = $reader->getParser();
|
|
|
|
|
|
|
|
if ($parser !== false) {
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
if ($feed['download_content']) {
|
|
|
|
|
|
|
|
// Don't fetch previous items, only new one
|
|
|
|
$parser->grabber_ignore_urls = \PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->eq('feed_id', $feed_id)
|
|
|
|
->findAllByColumn('url');
|
|
|
|
|
|
|
|
$parser->grabber = true;
|
|
|
|
$parser->grabber_timeout = HTTP_TIMEOUT;
|
|
|
|
$parser->grabber_user_agent = HTTP_FAKE_USERAGENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
$result = $parser->execute();
|
2013-04-07 03:15:42 +02:00
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
if ($result !== false) {
|
2013-04-07 03:15:42 +02:00
|
|
|
|
|
|
|
update_feed_cache_infos($feed_id, $resource->getLastModified(), $resource->getEtag());
|
2013-08-31 17:05:45 +02:00
|
|
|
update_items($feed_id, $result->items, $parser->grabber);
|
2013-08-30 01:34:11 +02:00
|
|
|
write_debug();
|
2013-04-07 03:15:42 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-30 01:34:11 +02:00
|
|
|
write_debug();
|
|
|
|
|
2013-04-07 03:15:42 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-18 20:35:16 +02:00
|
|
|
function get_feeds_id($limit = LIMIT_ALL)
|
2013-04-07 03:15:42 +02:00
|
|
|
{
|
2013-05-18 20:35:16 +02:00
|
|
|
$table_feeds = \PicoTools\singleton('db')->table('feeds')
|
2013-08-04 21:15:12 +02:00
|
|
|
->eq('enabled', 1)
|
2013-05-18 21:47:22 +02:00
|
|
|
->asc('last_checked');
|
2013-05-18 20:35:16 +02:00
|
|
|
|
2013-05-21 12:25:13 +02:00
|
|
|
if ($limit !== LIMIT_ALL) {
|
2013-05-18 20:35:16 +02:00
|
|
|
$table_feeds->limit((int)$limit);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $table_feeds->listing('id', 'id');
|
2013-04-07 03:15:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
function get_feeds()
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('feeds')
|
|
|
|
->asc('title')
|
|
|
|
->findAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function get_feed($feed_id)
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('feeds')
|
|
|
|
->eq('id', $feed_id)
|
|
|
|
->findOne();
|
|
|
|
}
|
|
|
|
|
2013-07-13 02:26:47 +02:00
|
|
|
|
2013-07-11 14:24:10 +02:00
|
|
|
function get_empty_feeds()
|
|
|
|
{
|
|
|
|
$feeds = \PicoTools\singleton('db')
|
|
|
|
->table('feeds')
|
2013-07-13 02:26:47 +02:00
|
|
|
->columns('feeds.id', 'feeds.title', 'COUNT(items.id) AS nb_items')
|
|
|
|
->join('items', 'feed_id', 'id')
|
|
|
|
->isNull('feeds.last_checked')
|
2013-07-17 02:43:10 +02:00
|
|
|
->groupBy('feeds.id')
|
2013-07-13 02:26:47 +02:00
|
|
|
->findAll();
|
2013-07-11 14:24:10 +02:00
|
|
|
|
2013-07-13 02:26:47 +02:00
|
|
|
foreach ($feeds as $key => &$feed) {
|
|
|
|
|
|
|
|
if ($feed['nb_items'] > 0) {
|
|
|
|
unset($feeds[$key]);
|
|
|
|
}
|
2013-07-11 14:24:10 +02:00
|
|
|
}
|
2013-07-13 02:26:47 +02:00
|
|
|
|
|
|
|
return $feeds;
|
2013-07-11 14:24:10 +02:00
|
|
|
}
|
|
|
|
|
2013-05-21 12:25:13 +02:00
|
|
|
|
|
|
|
function update_feed_last_checked($feed_id)
|
|
|
|
{
|
2013-05-18 20:35:16 +02:00
|
|
|
\PicoTools\singleton('db')
|
|
|
|
->table('feeds')
|
|
|
|
->eq('id', $feed_id)
|
|
|
|
->save(array(
|
2013-05-21 12:25:13 +02:00
|
|
|
'last_checked' => time()
|
2013-05-18 20:35:16 +02:00
|
|
|
));
|
|
|
|
}
|
2013-02-18 03:48:21 +01:00
|
|
|
|
2013-05-21 12:25:13 +02:00
|
|
|
|
2013-04-07 03:15:42 +02:00
|
|
|
function update_feed_cache_infos($feed_id, $last_modified, $etag)
|
|
|
|
{
|
|
|
|
\PicoTools\singleton('db')
|
|
|
|
->table('feeds')
|
|
|
|
->eq('id', $feed_id)
|
|
|
|
->save(array(
|
|
|
|
'last_modified' => $last_modified,
|
2013-05-21 12:25:13 +02:00
|
|
|
'etag' => $etag
|
2013-04-07 03:15:42 +02:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
function parse_content_with_readability($content, $url)
|
2013-07-29 02:10:07 +02:00
|
|
|
{
|
|
|
|
require_once 'vendor/Readability/Readability.php';
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
if (! empty($content)) {
|
|
|
|
|
|
|
|
$readability = new \Readability($content, $url);
|
|
|
|
|
|
|
|
if ($readability->init()) {
|
|
|
|
return $readability->getContent()->innerHTML;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function download_content($url)
|
|
|
|
{
|
|
|
|
require_once 'vendor/PicoFeed/Grabber.php';
|
2013-07-29 02:10:07 +02:00
|
|
|
|
|
|
|
$client = \PicoFeed\Client::create();
|
2013-08-31 17:05:45 +02:00
|
|
|
$client->url = $url;
|
2013-07-29 02:10:07 +02:00
|
|
|
$client->timeout = HTTP_TIMEOUT;
|
2013-08-31 17:05:45 +02:00
|
|
|
$client->user_agent = HTTP_FAKE_USERAGENT;
|
2013-07-29 02:10:07 +02:00
|
|
|
$client->execute();
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
$html = $client->getContent();
|
2013-07-29 02:10:07 +02:00
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
if (! empty($html)) {
|
2013-07-29 02:10:07 +02:00
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
// Try first with PicoFeed grabber and with Readability after
|
2013-10-04 05:14:39 +02:00
|
|
|
$grabber = new \PicoFeed\Grabber($url, $html, $client->getEncoding());
|
2013-09-01 00:37:26 +02:00
|
|
|
$content = '';
|
2013-08-31 17:05:45 +02:00
|
|
|
|
|
|
|
if ($grabber->parse()) {
|
|
|
|
$content = $grabber->content;
|
|
|
|
}
|
2013-07-29 02:10:07 +02:00
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
if (empty($content)) {
|
2013-09-01 00:37:26 +02:00
|
|
|
$content = parse_content_with_readability($grabber->html, $url);
|
2013-08-31 17:05:45 +02:00
|
|
|
}
|
2013-07-29 02:10:07 +02:00
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
// Filter content
|
|
|
|
$filter = new \PicoFeed\Filter($content, $url);
|
|
|
|
return $filter->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
return '';
|
|
|
|
}
|
2013-07-29 02:10:07 +02:00
|
|
|
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
function download_item($item_id)
|
|
|
|
{
|
|
|
|
$item = get_item($item_id);
|
|
|
|
$content = download_content($item['url']);
|
2013-07-29 02:10:07 +02:00
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
if (! empty($content)) {
|
2013-07-29 11:31:47 +02:00
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
if (! get_config_value('nocontent')) {
|
2013-07-29 02:10:07 +02:00
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
// Save content
|
|
|
|
\PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->eq('id', $item['id'])
|
|
|
|
->save(array('content' => $content));
|
2013-07-29 02:10:07 +02:00
|
|
|
}
|
2013-08-31 17:05:45 +02:00
|
|
|
|
2013-09-02 20:04:10 +02:00
|
|
|
write_debug();
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
return array(
|
|
|
|
'result' => true,
|
|
|
|
'content' => $content
|
|
|
|
);
|
2013-07-29 02:10:07 +02:00
|
|
|
}
|
|
|
|
|
2013-09-02 20:04:10 +02:00
|
|
|
write_debug();
|
|
|
|
|
2013-07-29 02:10:07 +02:00
|
|
|
return array(
|
|
|
|
'result' => false,
|
|
|
|
'content' => ''
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
function remove_feed($feed_id)
|
|
|
|
{
|
2013-06-29 03:50:46 +02:00
|
|
|
// Items are removed by a sql constraint
|
2013-08-04 21:15:12 +02:00
|
|
|
return \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-29 00:17:16 +02:00
|
|
|
function remove_feeds()
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')->table('feeds')->remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-04 21:15:12 +02:00
|
|
|
function enable_feed($feed_id)
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->save((array('enabled' => 1)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function disable_feed($feed_id)
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->save((array('enabled' => 0)));
|
2013-02-18 03:48:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
function enable_grabber_feed($feed_id)
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->save((array('download_content' => 1)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function disable_grabber_feed($feed_id)
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')->table('feeds')->eq('id', $feed_id)->save((array('download_content' => 0)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-06 03:23:46 +01:00
|
|
|
function validate_feed_modification(array $values)
|
|
|
|
{
|
|
|
|
$v = new Validator($values, array(
|
|
|
|
new Validators\Required('id', t('The feed id is required')),
|
|
|
|
new Validators\Required('title', t('The title is required')),
|
|
|
|
new Validators\Required('site_url', t('The site url is required')),
|
|
|
|
new Validators\Required('feed_url', t('The feed url is required')),
|
|
|
|
));
|
|
|
|
|
|
|
|
$result = $v->execute();
|
|
|
|
$errors = $v->getErrors();
|
|
|
|
|
|
|
|
return array(
|
|
|
|
$result,
|
|
|
|
$errors
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-15 01:05:52 +02:00
|
|
|
function get_items($status, $offset = null, $limit = null, $order_column = 'updated', $order_direction = 'desc')
|
2013-02-18 03:48:21 +01:00
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('items')
|
2013-08-23 03:38:09 +02:00
|
|
|
->columns(
|
|
|
|
'items.id',
|
|
|
|
'items.title',
|
|
|
|
'items.updated',
|
|
|
|
'items.url',
|
|
|
|
'items.bookmark',
|
|
|
|
'items.feed_id',
|
|
|
|
'items.status',
|
|
|
|
'items.content',
|
|
|
|
'feeds.site_url',
|
|
|
|
'feeds.title AS feed_title'
|
|
|
|
)
|
2013-02-18 03:48:21 +01:00
|
|
|
->join('feeds', 'id', 'feed_id')
|
2013-08-23 03:38:09 +02:00
|
|
|
->eq('status', $status)
|
2013-09-15 01:05:52 +02:00
|
|
|
->orderBy($order_column, $order_direction)
|
2013-07-06 04:37:19 +02:00
|
|
|
->offset($offset)
|
|
|
|
->limit($limit)
|
2013-02-18 03:48:21 +01:00
|
|
|
->findAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-06 04:37:19 +02:00
|
|
|
function count_items($status)
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->eq('status', $status)
|
|
|
|
->count();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function count_bookmarks()
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->eq('bookmark', 1)
|
2013-07-06 14:57:06 +02:00
|
|
|
->in('status', array('read', 'unread'))
|
2013-07-06 04:37:19 +02:00
|
|
|
->count();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function get_bookmarks($offset = null, $limit = null)
|
2013-06-04 13:38:54 +02:00
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('items')
|
2013-08-23 03:38:09 +02:00
|
|
|
->columns(
|
|
|
|
'items.id',
|
|
|
|
'items.title',
|
|
|
|
'items.updated',
|
|
|
|
'items.url',
|
2013-10-15 04:38:07 +02:00
|
|
|
'items.bookmark',
|
2013-08-23 03:38:09 +02:00
|
|
|
'items.status',
|
|
|
|
'items.content',
|
|
|
|
'items.feed_id',
|
|
|
|
'feeds.site_url',
|
|
|
|
'feeds.title AS feed_title'
|
|
|
|
)
|
2013-06-04 13:38:54 +02:00
|
|
|
->join('feeds', 'id', 'feed_id')
|
2013-06-15 05:12:08 +02:00
|
|
|
->in('status', array('read', 'unread'))
|
|
|
|
->eq('bookmark', 1)
|
2013-09-19 03:02:46 +02:00
|
|
|
->orderBy('updated', get_config_value('items_sorting_direction'))
|
2013-07-06 04:37:19 +02:00
|
|
|
->offset($offset)
|
|
|
|
->limit($limit)
|
2013-06-04 13:38:54 +02:00
|
|
|
->findAll();
|
2013-02-18 03:48:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-13 04:16:40 +02:00
|
|
|
function count_feed_items($feed_id)
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->eq('feed_id', $feed_id)
|
2013-09-19 01:29:39 +02:00
|
|
|
->in('status', array('unread', 'read'))
|
2013-07-13 04:16:40 +02:00
|
|
|
->count();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-15 01:05:52 +02:00
|
|
|
function get_feed_items($feed_id, $offset = null, $limit = null, $order_column = 'updated', $order_direction = 'desc')
|
2013-07-13 04:16:40 +02:00
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('items')
|
2013-08-23 03:38:09 +02:00
|
|
|
->columns(
|
|
|
|
'items.id',
|
|
|
|
'items.title',
|
|
|
|
'items.updated',
|
|
|
|
'items.url',
|
|
|
|
'items.feed_id',
|
|
|
|
'items.status',
|
|
|
|
'items.content',
|
|
|
|
'items.bookmark',
|
|
|
|
'feeds.site_url'
|
|
|
|
)
|
2013-07-13 04:16:40 +02:00
|
|
|
->join('feeds', 'id', 'feed_id')
|
2013-09-19 01:29:39 +02:00
|
|
|
->in('status', array('unread', 'read'))
|
2013-07-13 04:16:40 +02:00
|
|
|
->eq('feed_id', $feed_id)
|
2013-09-15 01:05:52 +02:00
|
|
|
->orderBy($order_column, $order_direction)
|
2013-07-13 04:16:40 +02:00
|
|
|
->offset($offset)
|
|
|
|
->limit($limit)
|
|
|
|
->findAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
function get_item($id)
|
|
|
|
{
|
2013-07-21 18:32:00 +02:00
|
|
|
return \PicoTools\singleton('db')
|
2013-02-18 03:48:21 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
|
|
|
->findOne();
|
|
|
|
}
|
2013-05-26 19:09:34 +02:00
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
|
2013-08-04 22:23:00 +02:00
|
|
|
function get_nav_item($item, $status = array('unread'), $bookmark = array(1, 0), $feed_id = null)
|
2013-03-27 02:56:20 +01:00
|
|
|
{
|
2013-08-04 22:23:00 +02:00
|
|
|
$query = \PicoTools\singleton('db')
|
2013-03-27 02:56:20 +01:00
|
|
|
->table('items')
|
2013-08-04 21:57:43 +02:00
|
|
|
->columns('id', 'status', 'title', 'bookmark')
|
2013-08-04 20:15:32 +02:00
|
|
|
->neq('status', 'removed')
|
2013-09-19 03:02:46 +02:00
|
|
|
->orderBy('updated', get_config_value('items_sorting_direction'));
|
2013-08-04 22:23:00 +02:00
|
|
|
|
|
|
|
if ($feed_id) $query->eq('feed_id', $feed_id);
|
|
|
|
|
|
|
|
$items = $query->findAll();
|
2013-03-27 02:56:20 +01:00
|
|
|
|
2013-05-01 04:34:02 +02:00
|
|
|
$next_item = null;
|
|
|
|
$previous_item = null;
|
|
|
|
|
2013-08-04 20:15:32 +02:00
|
|
|
for ($i = 0, $ilen = count($items); $i < $ilen; $i++) {
|
|
|
|
|
|
|
|
if ($items[$i]['id'] == $item['id']) {
|
|
|
|
|
|
|
|
if ($i > 0) {
|
|
|
|
|
|
|
|
$j = $i - 1;
|
2013-05-01 04:34:02 +02:00
|
|
|
|
2013-08-04 20:15:32 +02:00
|
|
|
while ($j >= 0) {
|
|
|
|
|
2013-08-04 21:57:43 +02:00
|
|
|
if (in_array($items[$j]['status'], $status) && in_array($items[$j]['bookmark'], $bookmark)) {
|
2013-08-04 20:15:32 +02:00
|
|
|
$previous_item = $items[$j];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$j--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($i < ($ilen - 1)) {
|
|
|
|
|
|
|
|
$j = $i + 1;
|
|
|
|
|
|
|
|
while ($j < $ilen) {
|
|
|
|
|
2013-08-04 21:57:43 +02:00
|
|
|
if (in_array($items[$j]['status'], $status) && in_array($items[$j]['bookmark'], $bookmark)) {
|
2013-08-04 20:15:32 +02:00
|
|
|
$next_item = $items[$j];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$j++;
|
|
|
|
}
|
|
|
|
}
|
2013-05-01 04:34:02 +02:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-03-27 02:56:20 +01:00
|
|
|
|
|
|
|
return array(
|
|
|
|
'next' => $next_item,
|
|
|
|
'previous' => $previous_item
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-23 04:44:28 +02:00
|
|
|
function set_item_removed($id)
|
|
|
|
{
|
2013-07-28 21:44:51 +02:00
|
|
|
return \PicoTools\singleton('db')
|
2013-04-23 04:44:28 +02:00
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
2013-06-14 04:08:38 +02:00
|
|
|
->save(array('status' => 'removed', 'content' => ''));
|
2013-04-23 04:44:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
function set_item_read($id)
|
|
|
|
{
|
2013-07-28 21:44:51 +02:00
|
|
|
return \PicoTools\singleton('db')
|
2013-02-18 03:48:21 +01:00
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
|
|
|
->save(array('status' => 'read'));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-03 04:49:14 +02:00
|
|
|
function set_item_unread($id)
|
|
|
|
{
|
2013-07-28 21:44:51 +02:00
|
|
|
return \PicoTools\singleton('db')
|
2013-04-03 04:49:14 +02:00
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
|
|
|
->save(array('status' => 'unread'));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-23 03:58:04 +02:00
|
|
|
function set_items_status($status, array $items)
|
|
|
|
{
|
|
|
|
if (! in_array($status, array('read', 'unread', 'removed'))) return false;
|
|
|
|
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->in('id', $items)
|
|
|
|
->save(array('status' => $status));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-15 05:12:08 +02:00
|
|
|
function set_bookmark_value($id, $value)
|
2013-06-04 13:38:54 +02:00
|
|
|
{
|
2013-07-28 21:44:51 +02:00
|
|
|
return \PicoTools\singleton('db')
|
2013-06-04 13:38:54 +02:00
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
2013-06-15 05:12:08 +02:00
|
|
|
->save(array('bookmark' => $value));
|
2013-06-04 13:38:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-03 04:49:14 +02:00
|
|
|
function switch_item_status($id)
|
|
|
|
{
|
|
|
|
$item = \PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->columns('status')
|
|
|
|
->eq('id', $id)
|
|
|
|
->findOne();
|
|
|
|
|
|
|
|
if ($item['status'] == 'unread') {
|
|
|
|
|
|
|
|
\PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
|
|
|
->save(array('status' => 'read'));
|
|
|
|
|
|
|
|
return 'read';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
\PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->eq('id', $id)
|
|
|
|
->save(array('status' => 'unread'));
|
|
|
|
|
|
|
|
return 'unread';
|
|
|
|
}
|
|
|
|
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-18 00:55:28 +02:00
|
|
|
// Mark all items as read
|
2013-04-03 04:49:14 +02:00
|
|
|
function mark_as_read()
|
|
|
|
{
|
2013-07-28 21:44:51 +02:00
|
|
|
return \PicoTools\singleton('db')
|
2013-04-03 04:49:14 +02:00
|
|
|
->table('items')
|
|
|
|
->eq('status', 'unread')
|
|
|
|
->save(array('status' => 'read'));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-18 00:55:28 +02:00
|
|
|
// Mark only specified items as read
|
|
|
|
function mark_items_as_read(array $items_id)
|
|
|
|
{
|
|
|
|
\PicoTools\singleton('db')->startTransaction();
|
|
|
|
|
2013-07-27 03:00:39 +02:00
|
|
|
foreach ($items_id as $id) {
|
|
|
|
set_item_read($id);
|
2013-07-18 00:55:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
\PicoTools\singleton('db')->closeTransaction();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-15 01:05:52 +02:00
|
|
|
// Mark all items of a feed as read
|
|
|
|
function mark_feed_as_read($feed_id)
|
|
|
|
{
|
|
|
|
\PicoTools\singleton('db')->startTransaction();
|
|
|
|
|
|
|
|
$items_id = \PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->columns('items.id')
|
|
|
|
->eq('status', 'unread')
|
|
|
|
->eq('feed_id', $feed_id)
|
|
|
|
->listing('id', 'id');
|
|
|
|
|
|
|
|
foreach ($items_id as $id) {
|
|
|
|
set_item_read($id);
|
|
|
|
}
|
|
|
|
|
|
|
|
\PicoTools\singleton('db')->closeTransaction();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-26 19:09:34 +02:00
|
|
|
function mark_as_removed()
|
2013-02-18 03:48:21 +01:00
|
|
|
{
|
2013-07-28 21:44:51 +02:00
|
|
|
return \PicoTools\singleton('db')
|
2013-02-18 03:48:21 +01:00
|
|
|
->table('items')
|
2013-05-26 19:09:34 +02:00
|
|
|
->eq('status', 'read')
|
2013-07-05 02:41:55 +02:00
|
|
|
->eq('bookmark', 0)
|
2013-06-14 04:08:38 +02:00
|
|
|
->save(array('status' => 'removed', 'content' => ''));
|
2013-02-18 03:48:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-26 19:09:34 +02:00
|
|
|
function autoflush()
|
|
|
|
{
|
2013-07-06 16:50:37 +02:00
|
|
|
$autoflush = get_config_value('autoflush');
|
2013-05-23 13:44:45 +02:00
|
|
|
|
2013-05-26 19:09:34 +02:00
|
|
|
if ($autoflush) {
|
2013-05-23 13:44:45 +02:00
|
|
|
|
2013-05-26 19:09:34 +02:00
|
|
|
\PicoTools\singleton('db')
|
|
|
|
->table('items')
|
2013-06-15 14:45:43 +02:00
|
|
|
->eq('bookmark', 0)
|
2013-05-26 19:09:34 +02:00
|
|
|
->eq('status', 'read')
|
|
|
|
->lt('updated', strtotime('-'.$autoflush.'day'))
|
2013-06-14 04:08:38 +02:00
|
|
|
->save(array('status' => 'removed', 'content' => ''));
|
2013-05-26 19:09:34 +02:00
|
|
|
}
|
2013-02-18 03:48:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
function update_items($feed_id, array $items, $grabber = false)
|
2013-02-18 03:48:21 +01:00
|
|
|
{
|
2013-07-06 16:50:37 +02:00
|
|
|
$nocontent = (bool) get_config_value('nocontent');
|
2013-06-06 17:54:22 +02:00
|
|
|
|
2013-04-23 04:44:28 +02:00
|
|
|
$items_in_feed = array();
|
2013-02-18 03:48:21 +01:00
|
|
|
$db = \PicoTools\singleton('db');
|
|
|
|
|
|
|
|
$db->startTransaction();
|
|
|
|
|
|
|
|
foreach ($items as $item) {
|
|
|
|
|
2013-04-23 04:44:28 +02:00
|
|
|
// Item parsed correctly?
|
|
|
|
if ($item->id) {
|
|
|
|
|
|
|
|
// Insert only new item
|
|
|
|
if ($db->table('items')->eq('id', $item->id)->count() !== 1) {
|
|
|
|
|
2013-08-31 17:05:45 +02:00
|
|
|
if (! $item->content && ! $nocontent && $grabber) {
|
|
|
|
$item->content = download_content($item->url);
|
|
|
|
}
|
|
|
|
|
2013-04-23 04:44:28 +02:00
|
|
|
$db->table('items')->save(array(
|
|
|
|
'id' => $item->id,
|
|
|
|
'title' => $item->title,
|
|
|
|
'url' => $item->url,
|
|
|
|
'updated' => $item->updated,
|
|
|
|
'author' => $item->author,
|
2013-06-11 04:09:51 +02:00
|
|
|
'content' => $nocontent ? '' : $item->content,
|
2013-04-23 04:44:28 +02:00
|
|
|
'status' => 'unread',
|
|
|
|
'feed_id' => $feed_id
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Items inside this feed
|
|
|
|
$items_in_feed[] = $item->id;
|
2013-02-18 03:48:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-23 04:44:28 +02:00
|
|
|
// Remove from the database items marked as "removed"
|
|
|
|
// and not present inside the feed
|
|
|
|
if (! empty($items_in_feed)) {
|
|
|
|
|
2013-07-14 18:00:42 +02:00
|
|
|
$removed_items = \PicoTools\singleton('db')
|
2013-04-23 04:44:28 +02:00
|
|
|
->table('items')
|
2013-07-14 18:00:42 +02:00
|
|
|
->columns('id')
|
2013-04-23 04:44:28 +02:00
|
|
|
->notin('id', $items_in_feed)
|
|
|
|
->eq('status', 'removed')
|
|
|
|
->eq('feed_id', $feed_id)
|
2013-07-14 18:00:42 +02:00
|
|
|
->desc('updated')
|
|
|
|
->findAllByColumn('id');
|
|
|
|
|
|
|
|
// Keep a buffer of 2 items
|
|
|
|
// It's workaround for buggy feeds (cache issue with some Wordpress plugins)
|
2013-07-17 01:28:20 +02:00
|
|
|
if (is_array($removed_items)) {
|
2013-07-14 18:00:42 +02:00
|
|
|
|
2013-07-17 01:28:20 +02:00
|
|
|
$items_to_remove = array_slice($removed_items, 2);
|
2013-07-14 18:00:42 +02:00
|
|
|
|
2013-07-17 01:28:20 +02:00
|
|
|
if (! empty($items_to_remove)) {
|
|
|
|
|
|
|
|
\PicoTools\singleton('db')
|
|
|
|
->table('items')
|
|
|
|
->in('id', $items_to_remove)
|
|
|
|
->eq('status', 'removed')
|
|
|
|
->eq('feed_id', $feed_id)
|
|
|
|
->remove();
|
|
|
|
}
|
2013-07-14 18:00:42 +02:00
|
|
|
}
|
2013-04-23 04:44:28 +02:00
|
|
|
}
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
$db->closeTransaction();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-06 16:50:37 +02:00
|
|
|
function get_config_value($name)
|
|
|
|
{
|
|
|
|
if (! isset($_SESSION)) {
|
|
|
|
|
|
|
|
return \PicoTools\singleton('db')->table('config')->findOneColumn($name);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
if (! isset($_SESSION['config'])) {
|
|
|
|
$_SESSION['config'] = get_config();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($_SESSION['config'][$name])) {
|
|
|
|
return $_SESSION['config'][$name];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
function get_config()
|
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('config')
|
2013-09-07 04:57:09 +02:00
|
|
|
->columns(
|
|
|
|
'username',
|
|
|
|
'language',
|
|
|
|
'autoflush',
|
|
|
|
'nocontent',
|
|
|
|
'items_per_page',
|
|
|
|
'theme',
|
|
|
|
'api_token',
|
|
|
|
'feed_token',
|
|
|
|
'auth_google_token',
|
2013-09-19 03:02:46 +02:00
|
|
|
'auth_mozilla_token',
|
|
|
|
'items_sorting_direction'
|
2013-09-07 04:57:09 +02:00
|
|
|
)
|
2013-02-18 03:48:21 +01:00
|
|
|
->findOne();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-04 04:05:10 +02:00
|
|
|
function get_user($username)
|
2013-02-18 03:48:21 +01:00
|
|
|
{
|
|
|
|
return \PicoTools\singleton('db')
|
|
|
|
->table('config')
|
2013-05-26 19:09:34 +02:00
|
|
|
->columns('username', 'password', 'language')
|
2013-07-04 04:05:10 +02:00
|
|
|
->eq('username', $username)
|
2013-02-18 03:48:21 +01:00
|
|
|
->findOne();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function validate_login(array $values)
|
|
|
|
{
|
|
|
|
$v = new Validator($values, array(
|
2013-04-13 03:08:55 +02:00
|
|
|
new Validators\Required('username', t('The user name is required')),
|
|
|
|
new Validators\MaxLength('username', t('The maximum length is 50 characters'), 50),
|
|
|
|
new Validators\Required('password', t('The password is required'))
|
2013-02-18 03:48:21 +01:00
|
|
|
));
|
|
|
|
|
|
|
|
$result = $v->execute();
|
|
|
|
$errors = $v->getErrors();
|
|
|
|
|
|
|
|
if ($result) {
|
|
|
|
|
2013-07-04 04:05:10 +02:00
|
|
|
$user = get_user($values['username']);
|
2013-02-18 03:48:21 +01:00
|
|
|
|
2013-03-20 05:21:48 +01:00
|
|
|
if ($user && \password_verify($values['password'], $user['password'])) {
|
2013-02-18 03:48:21 +01:00
|
|
|
|
2013-04-13 03:08:55 +02:00
|
|
|
unset($user['password']);
|
2013-07-06 16:50:37 +02:00
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
$_SESSION['user'] = $user;
|
2013-07-06 16:50:37 +02:00
|
|
|
$_SESSION['config'] = get_config();
|
2013-02-18 03:48:21 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
$result = false;
|
2013-04-13 03:08:55 +02:00
|
|
|
$errors['login'] = t('Bad username or password');
|
2013-02-18 03:48:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return array(
|
|
|
|
$result,
|
|
|
|
$errors
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function validate_config_update(array $values)
|
|
|
|
{
|
|
|
|
if (! empty($values['password'])) {
|
|
|
|
|
|
|
|
$v = new Validator($values, array(
|
2013-04-13 03:08:55 +02:00
|
|
|
new Validators\Required('username', t('The user name is required')),
|
|
|
|
new Validators\MaxLength('username', t('The maximum length is 50 characters'), 50),
|
|
|
|
new Validators\Required('password', t('The password is required')),
|
|
|
|
new Validators\MinLength('password', t('The minimum length is 6 characters'), 6),
|
|
|
|
new Validators\Required('confirmation', t('The confirmation is required')),
|
2013-05-23 13:44:45 +02:00
|
|
|
new Validators\Equals('password', 'confirmation', t('Passwords doesn\'t match')),
|
2013-07-06 16:50:37 +02:00
|
|
|
new Validators\Required('autoflush', t('Value required')),
|
|
|
|
new Validators\Required('items_per_page', t('Value required')),
|
|
|
|
new Validators\Integer('items_per_page', t('Must be an integer')),
|
2013-07-17 03:58:11 +02:00
|
|
|
new Validators\Required('theme', t('Value required')),
|
2013-02-18 03:48:21 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
$v = new Validator($values, array(
|
2013-04-13 03:08:55 +02:00
|
|
|
new Validators\Required('username', t('The user name is required')),
|
2013-07-28 21:44:51 +02:00
|
|
|
new Validators\MaxLength('username', t('The maximum length is 50 characters'), 50),
|
|
|
|
new Validators\Required('autoflush', t('Value required')),
|
|
|
|
new Validators\Required('items_per_page', t('Value required')),
|
|
|
|
new Validators\Integer('items_per_page', t('Must be an integer')),
|
|
|
|
new Validators\Required('theme', t('Value required')),
|
2013-02-18 03:48:21 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
return array(
|
|
|
|
$v->execute(),
|
|
|
|
$v->getErrors()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function save_config(array $values)
|
|
|
|
{
|
2013-07-06 17:47:20 +02:00
|
|
|
// Update the password if needed
|
2013-03-18 02:57:47 +01:00
|
|
|
if (! empty($values['password'])) {
|
2013-03-20 05:21:48 +01:00
|
|
|
$values['password'] = \password_hash($values['password'], PASSWORD_BCRYPT);
|
2013-07-17 03:58:11 +02:00
|
|
|
} else {
|
2013-03-18 02:57:47 +01:00
|
|
|
unset($values['password']);
|
|
|
|
}
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
unset($values['confirmation']);
|
|
|
|
|
2013-07-06 16:50:37 +02:00
|
|
|
// Reload configuration in session
|
|
|
|
$_SESSION['config'] = $values;
|
|
|
|
|
2013-07-06 17:47:20 +02:00
|
|
|
// Reload translations for flash session message
|
2013-04-13 03:27:51 +02:00
|
|
|
\PicoTools\Translator\load($values['language']);
|
|
|
|
|
2013-06-11 04:09:51 +02:00
|
|
|
// If the user does not want content of feeds, remove it in previous ones
|
2013-07-01 16:03:43 +02:00
|
|
|
if (isset($values['nocontent']) && (bool) $values['nocontent']) {
|
2013-06-11 04:09:51 +02:00
|
|
|
\PicoTools\singleton('db')->table('items')->update(array('content' => ''));
|
2013-06-06 17:54:22 +02:00
|
|
|
}
|
|
|
|
|
2013-02-18 03:48:21 +01:00
|
|
|
return \PicoTools\singleton('db')->table('config')->update($values);
|
|
|
|
}
|