Returns tree extra branches.

@since Moodle 3.5
@param int $contextid
@param string $element
@return array
327901
public static function tree_extra_branches($contextid, $element) {

        $params = external_api::validate_parameters(self::tree_extra_branches_parameters(), [
            'contextid' => $contextid,
            'element' => $element,
        ]);

        $context = context_helper::instance_by_id($params['contextid']);

        self::validate_context($context);
        api::check_can_manage_data_registry($context->id);

        switch ($params['element']) {
            case 'course':
                $branches = data_registry_page::get_courses_branch($context);
                break;
            case 'module':
                $branches = data_registry_page::get_modules_branch($context);
                break;
            case 'block':
                $branches = data_registry_page::get_blocks_branch($context);
                break;
            default:
                throw new \moodle_exception('Unsupported element provided.');
        }

        return [
            'branches' => $branches,
            'warnings' => [],
        ];
    }
291226
protected function fromChildOverDescendantsNodeIteratorParts( $context, $nodeTest, $iter )
	{
		$this->context = $context;
		$this->nodeTest = $nodeTest;
		$this->iter = $iter;
		$this->lastTest = $nodeTest[ count( $nodeTest ) - 1 ];
		$this->kind = XPathNodeType::All;
		if ( isset( $this->lastTest->nameTest ) || ( isset( $this->lastTest->typeTest ) && $this->lastTest->typeTest->GetNodeKind() == XPathNodeType::Element ) )
		{
			$this->kind = XPathNodeType::Element;
		}
	}
518148
protected function readXmlNodes(\SimpleXMLElement $element): array
    {
        $arrayElements = [];
        foreach ($element as $name => $node) {
            if ($name == "defaults") {
                continue;
            }
            $arrayElement = [];
            $arrayElement["type"] = $name;
            $arrayElement["attributes"] = $this->readAttributesArray($node);
            $details = $this->readXmlNodes($node);
            if (!empty($details)) {
                $arrayElement["details"] = $details;
            }
            $arrayElements[] = $arrayElement;
        }

        return $arrayElements;
    }
1063184
protected function getPropertyChildValue(\DOMElement $element, ContextInterface $context)
    {
        // If the property creates a new type: Return the element itself
        if ($element->hasAttribute('itemscope')) {
            $thing = $this->getThing($element->getAttribute('itemtype'), null, $context);
            return $this->processItemReferences($element, $context, $thing);
        }

        return null;
    }
1091098
public function getNodeFromContextPath($contextPath, Site $site = null, Domain $domain = null, $includeAll = false)
    {
        $nodePathAndContext = NodePaths::explodeContextPath($contextPath);
        $nodePath = $nodePathAndContext['nodePath'];
        $workspaceName = $nodePathAndContext['workspaceName'];
        $dimensions = $nodePathAndContext['dimensions'];

        $contextProperties = $this->prepareContextProperties($workspaceName, $dimensions);

        if ($site === null) {
            list(, , $siteNodeName) = explode('/', $nodePath);
            $site = $this->siteRepository->findOneByNodeName($siteNodeName);
        }

        if ($domain === null) {
            $domain = $this->domainRepository->findOneBySite($site);
        }

        $contextProperties['currentSite'] = $site;
        $contextProperties['currentDomain'] = $domain;
        if ($includeAll === true) {
            $contextProperties['invisibleContentShown'] = true;
            $contextProperties['removedContentShown'] = true;
        }

        $context = $this->contextFactory->create(
            $contextProperties
        );

        $workspace = $context->getWorkspace(false);
        if (!$workspace) {
            return new Error(
                sprintf('Could not convert the given source to Node object because the workspace "%s" as specified in the context node path does not exist.', $workspaceName), 1451392329);
        }

        return $context->getNode($nodePath);
    }
997155
public function getTree($id = null) {
        $parent = $this->getConfig('parentField');
        $left = $this->getConfig('leftField');
        $right = $this->getConfig('rightField');

        $query = $this->getRepository()->select()->orderBy($left, 'asc');

        if ($id) {
            if ($parentNode = $this->getNode($id)) {
                $query->where($left, 'between', [$parentNode[$left], $parentNode[$right]]);
            } else {
                return [];
            }
        }

        $nodes = $query->all();

        if ($nodes->isEmpty()) {
            return [];
        }

        $map = [];
        $stack = [];
        $pk = $this->getRepository()->getPrimaryKey();

        foreach ($nodes as $node) {
            if ($node[$parent] && $node[$pk] != $id) {
                $map[$node[$parent]][] = $node;
            } else {
                $stack[] = $node;
            }
        }

        $results = $this->mapTree($stack, $map);

        if ($id) {
            return $results[0];
        }

        return $results;
    }
