sfc-8.x-1.3/src/Commands/ComponentCommands.php

src/Commands/ComponentCommands.php
<?php

namespace Drupal\sfc\Commands;

use Consolidation\SiteAlias\SiteAliasManagerAwareTrait;
use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Asset\LibraryDiscoveryInterface;
use Drupal\sfc\ComponentFilenameInterface;
use Drush\Commands\DrushCommands;
use Drush\SiteAlias\SiteAliasManagerAwareInterface;

/**
 * Drush command file for SFC commands.
 */
class ComponentCommands extends DrushCommands implements SiteAliasManagerAwareInterface {

  use SiteAliasManagerAwareTrait;

  /**
   * The plugin manager.
   *
   * @var \Drupal\Component\Plugin\PluginManagerInterface
   */
  protected $manager;

  /**
   * The watch file path.
   *
   * @var string
   */
  protected $watchFilePath;

  /**
   * The library discovery service.
   *
   * @var \Drupal\Core\Asset\LibraryDiscoveryInterface
   */
  protected $libraryDiscovery;

  /**
   * ComponentCommands constructor.
   *
   * @param \Drupal\Component\Plugin\PluginManagerInterface $manager
   *   The plugin manager.
   * @param string $watch_file_path
   *   The watch file path.
   * @param \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery
   *   The simple component deriver.
   */
  public function __construct(PluginManagerInterface $manager, $watch_file_path = 'public://sfc_watch_file.txt', LibraryDiscoveryInterface $library_discovery = NULL) {
    $this->manager = $manager;
    $this->watchFilePath = $watch_file_path;
    if (!$library_discovery) {
      $library_discovery = \Drupal::service('library.discovery');
    }
    $this->libraryDiscovery = $library_discovery;
  }

  /**
   * Writes the assets and/or source for a given component.
   *
   * @param string $id
   *   The plugin ID.
   *
   * @command sfc:write
   */
  public function write($id) {
    /** @var \Drupal\sfc\ComponentInterface $component */
    $component = $this->manager->createInstance($id);
    $component->writeAssets();
  }

  /**
   * Watches for changes in all components.
   *
   * This is a good alternative to disabling the "data" cache bin for normal
   * components.
   *
   * @param array $options
   *   Options for this command.
   *
   * @command sfc:watch
   * @option run-once If the command should only be run once.
   */
  public function watch(array $options = ['run-once' => FALSE]) {
    $this->io()->writeln('Watching for changes...');
    $last_error = '';
    while (TRUE) {
      /** @var \Consolidation\SiteProcess\ProcessBase $process */
      $process = $this->processManager()->drush($this->siteAliasManager()->getSelf(), 'sfc:do-watch');
      $process->run();

      // Do not repeat errors in the loop.
      $error = $process->getErrorOutput();
      if ($last_error && !$error) {
        $this->io()->success('Errors resolved! Still watching...');
      }
      elseif ($last_error !== $error) {
        $this->io()->error($error);
        $process->clearErrorOutput();
        // Clearing cached definitions handles deleted components.
        if ($this->manager instanceof CachedDiscoveryInterface) {
          $this->manager->clearCachedDefinitions();
        }
      }
      $last_error = $error;

      $output = $process->getOutput();
      if (!$error && $output) {
        echo $output;
      }

      usleep(250000);
      if ($options['run-once']) {
        break;
      }
    }
    return 0;
  }

  /**
   * Writes components in another command to avoid killing "sfc:watch".
   *
   * @command sfc:do-watch
   */
  public function doWatch() {
    $last_cache_clear = @file_get_contents($this->watchFilePath) ?: time();

    // See if definitions changed, in which case all cache should be cleared.
    if ($this->manager instanceof CachedDiscoveryInterface) {
      $hash = md5(serialize($this->manager->getDefinitions()) . serialize($this->libraryDiscovery->getLibrariesByExtension('sfc')));
      $this->manager->clearCachedDefinitions();
      $this->libraryDiscovery->clearCachedDefinitions();
      if ($hash !== md5(serialize($this->manager->getDefinitions()) . serialize($this->libraryDiscovery->getLibrariesByExtension('sfc')))) {
        $this->io()->writeln('Definitions or libraries changed, clearing all cache');
        $this->processManager()->drush($this->siteAliasManager()->getSelf(), 'cr', [])->mustRun();
        file_put_contents($this->watchFilePath, time());
      }
    }

    $definitions = $this->manager->getDefinitions();
    if (empty($definitions)) {
      return 0;
    }

    clearstatcache();
    $clear_cache = FALSE;
    foreach (array_keys($definitions) as $id) {
      /** @var \Drupal\sfc\ComponentInterface $component */
      $component = $this->manager->createInstance($id);
      if ($component->shouldWriteAssets()) {
        $this->io()->writeln("Writing assets for $id");
        $this->processManager()->drush($this->siteAliasManager()->getSelf(), 'sfc:write', [$id])->mustRun();
        $clear_cache = TRUE;
      }
      if ($component instanceof ComponentFilenameInterface && $component->getComponentFileName() && filemtime($component->getComponentFileName()) > $last_cache_clear) {
        $clear_cache = TRUE;
      }
    }
    if ($clear_cache) {
      $this->io()->writeln("Clearing render cache");
      $this->processManager()->drush($this->siteAliasManager()->getSelf(), 'cc', ['render'])->mustRun();
      file_put_contents($this->watchFilePath, time());
    }

    return 0;
  }

}

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

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