private function getElementsArray($tag = null, $attr = '\\w*', $value = '\\w*', $one = false, &$deep = 0) { $deep++; $max = self::$maxResultsPerStartegy; // todo: measure the correction $maxDeep = self::$maxRecursionInStartegy; if ($deep > $maxDeep) { throw new XParserException('Recursion detected in dom tree.'); } $founds = []; if (is_null($tag)) { foreach ($this->getPossibleTags() as $tag) { $elems = $this->getElementsArray($tag, $attr, $value, $one, $deep); foreach ($elems as $elem) { $founds[] = $elem; } } } else { $simples = ['\\!doctype', 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']; $simple = in_array(strtolower($tag), $simples); $singles = ['\\!doctype', 'html', 'body', 'head', 'title']; // todo more? $single = in_array(strtolower($tag), $singles); $one = $single || $attr == 'id'; if ($attr == '\\w*' || $value == '\\w*') { if ($simple) { $regex = '/<' . $tag . '\\b[^>]*[^>\\/]*?>/is'; if ($one && preg_match($regex, $this->__html, $match)) { return $match; } preg_match_all($regex, $this->__xhtml, $matches); $founds = $matches[0]; } else { // todo : it's valid but not too propabilities do may it have to be the last check // $regex = '/<' . $tag . '\b[^>]*[^>\/]*?\/>/is'; // preg_match_all($regex, $this->__xhtml, $matches); // $founds = $matches[0]; // if($one && $founds) return [$founds[0]]; $regex = '/<' . $tag . '\\b[^>]*[^>\\/]*?\\>.*<\\/' . $tag . '>/is'; if ($one && preg_match($regex, $this->__xhtml, $match)) { return $match; } preg_match_all($regex, $this->__xhtml, $matches); foreach ($matches[0] as $match) { if (!in_array($match, $founds) && self::isValidClosure($match, true)) { $founds[] = $match; } else { $x = new XNode(substr($match, 1)); $more = $x->getElementsArray($tag, $attr, $value, $one, $deep); $founds = array_merge($founds, $more); if (count($founds) >= $max) { throw new XParserException('Too many element found, searching limit is ' . $max . ', please change your query to a more definitely selector.'); } $x = new XNode(substr($match, 0, -1)); $more = $x->getElementsArray($tag, $attr, $value, $one, $deep); $founds = array_merge($founds, $more); if (count($founds) >= $max) { throw new XParserException('Too many element found, searching limit is ' . $max . ', please change your query to a more definitely selector.'); } } } } } if ($simple) { $regex = '/<' . $tag . '\\b[^>]*([^-]\\b)' . $attr . '\\b\\s*?=\\s*?"' . $value . '"[^>\\/]*?>/is'; if ($one && preg_match($regex, $this->__html, $match)) { return $match; } preg_match_all($regex, $this->__xhtml, $matches); $founds = array_merge($founds, $matches[0]); } else { // todo : it's valid but not too propabilities do may it have to be the last check // $regex = '/<' . $tag . '\b[^>]*\b' . $attr . '\b\s*?=\s*?"' . $value . '"[^>\/]*?\/>/is'; // preg_match_all($regex, $this->__xhtml, $matches); // $founds = array_merge($founds, $matches[0]); // if($one && $founds) return [$founds[0]]; $regex = '/<' . $tag . '\\b[^>]*([^-]\\b)' . $attr . '\\b\\s*?=\\s*?"' . $value . '"[^>\\/]*?>.*?<\\/' . $tag . '>/is'; if (preg_match($regex, $this->__xhtml, $matches)) { if (self::isValidClosure($matches[0], true)) { if (!in_array($matches[0], $founds)) { if ($one) { return [$matches[0]]; } $founds[] = $matches[0]; } } } if (!$single) { $regex = '/<' . $tag . '\\b[^>]*([^-]\\b)' . $attr . '\\b\\s*?=\\s*?"' . $value . '"[^>\\/]*?>(\\R|.*?<\\/' . $tag . '>).*<\\/' . $tag . '>/is'; if (preg_match($regex, $this->__xhtml, $matches)) { // todo : duplicated code, separate this for an other function if (self::isValidClosure($matches[0], true)) { if (!in_array($matches[0], $founds)) { if ($one) { return [$matches[0]]; } $founds[] = $matches[0]; } } $x = new XNode(substr($matches[0], 1)); $more = $x->getElementsArray($tag, $attr, $value, $one, $deep); $founds = array_merge($founds, $more); if (count($founds) >= $max) { throw new XParserException('Too many element found, searching limit is ' . $max . ', please change your query to a more definitely selector.'); } $x = new XNode(substr($matches[0], 0, -1)); $more = $x->getElementsArray($tag, $attr, $value, $one, $deep); $founds = array_merge($founds, $more); if (count($founds) >= $max) { throw new XParserException('Too many element found, searching limit is ' . $max . ', please change your query to a more definitely selector.'); } } } } } $deep--; // TODO : may array_merge or array_unique function is not necessary... $founds = array_unique($founds); return $founds; }