api-8.x-1.x-dev/src/Commands/ApiCommands.php

src/Commands/ApiCommands.php
<?php

namespace Drupal\api\Commands;

use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\UrlHelper;
use Drupal\api\Entity\Branch;
use Drupal\api\Entity\ExternalBranch;
use Drupal\api\Entity\PhpBranch;
use Drupal\api\Entity\Project;
use Drupal\api\Interfaces\ProjectInterface;
use Drupal\api\Parser;
use Drupal\api\Utilities;
use Drush\Commands\DrushCommands;
use Symfony\Component\Console\Input\Input;
use Symfony\Component\Console\Output\Output;

/**
 * A Drush commandfile for some additional checks on the api module.
 */
class ApiCommands extends DrushCommands {

  /**
   * Creates a project and branch or updates them if existing.
   *
   * Given all the details of these via arguments and having uploaded
   * the source code to the given "directory" beforehand, it will create
   * and/or update a project and branch.
   *
   * @param string $project
   *   Project value. If not provided, user will be prompted.
   * @param string $project_title
   *   Project title value. If not provided, user will be prompted.
   * @param string $project_type
   *   Project type value. If not provided, user will be prompted.
   * @param string $branch
   *   Branch value. If not provided, user will be prompted.
   * @param string $branch_title
   *   Branch title value. If not provided, user will be prompted.
   * @param string $directory
   *   Directory where files are. If not provided, user will be prompted.
   * @param string $core_compatibility
   *   Core compatibility value. If not provided, user will be prompted.
   * @param int $update_frequency
   *   Update frequency value. If not provided, user will be prompted.
   *
   * @command api:upsert-branch
   * @aliases apiub
   * @usage drush apiub
   */
  public function upsertBranch($project, $project_title, $project_type, $branch, $branch_title, $directory, $core_compatibility, $update_frequency) {
    if (!Project::exists($project)) {
      $project_slug = $project;
      /** @var \Drupal\api\Interfaces\ProjectInterface $project */
      $project = Project::create();
      $project
        ->setTitle($project_title)
        ->setType($project_type)
        ->setSlug($project_slug)
        ->save();
    }
    else {
      $project = Project::getBySlug($project);
      $project
        ->setTitle($project_title)
        ->setType($project_type);
      $project->save();
    }

    $branch_slug = $branch;
    $branch = NULL;
    if ($project->id()) {
      $branch = Branch::getBySlug($branch_slug, $project);
      if (empty($branch)) {
        /** @var \Drupal\api\Interfaces\BranchInterface $branch */
        $branch = Branch::create();
        $branch
          ->setTitle($branch_title)
          ->setSlug($branch_slug)
          ->setCoreCompatibility($core_compatibility)
          ->setProject($project)
          ->setDirectories($directory)
          ->save();
      }
      else {
        $branch
          ->setTitle($branch_title)
          ->setDirectories($directory)
          ->setCoreCompatibility($core_compatibility)
          ->setUpdateFrequency($update_frequency);
        $branch->save();
      }
    }

    if (!empty($branch)) {
      $this->logger()->success(dt('The branch @branch was created.', [
        '@branch' => $branch->getTitle(),
      ]));
    }
    else {
      if (!empty($project)) {
        $this->logger()->warning(dt('The project @project was created, but not the branch.', [
          '@project' => $project->getTitle(),
        ]));
      }
      else {
        $this->logger()->error(dt('The project and branch could not be created.'));
      }
    }
  }

