/** * Iterates through a list of nodes and stores to each node in the * ConfigValueHolder * * @param mixed An array or an object that can be iterated over * @param AgaviXmlValueHolder The storage for the info from the nodes * @param bool Whether this list is the singular form of the parent node * * @author David Zülke <*****@*****.**> * @author Dominik del Bondio <*****@*****.**> * @since 0.11.0 */ protected function parseNodes($nodes, AgaviConfigValueHolder $parentVh, $isSingular = false) { foreach ($nodes as $node) { if ($node->nodeType == XML_ELEMENT_NODE && (!$node->namespaceURI || $node->namespaceURI == AgaviXmlConfigParser::NAMESPACE_AGAVI_ENVELOPE_0_11)) { $vh = new AgaviConfigValueHolder(); $nodeName = $this->convertEncoding($node->localName); $vh->setName($nodeName); $parentVh->addChildren($nodeName, $vh); foreach ($node->attributes as $attribute) { if (!$attribute->namespaceURI || $attribute->namespaceURI == AgaviXmlConfigParser::NAMESPACE_AGAVI_ENVELOPE_0_11) { $vh->setAttribute($this->convertEncoding($attribute->localName), $this->convertEncoding($attribute->nodeValue)); } } // there are no child nodes so we set the node text contents as the value for the valueholder if ($node->getElementsByTagName('*')->length == 0) { $vh->setValue($this->convertEncoding($node->nodeValue)); } if ($node->hasChildNodes()) { $this->parseNodes($node->childNodes, $vh); } } } }
public function testIteratorIterface() { $vh = new AgaviConfigValueHolder(); $vhChild1 = new AgaviConfigValueHolder(); $vhChild2 = new AgaviConfigValueHolder(); $vhChild3 = new AgaviConfigValueHolder(); $vh->addChildren('child1', $vhChild1); $vh->addChildren('child2', $vhChild2); $vh->addChildren('child3', $vhChild3); $i = 1; foreach ($vh as $name => $child) { $this->assertSame('child' . $i, $name); $this->assertSame(${'vhChild' . $i}, $child); ++$i; } $vh2 = new AgaviConfigValueHolder(); $vh2->appendChildren($vhChild1); $vh2->appendChildren($vhChild2); $vh2->appendChildren($vhChild3); $i = 0; foreach ($vh2 as $id => $child) { $this->assertSame($i, $id); $this->assertSame(${'vhChild' . ($i + 1)}, $child); ++$i; } }
/** * Converts an AgaviConfigValueHolder into an array. * * @param AgaviConfigValueHolder The config value to convert. * * @return array The config values as an array. * * @author Dominik del Bondio <*****@*****.**> * @since 0.11.0 */ protected function convertToArray(AgaviConfigValueHolder $item, $topLevel = false) { $idAttribute = $this->getParameter('id_attribute', 'name'); $valueKey = $this->getParameter('value_key', 'value'); $forceArrayValues = $this->getParameter('force_array_values', false); $attributePrefix = $this->getParameter('attribute_prefix', ''); $literalize = $this->getParameter('literalize', true); $singularParentName = AgaviInflector::singularize($item->getName()); $data = array(); $attribs = $item->getAttributes(); $numAttribs = count($attribs); if ($idAttribute && $item->hasAttribute($idAttribute)) { $numAttribs--; } foreach ($item->getAttributes() as $name => $value) { if ($topLevel && in_array($name, array('context', 'environment')) || $name == $idAttribute) { continue; } if ($literalize) { $value = AgaviToolkit::literalize($value); } if (!isset($data[$name])) { $data[$attributePrefix . $name] = $value; } } if (!$item->hasChildren()) { $val = $item->getValue(); if ($literalize) { $val = AgaviToolkit::literalize($val); } if ($val === null) { $val = ''; } if (!$topLevel && ($numAttribs || $forceArrayValues)) { $data[$valueKey] = $val; } else { $data = $val; } } else { $names = array(); $children = $item->getChildren(); foreach ($children as $child) { $names[] = $child->getName(); } $dupes = array(); foreach (array_unique(array_diff_assoc($names, array_unique($names))) as $name) { $dupes[] = $name; } foreach ($children as $key => $child) { $hasId = $idAttribute && $child->hasAttribute($idAttribute); $isDupe = in_array($child->getName(), $dupes); $hasParent = $child->getName() == $singularParentName && $item->getName() != $singularParentName; if (($hasId || $isDupe) && !$hasParent) { // it's one of multiple tags in this level without the respective plural form as the parent node if (!isset($data[$idx = AgaviInflector::pluralize($child->getName())])) { $data[$idx] = array(); } $hasParent = true; $to =& $data[$idx]; } else { $to =& $data; } if ($hasId) { $key = $child->getAttribute($idAttribute); if ($literalize) { // no literalize, just constants! $key = AgaviToolkit::expandDirectives($key); } $to[$key] = $this->convertToArray($child); } elseif ($hasParent) { $to[] = $this->convertToArray($child); } else { $to[$child->getName()] = $this->convertToArray($child); } } } return $data; }
/** * Returns a properly ordered array of AgaviConfigValueHolder configuration * elements for given env and context. * * @param AgaviConfigValueHolder The root config element * @param string An environment name. * @param string A context name. * @param bool Whether the parser class should be * autoloaded or not. * * @return array An array of ConfigValueHolder configuration elements. * * @author David Zülke <*****@*****.**> * @since 0.11.0 */ public function orderConfigurations(AgaviConfigValueHolder $configurations, $environment = null, $context = null, $autoloadParser = true) { $configs = array(); if ($configurations->hasAttribute('parent')) { $parent = AgaviToolkit::literalize($configurations->getAttribute('parent')); $parentConfigs = $this->orderConfigurations(AgaviConfigCache::parseConfig($parent, $autoloadParser, $this->getValidationFile(), $this->parser)->configurations, $environment, $context, $autoloadParser); $configs = array_merge($configs, $parentConfigs); } foreach ($configurations as $cfg) { if (!$cfg->hasAttribute('environment') && !$cfg->hasAttribute('context')) { $configs[] = $cfg; } } foreach ($configurations as $cfg) { if ($environment !== null && $cfg->hasAttribute('environment') && self::testPattern($cfg->getAttribute('environment'), $environment) && !$cfg->hasAttribute('context')) { $configs[] = $cfg; } } foreach ($configurations as $cfg) { if (!$cfg->hasAttribute('environment') && $context !== null && $cfg->hasAttribute('context') && self::testPattern($cfg->getAttribute('context'), $context)) { $configs[] = $cfg; } } foreach ($configurations as $cfg) { if ($environment !== null && $cfg->hasAttribute('environment') && self::testPattern($cfg->getAttribute('environment'), $environment) && $context !== null && $cfg->hasAttribute('context') && self::testPattern($cfg->getAttribute('context'), $context)) { $configs[] = $cfg; } } return $configs; }
/** * Magic getter overload. * * @param string Name of the child . * * @return AgaviConfigValueHolder The child, if it exists. * * @author Dominik del Bondio <*****@*****.**> * @since 0.11.0 */ public function __get($name) { if (isset($this->_childs[$name])) { return $this->_childs[$name]; } else { $tagName = $name; $tagNameStart = ''; if (($lastUScore = strrpos($tagName, '_')) !== false) { $lastUScore++; $tagNameStart = substr($tagName, 0, $lastUScore); $tagName = substr($tagName, $lastUScore); } // check if the requested node was specified using the plural version // and create a "virtual" node which reflects the non existent plural node $singularName = $tagNameStart . AgaviInflector::singularize($tagName); if ($this->hasChildren($singularName)) { $vh = new AgaviConfigValueHolder(); $vh->setName($name); foreach ($this->_childs as $child) { if ($child->getName() == $singularName) { $vh->addChildren($singularName, $child); } } return $vh; } else { //throw new AgaviException('Node with the name ' . $name . ' does not exist ('.$this->getName().', '.implode(', ', array_keys($this->_childs)).')'); return null; } } }