/** * Traverse the config object * * @param array $tree * @param int $depth * @param string $parentHref * @throws Exception * @return \Pop\Dom\Child */ protected function traverse(array $tree, $depth = 1, $parentHref = null) { // Create overriding top level parent, if set if ($depth == 1 && isset($this->config['top'])) { $parent = isset($this->config['top']) && isset($this->config['top']['node']) ? $this->config['top']['node'] : 'nav'; $child = null; if (isset($this->config['child']) && isset($this->config['child']['node'])) { $child = $this->config['child']['node']; } else { if ($parent == 'nav') { $child = 'nav'; } } // Create parent node $nav = new Child($parent); if (null !== $this->indent) { $nav->setIndent(str_repeat($this->indent, $depth)); } // Set top attributes if they exist if (isset($this->config['top']) && isset($this->config['top']['id'])) { $nav->setAttribute('id', $this->config['top']['id']); } if (isset($this->config['top']) && isset($this->config['top']['class'])) { $nav->setAttribute('class', $this->config['top']['class']); } if (isset($this->config['top']['attributes'])) { foreach ($this->config['top']['attributes'] as $attrib => $value) { $nav->setAttribute($attrib, $value); } } } else { // Set up parent/child node names $parent = isset($this->config['parent']) && isset($this->config['parent']['node']) ? $this->config['parent']['node'] : 'nav'; $child = null; if (isset($this->config['child']) && isset($this->config['child']['node'])) { $child = $this->config['child']['node']; } else { if ($parent == 'nav') { $child = 'nav'; } } // Create parent node $nav = new Child($parent); if (null !== $this->indent) { $nav->setIndent(str_repeat($this->indent, $depth)); } // Set parent attributes if they exist if (isset($this->config['parent']) && isset($this->config['parent']['id'])) { $nav->setAttribute('id', $this->config['parent']['id'] . '-' . $this->parentLevel); } if (isset($this->config['parent']) && isset($this->config['parent']['class'])) { $nav->setAttribute('class', $this->config['parent']['class'] . '-' . $depth); } if (isset($this->config['parent']['attributes'])) { foreach ($this->config['parent']['attributes'] as $attrib => $value) { $nav->setAttribute($attrib, $value); } } } $this->parentLevel++; $depth++; // Recursively loop through the nodes foreach ($tree as $node) { $allowed = true; if (isset($node['acl'])) { if (null === $this->acl) { throw new Exception('The access control object is not set.'); } if (null === $this->role) { $allowed = false; } else { $resource = isset($node['acl']['resource']) ? $node['acl']['resource'] : null; $permission = isset($node['acl']['permission']) ? $node['acl']['permission'] : null; $allowed = $this->acl->isAllowed($this->role, $resource, $permission); } } if ($allowed && isset($node['name']) && isset($node['href'])) { // Create child node and child link node $a = new Child('a', $node['name']); if (substr($node['href'], 0, 1) == '#' || substr($node['href'], -1) == '#' || substr($node['href'], 0, 4) == 'http' || substr($node['href'], 0, 7) == 'mailto:') { $href = $node['href']; } else { if (substr($node['href'], 0, 1) == '/') { $href = $this->baseUrl . $node['href']; } else { if (substr($parentHref, -1) == '/') { $href = $parentHref . $node['href']; } else { $href = $parentHref . '/' . $node['href']; } } } $a->setAttribute('href', $href); if ($this->returnFalse && ($href == '#' || substr($href, -1) == '#')) { $a->setAttribute('onclick', 'return false;'); } $url = $_SERVER['REQUEST_URI']; if (strpos($url, '?') !== false) { $url = substr($url, strpos($url, '?')); } $linkClass = null; if ($href == $url) { if (isset($this->config['on'])) { $linkClass = $this->config['on']; } } else { if (isset($this->config['off'])) { $linkClass = $this->config['off']; } } // If the node has any attributes if (isset($node['attributes'])) { foreach ($node['attributes'] as $attrib => $value) { $value = $attrib == 'class' && null !== $linkClass ? $value . ' ' . $linkClass : $value; $a->setAttribute($attrib, $value); } } else { if (null !== $linkClass) { $a->setAttribute('class', $linkClass); } } if (null !== $child) { $navChild = new Child($child); // Set child attributes if they exist if (isset($this->config['child']) && isset($this->config['child']['id'])) { $navChild->setAttribute('id', $this->config['child']['id'] . '-' . $this->childLevel); } if (isset($this->config['child']) && isset($this->config['child']['class'])) { $navChild->setAttribute('class', $this->config['child']['class'] . '-' . ($depth - 1)); } if (isset($this->config['child']['attributes'])) { foreach ($this->config['child']['attributes'] as $attrib => $value) { $navChild->setAttribute($attrib, $value); } } // Add link node $navChild->addChild($a); $this->childLevel++; // If there are children, loop through and add them if (isset($node['children']) && is_array($node['children']) && count($node['children']) > 0) { $childrenAllowed = true; // Check if the children are allowed $i = 0; foreach ($node['children'] as $nodeChild) { if (isset($nodeChild['acl'])) { if (null === $this->acl) { throw new Exception('The access control object is not set.'); } if (null === $this->role) { $childrenAllowed = false; } else { $resource = isset($nodeChild['acl']['resource']) ? $nodeChild['acl']['resource'] : null; $permission = isset($nodeChild['acl']['permission']) ? $nodeChild['acl']['permission'] : null; if (!$this->acl->isAllowed($this->role, $resource, $permission)) { $i++; } } } } if ($i == count($node['children'])) { $childrenAllowed = false; } if ($childrenAllowed) { $nextChild = $this->traverse($node['children'], $depth, $href); if ($nextChild->hasChildren() || null !== $nextChild->getNodeValue()) { $navChild->addChild($nextChild); } } } // Add child node $nav->addChild($navChild); } else { $nav->addChild($a); } } } return $nav; }
<?php require_once '../../bootstrap.php'; use Pop\Dom\Child; try { $children = array(array('nodeName' => 'h1', 'nodeValue' => 'This is a header', 'attributes' => array('class' => 'headerClass', 'style' => 'font-size: 3.0em;'), 'childrenFirst' => false, 'childNodes' => null), array('nodeName' => 'div', 'nodeValue' => 'This is a div element', 'attributes' => array('id' => 'contentDiv'), 'childrenFirst' => false, 'childNodes' => array(array('nodeName' => 'p', 'nodeValue' => 'This is a paragraph1', 'attributes' => array('style' => 'font-size: 0.9em;'), 'childrenFirst' => false, 'childNodes' => array(array('nodeName' => 'strong', 'nodeValue' => 'This is bold!', 'attributes' => array('style' => 'font-size: 1.2em;')))), array('nodeName' => 'p', 'nodeValue' => 'This is another paragraph!', 'attributes' => array('style' => 'font-size: 0.9em;'))))); $parent = new Child('div'); $parent->setIndent(' ')->addChildren($children); $parent->render(); } catch (\Exception $e) { echo $e->getMessage() . PHP_EOL . PHP_EOL; }
/** * Method to render the form using a basic 1:1 DT/DD layout * * @return string */ protected function renderWithoutTemplate() { // Initialize properties. $this->output = null; $children = $this->getChildren(); $this->removeChildren(); $id = null !== $this->getAttribute('id') ? $this->getAttribute('id') . '-field-group' : 'pop-form-field-group'; // Create DL element. $i = 1; $dl = new Child('dl', null, null, false, $this->getIndent()); $dl->setAttribute('id', $id . '-' . $i); $dl->setAttribute('class', $id); if (isset($this->headers[$i - 1])) { $fieldGroupHeader = new Child('h' . $this->headers[$i - 1]['weight'], $this->headers[$i - 1]['header']); $fieldGroupHeader->setAttribute('class', $id . '-header'); $fieldGroupHeader->setIndent($this->getIndent()); $this->addChild($fieldGroupHeader); } // Loop through the children and create and attach the appropriate DT and DT elements, with labels where applicable. foreach ($children as $child) { if ($child->getNodeName() == 'fieldset') { $chdrn = $child->getChildren(); if (isset($chdrn[0])) { $attribs = $chdrn[0]->getAttributes(); } } else { $attribs = $child->getAttributes(); } $name = isset($attribs['name']) ? $attribs['name'] : ''; $name = str_replace('[]', '', $name); if (count($this->groups) > 0) { if (isset($this->groups[$i]) && $this->groups[$i] == $name) { $this->addChild($dl); $i++; $dl = new Child('dl', null, null, false, $this->getIndent()); $dl->setAttribute('id', $id . '-' . $i); $dl->setAttribute('class', $id); if (isset($this->headers[$i - 1])) { $fieldGroupHeader = new Child('h' . $this->headers[$i - 1]['weight'], $this->headers[$i - 1]['header']); $fieldGroupHeader->setAttribute('class', $id . '-header'); $fieldGroupHeader->setIndent($this->getIndent()); $this->addChild($fieldGroupHeader); } } } // Clear the password field from display. if ($child->getAttribute('type') == 'password') { $child->setValue(null); $child->setAttribute('value', null); } // If the element label is set, render the appropriate DT and DD elements. if ($child instanceof Element\AbstractElement && null !== $child->getLabel()) { // Create the DT and DD elements. $dt = new Child('dt', null, null, false, $this->getIndent() . ' '); $dd = new Child('dd', null, null, false, $this->getIndent() . ' '); // Format the label name. $lblName = $child->getNodeName() == 'fieldset' ? '1' : ''; $label = new Child('label', $child->getLabel(), null, false, $this->getIndent() . ' '); $label->setAttribute('for', $name . $lblName); $labelAttributes = $child->getLabelAttributes(); if (count($labelAttributes) > 0) { foreach ($labelAttributes as $a => $v) { if ($a == 'class' && $child->isRequired()) { $v .= ' required'; } $label->setAttribute($a, $v); } } else { if ($child->isRequired()) { $label->setAttribute('class', 'required'); } } // Add the appropriate children to the appropriate elements. $dt->addChild($label); $child->setIndent($this->getIndent() . ' '); $childChildren = $child->getChildren(); $child->removeChildren(); foreach ($childChildren as $cChild) { $cChild->setIndent($this->getIndent() . ' '); $child->addChild($cChild); } $dd->addChild($child); if (null !== $child->getHint()) { $hint = new Child('span', $child->getHint(), null, false, $this->getIndent() . ' '); if (count($child->getHintAttributes()) > 0) { $hint->setAttributes($child->getHintAttributes()); } $dd->addChild($hint); } $dl->addChildren([$dt, $dd]); // Else, render only a DD element. } else { $dd = new Child('dd', null, null, false, $this->getIndent() . ' '); $child->setIndent($this->getIndent() . ' '); $dd->addChild($child); if ($child instanceof Element\AbstractElement && null !== $child->getHint()) { $hint = new Child('span', $child->getHint(), null, false, $this->getIndent() . ' '); if (count($child->getHintAttributes()) > 0) { $hint->setAttributes($child->getHintAttributes()); } $dd->addChild($hint); } $dl->addChild($dd); } } // Add the DL element and its children to the form element. $this->addChild($dl); return parent::render(true); }