groupdirectory.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. <?php
  2. /**
  3. * StatusNet, the distributed open-source microblogging tool
  4. *
  5. * Output a group directory
  6. *
  7. * PHP version 5
  8. *
  9. * LICENCE: This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * @category Public
  23. * @package StatusNet
  24. * @author Zach Copley <zach@status.net>
  25. * @copyright 2011 StatusNet, Inc.
  26. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  27. * @link http://status.net/
  28. */
  29. if (!defined('STATUSNET'))
  30. {
  31. exit(1);
  32. }
  33. require_once INSTALLDIR . '/lib/publicgroupnav.php';
  34. /**
  35. * Group directory
  36. *
  37. * @category Directory
  38. * @package StatusNet
  39. * @author Zach Copley <zach@status.net>
  40. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  41. * @link http://status.net/
  42. */
  43. class GroupdirectoryAction extends Action
  44. {
  45. /**
  46. * The page we're on
  47. *
  48. * @var integer
  49. */
  50. public $page;
  51. /**
  52. * What to filter the search results by
  53. *
  54. * @var string
  55. */
  56. public $filter;
  57. /**
  58. * Column to sort by
  59. *
  60. * @var string
  61. */
  62. public $sort;
  63. /**
  64. * How to order search results, ascending or descending
  65. *
  66. * @var string
  67. */
  68. public $reverse;
  69. /**
  70. * Query
  71. *
  72. * @var string
  73. */
  74. public $q;
  75. /**
  76. * Title of the page
  77. *
  78. * @return string Title of the page
  79. */
  80. function title()
  81. {
  82. // @fixme: This looks kinda gross
  83. if ($this->filter == 'all') {
  84. if ($this->page != 1) {
  85. // TRANS: Title for group directory page. %d is a page number.
  86. return(sprintf(_m('Group Directory, page %d'), $this->page));
  87. }
  88. // TRANS: Title for group directory page.
  89. return _m('Group directory');
  90. } else if ($this->page == 1) {
  91. return sprintf(
  92. // TRANS: Title for group directory page when it is filtered.
  93. // TRANS: %s is the filter string.
  94. _m('Group directory - %s'),
  95. strtoupper($this->filter)
  96. );
  97. } else {
  98. return sprintf(
  99. // TRANS: Title for group directory page when it is filtered.
  100. // TRANS: %1$s is the filter string, %2$d is a page number.
  101. _m('Group directory - %1$s, page %2$d'),
  102. strtoupper($this->filter),
  103. $this->page
  104. );
  105. }
  106. }
  107. /**
  108. * Instructions for use
  109. *
  110. * @return instructions for use
  111. */
  112. function getInstructions()
  113. {
  114. // TRANS: Page instructions.
  115. return _m("After you join a group you can send messages to all other members\n".
  116. "using the syntax \"!groupname\".\n\n".
  117. "Browse groups, or search for groups by their name, location or topic.\n".
  118. "Separate the terms by spaces; they must be three characters or more.") . "\n";
  119. }
  120. /**
  121. * Is this page read-only?
  122. *
  123. * @return boolean true
  124. */
  125. function isReadOnly($args)
  126. {
  127. return true;
  128. }
  129. /**
  130. * Take arguments for running
  131. *
  132. * @param array $args $_REQUEST args
  133. *
  134. * @return boolean success flag
  135. */
  136. function prepare($args)
  137. {
  138. parent::prepare($args);
  139. $this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1;
  140. $this->filter = $this->arg('filter', 'all');
  141. $this->reverse = $this->boolean('reverse');
  142. $this->q = $this->trimmed('q');
  143. $this->sort = $this->arg('sort', 'nickname');
  144. common_set_returnto($this->selfUrl());
  145. return true;
  146. }
  147. /**
  148. * Handle request
  149. *
  150. * Shows the page
  151. *
  152. * @param array $args $_REQUEST args; handled in prepare()
  153. *
  154. * @return void
  155. */
  156. function handle($args)
  157. {
  158. parent::handle($args);
  159. $this->showPage();
  160. }
  161. /**
  162. * Show the page notice
  163. *
  164. * Shows instructions for the page
  165. *
  166. * @return void
  167. */
  168. function showPageNotice()
  169. {
  170. $instr = $this->getInstructions();
  171. $output = common_markup_to_html($instr);
  172. $this->elementStart('div', 'instructions');
  173. $this->raw($output);
  174. $this->elementEnd('div');
  175. }
  176. /**
  177. * Content area
  178. *
  179. * Shows the groups
  180. *
  181. * @return void
  182. */
  183. function showContent()
  184. {
  185. if (common_logged_in()) {
  186. $this->elementStart(
  187. 'p',
  188. array(
  189. 'id' => 'new_group'
  190. )
  191. );
  192. $this->element(
  193. 'a',
  194. array(
  195. 'href' => common_local_url('newgroup'),
  196. 'class' => 'more'),
  197. // TRANS: Link to create a new group on the group list page.
  198. _m('Create a new group')
  199. );
  200. $this->elementEnd('p');
  201. }
  202. $this->showForm();
  203. $this->elementStart('div', array('id' => 'profile_directory'));
  204. // @todo FIXME: Does "All" need i18n here?
  205. $alphaNav = new AlphaNav($this, false, false, array('0-9', 'All'));
  206. $alphaNav->show();
  207. $group = null;
  208. $group = $this->getGroups();
  209. $cnt = 0;
  210. if (!empty($group)) {
  211. $groupList = new SortableGroupList(
  212. $group,
  213. common_current_user(),
  214. $this
  215. );
  216. $cnt = $groupList->show();
  217. $group->free();
  218. if (0 == $cnt) {
  219. $this->showEmptyListMessage();
  220. }
  221. }
  222. $args = array();
  223. if (isset($this->q)) {
  224. $args['q'] = $this->q;
  225. } else {
  226. $args['filter'] = $this->filter;
  227. }
  228. $this->pagination(
  229. $this->page > 1,
  230. $cnt > PROFILES_PER_PAGE,
  231. $this->page,
  232. 'groupdirectory',
  233. $args
  234. );
  235. $this->elementEnd('div');
  236. }
  237. function showForm($error=null)
  238. {
  239. $this->elementStart(
  240. 'form',
  241. array(
  242. 'method' => 'get',
  243. 'id' => 'form_search',
  244. 'class' => 'form_settings',
  245. 'action' => common_local_url('groupdirectory')
  246. )
  247. );
  248. $this->elementStart('fieldset');
  249. // TRANS: Fieldset legend.
  250. $this->element('legend', null, _m('Search groups'));
  251. $this->elementStart('ul', 'form_data');
  252. $this->elementStart('li');
  253. // TRANS: Field label for input of one or more keywords.
  254. $this->input('q', _m('Keyword(s)'), $this->q);
  255. // TRANS: Button text for searching group directory.
  256. $this->submit('search', _m('BUTTON','Search'));
  257. $this->elementEnd('li');
  258. $this->elementEnd('ul');
  259. $this->elementEnd('fieldset');
  260. $this->elementEnd('form');
  261. }
  262. /*
  263. * Get groups filtered by the current filter, sort key,
  264. * sort order, and page
  265. */
  266. function getGroups()
  267. {
  268. $group = new User_group();
  269. $offset = ($this->page-1) * PROFILES_PER_PAGE;
  270. $limit = PROFILES_PER_PAGE + 1;
  271. if (isset($this->q)) {
  272. $order = 'user_group.created ASC';
  273. if ($this->sort == 'nickname') {
  274. if ($this->reverse) {
  275. $order = 'user_group.nickname DESC';
  276. } else {
  277. $order = 'user_group.nickname ASC';
  278. }
  279. } else {
  280. if ($this->reverse) {
  281. $order = 'user_group.created DESC';
  282. }
  283. }
  284. $sql = <<< GROUP_QUERY_END
  285. SELECT user_group.*
  286. FROM user_group
  287. JOIN local_group ON user_group.id = local_group.group_id
  288. ORDER BY %s
  289. LIMIT %d, %d
  290. GROUP_QUERY_END;
  291. $cnt = 0;
  292. $group->query(sprintf($sql, $order, $limit, $offset));
  293. $group->find();
  294. } else {
  295. // User is browsing via AlphaNav
  296. $sort = $this->getSortKey();
  297. $sql = <<< GROUP_QUERY_END
  298. SELECT user_group.*
  299. FROM user_group
  300. JOIN local_group ON user_group.id = local_group.group_id
  301. GROUP_QUERY_END;
  302. switch($this->filter)
  303. {
  304. case 'all':
  305. // NOOP
  306. break;
  307. case '0-9':
  308. $sql .=
  309. ' AND LEFT(user_group.nickname, 1) BETWEEN \'0\' AND \'9\'';
  310. break;
  311. default:
  312. $sql .= sprintf(
  313. ' AND LEFT(LOWER(user_group.nickname), 1) = \'%s\'',
  314. $this->filter
  315. );
  316. }
  317. $sql .= sprintf(
  318. ' ORDER BY user_group.%s %s, user_group.nickname ASC LIMIT %d, %d',
  319. $sort,
  320. $this->reverse ? 'DESC' : 'ASC',
  321. $offset,
  322. $limit
  323. );
  324. $group->query($sql);
  325. }
  326. return $group;
  327. }
  328. /**
  329. * Filter the sort parameter
  330. *
  331. * @return string a column name for sorting
  332. */
  333. function getSortKey()
  334. {
  335. switch ($this->sort) {
  336. case 'nickname':
  337. return $this->sort;
  338. break;
  339. case 'created':
  340. return $this->sort;
  341. break;
  342. default:
  343. return 'nickname';
  344. }
  345. }
  346. /**
  347. * Show a nice message when there's no search results
  348. */
  349. function showEmptyListMessage()
  350. {
  351. if (!empty($this->filter) && ($this->filter != 'all')) {
  352. $this->element(
  353. 'p',
  354. 'error',
  355. sprintf(
  356. // TRANS: Empty list message for searching group directory.
  357. // TRANS: %s is the search string.
  358. _m('No groups starting with %s.'),
  359. $this->filter
  360. )
  361. );
  362. } else {
  363. // TRANS: Empty list message for searching group directory.
  364. $this->element('p', 'error', _m('No results.'));
  365. // TRANS: Help text for searching group directory.
  366. $message = _m("* Make sure all words are spelled correctly.\n".
  367. "* Try different keywords.\n".
  368. "* Try more general keywords.\n".
  369. "* Try fewer keywords.");
  370. $this->elementStart('div', 'help instructions');
  371. $this->raw(common_markup_to_html($message));
  372. $this->elementEnd('div');
  373. }
  374. }
  375. function showSections()
  376. {
  377. $gbp = new GroupsByPostsSection($this);
  378. $gbp->show();
  379. $gbm = new GroupsByMembersSection($this);
  380. $gbm->show();
  381. }
  382. }