/**
  * (non-PHPdoc)
  * @see lib/form/data/collection/phDataCollection::find()
  */
 public function find($name)
 {
     $info = new phNameInfo($name);
     if ($info->isArray()) {
         // if the $name specifies any auto keys then they will not be able to be found
         $keys = $info->getArrayInfo()->getKeys();
         foreach ($keys as $k) {
             if ($k->isAutoKey()) {
                 throw new phFormException("{$name} is ambiguous as it specifies an auto key ([])");
             }
         }
     }
     if (!array_key_exists($info->getName(), $this->_dataItems)) {
         return null;
     }
     $dataItem = $this->_dataItems[$info->getName()];
     if ($info->isArray() && !$dataItem instanceof phArrayFormDataItem) {
         /*
          * name is an array but the data type registered there is not
          * an array type
          */
         return null;
     }
     if ($info->isArray()) {
         $dataItem = $this->recurseArray($dataItem, $info->getArrayInfo()->getKeys());
     }
     return $dataItem;
 }
 /**
  * (non-PHPdoc)
  * @see lib/form/data/collection/phSimpleDataCollection::validate()
  */
 public function validate(phFormViewElement $element, phNameInfo $name, phCompositeDataCollection $collection)
 {
     /*
      * go through the name and, if it's an array, build it back up, BUT - skip
      * the last key if it's an auto key.  We do this because checkboxes with auto 
      * key's cannot be mixed with any other data type.
      */
     $nameString = $name->getName();
     $hasAutoKey = false;
     if ($name->isArray()) {
         $keys = $name->getArrayInfo()->getKeys();
         foreach ($keys as $k) {
             if ($k->isAutoKey()) {
                 $hasAutoKey = true;
                 break;
             }
             $nameString .= "[{$k->getKey()}]";
         }
     }
     $item = $collection->find($nameString);
     if ($hasAutoKey && $item !== null) {
         if (!$element instanceof phCheckboxElement && $item instanceof phSimpleArrayDataItem) {
             // not ok - checkbox registered here previously and someone is trying to add another datatype to the same array
             throw new phFormException("Trying to mix checkboxes with auto keys with another type of element at {$name}");
         }
         if ($element instanceof phCheckboxElement && !$item instanceof phSimpleArrayDataItem) {
             // not ok - checkbox with auto key trying to be registered to a normal array type
             throw new phFormException("Trying to mix checkboxes with auto keys with another type of element at {$name}");
         }
     }
     if (!$element instanceof phCheckboxElement) {
         return;
         // not interested at this point if it's not a checkbox
     }
     /*
      * check unique values
      */
     if (array_key_exists($name->getFullName(), $this->_checkboxValues) && in_array($element->getRawValue(), $this->_checkboxValues[$name->getFullName()])) {
         // value is not unique
         throw new phFormException("Duplicate value for checkbox with name {$name->getFullName()}");
     }
     if (!$name->isArray() && $item !== null) {
         throw new phFormException("Cannot register checkbox with name {$name->getFullName()}, an item of data with the same name already exists.  If you are trying to use multiple checkboxes with the same name then please note that these must have array names e.g. \"ids[]\"");
     }
 }
 /**
  * (non-PHPdoc)
  * @see lib/form/data/collection/phSimpleDataCollection::validate()
  */
 public function validate(phFormViewElement $element, phNameInfo $name, phCompositeDataCollection $collection)
 {
     if ($name->isArray()) {
         $arrayInfo = $name->getArrayInfo();
         $keys = $arrayInfo->getKeys();
         $lastKey = array_pop($keys);
         if ($lastKey->isAutoKey()) {
             throw new phFormException("The name {$name->getFullName()} is invalid, you cannot use an auto key with a radio button");
         }
     }
     if (!$element instanceof phRadioButtonElement) {
         return;
         // not interested from here on
     }
     if (array_key_exists($name->getFullName(), $this->_radioValues)) {
         if (in_array($element->getRawValue(), $this->_radioValues[$name->getFullName()])) {
             throw new phFormException("Non unique value for radio button with name \"{$name->getFullName()}\"");
         }
     }
 }
 /**
  * (non-PHPdoc)
  * @see lib/form/data/collection/phSimpleDataCollection::validate()
  */
 public function validate(phFormViewElement $element, phNameInfo $name, phCompositeDataCollection $collection)
 {
     /*
      * go through the name and, if it's an array, build it back up, BUT - skip
      * the last key if it's an auto key.  We do this because checkboxes with auto 
      * key's cannot be mixed with any other data type.
      */
     $nameString = $name->getName();
     $hasAutoKey = false;
     if ($name->isArray()) {
         $keys = $name->getArrayInfo()->getKeys();
         foreach ($keys as $k) {
             if ($k->isAutoKey()) {
                 $hasAutoKey = true;
                 break;
             }
             $nameString .= "[{$k->getKey()}]";
         }
     }
     if ($element instanceof phSelectListElement && $element->isMultiple()) {
         if (!$hasAutoKey) {
             throw new phFormException("Invalid name \"{$name->getFullName()}\" - Multi select list elements must use a name with an auto key");
         } else {
             $data = $collection->find($nameString);
             if ($data !== null) {
                 throw new phFormException("Cannot register multi-select list at {$name->getFullName()} another data item exists there");
             }
         }
     }
     if (array_key_exists($name->getFullName(), $this->_multipleElements)) {
         throw new phFormException("There is a multi-select list registered at \"{$name->getFullName()}\", you cannot register any other types of data here");
     }
     if ($element instanceof phSelectListElement) {
         /*
          * also do uniqueness checks if we are registering a select element
          */
         parent::validate($element, $name, $collection);
     }
 }
 protected function registerArray(phFormViewElement $element, phNameInfo $name, phCompositeDataCollection $collection)
 {
     /*
      * if the array has already been registered in another collection
      * then we need to add to the same data instance hence why we use 
      * find on the composite
      */
     $currentDataItem = $collection->find($name->getName());
     if ($currentDataItem === null) {
         $currentDataItem = $this->createArrayDataItem($name->getArrayInfo()->getKeyInfo(0), $element, $name->getName());
         $this->_dataItems[$name->getName()] = $currentDataItem;
     }
     $finalItem = $this->getOrCreateArrayDataType($name, $name->getArrayInfo()->getKeys(), 0, $element, $currentDataItem);
     $element->bindDataItem($finalItem);
 }