widgets.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. <?php
  2. /**
  3. * Elgg widgets library.
  4. * Contains code for handling widgets.
  5. *
  6. * @package Elgg.Core
  7. * @subpackage Widgets
  8. */
  9. /**
  10. * Get widgets for a particular context
  11. *
  12. * The widgets are ordered for display and grouped in columns.
  13. * $widgets = elgg_get_widgets(elgg_get_logged_in_user_guid(), 'dashboard');
  14. * $first_column_widgets = $widgets[1];
  15. *
  16. * @param int $owner_guid The owner GUID of the layout
  17. * @param string $context The context (profile, dashboard, etc)
  18. *
  19. * @return array An 2D array of \ElggWidget objects
  20. * @since 1.8.0
  21. */
  22. function elgg_get_widgets($owner_guid, $context) {
  23. return _elgg_services()->widgets->getWidgets($owner_guid, $context);
  24. }
  25. /**
  26. * Create a new widget instance
  27. *
  28. * @param int $owner_guid GUID of entity that owns this widget
  29. * @param string $handler The handler for this widget
  30. * @param string $context The context for this widget
  31. * @param int $access_id If not specified, it is set to the default access level
  32. *
  33. * @return int|false Widget GUID or false on failure
  34. * @since 1.8.0
  35. */
  36. function elgg_create_widget($owner_guid, $handler, $context, $access_id = null) {
  37. return _elgg_services()->widgets->createWidget($owner_guid, $handler, $context, $access_id);
  38. }
  39. /**
  40. * Can the user edit the widget layout
  41. *
  42. * Triggers a 'permissions_check', 'widget_layout' plugin hook
  43. *
  44. * @param string $context The widget context
  45. * @param int $user_guid The GUID of the user (0 for logged in user)
  46. *
  47. * @return bool
  48. * @since 1.8.0
  49. */
  50. function elgg_can_edit_widget_layout($context, $user_guid = 0) {
  51. return _elgg_services()->widgets->canEditLayout($context, $user_guid);
  52. }
  53. /**
  54. * Register a widget type
  55. *
  56. * This should be called by plugins in their init function.
  57. *
  58. * @param string $handler The identifier for the widget handler
  59. * @param string $name The name of the widget type
  60. * @param string $description A description for the widget type
  61. * @param array $context An array of contexts where this
  62. * widget is allowed (default: array('all'))
  63. * @param bool $multiple Whether or not multiple instances of this widget
  64. * are allowed in a single layout (default: false)
  65. *
  66. * @return bool
  67. * @since 1.8.0
  68. */
  69. function elgg_register_widget_type($handler, $name, $description, $context = array('all'), $multiple = false) {
  70. if (is_string($context)) {
  71. elgg_deprecated_notice('context parameters for elgg_register_widget_type() should be passed as an array())', 1.9);
  72. $context = explode(",", $context);
  73. } elseif (empty($context)) {
  74. $context = array('all');
  75. }
  76. return _elgg_services()->widgets->registerType($handler, $name, $description, $context, $multiple);
  77. }
  78. /**
  79. * Remove a widget type
  80. *
  81. * @param string $handler The identifier for the widget
  82. *
  83. * @return bool true if handler was found as unregistered
  84. * @since 1.8.0
  85. */
  86. function elgg_unregister_widget_type($handler) {
  87. return _elgg_services()->widgets->unregisterType($handler);
  88. }
  89. /**
  90. * Has a widget type with the specified handler been registered
  91. *
  92. * @param string $handler The widget handler identifying string
  93. *
  94. * @return bool Whether or not that widget type exists
  95. * @since 1.8.0
  96. */
  97. function elgg_is_widget_type($handler) {
  98. return _elgg_services()->widgets->validateType($handler);
  99. }
  100. /**
  101. * Get the widget types for a context
  102. *
  103. * The widget types are \stdClass objects.
  104. *
  105. * @param string $context The widget context or empty string for current context
  106. * @param bool $exact Only return widgets registered for this context (false)
  107. *
  108. * @return array
  109. * @since 1.8.0
  110. */
  111. function elgg_get_widget_types($context = "", $exact = false) {
  112. return _elgg_services()->widgets->getTypes($context, $exact);
  113. }
  114. /**
  115. * Set the widget title on ajax return from save action
  116. *
  117. * @param string $hook Hook name
  118. * @param string $type Hook type
  119. * @param array $results Array to be encoded as json
  120. * @param array $params Parameters about the request
  121. * @return array|null
  122. * @access private
  123. */
  124. function _elgg_widgets_set_ajax_title($hook, $type, $results, $params) {
  125. if ($params['action'] == 'widgets/save') {
  126. // @todo Elgg makes ajax so difficult - no other way to add data to output
  127. $widget = get_entity(get_input('guid'));
  128. if ($widget && $widget->title) {
  129. $results['title'] = $widget->title;
  130. return $results;
  131. }
  132. }
  133. }
  134. /**
  135. * Function to initialize widgets functionality
  136. *
  137. * @return void
  138. * @access private
  139. */
  140. function _elgg_widgets_init() {
  141. elgg_register_action('widgets/save');
  142. elgg_register_action('widgets/add');
  143. elgg_register_action('widgets/move');
  144. elgg_register_action('widgets/delete');
  145. elgg_register_action('widgets/upgrade', '', 'admin');
  146. elgg_register_plugin_hook_handler('output', 'ajax', '_elgg_widgets_set_ajax_title');
  147. }
  148. /**
  149. * Gets a list of events to create default widgets for and
  150. * register menu items for default widgets with the admin section.
  151. *
  152. * A plugin that wants to register a new context for default widgets should
  153. * register for the plugin hook 'get_list', 'default_widgets'. The handler
  154. * can register the new type of default widgets by adding an associate array to
  155. * the return value array like this:
  156. * array(
  157. * 'name' => elgg_echo('profile'),
  158. * 'widget_context' => 'profile',
  159. * 'widget_columns' => 3,
  160. *
  161. * 'event' => 'create',
  162. * 'entity_type' => 'user',
  163. * 'entity_subtype' => ELGG_ENTITIES_ANY_VALUE,
  164. * );
  165. *
  166. * The first set of keys define information about the new type of default
  167. * widgets and the second set determine what event triggers the creation of the
  168. * new widgets.
  169. *
  170. * @return void
  171. * @access private
  172. */
  173. function _elgg_default_widgets_init() {
  174. global $CONFIG;
  175. $default_widgets = elgg_trigger_plugin_hook('get_list', 'default_widgets', null, array());
  176. $CONFIG->default_widget_info = $default_widgets;
  177. if ($default_widgets) {
  178. elgg_register_admin_menu_item('configure', 'default_widgets', 'appearance');
  179. // override permissions for creating widget on logged out / just created entities
  180. elgg_register_plugin_hook_handler('container_permissions_check', 'object', '_elgg_default_widgets_permissions_override');
  181. // only register the callback once per event
  182. $events = array();
  183. foreach ($default_widgets as $info) {
  184. if (!is_array($info)) {
  185. continue;
  186. }
  187. $event = elgg_extract('event', $info);
  188. $entity_type = elgg_extract('entity_type', $info);
  189. if (!$event || !$entity_type) {
  190. continue;
  191. }
  192. if (!isset($events[$event][$entity_type])) {
  193. elgg_register_event_handler($event, $entity_type, '_elgg_create_default_widgets');
  194. $events[$event][$entity_type] = true;
  195. }
  196. }
  197. }
  198. }
  199. /**
  200. * Creates default widgets
  201. *
  202. * This plugin hook handler is registered for events based on what kinds of
  203. * default widgets have been registered. See elgg_default_widgets_init() for
  204. * information on registering new default widget contexts.
  205. *
  206. * @param string $event The event
  207. * @param string $type The type of object
  208. * @param \ElggEntity $entity The entity being created
  209. * @return void
  210. * @access private
  211. */
  212. function _elgg_create_default_widgets($event, $type, $entity) {
  213. $default_widget_info = elgg_get_config('default_widget_info');
  214. if (!$default_widget_info || !$entity) {
  215. return;
  216. }
  217. $type = $entity->getType();
  218. $subtype = $entity->getSubtype();
  219. // event is already guaranteed by the hook registration.
  220. // need to check subtype and type.
  221. foreach ($default_widget_info as $info) {
  222. if ($info['entity_type'] == $type) {
  223. if ($info['entity_subtype'] == ELGG_ENTITIES_ANY_VALUE || $info['entity_subtype'] == $subtype) {
  224. // need to be able to access everything
  225. $old_ia = elgg_set_ignore_access(true);
  226. elgg_push_context('create_default_widgets');
  227. // pull in by widget context with widget owners as the site
  228. // not using elgg_get_widgets() because it sorts by columns and we don't care right now.
  229. $options = array(
  230. 'type' => 'object',
  231. 'subtype' => 'widget',
  232. 'owner_guid' => elgg_get_site_entity()->guid,
  233. 'private_setting_name' => 'context',
  234. 'private_setting_value' => $info['widget_context'],
  235. 'limit' => 0
  236. );
  237. $widgets = elgg_get_entities_from_private_settings($options);
  238. /* @var \ElggWidget[] $widgets */
  239. foreach ($widgets as $widget) {
  240. // change the container and owner
  241. $new_widget = clone $widget;
  242. $new_widget->container_guid = $entity->guid;
  243. $new_widget->owner_guid = $entity->guid;
  244. // pull in settings
  245. $settings = get_all_private_settings($widget->guid);
  246. foreach ($settings as $name => $value) {
  247. $new_widget->$name = $value;
  248. }
  249. $new_widget->save();
  250. }
  251. elgg_set_ignore_access($old_ia);
  252. elgg_pop_context();
  253. }
  254. }
  255. }
  256. }
  257. /**
  258. * Overrides permissions checks when creating widgets for logged out users.
  259. *
  260. * @param string $hook The permissions hook.
  261. * @param string $type The type of entity being created.
  262. * @param string $return Value
  263. * @param mixed $params Params
  264. * @return true|null
  265. * @access private
  266. */
  267. function _elgg_default_widgets_permissions_override($hook, $type, $return, $params) {
  268. if ($type == 'object' && $params['subtype'] == 'widget') {
  269. return elgg_in_context('create_default_widgets') ? true : null;
  270. }
  271. return null;
  272. }
  273. return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
  274. $events->registerHandler('init', 'system', '_elgg_widgets_init');
  275. $events->registerHandler('ready', 'system', '_elgg_default_widgets_init');
  276. };