PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Web/POM/Panel.php

http://github.com/AlephTav/Aleph
PHP | 403 lines | 165 code | 28 blank | 210 comment | 8 complexity | fe0f52f91789aa678d9222ef97708529 MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * Copyright (c) 2013 - 2015 Aleph Tav
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  6. * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
  8. * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  13. * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  15. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. *
  17. * @author Aleph Tav <4lephtav@gmail.com>
  18. * @link http://www.4leph.com
  19. * @copyright Copyright &copy; 2013 - 2015 Aleph Tav
  20. * @license http://www.opensource.org/licenses/MIT
  21. */
  22. namespace Aleph\Web\POM;
  23. use Aleph\Core,
  24. Aleph\MVC,
  25. Aleph\Web,
  26. Aleph\Utils;
  27. /**
  28. * The base class of all container controls that have the main functionality such as:
  29. * adding a control to the panel, removing a control from the panel, search controls within a panel and other methods.
  30. *
  31. * The control has the following properties:
  32. * id - the logic identifier of the control.
  33. * visible - determines whether or not the control is visible on the client side.
  34. * tag - determines HTML tag of the container element.
  35. * expire - determines the cache lifetime (in seconds) of the render process. The default value is 0 (no cache).
  36. *
  37. * @author Aleph Tav <4lephtav@gmail.com>
  38. * @version 1.0.0
  39. * @package aleph.web.pom
  40. */
  41. class Panel extends Control implements \IteratorAggregate, \Countable
  42. {
  43. // Error message templates.
  44. const ERR_PANEL_1 = 'Web control %s does not exist in panel %s (full ID: %s).';
  45. /**
  46. * The panel template object.
  47. *
  48. * @var Aleph\Core\Template $tpl
  49. * @access public
  50. */
  51. public $tpl = null;
  52. /**
  53. * The control type.
  54. *
  55. * @var string $ctrl
  56. * @access protected
  57. */
  58. protected $ctrl = 'panel';
  59. /**
  60. * The panel controls.
  61. *
  62. * @var array $controls
  63. * @access protected
  64. */
  65. protected $controls = [];
  66. /**
  67. * It equals TRUE if some control detaches from the panel. Otherwise it is FALSE.
  68. *
  69. * @var boolean $inDetach
  70. * @access protected
  71. */
  72. protected $inDetach = false;
  73. /**
  74. * Constructor. Initializes the panel template object.
  75. *
  76. * @param string $id - the logic identifier of the panel.
  77. * @param string $template - the panel template or the full path to the template file.
  78. * @param integer $expire - the cache lifetime of the panel template.
  79. * @access public
  80. */
  81. public function __construct($id, $template = null, $expire = 0)
  82. {
  83. parent::__construct($id);
  84. $this->properties['tag'] = 'div';
  85. $this->properties['expire'] = $expire;
  86. $this->tpl = new Core\Template($template);
  87. $this->tpl->cacheID = $this->attributes['id'];
  88. $this->tpl->cacheExpire = $expire;
  89. }
  90. /**
  91. * Returns view state of the panel.
  92. *
  93. * @return array
  94. * @access public
  95. */
  96. public function getVS()
  97. {
  98. return parent::getVS() + ['controls' => array_keys($this->controls),
  99. 'tpl' => $this->tpl->getTemplate(),
  100. 'tplVars' => $this->tpl->getVars(),
  101. 'tplExpire' => $this->tpl->cacheExpire,
  102. 'tplGroup' => $this->tpl->cacheGroup,
  103. 'tplID' => $this->tpl->cacheID];
  104. }
  105. /**
  106. * Sets view state of the panel.
  107. *
  108. * @param array $vs - the panel view state.
  109. * @return self
  110. * @access public
  111. */
  112. public function setVS(array $vs)
  113. {
  114. $this->controls = array_combine($vs['controls'], $vs['controls']);
  115. $this->tpl->setTemplate($vs['tpl']);
  116. $this->tpl->setVars($vs['tplVars']);
  117. $this->tpl->cacheID = $vs['tplID'];
  118. $this->tpl->cacheExpire = $vs['tplExpire'];
  119. $this->tpl->cacheGroup = $vs['tplGroup'];
  120. parent::setVS($vs);
  121. }
  122. /**
  123. * Sets value of the panel property.
  124. *
  125. * @param string $property - the property name.
  126. * @param mixed $value - the property value.
  127. * @access public
  128. */
  129. public function offsetSet($property, $value)
  130. {
  131. if (strtolower($property) == 'expire') $this->tpl->cacheExpire = $value;
  132. parent::offsetSet($property, $value);
  133. }
  134. /**
  135. * Returns controls of the panel.
  136. *
  137. * @return array
  138. * @access public
  139. */
  140. public function getControls()
  141. {
  142. return $this->controls;
  143. }
  144. /**
  145. * Sets controls of the panel.
  146. *
  147. * @param array $controls
  148. * @return self
  149. * @access public
  150. */
  151. public function setControls(array $controls)
  152. {
  153. $this->controls = $controls;
  154. return $this;
  155. }
  156. /**
  157. * Returns number of the panel controls.
  158. *
  159. * @return integer
  160. * @access public
  161. */
  162. public function count()
  163. {
  164. return count($this->controls);
  165. }
  166. /**
  167. * Returns the control iterator object.
  168. *
  169. * @return Aleph\Web\POM\Iterator
  170. * @access public
  171. */
  172. public function getIterator()
  173. {
  174. return new Iterator($this->controls);
  175. }
  176. /**
  177. * Parses the given template of the panel.
  178. * If $template is not defined, the current panel template will be parsed.
  179. *
  180. * @param string $template - the template string or full path to the template file.
  181. * @param array $vars - the template variables for the template preprocessing.
  182. * @return self
  183. * @access public
  184. */
  185. public function parse($template = null, array $vars = null)
  186. {
  187. $res = View::analyze($template ?: $this->tpl->getTemplate(), $vars);
  188. $this->tpl->setTemplate($res['html']);
  189. foreach ($this->controls as $ctrl) $this->detach($ctrl);
  190. foreach ($res['controls'] as $ctrl) $this->add($ctrl);
  191. return $this->refresh();
  192. }
  193. /**
  194. * Adds some control to the panel.
  195. *
  196. * @param Aleph\Web\POM\Control $ctrl - any control to be added to the panel.
  197. * @param string $mode - determines the placement of the adding control in the panel template.
  198. * @param string $id - the unique or logic identifier of some panel control or value of the attribute "id" of some element in the panel template.
  199. * @return self
  200. * @access public
  201. */
  202. public function add(Control $ctrl, $mode = null, $id = null)
  203. {
  204. return $ctrl->setParent($this, $mode, $id);
  205. }
  206. /**
  207. * Removes the given control from the panel.
  208. *
  209. * @param string $id - the unique or logic identifier of the control.
  210. * @return self
  211. * @access public
  212. */
  213. public function detach($id)
  214. {
  215. if ($this->inDetach) return $this;
  216. $this->inDetach = true;
  217. $ctrl = $this->get($id, false);
  218. if (!$ctrl) throw new Core\Exception($this, 'ERR_PANEL_1', $id, get_class($this), $this->getFullID());
  219. $ctrl->remove();
  220. unset($this->controls[$ctrl->attr('id')]);
  221. $this->tpl->setTemplate(str_replace(View::getControlPlaceholder($ctrl->attr('id')), '', $this->tpl->getTemplate()));
  222. $this->inDetach = false;
  223. return $this;
  224. }
  225. /**
  226. * Replaces some panel control with the given control.
  227. *
  228. * @param string $id - the unique or logic identifier of the panel control to be replaced.
  229. * @param Aleph\Web\POM\Control $new - the control to replace.
  230. * @return self
  231. * @access public
  232. */
  233. public function replace($id, Control $new)
  234. {
  235. $ctrl = $this->get($id, false);
  236. if (!$ctrl) throw new Core\Exception($this, 'ERR_PANEL_1', $id, get_class($this), $this->getFullID());
  237. $oph = View::getControlPlaceholder($ctrl->attr('id'));
  238. $nph = View::getControlPlaceholder($new->attr('id'));
  239. if (false !== $this->get($new->attr('id'), false))
  240. {
  241. $this->tpl->setTemplate(str_replace($nph, '', $this->tpl->getTemplate()));
  242. unset($this->controls[$new->attr('id')]);
  243. }
  244. $this->tpl->setTemplate(str_replace($oph, $nph, $this->tpl->getTemplate()));
  245. $ctrl->remove();
  246. return $this->add($new, 'replace', $ctrl->attr('id'));
  247. }
  248. /**
  249. * Creates full copy of the control.
  250. * If $id is not defined the logic identifier of the original control is used.
  251. *
  252. * @param string $id - the logic identifier of the control copy.
  253. * @return Aleph\Web\POM\Control
  254. * @access public
  255. */
  256. public function copy($id = null)
  257. {
  258. $class = get_class($this);
  259. $ctrl = new $class($id ?: $this->properties['id']);
  260. $vs = $this->getVS();
  261. $vs['parent'] = null;
  262. $vs['attributes']['id'] = $ctrl->attr('id');
  263. $vs['properties']['id'] = $ctrl->prop('id');
  264. $vs['controls'] = [];
  265. $ctrl->setVS($vs);
  266. foreach ($this as $child)
  267. {
  268. $copy = $child->copy();
  269. $ctrl->tpl->setTemplate(str_replace(View::getControlPlaceholder($child->attr('id')), View::getControlPlaceholder($copy->attr('id')), $ctrl->tpl->getTemplate()));
  270. $ctrl->add($copy);
  271. }
  272. return $ctrl;
  273. }
  274. /**
  275. * Checks or unchecks checkboxes of the panel.
  276. *
  277. * @param boolean $flag - determines whether a checkbox will be checked or not.
  278. * @param boolean $searchRecursively - determines whether the method should be recursively applied to all child panels of the given panel.
  279. * @return self
  280. * @access public
  281. */
  282. public function check($flag = true, $searchRecursively = true)
  283. {
  284. $this->view->check($this->attributes['id'], $flag, $searchRecursively);
  285. return $this;
  286. }
  287. /**
  288. * For every panel control restores value of the property "value" to default.
  289. *
  290. * @param boolean $searchRecursively - determines whether the method should be recursively applied to all child panels of the given panel.
  291. * @return self
  292. * @access public
  293. */
  294. public function clean($searchRecursively = true)
  295. {
  296. $this->view->clean($this->attributes['id'], $searchRecursively);
  297. return $this;
  298. }
  299. /**
  300. * Searches the required control in the panel and returns its instance.
  301. * The method returns FALSE if the required control is not found.
  302. *
  303. * @param string $id - unique or logic identifier of a control.
  304. * @param boolean $searchRecursively - determines whether to recursively search the control inside all child panels of the given panel.
  305. * @return boolean|Aleph\Web\POM\Control
  306. * @access public
  307. */
  308. public function get($id, $searchRecursively = true)
  309. {
  310. return $this->view->get($id, $searchRecursively, $this);
  311. }
  312. /**
  313. * Returns associative array of values of form (panel) controls.
  314. *
  315. * @param boolean $searchRecursively - determines whether values of controls of nested panels will also be gathered.
  316. * @return array
  317. * @access public
  318. */
  319. public function getFormValues($searchRecursively = true)
  320. {
  321. return $this->view->getFormValues($this, $searchRecursively);
  322. }
  323. /**
  324. * Assigns values to the panel controls.
  325. *
  326. * @param array $values - values to be assigned to.
  327. * @param boolean $searchRecursively - determines whether values will be also assigned to the controls of nested panels.
  328. * @return self
  329. * @access public
  330. */
  331. public function setFormValues(array $values, $searchRecursively = true)
  332. {
  333. $this->view->setFormValues($this, $values, $searchRecursively);
  334. return $this;
  335. }
  336. /**
  337. * Returns HTML of the panel.
  338. *
  339. * @return string
  340. * @access public
  341. */
  342. public function render()
  343. {
  344. if (!$this->properties['visible']) return $this->invisible();
  345. return '<' . $this->properties['tag'] . $this->renderAttributes() . '>' . $this->renderInnerHTML() . '</' . $this->properties['tag'] . '>';
  346. }
  347. /**
  348. * Returns the inner HTML of the panel.
  349. *
  350. * @return string
  351. * @access public
  352. */
  353. public function renderInnerHTML()
  354. {
  355. if ($this->tpl->isExpired())
  356. {
  357. foreach ($this as $uniqueID => $ctrl) $this->tpl->{$uniqueID} = $ctrl->render();
  358. }
  359. return $this->tpl->render();
  360. }
  361. /**
  362. * Returns XHTML of the control.
  363. *
  364. * @return string
  365. * @access public
  366. */
  367. public function renderXHTML()
  368. {
  369. $tpl = $this->tpl->getTemplate();
  370. $tag = Utils\PHP\Tools::getClassName($this);
  371. $html = '<' . $tag . $this->renderXHTMLAttributes() . '>';
  372. foreach ($this as $uniqueID => $ctrl) $tpl = str_replace(View::getControlPlaceholder($uniqueID), $ctrl->renderXHTML(), $tpl);
  373. return $html . $tpl . '</' . $tag . '>';
  374. }
  375. }