favoritedslice.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. // This file is part of GNU social - https://www.gnu.org/software/social
  3. //
  4. // GNU social is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Affero General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // GNU social is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Affero General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Affero General Public License
  15. // along with GNU social. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * List of popular notices
  18. *
  19. * @category Public
  20. * @package GNUsocial
  21. * @author Zach Copley <zach@status.net>
  22. * @author Evan Prodromou <evan@status.net>
  23. * @copyright 2008-2009 StatusNet, Inc.
  24. * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
  25. */
  26. defined('GNUSOCIAL') || die();
  27. class FavoritedSliceAction extends FavoritedAction
  28. {
  29. private $includeUsers = [];
  30. private $excludeUsers = [];
  31. /**
  32. * Take arguments for running
  33. *
  34. * @param array $args $_REQUEST args
  35. *
  36. * @return boolean success flag
  37. *
  38. * @todo move queries from showContent() to here
  39. */
  40. public function prepare(array $args = [])
  41. {
  42. parent::prepare($args);
  43. $this->slice = $this->arg('slice', 'default');
  44. $data = array();
  45. if (Event::handle('SlicedFavoritesGetSettings', array($this->slice, &$data))) {
  46. // TRANS: Client exception.
  47. throw new ClientException(_m('Unknown favorites slice.'));
  48. }
  49. if (isset($data['include'])) {
  50. $this->includeUsers = $data['include'];
  51. }
  52. if (isset($data['exclude'])) {
  53. $this->excludeUsers = $data['exclude'];
  54. }
  55. return true;
  56. }
  57. /**
  58. * Content area
  59. *
  60. * Shows the list of popular notices
  61. *
  62. * @return void
  63. */
  64. public function showContent()
  65. {
  66. $slice = $this->sliceWhereClause();
  67. if (!$slice) {
  68. return parent::showContent();
  69. }
  70. $weightexpr = common_sql_weight('fave.modified', common_config('popular', 'dropoff'));
  71. $cutoff = sprintf(
  72. "fave.modified > CURRENT_TIMESTAMP - INTERVAL '%d' SECOND",
  73. common_config('popular', 'cutoff')
  74. );
  75. $offset = ($this->page - 1) * NOTICES_PER_PAGE;
  76. $limit = NOTICES_PER_PAGE + 1;
  77. $qry = <<<END
  78. SELECT *
  79. FROM notice INNER JOIN (
  80. SELECT notice.id, {$weightexpr} AS weight
  81. FROM notice
  82. INNER JOIN fave ON notice.id = fave.notice_id
  83. WHERE {$cutoff} AND {$slice}
  84. GROUP BY notice.id
  85. ) AS t1 USING (id)
  86. ORDER BY weight DESC
  87. LIMIT {$limit} OFFSET {$offset};
  88. END;
  89. $notice = Memcached_DataObject::cachedQuery('Notice', $qry, 600);
  90. $nl = new NoticeList($notice, $this);
  91. $cnt = $nl->show();
  92. if ($cnt == 0) {
  93. $this->showEmptyList();
  94. }
  95. $this->pagination(
  96. $this->page > 1,
  97. $cnt > NOTICES_PER_PAGE,
  98. $this->page,
  99. 'favorited'
  100. );
  101. }
  102. private function sliceWhereClause()
  103. {
  104. $include = $this->nicknamesToIds($this->includeUsers);
  105. $exclude = $this->nicknamesToIds($this->excludeUsers);
  106. $sql = [];
  107. if (count($include) > 0) {
  108. $sql[] = 'notice.profile_id IN (' . implode(',', $include) . ')';
  109. }
  110. if (count($exclude) > 0) {
  111. $sql[] = 'notice.profile_id NOT IN (' . implode(',', $exclude) . ')';
  112. }
  113. return implode(' AND ', $sql) ?: false;
  114. }
  115. /**
  116. *
  117. * @param array $nicks array of user nicknames
  118. * @return array of profile/user IDs
  119. */
  120. private function nicknamesToIds($nicks)
  121. {
  122. $ids = array();
  123. foreach ($nicks as $nick) {
  124. // not the most efficient way for a big list!
  125. $user = User::getKV('nickname', $nick);
  126. if ($user) {
  127. $ids[] = intval($user->id);
  128. }
  129. }
  130. return $ids;
  131. }
  132. }