From 21e63595083d556bd4a6ff56c4ccaab5cd318dd4 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 5 Nov 2016 15:08:10 +0100 Subject: Add compatibility with git in Web update https://github.com/FreshRSS/FreshRSS/issues/907 https://github.com/FreshRSS/FreshRSS/issues/1355 --- app/Controllers/updateController.php | 159 ++++++++++++++++++++++++----------- 1 file changed, 112 insertions(+), 47 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php index 64c984b04..8f939dbdb 100644 --- a/app/Controllers/updateController.php +++ b/app/Controllers/updateController.php @@ -2,6 +2,45 @@ class FreshRSS_update_Controller extends Minz_ActionController { + public static function isGit() { + return is_dir(FRESHRSS_PATH . '/.git/'); + } + + public static function hasGitUpdate() { + $cwd = getcwd(); + chdir(FRESHRSS_PATH); + $output = array(); + try { + exec('git fetch', $output, $return); + if ($return == 0) { + exec('git status -sb --porcelain remote', $output, $return); + } else { + $line = is_array($output) ? implode('; ', $output) : '' . $output; + Minz_Log::warning('git fetch warning:' . $line); + } + } catch (Exception $e) { + Minz_Log::warning('git fetch error:' . $e->getMessage()); + } + chdir($cwd); + $line = is_array($output) ? implode('; ', $output) : '' . $output; + return strpos($line, '[behind') !== false; + } + + public static function gitPull() { + $cwd = getcwd(); + chdir(FRESHRSS_PATH); + $output = array(); + $return = 1; + try { + exec('git pull --ff-only', $output, $return); + } catch (Exception $e) { + Minz_Log::warning('git pull error:' . $e->getMessage()); + } + chdir($cwd); + $line = is_array($output) ? implode('; ', $output) : '' . $output; + return $return == 0 ? true : 'Git error: ' . $line; + } + public function firstAction() { if (!FreshRSS_Auth::hasAccess('admin')) { Minz_Error::error(403); @@ -20,7 +59,7 @@ class FreshRSS_update_Controller extends Minz_ActionController { public function indexAction() { Minz_View::prependTitle(_t('admin.update.title') . ' · '); - if (file_exists(UPDATE_FILENAME) && !is_writable(FRESHRSS_PATH)) { + if (!is_writable(FRESHRSS_PATH)) { $this->view->message = array( 'status' => 'bad', 'title' => _t('gen.short.damn'), @@ -53,49 +92,65 @@ class FreshRSS_update_Controller extends Minz_ActionController { return; } - $auto_update_url = FreshRSS_Context::$system_conf->auto_update_url . '?v=' . FRESHRSS_VERSION; - $c = curl_init($auto_update_url); - curl_setopt($c, CURLOPT_RETURNTRANSFER, true); - curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true); - curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2); - $result = curl_exec($c); - $c_status = curl_getinfo($c, CURLINFO_HTTP_CODE); - $c_error = curl_error($c); - curl_close($c); - - if ($c_status !== 200) { - Minz_Log::warning( - 'Error during update (HTTP code ' . $c_status . '): ' . $c_error - ); + $script = ''; + $version = ''; - $this->view->message = array( - 'status' => 'bad', - 'title' => _t('gen.short.damn'), - 'body' => _t('feedback.update.server_not_found', $auto_update_url) - ); - return; - } - - $res_array = explode("\n", $result, 2); - $status = $res_array[0]; - if (strpos($status, 'UPDATE') !== 0) { - $this->view->message = array( - 'status' => 'bad', - 'title' => _t('gen.short.damn'), - 'body' => _t('feedback.update.none') - ); + if (self::isGit()) { + if (self::hasGitUpdate()) { + $version = 'git'; + } else { + $this->view->message = array( + 'status' => 'bad', + 'title' => _t('gen.short.damn'), + 'body' => _t('feedback.update.none') + ); + @touch(join_path(DATA_PATH, 'last_update.txt')); + return; + } + } else { + $auto_update_url = FreshRSS_Context::$system_conf->auto_update_url . '?v=' . FRESHRSS_VERSION; + Minz_Log::debug('HTTP GET ' . $auto_update_url); + $c = curl_init($auto_update_url); + curl_setopt($c, CURLOPT_RETURNTRANSFER, true); + curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2); + $result = curl_exec($c); + $c_status = curl_getinfo($c, CURLINFO_HTTP_CODE); + $c_error = curl_error($c); + curl_close($c); + + if ($c_status !== 200) { + Minz_Log::warning( + 'Error during update (HTTP code ' . $c_status . '): ' . $c_error + ); + + $this->view->message = array( + 'status' => 'bad', + 'title' => _t('gen.short.damn'), + 'body' => _t('feedback.update.server_not_found', $auto_update_url) + ); + return; + } - @touch(join_path(DATA_PATH, 'last_update.txt')); + $res_array = explode("\n", $result, 2); + $status = $res_array[0]; + if (strpos($status, 'UPDATE') !== 0) { + $this->view->message = array( + 'status' => 'bad', + 'title' => _t('gen.short.damn'), + 'body' => _t('feedback.update.none') + ); + @touch(join_path(DATA_PATH, 'last_update.txt')); + return; + } - return; + $script = $res_array[1]; + $version = explode(' ', $status, 2); + $version = $version[1]; } - $script = $res_array[1]; if (file_put_contents(UPDATE_FILENAME, $script) !== false) { - $version = explode(' ', $status, 2); - $version = $version[1]; @file_put_contents(join_path(DATA_PATH, 'last_update.txt'), $version); - Minz_Request::forward(array('c' => 'update'), true); } else { $this->view->message = array( @@ -111,10 +166,13 @@ class FreshRSS_update_Controller extends Minz_ActionController { Minz_Request::forward(array('c' => 'update'), true); } - require(UPDATE_FILENAME); - if (Minz_Request::param('post_conf', false)) { - $res = do_post_update(); + if (self::isGit()) { + $res = !self::hasGitUpdate(); + } else { + require(UPDATE_FILENAME); + $res = do_post_update(); + } Minz_ExtensionManager::callHook('post_update'); @@ -126,14 +184,21 @@ class FreshRSS_update_Controller extends Minz_ActionController { Minz_Request::bad(_t('feedback.update.error', $res), array('c' => 'update', 'a' => 'index')); } - } - - if (Minz_Request::isPost()) { - save_info_update(); - } + } else { + $res = false; - if (!need_info_update()) { - $res = apply_update(); + if (self::isGit()) { + $res = self::gitPull(); + } else { + if (Minz_Request::isPost()) { + save_info_update(); + } + if (!need_info_update()) { + $res = apply_update(); + } else { + return; + } + } if ($res === true) { Minz_Request::forward(array( -- cgit v1.2.3 From aeda49a7d271c2196fcba0d3b2b15d31ad0b33b5 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 5 Nov 2016 20:48:46 +0100 Subject: Add CLI for user information + Fix last user activity https://github.com/FreshRSS/FreshRSS/issues/1345 --- CHANGELOG.md | 4 ++++ app/Controllers/feedController.php | 4 ++++ app/Models/Auth.php | 2 +- app/Models/EntryDAO.php | 5 +++++ app/Models/UserDAO.php | 6 +++++- cli/README.md | 16 ++++++++++++++ cli/user-info.php | 43 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 cli/user-info.php (limited to 'app/Controllers') diff --git a/CHANGELOG.md b/CHANGELOG.md index 77ec29aed..92220f1f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 2016-xx-xx FreshRSS 1.7.0-dev +* CLI + * New command `./cli/user-info.php` to get some user information [#1345](https://github.com/FreshRSS/FreshRSS/issues/1345) +* Bug fixing + * Fix bug in estimating last user activity [#1358](https://github.com/FreshRSS/FreshRSS/issues/1358) ## 2016-11-02 FreshRSS 1.6.1 diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index c4115584a..f71f26a4e 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -27,6 +27,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } public static function addFeed($url, $title = '', $cat_id = 0, $new_cat_name = '', $http_auth = '') { + FreshRSS_UserDAO::touch(); @set_time_limit(300); $catDAO = new FreshRSS_CategoryDAO(); @@ -484,6 +485,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { if ($feed_id <= 0 || $feed_name == '') { return false; } + FreshRSS_UserDAO::touch(); $feedDAO = FreshRSS_Factory::createFeedDao(); return $feedDAO->updateFeed($feed_id, array('name' => $feed_name)); } @@ -492,6 +494,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { if ($feed_id <= 0 || ($cat_id <= 0 && $new_cat_name == '')) { return false; } + FreshRSS_UserDAO::touch(); $catDAO = new FreshRSS_CategoryDAO(); if ($cat_id > 0) { @@ -540,6 +543,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } public static function deleteFeed($feed_id) { + FreshRSS_UserDAO::touch(); $feedDAO = FreshRSS_Factory::createFeedDao(); if ($feedDAO->deleteFeed($feed_id)) { // TODO: Delete old favicon diff --git a/app/Models/Auth.php b/app/Models/Auth.php index b93942e19..3313fdf3f 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -25,7 +25,7 @@ class FreshRSS_Auth { self::giveAccess(); } elseif (self::accessControl()) { self::giveAccess(); - FreshRSS_UserDAO::touch($current_user); + FreshRSS_UserDAO::touch(); } else { // Be sure all accesses are removed! self::removeAccess(); diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index 58f2c1a79..d8a4a486d 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -241,6 +241,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { if (count($ids) < 1) { return 0; } + FreshRSS_UserDAO::touch(); $sql = 'UPDATE `' . $this->prefix . 'entry` ' . 'SET is_favorite=? ' . 'WHERE id IN (' . str_repeat('?,', count($ids) - 1). '?)'; @@ -315,6 +316,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { * @return integer affected rows */ public function markRead($ids, $is_read = true) { + FreshRSS_UserDAO::touch(); if (is_array($ids)) { //Many IDs at once (used by API) if (count($ids) < 6) { //Speed heuristics $affected = 0; @@ -379,6 +381,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { * @return integer affected rows */ public function markReadEntries($idMax = 0, $onlyFavorites = false, $priorityMin = 0, $filter = null, $state = 0) { + FreshRSS_UserDAO::touch(); if ($idMax == 0) { $idMax = time() . '000000'; Minz_Log::debug('Calling markReadEntries(0) is deprecated!'); @@ -421,6 +424,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { * @return integer affected rows */ public function markReadCat($id, $idMax = 0, $filter = null, $state = 0) { + FreshRSS_UserDAO::touch(); if ($idMax == 0) { $idMax = time() . '000000'; Minz_Log::debug('Calling markReadCat(0) is deprecated!'); @@ -458,6 +462,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { * @return integer affected rows */ public function markReadFeed($id_feed, $idMax = 0, $filter = null, $state = 0) { + FreshRSS_UserDAO::touch(); if ($idMax == 0) { $idMax = time() . '000000'; Minz_Log::debug('Calling markReadFeed(0) is deprecated!'); diff --git a/app/Models/UserDAO.php b/app/Models/UserDAO.php index a95ee6bc4..190954b1a 100644 --- a/app/Models/UserDAO.php +++ b/app/Models/UserDAO.php @@ -84,7 +84,11 @@ class FreshRSS_UserDAO extends Minz_ModelPdo { return is_dir(join_path(DATA_PATH , 'users', $username)); } - public static function touch($username) { + public static function touch($username = '') { + if (($username == '') || (!ctype_alnum($username))) { + $username = Minz_Session::param('currentUser', '_'); + } + Minz_Log::debug('touch ' . $username); return touch(join_path(DATA_PATH , 'users', $username, 'config.php')); } diff --git a/cli/README.md b/cli/README.md index 444606b50..09dcbd27e 100644 --- a/cli/README.md +++ b/cli/README.md @@ -55,4 +55,20 @@ cd /usr/share/FreshRSS ./cli/export-opml-for-user.php --user username > /path/to/file.opml.xml ./cli/export-zip-for-user.php --user username ( --max-feed-entries 100 ) > /path/to/file.zip + +./cli/user-info.php -h --user username +# -h is to use a human-readable format +# --user can be a username, or '*' to loop on all users +# Returns a * if the user is admin, the name of the user, the date/time of last action, and the size occupied +``` + + +## Unix piping + +It is possible to invoke a command multiple times, e.g. with different usernames, thanks to the `xargs -n1` command. + +Example showing user information for all users which username starts with 'a': + +```sh +./cli/list-users.php | grep '^a' | xargs -n1 ./cli/user-info.php -h --user ``` diff --git a/cli/user-info.php b/cli/user-info.php new file mode 100644 index 000000000..5b26ecb15 --- /dev/null +++ b/cli/user-info.php @@ -0,0 +1,43 @@ +#!/usr/bin/php +default_user ? '*' : ' ', "\t"; + + if (isset($options['h'])) { //Human format + echo + $username, "\t", + date('c', FreshRSS_UserDAO::mtime($username)), "\t", + formatSize($entryDAO->size()), "\t", + "\n"; + } else { + echo + $username, "\t", + FreshRSS_UserDAO::mtime($username), "\t", + $entryDAO->size(), "\t", + "\n"; + } +} -- cgit v1.2.3 From f59de4e2b679efb1ba4bbfd576a5ea07422cc169 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 15 Nov 2016 20:43:06 +0100 Subject: Stream JSON export Avoid large in-memory copies https://github.com/FreshRSS/FreshRSS/issues/1372 --- app/Controllers/importExportController.php | 4 +- app/Models/EntryDAO.php | 42 ++++++++------ app/views/helpers/export/articles.phtml | 92 +++++++++++++++++------------- 3 files changed, 78 insertions(+), 60 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 3ba91a243..d86587ea9 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -641,13 +641,13 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $this->view->list_title = _t('sub.import_export.starred_list'); $this->view->type = 'starred'; $unread_fav = $this->entryDAO->countUnreadReadFavorites(); - $this->view->entries = $this->entryDAO->listWhere( + $this->view->entriesRaw = $this->entryDAO->listWhereRaw( 's', '', FreshRSS_Entry::STATE_ALL, 'ASC', $unread_fav['all'] ); } elseif ($type === 'feed' && $feed != null) { $this->view->list_title = _t('sub.import_export.feed_list', $feed->name()); $this->view->type = 'feed/' . $feed->id(); - $this->view->entries = $this->entryDAO->listWhere( + $this->view->entriesRaw = $this->entryDAO->listWhereRaw( 'f', $feed->id(), FreshRSS_Entry::STATE_ALL, 'ASC', $maxFeedEntries ); diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index d8a4a486d..397471baa 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -518,7 +518,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { $stm->execute($values); $res = $stm->fetchAll(PDO::FETCH_ASSOC); - $entries = self::daoToEntry($res); + $entries = self::daoToEntries($res); return isset($entries[0]) ? $entries[0] : null; } @@ -533,7 +533,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { $stm->execute($values); $res = $stm->fetchAll(PDO::FETCH_ASSOC); - $entries = self::daoToEntry($res); + $entries = self::daoToEntries($res); return isset($entries[0]) ? $entries[0] : null; } @@ -666,7 +666,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { . ($limit > 0 ? ' LIMIT ' . $limit : '')); //TODO: See http://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/ } - public function listWhere($type = 'a', $id = '', $state = FreshRSS_Entry::STATE_ALL, $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0) { + public function listWhereRaw($type = 'a', $id = '', $state = FreshRSS_Entry::STATE_ALL, $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0) { list($values, $sql) = $this->sqlListWhere($type, $id, $state, $order, $limit, $firstId, $filter, $date_min); $sql = 'SELECT e0.id, e0.guid, e0.title, e0.author, ' @@ -680,8 +680,12 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { $stm = $this->bd->prepare($sql); $stm->execute($values); + return $stm; + } - return self::daoToEntry($stm->fetchAll(PDO::FETCH_ASSOC)); + public function listWhere($type = 'a', $id = '', $state = FreshRSS_Entry::STATE_ALL, $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0) { + $stm = $this->listWhereRaw($type, $id, $state, $order, $limit, $firstId, $filter, $date_min); + return self::daoToEntries($stm->fetchAll(PDO::FETCH_ASSOC)); } public function listIdsWhere($type = 'a', $id = '', $state = FreshRSS_Entry::STATE_ALL, $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0) { //For API @@ -810,15 +814,8 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { return $res[0]; } - public static function daoToEntry($listDAO) { - $list = array(); - - if (!is_array($listDAO)) { - $listDAO = array($listDAO); - } - - foreach ($listDAO as $key => $dao) { - $entry = new FreshRSS_Entry( + public static function daoToEntry($dao) { + $entry = new FreshRSS_Entry( $dao['id_feed'], $dao['guid'], $dao['title'], @@ -830,10 +827,21 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { $dao['is_favorite'], $dao['tags'] ); - if (isset($dao['id'])) { - $entry->_id($dao['id']); - } - $list[] = $entry; + if (isset($dao['id'])) { + $entry->_id($dao['id']); + } + return $entry; + } + + private static function daoToEntries($listDAO) { + $list = array(); + + if (!is_array($listDAO)) { + $listDAO = array($listDAO); + } + + foreach ($listDAO as $key => $dao) { + $list[] = self::daoToEntry($dao); } unset($listDAO); diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml index ffdca1daa..2ad4a3abf 100644 --- a/app/views/helpers/export/articles.phtml +++ b/app/views/helpers/export/articles.phtml @@ -1,47 +1,57 @@ 'user/' . str_replace('/', '', $username) . '/state/org.freshrss/' . $this->type, - 'title' => $this->list_title, - 'author' => $username, - 'items' => array() - ); + $options = 0; + if (version_compare(PHP_VERSION, '5.4.0') >= 0) { + $options = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; + } - foreach ($this->entries as $entry) { - if (!isset($this->feed)) { - $feed = FreshRSS_CategoryDAO::findFeed($this->categories, $entry->feed ()); - } else { - $feed = $this->feed; - } + $articles = array( + 'id' => 'user/' . str_replace('/', '', $username) . '/state/org.freshrss/' . $this->type, + 'title' => $this->list_title, + 'author' => $username, + 'items' => array(), + ); - $articles['items'][] = array( - 'id' => $entry->guid(), - 'categories' => array_values($entry->tags()), - 'title' => $entry->title(), - 'author' => $entry->author(), - 'published' => $entry->date(true), - 'updated' => $entry->date(true), - 'alternate' => array(array( - 'href' => $entry->link(), - 'type' => 'text/html' - )), - 'content' => array( - 'content' => $entry->content() - ), - 'origin' => array( - 'streamId' => $feed->id(), - 'title' => $feed->name(), - 'htmlUrl' => $feed->website(), - 'feedUrl' => $feed->url() - ) - ); - } + echo rtrim(json_encode($articles, $options), " ]}\n\r\t"); + $first = true; - $options = 0; - if (version_compare(PHP_VERSION, '5.4.0') >= 0) { - $options = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; - } + foreach ($this->entriesRaw as $entryRaw) { + $entry = FreshRSS_EntryDAO::daoToEntry($entryRaw); + if (!isset($this->feed)) { + $feed = FreshRSS_CategoryDAO::findFeed($this->categories, $entry->feed ()); + } else { + $feed = $this->feed; + } - echo json_encode($articles, $options); -?> + $article = array( + 'id' => $entry->guid(), + 'categories' => array_values($entry->tags()), + 'title' => $entry->title(), + 'author' => $entry->author(), + 'published' => $entry->date(true), + 'updated' => $entry->date(true), + 'alternate' => array(array( + 'href' => $entry->link(), + 'type' => 'text/html', + )), + 'content' => array( + 'content' => $entry->content(), + ), + 'origin' => array( + 'streamId' => $feed->id(), + 'title' => $feed->name(), + 'htmlUrl' => $feed->website(), + 'feedUrl' => $feed->url(), + ) + ); + + if ($first) { + $first = false; + } else { + echo ",\n"; + } + echo json_encode($article, $options); + } + + echo "\n]}\n"; -- cgit v1.2.3 From 568b737b6c62ace5aaa6b3f6c968e2595ea70f55 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 15 Nov 2016 21:38:18 +0100 Subject: Function to disable MySQL buffering for large exports --- app/Controllers/importExportController.php | 2 ++ lib/Minz/ModelPdo.php | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'app/Controllers') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index d86587ea9..6ae89defb 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -531,6 +531,8 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $this->entryDAO = FreshRSS_Factory::createEntryDao($username); $this->feedDAO = FreshRSS_Factory::createFeedDao($username); + $this->entryDAO->disableBuffering(); + if ($export_feeds === true) { //All feeds $export_feeds = $this->feedDAO->listFeedsIds(); diff --git a/lib/Minz/ModelPdo.php b/lib/Minz/ModelPdo.php index 6e8d60bc9..caab1d114 100644 --- a/lib/Minz/ModelPdo.php +++ b/lib/Minz/ModelPdo.php @@ -116,6 +116,12 @@ class Minz_ModelPdo { self::$sharedBd = null; self::$sharedPrefix = ''; } + + public function disableBuffering() { + if ((self::$sharedDbType === 'mysql') && defined('PDO::MYSQL_ATTR_USE_BUFFERED_QUERY')) { + $this->bd->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + } + } } class MinzPDO extends PDO { -- cgit v1.2.3 From 332a4dec8690b658bcb878a20056aea33c673f69 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 24 Dec 2016 16:33:28 +0100 Subject: Option for cookie duration https://github.com/FreshRSS/FreshRSS/issues/1384 --- app/Controllers/authController.php | 4 ++++ app/Models/Auth.php | 11 ++++++++--- app/i18n/cz/gen.php | 2 +- app/i18n/de/gen.php | 2 +- app/i18n/en/gen.php | 2 +- app/i18n/fr/gen.php | 2 +- app/i18n/it/gen.php | 2 +- app/i18n/nl/gen.php | 2 +- app/i18n/ru/gen.php | 2 +- app/i18n/tr/gen.php | 2 +- app/views/auth/formLogin.phtml | 2 +- data/config.default.php | 3 +++ 12 files changed, 24 insertions(+), 12 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php index 9decba431..1398e4e49 100644 --- a/app/Controllers/authController.php +++ b/app/Controllers/authController.php @@ -113,6 +113,10 @@ class FreshRSS_auth_Controller extends Minz_ActionController { $file_mtime = @filemtime(PUBLIC_PATH . '/scripts/bcrypt.min.js'); Minz_View::appendScript(Minz_Url::display('/scripts/bcrypt.min.js?' . $file_mtime)); + $conf = Minz_Configuration::get('system'); + $limits = $conf->limits; + $this->view->cookie_days = round($limits['cookie_duration'] / 86400, 1); + if (Minz_Request::isPost()) { $nonce = Minz_Session::param('nonce'); $username = Minz_Request::param('username', ''); diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 3313fdf3f..042210eaf 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -219,8 +219,8 @@ class FreshRSS_FormAuth { } public static function makeCookie($username, $password_hash) { + $conf = Minz_Configuration::get('system'); do { - $conf = Minz_Configuration::get('system'); $token = sha1($conf->salt . $username . uniqid(mt_rand(), true)); $token_file = DATA_PATH . '/tokens/' . $token . '.txt'; } while (file_exists($token_file)); @@ -229,7 +229,9 @@ class FreshRSS_FormAuth { return false; } - $expire = time() + 2629744; //1 month //TODO: Use a configuration instead + $limits = $conf->limits; + $cookie_duration = empty($limits['cookie_duration']) ? 2629744 : $limits['cookie_duration']; + $expire = time() + $cookie_duration; Minz_Session::setLongTermCookie('FreshRSS_login', $token, $expire); return $token; } @@ -247,7 +249,10 @@ class FreshRSS_FormAuth { } public static function purgeTokens() { - $oldest = time() - 2629744; // 1 month // TODO: Use a configuration instead + $conf = Minz_Configuration::get('system'); + $limits = $conf->limits; + $cookie_duration = empty($limits['cookie_duration']) ? 2629744 : $limits['cookie_duration']; + $oldest = time() - $cookie_duration; foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $file_info) { // $extension = $file_info->getExtension(); doesn't work in PHP < 5.3.7 $extension = pathinfo($file_info->getFilename(), PATHINFO_EXTENSION); diff --git a/app/i18n/cz/gen.php b/app/i18n/cz/gen.php index e73325c55..6722a02e5 100644 --- a/app/i18n/cz/gen.php +++ b/app/i18n/cz/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Email', - 'keep_logged_in' => 'Zapamatovat přihlášení (1 měsíc)', + 'keep_logged_in' => 'Zapamatovat přihlášení (%s dny)', 'login' => 'Login', 'logout' => 'Odhlášení', 'password' => array( diff --git a/app/i18n/de/gen.php b/app/i18n/de/gen.php index c6e7f1ef3..3f1238edc 100644 --- a/app/i18n/de/gen.php +++ b/app/i18n/de/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'E-Mail-Adresse', - 'keep_logged_in' => 'Eingeloggt bleiben (1 Monat)', + 'keep_logged_in' => 'Eingeloggt bleiben (%s Tage)', 'login' => 'Anmelden', 'logout' => 'Abmelden', 'password' => array( diff --git a/app/i18n/en/gen.php b/app/i18n/en/gen.php index 17b47ba2f..c68a0f07b 100644 --- a/app/i18n/en/gen.php +++ b/app/i18n/en/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Email address', - 'keep_logged_in' => 'Keep me logged in (1 month)', + 'keep_logged_in' => 'Keep me logged in (%s days)', 'login' => 'Login', 'logout' => 'Logout', 'password' => array( diff --git a/app/i18n/fr/gen.php b/app/i18n/fr/gen.php index d61a716a7..b5dc098ae 100644 --- a/app/i18n/fr/gen.php +++ b/app/i18n/fr/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Adresse courriel', - 'keep_logged_in' => 'Rester connecté (1 mois)', + 'keep_logged_in' => 'Rester connecté (%s jours)', 'login' => 'Connexion', 'logout' => 'Déconnexion', 'password' => array( diff --git a/app/i18n/it/gen.php b/app/i18n/it/gen.php index c02ddd13a..01c0afba8 100644 --- a/app/i18n/it/gen.php +++ b/app/i18n/it/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Indirizzo email', - 'keep_logged_in' => 'Ricorda i dati (1 mese)', + 'keep_logged_in' => 'Ricorda i dati (%s giorni)', 'login' => 'Accedi', 'logout' => 'Esci', 'password' => array( diff --git a/app/i18n/nl/gen.php b/app/i18n/nl/gen.php index 7e03229c9..a156697d5 100644 --- a/app/i18n/nl/gen.php +++ b/app/i18n/nl/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Email adres', - 'keep_logged_in' => 'Ingelogd blijven voor (1 maand)', + 'keep_logged_in' => 'Ingelogd blijven voor (%s dagen)', 'login' => 'Log in', 'logout' => 'Log uit', 'password' => array( diff --git a/app/i18n/ru/gen.php b/app/i18n/ru/gen.php index eecd72749..130fac4ed 100644 --- a/app/i18n/ru/gen.php +++ b/app/i18n/ru/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Email address', - 'keep_logged_in' => 'Keep me logged in (1 month)', + 'keep_logged_in' => 'Keep me logged in (%s дней)', 'login' => 'Login', 'logout' => 'Logout', 'password' => array( diff --git a/app/i18n/tr/gen.php b/app/i18n/tr/gen.php index 865dbd4e2..7f9d3d8e0 100644 --- a/app/i18n/tr/gen.php +++ b/app/i18n/tr/gen.php @@ -22,7 +22,7 @@ return array( ), 'auth' => array( 'email' => 'Email adresleri', - 'keep_logged_in' => '(1 ay) oturumu açık tut', + 'keep_logged_in' => '(%s günler) oturumu açık tut', 'login' => 'Giriş', 'logout' => 'Çıkış', 'password' => array( diff --git a/app/views/auth/formLogin.phtml b/app/views/auth/formLogin.phtml index 4bbc8ed55..a8213b7ae 100644 --- a/app/views/auth/formLogin.phtml +++ b/app/views/auth/formLogin.phtml @@ -20,7 +20,7 @@

diff --git a/data/config.default.php b/data/config.default.php index 8b07b85cd..433207a9c 100644 --- a/data/config.default.php +++ b/data/config.default.php @@ -74,6 +74,9 @@ return array( 'limits' => array( + # Duration in seconds of the login cookie. + 'cookie_duration' => 2592000, + # Duration in seconds of the SimplePie cache, # during which a query to the RSS feed will return the local cached version. # Especially important for multi-user setups. -- cgit v1.2.3