Join selectors; looks for & to replace, or append parent before child

@param array $parent
@param array $child
@param array $selfParentSelectors

@return array
198413
protected function joinSelectors($parent, $child, $selfParentSelectors = null)
    {
        $setSelf = false;
        $out = [];

        foreach ($child as $part) {
            $newPart = [];

            foreach ($part as $p) {
                if ($p === static::$selfSelector) {
                    $setSelf = true;

                    if (is_null($selfParentSelectors)) {
                        $selfParentSelectors = $parent;
                    }

                    foreach ($selfParentSelectors as $i => $parentPart) {
                        if ($i > 0) {
                            $out[] = $newPart;
                            $newPart = [];
                        }

                        foreach ($parentPart as $pp) {
                            if (is_array($pp)) {
                                $flatten = [];
                                array_walk_recursive($pp, function ($a) use (&$flatten) {
                                    $flatten[] = $a;
                                });
                                $pp = implode($flatten);
                            }
                            $newPart[] = $pp;
                        }
                    }
                } else {
                    $newPart[] = $p;
                }
            }

            $out[] = $newPart;
        }

        return $setSelf ? $out : array_merge($parent, $child);
    }
1278638
final public function parent()
    {
        $parent = NULL;

        if(!!isset($this->dom_element->parentNode))
        {
            if($this->dom_element->parentNode->nodeType == 1)
            {
                $parent = new PHPHtmlDomElement($this->dom_element->parentNode);
            }
            else
            {
                $parent = $this->dom_element->parentNode;
            }
        }
        return $parent;
    }
231817
protected function _findInChildren(array $element, $id, $withParents, array &$parents)
    {
        if ($element['id'] == $id) {
            return $element;
        }
        foreach ($element['children'] as $child) {
            if ($child['id'] == $id) {
                if ($withParents) {
                    $parents[] = $element;
                }
                return $child;
            }
            if (null !== ($found = $this->_findInChildren($child, $id, $withParents, $parents))) {
                if ($withParents) {
                    $parents[] = $element;
                }
                return $found;
            }
        }
    }
851878
protected function _pushParent(&$parent)
    {
        $children    = &$this->_getElementChildren($parent);
        $pathSegment = $this->_getElementPathSegment(null, $parent);

        $this->_pushPathSegment($pathSegment);

        reset($children);
        array_unshift($this->parents, $children);
    }
386484
protected function _parseParent($child, $data, $attributes) {
        $parent = $child->xpath("parent::*");

        if (is_object($parent[0]['name'])) {
            foreach ($attributes as $attribute) {
                $name = $attribute['name'];

                if (is_object($parent[0][$name])) {
                    /** @var SimpleXMLElement $element */
                    $element = $parent[0][$name];

                    if ($attribute['concatenate'] == true) {
                        if ($data[$name] != '') {
                            $data[$name] = $element->__toString() . $attribute['separator'] . $data[$name];
                        }
                        else {
                            $data[$name] = $element->__toString();
                        }
                    }
                    else {
                        if ($data[$name] == '') {
                            $data[$name] = $element->__toString();
                        }
                    }
                }
            }

            $data = $this->_parseParent($parent[0], $data, $attributes);
        }

        return $data;
    }
1065479
public function validateSetChildOf(Tree $parent)
    {
        if ($parent->getKey() == $this->getKey()) {
            throw new SelfConnectionException();
        }
        if ($parent->{$this->getTreeColumn('path')} != $this->removeLastNodeFromPath()) { // Only if new parent
            return true;
        }
        return false;
    }
412587
function select(parent, selectors) {
  if (parent === null || parent === undefined) {
    return null;
  }
  if (selectors.length === 0) {
    return parent;
  }
  let selector = selectors[0];
  return select(parent[selector], selectors.splice(1, selectors.length - 1));
}
1032493
private function process(array $element, $parent = null)
    {
        $apiElement = $element['element'];

        if (isset($this->elementMap[$apiElement])) {
            $this->processElement(
                $element,
                $this->elementMap[$apiElement],
                $parent
            );
        }

        if ($element['element'] === 'category') {
            // todo extend the element map to check for classes, then merge processCategory into processElement
            $this->processCategory($element, $parent);
        }
    }
