PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/actions/conversation.php

https://github.com/Br3nda/laconica
PHP | 299 lines | 118 code | 51 blank | 130 comment | 10 complexity | 1d97e3a3ae9c615d7897d2d3247ba26d MD5 | raw file
Possible License(s): AGPL-3.0
  1. <?php
  2. /**
  3. * Display a conversation in the browser
  4. *
  5. * PHP version 5
  6. *
  7. * @category Action
  8. * @package Laconica
  9. * @author Evan Prodromou <evan@controlyourself.ca>
  10. * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
  11. * @link http://laconi.ca/
  12. *
  13. * Laconica - a distributed open-source microblogging tool
  14. * Copyright (C) 2009, Control Yourself, Inc.
  15. *
  16. * This program is free software: you can redistribute it and/or modify
  17. * it under the terms of the GNU Affero General Public License as published by
  18. * the Free Software Foundation, either version 3 of the License, or
  19. * (at your option) any later version.
  20. *
  21. * This program is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU Affero General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU Affero General Public License
  27. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  28. */
  29. if (!defined('LACONICA')) {
  30. exit(1);
  31. }
  32. // XXX: not sure how to do paging yet,
  33. // so set a 60-notice limit
  34. require_once INSTALLDIR.'/lib/noticelist.php';
  35. /**
  36. * Conversation tree in the browser
  37. *
  38. * @category Action
  39. * @package Laconica
  40. * @author Evan Prodromou <evan@controlyourself.ca>
  41. * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
  42. * @link http://laconi.ca/
  43. */
  44. class ConversationAction extends Action
  45. {
  46. var $id = null;
  47. var $page = null;
  48. /**
  49. * Initialization.
  50. *
  51. * @param array $args Web and URL arguments
  52. *
  53. * @return boolean false if id not passed in
  54. */
  55. function prepare($args)
  56. {
  57. parent::prepare($args);
  58. $this->id = $this->trimmed('id');
  59. if (empty($this->id)) {
  60. return false;
  61. }
  62. $this->id = $this->id+0;
  63. $this->page = $this->trimmed('page');
  64. if (empty($this->page)) {
  65. $this->page = 1;
  66. }
  67. return true;
  68. }
  69. /**
  70. * Handle the action
  71. *
  72. * @param array $args Web and URL arguments
  73. *
  74. * @return void
  75. */
  76. function handle($args)
  77. {
  78. parent::handle($args);
  79. $this->showPage();
  80. }
  81. /**
  82. * Returns the page title
  83. *
  84. * @return string page title
  85. */
  86. function title()
  87. {
  88. return _("Conversation");
  89. }
  90. /**
  91. * Show content.
  92. *
  93. * Display a hierarchical unordered list in the content area.
  94. * Uses ConversationTree to do most of the heavy lifting.
  95. *
  96. * @return void
  97. */
  98. function showContent()
  99. {
  100. $notices = Notice::conversationStream($this->id, null, null);
  101. $ct = new ConversationTree($notices, $this);
  102. $cnt = $ct->show();
  103. }
  104. function isReadOnly()
  105. {
  106. return true;
  107. }
  108. }
  109. /**
  110. * Conversation tree
  111. *
  112. * The widget class for displaying a hierarchical list of notices.
  113. *
  114. * @category Widget
  115. * @package Laconica
  116. * @author Evan Prodromou <evan@controlyourself.ca>
  117. * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
  118. * @link http://laconi.ca/
  119. */
  120. class ConversationTree extends NoticeList
  121. {
  122. var $tree = null;
  123. var $table = null;
  124. /**
  125. * Show the tree of notices
  126. *
  127. * @return void
  128. */
  129. function show()
  130. {
  131. $cnt = $this->_buildTree();
  132. $this->out->elementStart('div', array('id' =>'notices_primary'));
  133. $this->out->element('h2', null, _('Notices'));
  134. $this->out->elementStart('ol', array('class' => 'notices xoxo'));
  135. if (array_key_exists('root', $this->tree)) {
  136. $rootid = $this->tree['root'][0];
  137. $this->showNoticePlus($rootid);
  138. }
  139. $this->out->elementEnd('ol');
  140. $this->out->elementEnd('div');
  141. return $cnt;
  142. }
  143. function _buildTree()
  144. {
  145. $this->tree = array();
  146. $this->table = array();
  147. while ($this->notice->fetch()) {
  148. $cnt++;
  149. $id = $this->notice->id;
  150. $notice = clone($this->notice);
  151. $this->table[$id] = $notice;
  152. if (is_null($notice->reply_to)) {
  153. $this->tree['root'] = array($notice->id);
  154. } else if (array_key_exists($notice->reply_to, $this->tree)) {
  155. $this->tree[$notice->reply_to][] = $notice->id;
  156. } else {
  157. $this->tree[$notice->reply_to] = array($notice->id);
  158. }
  159. }
  160. return $cnt;
  161. }
  162. /**
  163. * Shows a notice plus its list of children.
  164. *
  165. * @param integer $id ID of the notice to show
  166. *
  167. * @return void
  168. */
  169. function showNoticePlus($id)
  170. {
  171. $notice = $this->table[$id];
  172. // We take responsibility for doing the li
  173. $this->out->elementStart('li', array('class' => 'hentry notice',
  174. 'id' => 'notice-' . $id));
  175. $item = $this->newListItem($notice);
  176. $item->show();
  177. if (array_key_exists($id, $this->tree)) {
  178. $children = $this->tree[$id];
  179. $this->out->elementStart('ol', array('class' => 'notices'));
  180. sort($children);
  181. foreach ($children as $child) {
  182. $this->showNoticePlus($child);
  183. }
  184. $this->out->elementEnd('ol');
  185. }
  186. $this->out->elementEnd('li');
  187. }
  188. /**
  189. * Override parent class to return our preferred item.
  190. *
  191. * @param Notice $notice Notice to display
  192. *
  193. * @return NoticeListItem a list item to show
  194. */
  195. function newListItem($notice)
  196. {
  197. return new ConversationTreeItem($notice, $this->out);
  198. }
  199. }
  200. /**
  201. * Conversation tree list item
  202. *
  203. * Special class of NoticeListItem for use inside conversation trees.
  204. *
  205. * @category Widget
  206. * @package Laconica
  207. * @author Evan Prodromou <evan@controlyourself.ca>
  208. * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
  209. * @link http://laconi.ca/
  210. */
  211. class ConversationTreeItem extends NoticeListItem
  212. {
  213. /**
  214. * start a single notice.
  215. *
  216. * The default creates the <li>; we skip, since the ConversationTree
  217. * takes care of that.
  218. *
  219. * @return void
  220. */
  221. function showStart()
  222. {
  223. return;
  224. }
  225. /**
  226. * finish the notice
  227. *
  228. * The default closes the <li>; we skip, since the ConversationTree
  229. * takes care of that.
  230. *
  231. * @return void
  232. */
  233. function showEnd()
  234. {
  235. return;
  236. }
  237. /**
  238. * show link to notice conversation page
  239. *
  240. * Since we're only used on the conversation page, we skip this
  241. *
  242. * @return void
  243. */
  244. function showContext()
  245. {
  246. return;
  247. }
  248. }