4
0

entryController.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. /**
  3. * Controller to handle every entry actions.
  4. */
  5. class FreshRSS_entry_Controller extends FreshRSS_ActionController {
  6. /**
  7. * JavaScript request or not.
  8. */
  9. private bool $ajax = false;
  10. /**
  11. * This action is called before every other action in that class. It is
  12. * the common boilerplate for every action. It is triggered by the
  13. * underlying framework.
  14. */
  15. public function firstAction(): void {
  16. if (!FreshRSS_Auth::hasAccess()) {
  17. Minz_Error::error(403);
  18. }
  19. // If ajax request, we do not print layout
  20. $this->ajax = Minz_Request::paramBoolean('ajax');
  21. if ($this->ajax) {
  22. $this->view->_layout(null);
  23. Minz_Request::_param('ajax');
  24. }
  25. }
  26. /**
  27. * Mark one or several entries as read (or not!).
  28. *
  29. * If request concerns several entries, it MUST be a POST request.
  30. * If request concerns several entries, only mark them as read is available.
  31. *
  32. * Parameters are:
  33. * - id (default: false)
  34. * - get (default: false) /(c_\d+|f_\d+|s|a)/
  35. * - nextGet (default: $get)
  36. * - idMax (default: 0)
  37. * - is_read (default: true)
  38. */
  39. public function readAction(): void {
  40. $id = Minz_Request::param('id');
  41. $get = Minz_Request::paramString('get');
  42. $next_get = Minz_Request::paramString('nextGet') ?: $get;
  43. $id_max = Minz_Request::paramString('idMax') ?: '0';
  44. $is_read = Minz_Request::paramTernary('is_read') ?? true;
  45. FreshRSS_Context::$search = new FreshRSS_BooleanSearch(Minz_Request::paramString('search'));
  46. FreshRSS_Context::$state = Minz_Request::paramInt('state');
  47. if (FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_FAVORITE)) {
  48. FreshRSS_Context::$state = FreshRSS_Entry::STATE_FAVORITE;
  49. } elseif (FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_NOT_FAVORITE)) {
  50. FreshRSS_Context::$state = FreshRSS_Entry::STATE_NOT_FAVORITE;
  51. } else {
  52. FreshRSS_Context::$state = 0;
  53. }
  54. $params = [];
  55. $this->view->tagsForEntries = [];
  56. $entryDAO = FreshRSS_Factory::createEntryDao();
  57. if ($id == false) {
  58. // id is false? It MUST be a POST request!
  59. if (!Minz_Request::isPost()) {
  60. Minz_Request::bad(_t('feedback.access.not_found'), ['c' => 'index', 'a' => 'index']);
  61. return;
  62. }
  63. if (!$get) {
  64. // No get? Mark all entries as read (from $id_max)
  65. $entryDAO->markReadEntries($id_max, false, FreshRSS_Feed::PRIORITY_MAIN_STREAM, FreshRSS_Feed::PRIORITY_IMPORTANT, null, 0, $is_read);
  66. } else {
  67. $type_get = $get[0];
  68. $get = (int)substr($get, 2);
  69. switch($type_get) {
  70. case 'c':
  71. $entryDAO->markReadCat($get, $id_max, FreshRSS_Context::$search, FreshRSS_Context::$state, $is_read);
  72. break;
  73. case 'f':
  74. $entryDAO->markReadFeed($get, $id_max, FreshRSS_Context::$search, FreshRSS_Context::$state, $is_read);
  75. break;
  76. case 's':
  77. $entryDAO->markReadEntries($id_max, true, null, FreshRSS_Feed::PRIORITY_IMPORTANT,
  78. FreshRSS_Context::$search, FreshRSS_Context::$state, $is_read);
  79. break;
  80. case 'a':
  81. $entryDAO->markReadEntries($id_max, false, FreshRSS_Feed::PRIORITY_MAIN_STREAM, FreshRSS_Feed::PRIORITY_IMPORTANT,
  82. FreshRSS_Context::$search, FreshRSS_Context::$state, $is_read);
  83. break;
  84. case 'i':
  85. $entryDAO->markReadEntries($id_max, false, FreshRSS_Feed::PRIORITY_IMPORTANT, null,
  86. FreshRSS_Context::$search, FreshRSS_Context::$state, $is_read);
  87. break;
  88. case 't':
  89. $entryDAO->markReadTag($get, $id_max, FreshRSS_Context::$search, FreshRSS_Context::$state, $is_read);
  90. break;
  91. case 'T':
  92. $entryDAO->markReadTag(0, $id_max, FreshRSS_Context::$search, FreshRSS_Context::$state, $is_read);
  93. break;
  94. }
  95. if ($next_get !== 'a') {
  96. // Redirect to the correct page (category, feed or starred)
  97. // Not "a" because it is the default value if nothing is given.
  98. $params['get'] = $next_get;
  99. }
  100. }
  101. } else {
  102. $ids = is_array($id) ? $id : [$id];
  103. $entryDAO->markRead($ids, $is_read);
  104. $tagDAO = FreshRSS_Factory::createTagDao();
  105. $tagsForEntries = $tagDAO->getTagsForEntries($ids) ?: [];
  106. $tags = [];
  107. foreach ($tagsForEntries as $line) {
  108. $tags['t_' . $line['id_tag']][] = $line['id_entry'];
  109. }
  110. $this->view->tagsForEntries = $tags;
  111. }
  112. if (!$this->ajax) {
  113. Minz_Request::good(
  114. $is_read ? _t('feedback.sub.articles.marked_read') : _t('feedback.sub.articles.marked_unread'),
  115. [
  116. 'c' => 'index',
  117. 'a' => 'index',
  118. 'params' => $params,
  119. ]
  120. );
  121. }
  122. }
  123. /**
  124. * This action marks an entry as favourite (bookmark) or not.
  125. *
  126. * Parameter is:
  127. * - id (default: false)
  128. * - is_favorite (default: true)
  129. * If id is false, nothing happened.
  130. */
  131. public function bookmarkAction(): void {
  132. $id = Minz_Request::paramString('id');
  133. $is_favourite = Minz_Request::paramTernary('is_favorite') ?? true;
  134. if ($id != '') {
  135. $entryDAO = FreshRSS_Factory::createEntryDao();
  136. $entryDAO->markFavorite($id, $is_favourite);
  137. }
  138. if (!$this->ajax) {
  139. Minz_Request::forward([
  140. 'c' => 'index',
  141. 'a' => 'index',
  142. ], true);
  143. }
  144. }
  145. /**
  146. * This action optimizes database to reduce its size.
  147. *
  148. * This action should be reached by a POST request.
  149. *
  150. * @todo move this action in configure controller.
  151. * @todo call this action through web-cron when available
  152. */
  153. public function optimizeAction(): void {
  154. $url_redirect = [
  155. 'c' => 'configure',
  156. 'a' => 'archiving',
  157. ];
  158. if (!Minz_Request::isPost()) {
  159. Minz_Request::forward($url_redirect, true);
  160. }
  161. if (function_exists('set_time_limit')) {
  162. @set_time_limit(300);
  163. }
  164. $databaseDAO = FreshRSS_Factory::createDatabaseDAO();
  165. $databaseDAO->optimize();
  166. $feedDAO = FreshRSS_Factory::createFeedDao();
  167. $feedDAO->updateCachedValues();
  168. invalidateHttpCache();
  169. Minz_Request::good(_t('feedback.admin.optimization_complete'), $url_redirect);
  170. }
  171. /**
  172. * This action purges old entries from feeds.
  173. *
  174. * @todo should be a POST request
  175. * @todo should be in feedController
  176. */
  177. public function purgeAction(): void {
  178. if (function_exists('set_time_limit')) {
  179. @set_time_limit(300);
  180. }
  181. $feedDAO = FreshRSS_Factory::createFeedDao();
  182. $feeds = $feedDAO->listFeeds();
  183. $nb_total = 0;
  184. invalidateHttpCache();
  185. $feedDAO->beginTransaction();
  186. foreach ($feeds as $feed) {
  187. $nb_total += $feed->cleanOldEntries();
  188. }
  189. $feedDAO->updateCachedValues();
  190. $feedDAO->commit();
  191. $databaseDAO = FreshRSS_Factory::createDatabaseDAO();
  192. $databaseDAO->minorDbMaintenance();
  193. invalidateHttpCache();
  194. Minz_Request::good(_t('feedback.sub.purge_completed', $nb_total), [
  195. 'c' => 'configure',
  196. 'a' => 'archiving',
  197. ]);
  198. }
  199. }