956982
protected final function appendXMLTo(
       SimpleXMLElement $parent,
       string $child): SimpleXMLElement
   {
       return $this->appendTo(
           $parent,
           simplexml_load_string(str_replace("\n", "\n\t", $child)));
   }
365331
protected function multiplySelectors(Environment $env, $selfParent = null)
    {
        $envs            = $this->compactEnv($env);
        $selectors       = [];
        $parentSelectors = [[]];

        $selfParentSelectors = null;

        if (!is_null($selfParent) and $selfParent->selectors) {
            $selfParentSelectors = $this->evalSelectors($selfParent->selectors);
        }

        while ($env = array_pop($envs)) {
            if (empty($env->selectors)) {
                continue;
            }

            $selectors = [];

            foreach ($env->selectors as $selector) {
                foreach ($parentSelectors as $parent) {
                    if ($selfParentSelectors) {
                        $previous = null;

                        foreach ($selfParentSelectors as $selfParent) {
                            // if no '&' in the selector, each call will give same result, only add once
                            $s = $this->joinSelectors($parent, $selector, $selfParent);

                            if ($s !== $previous) {
                                $selectors[serialize($s)] = $s;
                            }

                            $previous = $s;
                        }
                    } else {
                        $s = $this->joinSelectors($parent, $selector);
                        $selectors[serialize($s)] = $s;
                    }
                }
            }

            $parentSelectors = $selectors;
        }

        $selectors = array_values($selectors);

        return $selectors;
    }
538417
private function _getParentArray($parent, $array)
    {
        foreach ($array as $section => $arraySection) {

            $sectionName = explode(':', $section);

            if (trim($sectionName[0]) == $parent) return $arraySection;
        }

        throw new NoSectionMatchesException('No section matches with ' . $parent);
    }
837893
public function attachParents(array $parents)
    {
        $this->_parents = [];

        foreach ($parents as $parent) {
            $this->attachParent($parent, false);
        }
    }
997084
private function addSkipped(ParentNode $parent) {
    $parent->addChildren($this->getSkipNodes($this->skipped));
    $this->skipped = [];
    $this->matchDocComment($this->skipParent ?: $parent, NULL);
    $this->skipParent = NULL;
  }
1188813
public function prepend(DOMElement &$parent, &$child)
    {
        if (empty($child)) {
            throw new InvalidArgumentException('You are trying to prepend an empty element.');
        }

        // Append before first child
        if ($parent->childNodes->length > 0) {
            $parent->insertBefore($child, $parent->childNodes->item(0));
        } else {
            $this->append($parent, $child);
        }

        // Return the DOMElement
        return $parent;
    }
612738
private function joinWithRelation($parent, $child)
    {
        if (!empty($child->join)) {
            foreach ($child->join as $join) {
                $this->join[] = $join;
            }
        }
    }
272281
protected function matchToMorphParents($type, EntityCollection $results, array $parents)
    {
        $mapper = $this->relatedMapper->getManager()->mapper($type);
        $keyName = $mapper->getEntityMap()->getKeyName();

        $keys = array_map(function ($parent) use ($keyName) {
            return $parent[$keyName];
        }, $parents);

        $parents = array_combine($keys, $parents);

        foreach ($results as $result) {
            $key = $result[$keyName];

            if (isset($this->dictionary[$type][$key])) {
                foreach ($this->dictionary[$type][$key] as $parent) {
                    $parents[$parent[$keyName]][$this->relation] = $result;
                }
            }
        }

        return array_values($parents);
    }
8216
private List<TreeNode> getSelected(TreeNode parent) {
        List<TreeNode> result = new ArrayList<>();
        for (TreeNode n : parent.getChildren()) {
            if (n.isSelected()) {
                result.add(n);
            }
            result.addAll(getSelected(n));
        }
        return result;
    }