NoticeTitlePlugin.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <?php
  2. /**
  3. * StatusNet - the distributed open-source microblogging tool
  4. * Copyright (C) 2010, StatusNet, Inc.
  5. *
  6. * A plugin to add titles to notices
  7. *
  8. * PHP version 5
  9. *
  10. * This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Affero General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Affero General Public License
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. *
  23. * @category NoticeTitle
  24. * @package StatusNet
  25. * @author Evan Prodromou <evan@status.net>
  26. * @copyright 2010 StatusNet, Inc.
  27. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
  28. * @link http://status.net/
  29. */
  30. if (!defined('STATUSNET')) {
  31. // This check helps protect against security problems;
  32. // your code file can't be executed directly from the web.
  33. exit(1);
  34. }
  35. define('NOTICE_TITLE_PLUGIN_VERSION', '0.1');
  36. /**
  37. * NoticeTitle plugin to add an optional title to notices.
  38. *
  39. * Stores notice titles in a secondary table, notice_title.
  40. *
  41. * @category NoticeTitle
  42. * @package StatusNet
  43. * @author Evan Prodromou <evan@status.net>
  44. * @copyright 2010 StatusNet, Inc.
  45. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
  46. * @link http://status.net/
  47. */
  48. class NoticeTitlePlugin extends Plugin
  49. {
  50. // By default, notice-title widget will be available to all users.
  51. // With restricted on, only users who have been granted the
  52. // "richedit" role get it.
  53. public $restricted = false;
  54. /**
  55. * Database schema setup
  56. *
  57. * Add the notice_title helper table
  58. *
  59. * @see Schema
  60. * @see ColumnDef
  61. *
  62. * @return boolean hook value; true means continue processing, false means stop.
  63. */
  64. function onCheckSchema()
  65. {
  66. $schema = Schema::get();
  67. // For storing titles for notices
  68. $schema->ensureTable('notice_title', Notice_title::schemaDef());
  69. return true;
  70. }
  71. /**
  72. * Provide plugin version information.
  73. *
  74. * This data is used when showing the version page.
  75. *
  76. * @param array &$versions array of version data arrays; see EVENTS.txt
  77. *
  78. * @return boolean hook value
  79. */
  80. function onPluginVersion(array &$versions)
  81. {
  82. $url = 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/NoticeTitle';
  83. $versions[] = array('name' => 'NoticeTitle',
  84. 'version' => NOTICE_TITLE_PLUGIN_VERSION,
  85. 'author' => 'Evan Prodromou',
  86. 'homepage' => $url,
  87. 'rawdescription' =>
  88. // TRANS: Plugin description.
  89. _m('Adds optional titles to notices.'));
  90. return true;
  91. }
  92. /**
  93. * Show title entry when showing notice form
  94. *
  95. * @param Form $form Form being shown
  96. *
  97. * @return boolean hook value
  98. */
  99. function onStartShowNoticeFormData($form)
  100. {
  101. if ($this->isAllowedRichEdit()) {
  102. $form->out->element('style',
  103. null,
  104. 'label#notice_data-text-label { display: none }');
  105. $form->out->element('input', array('type' => 'text',
  106. 'id' => 'notice_title',
  107. 'name' => 'notice_title',
  108. 'size' => 40,
  109. 'maxlength' => Notice_title::MAXCHARS));
  110. }
  111. return true;
  112. }
  113. /**
  114. * Validate notice title before saving
  115. *
  116. * @param Action $action NewNoticeAction being executed
  117. * @param Profile $author Profile object for the author of the notice being saved
  118. * @param string &$text Text of the notice
  119. * @param array &$options Options array
  120. *
  121. * @return boolean hook value
  122. */
  123. function onStartNoticeSaveWeb(Action $action, Profile $author, &$content, &$options)
  124. {
  125. $title = $action->trimmed('notice_title');
  126. if (!empty($title) && $this->isAllowedRichEdit()) {
  127. if (mb_strlen($title) > Notice_title::MAXCHARS) {
  128. // TRANS: Exception thrown when a notice title is too long.
  129. // TRANS: %d is the maximum number of characters allowed in a title (used for plural).
  130. throw new Exception(sprintf(_m('The notice title is too long (maximum %d character).',
  131. 'The notice title is too long (maximum %d characters).',
  132. Notice_title::MAXCHARS),
  133. Notice_title::MAXCHARS));
  134. }
  135. }
  136. return true;
  137. }
  138. /**
  139. * Save notice title after notice is saved
  140. *
  141. * @param Action $action NewNoticeAction being executed
  142. * @param Notice $notice Notice that was saved
  143. *
  144. * @return boolean hook value
  145. */
  146. function onEndNoticeSaveWeb($action, $notice)
  147. {
  148. if (!empty($notice)) {
  149. $title = $action->trimmed('notice_title');
  150. if (!empty($title) && $this->isAllowedRichEdit()) {
  151. $nt = new Notice_title();
  152. $nt->notice_id = $notice->id;
  153. $nt->title = $title;
  154. $nt->insert();
  155. }
  156. }
  157. return true;
  158. }
  159. /**
  160. * Show the notice title in lists
  161. *
  162. * @param NoticeListItem $nli NoticeListItem being shown
  163. *
  164. * @return boolean hook value
  165. */
  166. function onStartShowNoticeTitle(NoticeListItem $nli)
  167. {
  168. $title = Notice_title::fromNotice($nli->notice);
  169. if (!empty($title)) {
  170. $nli->elementStart('h4', array('class' => 'p-name'));
  171. $nli->element('a', array('href' => $nli->notice->getUrl()), $title);
  172. $nli->elementEnd('h4');
  173. return false;
  174. }
  175. return true;
  176. }
  177. /**
  178. * Show the notice title in RSS output
  179. *
  180. * @param Notice $notice Notice being shown
  181. * @param array &$entry array of values used for RSS output
  182. *
  183. * @return boolean hook value
  184. */
  185. function onEndRssEntryArray($notice, &$entry)
  186. {
  187. $title = Notice_title::fromNotice($notice);
  188. if (!empty($title)) {
  189. $entry['title'] = $title;
  190. }
  191. return true;
  192. }
  193. /**
  194. * Show the notice title in Atom output
  195. *
  196. * @param Notice $notice Notice being shown
  197. * @param Activity $act Activity object to be modified
  198. * @param Profile $scoped Currently logged in/scoped profile
  199. *
  200. * @return boolean hook value
  201. */
  202. function onEndNoticeAsActivity(Notice $stored, Activity $act, Profile $scoped=null)
  203. {
  204. $title = Notice_title::fromNotice($stored);
  205. if (!empty($title)) {
  206. foreach ($act->objects as $obj) {
  207. if ($obj->id == $stored->getUri()) {
  208. $obj->title = $title;
  209. break;
  210. }
  211. }
  212. }
  213. return true;
  214. }
  215. /**
  216. * Remove title when the notice is deleted
  217. *
  218. * @param Notice $notice Notice being deleted
  219. *
  220. * @return boolean hook value
  221. */
  222. function onNoticeDeleteRelated($notice)
  223. {
  224. $nt = Notice_title::getKV('notice_id', $notice->id);
  225. if (!empty($nt)) {
  226. $nt->delete();
  227. }
  228. return true;
  229. }
  230. /**
  231. * If a notice has a title, show it in the <title> element
  232. *
  233. * @param Action $action Action being executed
  234. *
  235. * @return boolean hook value
  236. */
  237. function onStartShowHeadTitle($action)
  238. {
  239. $actionName = $action->trimmed('action');
  240. if ($actionName == 'shownotice') {
  241. $title = Notice_title::fromNotice($action->notice);
  242. if (!empty($title)) {
  243. $action->element('title', null,
  244. // TRANS: Page title. %1$s is the title, %2$s is the site name.
  245. sprintf(_m("%1\$s - %2\$s"),
  246. $title,
  247. common_config('site', 'name')));
  248. }
  249. }
  250. return true;
  251. }
  252. /**
  253. * If a notice has a title, show it in the <h1> element
  254. *
  255. * @param Notice $notice Notice we're getting the title for
  256. * @param string $title Reference to the variable which we set to the notice's title
  257. *
  258. * @return boolean hook value
  259. */
  260. function onGetNoticeTitle(Notice $notice, &$title)
  261. {
  262. $title = Notice_title::fromNotice($notice);
  263. if (!is_null($title)) {
  264. return false;
  265. }
  266. return true;
  267. }
  268. /**
  269. * Does the current user have permission to use the notice-title widget?
  270. * Always true unless the plugin's "restricted" setting is on, in which
  271. * case it's limited to users with the "richedit" role.
  272. *
  273. * @todo FIXME: make that more sanely configurable :)
  274. *
  275. * @return boolean
  276. */
  277. private function isAllowedRichEdit()
  278. {
  279. if ($this->restricted) {
  280. $user = common_current_user();
  281. return !empty($user) && $user->hasRole('richedit');
  282. } else {
  283. return true;
  284. }
  285. }
  286. }