Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
Job.php
1<?php
2
3namespace Bitrix\Seo\Sitemap;
4
13
14Loc::loadMessages(__DIR__ . '/../../admin/seo_sitemap.php');
15
19class Job
20{
21 protected const AGENT_FUNCTION = 'doJobAgent';
22 protected const AGENT_INTERVAL = 1;
23 protected const AGENT_DELAY = 60;
24
25 protected const LOCK_MAX_INTERVAL = 300;
26
30 protected const PROGRESS_WIDTH = 500;
31
35 public const STATUS_REGISTER = 'R';
36 public const STATUS_PROCESS = 'P';
37 public const STATUS_FINISH = 'F';
38 public const STATUS_ERROR = 'E';
39
44 protected int $id;
45
50 protected int $sitemapId;
51
55 protected int $step;
56 protected array $state;
57 protected string $status;
58 protected string $statusMessage = '';
59
63 protected bool $isLocked = false;
65
70 protected function __construct(int $sitemapId)
71 {
72 $this->sitemapId = $sitemapId;
73
74 // init from table
76 if ($job)
77 {
78 $this->id = (int)$job['ID'];
79 $this->status = $job['STATUS'];
80 $this->statusMessage = $job['STATUS_MESSAGE'];
81 $this->step = (int)$job['STEP'];
82 $this->state = $job['STATE'] ?? [];
83
84 $this->isLocked = $job['RUNNING'] === 'Y';
85 $this->dateModify = $job['DATE_MODIFY'] ? new DateTime($job['DATE_MODIFY']) : null;
86
87 if (!self::checkSitemapExists($sitemapId))
88 {
89 $this->finish();
90
91 throw new SystemException('Sitemap for current job is not exists.');
92 }
93 }
94 else
95 {
96 throw new SystemException('Job for current sitemap is not exists.');
97 }
98 }
99
108 protected static function checkSitemapExists(int $sitemapId): bool
109 {
110 $sitemap = SitemapTable::query()
111 ->setSelect(['ID'])
112 ->where('ID', $sitemapId)
113 ->exec()
114 ->fetch()
115 ;
116
117 return (bool)$sitemap;
118 }
119
125 public static function findJob(int $sitemapId): ?Job
126 {
127 try
128 {
130
131 return $job ? new self($sitemapId) : null;
132 }
133 catch (SystemException $e)
134 {
135 return null;
136 }
137 }
138
145 public static function addJob(int $sitemapId): ?Job
146 {
148 if ($exists)
149 {
150 return new self($sitemapId);
151 }
152
153 $res = JobTable::add(
154 [
155 'SITEMAP_ID' => $sitemapId,
156 'RUNNING' => 'N',
157 'STATUS' => Job::STATUS_REGISTER,
158 'STATUS_MESSAGE' => '',
159 'STEP' => Step::getFirstStep(),
160 'STATE' => [],
161 ]
162 );
163
164 if ($res->isSuccess())
165 {
166 return new self($sitemapId);
167 }
168
169 return null;
170 }
171
177 protected static function getDataBySitemap(int $sitemapId): ?array
178 {
179 if ($sitemapId > 0)
180 {
181 $job = JobTable::query()
182 ->setSelect(['ID', 'RUNNING', 'STATUS', 'STATUS_MESSAGE', 'STEP', 'STATE', 'DATE_MODIFY'])
183 ->where('SITEMAP_ID', $sitemapId)
184 ->exec()
185 ->fetch()
186 ;
187
188 return $job ?: null;
189 }
190
191 return null;
192 }
193
199 public static function markToRegenerate(int $sitemapId): bool
200 {
201 try
202 {
203 if ($sitemapId > 0)
204 {
205 $existsJob = self::findJob($sitemapId);
206 if (!$existsJob)
207 {
209 }
210
212
213 return (bool)self::addAgent($sitemapId);
214 }
215 }
216 catch (SystemException $e)
217 {
218 return false;
219 }
220
221 return false;
222 }
223
224 public static function clearBySitemap(int $sitemapId)
225 {
227 $job?->finish();
228 }
229
235 protected static function findAgent(int $sitemapId): ?array
236 {
237 $funcName = self::getAgentName($sitemapId);
238 $res = \CAgent::getList(
239 [],
240 [
241 'MODULE_ID' => 'seo',
242 'NAME' => $funcName,
243 ]
244 );
245 $exists = $res->Fetch();
246
247 return $exists ?: null;
248 }
249
255 protected static function addAgent(int $sitemapId): int
256 {
257 $funcName = self::getAgentName($sitemapId);
258 $nextExec = \ConvertTimeStamp(time() + \CTimeZone::GetOffset() + self::AGENT_DELAY, "FULL");
259
260 return \CAgent::addAgent(
261 $funcName,
262 'seo',
263 'N',
264 self::AGENT_INTERVAL,
265 '',
266 'Y',
267 $nextExec
268 );
269 }
270
276 protected static function deleteAgent(int $sitemapId): bool
277 {
278 $agent = self::findAgent($sitemapId);
279 if ($agent && $agent['RUNNING'] === 'N')
280 {
281 return \CAgent::Delete($agent['ID']);
282 }
283
284 return true;
285 }
286
287 protected static function getAgentName(int $sitemapId): string
288 {
289 return __CLASS__ . '::' . self::AGENT_FUNCTION . '(' . $sitemapId . ');';
290 }
291
297 public static function doJobAgent(int $sitemapId): string
298 {
300
301 if ($job)
302 {
303 $result = $job->doStep();
304 if ($result->isSuccess())
305 {
307 }
308 }
309
310 return '';
311 }
312
317 public function doStep(): Result
318 {
319 $result = new Result();
320
321 // skip if job running now
322 if (
323 $this->checkLock()
324 || !$this->lock()
325 )
326 {
327 return $result;
328 }
329
330 $generator =
331 (new Generator($this->sitemapId))
332 ->setStep($this->step)
333 ->setState($this->state)
334 ;
335 if ($generator->run())
336 {
337 $this->state = $generator->getState();
338 $this->statusMessage = $generator->getStatusMessage();
339 $this->step = $generator->getStep();
340
341 if ($this->step <= Step::STEPS[Step::STEP_INIT])
342 {
343 $this->status = self::STATUS_REGISTER;
344 }
345 elseif ($this->step >= Step::STEPS[Step::STEP_INDEX])
346 {
347 $this->status = self::STATUS_FINISH;
348 $this->finish();
349 }
350 else
351 {
352 $this->status = self::STATUS_PROCESS;
353 }
354
355 $this->save();
356 }
357 $this->unlock();
358
359 return $result;
360 }
361
362 protected function lock(): bool
363 {
364 $res = JobTable::update(
365 $this->id,
366 [
367 'RUNNING' => 'Y',
368 ]
369 );
370 if ($res->isSuccess())
371 {
372 $this->isLocked = true;
373
374 return true;
375 }
376
377 return false;
378 }
379
380 protected function unlock(): bool
381 {
382 $res = JobTable::update(
383 $this->id,
384 [
385 'RUNNING' => 'N',
386 ]
387 );
388
389 if ($res->isSuccess())
390 {
391 $this->isLocked = false;
392
393 return true;
394 }
395
396 return false;
397 }
398
399 protected function checkLock(): bool
400 {
401 if ($this->isLocked)
402 {
403 if ($this->dateModify)
404 {
405 $secondsDiff = (new DateTime())->getDiff($this->dateModify)->s;
406 if ($secondsDiff > self::LOCK_MAX_INTERVAL)
407 {
408 return !$this->unlock();
409 }
410 }
411
412 return true;
413 }
414
415 return false;
416 }
417
422 protected function save(): bool
423 {
424 $res = JobTable::update(
425 $this->id,
426 [
427 'STATUS' => $this->status,
428 'STATUS_MESSAGE' => $this->statusMessage,
429 'STATE' => $this->state,
430 'STEP' => $this->step,
431 ]
432 );
433
434 return $res->isSuccess();
435 }
436
441 protected function finish(): bool
442 {
443 self::deleteAgent($this->sitemapId);
444
445 $res = JobTable::delete(
446 $this->id
447 );
448
449 return $res->isSuccess();
450 }
451
456 public function getData(): array
457 {
458 return [
459 'status' => $this->status,
460 'statusMessage' => $this->statusMessage,
461 'formattedStatusMessage' => $this->getFormattedStatusMessage(),
462 'step' => $this->step,
463 ];
464 }
465
466 protected function getFormattedStatusMessage(): string
467 {
468 require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/interface/admin_lib.php');
469
470 $title = Loc::getMessage('SEO_SITEMAP_RUN_TITLE') . " (ID {$this->sitemapId})";
471 if ($this->step < Step::getLastStep())
472 {
473 $msg = new \CAdminMessage([
474 "TYPE" => "PROGRESS",
475 "HTML" => true,
476 "MESSAGE" => $title,
477 "DETAILS" => "#PROGRESS_BAR#<div style=\"width: "
478 . self::PROGRESS_WIDTH
479 . "px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-top: 20px;\">"
480 . Converter::getHtmlConverter()->encode($this->statusMessage)
481 . "</div>",
482 "PROGRESS_TOTAL" => 100,
483 "PROGRESS_VALUE" => $this->step,
484 "PROGRESS_TEMPLATE" => '#PROGRESS_PERCENT#',
485 "PROGRESS_WIDTH" => self::PROGRESS_WIDTH,
486 ]);
487 }
488 else
489 {
490 $msg = new \CAdminMessage([
491 "TYPE" => "OK",
492 "MESSAGE" => $title,
493 "DETAILS" => $this->statusMessage,
494 ]);
495 }
496
497 return $msg->show();
498 }
499}
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
const STATUS_REGISTER
Definition Job.php:35
static deleteAgent(int $sitemapId)
Definition Job.php:276
static findJob(int $sitemapId)
Definition Job.php:125
static addJob(int $sitemapId)
Definition Job.php:145
static getDataBySitemap(int $sitemapId)
Definition Job.php:177
static addAgent(int $sitemapId)
Definition Job.php:255
static getAgentName(int $sitemapId)
Definition Job.php:287
static doJobAgent(int $sitemapId)
Definition Job.php:297
__construct(int $sitemapId)
Definition Job.php:70
static markToRegenerate(int $sitemapId)
Definition Job.php:199
DateTime $dateModify
Definition Job.php:64
string $statusMessage
Definition Job.php:58
static clearBySitemap(int $sitemapId)
Definition Job.php:224
const LOCK_MAX_INTERVAL
Definition Job.php:25
static findAgent(int $sitemapId)
Definition Job.php:235
static checkSitemapExists(int $sitemapId)
Definition Job.php:108