PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/elgg/engine/lib/widgets.php

https://bitbucket.org/rhizomatik/lorea_production/
PHP | 528 lines | 323 code | 86 blank | 119 comment | 93 complexity | 46eaaa95596e9020d369633f97d45487 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /**
  3. * Elgg widgets library.
  4. * Contains code for handling widgets.
  5. *
  6. * @package Elgg
  7. * @subpackage Core
  8. */
  9. /**
  10. * Override ElggObject in order to store widget data in ultra-private stores.
  11. */
  12. class ElggWidget extends ElggObject {
  13. protected function initialise_attributes() {
  14. parent::initialise_attributes();
  15. $this->attributes['subtype'] = "widget";
  16. }
  17. public function __construct($guid = null) {
  18. parent::__construct($guid);
  19. }
  20. /**
  21. * Override entity get and sets in order to save data to private data store.
  22. */
  23. public function get($name) {
  24. // See if its in our base attribute
  25. if (isset($this->attributes[$name])) {
  26. return $this->attributes[$name];
  27. }
  28. // No, so see if its in the private data store.
  29. $meta = get_private_setting($this->guid, $name);
  30. if ($meta) {
  31. return $meta;
  32. }
  33. // Can't find it, so return null
  34. return null;
  35. }
  36. /**
  37. * Override entity get and sets in order to save data to private data store.
  38. */
  39. public function set($name, $value) {
  40. if (array_key_exists($name, $this->attributes)) {
  41. // Check that we're not trying to change the guid!
  42. if ((array_key_exists('guid', $this->attributes)) && ($name=='guid')) {
  43. return false;
  44. }
  45. $this->attributes[$name] = $value;
  46. } else {
  47. return set_private_setting($this->guid, $name, $value);
  48. }
  49. return true;
  50. }
  51. }
  52. /**
  53. * Register a particular context for use with widgets.
  54. *
  55. * @param string $context The context we wish to enable context for
  56. */
  57. function use_widgets($context) {
  58. global $CONFIG;
  59. if (!isset($CONFIG->widgets)) {
  60. $CONFIG->widgets = new stdClass;
  61. }
  62. if (!isset($CONFIG->widgets->contexts)) {
  63. $CONFIG->widgets->contexts = array();
  64. }
  65. if (!empty($context)) {
  66. $CONFIG->widgets->contexts[] = $context;
  67. }
  68. }
  69. /**
  70. * Determines whether or not the current context is using widgets
  71. *
  72. * @return true|false Depending on widget status
  73. */
  74. function using_widgets() {
  75. global $CONFIG;
  76. $context = get_context();
  77. if (isset($CONFIG->widgets->contexts) && is_array($CONFIG->widgets->contexts)) {
  78. if (in_array($context, $CONFIG->widgets->contexts)) return true;
  79. }
  80. return false;
  81. }
  82. /**
  83. * When given a widget entity and a new requested location, saves the new location
  84. * and also provides a sensible ordering for all widgets in that column
  85. *
  86. * @param ElggObject $widget The widget entity
  87. * @param int $order The order within the column
  88. * @param int $column The column (1, 2 or 3)
  89. * @return true|false Depending on success
  90. */
  91. function save_widget_location(ElggObject $widget, $order, $column) {
  92. if ($widget instanceof ElggObject) {
  93. if ($widget->subtype == "widget") {
  94. // If you can't move the widget, don't save a new location
  95. if (!$widget->draggable) {
  96. return false;
  97. }
  98. // Sanitise the column value
  99. if ($column != 1 || $column != 2 || $column != 3) {
  100. $column = 1;
  101. }
  102. $widget->column = (int) $column;
  103. $ordertmp = array();
  104. $params = array(
  105. 'context' => $widget->context,
  106. 'column' => $column,
  107. );
  108. if ($entities = get_entities_from_metadata_multi($params,'object','widget')) {
  109. foreach($entities as $entity) {
  110. $entityorder = $entity->order;
  111. if ($entityorder < $order) {
  112. $ordertmp[$entityorder] = $entity;
  113. }
  114. if ($entityorder >= $order) {
  115. $ordertmp[$entityorder + 10000] = $entity;
  116. }
  117. }
  118. }
  119. $ordertmp[$order] = $widget;
  120. ksort($ordertmp);
  121. $orderticker = 10;
  122. foreach($ordertmp as $orderval => $entity) {
  123. $entity->order = $orderticker;
  124. $orderticker += 10;
  125. }
  126. return true;
  127. } else {
  128. register_error($widget->subtype);
  129. }
  130. }
  131. return false;
  132. }
  133. /**
  134. * Get widgets for a particular context and column, in order of display
  135. *
  136. * @param int $user_guid The owner user GUID
  137. * @param string $context The context (profile, dashboard etc)
  138. * @param int $column The column (1 or 2)
  139. * @return array|false An array of widget ElggObjects, or false
  140. */
  141. function get_widgets($user_guid, $context, $column) {
  142. $params = array(
  143. 'column' => $column,
  144. 'context' => $context
  145. );
  146. $widgets = get_entities_from_private_setting_multi($params, "object", "widget", $user_guid, "", 10000);
  147. if ($widgets) {
  148. $widgetorder = array();
  149. foreach($widgets as $widget) {
  150. $order = $widget->order;
  151. while(isset($widgetorder[$order])) {
  152. $order++;
  153. }
  154. $widgetorder[$order] = $widget;
  155. }
  156. ksort($widgetorder);
  157. return $widgetorder;
  158. }
  159. return false;
  160. }
  161. /**
  162. * Displays a particular widget
  163. *
  164. * @param ElggObject $widget The widget to display
  165. * @return string The HTML for the widget, including JavaScript wrapper
  166. */
  167. function display_widget(ElggObject $widget) {
  168. return elgg_view_entity($widget);
  169. }
  170. /**
  171. * Add a new widget instance
  172. *
  173. * @param int $entity_guid GUID of entity that owns this widget
  174. * @param string $handler The handler for this widget
  175. * @param string $context The page context for this widget
  176. * @param int $order The order to display this widget in
  177. * @param int $column The column to display this widget in (1, 2 or 3)
  178. * @param int $access_id If not specified, it is set to the default access level
  179. * @return true|false Depending on success
  180. */
  181. function add_widget($entity_guid, $handler, $context, $order = 0, $column = 1, $access_id = null) {
  182. if (empty($entity_guid) || empty($context) || empty($handler) || !widget_type_exists($handler)) {
  183. return false;
  184. }
  185. if ($entity = get_entity($entity_guid)) {
  186. $widget = new ElggWidget;
  187. $widget->owner_guid = $entity_guid;
  188. $widget->container_guid = $entity_guid;
  189. if (isset($access_id)) {
  190. $widget->access_id = $access_id;
  191. } else {
  192. $widget->access_id = get_default_access();
  193. }
  194. if (!$widget->save()) {
  195. return false;
  196. }
  197. $widget->handler = $handler;
  198. $widget->context = $context;
  199. $widget->column = $column;
  200. $widget->order = $order;
  201. // save_widget_location($widget, $order, $column);
  202. return true;
  203. }
  204. return false;
  205. }
  206. /**
  207. * Define a new widget type
  208. *
  209. * @param string $handler The identifier for the widget handler
  210. * @param string $name The name of the widget type
  211. * @param string $description A description for the widget type
  212. * @param string $context A comma-separated list of contexts where this widget is allowed (default: 'all')
  213. * @param true|false $multiple Whether or not multiple instances of this widget are allowed on a single dashboard (default: false)
  214. * @param string $position A comma-separated list of positions on the page (side or main) where this widget is allowed (default: "side,main")
  215. * @return true|false Depending on success
  216. */
  217. function add_widget_type($handler, $name, $description, $context = "all", $multiple = false, $positions = "side,main", $url = "") {
  218. if (!empty($handler) && !empty($name)) {
  219. global $CONFIG;
  220. if (!isset($CONFIG->widgets)) {
  221. $CONFIG->widgets = new stdClass;
  222. }
  223. if (!isset($CONFIG->widgets->handlers)) {
  224. $CONFIG->widgets->handlers = array();
  225. }
  226. $handlerobj = new stdClass;
  227. $handlerobj->name = $name;
  228. $handlerobj->description = $description;
  229. $handlerobj->context = explode(",",$context);
  230. $handlerobj->multiple = $multiple;
  231. $handlerobj->widget_url = $url;
  232. $handlerobj->positions = explode(",",$positions);
  233. $CONFIG->widgets->handlers[$handler] = $handlerobj;
  234. return true;
  235. }
  236. return false;
  237. }
  238. /**
  239. * Remove a widget type
  240. *
  241. * @param string $handler The identifier for the widget handler
  242. * @since 1.7.1
  243. */
  244. function remove_widget_type($handler) {
  245. global $CONFIG;
  246. if (!isset($CONFIG->widgets)) {
  247. return;
  248. }
  249. if (!isset($CONFIG->widgets->handlers)) {
  250. return;
  251. }
  252. if (isset($CONFIG->widgets->handlers[$handler])) {
  253. unset($CONFIG->widgets->handlers[$handler]);
  254. }
  255. }
  256. /**
  257. * Determines whether or not widgets with the specified handler have been defined
  258. *
  259. * @param string $handler The widget handler identifying string
  260. * @return true|false Whether or not those widgets exist
  261. */
  262. function widget_type_exists($handler) {
  263. global $CONFIG;
  264. if (!empty($CONFIG->widgets)
  265. && !empty($CONFIG->widgets->handlers)
  266. && is_array($CONFIG->widgets->handlers)
  267. && array_key_exists($handler, $CONFIG->widgets->handlers)) {
  268. return true;
  269. }
  270. return false;
  271. }
  272. /**
  273. * Returns an array of stdClass objects representing the defined widget types
  274. *
  275. * @return array A list of types defined (if any)
  276. */
  277. function get_widget_types() {
  278. global $CONFIG;
  279. if (empty($CONFIG->widgets) ||
  280. empty($CONFIG->widgets->handlers) ||
  281. !is_array($CONFIG->widgets->handlers)) {
  282. // no widgets
  283. return array();
  284. }
  285. if (!$context) {
  286. $context = get_context();
  287. }
  288. $widgets = array();
  289. foreach ($CONFIG->widgets->handlers as $key => $handler) {
  290. if (in_array('all', $handler->context) || in_array($context, $handler->context)) {
  291. $widgets[$key] = $handler;
  292. }
  293. }
  294. return $widgets;
  295. }
  296. /**
  297. * Saves a widget's settings (by passing an array of (name => value) pairs to save_{$handler}_widget)
  298. *
  299. * @param int $widget_guid The GUID of the widget we're saving to
  300. * @param array $params An array of name => value parameters
  301. */
  302. function save_widget_info($widget_guid, $params) {
  303. if ($widget = get_entity($widget_guid)) {
  304. $subtype = $widget->getSubtype();
  305. if ($subtype != "widget") {
  306. return false;
  307. }
  308. $handler = $widget->handler;
  309. if (empty($handler) || !widget_type_exists($handler)) {
  310. return false;
  311. }
  312. if (!$widget->canEdit()) {
  313. return false;
  314. }
  315. // Save the params to the widget
  316. if (is_array($params) && sizeof($params) > 0) {
  317. foreach($params as $name => $value) {
  318. if (!empty($name) && !in_array($name, array(
  319. 'guid','owner_guid','site_guid'
  320. ))) {
  321. if (is_array($value)) {
  322. // @todo Handle arrays securely
  323. $widget->setMetaData($name, $value, "", true);
  324. } else {
  325. $widget->$name = $value;
  326. }
  327. }
  328. }
  329. $widget->save();
  330. }
  331. $function = "save_{$handler}_widget";
  332. if (is_callable($function)) {
  333. return $function($params);
  334. }
  335. return true;
  336. }
  337. return false;
  338. }
  339. function reorder_widgets_from_panel($panelstring1, $panelstring2, $panelstring3, $context, $owner) {
  340. $return = true;
  341. $mainwidgets = explode('::',$panelstring1);
  342. $sidewidgets = explode('::',$panelstring2);
  343. $rightwidgets = explode('::',$panelstring3);
  344. $handlers = array();
  345. $guids = array();
  346. if (is_array($mainwidgets) && sizeof($mainwidgets) > 0) {
  347. foreach($mainwidgets as $widget) {
  348. $guid = (int) $widget;
  349. if ("{$guid}" == "{$widget}") {
  350. $guids[1][] = $widget;
  351. } else {
  352. $handlers[1][] = $widget;
  353. }
  354. }
  355. }
  356. if (is_array($sidewidgets) && sizeof($sidewidgets) > 0) {
  357. foreach($sidewidgets as $widget) {
  358. $guid = (int) $widget;
  359. if ("{$guid}" == "{$widget}") {
  360. $guids[2][] = $widget;
  361. } else {
  362. $handlers[2][] = $widget;
  363. }
  364. }
  365. }
  366. if (is_array($rightwidgets) && sizeof($rightwidgets) > 0) {
  367. foreach($rightwidgets as $widget) {
  368. $guid = (int) $widget;
  369. if ("{$guid}" == "{$widget}") {
  370. $guids[3][] = $widget;
  371. } else {
  372. $handlers[3][] = $widget;
  373. }
  374. }
  375. }
  376. // Reorder existing widgets or delete ones that have vanished
  377. foreach (array(1,2,3) as $column) {
  378. if ($dbwidgets = get_widgets($owner,$context,$column)) {
  379. foreach($dbwidgets as $dbwidget) {
  380. if (in_array($dbwidget->getGUID(),$guids[1]) || in_array($dbwidget->getGUID(),$guids[2]) || in_array($dbwidget->getGUID(),$guids[3])) {
  381. if (in_array($dbwidget->getGUID(),$guids[1])) {
  382. $pos = array_search($dbwidget->getGUID(),$guids[1]);
  383. $col = 1;
  384. } else if (in_array($dbwidget->getGUID(),$guids[2])) {
  385. $pos = array_search($dbwidget->getGUID(),$guids[2]);
  386. $col = 2;
  387. } else {
  388. $pos = array_search($dbwidget->getGUID(),$guids[3]);
  389. $col = 3;
  390. }
  391. $pos = ($pos + 1) * 10;
  392. $dbwidget->column = $col;
  393. $dbwidget->order = $pos;
  394. } else {
  395. $dbguid = $dbwidget->getGUID();
  396. if (!$dbwidget->delete()) {
  397. $return = false;
  398. } else {
  399. // Remove state cookie
  400. setcookie('widget' + $dbguid, null);
  401. }
  402. }
  403. }
  404. }
  405. // Add new ones
  406. if (sizeof($guids[$column]) > 0) {
  407. foreach($guids[$column] as $key => $guid) {
  408. if ($guid == 0) {
  409. $pos = ($key + 1) * 10;
  410. $handler = $handlers[$column][$key];
  411. if (!add_widget($owner,$handler,$context,$pos,$column)) {
  412. $return = false;
  413. }
  414. }
  415. }
  416. }
  417. }
  418. return $return;
  419. }
  420. /**
  421. * Run some things once.
  422. *
  423. */
  424. function widget_run_once() {
  425. // Register a class
  426. add_subtype("object", "widget", "ElggWidget");
  427. }
  428. /**
  429. * Function to initialise widgets functionality on Elgg init
  430. *
  431. */
  432. function widgets_init() {
  433. register_action('widgets/reorder');
  434. register_action('widgets/save');
  435. register_action('widgets/add');
  436. // Now run this stuff, but only once
  437. run_function_once("widget_run_once");
  438. }
  439. // Register event
  440. register_elgg_event_handler('init','system','widgets_init');
  441. // Use widgets on the dashboard
  442. use_widgets('dashboard');