group.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4.0 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available at through the world-wide-web at |
  11. // | http://www.php.net/license/2_02.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | license@php.net so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
  17. // | Bertrand Mansion <bmansion@mamasam.com> |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: group.php 20456 2009-05-10 17:27:44Z ivantcholakov $
  21. require_once("HTML/QuickForm/element.php");
  22. /**
  23. * HTML class for a form element group
  24. *
  25. * @author Adam Daniel <adaniel1@eesus.jnj.com>
  26. * @author Bertrand Mansion <bmansion@mamasam.com>
  27. * @version 1.0
  28. * @since PHP4.04pl1
  29. * @access public
  30. */
  31. class HTML_QuickForm_group extends HTML_QuickForm_element
  32. {
  33. // {{{ properties
  34. /**
  35. * Name of the element
  36. * @var string
  37. * @since 1.0
  38. * @access private
  39. */
  40. var $_name = '';
  41. /**
  42. * Array of grouped elements
  43. * @var array
  44. * @since 1.0
  45. * @access private
  46. */
  47. var $_elements = array();
  48. /**
  49. * String to separate elements
  50. * @var mixed
  51. * @since 2.5
  52. * @access private
  53. */
  54. var $_separator = null;
  55. /**
  56. * Required elements in this group
  57. * @var array
  58. * @since 2.5
  59. * @access private
  60. */
  61. var $_required = array();
  62. /**
  63. * Whether to change elements' names to $groupName[$elementName] or leave them as is
  64. * @var bool
  65. * @since 3.0
  66. * @access private
  67. */
  68. var $_appendName = true;
  69. // }}}
  70. // {{{ constructor
  71. /**
  72. * Class constructor
  73. *
  74. * @param string $elementName (optional)Group name
  75. * @param array $elementLabel (optional)Group label
  76. * @param array $elements (optional)Group elements
  77. * @param mixed $separator (optional)Use a string for one separator,
  78. * use an array to alternate the separators.
  79. * @param bool $appendName (optional)whether to change elements' names to
  80. * the form $groupName[$elementName] or leave
  81. * them as is.
  82. * @since 1.0
  83. * @access public
  84. * @return void
  85. */
  86. function HTML_QuickForm_group($elementName=null, $elementLabel=null, $elements=null, $separator=null, $appendName = true)
  87. {
  88. $this->HTML_QuickForm_element($elementName, $elementLabel);
  89. $this->_type = 'group';
  90. if (isset($elements) && is_array($elements)) {
  91. $this->setElements($elements);
  92. }
  93. if (isset($separator)) {
  94. $this->_separator = $separator;
  95. }
  96. if (isset($appendName)) {
  97. $this->_appendName = $appendName;
  98. }
  99. } //end constructor
  100. // }}}
  101. // {{{ setName()
  102. /**
  103. * Sets the group name
  104. *
  105. * @param string $name Group name
  106. * @since 1.0
  107. * @access public
  108. * @return void
  109. */
  110. function setName($name)
  111. {
  112. $this->_name = $name;
  113. } //end func setName
  114. // }}}
  115. // {{{ getName()
  116. /**
  117. * Returns the group name
  118. *
  119. * @since 1.0
  120. * @access public
  121. * @return string
  122. */
  123. function getName()
  124. {
  125. return $this->_name;
  126. } //end func getName
  127. // }}}
  128. // {{{ setValue()
  129. /**
  130. * Sets values for group's elements
  131. *
  132. * @param mixed Values for group's elements
  133. * @since 1.0
  134. * @access public
  135. * @return void
  136. */
  137. function setValue($value)
  138. {
  139. $this->_createElementsIfNotExist();
  140. foreach (array_keys($this->_elements) as $key) {
  141. if (!$this->_appendName) {
  142. $v = $this->_elements[$key]->_findValue($value);
  143. if (null !== $v) {
  144. $this->_elements[$key]->onQuickFormEvent('setGroupValue', $v, $this);
  145. }
  146. } else {
  147. $elementName = $this->_elements[$key]->getName();
  148. $index = api_strlen($elementName) ? $elementName : $key;
  149. if (is_array($value)) {
  150. if (isset($value[$index])) {
  151. $this->_elements[$key]->onQuickFormEvent('setGroupValue', $value[$index], $this);
  152. }
  153. } elseif (isset($value)) {
  154. $this->_elements[$key]->onQuickFormEvent('setGroupValue', $value, $this);
  155. }
  156. }
  157. }
  158. } //end func setValue
  159. // }}}
  160. // {{{ getValue()
  161. /**
  162. * Returns the value of the group
  163. *
  164. * @since 1.0
  165. * @access public
  166. * @return mixed
  167. */
  168. function getValue()
  169. {
  170. $value = null;
  171. foreach (array_keys($this->_elements) as $key) {
  172. $element =& $this->_elements[$key];
  173. switch ($element->getType()) {
  174. case 'radio':
  175. $v = $element->getChecked()? $element->getValue(): null;
  176. break;
  177. case 'checkbox':
  178. $v = $element->getChecked()? true: null;
  179. break;
  180. default:
  181. $v = $element->getValue();
  182. }
  183. if (null !== $v) {
  184. $elementName = $element->getName();
  185. if (is_null($elementName)) {
  186. $value = $v;
  187. } else {
  188. if (!is_array($value)) {
  189. $value = is_null($value)? array(): array($value);
  190. }
  191. if ('' === $elementName) {
  192. $value[] = $v;
  193. } else {
  194. $value[$elementName] = $v;
  195. }
  196. }
  197. }
  198. }
  199. return $value;
  200. } // end func getValue
  201. // }}}
  202. // {{{ setElements()
  203. /**
  204. * Sets the grouped elements
  205. *
  206. * @param array $elements Array of elements
  207. * @since 1.1
  208. * @access public
  209. * @return void
  210. */
  211. function setElements($elements)
  212. {
  213. $this->_elements = array_values($elements);
  214. if ($this->_flagFrozen) {
  215. $this->freeze();
  216. }
  217. } // end func setElements
  218. // }}}
  219. // {{{ getElements()
  220. /**
  221. * Gets the grouped elements
  222. *
  223. * @since 2.4
  224. * @access public
  225. * @return array
  226. */
  227. function &getElements()
  228. {
  229. $this->_createElementsIfNotExist();
  230. return $this->_elements;
  231. } // end func getElements
  232. // }}}
  233. // {{{ getGroupType()
  234. /**
  235. * Gets the group type based on its elements
  236. * Will return 'mixed' if elements contained in the group
  237. * are of different types.
  238. *
  239. * @access public
  240. * @return string group elements type
  241. */
  242. function getGroupType()
  243. {
  244. $this->_createElementsIfNotExist();
  245. $prevType = '';
  246. foreach (array_keys($this->_elements) as $key) {
  247. $type = $this->_elements[$key]->getType();
  248. if ($type != $prevType && $prevType != '') {
  249. return 'mixed';
  250. }
  251. $prevType = $type;
  252. }
  253. return $type;
  254. } // end func getGroupType
  255. // }}}
  256. // {{{ toHtml()
  257. /**
  258. * Returns Html for the group
  259. *
  260. * @since 1.0
  261. * @access public
  262. * @return string
  263. */
  264. function toHtml()
  265. {
  266. include_once('HTML/QuickForm/Renderer/Default.php');
  267. // Suppressing a deprecation warning on PHP 5.3
  268. //$renderer =& new HTML_QuickForm_Renderer_Default();
  269. $renderer = new HTML_QuickForm_Renderer_Default();
  270. //
  271. $renderer->setElementTemplate('{element}');
  272. $this->accept($renderer);
  273. return $renderer->toHtml();
  274. } //end func toHtml
  275. // }}}
  276. // {{{ getElementName()
  277. /**
  278. * Returns the element name inside the group such as found in the html form
  279. *
  280. * @param mixed $index Element name or element index in the group
  281. * @since 3.0
  282. * @access public
  283. * @return mixed string with element name, false if not found
  284. */
  285. function getElementName($index)
  286. {
  287. $this->_createElementsIfNotExist();
  288. $elementName = false;
  289. if (is_int($index) && isset($this->_elements[$index])) {
  290. $elementName = $this->_elements[$index]->getName();
  291. if (isset($elementName) && $elementName == '') {
  292. $elementName = $index;
  293. }
  294. if ($this->_appendName) {
  295. if (is_null($elementName)) {
  296. $elementName = $this->getName();
  297. } else {
  298. $elementName = $this->getName().'['.$elementName.']';
  299. }
  300. }
  301. } elseif (is_string($index)) {
  302. foreach (array_keys($this->_elements) as $key) {
  303. $elementName = $this->_elements[$key]->getName();
  304. if ($index == $elementName) {
  305. if ($this->_appendName) {
  306. $elementName = $this->getName().'['.$elementName.']';
  307. }
  308. break;
  309. } elseif ($this->_appendName && $this->getName().'['.$elementName.']' == $index) {
  310. break;
  311. }
  312. }
  313. }
  314. return $elementName;
  315. } //end func getElementName
  316. // }}}
  317. // {{{ getFrozenHtml()
  318. /**
  319. * Returns the value of field without HTML tags
  320. *
  321. * @since 1.3
  322. * @access public
  323. * @return string
  324. */
  325. function getFrozenHtml()
  326. {
  327. $flags = array();
  328. $this->_createElementsIfNotExist();
  329. foreach (array_keys($this->_elements) as $key) {
  330. if (false === ($flags[$key] = $this->_elements[$key]->isFrozen())) {
  331. $this->_elements[$key]->freeze();
  332. }
  333. }
  334. $html = $this->toHtml();
  335. foreach (array_keys($this->_elements) as $key) {
  336. if (!$flags[$key]) {
  337. $this->_elements[$key]->unfreeze();
  338. }
  339. }
  340. return $html;
  341. } //end func getFrozenHtml
  342. // }}}
  343. // {{{ onQuickFormEvent()
  344. /**
  345. * Called by HTML_QuickForm whenever form event is made on this element
  346. *
  347. * @param string $event Name of event
  348. * @param mixed $arg event arguments
  349. * @param object $caller calling object
  350. * @since 1.0
  351. * @access public
  352. * @return void
  353. */
  354. function onQuickFormEvent($event, $arg, &$caller)
  355. {
  356. switch ($event) {
  357. case 'updateValue':
  358. $this->_createElementsIfNotExist();
  359. foreach (array_keys($this->_elements) as $key) {
  360. if ($this->_appendName) {
  361. $elementName = $this->_elements[$key]->getName();
  362. if (is_null($elementName)) {
  363. $this->_elements[$key]->setName($this->getName());
  364. } elseif ('' === $elementName) {
  365. $this->_elements[$key]->setName($this->getName() . '[' . $key . ']');
  366. } else {
  367. $this->_elements[$key]->setName($this->getName() . '[' . $elementName . ']');
  368. }
  369. }
  370. $this->_elements[$key]->onQuickFormEvent('updateValue', $arg, $caller);
  371. if ($this->_appendName) {
  372. $this->_elements[$key]->setName($elementName);
  373. }
  374. }
  375. break;
  376. default:
  377. parent::onQuickFormEvent($event, $arg, $caller);
  378. }
  379. return true;
  380. } // end func onQuickFormEvent
  381. // }}}
  382. // {{{ accept()
  383. /**
  384. * Accepts a renderer
  385. *
  386. * @param object An HTML_QuickForm_Renderer object
  387. * @param bool Whether a group is required
  388. * @param string An error message associated with a group
  389. * @access public
  390. * @return void
  391. */
  392. function accept(&$renderer, $required = false, $error = null)
  393. {
  394. $this->_createElementsIfNotExist();
  395. $renderer->startGroup($this, $required, $error);
  396. $name = $this->getName();
  397. foreach (array_keys($this->_elements) as $key) {
  398. $element =& $this->_elements[$key];
  399. if ($this->_appendName) {
  400. $elementName = $element->getName();
  401. if (isset($elementName)) {
  402. $element->setName($name . '['. (api_strlen($elementName)? $elementName: $key) .']');
  403. } else {
  404. $element->setName($name);
  405. }
  406. }
  407. $required = !$element->isFrozen() && in_array($element->getName(), $this->_required);
  408. $element->accept($renderer, $required);
  409. // restore the element's name
  410. if ($this->_appendName) {
  411. $element->setName($elementName);
  412. }
  413. }
  414. $renderer->finishGroup($this);
  415. } // end func accept
  416. // }}}
  417. // {{{ exportValue()
  418. /**
  419. * As usual, to get the group's value we access its elements and call
  420. * their exportValue() methods
  421. */
  422. function exportValue(&$submitValues, $assoc = false)
  423. {
  424. $value = null;
  425. foreach (array_keys($this->_elements) as $key) {
  426. $elementName = $this->_elements[$key]->getName();
  427. if ($this->_appendName) {
  428. if (is_null($elementName)) {
  429. $this->_elements[$key]->setName($this->getName());
  430. } elseif ('' === $elementName) {
  431. $this->_elements[$key]->setName($this->getName() . '[' . $key . ']');
  432. } else {
  433. $this->_elements[$key]->setName($this->getName() . '[' . $elementName . ']');
  434. }
  435. }
  436. $v = $this->_elements[$key]->exportValue($submitValues, $assoc);
  437. if ($this->_appendName) {
  438. $this->_elements[$key]->setName($elementName);
  439. }
  440. if (null !== $v) {
  441. // Make $value an array, we will use it like one
  442. if (null === $value) {
  443. $value = array();
  444. }
  445. if ($assoc) {
  446. // just like HTML_QuickForm::exportValues()
  447. $value = HTML_QuickForm::arrayMerge($value, $v);
  448. } else {
  449. // just like getValue(), but should work OK every time here
  450. if (is_null($elementName)) {
  451. $value = $v;
  452. } elseif ('' === $elementName) {
  453. $value[] = $v;
  454. } else {
  455. $value[$elementName] = $v;
  456. }
  457. }
  458. }
  459. }
  460. // do not pass the value through _prepareValue, we took care of this already
  461. return $value;
  462. }
  463. // }}}
  464. // {{{ _createElements()
  465. /**
  466. * Creates the group's elements.
  467. *
  468. * This should be overriden by child classes that need to create their
  469. * elements. The method will be called automatically when needed, calling
  470. * it from the constructor is discouraged as the constructor is usually
  471. * called _twice_ on element creation, first time with _no_ parameters.
  472. *
  473. * @access private
  474. * @abstract
  475. */
  476. function _createElements()
  477. {
  478. // abstract
  479. }
  480. // }}}
  481. // {{{ _createElementsIfNotExist()
  482. /**
  483. * A wrapper around _createElements()
  484. *
  485. * This method calls _createElements() if the group's _elements array
  486. * is empty. It also performs some updates, e.g. freezes the created
  487. * elements if the group is already frozen.
  488. *
  489. * @access private
  490. */
  491. function _createElementsIfNotExist()
  492. {
  493. if (empty($this->_elements)) {
  494. $this->_createElements();
  495. if ($this->_flagFrozen) {
  496. $this->freeze();
  497. }
  498. }
  499. }
  500. // }}}
  501. // {{{ freeze()
  502. function freeze()
  503. {
  504. parent::freeze();
  505. foreach (array_keys($this->_elements) as $key) {
  506. $this->_elements[$key]->freeze();
  507. }
  508. }
  509. // }}}
  510. // {{{ unfreeze()
  511. function unfreeze()
  512. {
  513. parent::unfreeze();
  514. foreach (array_keys($this->_elements) as $key) {
  515. $this->_elements[$key]->unfreeze();
  516. }
  517. }
  518. // }}}
  519. // {{{ setPersistantFreeze()
  520. function setPersistantFreeze($persistant = false)
  521. {
  522. parent::setPersistantFreeze($persistant);
  523. foreach (array_keys($this->_elements) as $key) {
  524. $this->_elements[$key]->setPersistantFreeze($persistant);
  525. }
  526. }
  527. // }}}
  528. } //end class HTML_QuickForm_group
  529. ?>