ElggWidget.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <?php
  2. /**
  3. * \ElggWidget
  4. *
  5. * Stores metadata in private settings rather than as \ElggMetadata
  6. *
  7. * @package Elgg.Core
  8. * @subpackage Widgets
  9. *
  10. * @property-read string $handler internal, do not use
  11. * @property-read string $column internal, do not use
  12. * @property-read string $order internal, do not use
  13. * @property-read string $context internal, do not use
  14. */
  15. class ElggWidget extends \ElggObject {
  16. /**
  17. * Set subtype to widget.
  18. *
  19. * @return void
  20. */
  21. protected function initializeAttributes() {
  22. parent::initializeAttributes();
  23. $this->attributes['subtype'] = "widget";
  24. }
  25. /**
  26. * Get a value from attributes or private settings
  27. *
  28. * @param string $name The name of the value
  29. * @return mixed
  30. */
  31. public function __get($name) {
  32. // See if its in our base attribute
  33. if (array_key_exists($name, $this->attributes)) {
  34. return $this->attributes[$name];
  35. }
  36. // @todo clean up now that private settings return null
  37. // No, so see if its in the private data store.
  38. $meta = $this->getPrivateSetting($name);
  39. if ($meta) {
  40. return $meta;
  41. }
  42. // Can't find it, so return null
  43. return null;
  44. }
  45. /**
  46. * Override entity get and sets in order to save data to private data store.
  47. *
  48. * @param string $name Name
  49. * @return mixed
  50. * @deprecated 1.9
  51. */
  52. public function get($name) {
  53. elgg_deprecated_notice("Use -> instead of get()", 1.9);
  54. return $this->__get($name);
  55. }
  56. /**
  57. * Set an attribute or private setting value
  58. *
  59. * @param string $name The name of the value to set
  60. * @param mixed $value The value to set
  61. * @return void
  62. */
  63. public function __set($name, $value) {
  64. if (array_key_exists($name, $this->attributes)) {
  65. // Check that we're not trying to change the guid!
  66. if ((array_key_exists('guid', $this->attributes)) && ($name == 'guid')) {
  67. return;
  68. }
  69. $this->attributes[$name] = $value;
  70. } else {
  71. $this->setPrivateSetting($name, $value);
  72. }
  73. }
  74. /**
  75. * Override entity get and sets in order to save data to private data store.
  76. *
  77. * @param string $name Name
  78. * @param string $value Value
  79. * @return bool
  80. * @deprecated 1.9
  81. */
  82. public function set($name, $value) {
  83. elgg_deprecated_notice("Use -> instead of set()", 1.9);
  84. $this->__set($name, $value);
  85. return true;
  86. }
  87. /**
  88. * Set the widget context
  89. *
  90. * @param string $context The widget context
  91. * @return bool
  92. * @since 1.8.0
  93. */
  94. public function setContext($context) {
  95. return $this->setPrivateSetting('context', $context);
  96. }
  97. /**
  98. * Get the widget context
  99. *
  100. * @return string
  101. * @since 1.8.0
  102. */
  103. public function getContext() {
  104. return $this->getPrivateSetting('context');
  105. }
  106. /**
  107. * Get the title of the widget
  108. *
  109. * @return string
  110. * @since 1.8.0
  111. */
  112. public function getTitle() {
  113. $title = $this->title;
  114. if (!$title) {
  115. $title = _elgg_services()->widgets->getNameByType($this->handler);
  116. }
  117. return $title;
  118. }
  119. /**
  120. * Move the widget
  121. *
  122. * @param int $column The widget column
  123. * @param int $rank Zero-based rank from the top of the column
  124. * @return void
  125. * @since 1.8.0
  126. */
  127. public function move($column, $rank) {
  128. $options = array(
  129. 'type' => 'object',
  130. 'subtype' => 'widget',
  131. 'container_guid' => $this->container_guid,
  132. 'limit' => false,
  133. 'private_setting_name_value_pairs' => array(
  134. array('name' => 'context', 'value' => $this->getContext()),
  135. array('name' => 'column', 'value' => $column)
  136. )
  137. );
  138. $widgets = elgg_get_entities_from_private_settings($options);
  139. if (!$widgets) {
  140. $this->column = (int)$column;
  141. $this->order = 0;
  142. return;
  143. }
  144. usort($widgets, create_function('$a,$b','return (int)$a->order > (int)$b->order;'));
  145. // remove widgets from inactive plugins
  146. $widget_types = elgg_get_widget_types($this->context);
  147. $inactive_widgets = array();
  148. foreach ($widgets as $index => $widget) {
  149. if (!array_key_exists($widget->handler, $widget_types)) {
  150. $inactive_widgets[] = $widget;
  151. unset($widgets[$index]);
  152. }
  153. }
  154. $bottom_rank = count($widgets);
  155. if ($column == $this->column) {
  156. $bottom_rank--;
  157. }
  158. if ($rank == 0) {
  159. // top of the column
  160. $this->order = reset($widgets)->order - 10;
  161. } elseif ($rank == $bottom_rank) {
  162. // bottom of the column of active widgets
  163. $this->order = end($widgets)->order + 10;
  164. } else {
  165. // reorder widgets
  166. // remove the widget that's being moved from the array
  167. foreach ($widgets as $index => $widget) {
  168. if ($widget->guid == $this->guid) {
  169. unset($widgets[$index]);
  170. }
  171. }
  172. // split the array in two and recombine with the moved widget in middle
  173. $before = array_slice($widgets, 0, $rank);
  174. array_push($before, $this);
  175. $after = array_slice($widgets, $rank);
  176. $widgets = array_merge($before, $after);
  177. ksort($widgets);
  178. $order = 0;
  179. foreach ($widgets as $widget) {
  180. $widget->order = $order;
  181. $order += 10;
  182. }
  183. }
  184. // put inactive widgets at the bottom
  185. if ($inactive_widgets) {
  186. $bottom = 0;
  187. foreach ($widgets as $widget) {
  188. if ($widget->order > $bottom) {
  189. $bottom = $widget->order;
  190. }
  191. }
  192. $bottom += 10;
  193. foreach ($inactive_widgets as $widget) {
  194. $widget->order = $bottom;
  195. $bottom += 10;
  196. }
  197. }
  198. $this->column = $column;
  199. }
  200. /**
  201. * Saves the widget's settings
  202. *
  203. * Plugins can override the save mechanism using the plugin hook:
  204. * 'widget_settings', <widget handler identifier>. The widget and
  205. * the parameters are passed. The plugin hook handler should return
  206. * true to indicate that it has successfully saved the settings.
  207. *
  208. * @warning The values in the parameter array cannot be arrays
  209. *
  210. * @param array $params An array of name => value parameters
  211. *
  212. * @return bool
  213. * @since 1.8.0
  214. */
  215. public function saveSettings($params) {
  216. if (!$this->canEdit()) {
  217. return false;
  218. }
  219. // plugin hook handlers should return true to indicate the settings have
  220. // been saved so that default code does not run
  221. $hook_params = array(
  222. 'widget' => $this,
  223. 'params' => $params
  224. );
  225. if (_elgg_services()->hooks->trigger('widget_settings', $this->handler, $hook_params, false) == true) {
  226. return true;
  227. }
  228. if (is_array($params) && count($params) > 0) {
  229. foreach ($params as $name => $value) {
  230. if (is_array($value)) {
  231. // private settings cannot handle arrays
  232. return false;
  233. } else {
  234. $this->$name = $value;
  235. }
  236. }
  237. $this->save();
  238. }
  239. return true;
  240. }
  241. }