1039130
public function arrTree(array $tree, $rootId = 0, $setKey = 'id')
    {
        $result = [];
        $id = $this->pkColumn;
        $parentId = $this->pidColumn;
        $childKey = $this->childKeyName;

        foreach ($tree as $leaf) {
            if ($leaf[$parentId] === $rootId) {
                foreach ($tree as $subLeaf) {
                    if ($subLeaf[$parentId] === $leaf[$id]) {
                        $leaf[$childKey] = $this->arrTree($tree, $leaf[$id], $setKey);
                        break;
                    }
                }

                if ($setKey) {
                    $result[$leaf[$setKey]] = $leaf;
                } else {
                    $result[] = $leaf;
                }
            }
        }

        return $result;
    }
586218
protected function createAndAddChild(\DOMElement $element, ContextInterface $context)
    {
        $thing = $this->getThing(
            trim($element->getAttribute('itemtype')) ?: null,
            trim($element->getAttribute('itemid')) ?: null,
            $context
        );

        // Process item references
        $this->processItemReferences($element, $context, $thing);

        // Add the new thing as a child to the current context
        // and set the thing as parent thing for nested iterations
        return $context->addChild($thing)->setParentThing($thing);
    }
449608
public static List<Element> getChildElements(Element e) {

		List<Element> ret = new ArrayList<Element>();
		NodeList children = e.getChildNodes();

		for (int i = 0; i < children.getLength(); i++) {
			Node child = children.item(i);
			if (child.getNodeType()  == Node.ELEMENT_NODE) {
				ret.add((Element) child);
			}
		}

		return ret;
	}
519265
private function get_default_tree_structure() {

        $frontpage = \context_course::instance(SITEID);

        $categorybranches = $this->get_all_category_branches();

        $elements = [
            'text' => get_string('contextlevelname' . CONTEXT_SYSTEM, 'tool_dataprivacy'),
            'contextlevel' => CONTEXT_SYSTEM,
            'branches' => [
                [
                    'text' => get_string('user'),
                    'contextlevel' => CONTEXT_USER,
                ], [
                    'text' => get_string('categories'),
                    'branches' => $categorybranches,
                    'expandelement' => 'category',
                ], [
                    'text' => get_string('frontpagecourse', 'tool_dataprivacy'),
                    'contextid' => $frontpage->id,
                    'branches' => [
                        [
                            'text' => get_string('activitiesandresources', 'tool_dataprivacy'),
                            'expandcontextid' => $frontpage->id,
                            'expandelement' => 'module',
                            'expanded' => 0,
                        ], [
                            'text' => get_string('blocks'),
                            'expandcontextid' => $frontpage->id,
                            'expandelement' => 'block',
                            'expanded' => 0,
                        ],
                    ]
                ]
            ]
        ];

        // Returned as an array to follow a common array format.
        return [self::complete($elements, $this->defaultcontextlevel, $this->defaultcontextid)];
    }
946500
private function _getSectionSources(Element $element = null): array
    {
        $sources = [];
        $sections = Craft::$app->getSections()->getAllSections();
        $showSingles = false;

        foreach ($sections as $section) {
            if ($section->type === Section::TYPE_SINGLE) {
                $showSingles = true;
            } else if ($element) {
                // Does the section have URLs in the same site as the element we're editing?
                $sectionSiteSettings = $section->getSiteSettings();
                if (isset($sectionSiteSettings[$element->siteId]) && $sectionSiteSettings[$element->siteId]->hasUrls) {
                    $sources[] = 'section:'.$section->uid;
                }
            }
        }

        if ($showSingles) {
            array_unshift($sources, 'singles');
        }

        return $sources;
    }
786486
private function loadTypes(&$tags, \DOMXPath $xpath, \DOMNode $context = null)
    {
        $result = [];

        /** @var \DOMElement $node */
        foreach ($xpath->query('x:types/x:type', $context) as $node) {
            $value = $this->loadType($xpath, $node, $tags);
            $result[$value['name']] = $value;
        }

        return $result;
    }
494109
public function get_parent_context_ids($includeself = false) {
        if (empty($this->_path)) {
            return array();
        }

        $parentcontexts = trim($this->_path, '/'); // kill leading slash
        $parentcontexts = explode('/', $parentcontexts);
        if (!$includeself) {
            array_pop($parentcontexts); // and remove its own id
        }

        return array_reverse($parentcontexts);
    }
