PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/core/model/modx/moddashboardwidget.class.php

http://github.com/modxcms/revolution
PHP | 326 lines | 171 code | 21 blank | 134 comment | 23 complexity | 381be501c004a68dbd49b9bd919a15d1 MD5 | raw file
Possible License(s): GPL-2.0, Apache-2.0, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /*
  3. * This file is part of MODX Revolution.
  4. *
  5. * Copyright (c) MODX, LLC. All Rights Reserved.
  6. *
  7. * For complete copyright and license information, see the COPYRIGHT and LICENSE
  8. * files found in the top-level directory of this distribution.
  9. */
  10. /**
  11. * Abstraction of a Dashboard Widget, which can be placed on Dashboards for welcome screen customization.
  12. *
  13. * @property string $name The name of this widget
  14. * @property string $description A short description, or lexicon key, of this widget
  15. * @property string $type The type of widget that this is: file/snippet/html
  16. * @property string $content The content, or location, of this widget
  17. * @property string $namespace The namespace key of this widget
  18. * @property string $lexicon The lexicon that will be loaded for this widget's description/execution
  19. *
  20. * @property modNamespace $Namespace The Namespace this widget is related to
  21. * @property array $Placements An array of Placements this widget has been put on in Dashboards
  22. * @package modx
  23. */
  24. class modDashboardWidget extends xPDOSimpleObject {
  25. public function toArray($keyPrefix = '',$rawValues = false,$excludeLazy = false,$includeRelated = false) {
  26. $array = parent::toArray($keyPrefix,$rawValues,$excludeLazy);
  27. if (!empty($this->xpdo->lexicon) && $this->xpdo->lexicon instanceof modLexicon) {
  28. if ($this->get('lexicon') != 'core:dashboards') {
  29. $this->xpdo->lexicon->load($this->get('lexicon'));
  30. }
  31. $array['name_trans'] = $this->xpdo->lexicon->exists($this->get('name')) ? $this->xpdo->lexicon($this->get('name')) : $this->get('name');
  32. $array['description_trans'] = $this->xpdo->lexicon->exists($this->get('description')) ? $this->xpdo->lexicon($this->get('description')) : $this->get('description');
  33. }
  34. return $array;
  35. }
  36. /**
  37. * Return the output for the widget, processed by type
  38. *
  39. * @param modManagerController $controller
  40. * @return mixed
  41. */
  42. public function getContent($controller) {
  43. /** @var string $lexicon */
  44. $lexicon = $this->get('lexicon');
  45. if (!empty($lexicon) && !empty($this->xpdo->lexicon)) {
  46. $this->xpdo->lexicon->load($lexicon);
  47. }
  48. /** @var modNamespace $namespace */
  49. $namespace = $this->getOne('Namespace');
  50. /** @var string $content */
  51. $content = $this->get('content');
  52. /** @var modDashboardWidgetInterface $widget */
  53. $widget = null;
  54. switch (strtolower($this->get('type'))) {
  55. /* file/class-based widget */
  56. case 'file':
  57. $content = str_replace(array(
  58. '[[++base_path]]',
  59. '[[++core_path]]',
  60. '[[++manager_path]]',
  61. '[[++assets_path]]',
  62. '[[++manager_theme]]',
  63. ),array(
  64. $this->xpdo->getOption('base_path',null,MODX_BASE_PATH),
  65. $this->xpdo->getOption('core_path',null,MODX_CORE_PATH),
  66. $this->xpdo->getOption('manager_path',null,MODX_MANAGER_PATH),
  67. $this->xpdo->getOption('assets_path',null,MODX_ASSETS_PATH),
  68. $this->xpdo->getOption('manager_theme',null,'default'),
  69. ),$content);
  70. if (file_exists($content)) {
  71. $modx =& $this->xpdo;
  72. $scriptProperties = $this->toArray();
  73. ob_start();
  74. $className = include_once $content;
  75. $buffer = ob_get_contents();
  76. ob_end_clean();
  77. if (class_exists($className)) { /* is a class-based widget */
  78. /** @var modDashboardWidgetInterface $widget */
  79. $widget = new $className($this->xpdo,$this,$controller);
  80. } else { /* just a standard file with a return */
  81. if (($className === 1 || $className === true) && !empty($buffer)) {
  82. $className = $buffer;
  83. }
  84. $widget = new modDashboardFileWidget($this->xpdo,$this,$controller);
  85. $widget->setContent($className);
  86. }
  87. }
  88. break;
  89. /* Snippet widget */
  90. case 'snippet':
  91. $widget = new modDashboardSnippetWidget($this->xpdo,$this,$controller);
  92. break;
  93. /* PHP (Snippet) widget */
  94. case 'php':
  95. $widget = new modDashboardPhpWidget($this->xpdo,$this,$controller);
  96. break;
  97. /* HTML/static content widget */
  98. case 'html':
  99. default:
  100. $widget = new modDashboardHtmlWidget($this->xpdo,$this,$controller);
  101. break;
  102. }
  103. // Make sure we actually have a widget before proceeding
  104. if ($widget === null) {
  105. if ($controller === null) {
  106. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Failed to load dashboard widget with unknown controller.');
  107. return null;
  108. }
  109. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Failed to load dashboard widget with controller title "' . $controller->getPageTitle() . '".');
  110. return null;
  111. }
  112. if (!empty($namespace)) {
  113. $widget->setNamespace($namespace);
  114. }
  115. return $widget->process();
  116. }
  117. }
  118. /**
  119. * A file-based widget that returns only the content of its include.
  120. *
  121. * @package modx
  122. * @subpackage dashboard
  123. */
  124. class modDashboardFileWidget extends modDashboardWidgetInterface {
  125. public function render() {
  126. return $this->content;
  127. }
  128. }
  129. /**
  130. * A widget that contains only HTML.
  131. *
  132. * @package modx
  133. * @subpackage dashboard
  134. */
  135. class modDashboardHtmlWidget extends modDashboardWidgetInterface {
  136. public function render() {
  137. return $this->widget->get('content');
  138. }
  139. }
  140. /**
  141. * A widget that runs its content as PHP in Snippet-like format to get its content.
  142. * @package modx
  143. * @subpackage dashboard
  144. */
  145. class modDashboardPhpWidget extends modDashboardWidgetInterface {
  146. public function render() {
  147. return $this->renderAsSnippet();
  148. }
  149. }
  150. /**
  151. * A Snippet-based widget that loads a MODX Snippet to return its content.
  152. * @package modx
  153. * @subpackage dashboard
  154. */
  155. class modDashboardSnippetWidget extends modDashboardWidgetInterface {
  156. public function render() {
  157. /** @var modSnippet $snippet */
  158. $snippet = $this->modx->getObject('modSnippet',array(
  159. 'name' => $this->widget->get('content'),
  160. ));
  161. if ($snippet) {
  162. $snippet->setCacheable(false);
  163. $content = $snippet->process(array(
  164. 'controller' => $this->controller,
  165. ));
  166. } else {
  167. $content = '';
  168. }
  169. return $content;
  170. }
  171. }
  172. /**
  173. * Abstract class used for creating Dashboard Widgets. In your widget file, simply return the name of the class
  174. * at the end of the file, and MODX will instantiate your class as a widget, and run the render() method to get
  175. * the widget output.
  176. *
  177. * @abstract
  178. * @package modx
  179. * @subpackage dashboard
  180. */
  181. abstract class modDashboardWidgetInterface {
  182. /**
  183. * A reference to the modX|xPDO instance
  184. * @var xPDO|modX $modx
  185. */
  186. public $modx;
  187. /**
  188. * A reference to the currently loaded manager controller
  189. * @var modManagerController $controller
  190. */
  191. public $controller;
  192. /**
  193. * A reference to this class's widget
  194. * @var modDashboardWidget $widget
  195. */
  196. public $widget;
  197. /**
  198. * A reference to the Namespace that this widget is executing in
  199. * @var modNamespace $namespace
  200. */
  201. public $namespace;
  202. /**
  203. * Allows widgets to specify a CSS class to attach to the block
  204. *
  205. * @var string
  206. */
  207. public $cssBlockClass = '';
  208. /**
  209. * @var string
  210. */
  211. public $content = '';
  212. /**
  213. * @param xPDO|modX $modx A reference to the modX instance
  214. * @param modDashboardWidget $widget A reference to this class's widget
  215. * @param modManagerController $controller A reference to the currently loaded manager controller
  216. */
  217. function __construct(xPDO &$modx,modDashboardWidget &$widget,modManagerController &$controller) {
  218. $this->modx =& $modx;
  219. $this->widget =& $widget;
  220. $this->controller =& $controller;
  221. }
  222. /**
  223. * Set the widget content
  224. * @param string $content
  225. * @return void
  226. */
  227. public function setContent($content) {
  228. $this->content = $content;
  229. }
  230. /**
  231. * Renders the content of the block in the appropriate size
  232. * @return string
  233. */
  234. public function process() {
  235. $output = $this->render();
  236. if (!empty($output)) {
  237. $widgetArray = $this->widget->toArray();
  238. $widgetArray['content'] = $output;
  239. $widgetArray['class'] = $this->cssBlockClass;
  240. $output = $this->getFileChunk('dashboard/block.tpl',$widgetArray);
  241. $output = preg_replace('@\[\[(.[^\[\[]*?)\]\]@si','',$output);
  242. $output = preg_replace('@\[\[(.[^\[\[]*?)\]\]@si','',$output);
  243. }
  244. return $output;
  245. }
  246. /**
  247. * Sets the Namespace that this widget will execute in
  248. * @param modNamespace $namespace
  249. * @return void
  250. */
  251. public function setNamespace(modNamespace $namespace) {
  252. $this->namespace =& $namespace;
  253. }
  254. /**
  255. * Returns an array of placeholders for the block from the widget class. Override to add or change placeholders.
  256. * @return array
  257. */
  258. public function toArray() {
  259. return $this->widget->toArray();
  260. }
  261. /**
  262. * Must be declared in your derivative class. Must return the processed output of the widget.
  263. * @abstract
  264. * @return string
  265. */
  266. abstract public function render();
  267. /**
  268. * @param string $tpl
  269. * @param array $placeholders
  270. * @return string
  271. */
  272. public function getFileChunk($tpl,array $placeholders = array()) {
  273. $output = '';
  274. $file = $tpl;
  275. if (!file_exists($file)) {
  276. $file = $this->modx->getOption('manager_path').'templates/'.$this->modx->getOption('manager_theme',null,'default').'/'.$tpl;
  277. }
  278. if (!file_exists($file)) {
  279. $file = $this->modx->getOption('manager_path').'templates/default/'.$tpl;
  280. }
  281. if (file_exists($file)) {
  282. /** @var modChunk $chunk */
  283. $chunk = $this->modx->newObject('modChunk');
  284. $chunk->setCacheable(false);
  285. $tplContent = file_get_contents($file);
  286. $chunk->setContent($tplContent);
  287. $output = $chunk->process($placeholders);
  288. }
  289. return $output;
  290. }
  291. /**
  292. * Render the widget content as if it were a Snippet
  293. *
  294. * @param string $content
  295. * @return string
  296. */
  297. public function renderAsSnippet($content = '') {
  298. if (empty($content)) $content = $this->widget->get('content');
  299. $content = str_replace(array('<?php','?>'),'',$content);
  300. $closure = create_function('$scriptProperties','global $modx;if (is_array($scriptProperties)) {extract($scriptProperties, EXTR_SKIP);}'.$content);
  301. return $closure(array(
  302. 'controller' => $this->controller,
  303. ));
  304. }
  305. }