group.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  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. $renderer =& new HTML_QuickForm_Renderer_Default();
  268. $renderer->setElementTemplate('{element}');
  269. $this->accept($renderer);
  270. return $renderer->toHtml();
  271. } //end func toHtml
  272. // }}}
  273. // {{{ getElementName()
  274. /**
  275. * Returns the element name inside the group such as found in the html form
  276. *
  277. * @param mixed $index Element name or element index in the group
  278. * @since 3.0
  279. * @access public
  280. * @return mixed string with element name, false if not found
  281. */
  282. function getElementName($index)
  283. {
  284. $this->_createElementsIfNotExist();
  285. $elementName = false;
  286. if (is_int($index) && isset($this->_elements[$index])) {
  287. $elementName = $this->_elements[$index]->getName();
  288. if (isset($elementName) && $elementName == '') {
  289. $elementName = $index;
  290. }
  291. if ($this->_appendName) {
  292. if (is_null($elementName)) {
  293. $elementName = $this->getName();
  294. } else {
  295. $elementName = $this->getName().'['.$elementName.']';
  296. }
  297. }
  298. } elseif (is_string($index)) {
  299. foreach (array_keys($this->_elements) as $key) {
  300. $elementName = $this->_elements[$key]->getName();
  301. if ($index == $elementName) {
  302. if ($this->_appendName) {
  303. $elementName = $this->getName().'['.$elementName.']';
  304. }
  305. break;
  306. } elseif ($this->_appendName && $this->getName().'['.$elementName.']' == $index) {
  307. break;
  308. }
  309. }
  310. }
  311. return $elementName;
  312. } //end func getElementName
  313. // }}}
  314. // {{{ getFrozenHtml()
  315. /**
  316. * Returns the value of field without HTML tags
  317. *
  318. * @since 1.3
  319. * @access public
  320. * @return string
  321. */
  322. function getFrozenHtml()
  323. {
  324. $flags = array();
  325. $this->_createElementsIfNotExist();
  326. foreach (array_keys($this->_elements) as $key) {
  327. if (false === ($flags[$key] = $this->_elements[$key]->isFrozen())) {
  328. $this->_elements[$key]->freeze();
  329. }
  330. }
  331. $html = $this->toHtml();
  332. foreach (array_keys($this->_elements) as $key) {
  333. if (!$flags[$key]) {
  334. $this->_elements[$key]->unfreeze();
  335. }
  336. }
  337. return $html;
  338. } //end func getFrozenHtml
  339. // }}}
  340. // {{{ onQuickFormEvent()
  341. /**
  342. * Called by HTML_QuickForm whenever form event is made on this element
  343. *
  344. * @param string $event Name of event
  345. * @param mixed $arg event arguments
  346. * @param object $caller calling object
  347. * @since 1.0
  348. * @access public
  349. * @return void
  350. */
  351. function onQuickFormEvent($event, $arg, &$caller)
  352. {
  353. switch ($event) {
  354. case 'updateValue':
  355. $this->_createElementsIfNotExist();
  356. foreach (array_keys($this->_elements) as $key) {
  357. if ($this->_appendName) {
  358. $elementName = $this->_elements[$key]->getName();
  359. if (is_null($elementName)) {
  360. $this->_elements[$key]->setName($this->getName());
  361. } elseif ('' === $elementName) {
  362. $this->_elements[$key]->setName($this->getName() . '[' . $key . ']');
  363. } else {
  364. $this->_elements[$key]->setName($this->getName() . '[' . $elementName . ']');
  365. }
  366. }
  367. $this->_elements[$key]->onQuickFormEvent('updateValue', $arg, $caller);
  368. if ($this->_appendName) {
  369. $this->_elements[$key]->setName($elementName);
  370. }
  371. }
  372. break;
  373. default:
  374. parent::onQuickFormEvent($event, $arg, $caller);
  375. }
  376. return true;
  377. } // end func onQuickFormEvent
  378. // }}}
  379. // {{{ accept()
  380. /**
  381. * Accepts a renderer
  382. *
  383. * @param object An HTML_QuickForm_Renderer object
  384. * @param bool Whether a group is required
  385. * @param string An error message associated with a group
  386. * @access public
  387. * @return void
  388. */
  389. function accept(&$renderer, $required = false, $error = null)
  390. {
  391. $this->_createElementsIfNotExist();
  392. $renderer->startGroup($this, $required, $error);
  393. $name = $this->getName();
  394. foreach (array_keys($this->_elements) as $key) {
  395. $element =& $this->_elements[$key];
  396. if ($this->_appendName) {
  397. $elementName = $element->getName();
  398. if (isset($elementName)) {
  399. $element->setName($name . '['. (api_strlen($elementName)? $elementName: $key) .']');
  400. } else {
  401. $element->setName($name);
  402. }
  403. }
  404. $required = !$element->isFrozen() && in_array($element->getName(), $this->_required);
  405. $element->accept($renderer, $required);
  406. // restore the element's name
  407. if ($this->_appendName) {
  408. $element->setName($elementName);
  409. }
  410. }
  411. $renderer->finishGroup($this);
  412. } // end func accept
  413. // }}}
  414. // {{{ exportValue()
  415. /**
  416. * As usual, to get the group's value we access its elements and call
  417. * their exportValue() methods
  418. */
  419. function exportValue(&$submitValues, $assoc = false)
  420. {
  421. $value = null;
  422. foreach (array_keys($this->_elements) as $key) {
  423. $elementName = $this->_elements[$key]->getName();
  424. if ($this->_appendName) {
  425. if (is_null($elementName)) {
  426. $this->_elements[$key]->setName($this->getName());
  427. } elseif ('' === $elementName) {
  428. $this->_elements[$key]->setName($this->getName() . '[' . $key . ']');
  429. } else {
  430. $this->_elements[$key]->setName($this->getName() . '[' . $elementName . ']');
  431. }
  432. }
  433. $v = $this->_elements[$key]->exportValue($submitValues, $assoc);
  434. if ($this->_appendName) {
  435. $this->_elements[$key]->setName($elementName);
  436. }
  437. if (null !== $v) {
  438. // Make $value an array, we will use it like one
  439. if (null === $value) {
  440. $value = array();
  441. }
  442. if ($assoc) {
  443. // just like HTML_QuickForm::exportValues()
  444. $value = HTML_QuickForm::arrayMerge($value, $v);
  445. } else {
  446. // just like getValue(), but should work OK every time here
  447. if (is_null($elementName)) {
  448. $value = $v;
  449. } elseif ('' === $elementName) {
  450. $value[] = $v;
  451. } else {
  452. $value[$elementName] = $v;
  453. }
  454. }
  455. }
  456. }
  457. // do not pass the value through _prepareValue, we took care of this already
  458. return $value;
  459. }
  460. // }}}
  461. // {{{ _createElements()
  462. /**
  463. * Creates the group's elements.
  464. *
  465. * This should be overriden by child classes that need to create their
  466. * elements. The method will be called automatically when needed, calling
  467. * it from the constructor is discouraged as the constructor is usually
  468. * called _twice_ on element creation, first time with _no_ parameters.
  469. *
  470. * @access private
  471. * @abstract
  472. */
  473. function _createElements()
  474. {
  475. // abstract
  476. }
  477. // }}}
  478. // {{{ _createElementsIfNotExist()
  479. /**
  480. * A wrapper around _createElements()
  481. *
  482. * This method calls _createElements() if the group's _elements array
  483. * is empty. It also performs some updates, e.g. freezes the created
  484. * elements if the group is already frozen.
  485. *
  486. * @access private
  487. */
  488. function _createElementsIfNotExist()
  489. {
  490. if (empty($this->_elements)) {
  491. $this->_createElements();
  492. if ($this->_flagFrozen) {
  493. $this->freeze();
  494. }
  495. }
  496. }
  497. // }}}
  498. // {{{ freeze()
  499. function freeze()
  500. {
  501. parent::freeze();
  502. foreach (array_keys($this->_elements) as $key) {
  503. $this->_elements[$key]->freeze();
  504. }
  505. }
  506. // }}}
  507. // {{{ unfreeze()
  508. function unfreeze()
  509. {
  510. parent::unfreeze();
  511. foreach (array_keys($this->_elements) as $key) {
  512. $this->_elements[$key]->unfreeze();
  513. }
  514. }
  515. // }}}
  516. // {{{ setPersistantFreeze()
  517. function setPersistantFreeze($persistant = false)
  518. {
  519. parent::setPersistantFreeze($persistant);
  520. foreach (array_keys($this->_elements) as $key) {
  521. $this->_elements[$key]->setPersistantFreeze($persistant);
  522. }
  523. }
  524. // }}}
  525. } //end class HTML_QuickForm_group
  526. ?>