PageRenderTime 21ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/system/cms/modules/widgets/libraries/Widgets.php

https://github.com/kadoshmt/Pyro-Deals
PHP | 476 lines | 347 code | 107 blank | 22 comment | 24 complexity | 69e01506378c6fb8b3dc6fffb3b2865b MD5 | raw file
  1. <?php defined('BASEPATH') OR exit('No direct script access allowed');
  2. /**
  3. * @package PyroCMS
  4. * @subpackage Widget module
  5. * @author Phil Sturgeon - PyroCMS Development Team
  6. *
  7. * Widget library takes care of the logic for widgets
  8. */
  9. class Widgets {
  10. private $_widget = NULL;
  11. private $_rendered_areas = array();
  12. private $_widget_locations = array();
  13. function __construct()
  14. {
  15. $this->load->model('widgets/widget_m');
  16. $locations = array(APPPATH,
  17. ADDONPATH,
  18. SHARED_ADDONPATH,
  19. SHARED_ADDONPATH.'themes/'.ADMIN_THEME.'/',
  20. APPPATH.'themes/'.ADMIN_THEME.'/',
  21. ADDONPATH.'themes/'.ADMIN_THEME.'/'
  22. );
  23. // Map where all widgets are
  24. foreach ($locations as $path)
  25. {
  26. $widgets = glob($path . 'widgets/*', GLOB_ONLYDIR);
  27. if ( ! is_array($widgets))
  28. {
  29. $widgets = array();
  30. }
  31. $module_widgets = glob($path . 'modules/*/widgets/*', GLOB_ONLYDIR);
  32. if ( ! is_array($module_widgets))
  33. {
  34. $module_widgets = array();
  35. }
  36. $widgets = array_merge($widgets, $module_widgets);
  37. foreach ($widgets as $widget_path)
  38. {
  39. $slug = basename($widget_path);
  40. // Set this so we know where it is later
  41. $this->_widget_locations[$slug] = $widget_path . '/';
  42. }
  43. }
  44. }
  45. function list_areas()
  46. {
  47. return $this->widget_m->get_areas();
  48. }
  49. function list_area_instances($slug)
  50. {
  51. return is_array($slug) ? $this->widget_m->get_by_areas($slug) : $this->widget_m->get_by_area($slug);
  52. }
  53. function list_available_widgets()
  54. {
  55. // Firstly, install any uninstalled widgets
  56. $uninstalled_widgets = $this->list_uninstalled_widgets();
  57. foreach ($uninstalled_widgets as $widget)
  58. {
  59. $this->add_widget((array) $widget);
  60. }
  61. // Secondly, uninstall any installed widgets missed
  62. $installed_widgets = $this->widget_m->order_by('slug')->get_all();
  63. $avaliable = array();
  64. foreach ($installed_widgets as $widget)
  65. {
  66. if ( ! isset($this->_widget_locations[$widget->slug]))
  67. {
  68. $this->delete_widget($widget->slug);
  69. continue;
  70. }
  71. $avaliable[] = $widget;
  72. }
  73. return $avaliable;
  74. }
  75. function list_uninstalled_widgets()
  76. {
  77. $available = $this->widget_m->order_by('slug')->get_all();
  78. $available_slugs = array();
  79. foreach ($available as $widget)
  80. {
  81. $available_slugs[] = $widget->slug;
  82. }
  83. unset($widget);
  84. $uninstalled = array();
  85. foreach ($this->_widget_locations as $widget_path)
  86. {
  87. $slug = basename($widget_path);
  88. if ( ! in_array($slug, $available_slugs) AND $widget = $this->read_widget($slug))
  89. {
  90. $uninstalled[] = $widget;
  91. }
  92. }
  93. return $uninstalled;
  94. }
  95. function get_instance($instance_id)
  96. {
  97. $widget = $this->widget_m->get_instance($instance_id);
  98. if ($widget)
  99. {
  100. $widget->options = $this->_unserialize_options($widget->options);
  101. return $widget;
  102. }
  103. return FALSE;
  104. }
  105. function get_area($id)
  106. {
  107. return is_numeric($id) ? $this->widget_m->get_area_by('id', $id) : $this->widget_m->get_area_by('slug', $id);
  108. }
  109. function get_widget($id)
  110. {
  111. return is_numeric($id) ? $this->widget_m->get_widget_by('id', $id) : $this->widget_m->get_widget_by('slug', $id);
  112. }
  113. function read_widget($slug)
  114. {
  115. $this->_spawn_widget($slug);
  116. if ($this->_widget === FALSE OR ! is_subclass_of($this->_widget, 'Widgets'))
  117. {
  118. return FALSE;
  119. }
  120. $widget = (object) get_object_vars($this->_widget);
  121. $widget->slug = $slug;
  122. $widget->module = strpos($this->_widget->path, 'modules/') ? basename(dirname($this->_widget->path)) : NULL;
  123. $widget->is_addon = strpos($this->_widget->path, 'addons/') !== FALSE;
  124. return $widget;
  125. }
  126. function render($name, $options = array())
  127. {
  128. $this->_spawn_widget($name);
  129. $data = method_exists($this->_widget, 'run') ? call_user_func(array($this->_widget, 'run'), $options) : array();
  130. // Don't run this widget
  131. if ($data === FALSE)
  132. {
  133. return FALSE;
  134. }
  135. // If we have TRUE, just make an empty array
  136. $data !== TRUE OR $data = array();
  137. // convert to array
  138. is_array($data) OR $data = (array) $data;
  139. $data['options'] = $options;
  140. return $this->load_view('display', $data);
  141. }
  142. function render_backend($name, $saved_data = array())
  143. {
  144. $this->_spawn_widget($name);
  145. // No fields, no backend, no rendering
  146. if (empty($this->_widget->fields))
  147. {
  148. return '';
  149. }
  150. $options = array();
  151. $_arrays = array();
  152. foreach ($this->_widget->fields as $field)
  153. {
  154. $field_name = &$field['field'];
  155. if (($pos = strpos($field_name, '[')) !== FALSE)
  156. {
  157. $key = substr($field_name, 0, $pos);
  158. if ( ! in_array($key, $_arrays))
  159. {
  160. $options[$key] = $this->input->post($key);
  161. $_arrays[] = $key;
  162. }
  163. }
  164. $options[$field_name] = set_value($field_name, isset($saved_data[$field_name]) ? $saved_data[$field_name] : '');
  165. unset($saved_data[$field_name]);
  166. }
  167. // Any extra data? Merge it in, but options wins!
  168. if ( ! empty($saved_data))
  169. {
  170. $options = array_merge($saved_data, $options);
  171. }
  172. // Check for default data if there is any
  173. $data = method_exists($this->_widget, 'form') ? call_user_func(array(&$this->_widget, 'form'), $options) : array();
  174. // Options we'rent changed, lets use the defaults
  175. isset($data['options']) OR $data['options'] = $options;
  176. return $this->load_view('form', $data);
  177. }
  178. function render_area($area)
  179. {
  180. if (isset($this->_rendered_areas[$area]))
  181. {
  182. return $this->_rendered_areas[$area];
  183. }
  184. $widgets = $this->widget_m->get_by_area($area);
  185. $output = '';
  186. $view = 'widget_wrapper';
  187. $path = $this->template->get_views_path() . 'modules/widgets/';
  188. if ( ! file_exists($path . $view . EXT))
  189. {
  190. list($path, $view) = Modules::find($view, 'widgets', 'views/');
  191. }
  192. $save_path = $this->load->_ci_view_path;
  193. foreach ($widgets as $widget)
  194. {
  195. $widget->options = $this->_unserialize_options($widget->options);
  196. $widget->body = $this->render($widget->slug, $widget->options);
  197. if ($widget->body !== FALSE)
  198. {
  199. $this->load->_ci_view_path = $path;
  200. $output .= $this->load->_ci_load(array('_ci_view' => $view, '_ci_vars' => array('widget' => $widget), '_ci_return' => TRUE)) . "\n";
  201. // Put the path back
  202. $this->load->_ci_view_path = $save_path;
  203. }
  204. }
  205. $this->_rendered_areas[$area] = $output;
  206. return $output;
  207. }
  208. function reload_widget($slug)
  209. {
  210. if (is_array($slug))
  211. {
  212. foreach ($slug as $_slug)
  213. {
  214. if ( ! $this->reload_widget($_slug))
  215. {
  216. return FALSE;
  217. }
  218. }
  219. return TRUE;
  220. }
  221. $widget = $this->read_widget($slug);
  222. return $this->edit_widget(array(
  223. 'title' => $widget->title,
  224. 'slug' => $widget->slug,
  225. 'description' => $widget->description,
  226. 'author' => $widget->author,
  227. 'website' => $widget->website,
  228. 'version' => $widget->version
  229. ));
  230. }
  231. function add_widget($input)
  232. {
  233. return $this->widget_m->insert_widget($input);
  234. }
  235. function edit_widget($input)
  236. {
  237. return $this->widget_m->update_widget($input);
  238. }
  239. function update_widget_order($id, $position)
  240. {
  241. return $this->widget_m->update_widget_order($id, $position);
  242. }
  243. function delete_widget($slug)
  244. {
  245. return $this->widget_m->delete_widget($slug);
  246. }
  247. function add_area($input)
  248. {
  249. return $this->widget_m->insert_area((array) $input);
  250. }
  251. function edit_area($input)
  252. {
  253. return $this->widget_m->update_area((array) $input);
  254. }
  255. function delete_area($slug)
  256. {
  257. return $this->widget_m->delete_area($slug);
  258. }
  259. function add_instance($title, $widget_id, $widget_area_id, $options = array(), $data = array())
  260. {
  261. $slug = $this->get_widget($widget_id)->slug;
  262. if ($error = $this->validation_errors($slug, $data))
  263. {
  264. return array('status' => 'error', 'error' => $error);
  265. }
  266. // The widget has to do some stuff before it saves
  267. $options = $this->widgets->prepare_options($slug, $options);
  268. $this->widget_m->insert_instance(array(
  269. 'title' => $title,
  270. 'widget_id' => $widget_id,
  271. 'widget_area_id' => $widget_area_id,
  272. 'options' => $this->_serialize_options($options),
  273. 'data' => $data
  274. ));
  275. return array('status' => 'success');
  276. }
  277. function edit_instance($instance_id, $title, $widget_area_id, $options = array(), $data = array())
  278. {
  279. $slug = $this->widget_m->get_instance($instance_id)->slug;
  280. if ($error = $this->validation_errors($slug, $options))
  281. {
  282. return array('status' => 'error', 'error' => $error);
  283. }
  284. // The widget has to do some stuff before it saves
  285. $options = $this->widgets->prepare_options($slug, $options);
  286. $this->widget_m->update_instance($instance_id, array(
  287. 'title' => $title,
  288. 'widget_area_id' => $widget_area_id,
  289. 'options' => $this->_serialize_options($options),
  290. 'data' => $data
  291. ));
  292. return array('status' => 'success');
  293. }
  294. function update_instance_order($id, $position)
  295. {
  296. return $this->widget_m->update_instance_order($id, $position);
  297. }
  298. function delete_instance($id)
  299. {
  300. return $this->widget_m->delete_instance($id);
  301. }
  302. function validation_errors($name, $options)
  303. {
  304. // $_POST = $options;
  305. $this->load->library('form_validation');
  306. $this->form_validation->set_rules('title', lang('title_label'), 'trim|required|max_length[100]');
  307. $this->_widget OR $this->_spawn_widget($name);
  308. if (property_exists($this->_widget, 'fields'))
  309. {
  310. $this->form_validation->set_rules($this->_widget->fields);
  311. }
  312. if ( ! $this->form_validation->run('', FALSE))
  313. {
  314. return validation_errors();
  315. }
  316. }
  317. function prepare_options($name, $options = array())
  318. {
  319. $this->_widget OR $this->_spawn_widget($name);
  320. if (method_exists($this->_widget, 'save'))
  321. {
  322. return (array) call_user_func(array(&$this->_widget, 'save'), $options);
  323. }
  324. return $options;
  325. }
  326. private function _spawn_widget($name)
  327. {
  328. $widget_path = $this->_widget_locations[$name];
  329. if (file_exists(FCPATH . $widget_path . $name . EXT))
  330. {
  331. require_once FCPATH . $widget_path . $name . EXT;
  332. $class_name = 'Widget_' . ucfirst($name);
  333. $this->_widget = new $class_name;
  334. $this->_widget->path = $widget_path;
  335. return;
  336. }
  337. $this->_widget = NULL;
  338. }
  339. public function __get($var)
  340. {
  341. if (isset(get_instance()->$var))
  342. {
  343. return get_instance()->$var;
  344. }
  345. }
  346. protected function load_view($view, $data = array())
  347. {
  348. $path = isset($this->_widget->path) ? $this->_widget->path : $this->path;
  349. return $view == 'display'
  350. ? $this->parser->parse_string($this->load->_ci_load(array(
  351. '_ci_path' => $path . 'views/' . $view . EXT,
  352. '_ci_vars' => $data,
  353. '_ci_return' => TRUE
  354. )), array(), TRUE)
  355. : $this->load->_ci_load(array(
  356. '_ci_path' => $path . 'views/' . $view . EXT,
  357. '_ci_vars' => $data,
  358. '_ci_return' => TRUE
  359. ));
  360. }
  361. private function _serialize_options($options)
  362. {
  363. return serialize((array) $options);
  364. }
  365. private function _unserialize_options($options)
  366. {
  367. return (array) unserialize($options);
  368. }
  369. }