2013-02-18 03:48:21 +01:00
< ? php
namespace Model ;
2013-07-29 02:10:07 +02:00
require_once 'vendor/PicoFeed/Encoding.php' ;
require_once 'vendor/PicoFeed/Filter.php' ;
require_once 'vendor/PicoFeed/Client.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-08-04 21:15:12 +02:00
const DB_VERSION = 13 ;
2013-07-06 16:50:37 +02:00
const HTTP_USERAGENT = 'Miniflux - http://miniflux.net' ;
const LIMIT_ALL = - 1 ;
2013-04-13 03:08:55 +02:00
function get_languages ()
{
return array (
2013-07-13 10:36:21 +02:00
'cs_CZ' => t ( 'Czech' ),
2013-04-13 03:08:55 +02:00
'en_US' => t ( 'English' ),
2013-07-02 00:02:47 +02:00
'fr_FR' => t ( 'French' ),
2013-07-08 20:56:26 +02:00
'de_DE' => t ( 'German' ),
2013-07-09 00:16:01 +02:00
'it_IT' => t ( 'Italian' ),
'zh_CN' => t ( 'Simplified Chinese' ),
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 ) {
file_put_contents (
DEBUG_DIRECTORY . '/miniflux_' . date ( 'YmdH' ) . '.debug' ,
var_export ( \PicoFeed\Logging :: $messages , true ) . PHP_EOL ,
FILE_APPEND | LOCK_EX
);
}
}
2013-07-28 21:44:51 +02:00
function generate_api_token ()
{
return substr ( base64_encode ( file_get_contents ( '/dev/urandom' , false , null , 0 , 20 )), 0 , 15 );
}
2013-02-18 03:48:21 +01:00
function export_feeds ()
{
$opml = new Export ( get_feeds ());
return $opml -> execute ();
}
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 ();
return true ;
}
return false ;
}
function import_feed ( $url )
{
$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 ) {
$feed = $parser -> execute ();
2013-04-07 03:15:42 +02:00
if ( $feed === false ) return false ;
if ( ! $feed -> title || ! $feed -> url ) 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 ,
'feed_url' => $reader -> getUrl ()
));
if ( $rs ) {
$feed_id = $db -> getConnection () -> getLastId ();
update_items ( $feed_id , $feed -> items );
2013-07-28 21:44:51 +02:00
return ( int ) $feed_id ;
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-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-07-06 16:50:37 +02:00
if ( ! $resource -> isModified ()) return true ;
2013-04-07 03:15:42 +02:00
$parser = $reader -> getParser ();
if ( $parser !== false ) {
$feed = $parser -> execute ();
if ( $feed !== false ) {
update_feed_cache_infos ( $feed_id , $resource -> getLastModified (), $resource -> getEtag ());
update_items ( $feed_id , $feed -> items );
return true ;
}
}
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-07-29 02:10:07 +02:00
function download_item ( $item_id )
{
require_once 'vendor/Readability/Readability.php' ;
$item = get_item ( $item_id );
$client = \PicoFeed\Client :: create ();
$client -> url = $item [ 'url' ];
$client -> timeout = HTTP_TIMEOUT ;
$client -> user_agent = HTTP_USERAGENT ;
$client -> execute ();
$content = $client -> getContent ();
if ( ! empty ( $content )) {
$content = \PicoFeed\Encoding :: toUTF8 ( $content );
$readability = new \Readability ( $content , $item [ 'url' ]);
if ( $readability -> init ()) {
// Get relevant content
$content = $readability -> getContent () -> innerHTML ;
// Filter content
$filter = new \PicoFeed\Filter ( $content , $item [ 'url' ]);
$content = $filter -> execute ();
2013-07-29 11:31:47 +02:00
$nocontent = ( bool ) get_config_value ( 'nocontent' );
if ( $nocontent === false ) {
// Save content
\PicoTools\singleton ( 'db' )
-> table ( 'items' )
-> eq ( 'id' , $item [ 'id' ])
-> save ( array ( 'content' => $content ));
}
2013-07-29 02:10:07 +02:00
return array (
'result' => true ,
'content' => $content
);
}
}
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 ();
}
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-07-06 04:37:19 +02:00
function get_unread_items ( $offset = null , $limit = null )
2013-02-18 03:48:21 +01:00
{
return \PicoTools\singleton ( 'db' )
-> table ( 'items' )
2013-08-04 20:22:53 +02:00
-> columns ( 'items.id' , 'items.title' , 'items.updated' , 'items.url' , 'items.content' , 'items.bookmark' , 'items.status' , 'items.feed_id' , 'feeds.site_url' , 'feeds.title AS feed_title' )
2013-02-18 03:48:21 +01:00
-> join ( 'feeds' , 'id' , 'feed_id' )
-> eq ( 'status' , 'unread' )
-> desc ( 'updated' )
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 get_read_items ( $offset = null , $limit = null )
2013-02-18 03:48:21 +01:00
{
return \PicoTools\singleton ( 'db' )
-> table ( 'items' )
2013-08-04 20:22:53 +02:00
-> columns ( 'items.id' , 'items.title' , 'items.updated' , 'items.url' , 'items.bookmark' , 'items.feed_id' , 'feeds.site_url' , 'feeds.title AS feed_title' )
2013-02-18 03:48:21 +01:00
-> join ( 'feeds' , 'id' , 'feed_id' )
-> eq ( 'status' , 'read' )
-> desc ( 'updated' )
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_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-04 20:22:53 +02:00
-> columns ( 'items.id' , 'items.title' , 'items.updated' , 'items.url' , 'items.status' , '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-06-04 13:38:54 +02:00
-> desc ( 'updated' )
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 )
-> in ( 'status' , array ( 'read' , 'unread' ))
-> count ();
}
function get_feed_items ( $feed_id , $offset = null , $limit = null )
{
return \PicoTools\singleton ( 'db' )
-> table ( 'items' )
2013-08-04 20:22:53 +02:00
-> columns ( 'items.id' , 'items.title' , 'items.updated' , 'items.url' , 'items.feed_id' , 'items.status' , 'items.bookmark' , 'feeds.site_url' )
2013-07-13 04:16:40 +02:00
-> join ( 'feeds' , 'id' , 'feed_id' )
-> in ( 'status' , array ( 'read' , 'unread' ))
-> eq ( 'feed_id' , $feed_id )
-> desc ( 'updated' )
-> 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 20:15:32 +02:00
function get_nav_item ( $item , $status = array ( 'unread' ), $bookmark = array ( 1 , 0 ))
2013-03-27 02:56:20 +01:00
{
2013-08-04 20:15:32 +02:00
$items = \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-03-27 02:56:20 +01:00
-> desc ( 'updated' )
2013-05-01 04:34:02 +02:00
-> 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-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-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
}
function update_items ( $feed_id , array $items )
{
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 ) {
$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-07-28 21:44:51 +02:00
-> columns ( 'username' , 'language' , 'autoflush' , 'nocontent' , 'items_per_page' , 'theme' , 'api_token' )
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 );
}