724573
private function flattenBody($xml, $context = '')
    {
        foreach ($xml as $elementName => $element) {
            //Check ref first
            $elementContext = $context;
            foreach ($element->attributes() as $name => $value) {
                if ($name == 'ref' || $name == 'nodeset' ) {
                    if (!empty($elementContext)) {
                        $elementContext .= '/';
                    } else {
                        $elementContext = $this->bindRoot;
                    }
                    if (substr($value, 0, 1) == '/') {
                        $elementContext    = '';
                    }
                    $elementContext .= $value;
                    break;
                }
            }
            $result['context'] = $elementContext;
            $result['name']    = $element->getName();

            //elementName can be label, hint, or a sub element (group, input, select, select1
            switch ($elementName) {
                case 'label':
                    $result['label'] = (string) $element;
                    break;

                case 'hint':
                    $result['hint'] = (string) $element;
                    break;

                case 'value':
                    $result['value'] = (string) $element;
                    break;

                case 'trigger':
                case 'upload':
                case 'input':
                case 'select':
                case 'select1':
                    //has only value and label but repeated, add value/label pairs in array
                    $rawItem                     = $this->flattenBody($element, $elementContext);
                    $rawItem['context']          = $elementContext;
                    $rawItem['name']             = $element->getName();
                    $rawItem['attribs']          = $element->attributes();
                    $result[$rawItem['context']] = $rawItem;
                    break;

                case 'item':
                    //has only value and label but repeated, add value/label pairs in array
                    $rawItem                           = $this->flattenBody($element->children(), $elementContext);
                    unset($rawItem['context']);
                    unset($rawItem['name']);
                    $result['item'][$rawItem['value']] = $rawItem['label'];
                    break;

                case 'repeat':
                case 'group':
                default:
                    if (isset($result['context'], $result['label'])) {
                        $this->groupLabels[$result['context']] = $result['label'];
                    }
                    unset($result['context']);
                    unset($result['name']);
                    $subarray = $this->flattenBody($element->children(), $elementContext);
                    unset($subarray['context']);
                    unset($subarray['label']);
                    unset($subarray['hint']);
                    unset($subarray['name']);
                    // If it is a repeat element, we need to do something special when data is coming in
                    if ($elementName == 'repeat') {
                        foreach($subarray as $key => &$info)
                        {
                            $info['repeat'] = substr($elementContext, strlen($this->bindRoot));
                        }
                    }
                    $result   = $result + $subarray;
                    break;
            }
        }

        return $result;
    }
409300
protected function getBlock(\DOMElement $element) {
    $block = '';
    /** @var \DOMNode $node */
    foreach ($element->childNodes as $node) {
      switch ($node->nodeType) {

        case XML_ELEMENT_NODE:
          /** @var \DOMElement $node */
          switch ($node->nodeName) {

            // Explicitly handle these elements.

            case 'i':
            case 'em':
              $block .= '*' . $this->getBlock($node) . '*';
              break;

            case 'b':
            case 'strong':
              $block .= '**' . $this->getBlock($node) . '**';
              break;

            case 'a':
              if ($node->hasAttribute('href')) {
                $block .= '[' . $this->getBlock($node) . ']' .
                  '(' . $node->getAttribute('href') . ')';
              }
              break;

            // Other inline elements.
            default:
              // Recursively handle any descendant elements we care about.
              $block .= $this->getBlock($node);
              break;

          }
          break;

        case XML_TEXT_NODE:
          /** @var \DOMText $node */
          $block .= self::escape($node->textContent);
          break;

      }
    }

    // Handle white-listed elements.
    if (in_array($element->nodeName, $this->white_list)) {
      $tag = $element->cloneNode();
      if (!empty($block)) {
        $tag->appendChild(new \DOMText($block));
      }
      $block = $this->dom->saveXML($tag);
    }

    return $block;
  }
761251
private function loadTags(&$tags, \DOMXPath $xpath, \DOMNode $context = null)
    {
        $result = [];

        /** @var \DOMElement $node */
        foreach ($xpath->query('x:tag', $context) as $node) {
            $tag = $this->loadTag($xpath, $node);
            $this->validateTag($tag, $tags);

            $result[] = $tag;
        }

        return $result;
    }
1180876
public static List<Node> getSiblings(Node parent, Node element) {
		List<Node> result = new ArrayList<>();
		NodeList list = parent.getChildNodes();

		for (int i = 0; i < list.getLength(); i++) {
			Node el = list.item(i);

			if (el.getNodeName().equals(element.getNodeName())) {
				result.add(el);
			}
		}

		return result;
	}