CssSelector::getElements PHP Method

getElements() public method

public getElements ( $selector )
    public function getElements($selector)
    {
        $all_nodes = array();
        foreach ($this->tokenize_selectors($selector) as $selector) {
            $nodes = array($this->dom);
            foreach ($this->tokenize($selector) as $token) {
                $combinator = $token['combinator'];
                $token = trim($token['name']);
                $pos = strpos($token, '#');
                if (false !== $pos && preg_match('/^[A-Za-z0-9]*$/', substr($token, 0, $pos))) {
                    // Token is an ID selector
                    $tagName = substr($token, 0, $pos);
                    $id = substr($token, $pos + 1);
                    $xpath = new DomXPath($this->dom);
                    $element = $xpath->query(sprintf("//*[@id = '%s']", $id))->item(0);
                    if (!$element || $tagName && strtolower($element->nodeName) != $tagName) {
                        // tag with that ID not found
                        return array();
                    }
                    // Set nodes to contain just this element
                    $nodes = array($element);
                    continue;
                    // Skip to next token
                }
                $pos = strpos($token, '.');
                if (false !== $pos && preg_match('/^[A-Za-z0-9]*$/', substr($token, 0, $pos))) {
                    // Token contains a class selector
                    $tagName = substr($token, 0, $pos);
                    if (!$tagName) {
                        $tagName = '*';
                    }
                    $className = substr($token, $pos + 1);
                    // Get elements matching tag, filter them for class selector
                    $founds = $this->getElementsByTagName($nodes, $tagName, $combinator);
                    $nodes = array();
                    foreach ($founds as $found) {
                        if (preg_match('/\\b' . $className . '\\b/', $found->getAttribute('class'))) {
                            $nodes[] = $found;
                        }
                    }
                    continue;
                    // Skip to next token
                }
                // Code to deal with attribute selectors
                if (preg_match('/^(\\w*)(\\[.+\\])$/', $token, $matches)) {
                    $tagName = $matches[1] ? $matches[1] : '*';
                    preg_match_all('/
            \\[
              (\\w+)                 # attribute
              ([=~\\|\\^\\$\\*]?)       # modifier (optional)
              =?                    # equal (optional)
              (
                "([^"]*)"           # quoted value (optional)
                |
                ([^\\]]*)            # non quoted value (optional)
              )
            \\]
          /x', $matches[2], $matches, PREG_SET_ORDER);
                    // Grab all of the tagName elements within current node
                    $founds = $this->getElementsByTagName($nodes, $tagName, $combinator);
                    $nodes = array();
                    foreach ($founds as $found) {
                        $ok = false;
                        foreach ($matches as $match) {
                            $attrName = $match[1];
                            $attrOperator = $match[2];
                            $attrValue = $match[4];
                            switch ($attrOperator) {
                                case '=':
                                    // Equality
                                    $ok = $found->getAttribute($attrName) == $attrValue;
                                    break;
                                case '~':
                                    // Match one of space seperated words
                                    $ok = preg_match('/\\b' . preg_quote($attrValue, '/') . '\\b/', $found->getAttribute($attrName));
                                    break;
                                case '|':
                                    // Match start with value followed by optional hyphen
                                    $ok = preg_match('/^' . preg_quote($attrValue, '/') . '-?/', $found->getAttribute($attrName));
                                    break;
                                case '^':
                                    // Match starts with value
                                    $ok = 0 === strpos($found->getAttribute($attrName), $attrValue);
                                    break;
                                case '$':
                                    // Match ends with value
                                    $ok = $attrValue == substr($found->getAttribute($attrName), -strlen($attrValue));
                                    break;
                                case '*':
                                    // Match ends with value
                                    $ok = false !== strpos($found->getAttribute($attrName), $attrValue);
                                    break;
                                default:
                                    // Just test for existence of attribute
                                    $ok = $found->hasAttribute($attrName);
                            }
                            if (false == $ok) {
                                break;
                            }
                        }
                        if ($ok) {
                            $nodes[] = $found;
                        }
                    }
                    continue;
                    // Skip to next token
                }
                if (preg_match('/^(\\w*)(:first-child)$/', $token, $matches)) {
                    $token = $matches[1] ? $matches[1] : '*';
                    $combinator = $matches[2] ? $matches[2] : '';
                }
                // If we get here, token is JUST an element (not a class or ID selector)
                $nodes = $this->getElementsByTagName($nodes, $token, $combinator);
            }
            foreach ($nodes as $node) {
                if (!$node->getAttribute('sf_matched')) {
                    $node->setAttribute('sf_matched', true);
                    $all_nodes[] = $node;
                }
            }
        }
        foreach ($all_nodes as $node) {
            $node->removeAttribute('sf_matched');
        }
        return $all_nodes;
    }