phpQueryObject::find PHP Method

find() public method

..
public find ( $selectors, $context = null, $noHistory = false ) : phpQueryObject | QueryTemplatesSource | QueryTemplatesParse | QueryTemplatesSourceQuery
return phpQueryObject | QueryTemplatesSource | QueryTemplatesParse | QueryTemplatesSourceQuery
    public function find($selectors, $context = null, $noHistory = false)
    {
        if (!$noHistory) {
            // backup last stack /for end()/
            $this->elementsBackup = $this->elements;
        }
        // allow to define context
        // TODO combine code below with phpQuery::pq() context guessing code
        //   as generic function
        if ($context) {
            if (!is_array($context) && $context instanceof DOMELEMENT) {
                $this->elements = array($context);
            } elseif (is_array($context)) {
                $this->elements = array();
                foreach ($context as $c) {
                    if ($c instanceof DOMELEMENT) {
                        $this->elements[] = $c;
                    }
                }
            } elseif ($context instanceof self) {
                $this->elements = $context->elements;
            }
        }
        $queries = $this->parseSelector($selectors);
        $this->debug(array('FIND', $selectors, $queries));
        $XQuery = '';
        // remember stack state because of multi-queries
        $oldStack = $this->elements;
        // here we will be keeping found elements
        $stack = array();
        foreach ($queries as $selector) {
            $this->elements = $oldStack;
            $delimiterBefore = false;
            foreach ($selector as $s) {
                // TAG
                $isTag = extension_loaded('mbstring') && phpQuery::$mbstringSupport ? mb_ereg_match('^[\\w|\\||-]+$', $s) || $s == '*' : preg_match('@^[\\w|\\||-]+$@', $s) || $s == '*';
                if ($isTag) {
                    if ($this->isXML()) {
                        // namespace support
                        if (mb_strpos($s, '|') !== false) {
                            $ns = $tag = null;
                            list($ns, $tag) = explode('|', $s);
                            $XQuery .= "{$ns}:{$tag}";
                        } elseif ($s == '*') {
                            $XQuery .= '*';
                        } else {
                            $XQuery .= "*[local-name()='{$s}']";
                        }
                    } else {
                        $XQuery .= $s;
                    }
                    // ID
                } elseif ($s[0] == '#') {
                    if ($delimiterBefore) {
                        $XQuery .= '*';
                    }
                    $XQuery .= "[@id='" . substr($s, 1) . "']";
                    // ATTRIBUTES
                } elseif ($s[0] == '[') {
                    if ($delimiterBefore) {
                        $XQuery .= '*';
                    }
                    // strip side brackets
                    $attr = trim($s, '][');
                    $execute = false;
                    // attr with specifed value
                    if (mb_strpos($s, '=')) {
                        $value = null;
                        list($attr, $value) = explode('=', $attr);
                        $value = trim($value, "'\"");
                        if ($this->isRegexp($attr)) {
                            // cut regexp character
                            $attr = substr($attr, 0, -1);
                            $execute = true;
                            $XQuery .= "[@{$attr}]";
                        } else {
                            $XQuery .= "[@{$attr}='{$value}']";
                        }
                        // attr without specified value
                    } else {
                        $XQuery .= "[@{$attr}]";
                    }
                    if ($execute) {
                        $this->runQuery($XQuery, $s, 'is');
                        $XQuery = '';
                        if (!$this->length()) {
                            break;
                        }
                    }
                    // CLASSES
                } elseif ($s[0] == '.') {
                    // TODO use return $this->find("./self::*[contains(concat(\" \",@class,\" \"), \" $class \")]");
                    // thx wizDom ;)
                    if ($delimiterBefore) {
                        $XQuery .= '*';
                    }
                    $XQuery .= '[@class]';
                    $this->runQuery($XQuery, $s, 'matchClasses');
                    $XQuery = '';
                    if (!$this->length()) {
                        break;
                    }
                    // ~ General Sibling Selector
                } elseif ($s[0] == '~') {
                    $this->runQuery($XQuery);
                    $XQuery = '';
                    $this->elements = $this->siblings(substr($s, 1))->elements;
                    if (!$this->length()) {
                        break;
                    }
                    // + Adjacent sibling selectors
                } elseif ($s[0] == '+') {
                    // TODO /following-sibling::
                    $this->runQuery($XQuery);
                    $XQuery = '';
                    $subSelector = substr($s, 1);
                    $subElements = $this->elements;
                    $this->elements = array();
                    foreach ($subElements as $node) {
                        // search first DOMElement sibling
                        $test = $node->nextSibling;
                        while ($test && !$test instanceof DOMELEMENT) {
                            $test = $test->nextSibling;
                        }
                        if ($test && $this->is($subSelector, $test)) {
                            $this->elements[] = $test;
                        }
                    }
                    if (!$this->length()) {
                        break;
                    }
                    // PSEUDO CLASSES
                } elseif ($s[0] == ':') {
                    // TODO optimization for :first :last
                    if ($XQuery) {
                        $this->runQuery($XQuery);
                        $XQuery = '';
                    }
                    if (!$this->length()) {
                        break;
                    }
                    $this->pseudoClasses($s);
                    if (!$this->length()) {
                        break;
                    }
                    // DIRECT DESCENDANDS
                } elseif ($s == '>') {
                    $XQuery .= '/';
                    $delimiterBefore = 2;
                    // ALL DESCENDANDS
                } elseif ($s == ' ') {
                    $XQuery .= '//';
                    $delimiterBefore = 2;
                    // ERRORS
                } else {
                    phpQuery::debug("Unrecognized token '{$s}'");
                }
                $delimiterBefore = $delimiterBefore === 2;
            }
            // run query if any
            if ($XQuery && $XQuery != '//') {
                $this->runQuery($XQuery);
                $XQuery = '';
            }
            foreach ($this->elements as $node) {
                if (!$this->elementsContainsNode($node, $stack)) {
                    $stack[] = $node;
                }
            }
        }
        $this->elements = $stack;
        return $this->newInstance();
    }

Usage Example

Esempio n. 1
0
 /**
  * Query the response for a JQuery compatible CSS selector
  *
  * @link https://code.google.com/p/phpquery/wiki/Selectors
  * @param $selector string
  * @return phpQueryObject
  */
 public function queryHTML($selector)
 {
     if (is_null($this->pq)) {
         $this->pq = phpQuery::newDocument($this->content);
     }
     return $this->pq->find($selector);
 }
All Usage Examples Of phpQueryObject::find