1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
seo_page_checker.php
См. документацию.
1<?
3
6{
7 var $__site;
8 var $__url;
9 var $__lang;
11
12 var $__bCheckErrors = true;
13
15
19
20 var $__result_meta = array('KEYWORDS' => '', 'DESCRIPTION' => '');
21
23
26
28
30
31 var $bError = false;
32 var $errorString = '';
33 var $bSearch = false;
34
35 public function __construct($site, $url, $get = true, $check_errors = true)
36 {
37 global $APPLICATION;
39 global $DB;
40
41 if (CModule::IncludeModule('search'))
42 {
43 $this->bSearch = true;
44 }
45 elseif ($DB->type !== "PGSQL")
46 {
47 $APPLICATION->ThrowException(GetMessage('SEO_ERROR_NO_SEARCH'));
48 // don't return false or set bError!
49 }
50
51 $this->__bCheckErrors = $check_errors;
52
53 $this->__site = $site;
54
55 $dbRes = CSite::GetByID($this->__site);
56 if ($arRes = $dbRes->Fetch())
57 {
58 $this->__lang = $arRes['LANGUAGE_ID'];
59 $this->__server_name = $arRes['SERVER_NAME'];
60
61 if ($this->__server_name == '')
62 $this->__server_name = COption::GetOptionString('main', 'server_name', '');
63
64 if ($this->__server_name <> '')
65 {
66 $this->__url = (CMain::IsHTTPS() ? "https://" : "http://")
67 .CBXPunycode::ToASCII($this->__server_name, $e)
68 .$url;
69
70 if(!$get || $this->GetHTTPData())
71 return true;
72
73 if($this->bError && $this->errorString <> '')
74 $APPLICATION->ThrowException($this->errorString);
75
76 return false;
77 }
78 else
79 {
80 $this->bError = true;
81 $APPLICATION->ThrowException(str_replace('#SITE_ID#', $this->__site, GetMessage('SEO_ERROR_NO_SERVER_NAME')));
82 return false;
83 }
84 }
85
86 return false;
87 }
88
89 function GetHTTPData()
90 {
91 $this->__getter = new HttpClient();
92 $this->__getter->setStreamTimeout(25);
93 $this->__getter->setRedirect(true);
94
95 if ($result = $this->__getter->get($this->__url))
96 {
97 $this->__result_data = $result;
98 $headers = $this->__getter->getHeaders()->toArray();
99
100 foreach ($headers as $header)
101 {
102 $currHeader = array();
103 foreach($header['values'] as $value)
104 $currHeader[] = $value;
105 $currHeader = implode(", ", $currHeader);
106 $this->__result_headers[$header["name"]] = $currHeader;
107 }
108
109 $this->_PrepareData();
110
111 unset($this->__getter);
112 $this->bError = false;
113 return true;
114 }
115 if($errors = $this->__getter->getError())
116 $this->errorString = implode(', ', $errors);
117 unset($this->__getter);
118 $this->bError = true;
119
120 return false;
121 }
122
124 {
125 $res = array();
126 if ($this->bSearch)
127 $res = stemming(CSearch::KillTags($text), $this->__lang);
128 else
129 $res = array();
130
131 return $res;
132 }
133
134 function _PrepareData()
135 {
136 if($this->pcre_backtrack_limit === false)
137 $this->pcre_backtrack_limit = intval(ini_get("pcre.backtrack_limit"));
138 $text_len = strlen($this->__result_data);
139 $text_len++;
140 if($this->pcre_backtrack_limit > 0 && $this->pcre_backtrack_limit < $text_len)
141 {
142 @ini_set("pcre.backtrack_limit", $text_len);
143 $this->pcre_backtrack_limit = intval(ini_get("pcre.backtrack_limit"));
144 }
145
146 if($this->__bCheckErrors && $this->pcre_backtrack_limit > 0 && $this->pcre_backtrack_limit < $text_len)
147 {
148 $this->__result_errors[] = array(
149 'CODE' => 'SEO_PCRE',
150 'TYPE' => 'NOTE',
151 'DETAIL' => array(
152 '#PCRE_BACKTRACK_LIMIT#' => $this->pcre_backtrack_limit,
153 '#TEXT_LEN#' => $text_len,
154 )
155 );
156 }
157
158 $this->__index = array('TOTAL' => array(), 'BOLD' => array(), 'ITALIC' => array(), 'LINK' => array(), 'DESCRIPTION' => array(), 'KEYWORDS' => array());
159
160 // replace all images on their not empty ALT or TITLE attributes
161 $this->__result_data = preg_replace('/<img[^>]*(alt|title)=\"([^\"]*)\".*?>/is', '\\2', $this->__result_data);
162
163 if ($this->__bCheckErrors && ($img_cnt = preg_match('/<img.*?>/is', $this->__result_data)))
164 {
165 $this->__result_errors[] = array(
166 'CODE' => 'SEO_IMG_NO_ALT',
167 'TYPE' => 'NOTE',
168 'DETAIL' => array(
169 '#COUNT#' => $img_cnt
170 )
171 );
172 }
173
174 // get full words index
175 $this->__index['TOTAL'] = $this->__prepareText($this->__result_data);
176
177 // get bold words index
178 $arRes = array();
179 if(preg_match_all("/<(b|strong)>(.*?)<\\/\\1>/is", $this->__result_data, $arRes))
180 {
181 $this->__result_extended['BOLD'] = $arRes[0];
182 $this->__index['BOLD'] = $this->__prepareText(implode(" ", $arRes[2]));
183 }
184
185 // get italic words index
186 if(preg_match_all("/<(i|em)>(.*?)<\\/\\1>/is", $this->__result_data, $arRes))
187 {
188 $this->__result_extended['ITALIC'] = $arRes[0];
189 $this->__index['ITALIC'] = $this->__prepareText(implode(" ", $arRes[2]));
190 }
191
192 // get noindex tags
193 if(preg_match_all("/<(noindex)>(.*?)<\\/\\1>/is", $this->__result_data, $arRes))
194 {
195 $this->__result_extended['NOINDEX'] = $arRes[0];
196 $this->__index['NOINDEX'] = $this->__prepareText(implode(" ", $arRes[2]));
197 }
198 // get link words index
199 if(preg_match_all("/<(a) ([^>]*)>(.*?)<\\/\\1>/is", $this->__result_data, $arRes))
200 {
201 $this->__result_extended['LINK'] = $arRes[0];
202 $this->__index['LINK'] = $this->__prepareText(implode(" ", $arRes[3]));
203
204 $this->__result_extended['NOFOLLOW'] = array();
205 $this->__result_extended['LINK_EXTERNAL'] = array();
206 $this->__index['LINK_EXTERNAL'] = array();
207
208 foreach ($arRes[2] as $key => $attrs)
209 {
210 if (false !== mb_strpos($attrs, 'rel="nofollow"'))
211 $this->__result_extended['NOFOLLOW'][] = $arRes[0][$key];
212 if (false !== ($pos = mb_strpos($attrs, 'href="')))
213 {
214 $pos1 = mb_strpos($attrs, '"', $pos + 6);
215 $url = mb_substr($attrs, $pos, $pos1 - $pos);
216
217 if ($this->IsOuterUrl($url))
218 {
219 $this->__index['LINK_EXTERNAL'] = array_merge($this->__index['LINK_EXTERNAL'], $this->__prepareText($arRes[3][$key]));
220 $this->__result_extended['LINK_EXTERNAL'][] = $arRes[0][$key];
221 }
222 }
223 }
224
225 if ($this->__bCheckErrors && count($arRes[0]) > $this->__qualifier_links_count)
226 {
227 $this->__result_errors[] = array(
228 'CODE' => 'SEO_LINKS_COUNT',
229 'TYPE' => 'NOTE',
230 'DETAIL' => array(
231 '#COUNT#' => count($arRes[0]),
232 '#COUNT_EXTERNAL#' => count($this->__result_extended['LINK_EXTERNAL']),
233 '#QUALIFIER#' => $this->__qualifier_links_count,
234 )
235 );
236 }
237
238 }
239
240 // get meta description words index
241 if(preg_match('/<meta.*?name=\"description\".*?content=\"([^\"]+)\"[^>]*>/i', $this->__result_data, $arRes))
242 {
243 $this->__result_meta['DESCRIPTION'] = $arRes[1];
244 $this->__result_extended['META_DESCRIPTION'] = $arRes[0];
245 $this->__index['DESCRIPTION'] = $this->__prepareText($this->__result_meta['DESCRIPTION']);
246 }
247 else
248 {
249 $this->__result_errors[] = array(
250 'CODE' => 'SEO_META_NO_DESCRIPTION',
251 'TYPE' => 'NOTE',
252 'DETAIL' => array()
253 );
254 }
255
256 // get meta keywords words index
257 if(preg_match('/<meta.*?name=\"keywords\".*?content=\"([^\"]+)\"[^>]*>/i', $this->__result_data, $arRes))
258 {
259 $this->__result_meta['KEYWORDS'] = $arRes[1];
260 $this->__result_extended['META_KEYWORDS'] = $arRes[0];
261 $this->__index['KEYWORDS'] = $this->__prepareText($this->__result_meta['KEYWORDS']);
262 }
263 else
264 {
265 $this->__result_errors[] = array(
266 'CODE' => 'SEO_META_NO_KEYWORDS',
267 'TYPE' => 'NOTE',
268 'DETAIL' => array()
269 );
270 }
271
272 // get titles words index
273 if(preg_match("/<(title)>(.*?)<\\/\\1>/is", $this->__result_data, $arRes))
274 {
275 $this->__result_extended['TITLE'] = $arRes[0];
276 $this->__index['TITLE'] = $this->__prepareText($arRes[2]);
277 }
278
279 if(preg_match_all("/<(h[\d]{1}).*?>.*?<\\/\\1>/is", $this->__result_data, $arRes))
280 {
281 $this->__result_extended['H'] = $arRes[0];
282 }
283
284 if(preg_match_all("/<(h1).*?>(.*?)<\\/\\1>/is", $this->__result_data, $arRes))
285 {
286 if ($this->__bCheckErrors && count($arRes[0]) > 1)
287 {
288 $this->__result_errors[] = array(
289 'CODE' => 'SEO_H1_UNIQUE',
290 'TYPE' => 'NOTE',
291 'DETAIL' => array(
292 '#COUNT#' => count($arRes[0]),
293 '#VALUES#' => htmlspecialcharsbx('"'.implode('", "', $arRes[2]).'"'),
294 )
295 );
296 }
297
298 $this->__index['H1'] = $this->__prepareText(implode(" ", $arRes[2]));
299 }
300 elseif ($this->__bCheckErrors)
301 {
302 $this->__result_errors[] = array(
303 'CODE' => 'SEO_H1_ABSENT',
304 'TYPE' => 'NOTE',
305 'DETAIL' => array()
306 );
307 }
308
309 if ($this->__bCheckErrors)
310 {
311 foreach(GetModuleEvents('seo', 'onPageCheck', true) as $arEvent)
312 {
313 if (!ExecuteModuleEventEx($arEvent, array(
314 array(
315 'URL' => $this->__url,
316 'LANG' => $this->__lang,
317 'SERVER_NAME' => $this->__server_name,
318 'SITE' => $this->__site,
319 ),
320 array(
321 'HEADERS' => $this->__result_headers,
322 'BODY' => $this->__result_data,
323 ),
324 $this->__result_meta,
325 $this->__index,
326 )) && ($ex = $GLOBALS['APPLICATION']->GetException()))
327 {
328 $this->__result_errors[] = array(
329 'CODE' => $ex->GetId(),
330 'TYPE' => 'NOTE',
331 'TEXT' => $ex->GetString(),
332 );
333 }
334 }
335 }
336 }
337
338 function _GetContrast($word)
339 {
340 if (null == $this->__index_total_len)
341 $this->__index_total_len = array_sum($this->__index['TOTAL']);
342
343 $logDocLength = log($this->__index_total_len < 20 ? 20 : $this->__index_total_len);
344
345 $count = intval($this->__index['TOTAL'][$word]);
346
347 return log($count+1)/$logDocLength;
348 }
349
350 function GetStatistics()
351 {
352 if (!is_array($this->__index))
353 return false;
354
355 if (null == $this->__index_total_len)
356 $this->__index_total_len = array_sum($this->__index['TOTAL']);
357
358 return array(
359 'URL' => $this->__url,
360 'TOTAL_LENGTH' => strlen($this->__result_data),
361 'TOTAL_WORDS_COUNT' => $this->__index_total_len ? $this->__index_total_len : '-',
362 'UNIQUE_WORDS_COUNT' => $this->__index_total_len ? count($this->__index['TOTAL']) : '-',
363 'META_KEYWORDS' => $this->__result_meta['KEYWORDS'],
364 'META_DESCRIPTION' => $this->__result_meta['DESCRIPTION'],
365 );
366 }
367
368 function GetURL()
369 {
370 return $this->__url;
371 }
372
373 function CheckKeyword($keyword, $bStemmed = false)
374 {
375 if (!is_array($this->__index))
376 return false;
377
378 if (is_array($keyword))
379 {
380 $arResult = array();
381
382 foreach ($keyword as $key => $word)
383 {
384 $arResult[$key] = $this->CheckKeyword($bStemmed ? $key : $word, $bStemmed);
385 }
386 return $arResult;
387 }
388
389 if (!$bStemmed && $this->bSearch)
390 $keyword = stemming($keyword, $this->__lang);
391
392 if (is_array($keyword))
393 return $this->CheckKeyword($keyword, true);
394
396 'TOTAL' => intval($this->__index['TOTAL'][$keyword]),
397 'BOLD' => intval($this->__index['BOLD'][$keyword]),
398 'ITALIC' => intval($this->__index['ITALIC'][$keyword]),
399 'LINK' => intval($this->__index['LINK'][$keyword]),
400 'LINK_EXTERNAL' => intval($this->__index['LINK_EXTERNAL'][$keyword]),
401 'DESCRIPTION' => intval($this->__index['DESCRIPTION'][$keyword]),
402 'KEYWORDS' => intval($this->__index['KEYWORDS'][$keyword]),
403 'TITLE' => intval($this->__index['TITLE'][$keyword]),
404 'H1' => intval($this->__index['H1'][$keyword]),
405
406 'CONTRAST' => $this->_GetContrast($keyword),
407 );
408
409 return $arResult;
410 }
411
413 {
414 return array_merge(array('HEADERS' => $this->__result_headers), $this->__result_extended);
415 }
416
417 function GetErrors()
418 {
419 $arResult = false;
420
421 if (count($this->__result_errors) > 0)
422 {
423 $arResult = array();
424
425 foreach ($this->__result_errors as $arError)
426 {
427 $arResult[] = array(
428 'CODE' => $arError['CODE'],
429 'TYPE' => $arError['TYPE'],
430 'TEXT' => isset($arError['TEXT']) ? $arError['TEXT'] : str_replace(array_keys($arError['DETAIL']), array_values($arError['DETAIL']), GetMessage($arError['CODE'].'_ERROR')),
431 );
432 }
433 }
434
435 return $arResult;
436 }
437
438 function IsOuterUrl($url)
439 {
440 if (strncmp($url, '#', 1) === 0) return false;
441 if (strncmp($url, 'mailto:', 7) === 0) return false;
442 if (strncmp($url, 'javascript:', 11) === 0) return false;
443
444 $pos = mb_strpos($url, '://');
445 if ($pos === false) return false;
446
447 static $arDomainNames = null;
448
449 if (null == $arDomainNames)
450 {
451 $arDomainNames = array($_SERVER['SERVER_NAME']);
452
453 $dbRes = CSite::GetList('sort', 'asc', array('ACTIVE' => 'Y'));
454 while ($arSite = $dbRes->Fetch())
455 {
456 if ($arSite['DOMAINS'])
457 $arDomainNames = array_merge($arDomainNames, explode("\r\n", $arSite['DOMAINS']));
458 }
459
460 $arDomainNames = array_values(array_unique($arDomainNames));
461 }
462
463 $url = mb_substr($url, $pos + 3);
464 $pos = mb_strpos($url, '/');
465
466 if ($pos === false)
467 {
468 $pos = mb_strlen($url);
469 }
470
471 $domain = mb_substr($url, 0, $pos);
472 if (mb_substr($domain, 0, 4) == 'www.')
473 {
474 $domain = mb_substr($domain, 4);
475 }
476
477 if ($domain)
478 return !in_array($domain, $arDomainNames);
479
480 return false;
481 }
482}
483?>
$count
Определения admin_tab.php:4
global $APPLICATION
Определения include.php:80
$arResult
Определения generate_coupon.php:16
static KillTags($str)
Определения search.php:2092
static ToASCII($domainName, &$arErrors)
Определения punycode.php:44
$__result_errors
Определения seo_page_checker.php:22
$__result_extended
Определения seo_page_checker.php:18
GetExtendedData()
Определения seo_page_checker.php:412
$__bCheckErrors
Определения seo_page_checker.php:12
$__server_name
Определения seo_page_checker.php:10
$__result_headers
Определения seo_page_checker.php:16
$__index_total_len
Определения seo_page_checker.php:25
$errorString
Определения seo_page_checker.php:32
$__site
Определения seo_page_checker.php:7
_PrepareData()
Определения seo_page_checker.php:134
GetErrors()
Определения seo_page_checker.php:417
GetHTTPData()
Определения seo_page_checker.php:89
$__qualifier_links_count
Определения seo_page_checker.php:29
CheckKeyword($keyword, $bStemmed=false)
Определения seo_page_checker.php:373
__prepareText($text)
Определения seo_page_checker.php:123
GetStatistics()
Определения seo_page_checker.php:350
$__getter
Определения seo_page_checker.php:14
$__result_meta
Определения seo_page_checker.php:20
$__result_data
Определения seo_page_checker.php:17
$pcre_backtrack_limit
Определения seo_page_checker.php:27
_GetContrast($word)
Определения seo_page_checker.php:338
$__lang
Определения seo_page_checker.php:9
IsOuterUrl($url)
Определения seo_page_checker.php:438
GetURL()
Определения seo_page_checker.php:368
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$result
Определения get_property_values.php:14
$errors
Определения iblock_catalog_edit.php:74
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
global $DB
Определения cron_frame.php:29
ExecuteModuleEventEx($arEvent, $arParams=[])
Определения tools.php:5214
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
Определения tools.php:2701
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
Определения tools.php:5177
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
GetMessage($name, $aReplace=null)
Определения tools.php:3397
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
$text
Определения template_pdf.php:79
</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
$arRes
Определения options.php:104
stemming($sText, $sLang='ru', $bIgnoreStopWords=false, $bReturnPositions=false)
Определения stemming.php:148
$GLOBALS['_____370096793']
Определения update_client.php:1
$url
Определения iframe.php:7
$dbRes
Определения yandex_detail.php:168
$site
Определения yandex_run.php:614