/library/Zly/Form/Element/Tree.php

https://github.com/x3ak/zly · PHP · 336 lines · 161 code · 42 blank · 133 comment · 27 complexity · 1caac58dd8e4b53c785c188cee156f22 MD5 · raw file

  1. <?php
  2. /**
  3. * Zly
  4. *
  5. * @author Evgheni Poleacov <evgheni.poelacov@gmail.com>
  6. * @version $Id: Tree.php 998 2011-01-06 16:14:45Z deeper $
  7. */
  8. namespace Zly\Form\Element;
  9. class Tree extends \Zend\Form\Element\Multi
  10. {
  11. /**
  12. * Disable autoregister inArray validator
  13. * @var bool
  14. */
  15. protected $_registerInArrayValidator = false;
  16. /**
  17. * Use Tree view helper
  18. * @var string
  19. */
  20. public $helper = 'Tree';
  21. /**
  22. * Element config
  23. *
  24. * @var array
  25. */
  26. protected $_config = array();
  27. /**
  28. * Value pattern separator
  29. *
  30. * @var string
  31. */
  32. protected $_patternSeparator = ':';
  33. /**
  34. * Disabled conditions
  35. *
  36. * @var string
  37. */
  38. protected $_disableConditions = array();
  39. /**
  40. * Key which indicate that field is childrens array
  41. * @var string
  42. */
  43. protected $_childrensKey = '__children';
  44. /**
  45. * Option value key
  46. * @var string
  47. */
  48. protected $_valueKey = null;
  49. /**
  50. * Option title key
  51. * @var string
  52. */
  53. protected $_titleKey = null;
  54. /**
  55. * Tree root label
  56. * @var string
  57. */
  58. protected $_rootLabel;
  59. /**
  60. * Tree root value
  61. * @var string
  62. */
  63. protected $_rootValue;
  64. /**
  65. * Switch tree to multiple select mode
  66. * @param boolean $multiple
  67. * @return Zly_Form_Element_Tree
  68. */
  69. public function setMultiple($multiple = true)
  70. {
  71. $this->setAttrib('multiple', $multiple);
  72. return $this;
  73. }
  74. /**
  75. * Add disabled node condition based on Zend_Validation
  76. *
  77. * @param string $field
  78. * @param Zend_Validate_Interface $validator
  79. * @return Zly_Form_Element_Tree
  80. */
  81. public function addDisableCondition($field, \Zend\Validator\AbstractValidator $validator = null)
  82. {
  83. $this->_disableConditions[$field][] = $validator;
  84. return $this;
  85. }
  86. /**
  87. * Set root element properties
  88. *
  89. * @param string $label
  90. * @param mixed $value
  91. * @return Zly_Form_Element_Tree
  92. */
  93. public function setRoot($label, $value = null)
  94. {
  95. $this->_rootLabel = $label;
  96. $this->_rootValue = $value;
  97. return $this;
  98. }
  99. /**
  100. * Set key which would be represented like tree item title
  101. * @param string $key
  102. * @return Zly_Form_Element_Tree
  103. */
  104. public function setTitleKey($key)
  105. {
  106. $this->_titleKey = $key;
  107. return $this;
  108. }
  109. /**
  110. * Return opyion title key
  111. * @return string
  112. */
  113. public function getTitleKey()
  114. {
  115. return $this->_titleKey;
  116. }
  117. /**
  118. * Set key which would be represented like tree item value
  119. * @param string $key
  120. * @return Zly_Form_Element_Tree
  121. */
  122. public function setValueKey($key, $defaultValue = null)
  123. {
  124. $this->_valueKey = $key;
  125. return $this;
  126. }
  127. /**
  128. * Get key which would be represented like tree item value
  129. */
  130. public function getValueKey()
  131. {
  132. return $this->_valueKey;
  133. }
  134. /**
  135. * Set key which would be represented like tree item value
  136. * @param string $key
  137. * @return Zly_Form_Element_Tree
  138. */
  139. public function setChildrensKey($key)
  140. {
  141. $this->_childrensKey = $key;
  142. return $this;
  143. }
  144. /**
  145. * Get key which would be represented like tree item value
  146. * @param string $key
  147. * @return Zly_Form_Element_Tree
  148. */
  149. public function getChildrensKey()
  150. {
  151. return $this->_childrensKey;
  152. }
  153. /**
  154. * Set value pattern separator
  155. * @param string $separator
  156. * @return Zly_Form_Element_Tree
  157. */
  158. public function setValuePatternSeparator($separator)
  159. {
  160. $this->_patternSeparator = $separator;
  161. return $this;
  162. }
  163. /**
  164. * Return value pattern separator
  165. * @return string
  166. */
  167. public function getValuePatternSeparator()
  168. {
  169. return $this->_patternSeparator;
  170. }
  171. /**
  172. * Return rendred element
  173. *
  174. * @param Zend_View_Abstract $view
  175. * @return string
  176. */
  177. public function render(\Zend\View\Renderer $view = null)
  178. {
  179. $preparedOptions = $this->_prepareOptions($this->options);
  180. $this->options = $this->_addRoot($preparedOptions);
  181. return parent::render($view);
  182. }
  183. /**
  184. * Prepare attributes of options as
  185. * indicated by element configuration
  186. *
  187. * @param array $options
  188. */
  189. protected function _prepareOptions($options)
  190. {
  191. $prepared = array();
  192. foreach ($options as $key => $option) {
  193. $value = $this->_parsePattern($option, $this->getValueKey());
  194. $title = $this->_parsePattern($option, $this->getTitleKey());
  195. $this->_checkDisabled($option, $value);
  196. $prepared[$value] = $title;
  197. if(is_array($option) && !empty($option[$this->_childrensKey])
  198. && is_array($option[$this->_childrensKey])) {
  199. $prepared[$value.'_childrens'] = $this->_prepareOptions($option[$this->_childrensKey]);
  200. } elseif(is_object($option) && !empty($option->{$this->_childrensKey})
  201. && is_array($option->{$this->_childrensKey})) {
  202. $prepared[$value.'_childrens'] = $this->_prepareOptions($option->{$this->_childrensKey});
  203. }
  204. }
  205. return $prepared;
  206. }
  207. /**
  208. * Check and set disabled options to element attributes
  209. * @param array $option
  210. * @param mixed $value
  211. * @return boolean
  212. */
  213. protected function _checkDisabled($option, $value)
  214. {
  215. $disabled = false;
  216. if(!empty($this->_disableConditions)) {
  217. foreach($this->_disableConditions as $field=>$validators) {
  218. $disables = array();
  219. foreach($validators as $validator) {
  220. if ($validator instanceof \Zend\Validator\Validator && is_array($option) && isset($option[$field]))
  221. $disables[] = $validator->isValid($option[$field]);
  222. elseif ($validator instanceof \Zend\Validator\Validator && is_object($option) && isset($option->$field)) {
  223. $disables[] = $validator->isValid($option->$field);
  224. }
  225. elseif(is_array($option) && isset($option[$field]))
  226. $disables[] = true;
  227. elseif(is_object($option) && isset($option->$field)) {
  228. $disables[] = true;
  229. }
  230. }
  231. if(in_array(true, $disables))
  232. $disabled = true;
  233. else
  234. $disabled = false;
  235. }
  236. if($disabled) {
  237. $disableAttr = $this->getAttrib('disable');
  238. if(!empty($disableAttr)) {
  239. if(is_array($disableAttr)) {
  240. $disableAttr[] = $value;
  241. } elseif(is_string($disableAttr)) {
  242. $disableAttr = array($disableAttr, $value);
  243. }
  244. } else {
  245. $disableAttr = array($value);
  246. }
  247. $this->setAttrib('disable', $disableAttr);
  248. }
  249. }
  250. return $disabled;
  251. }
  252. /**
  253. * Patterns parser
  254. *
  255. * @param array $option
  256. * @param string $pattern
  257. * @return string
  258. */
  259. protected function _parsePattern($option, $pattern)
  260. {
  261. $parts = explode($this->_patternSeparator, $pattern);
  262. $values = array();
  263. foreach ($parts as $part) {
  264. if (is_array($option) && !empty($option[$part]))
  265. $values[] = $option[$part];
  266. elseif($option instanceof \stdClass && !empty($option->$part)) {
  267. $values[] = $option->$part;
  268. }
  269. }
  270. $value = implode($this->_patternSeparator, $values);
  271. return $value;
  272. }
  273. /**
  274. * Add root node to options if that required
  275. * @return array|boolean
  276. */
  277. protected function _addRoot($options)
  278. {
  279. if(!empty($this->_rootLabel) && $this->_rootValue !== null) {
  280. $root = array($this->_rootValue=>$this->_rootLabel);
  281. } elseif(!empty($this->_rootLabel) && $this->_rootValue === null) {
  282. $root = array($this->_rootLabel);
  283. } else {
  284. $root = false;
  285. }
  286. if($root) {
  287. $childrensKey = uniqid();
  288. $root[$childrensKey] = $options;
  289. return $root;
  290. } else {
  291. return $options;
  292. }
  293. }
  294. }