Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
365 lars 1
<?php
2
 
3
declare(strict_types=1);
4
 
5
namespace PHPHtmlParser\Selector;
6
 
7
/**
8
 * This is the parser for the selector.
9
 *
10
 *
11
 */
12
class Parser implements ParserInterface
13
{
14
 
15
    /**
16
     * Pattern of CSS selectors, modified from 'mootools'
17
     *
18
     * @var string
19
     */
20
    protected $pattern = "/([\w\-:\*>]*)(?:\#([\w\-]+)|\.([\w\.\-]+))?(?:\[@?(!?[\w\-:]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
21
 
22
    /**
23
     * Parses the selector string
24
     *
25
     * @param string $selector
26
     *
27
     * @return array
28
     */
29
    public function parseSelectorString(string $selector): array
30
    {
31
        $selectors = [];
32
 
33
        $matches = [];
34
        preg_match_all($this->pattern, trim($selector).' ', $matches, PREG_SET_ORDER);
35
 
36
        // skip tbody
37
        $result = [];
38
        foreach ($matches as $match) {
39
            // default values
40
            $tag       = strtolower(trim($match[1]));
41
            $operator  = '=';
42
            $key       = null;
43
            $value     = null;
44
            $noKey     = false;
45
            $alterNext = false;
46
 
47
            // check for elements that alter the behavior of the next element
48
            if ($tag == '>') {
49
                $alterNext = true;
50
            }
51
 
52
            // check for id selector
53
            if ( ! empty($match[2])) {
54
                $key   = 'id';
55
                $value = $match[2];
56
            }
57
 
58
            // check for class selector
59
            if ( ! empty($match[3])) {
60
                $key   = 'class';
61
                $value = explode('.', $match[3]);
62
            }
63
 
64
            // and final attribute selector
65
            if ( ! empty($match[4])) {
66
                $key = strtolower($match[4]);
67
            }
68
            if ( ! empty($match[5])) {
69
                $operator = $match[5];
70
            }
71
            if ( ! empty($match[6])) {
72
                $value = $match[6];
73
                if (strpos($value, '][') !== false) {
74
                    // we have multiple type selectors
75
                    $keys = [];
76
                    $keys[] = $key;
77
                    $key = $keys;
78
                    $parts = explode('][', $value);
79
                    $value = [];
80
                    foreach ($parts as $part) {
81
                        if (strpos($part, '=') !== false) {
82
                            list($first, $second) = explode('=', $part);
83
                            $key[] = $first;
84
                            $value[] = $second;
85
                        } else {
86
                            $value[] = $part;
87
                        }
88
                    }
89
                }
90
            }
91
 
92
            // check for elements that do not have a specified attribute
93
            if (is_string($key) && isset($key[0]) && $key[0] == '!') {
94
                $key   = substr($key, 1);
95
                $noKey = true;
96
            }
97
 
98
            $result[] = [
99
                'tag'       => $tag,
100
                'key'       => $key,
101
                'value'     => $value,
102
                'operator'  => $operator,
103
                'noKey'     => $noKey,
104
                'alterNext' => $alterNext,
105
            ];
106
            if (isset($match[7]) && is_string($match[7]) && trim($match[7]) == ',') {
107
                $selectors[] = $result;
108
                $result      = [];
109
            }
110
        }
111
 
112
        // save last results
113
        if (count($result) > 0) {
114
            $selectors[] = $result;
115
        }
116
 
117
        return $selectors;
118
    }
119
}