1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
urlrewriter.php
См. документацию.
1<?php
2
3namespace Bitrix\Main;
4
6{
7 const DEFAULT_SORT = 100;
8
9 protected static function loadRules($siteId)
10 {
11 $site = SiteTable::getRow(["filter" => ["=LID" => $siteId], "cache" => ["ttl" => 3600]]);
12 $docRoot = $site["DOC_ROOT"];
13
14 if (!empty($docRoot))
15 {
16 $docRoot = IO\Path::normalize($docRoot);
17 }
18 else
19 {
21 }
22
23 $arUrlRewrite = [];
24
25 if (IO\File::isFileExists($docRoot . "/urlrewrite.php"))
26 {
27 include($docRoot . "/urlrewrite.php");
28 }
29
30 foreach ($arUrlRewrite as &$rule)
31 {
32 if (!isset($rule["SORT"]))
33 {
34 $rule["SORT"] = self::DEFAULT_SORT;
35 }
36 }
37
38 return $arUrlRewrite;
39 }
40
41 protected static function saveRules($siteId, array $urlRewrite)
42 {
43 $site = SiteTable::getRow(["filter" => ["=LID" => $siteId], "cache" => ["ttl" => 3600]]);
44 $docRoot = $site["DOC_ROOT"];
45
46 if (!empty($docRoot))
47 {
48 $docRoot = IO\Path::normalize($docRoot);
49 }
50 else
51 {
53 }
54
55 $data = var_export($urlRewrite, true);
56
57 $event = new Event("main", "onUrlRewriteSaveRules", [
58 $siteId,
60 $urlRewrite,
61 ]);
62 $event->send();
63
64 $filename = $docRoot . "/urlrewrite.php";
65 IO\File::putFileContents($filename, "<" . "?php\n\$arUrlRewrite=" . $data . ";\n");
67 }
68
69 public static function getList($siteId, $filter = [], $order = [])
70 {
71 if (empty($siteId))
72 {
73 throw new ArgumentNullException("siteId");
74 }
75
76 $urlRewrite = static::loadRules($siteId);
77
78 $result = [];
79 $resultKeys = self::filterRules($urlRewrite, $filter);
80 foreach ($resultKeys as $key)
81 {
82 $result[] = $urlRewrite[$key];
83 }
84
85 if (!empty($order) && !empty($result))
86 {
87 $orderKeys = array_keys($order);
88 $orderBy = array_shift($orderKeys);
89 $orderDir = $order[$orderBy];
90
91 $orderBy = mb_strtoupper($orderBy);
92 $orderDir = mb_strtoupper($orderDir);
93
94 $orderDir = (($orderDir == "DESC") ? SORT_DESC : SORT_ASC);
95
96 $ar = [];
97 foreach ($result as $key => $row)
98 {
99 $ar[$key] = $row[$orderBy];
100 }
101
102 array_multisort($ar, $orderDir, $result);
103 }
104
105 return $result;
106 }
107
108 protected static function filterRules(array $urlRewrite, array $filter)
109 {
110 $resultKeys = [];
111
112 foreach ($urlRewrite as $keyRule => $rule)
113 {
114 $isMatched = true;
115 foreach ($filter as $keyFilter => $valueFilter)
116 {
117 $isNegative = false;
118 if (str_starts_with($keyFilter, "!"))
119 {
120 $isNegative = true;
121 $keyFilter = mb_substr($keyFilter, 1);
122 }
123
124 if ($keyFilter === 'QUERY')
125 {
126 $isMatchedTmp = preg_match($rule["CONDITION"], $valueFilter);
127 }
128 elseif ($keyFilter === 'CONDITION')
129 {
130 $isMatchedTmp = ($rule["CONDITION"] == $valueFilter);
131 }
132 elseif ($keyFilter === 'ID')
133 {
134 $isMatchedTmp = (isset($rule["ID"]) && ($rule["ID"] == $valueFilter));
135 }
136 elseif ($keyFilter === 'PATH')
137 {
138 $isMatchedTmp = ($rule["PATH"] == $valueFilter);
139 }
140 else
141 {
142 throw new ArgumentException("arFilter");
143 }
144
145 $isMatched = ($isNegative xor $isMatchedTmp);
146
147 if (!$isMatched)
148 {
149 break;
150 }
151 }
152
153 if ($isMatched)
154 {
155 $resultKeys[] = $keyRule;
156 }
157 }
158
159 return $resultKeys;
160 }
161
162 protected static function recordsCompare($a, $b)
163 {
164 $sortA = isset($a["SORT"]) ? intval($a["SORT"]) : self::DEFAULT_SORT;
165 $sortB = isset($b["SORT"]) ? intval($b["SORT"]) : self::DEFAULT_SORT;
166
167 if ($sortA > $sortB)
168 {
169 return 1;
170 }
171 elseif ($sortA < $sortB)
172 {
173 return -1;
174 }
175
176 $lenA = mb_strlen($a["CONDITION"]);
177 $lenB = mb_strlen($b["CONDITION"]);
178 if ($lenA < $lenB)
179 {
180 return 1;
181 }
182 elseif ($lenA > $lenB)
183 {
184 return -1;
185 }
186 else
187 {
188 return 0;
189 }
190 }
191
192 public static function add($siteId, $fields)
193 {
194 if (empty($siteId))
195 {
196 throw new ArgumentNullException("siteId");
197 }
198
199 $urlRewrite = static::loadRules($siteId);
200
201 // if rule is exist – return
202 foreach ($urlRewrite as $rule)
203 {
204 if ($fields["CONDITION"] == $rule["CONDITION"])
205 {
206 return;
207 }
208 }
209
210 $urlRewrite[] = [
211 "CONDITION" => $fields["CONDITION"],
212 "RULE" => $fields["RULE"],
213 "ID" => $fields["ID"],
214 "PATH" => $fields["PATH"],
215 "SORT" => isset($fields["SORT"]) ? intval($fields["SORT"]) : self::DEFAULT_SORT,
216 ];
217
218 uasort($urlRewrite, ['\Bitrix\Main\UrlRewriter', "recordsCompare"]);
219
220 static::saveRules($siteId, $urlRewrite);
221 }
222
223 public static function update($siteId, $filter, $fields)
224 {
225 if (empty($siteId))
226 {
227 throw new ArgumentNullException("siteId");
228 }
229
230 $urlRewrite = static::loadRules($siteId);
231
232 $resultKeys = self::filterRules($urlRewrite, $filter);
233 foreach ($resultKeys as $key)
234 {
235 if (array_key_exists("CONDITION", $fields))
236 {
237 $urlRewrite[$key]["CONDITION"] = $fields["CONDITION"];
238 }
239 if (array_key_exists("RULE", $fields))
240 {
241 $urlRewrite[$key]["RULE"] = $fields["RULE"];
242 }
243 if (array_key_exists("ID", $fields))
244 {
245 $urlRewrite[$key]["ID"] = $fields["ID"];
246 }
247 if (array_key_exists("PATH", $fields))
248 {
249 $urlRewrite[$key]["PATH"] = $fields["PATH"];
250 }
251 if (array_key_exists("SORT", $fields))
252 {
253 $urlRewrite[$key]["SORT"] = intval($fields["SORT"]);
254 }
255 }
256
257 uasort($urlRewrite, ['\Bitrix\Main\UrlRewriter', "recordsCompare"]);
258
259 static::saveRules($siteId, $urlRewrite);
260 }
261
262 public static function delete($siteId, $filter)
263 {
264 if (empty($siteId))
265 {
266 throw new ArgumentNullException("siteId");
267 }
268
269 $urlRewrite = static::loadRules($siteId);
270
271 $resultKeys = self::filterRules($urlRewrite, $filter);
272 foreach ($resultKeys as $key)
273 {
274 unset($urlRewrite[$key]);
275 }
276
277 uasort($urlRewrite, ['\Bitrix\Main\UrlRewriter', "recordsCompare"]);
278
279 static::saveRules($siteId, $urlRewrite);
280 }
281
282 public static function reindexAll($maxExecutionTime = 0, $ns = [])
283 {
284 @set_time_limit(0);
285 if (!is_array($ns))
286 {
287 $ns = [];
288 }
289
290 if ($maxExecutionTime <= 0)
291 {
292 $nsOld = $ns;
293 $ns = [
294 "CLEAR" => "N",
295 "ID" => "",
296 "FLG" => "",
297 "SESS_ID" => md5(uniqid()),
298 "max_execution_time" => $nsOld["max_execution_time"],
299 "stepped" => $nsOld["stepped"],
300 "max_file_size" => $nsOld["max_file_size"],
301 ];
302
303 if (!empty($nsOld["SITE_ID"]))
304 {
305 $ns["SITE_ID"] = $nsOld["SITE_ID"];
306 }
307 }
308 $ns["CNT"] = intval($ns["CNT"] ?? 0);
309
310 $sites = [];
311 $filterRootPath = "";
312
313 $db = SiteTable::getList(
314 [
315 "select" => ["LID", "DOC_ROOT", "DIR"],
316 "filter" => ["=ACTIVE" => "Y"],
317 ]
318 );
319 while ($ar = $db->fetch())
320 {
321 if (empty($ar["DOC_ROOT"]))
322 {
323 $ar["DOC_ROOT"] = Application::getDocumentRoot();
324 }
325
326 $sites[] = [
327 "site_id" => $ar["LID"],
328 "root" => $ar["DOC_ROOT"],
329 "path" => IO\Path::combine($ar["DOC_ROOT"], $ar["DIR"]),
330 ];
331
332 if (!empty($ns["SITE_ID"]) && $ns["SITE_ID"] == $ar["LID"])
333 {
334 $filterRootPath = $ar["DOC_ROOT"];
335 }
336 }
337
338 if (!empty($ns["SITE_ID"]) && !empty($filterRootPath))
339 {
340 $sitesTmp = [];
341 $keys = array_keys($sites);
342 foreach ($keys as $key)
343 {
344 if ($sites[$key]["root"] == $filterRootPath)
345 {
346 $sitesTmp[] = $sites[$key];
347 }
348 }
349 $sites = $sitesTmp;
350 }
351
352 uasort($sites,
353 function ($a, $b) {
354 $la = mb_strlen($a["path"]);
355 $lb = mb_strlen($b["path"]);
356 if ($la == $lb)
357 {
358 if ($a["site_id"] == $b["site_id"])
359 {
360 return 0;
361 }
362 else
363 {
364 return ($a["site_id"] > $b["site_id"]) ? -1 : 1;
365 }
366 }
367 return ($la > $lb) ? -1 : 1;
368 }
369 );
370
371 if ($ns["CLEAR"] != "Y")
372 {
373 $alreadyDeleted = [];
374 foreach ($sites as $site)
375 {
377 if (!in_array($site["root"], $alreadyDeleted))
378 {
379 static::delete(
380 $site["site_id"],
381 ["!ID" => ""]
382 );
383 $alreadyDeleted[] = $site["root"];
384 }
385 }
386 }
387 $ns["CLEAR"] = "Y";
388
389 clearstatcache();
390
391 $alreadyParsed = [];
392 foreach ($sites as $site)
393 {
394 if (in_array($site["root"], $alreadyParsed))
395 {
396 continue;
397 }
398 $alreadyParsed[] = $site["root"];
399
400 if ($maxExecutionTime > 0 && !empty($ns["FLG"])
401 && mb_substr($ns["ID"] . "/", 0, mb_strlen($site["root"] . "/")) != $site["root"] . "/")
402 {
403 continue;
404 }
405
406 static::recursiveReindex($site["root"], "/", $sites, $maxExecutionTime, $ns);
407
408 if ($maxExecutionTime > 0 && !empty($ns["FLG"]))
409 {
410 return $ns;
411 }
412 }
413
414 return $ns["CNT"];
415 }
416
417 protected static function recursiveReindex($rootPath, $path, $sites, $maxExecutionTime, &$ns)
418 {
419 $pathAbs = IO\Path::combine($rootPath, $path);
420
421 $siteId = "";
422 foreach ($sites as $site)
423 {
424 if (str_starts_with($pathAbs . "/", $site["path"] . "/"))
425 {
426 $siteId = $site["site_id"];
427 break;
428 }
429 }
430 if (empty($siteId))
431 {
432 return 0;
433 }
434
435 $dir = new IO\Directory($pathAbs, $siteId);
436 if (!$dir->isExists())
437 {
438 return 0;
439 }
440
441 $children = $dir->getChildren();
442 foreach ($children as $child)
443 {
444 if ($child->isDirectory())
445 {
446 if ($child->isSystem())
447 {
448 continue;
449 }
450
451 //this is not first step, and we had stopped here, so go on to reindex
452 if ($maxExecutionTime <= 0
453 || $ns["FLG"] == ''
454 || str_starts_with($ns["ID"] . "/", $child->getPath() . "/")
455 )
456 {
457 if (static::recursiveReindex($rootPath, mb_substr($child->getPath(), mb_strlen($rootPath)), $sites, $maxExecutionTime, $ns) === false)
458 {
459 return false;
460 }
461 }
462 }
463 else
464 {
465 //not the first step and we found last file from previos one
466 if ($maxExecutionTime > 0 && $ns["FLG"] <> ''
467 && $ns["ID"] == $child->getPath())
468 {
469 $ns["FLG"] = "";
470 }
471 elseif (empty($ns["FLG"]))
472 {
473 $ID = static::reindexFile($siteId, $rootPath, mb_substr($child->getPath(), mb_strlen($rootPath)), $ns["max_file_size"]);
474 if ($ID)
475 {
476 $ns["CNT"] = intval($ns["CNT"]) + 1;
477 }
478 }
479
480 if ($maxExecutionTime > 0
481 && (microtime(true) - START_EXEC_TIME > $maxExecutionTime))
482 {
483 $ns["FLG"] = "Y";
484 $ns["ID"] = $child->getPath();
485 return false;
486 }
487 }
488 }
489 return true;
490 }
491
492 public static function reindexFile($siteId, $rootPath, $path, $maxFileSize = 0)
493 {
494 $pathAbs = IO\Path::combine($rootPath, $path);
495
496 if (!static::checkPath($pathAbs))
497 {
498 return 0;
499 }
500
501 $file = new IO\File($pathAbs);
502 if ($maxFileSize > 0 && $file->getSize() > $maxFileSize * 1024)
503 {
504 return 0;
505 }
506
507 $fileSrc = $file->getContents();
508
509 if (!$fileSrc || $fileSrc == "")
510 {
511 return 0;
512 }
513
514 $components = \PHPParser::parseScript($fileSrc);
515
516 for ($i = 0, $cnt = count($components); $i < $cnt; $i++)
517 {
518 $sef = (isset($components[$i]["DATA"]["PARAMS"]["SEF_MODE"]) && $components[$i]["DATA"]["PARAMS"]["SEF_MODE"] == "Y");
519
521 [
522 'SITE_ID' => $siteId,
523 'COMPONENT_NAME' => $components[$i]["DATA"]["COMPONENT_NAME"],
524 'TEMPLATE_NAME' => $components[$i]["DATA"]["TEMPLATE_NAME"],
525 'REAL_PATH' => $path,
526 'SEF_MODE' => ($sef ? Component\ParametersTable::SEF_MODE : Component\ParametersTable::NOT_SEF_MODE),
527 'SEF_FOLDER' => ($sef ? $components[$i]["DATA"]["PARAMS"]["SEF_FOLDER"] : null),
528 'START_CHAR' => $components[$i]["START"],
529 'END_CHAR' => $components[$i]["END"],
530 'PARAMETERS' => serialize($components[$i]["DATA"]["PARAMS"]),
531 ]
532 );
533
534 if ($sef)
535 {
536 if (array_key_exists("SEF_RULE", $components[$i]["DATA"]["PARAMS"]))
537 {
538 $ruleMaker = new UrlRewriterRuleMaker;
539 $ruleMaker->process($components[$i]["DATA"]["PARAMS"]["SEF_RULE"]);
540
541 $fields = [
542 "CONDITION" => $ruleMaker->getCondition(),
543 "RULE" => $ruleMaker->getRule(),
544 "ID" => $components[$i]["DATA"]["COMPONENT_NAME"],
545 "PATH" => $path,
546 "SORT" => self::DEFAULT_SORT,
547 ];
548 }
549 else
550 {
551 $fields = [
552 "CONDITION" => "#^" . $components[$i]["DATA"]["PARAMS"]["SEF_FOLDER"] . "#",
553 "RULE" => "",
554 "ID" => $components[$i]["DATA"]["COMPONENT_NAME"],
555 "PATH" => $path,
556 "SORT" => self::DEFAULT_SORT,
557 ];
558 }
559
560 static::add($siteId, $fields);
561 }
562 }
563
564 return true;
565 }
566
567 public static function checkPath($path)
568 {
569 static $searchMasksCache = false;
570
571 if (is_array($searchMasksCache))
572 {
573 $exclude = $searchMasksCache["exc"];
574 $include = $searchMasksCache["inc"];
575 }
576 else
577 {
578 $exclude = [];
579 $include = [];
580
581 $inc = Config\Option::get("main", "urlrewrite_include_mask", "*.php");
582 $inc = str_replace("'", "\\'", str_replace("*", ".*?", str_replace("?", ".", str_replace(".", "\\.", str_replace("\\", "/", $inc)))));
583 $incTmp = explode(";", $inc);
584 foreach ($incTmp as $pregMask)
585 {
586 if (trim($pregMask) <> '')
587 {
588 $include[] = "'^" . trim($pregMask) . "$'";
589 }
590 }
591
592 $exc = Config\Option::get("main", "urlrewrite_exclude_mask", "/bitrix/*;");
593 $exc = str_replace("'", "\\'", str_replace("*", ".*?", str_replace("?", ".", str_replace(".", "\\.", str_replace("\\", "/", $exc)))));
594 $excTmp = explode(";", $exc);
595 foreach ($excTmp as $pregMask)
596 {
597 if (trim($pregMask) <> '')
598 {
599 $exclude[] = "'^" . trim($pregMask) . "$'";
600 }
601 }
602
603 $searchMasksCache = ["exc" => $exclude, "inc" => $include];
604 }
605
606 $file = IO\Path::getName($path);
607 if (str_starts_with($file, "."))
608 {
609 return 0;
610 }
611
612 foreach ($exclude as $pregMask)
613 {
614 if (preg_match($pregMask, $path))
615 {
616 return false;
617 }
618 }
619
620 foreach ($include as $pregMask)
621 {
622 if (preg_match($pregMask, $path))
623 {
624 return true;
625 }
626 }
627
628 return false;
629 }
630}
$path
Определения access_edit.php:21
static resetAccelerator(string $filename=null)
Определения application.php:786
static getDocumentRoot()
Определения application.php:736
static deleteBySiteId($siteId)
Определения parameters.php:77
Определения event.php:5
static getRow(array $parameters)
Определения datamanager.php:398
static getList(array $parameters=array())
Определения datamanager.php:431
static add(array $data)
Определения datamanager.php:877
static recursiveReindex($rootPath, $path, $sites, $maxExecutionTime, &$ns)
Определения urlrewriter.php:417
static reindexAll($maxExecutionTime=0, $ns=[])
Определения urlrewriter.php:282
static recordsCompare($a, $b)
Определения urlrewriter.php:162
static update($siteId, $filter, $fields)
Определения urlrewriter.php:223
const DEFAULT_SORT
Определения urlrewriter.php:7
static reindexFile($siteId, $rootPath, $path, $maxFileSize=0)
Определения urlrewriter.php:492
static add($siteId, $fields)
Определения urlrewriter.php:192
static saveRules($siteId, array $urlRewrite)
Определения urlrewriter.php:41
static checkPath($path)
Определения urlrewriter.php:567
static getList($siteId, $filter=[], $order=[])
Определения urlrewriter.php:69
static loadRules($siteId)
Определения urlrewriter.php:9
static filterRules(array $urlRewrite, array $filter)
Определения urlrewriter.php:108
$sites
Определения clear_component_cache.php:15
$children
Определения sync.php:12
$data['IS_AVAILABLE']
Определения .description.php:13
$filename
Определения file_edit.php:47
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
if($ajaxMode) $ID
Определения get_user.php:27
$filter
Определения iblock_catalog_list.php:54
$docRoot
Определения options.php:20
$arUrlRewrite
Определения urlrewrite.php:55
$siteId
Определения ajax.php:8
const START_EXEC_TIME
Определения start.php:12
Определения directory.php:3
$order
Определения payment.php:8
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$ar
Определения options.php:199
$dir
Определения quickway.php:303
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
else $a
Определения template.php:137
$site
Определения yandex_run.php:614
$fields
Определения yandex_run.php:501
$maxExecutionTime
Определения yandex_setup.php:647