  /**
   * Prompt for parameters for the api:upsert-branch command.
   *
   * @hook interact api:upsert-branch
   */
  public function interactUpsertBranch(Input $input, Output $output) {
    if (!$input->getArgument('project')) {
      $project = $this->io()->ask('Project machine_name');
      $input->setArgument('project', $project);
    }

    if (!$input->getArgument('project_title')) {
      $project_title = $this->io()->ask('Project title');
      $input->setArgument('project_title', $project_title);
    }

    if (!$input->getArgument('project_type')) {
      $project_type = $this->io()->ask('Project type (ie: core, module)');
      $input->setArgument('project_type', $project_type);
    }

    if (!$input->getArgument('branch')) {
      $branch = $this->io()->ask('Branch machine_name');
      $input->setArgument('branch', $branch);
    }

    if (!$input->getArgument('branch_title')) {
      $branch_title = $this->io()->ask('Branch title');
      $input->setArgument('branch_title', $branch_title);
    }

    if (!$input->getArgument('directory')) {
      $directory = $this->io()->ask('Directory where the code is (no validation will be done)');
      $input->setArgument('directory', $directory);
    }

    if (!$input->getArgument('core_compatibility')) {
      $core_compatibility = $this->io()->ask('Core compatibility');
      $input->setArgument('core_compatibility', $core_compatibility);
    }

    if (!$input->getArgument('update_frequency')) {
      $update_frequency = $this->io()->ask('Update frequency in seconds (ie: 604800 for 1 week). Defaults to one month', Utilities::ONE_MONTH);
      $input->setArgument('update_frequency', $update_frequency);
    }
  }

  /**
   * Reset the API parsing queue.
   *
   * @command api:reset-queue
   * @aliases apirq
   */
  public function resetQueue() {
    $this->emptyParsingQueue();
    $this->logger()->success(dt('The contents of the queue "@queue" were deleted.', [
      '@queue' => Parser::QUEUE_PARSE,
    ]));
  }

  /**
   * Empties parsing queue.
   */
  protected function emptyParsingQueue() {
    $queue_factory = \Drupal::service('queue');
    /** @var \Drupal\Core\Queue\QueueInterface $queue */
    $queue = $queue_factory->get(Parser::QUEUE_PARSE);
    $queue->deleteQueue();
  }

  /**
   * Reparse single file.
   *
   * Example: drush api:re-parse-file /path/to/file.php 19
   *
   * @param string $path
   *   Path of the file.
   * @param int $branch_id
   *   Id of the branch.
   *
   * @command api:re-parse-file
   * @aliases apirpf
   */
  public function reParseFile(string $path, int $branch_id) {
    /** @var \Drupal\api\Parser $parser */
    $parser = \Drupal::service('api.parser');
    if ($parser->parseSingleFile($path, $branch_id)) {
      $this->logger()->success(dt('File was re-parsed.'));
    }
    else {
      $this->logger()->error(dt('Not parsed. Review path and branch id and make sure that the path belongs to that branch.'));
    }
  }

  /**
   * Mark all branches to be reparsed in the next run.
   *
   * @command api:re-parse
   * @aliases apirp
   */
  public function reParse() {
    // Remove everything in the queue first.
    $this->emptyParsingQueue();

    // And now go through branches and clean the queued value.
    $counter = 0;
    $all = $this->getAllBranches();
    foreach ($all as $branches) {
      foreach ($branches as $branch) {
        if (method_exists($branch, 'reParse')) {
          $branch->reParse();
          $counter++;
        }
      }
    }

    $this->logger()->success(dt('@count branches were set to be re-parsed.', [
      '@count' => $counter,
    ]));
  }

