PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/blocks/form.php

https://github.com/Icybee/Icybee
PHP | 673 lines | 560 code | 27 blank | 86 comment | 1 complexity | 549b0e695d47d6413d6748221f5ecfcc MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /*
  3. * This file is part of the Icybee package.
  4. *
  5. * (c) Olivier Laviale <olivier.laviale@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Icybee;
  11. use ICanBoogie\Event;
  12. use ICanBoogie\Exception;
  13. use ICanBoogie\I18n;
  14. use ICanBoogie\Operation;
  15. use ICanBoogie\Route;
  16. use Brickrouge\A;
  17. use Brickrouge\Button;
  18. use Brickrouge\Element;
  19. use Brickrouge\Form;
  20. /**
  21. * Base class for form type blocks.
  22. *
  23. * @property array $actions The actions for the {@link Form} element.
  24. * @property array $attributes The attributes for the {@link Form} element.
  25. * @property Form $element The {@link Form} element.
  26. * @property array $values The values for the {@link Form} element.
  27. */
  28. abstract class FormBlock extends \ICanBoogie\Object
  29. {
  30. /**
  31. * Adds assets to the document.
  32. *
  33. * The method doesn't add any asset.
  34. *
  35. * @param \Brickrouge\Document $document
  36. */
  37. static protected function add_assets(\Brickrouge\Document $document)
  38. {
  39. }
  40. /**
  41. * Module requesting the block.
  42. *
  43. * @var Module
  44. */
  45. protected $module;
  46. /**
  47. * Attributes provided during construct.
  48. *
  49. * @var array
  50. */
  51. protected $initial_attributes;
  52. /**
  53. * Constructor.
  54. *
  55. * @param Module $module
  56. * @param array $attributes
  57. */
  58. public function __construct(Module $module, array $attributes=array())
  59. {
  60. $this->module = $module;
  61. $this->initial_attributes = $attributes;
  62. $this->access_control();
  63. }
  64. /**
  65. * Returns whether the user has permission to display this block.
  66. *
  67. * @return bool
  68. */
  69. abstract protected function get_permission();
  70. /**
  71. * Controls the access to the block.
  72. *
  73. * @throws \Exception if the used has no permission to access the block.
  74. */
  75. abstract protected function access_control();
  76. /**
  77. * Alters the various parameters of the block.
  78. *
  79. * For each parameter the method checks if a `alter_<param>` method exists. If the method
  80. * exists the following methods are invoked to alter the value of the parameter:
  81. *
  82. * 1. `fire_before_<param>`: Fires the `alter_<param>:before` event.
  83. * 2. `alter_<param>`: Alters the values of the parameter.
  84. * 3. `fire_<param>`: Fires the `alter_<param>` event.
  85. *
  86. * @param array $params The parameters to alter.
  87. *
  88. * @return array
  89. */
  90. protected function alter(array $params)
  91. {
  92. foreach ($params as $param => &$value)
  93. {
  94. $method_name = 'alter_' . $param;
  95. if (!method_exists($this, $method_name))
  96. {
  97. continue;
  98. }
  99. call_user_func(array($this, 'fire_before_' . $method_name), $params);
  100. $value = $this->$method_name($value, $params);
  101. call_user_func(array($this, 'fire_' . $method_name), $params);
  102. }
  103. return $params;
  104. }
  105. /**
  106. * Renders the block into a {@link Form} element.
  107. *
  108. * The method invokes the {@link alter()} method to alter the attribute for the {@link Form}
  109. * element, and invokes the {@link alter_element()} method to alter the {@link Form} element
  110. * with the following properties:
  111. *
  112. * - `module`: The module creating the block.
  113. * - `attributes`: The attributes of the {@link Form} element.
  114. * - `actions`: The actions of the {@link Form} element.
  115. * - `children`: The children of the {@link Form} element.
  116. * - `values`: The values of the {@link Form} element.
  117. *
  118. * @return Form
  119. */
  120. public function render()
  121. {
  122. global $core;
  123. static::add_assets($core->document);
  124. $this->attributes;
  125. $attributes = &$this->attributes;
  126. $this->values;
  127. $values = &$this->values;
  128. $this->children;
  129. $children = &$this->children;
  130. $this->actions;
  131. $actions = &$this->actions;
  132. $params = $this->alter
  133. (
  134. array
  135. (
  136. 'module' => $this->module,
  137. 'attributes' => &$attributes,
  138. 'actions' => &$actions,
  139. 'children' => &$children,
  140. 'values' => &$values
  141. )
  142. );
  143. $attributes = array
  144. (
  145. Form::ACTIONS => &$actions,
  146. Form::CHILDREN => &$children,
  147. Form::VALUES => &$values
  148. )
  149. + $params['attributes'];
  150. $this->alter_element($this->element, $params);
  151. return $this;
  152. }
  153. /**
  154. * Renders the block into a HTML string.
  155. *
  156. * The method invokes the {@link render()} method.
  157. *
  158. * @return string
  159. */
  160. public function __toString()
  161. {
  162. try
  163. {
  164. // $html = (string) $this->render();
  165. $this->render();
  166. I18n::push_scope($this->module->flat_id . '.' . \ICanBoogie\underscore(basename(strtr(get_class($this), '\\', '/'))));
  167. $html = (string) $this->element;
  168. I18n::pop_scope();
  169. return $html;
  170. }
  171. catch (\Exception $e)
  172. {
  173. return \Brickrouge\render_exception($e);
  174. }
  175. }
  176. /*
  177. * ATTRIBUTES
  178. */
  179. /**
  180. * Returns the attributes for the {@link Form} element.
  181. *
  182. * The following attributes are defined:
  183. *
  184. * - The destination of the operation: The module id.
  185. * - The form renderer: An instance of {@link Brickrouge\Renderer\Simple} with the
  186. * {@link Icybee\Element\Group} group class.
  187. * - Groups: The `primary` group.
  188. * - id: `editor.
  189. * - action: An empty string.
  190. * - class: `form-primary edit`.
  191. * - name: The identifier of the module.
  192. *
  193. * @return array
  194. */
  195. protected function lazy_get_attributes()
  196. {
  197. $module = $this->module;
  198. return \ICanBoogie\array_merge_recursive
  199. (
  200. $this->initial_attributes, array
  201. (
  202. Form::HIDDENS => array
  203. (
  204. Operation::DESTINATION => $module->id
  205. ),
  206. Form::RENDERER => new \Brickrouge\Renderer\Simple
  207. (
  208. array
  209. (
  210. \Brickrouge\Renderer\Simple::GROUP_CLASS => 'Icybee\Element\Group'
  211. )
  212. ),
  213. Element::GROUPS => array
  214. (
  215. 'primary' => array
  216. (
  217. )
  218. ),
  219. 'id' => 'editor',
  220. 'action' => '',
  221. 'class' => 'form-primary edit',
  222. 'name' => (string) $module
  223. )
  224. );
  225. }
  226. /**
  227. * Alters the attributes of the {@link Form} element.
  228. *
  229. * The method returns the attributes as is.
  230. *
  231. * @param array $attributes The attributes to alter.
  232. * @param array $params The alter parameters.
  233. *
  234. * @return array
  235. */
  236. protected function alter_attributes(array $attributes, array $params)
  237. {
  238. return $attributes;
  239. }
  240. /**
  241. * Fires the `alter_attributes:before` event of class {@link FormBlock\BeforeAlterAttributesEvent}.
  242. *
  243. * @param array $payload The properties of the event.
  244. */
  245. protected function fire_before_alter_attributes(array $payload)
  246. {
  247. new FormBlock\BeforeAlterAttributesEvent($this, $payload);
  248. }
  249. /**
  250. * Fires the `alter_attributes` event of class {@link FormBlock\AlterAttributesEvent}.
  251. *
  252. * @param array $payload The properties of the event.
  253. */
  254. protected function fire_alter_attributes(array $payload)
  255. {
  256. new FormBlock\AlterAttributesEvent($this, $payload);
  257. }
  258. /*
  259. * VALUES
  260. */
  261. /**
  262. * Returns the values for the {@link Form} element.
  263. *
  264. * The method returns the values defined in the initial attributes or an empty array
  265. * if they were not defined.
  266. *
  267. * @return array
  268. */
  269. protected function lazy_get_values()
  270. {
  271. return isset($this->initial_attributes[Form::VALUES]) ? $this->initial_attributes[Form::VALUES] : array();
  272. }
  273. /**
  274. * Alerts the values for the {@link Form} element.
  275. *
  276. * The method returns the values as is.
  277. *
  278. * @param array $values The values to alter.
  279. * @param array $params The alter parameters.
  280. *
  281. * @return array
  282. */
  283. protected function alter_values(array $values, array $params)
  284. {
  285. return $values;
  286. }
  287. /**
  288. * Fires the `alter_values:before` event of class {@link FormBlock\BeforeAlterValuesEvent}.
  289. *
  290. * @param array $payload The properties of the event.
  291. */
  292. protected function fire_before_alter_values(array $payload)
  293. {
  294. new FormBlock\BeforeAlterValuesEvent($this, $payload);
  295. }
  296. /**
  297. * Fires the `alter_values` event of class {@link FormBlock\AlterValuesEvent}.
  298. *
  299. * @param array $payload The properties of the event.
  300. */
  301. protected function fire_alter_values(array $payload)
  302. {
  303. new FormBlock\AlterValuesEvent($this, $payload);
  304. }
  305. /*
  306. * CHILDREN
  307. */
  308. /**
  309. * Returns the children of the {@link Form} element.
  310. *
  311. * The method returns the children defined in the initial attributes or an empty array
  312. * if they were not defined.
  313. *
  314. * @return array
  315. */
  316. protected function lazy_get_children()
  317. {
  318. return isset($this->initial_attributes[Element::CHILDREN]) ? $this->initial_attributes[Element::CHILDREN] : array();
  319. }
  320. /**
  321. * Alters the children for the {@link Form} element.
  322. *
  323. * The method returns the children as is.
  324. *
  325. * @param array $children The children to alter.
  326. * @param array $params The alter parameters.
  327. *
  328. * @return array
  329. */
  330. protected function alter_children(array $children, array $params)
  331. {
  332. return $children;
  333. }
  334. /**
  335. * Fires the `alter_children:before` event of class {@link FormBlock\BeforeAlterChildrenEvent}.
  336. *
  337. * @param array $payload The properties of the event.
  338. */
  339. protected function fire_before_alter_children(array $payload)
  340. {
  341. new FormBlock\BeforeAlterChildrenEvent($this, $payload);
  342. }
  343. /**
  344. * Fires the `alter_children` event of class {@link FormBlock\AlterChildrenEvent}.
  345. *
  346. * @param array $payload The properties of the event.
  347. */
  348. protected function fire_alter_children(array $payload)
  349. {
  350. new FormBlock\AlterChildrenEvent($this, $payload);
  351. }
  352. /*
  353. * ACTIONS
  354. */
  355. /**
  356. * Returns the actions for the {@link Form} element.
  357. *
  358. * The method returns an array with a `Send` button. The button can be overrode using the
  359. * `primary` key.
  360. *
  361. * @return array
  362. */
  363. protected function lazy_get_actions()
  364. {
  365. return array
  366. (
  367. 'primary' => new Button
  368. (
  369. 'Send', array
  370. (
  371. 'class' => 'btn-primary',
  372. 'type' => 'submit',
  373. 'name' => false
  374. )
  375. )
  376. );
  377. }
  378. /**
  379. * Alters the actions for the {@link Form} element.
  380. *
  381. * The method returns the actions as is.
  382. *
  383. * @param array $actions The actions to alter.
  384. * @param array $params The alter parameters.
  385. *
  386. * @return array
  387. */
  388. protected function alter_actions(array $actions, array $params)
  389. {
  390. return $actions;
  391. }
  392. /**
  393. * Fires the `alter_actions:before` event of class {@link FormBlock\BeforeAlterActionsEvent}.
  394. *
  395. * @param array $payload The properties of the event.
  396. */
  397. protected function fire_before_alter_actions(array $payload)
  398. {
  399. new FormBlock\BeforeAlterActionsEvent($this, $payload);
  400. }
  401. /**
  402. * Fires the `alter_actions` event of class {@link FormBlock\AlterActionsEvent}.
  403. *
  404. * @param array $payload The properties of the event.
  405. */
  406. protected function fire_alter_actions(array $payload)
  407. {
  408. new FormBlock\AlterActionsEvent($this, $payload);
  409. }
  410. /*
  411. * ELEMENT
  412. */
  413. /**
  414. * Returns the {@link Form} element.
  415. *
  416. * @return \Brickrouge\Form
  417. */
  418. protected function lazy_get_element()
  419. {
  420. return new Form($this->attributes);
  421. }
  422. /**
  423. * Alters the {@link Form} element.
  424. *
  425. * The method return the element as is.
  426. *
  427. * @param Form $element The element to alter.
  428. * @param array $params The alter parameters.
  429. *
  430. * @return Form
  431. */
  432. protected function alter_element(Form $element, array $params)
  433. {
  434. return $element;
  435. }
  436. }
  437. namespace Icybee\FormBlock;
  438. /**
  439. * Base class for the alter events of the {@link FormBlock} class.
  440. */
  441. abstract class AlterEvent extends \ICanBoogie\Event
  442. {
  443. /**
  444. * The module creating the block.
  445. *
  446. * @var \ICanBoogie\Module
  447. */
  448. public $module;
  449. /**
  450. * Reference to the attributes for the {@link Form} element.
  451. *
  452. * @var array
  453. */
  454. public $attributes;
  455. /**
  456. * Reference to the actions for the {@link Form} element.
  457. *
  458. * @var array
  459. */
  460. public $actions;
  461. /**
  462. * Reference to the children for the {@link Form} element.
  463. *
  464. * @var array
  465. */
  466. public $children;
  467. /**
  468. * Reference to the values for the {@link Form} element.
  469. *
  470. * @var array
  471. */
  472. public $values;
  473. }
  474. /**
  475. * Event class for the `Icybee\FormBlock::alter_attributes:before` event.
  476. */
  477. class BeforeAlterAttributesEvent extends AlterEvent
  478. {
  479. /**
  480. * The event is constructed with the type `alter_attributes:before`.
  481. *
  482. * @param \Icybee\FormBlock $target
  483. * @param array $payload
  484. */
  485. public function __construct(\Icybee\FormBlock $target, array $payload)
  486. {
  487. parent::__construct($target, 'alter_attributes:before', $payload);
  488. }
  489. }
  490. /**
  491. * Event class for the `Icybee\FormBlock::alter_attributes` event.
  492. */
  493. class AlterAttributesEvent extends AlterEvent
  494. {
  495. /**
  496. * The event is constructed with the type `alter_attributes`.
  497. *
  498. * @param \Icybee\FormBlock $target
  499. * @param array $payload
  500. */
  501. public function __construct(\Icybee\FormBlock $target, array $payload)
  502. {
  503. parent::__construct($target, 'alter_attributes', $payload);
  504. }
  505. }
  506. /**
  507. * Event class for the `Icybee\FormBlock::alter_properties:before` event.
  508. */
  509. class BeforeAlterValuesEvent extends AlterEvent
  510. {
  511. /**
  512. * The event is constructed with the type `alter_properties:before`.
  513. *
  514. * @param \Icybee\FormBlock $target
  515. * @param array $payload
  516. */
  517. public function __construct(\Icybee\FormBlock $target, array $payload)
  518. {
  519. parent::__construct($target, 'alter_values:before', $payload);
  520. }
  521. }
  522. /**
  523. * Event class for the `Icybee\FormBlock::alter_values` event.
  524. */
  525. class AlterValuesEvent extends AlterEvent
  526. {
  527. /**
  528. * The event is constructed with the type `alter_properties`.
  529. *
  530. * @param \Icybee\FormBlock $target
  531. * @param array $payload
  532. */
  533. public function __construct(\Icybee\FormBlock $target, array $payload)
  534. {
  535. parent::__construct($target, 'alter_values', $payload);
  536. }
  537. }
  538. /**
  539. * Event class for the `Icybee\FormBlock::alter_children:before` event.
  540. */
  541. class BeforeAlterChildrenEvent extends AlterEvent
  542. {
  543. /**
  544. * The event is constructed with the type `alter_children:before`.
  545. *
  546. * @param \Icybee\FormBlock $target
  547. * @param array $payload
  548. */
  549. public function __construct(\Icybee\FormBlock $target, array $payload)
  550. {
  551. parent::__construct($target, 'alter_children:before', $payload);
  552. }
  553. }
  554. /**
  555. * Event class for the `Icybee\FormBlock::alter_children` event.
  556. */
  557. class AlterChildrenEvent extends AlterEvent
  558. {
  559. /**
  560. * The event is constructed with the type `alter_children`.
  561. *
  562. * @param \Icybee\FormBlock $target
  563. * @param array $payload
  564. */
  565. public function __construct(\Icybee\FormBlock $target, array $payload)
  566. {
  567. parent::__construct($target, 'alter_children', $payload);
  568. }
  569. }
  570. /**
  571. * Event class for the `Icybee\FormBlock::alter_actions:before` event.
  572. */
  573. class BeforeAlterActionsEvent extends AlterEvent
  574. {
  575. /**
  576. * The event is constructed with the type `alter_actions:before`.
  577. *
  578. * @param \Icybee\FormBlock $target
  579. * @param array $payload
  580. */
  581. public function __construct(\Icybee\FormBlock $target, array $payload)
  582. {
  583. parent::__construct($target, 'alter_actions:before', $payload);
  584. }
  585. }
  586. /**
  587. * Event class for the `Icybee\FormBlock::alter_actions` event.
  588. */
  589. class AlterActionsEvent extends AlterEvent
  590. {
  591. /**
  592. * The event is constructed with the type `alter_actions`.
  593. *
  594. * @param \Icybee\FormBlock $target
  595. * @param array $payload
  596. */
  597. public function __construct(\Icybee\FormBlock $target, array $payload)
  598. {
  599. parent::__construct($target, 'alter_actions', $payload);
  600. }
  601. }