start.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. <?php
  2. /**
  3. * Elgg Pages
  4. *
  5. * @package ElggPages
  6. */
  7. elgg_register_event_handler('init', 'system', 'pages_init');
  8. /**
  9. * Initialize the pages plugin.
  10. *
  11. */
  12. function pages_init() {
  13. // register a library of helper functions
  14. elgg_register_library('elgg:pages', elgg_get_plugins_path() . 'pages/lib/pages.php');
  15. $item = new ElggMenuItem('pages', elgg_echo('pages'), 'pages/all');
  16. elgg_register_menu_item('site', $item);
  17. // Register a page handler, so we can have nice URLs
  18. elgg_register_page_handler('pages', 'pages_page_handler');
  19. // Register a url handler
  20. elgg_register_plugin_hook_handler('entity:url', 'object', 'pages_set_url');
  21. elgg_register_plugin_hook_handler('entity:url', 'object', 'pages_set_url');
  22. elgg_register_plugin_hook_handler('extender:url', 'annotation', 'pages_set_revision_url');
  23. // Register some actions
  24. $action_base = elgg_get_plugins_path() . 'pages/actions';
  25. elgg_register_action("pages/edit", "$action_base/pages/edit.php");
  26. elgg_register_action("pages/delete", "$action_base/pages/delete.php");
  27. elgg_register_action("annotations/page/delete", "$action_base/annotations/page/delete.php");
  28. // Extend the main css view
  29. elgg_extend_view('css/elgg', 'pages/css');
  30. elgg_define_js('jquery.treeview', array(
  31. 'src' => '/mod/pages/vendors/jquery-treeview/jquery.treeview.min.js',
  32. 'exports' => 'jQuery.fn.treeview',
  33. 'deps' => array('jquery'),
  34. ));
  35. $css_url = 'mod/pages/vendors/jquery-treeview/jquery.treeview.css';
  36. elgg_register_css('jquery.treeview', $css_url);
  37. // Register entity type for search
  38. elgg_register_entity_type('object', 'page');
  39. elgg_register_entity_type('object', 'page_top');
  40. // Register for notifications
  41. elgg_register_notification_event('object', 'page');
  42. elgg_register_notification_event('object', 'page_top');
  43. elgg_register_plugin_hook_handler('prepare', 'notification:create:object:page', 'pages_prepare_notification');
  44. elgg_register_plugin_hook_handler('prepare', 'notification:create:object:page_top', 'pages_prepare_notification');
  45. // add to groups
  46. add_group_tool_option('pages', elgg_echo('groups:enablepages'), true);
  47. elgg_extend_view('groups/tool_latest', 'pages/group_module');
  48. //add a widget
  49. elgg_register_widget_type('pages', elgg_echo('pages'), elgg_echo('pages:widget:description'));
  50. // Language short codes must be of the form "pages:key"
  51. // where key is the array key below
  52. elgg_set_config('pages', array(
  53. 'title' => 'text',
  54. 'description' => 'longtext',
  55. 'tags' => 'tags',
  56. 'parent_guid' => 'parent',
  57. 'access_id' => 'access',
  58. // TODO change to "access" when input/write_access is removed
  59. 'write_access_id' => 'write_access',
  60. ));
  61. elgg_register_plugin_hook_handler('register', 'menu:owner_block', 'pages_owner_block_menu');
  62. // write permission plugin hooks
  63. elgg_register_plugin_hook_handler('permissions_check', 'object', 'pages_write_permission_check');
  64. elgg_register_plugin_hook_handler('container_permissions_check', 'object', 'pages_container_permission_check');
  65. elgg_register_plugin_hook_handler('access:collections:write', 'user', 'pages_write_access_options_hook');
  66. // icon url override
  67. elgg_register_plugin_hook_handler('entity:icon:url', 'object', 'pages_icon_url_override');
  68. // entity menu
  69. elgg_register_plugin_hook_handler('register', 'menu:entity', 'pages_entity_menu_setup');
  70. // register ecml views to parse
  71. elgg_register_plugin_hook_handler('get_views', 'ecml', 'pages_ecml_views_hook');
  72. // prevent public write access
  73. elgg_register_plugin_hook_handler('view_vars', 'input/access', 'pages_write_access_vars');
  74. }
  75. /**
  76. * Dispatcher for pages.
  77. * URLs take the form of
  78. * All pages: pages/all
  79. * User's pages: pages/owner/<username>
  80. * Friends' pages: pages/friends/<username>
  81. * View page: pages/view/<guid>/<title>
  82. * New page: pages/add/<guid> (container: user, group, parent)
  83. * Edit page: pages/edit/<guid>
  84. * History of page: pages/history/<guid>
  85. * Revision of page: pages/revision/<id>
  86. * Group pages: pages/group/<guid>/all
  87. *
  88. * Title is ignored
  89. *
  90. * @param array $page
  91. * @return bool
  92. */
  93. function pages_page_handler($page) {
  94. elgg_load_library('elgg:pages');
  95. if (!isset($page[0])) {
  96. $page[0] = 'all';
  97. }
  98. elgg_push_breadcrumb(elgg_echo('pages'), 'pages/all');
  99. $base_dir = elgg_get_plugins_path() . 'pages/pages/pages';
  100. $page_type = $page[0];
  101. switch ($page_type) {
  102. case 'owner':
  103. include "$base_dir/owner.php";
  104. break;
  105. case 'friends':
  106. include "$base_dir/friends.php";
  107. break;
  108. case 'view':
  109. set_input('guid', $page[1]);
  110. include "$base_dir/view.php";
  111. break;
  112. case 'add':
  113. set_input('guid', $page[1]);
  114. include "$base_dir/new.php";
  115. break;
  116. case 'edit':
  117. set_input('guid', $page[1]);
  118. include "$base_dir/edit.php";
  119. break;
  120. case 'group':
  121. include "$base_dir/owner.php";
  122. break;
  123. case 'history':
  124. set_input('guid', $page[1]);
  125. include "$base_dir/history.php";
  126. break;
  127. case 'revision':
  128. set_input('id', $page[1]);
  129. include "$base_dir/revision.php";
  130. break;
  131. case 'all':
  132. include "$base_dir/world.php";
  133. break;
  134. default:
  135. return false;
  136. }
  137. return true;
  138. }
  139. /**
  140. * Override the page url
  141. *
  142. * @param string $hook
  143. * @param string $type
  144. * @param string $url
  145. * @param array $params
  146. * @return string
  147. */
  148. function pages_set_url($hook, $type, $url, $params) {
  149. $entity = $params['entity'];
  150. if (pages_is_page($entity)) {
  151. $title = elgg_get_friendly_title($entity->title);
  152. return "pages/view/$entity->guid/$title";
  153. }
  154. }
  155. /**
  156. * Override the page annotation url
  157. *
  158. * @param string $hook
  159. * @param string $type
  160. * @param string $url
  161. * @param array $params
  162. * @return string
  163. */
  164. function pages_set_revision_url($hook, $type, $url, $params) {
  165. $annotation = $params['extender'];
  166. if ($annotation->getSubtype() == 'page') {
  167. return "pages/revision/$annotation->id";
  168. }
  169. }
  170. /**
  171. * Override the default entity icon for pages
  172. *
  173. * @return string Relative URL
  174. */
  175. function pages_icon_url_override($hook, $type, $returnvalue, $params) {
  176. $entity = $params['entity'];
  177. if (pages_is_page($entity)) {
  178. switch ($params['size']) {
  179. case 'topbar':
  180. case 'tiny':
  181. case 'small':
  182. return 'mod/pages/images/pages.gif';
  183. break;
  184. default:
  185. return 'mod/pages/images/pages_lrg.gif';
  186. break;
  187. }
  188. }
  189. }
  190. /**
  191. * Add a menu item to the user ownerblock
  192. */
  193. function pages_owner_block_menu($hook, $type, $return, $params) {
  194. if (elgg_instanceof($params['entity'], 'user')) {
  195. $url = "pages/owner/{$params['entity']->username}";
  196. $item = new ElggMenuItem('pages', elgg_echo('pages'), $url);
  197. $return[] = $item;
  198. } else {
  199. if ($params['entity']->pages_enable != "no") {
  200. $url = "pages/group/{$params['entity']->guid}/all";
  201. $item = new ElggMenuItem('pages', elgg_echo('pages:group'), $url);
  202. $return[] = $item;
  203. }
  204. }
  205. return $return;
  206. }
  207. /**
  208. * Add links/info to entity menu particular to pages plugin
  209. */
  210. function pages_entity_menu_setup($hook, $type, $return, $params) {
  211. if (elgg_in_context('widgets')) {
  212. return $return;
  213. }
  214. elgg_load_library('elgg:pages');
  215. $entity = $params['entity'];
  216. $handler = elgg_extract('handler', $params, false);
  217. if ($handler != 'pages') {
  218. return $return;
  219. }
  220. // remove delete if not owner or admin
  221. if (!elgg_is_admin_logged_in()
  222. && elgg_get_logged_in_user_guid() != $entity->getOwnerGuid()
  223. && ! pages_can_delete_page($entity)) {
  224. foreach ($return as $index => $item) {
  225. if ($item->getName() == 'delete') {
  226. unset($return[$index]);
  227. }
  228. }
  229. }
  230. $options = array(
  231. 'name' => 'history',
  232. 'text' => elgg_echo('pages:history'),
  233. 'href' => "pages/history/$entity->guid",
  234. 'priority' => 150,
  235. );
  236. $return[] = ElggMenuItem::factory($options);
  237. return $return;
  238. }
  239. /**
  240. * Prepare a notification message about a new page
  241. *
  242. * @param string $hook Hook name
  243. * @param string $type Hook type
  244. * @param Elgg\Notifications\Notification $notification The notification to prepare
  245. * @param array $params Hook parameters
  246. * @return Elgg\Notifications\Notification
  247. */
  248. function pages_prepare_notification($hook, $type, $notification, $params) {
  249. $entity = $params['event']->getObject();
  250. $owner = $params['event']->getActor();
  251. $recipient = $params['recipient'];
  252. $language = $params['language'];
  253. $method = $params['method'];
  254. $descr = $entity->description;
  255. $title = $entity->title;
  256. $notification->subject = elgg_echo('pages:notify:subject', array($title), $language);
  257. $notification->body = elgg_echo('pages:notify:body', array(
  258. $owner->name,
  259. $title,
  260. $descr,
  261. $entity->getURL(),
  262. ), $language);
  263. $notification->summary = elgg_echo('pages:notify:summary', array($entity->title), $language);
  264. return $notification;
  265. }
  266. /**
  267. * Extend permissions checking to extend can-edit for write users.
  268. *
  269. * @param string $hook
  270. * @param string $entity_type
  271. * @param bool $returnvalue
  272. * @param array $params
  273. *
  274. * @return bool
  275. */
  276. function pages_write_permission_check($hook, $entity_type, $returnvalue, $params) {
  277. if (!pages_is_page($params['entity'])) {
  278. return null;
  279. }
  280. $entity = $params['entity'];
  281. /* @var ElggObject $entity */
  282. $write_permission = $entity->write_access_id;
  283. $user = $params['user'];
  284. if ($write_permission && $user) {
  285. switch ($write_permission) {
  286. case ACCESS_PRIVATE:
  287. // Elgg's default decision is what we want
  288. return null;
  289. break;
  290. case ACCESS_FRIENDS:
  291. $owner = $entity->getOwnerEntity();
  292. if (($owner instanceof ElggUser) && $owner->isFriendsWith($user->guid)) {
  293. return true;
  294. }
  295. break;
  296. default:
  297. $list = get_access_array($user->guid);
  298. if (in_array($write_permission, $list)) {
  299. // user in the access collection
  300. return true;
  301. }
  302. break;
  303. }
  304. }
  305. }
  306. /**
  307. * Extend container permissions checking to extend can_write_to_container for write users.
  308. *
  309. * @param string $hook
  310. * @param string $entity_type
  311. * @param bool $returnvalue
  312. * @param array $params
  313. *
  314. * @return bool
  315. */
  316. function pages_container_permission_check($hook, $entity_type, $returnvalue, $params) {
  317. if (elgg_get_context() != "pages") {
  318. return null;
  319. }
  320. if (elgg_get_page_owner_guid()
  321. && can_write_to_container(elgg_get_logged_in_user_guid(), elgg_get_page_owner_guid())) {
  322. return true;
  323. }
  324. if ($page_guid = get_input('page_guid', 0)) {
  325. $entity = get_entity($page_guid);
  326. } elseif ($parent_guid = get_input('parent_guid', 0)) {
  327. $entity = get_entity($parent_guid);
  328. }
  329. if (isset($entity) && pages_is_page($entity)) {
  330. if (can_write_to_container(elgg_get_logged_in_user_guid(), $entity->container_guid)
  331. || in_array($entity->write_access_id, get_access_list())) {
  332. return true;
  333. }
  334. }
  335. }
  336. /**
  337. * Return views to parse for pages.
  338. *
  339. * @param string $hook
  340. * @param string $entity_type
  341. * @param array $return_value
  342. * @param array $params
  343. *
  344. * @return array
  345. */
  346. function pages_ecml_views_hook($hook, $entity_type, $return_value, $params) {
  347. $return_value['object/page'] = elgg_echo('item:object:page');
  348. $return_value['object/page_top'] = elgg_echo('item:object:page_top');
  349. return $return_value;
  350. }
  351. /**
  352. * Is the given value a page object?
  353. *
  354. * @param mixed $value
  355. *
  356. * @return bool
  357. * @access private
  358. */
  359. function pages_is_page($value) {
  360. return ($value instanceof ElggObject) && in_array($value->getSubtype(), array('page', 'page_top'));
  361. }
  362. /**
  363. * Return options for the write_access_id input
  364. *
  365. * @param string $hook
  366. * @param string $type
  367. * @param array $return_value
  368. * @param array $params
  369. *
  370. * @return array
  371. */
  372. function pages_write_access_options_hook($hook, $type, $return_value, $params) {
  373. if (empty($params['input_params']['entity_subtype'])
  374. || !in_array($params['input_params']['entity_subtype'], array('page', 'page_top'))) {
  375. return null;
  376. }
  377. if ($params['input_params']['purpose'] === 'write') {
  378. unset($return_value[ACCESS_PUBLIC]);
  379. return $return_value;
  380. }
  381. }
  382. /**
  383. * Called on view_vars, input/access hook
  384. * Prevent ACCESS_PUBLIC from ending up as a write access option
  385. *
  386. * @param string $hook
  387. * @param string $type
  388. * @param array $return
  389. * @param array $params
  390. * @return array
  391. */
  392. function pages_write_access_vars($hook, $type, $return, $params) {
  393. if ($return['name'] != 'write_access_id') {
  394. return $return;
  395. }
  396. if ($return['purpose'] != 'write') {
  397. return $return;
  398. }
  399. if ($return['value'] != ACCESS_PUBLIC && $return['value'] != ACCESS_DEFAULT) {
  400. return $return;
  401. }
  402. $default_access = get_default_access();
  403. if ($return['value'] == ACCESS_PUBLIC || $default_access == ACCESS_PUBLIC) {
  404. // is the value public, or default which resolves to public?
  405. // if so we'll set it to logged in, the next most permissible write access level
  406. $return['value'] = ACCESS_LOGGED_IN;
  407. }
  408. return $return;
  409. }