Source for file WRepeatableComponentCollection.class.php

Documentation is available at WRepeatableComponentCollection.class.php

  1. <?php
  2. /**
  3. * @since Aug 1, 2005
  4. * @package polyphony.wizard.components
  5. *
  6. * @copyright Copyright &copy; 2005, Middlebury College
  7. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  8. *
  9. * @version $Id: WRepeatableComponentCollection.class.php,v 1.17 2007/09/19 14:04:51 adamfranco Exp $
  10. */
  11.  
  12. /**
  13. * This component allows for the creation of repeatable components or groups of components.
  14. *
  15. * @since Aug 1, 2005
  16. * @package polyphony.wizard.components
  17. *
  18. * @copyright Copyright &copy; 2005, Middlebury College
  19. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  20. *
  21. * @version $Id: WRepeatableComponentCollection.class.php,v 1.17 2007/09/19 14:04:51 adamfranco Exp $
  22. */
  23.  
  24. class WRepeatableComponentCollection
  25. extends WizardComponentWithChildren
  26. {
  27.  
  28. var $_collections = array();
  29. var $_min = 0;
  30. var $_max = -1;
  31. var $_num = 1;
  32. var $_text = '';
  33. var $_prefixFunction = 0;
  34. var $_addButton;
  35. function WRepeatableComponentCollection() {
  36. $this->_addLabel = dgettext("polyphony", "Add");
  37. $this->_removeLabel = dgettext("polyphony", "Remove");
  38. $this->_addButton = WEventButton::withLabel($this->_addLabel);
  39. $this->_addButton->setParent($this);
  40. }
  41. /**
  42. * Sets if this component will be enabled or disabled.
  43. * @param boolean $enabled
  44. * @param boolean $sticky If true, future calls to setEnabled without sticky
  45. * will have no effect.
  46. * @access public
  47. * @return void
  48. */
  49. function setEnabled ($enabled, $sticky = false) {
  50. parent::setEnabled($enabled, $sticky);
  51. $this->_addButton->setEnabled($enabled, $sticky);
  52. foreach ($this->_collections as $key => $copy) {
  53. $this->_collections[$key]["_remove"]->setEnabled($enabled, $sticky);
  54. }
  55. }
  56. /**
  57. * Set the label to use on the addButton
  58. *
  59. * @param string $label
  60. * @return void
  61. * @access public
  62. * @since 6/5/06
  63. */
  64. function setAddLabel ($label) {
  65. $this->_addLabel = $label;
  66. $this->_addButton->setLabel($label);
  67. }
  68. /**
  69. * Set the label to use on the remove button
  70. *
  71. * @param string $label
  72. * @return void
  73. * @access public
  74. * @since 6/5/06
  75. */
  76. function setRemoveLabel ($label) {
  77. $this->_removeLabel = $label;
  78. foreach ($this->_collections as $key => $copy) {
  79. $this->_collections[$key]["_remove"]->setLabel($label);
  80. }
  81. }
  82. /**
  83. * Sets the Component to prefix each "collection" or value with the return
  84. * value of this function. The function will be passed: the index of the value (starting from zero)
  85. * and a hash of the values.
  86. * @param string $functionName
  87. * @access public
  88. * @return void
  89. */
  90. function usePrefixFunction($functionName) {
  91. $this->_prefixFunction = $functionName;
  92. }
  93.  
  94. /**
  95. * Sets the minimum number of elements that we allow in the collection.
  96. * @param integer $min
  97. * @access public
  98. * @return void
  99. */
  100. function setMiminum ($min) {
  101. $this->_min = $min;
  102. }
  103. /**
  104. * Sets the maximum number of elements that we allow in this collection. A value of "-1" is no limit.
  105. * @param integer $max
  106. * @access public
  107. * @return void
  108. */
  109. function setMaximum ($max) {
  110. $this->_max = $max;
  111. }
  112. /**
  113. * Sets the number of elements to display as a starting value.
  114. * @param integer $start
  115. * @access public
  116. * @return void
  117. */
  118. function setStartingNumber ($start) {
  119. $this->_num = $start;
  120. }
  121. /**
  122. * Sets the textual layout of each element in the collection. They will be surrounded by html DIV tags.
  123. * @param string $text
  124. * @access public
  125. * @return void
  126. */
  127. function setElementLayout ($text) {
  128. $this->_text = $text;
  129. }
  130. /**
  131. * Sets this step's content text.
  132. * This text will be parsed with {@link Wizard::parseText()}
  133. * @param string $content;
  134. * @access public
  135. * @return void
  136. */
  137. function setContent ($content) {
  138. $this->setElementLayout ($content);
  139. }
  140. /**
  141. * Adds a collection of {@link WizardComponent}s indexed by field name to the list of collections.
  142. * This is useful when pre-populating the list with old/previous values.
  143. * @param ref array $collection Indexed by field name.
  144. * @param boolean $removable Can this collection be removed by the user?
  145. * @access public
  146. * @return ref array An array of the components created with the values passed.
  147. */
  148. function addValueCollection ($collection, $removable = true) {
  149. // @todo - make sure that the correct fields/classes are represented
  150. $newCollection =$this->_addElement($removable);
  151. foreach (array_keys($newCollection) as $key) {
  152. if (isset($collection[$key]))
  153. $newCollection[$key]->setValue($collection[$key]);
  154. }
  155. return $newCollection;
  156. }
  157. /**
  158. * A wrapper for addValueCollection which adds a ValueCollection for every element
  159. * in the array passet, to allow for adding values to nested
  160. * RepeatableComponentCollections.
  161. *
  162. * @param ref array $collectionArray
  163. * @return void
  164. * @access public
  165. * @since 10/27/05
  166. */
  167. function setValue ( $collectionArray ) {
  168. foreach(array_keys($collectionArray) as $key) {
  169. $this->addValueCollection($collectionArray[$key]);
  170. }
  171. }
  172. /**
  173. * Adds a new element to the end of the list.
  174. * @param boolean $removable Can this collection be removed by the user?
  175. * @access private
  176. * @return void
  177. */
  178. function _addElement ($removable = true) {
  179. if ($this->_max != -1 && $this->_num == $this->_max - 1) return;
  180. // printDebugBacktrace();
  181. // clone our base set (the getChildren() array)
  182. $newArray = array();
  183. $base =$this->getChildren();
  184. foreach (array_keys($base) as $key) {
  185. $newArray[$key] =$base[$key]->copy();
  186. $newArray[$key]->setParent($this);
  187. }
  188. $newArray["_remove"] = WEventButton::withLabel($this->_removeLabel);
  189. $newArray["_remove"]->setParent($this);
  190. $newArray["_remove"]->addOnClick("ignoreValidation(this.form);");
  191. if (!$this->_enabled && $this->_enabledSticky)
  192. $newArray["_remove"]->setEnabled(false, true);
  193. else
  194. $newArray["_remove"]->setEnabled($removable, !$removable);
  195.  
  196. $this->_collections[] =$newArray;
  197. $this->_num++;
  198.  
  199. return $newArray;
  200. }
  201.  
  202. /**
  203. * Removes the elements from our list.
  204. * @param array $ar An array of element keys.
  205. * @access private
  206. * @return void
  207. */
  208. function _removeElements ($ar) {
  209. if (($this->_num-count($ar)) < $this->_min) return;
  210. foreach ($ar as $key) {
  211. unset($this->_collections[$key]);
  212. $this->_num--;
  213. }
  214. $this->_collections = array_values($this->_collections); // re-index the array
  215. }
  216. /**
  217. * Returns true if this component (and all child components if applicable) have valid values.
  218. * By default, this will just return TRUE. Validate should be called usually before a save event
  219. * is handled, to make sure everything went smoothly.
  220. * @access public
  221. * @return boolean
  222. */
  223. function validate () {
  224. $ok = true;
  225. foreach (array_keys($this->_collections) as $key) {
  226. foreach(array_keys($this->_collections[$key]) as $name) {
  227. if (!$this->_collections[$key][$name]->validate()) $ok = false;
  228. }
  229. }
  230. return $ok;
  231. }
  232. /**
  233. * Tells the wizard component to update itself - this may include getting
  234. * form post data or validation - whatever this particular component wants to
  235. * do every pageload.
  236. * @param string $fieldName The field name to use when outputting form data or
  237. * similar parameters/information.
  238. * @access public
  239. * @return boolean - TRUE if everything is OK
  240. */
  241. function update ($fieldName) {
  242. $ok = true;
  243. // $this->_removeElements(array(2));
  244. // first update all our components in the collections
  245. $toRemove = array();
  246. foreach(array_keys($this->_collections) as $key) {
  247. foreach(array_keys($this->_collections[$key]) as $name) {
  248. // print "$name in $key is a ".gettype($this->_collections[$key][$name])."<br/>";
  249. // if (!is_object($this->_collections[$key][$name])) continue;
  250. if (!$this->_collections[$key][$name]->update($fieldName."_".$key."_".$name)) $ok = false;
  251. }
  252. if ($this->_collections[$key]["_remove"]->getAllValues()) $toRemove[] = $key;
  253. }
  254. $this->_removeElements($toRemove);
  255. // then, check if any "buttons" or anything were pressed to add/remove elements
  256. $this->_addButton->update($fieldName."_add");
  257. if ($this->_addButton->getAllValues()) {
  258. // print "adding element.<br/>";
  259. $this->_addElement();
  260. }
  261. return $ok;
  262. }
  263. /**
  264. * Returns the values of wizard-components. Should return an array if children are involved,
  265. * otherwise a whatever type of object is expected.
  266. * @access public
  267. * @return mixed
  268. */
  269. function getAllValues () {
  270. // make an array indexed by collection of all the values.
  271. $array = array();
  272. foreach (array_keys($this->_collections) as $key) {
  273. $array[$key] = $this->_getAllValues($key);
  274. }
  275. return $array;
  276. }
  277. /**
  278. * Returns the values for the given item.
  279. * @param string $key
  280. * @access public
  281. * @return array
  282. */
  283. function _getAllValues($key) {
  284. $array = array();
  285. foreach(array_keys($this->_collections[$key]) as $name) {
  286. $array[$name] = $this->_collections[$key][$name]->getAllValues();
  287. }
  288. return $array;
  289. }
  290. /**
  291. * Makes sure we have $num collections available.
  292. * @param integer $num
  293. * @access public
  294. * @return void
  295. */
  296. function _ensureNumber ($num) {
  297. $curr = count($this->_collections);
  298. if ($curr < $num) {
  299. for($i = $curr; $i < $num; $i++) {
  300. $this->_addElement();
  301. }
  302. $this->_num = $num;
  303. }
  304. }
  305. /**
  306. * Returns a block of XHTML-valid code that contains markup for this specific
  307. * component.
  308. * @param string $fieldName The field name to use when outputting form data or
  309. * similar parameters/information.
  310. * @access public
  311. * @return string
  312. */
  313. function getMarkup ($fieldName) {
  314. // check if we have min/max values that are appropriate, etc.
  315. if ($this->_num < $this->_min) $this->_num = $this->_min;
  316. if ($this->_max != -1 && $this->_num > $this->_max) $this->_num = $this->_max;
  317. $this->_ensureNumber($this->_num);
  318. $includeAdd = !($this->_num == $this->_max);
  319. $includeRemove = (!($this->_num == $this->_min));
  320. $cnt = 0;
  321. $pfunc = $this->_prefixFunction;
  322.  
  323. $m = "<table width='100%' border='0' cellspacing='0' cellpadding='2'>\n";
  324. foreach (array_keys($this->_collections) as $key) {
  325. $this->_collections[$key]["_remove"]->setEnabled($includeRemove);
  326. $m .= "<tr>";
  327. $m .= "<td valign='top' style='border-bottom: 1px solid #555; width: 75px'>".$this->_collections[$key]["_remove"]->getMarkup($fieldName."_".$key."__remove")."</td>";
  328. if ($pfunc) {
  329. $m .= "<td valign='middle' style='border-bottom: 1px solid #555;'>" . ($pfunc($cnt, $this->_getAllValues($key))) . "</td>";
  330. }
  331. $m .= "<td style='border-bottom: 1px solid #555;'>";
  332. $m .= Wizard::parseText($this->_text, $this->_collections[$key], $fieldName."_".$key."_");
  333. $m .= "</td></tr>\n";
  334.  
  335. $cnt++;
  336. }
  337. $this->_addButton->setEnabled($includeAdd);
  338. $m .= "<tr><td colspan='2'>".$this->_addButton->getMarkup($fieldName."_add")."</td></tr>\n";
  339. $m .= "</table>\n";
  340. return $m;
  341. }
  342. }
  343. ?>

Documentation generated on Wed, 19 Sep 2007 10:28:15 -0400 by phpDocumentor 1.3.0RC3