Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
queryengine.php
1<?php
2namespace Bitrix\Main\Web\DOM;
3
4abstract class QueryEngine
5{
6 const DIR_DOWN = 0;
7 const DIR_UP = 1;
8 const FILTER_NODE_TYPE = 'nodeType';
9 const FILTER_NODE_NAME = 'nodeName';
10 const FILTER_ATTR = 'attr';
11 const FILTER_ATTR_VALUE = 'attrValue';
12 const FILTER_ATTR_CLASS_NAME = 'attrClassName';
13
20
21 protected $limit = null;
22 protected $deep = true;
24
25 private static $querySelectorEngine;
26
27 public static function getQuerySelectorEngine()
28 {
29 if (self::$querySelectorEngine == null)
30 {
31 self::$querySelectorEngine = new QuerySelectorEngine();
32 }
33
34 return self::$querySelectorEngine;
35 }
36
37 protected function isNodeFiltered(Node $node, array $filter)
38 {
39 $isFiltered = false;
40 foreach($filter as $filterItem)
41 {
42 foreach($filterItem as $type => $value)
43 {
44 switch($type)
45 {
47
48 if (!is_array($value))
49 {
50 $value = array($value);
51 }
52
53 foreach($value as $nodeType)
54 {
55 if(!$node->getNodeType() === $nodeType)
56 {
57 return false;
58 }
59 else
60 {
61 $isFiltered = true;
62 }
63 }
64 break;
65
67 if(mb_strtoupper($value) === $node->getNodeName())
68 {
69 $isFiltered = true;
70 }
71 else
72 {
73 return false;
74 }
75 break;
76
78 if(!$node->hasAttributes())
79 {
80 $isFiltered = false;
81 }
82 else
83 {
84 if (!is_array($value))
85 {
86 $value = array($value);
87 }
88
89 foreach($value as $attrName)
90 {
91 /* @var $node Element*/
92 if($node->getAttribute($attrName) === null)
93 {
94 return false;
95 }
96 else
97 {
98 $isFiltered = true;
99 }
100 }
101 }
102 break;
103
105 if(!$node->hasAttributes())
106 {
107 $isFiltered = false;
108 }
109 else
110 {
111 foreach($value as $attr)
112 {
113 $attrValue = $node->getAttribute($attr['name']);
114 if(!$attrValue)
115 {
116 continue;
117 }
118
119 $operationValue = $attr['value'];
120 switch($attr['operation'])
121 {
123
124 if($attrValue === $operationValue)
125 {
126 return false;
127 }
128 break;
129
131
132 if(mb_strpos($attrValue, $operationValue) === false)
133 {
134 return false;
135 }
136 break;
137
139
140 if(mb_substr($attrValue, -mb_strlen($operationValue)) !== $operationValue)
141 {
142 return false;
143 }
144 break;
145
147
148 if(mb_strpos($attrValue, $operationValue) !== 0)
149 {
150 return false;
151 }
152 break;
153
155
156 throw new DomException('Not supported query filter: FILTER_OPERATION_CONTAIN_WORD');
157 break;
158
160 default:
161 if($attrValue !== $operationValue)
162 {
163 return false;
164 }
165
166 }
167
168 $isFiltered = true;
169 }
170 }
171 break;
172
174 if(!$node->hasAttributes())
175 {
176 $isFiltered = false;
177 }
178 else
179 {
180 if (!is_array($value))
181 {
182 $value = array($value);
183 }
184
185 foreach($value as $className)
186 {
187 if(!in_array($className, $node->getClassList()))
188 {
189 return false;
190 }
191 else
192 {
193 $isFiltered = true;
194 }
195 }
196 }
197 break;
198 }
199 }
200 }
201
202 return $isFiltered;
203 }
204
205 public function walk(array $filter = null, callable $callback = null, Node $node, $limit = 0, $direction = self::DIR_DOWN)
206 {
207 if($limit > 0)
208 {
209 $this->limit = $limit;
210 }
211 else
212 {
213 $this->limit = null;
214 }
215
216 $this->deep = true;
217 $this->direction = $direction;
218
219 return $this->walkInternal($filter, $callback, $node, $callback, $direction);
220 }
221
222
223 protected function walkInternal(array $filter = null, callable $callback = null, Node $node)
224 {
225 $resultList = array();
226 if($node->hasChildNodes())
227 {
228 foreach($node->getChildNodesArray() as $childNode)
229 {
230 if($callback)
231 {
232 $flag = call_user_func_array($callback, array($childNode, $filter));
233 }
234 elseif($filter)
235 {
236 $flag = $this->isNodeFiltered($childNode, $filter);
237 }
238 else
239 {
240 break;
241 }
242
243 if($flag === true)
244 {
245 // save node to result list
246 $resultList[] = $childNode;
247
248 // check limit of results
249 if($this->limit !== null)
250 {
251 --$this->limit;
252 if($this->limit <= 0)
253 {
254 break;
255 }
256 }
257
258 // check search only in child list
259 if(!$this->deep)
260 {
261 continue;
262 }
263 }
264
265 $resultList = array_merge(
266 $resultList,
267 $this->walkInternal($filter, $callback, $childNode, $callback)
268 );
269 }
270 }
271
272 return $resultList;
273 }
274
275 abstract public function query($queryString = "", Node $node, $limit = 0, $direction = self::DIR_DOWN);
276}
walk(array $filter=null, callable $callback=null, Node $node, $limit=0, $direction=self::DIR_DOWN)
isNodeFiltered(Node $node, array $filter)
walkInternal(array $filter=null, callable $callback=null, Node $node)
query($queryString="", Node $node, $limit=0, $direction=self::DIR_DOWN)