sgd_dashboard-1.0.0-beta1/src/Services/SiteGuardianCronService.php

src/Services/SiteGuardianCronService.php
<?php

namespace Drupal\sgd_dashboard\Services;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Session\AccountSwitcherInterface;
use Drupal\Core\Session\UserSession;
use Drupal\sgd_dashboard\Entity\Bundle\WebsiteBundle;
use Drupal\sgd_dashboard\Exception\SiteGuardianClientAPIException;
use Drupal\ultimate_cron\Entity\CronJob;
use Drupal\ultimate_cron\CronJobInterface;
use Panlatent\CronExpressionDescriptor\ExpressionDescriptor;
use Psr\Log\LoggerInterface;

/**
 * SiteGuardian Cron service.
 *
 * Provides functions for handling cron jobs.
 */
class SiteGuardianCronService {

  use StringTranslationTrait;

  /**
   * The SGD data service.
   *
   * @var Drupal\sgd_dashboard\Services\SiteGuardianDataService
   */
  protected $dataService;

  /**
   * The storage handler class for nodes.
   *
   * @var \Drupal\node\NodeStorage
   */
  private $nodeStorage;

  /**
   * The account switcher service.
   *
   * @var \Drupal\Core\Session\AccountSwitcherInterface
   */
  protected $accountSwitcher;

  /**
   * The module handler to invoke hooks on.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * Logger.
   *
   * @var Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * {@inheritDoc}
   */
  public function __construct(SiteGuardianDataService $dataService, EntityTypeManagerInterface $entity, AccountSwitcherInterface $account_switcher, ModuleHandlerInterface $module_handler, LoggerInterface $logger) {
    $this->dataService = $dataService;
    $this->nodeStorage = $entity->getStorage('node');
    $this->accountSwitcher = $account_switcher;
    $this->moduleHandler = $module_handler;
    $this->logger = $logger;
  }

  /**
   * Adds a Cron job for a website node.
   */
  public function addCronJob(WebsiteBundle $node) {

    $jobId = $this->getCronJobId($node);

    // If no cron job for the node being passed then create one.
    if (!CronJob::load($jobId)) {

      // We don't want every cron job to run at the exact same time so figure
      // out a random time within the morning hours between 2 and 5.
      $hour = rand(2, 5);
      $minute = rand(0, 59);

      $cronRule = "$minute $hour * * *";

      $jobTitle = $this->t("Site Guardian: Website refresh for: @title", ['@title' => $node->getTitle()]);

      $values = [
        'id' => $jobId,
        'title' => $jobTitle,
        'module' => "sgd_dashboard",
        'weight' => 10,
        'callback' => 'siteguardian.CronService::refreshCallback',
        'scheduler' => [
          'id' => 'crontab',
          'configuration' => [
            'rules' => [$cronRule],
          ],
        ],
      ];

      $cronJob = CronJob::create($values);

      $cronJob->setThirdPartySetting('sgd_dashboard', 'target_node', $node->id());

      $cronJob->save();
    }
  }

  /**
   * Updates a Cron job for a website node.
   */
  public function updateCronJob(WebsiteBundle $node) {

    $jobId = $this->getCronJobId($node);

    if ($cronJob = CronJob::load($jobId)) {

      $jobTitle = $this->t("Site Guardian: Website refresh for: @title", ['@title' => $node->getTitle()]);

      $cronJob->setTitle($jobTitle);

      $cronJob->save();

      return TRUE;
    }

    else {
      return FALSE;
    }
  }

  /**
   * Deletes a Cron job for a website node.
   */
  public function deleteCronJob(WebsiteBundle $node) {

    $jobId = $this->getCronJobId($node);

    if ($cronJob = CronJob::load($jobId)) {
      $cronJob->delete();
    }
  }

  /**
   * Get the crontab for a website cron job.
   */
  public function getCrontab(WebsiteBundle $node) : ?string {

    $jobId = $this->getCronJobId($node);

    if ($cronJob = CronJob::load($jobId)) {

      $crontab = $cronJob->get('scheduler')['configuration']['rules'][0];

      return $crontab;
    }

    return NULL;
  }

  /**
   * Get the crontab for a website cron job as human readable text.
   */
  public function getCrontabAsText(WebsiteBundle $node) : ?string {

    if ($crontab = $this->getCrontab($node)) {

      return (new ExpressionDescriptor($crontab))->getDescription();
    }

    return $this->t("No cron schedule found.");
  }

  /**
   * Set the crontab for a website cron job.
   */
  public function setCrontab(WebsiteBundle $node, string $crontab) : void {

    $jobId = $this->getCronJobId($node);

    if ($cronJob = CronJob::load($jobId)) {

      $scheduler = $cronJob->get('scheduler');

      $scheduler['configuration']['rules'][0] = $crontab;

      $cronJob->set('scheduler', $scheduler);

      $cronJob->save();
    }

  }

  /**
   * Cron callback that refreshes the data for a website.
   */
  public function refreshCallback(CronJobInterface $job) {

    $websiteNodeId = $job->getThirdPartySetting('sgd_dashboard', 'target_node', FALSE);

    /** @var \Drupal\sgd_dashboard\Entity\Bundle\WebsiteBundle $websiteNode */
    $websiteNode = $this->nodeStorage->load($websiteNodeId);

    if ($websiteNode->isPublished()) {

      try {

        // Need to be able to run as admin (CRON runs as anon) so basic auth
        // info can be retreived by the CRON job.
        $this->accountSwitcher->switchTo(new UserSession(['uid' => 1]));

        $this->dataService->refreshWebsiteFields($websiteNode);

        // Fire a hook so any other modules can react to the completion of a
        // website refresh.
        $this->moduleHandler->invokeAll('site_guardian_dashboard_cron_refresh_complete', [$websiteNode]);
      }

      catch (SiteGuardianClientAPIException $e) {

        $this->logger->error("Error getting website status from %website: @error", [
          '%website' => $websiteNode->get('field_url')->value,
          '@error' => $e->getMessage(),
        ]);

      }

      finally {
        // Must allways switch back to the old session.
        $this->accountSwitcher->switchBack();
      }

    }

    return TRUE;
  }

  /**
   * Return the cron job id for the website node passed in.
   */
  private function getCronJobId(WebsiteBundle $node) : string {
    return "sgd_refresh_job_" . $node->id();
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc