demo_plugin.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <?php
  2. /**
  3. * Demo Plugin.
  4. *
  5. * This plugin try to cover Shaarli's plugin API entirely.
  6. * Can be used by plugin developper to make their own.
  7. */
  8. /*
  9. * RENDER HEADER, INCLUDES, FOOTER
  10. *
  11. * Those hooks are called at every page rendering.
  12. * You can filter its execution by checking _PAGE_ value
  13. * and check user status with _LOGGEDIN_.
  14. */
  15. use Shaarli\Config\ConfigManager;
  16. /**
  17. * In the footer hook, there is a working example of a translation extension for Shaarli.
  18. *
  19. * The extension must be attached to a new translation domain (i.e. NOT 'shaarli').
  20. * Use case: any custom theme or non official plugin can use the translation system.
  21. *
  22. * See the documentation for more information.
  23. */
  24. const EXT_TRANSLATION_DOMAIN = 'demo';
  25. /*
  26. * This is not necessary, but it's easier if you don't want Poedit to mix up your translations.
  27. */
  28. function demo_plugin_t($text, $nText = '', $nb = 1)
  29. {
  30. return t($text, $nText, $nb, EXT_TRANSLATION_DOMAIN);
  31. }
  32. /**
  33. * Initialization function.
  34. * It will be called when the plugin is loaded.
  35. * This function can be used to return a list of initialization errors.
  36. *
  37. * @param $conf ConfigManager instance.
  38. *
  39. * @return array List of errors (optional).
  40. */
  41. function demo_plugin_init($conf)
  42. {
  43. $conf->get('toto', 'nope');
  44. if (! $conf->exists('translation.extensions.demo')) {
  45. // Custom translation with the domain 'demo'
  46. $conf->set('translation.extensions.demo', 'plugins/demo_plugin/languages/');
  47. $conf->write(true);
  48. }
  49. $errors[] = 'This a demo init error.';
  50. return $errors;
  51. }
  52. /**
  53. * Hook render_header.
  54. * Executed on every page redering.
  55. *
  56. * Template placeholders:
  57. * - buttons_toolbar
  58. * - fields_toolbar
  59. *
  60. * @param array $data data passed to plugin
  61. *
  62. * @return array altered $data.
  63. */
  64. function hook_demo_plugin_render_header($data)
  65. {
  66. // Only execute when linklist is rendered.
  67. if ($data['_PAGE_'] == Router::$PAGE_LINKLIST) {
  68. // If loggedin
  69. if ($data['_LOGGEDIN_'] === true) {
  70. /*
  71. * Links in toolbar:
  72. * A link is an array of its attributes (key="value"),
  73. * and a mandatory `html` key, which contains its value.
  74. */
  75. $button = array(
  76. 'attr' => array (
  77. 'href' => '#',
  78. 'class' => 'mybutton',
  79. 'title' => 'hover me',
  80. ),
  81. 'html' => 'DEMO buttons toolbar',
  82. );
  83. $data['buttons_toolbar'][] = $button;
  84. }
  85. /*
  86. * Add additional input fields in the tools.
  87. * A field is an array containing:
  88. * [
  89. * 'form-attribute-1' => 'form attribute 1 value',
  90. * 'form-attribute-2' => 'form attribute 2 value',
  91. * 'inputs' => [
  92. * [
  93. * 'input-1-attribute-1 => 'input 1 attribute 1 value',
  94. * 'input-1-attribute-2 => 'input 1 attribute 2 value',
  95. * ],
  96. * [
  97. * 'input-2-attribute-1 => 'input 2 attribute 1 value',
  98. * ],
  99. * ],
  100. * ]
  101. * This example renders as:
  102. * <form form-attribute-1="form attribute 1 value" form-attribute-2="form attribute 2 value">
  103. * <input input-1-attribute-1="input 1 attribute 1 value" input-1-attribute-2="input 1 attribute 2 value">
  104. * <input input-2-attribute-1="input 2 attribute 1 value">
  105. * </form>
  106. */
  107. $form = array(
  108. 'attr' => array(
  109. 'method' => 'GET',
  110. 'action' => '?',
  111. 'class' => 'addform',
  112. ),
  113. 'inputs' => array(
  114. array(
  115. 'type' => 'text',
  116. 'name' => 'demo',
  117. 'placeholder' => 'demo',
  118. )
  119. )
  120. );
  121. $data['fields_toolbar'][] = $form;
  122. }
  123. // Another button always displayed
  124. $button = array(
  125. 'attr' => array(
  126. 'href' => '#',
  127. ),
  128. 'html' => 'Demo',
  129. );
  130. $data['buttons_toolbar'][] = $button;
  131. return $data;
  132. }
  133. /**
  134. * Hook render_includes.
  135. * Executed on every page redering.
  136. *
  137. * Template placeholders:
  138. * - css_files
  139. *
  140. * Data:
  141. * - _PAGE_: current page
  142. * - _LOGGEDIN_: true/false
  143. *
  144. * @param array $data data passed to plugin
  145. *
  146. * @return array altered $data.
  147. */
  148. function hook_demo_plugin_render_includes($data)
  149. {
  150. // List of plugin's CSS files.
  151. // Note that you just need to specify CSS path.
  152. $data['css_files'][] = PluginManager::$PLUGINS_PATH . '/demo_plugin/custom_demo.css';
  153. return $data;
  154. }
  155. /**
  156. * Hook render_footer.
  157. * Executed on every page redering.
  158. *
  159. * Template placeholders:
  160. * - text
  161. * - endofpage
  162. * - js_files
  163. *
  164. * Data:
  165. * - _PAGE_: current page
  166. * - _LOGGEDIN_: true/false
  167. *
  168. * @param array $data data passed to plugin
  169. *
  170. * @return array altered $data.
  171. */
  172. function hook_demo_plugin_render_footer($data)
  173. {
  174. // footer text
  175. $data['text'][] = '<br>'. demo_plugin_t('Shaarli is now enhanced by the awesome demo_plugin.');
  176. // Free elements at the end of the page.
  177. $data['endofpage'][] = '<marquee id="demo_marquee">' .
  178. 'DEMO: it\'s 1999 all over again!' .
  179. '</marquee>';
  180. // List of plugin's JS files.
  181. // Note that you just need to specify CSS path.
  182. $data['js_files'][] = PluginManager::$PLUGINS_PATH . '/demo_plugin/demo_plugin.js';
  183. return $data;
  184. }
  185. /*
  186. * SPECIFIC PAGES
  187. */
  188. /**
  189. * Hook render_linklist.
  190. *
  191. * Template placeholders:
  192. * - action_plugin: next to 'private only' button.
  193. * - plugin_start_zone: page start
  194. * - plugin_end_zone: page end
  195. * - link_plugin: icons below each links.
  196. *
  197. * Data:
  198. * - _LOGGEDIN_: true/false
  199. *
  200. * @param array $data data passed to plugin
  201. *
  202. * @return array altered $data.
  203. */
  204. function hook_demo_plugin_render_linklist($data)
  205. {
  206. /*
  207. * Action links (action_plugin):
  208. * A link is an array of its attributes (key="value"),
  209. * and a mandatory `html` key, which contains its value.
  210. * It's also recommended to add key 'on' or 'off' for theme rendering.
  211. */
  212. $action = array(
  213. 'attr' => array(
  214. 'href' => '?up',
  215. 'title' => 'Uppercase!',
  216. ),
  217. 'html' => '←',
  218. );
  219. if (isset($_GET['up'])) {
  220. // Manipulate link data
  221. foreach ($data['links'] as &$value) {
  222. $value['description'] = strtoupper($value['description']);
  223. $value['title'] = strtoupper($value['title']);
  224. }
  225. $action['on'] = true;
  226. } else {
  227. $action['off'] = true;
  228. }
  229. $data['action_plugin'][] = $action;
  230. // link_plugin (for each link)
  231. foreach ($data['links'] as &$value) {
  232. $value['link_plugin'][] = ' DEMO \o/';
  233. }
  234. // plugin_start_zone
  235. $data['plugin_start_zone'][] = '<center>BEFORE</center>';
  236. // plugin_start_zone
  237. $data['plugin_end_zone'][] = '<center>AFTER</center>';
  238. return $data;
  239. }
  240. /**
  241. * Hook render_editlink.
  242. *
  243. * Template placeholders:
  244. * - field_plugin: add link fields after tags.
  245. *
  246. * @param array $data data passed to plugin
  247. *
  248. * @return array altered $data.
  249. */
  250. function hook_demo_plugin_render_editlink($data)
  251. {
  252. // Load HTML into a string
  253. $html = file_get_contents(PluginManager::$PLUGINS_PATH .'/demo_plugin/field.html');
  254. // replace value in HTML if it exists in $data
  255. if (!empty($data['link']['stuff'])) {
  256. $html = sprintf($html, $data['link']['stuff']);
  257. } else {
  258. $html = sprintf($html, '');
  259. }
  260. // field_plugin
  261. $data['edit_link_plugin'][] = $html;
  262. return $data;
  263. }
  264. /**
  265. * Hook render_tools.
  266. *
  267. * Template placeholders:
  268. * - tools_plugin: after other tools.
  269. *
  270. * @param array $data data passed to plugin
  271. *
  272. * @return array altered $data.
  273. */
  274. function hook_demo_plugin_render_tools($data)
  275. {
  276. // field_plugin
  277. $data['tools_plugin'][] = 'tools_plugin';
  278. return $data;
  279. }
  280. /**
  281. * Hook render_picwall.
  282. *
  283. * Template placeholders:
  284. * - plugin_start_zone: page start.
  285. * - plugin_end_zone: page end.
  286. *
  287. * Data:
  288. * - _LOGGEDIN_: true/false
  289. *
  290. * @param array $data data passed to plugin
  291. *
  292. * @return array altered $data.
  293. */
  294. function hook_demo_plugin_render_picwall($data)
  295. {
  296. // plugin_start_zone
  297. $data['plugin_start_zone'][] = '<center>BEFORE</center>';
  298. // plugin_end_zone
  299. $data['plugin_end_zone'][] = '<center>AFTER</center>';
  300. return $data;
  301. }
  302. /**
  303. * Hook render_tagcloud.
  304. *
  305. * Template placeholders:
  306. * - plugin_start_zone: page start.
  307. * - plugin_end_zone: page end.
  308. *
  309. * Data:
  310. * - _LOGGEDIN_: true/false
  311. *
  312. * @param array $data data passed to plugin
  313. *
  314. * @return array altered $data.
  315. */
  316. function hook_demo_plugin_render_tagcloud($data)
  317. {
  318. // plugin_start_zone
  319. $data['plugin_start_zone'][] = '<center>BEFORE</center>';
  320. // plugin_end_zone
  321. $data['plugin_end_zone'][] = '<center>AFTER</center>';
  322. return $data;
  323. }
  324. /**
  325. * Hook render_daily.
  326. *
  327. * Template placeholders:
  328. * - plugin_start_zone: page start.
  329. * - plugin_end_zone: page end.
  330. *
  331. * Data:
  332. * - _LOGGEDIN_: true/false
  333. *
  334. * @param array $data data passed to plugin
  335. *
  336. * @return array altered $data.
  337. */
  338. function hook_demo_plugin_render_daily($data)
  339. {
  340. // plugin_start_zone
  341. $data['plugin_start_zone'][] = '<center>BEFORE</center>';
  342. // plugin_end_zone
  343. $data['plugin_end_zone'][] = '<center>AFTER</center>';
  344. // Manipulate columns data
  345. foreach ($data['linksToDisplay'] as &$value) {
  346. $value['formatedDescription'] .= ' ಠ_ಠ';
  347. }
  348. // Add plugin content at the end of each link
  349. foreach ($data['linksToDisplay'] as &$value) {
  350. $value['link_plugin'][] = 'DEMO';
  351. }
  352. return $data;
  353. }
  354. /*
  355. * DATA SAVING HOOK.
  356. */
  357. /**
  358. * Hook savelink.
  359. *
  360. * Triggered when a link is save (new or edit).
  361. * All new links now contain a 'stuff' value.
  362. *
  363. * @param array $data contains the new link data.
  364. *
  365. * @return array altered $data.
  366. */
  367. function hook_demo_plugin_save_link($data)
  368. {
  369. // Save stuff added in editlink field
  370. if (!empty($_POST['lf_stuff'])) {
  371. $data['stuff'] = escape($_POST['lf_stuff']);
  372. }
  373. return $data;
  374. }
  375. /**
  376. * Hook delete_link.
  377. *
  378. * Triggered when a link is deleted.
  379. *
  380. * @param array $data contains the link to be deleted.
  381. *
  382. * @return array altered data.
  383. */
  384. function hook_demo_plugin_delete_link($data)
  385. {
  386. if (strpos($data['url'], 'youtube.com') !== false) {
  387. exit('You can not delete a YouTube link. Don\'t ask.');
  388. }
  389. }
  390. /**
  391. * Execute render_feed hook.
  392. * Called with ATOM and RSS feed.
  393. *
  394. * Special data keys:
  395. * - _PAGE_: current page
  396. * - _LOGGEDIN_: true/false
  397. *
  398. * @param array $data data passed to plugin
  399. *
  400. * @return array altered $data.
  401. */
  402. function hook_demo_plugin_render_feed($data)
  403. {
  404. foreach ($data['links'] as &$link) {
  405. if ($data['_PAGE_'] == Router::$PAGE_FEED_ATOM) {
  406. $link['description'] .= ' - ATOM Feed' ;
  407. } elseif ($data['_PAGE_'] == Router::$PAGE_FEED_RSS) {
  408. $link['description'] .= ' - RSS Feed';
  409. }
  410. }
  411. return $data;
  412. }
  413. /**
  414. * This function is never called, but contains translation calls for GNU gettext extraction.
  415. */
  416. function demo_dummy_translation()
  417. {
  418. // meta
  419. t('A demo plugin covering all use cases for template designers and plugin developers.');
  420. }