Пример #1
0
 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;
 }