  /**
   * Create a project and branches from a git URL.
   *
   * @param string $repo_url
   *   Url of the repo.
   * @param string $type
   *   Type of project.
   *
   * @command api:quick-wizard
   * @aliases apiqw
   */
  public function quickWizard($repo_url, $type = 'module') {
    /** @var \Drupal\api\Utilities $utilities */
    $utilities = \Drupal::service('api.utilities');
    $project = NULL;

    if (!UrlHelper::isValid($repo_url)) {
      $this->logger()->error(dt('The given URL is not valid. Use "https" format.'));
    }

    // Check if project is already there.
    $project_name = $utilities->gitProjectName($repo_url);
    $exists = Project::exists($project_name);
    if ($exists) {
      $project = Project::getBySlug($project_name);
      $results = $utilities->gitFetchBranches($project);
      if (empty($results)) {
        $this->logger()->error(dt('Branches could not be pulled or checked out.'));
      }
    }
    else {
      $results = $utilities->gitClone($repo_url);
      if (empty($results)) {
        $this->logger()->error(dt('There was an error cloning the repository.'));
      }
      else {
        // Repo was cloned to the filesystem, create the project now.
        $formatted_name = Unicode::ucwords(str_replace(['-', '_'], [' ', ' '], $project_name));
        // Remove the .git extension from the URL to display external links.
        $web_repo_url = str_replace('.git', '', $repo_url);

        /** @var \Drupal\api\Interfaces\ProjectInterface $project */
        $project = Project::create();
        $project
          ->setTitle($formatted_name)
          ->setType($type)
          ->setSlug($project_name)
          ->setGitUrl($web_repo_url)
          ->save();
        $this->logger()->success(dt('Project ' . $project_name . ' was created.'));
      }
    }

    if (!empty($results) && ($project instanceof ProjectInterface)) {
      foreach ($results as $branch_info) {
        $base_folder = substr($branch_info['folder'], 0, -1 * (strlen($branch_info['branch']) + 1));

        $branch_folder = $utilities->createBranchFolder(
          $branch_info['branch'],
          $base_folder,
          $branch_info['repo']
        );

        if ($branch_folder == $branch_info['folder']) {
          $core_compatibility = $project->isCore() ?
            $branch_info['branch'] :
            $utilities->getCoreCompatibility($branch_info['folder'], $project->getSlug());

          if ($project->isCore()) {
            $utilities->addExtraDocumentation($branch_info['folder'], $branch_info['branch'], $project);
          }

          /** @var \Drupal\api\Interfaces\BranchInterface $branch */
          $branch = Branch::getBySlug($branch_info['branch'], $project) ?? Branch::create();
          $branch
            ->setTitle($branch_info['branch'])
            ->setSlug($branch_info['branch'])
            ->setCoreCompatibility($core_compatibility)
            ->setProject($project)
            ->setDirectories($branch_info['folder'])
            ->save();
          $this->logger()->success(dt('* Branch ' . $branch_info['branch'] . ' was created.'));
        }
      }
    }
  }

  /**
   * Gets all branches from all types defined in the api module.
   *
   * @return array
   *   Arrays of branches organised per type.
   */
  protected function getAllBranches() {
    return [
      'branch' => Branch::loadMultiple(),
      'php_branch' => PhpBranch::loadMultiple(),
      'external_branch' => ExternalBranch::loadMultiple(),
    ];
  }

  /**
   * List all branches available and their type.
   *
   * @param array $options
   *   Options for the output.
   *
   * @field-labels
   *   branch: Branch
   *   type: Type
   * @default-fields branch,type
   *
   * @command api:list-branches
   * @aliases apilb
   *
   * @filter-default-field branch
   *
   * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
   *   Rows to be rendered as output.
   */
  public function listBranches(array $options = ['format' => 'table']) {
    $all = $this->getAllBranches();
    $rows = [];
    foreach ($all as $type => $branches) {
      foreach ($branches as $branch) {
        $project = '';
        if (method_exists($branch, 'getProject')) {
          $project = ' @ ' . $branch->getProject()->label();
        }
        $rows[] = [
          'branch' => $branch->label() . $project,
          'type' => $type,
        ];
      }
    }
    return new RowsOfFields($rows);
  }

  /**
   * Count contents of API queues.
   *
   * @param array $options
   *   Options for the output.
   *
   * @field-labels
   *   queue: Queue
   *   count: Count
   * @default-fields queue,count
   *
   * @command api:count-queues
   * @aliases apicq
   *
   * @filter-default-field queue
   *
   * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
   *   Rows to be rendered as output.
   */
  public function countQueues(array $options = ['format' => 'table']) {
    $queue_factory = \Drupal::service('queue');
    /** @var \Drupal\Core\Queue\QueueInterface $queue */
    $queue = $queue_factory->get(Parser::QUEUE_PARSE);

    $rows[] = [
      'queue' => Parser::QUEUE_PARSE,
      'count' => $queue->numberOfItems(),
    ];

    return new RowsOfFields($rows);
  }

}

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

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