class OperationFactory

Same name in other branches
  1. 8.9.x composer/Plugin/Scaffold/Operations/OperationFactory.php \Drupal\Composer\Plugin\Scaffold\Operations\OperationFactory
  2. 10 composer/Plugin/Scaffold/Operations/OperationFactory.php \Drupal\Composer\Plugin\Scaffold\Operations\OperationFactory
  3. 11.x composer/Plugin/Scaffold/Operations/OperationFactory.php \Drupal\Composer\Plugin\Scaffold\Operations\OperationFactory

Create Scaffold operation objects based on provided metadata.

@internal

Hierarchy

Expanded class hierarchy of OperationFactory

1 file declares its use of OperationFactory
Handler.php in composer/Plugin/Scaffold/Handler.php

File

composer/Plugin/Scaffold/Operations/OperationFactory.php, line 14

Namespace

Drupal\Composer\Plugin\Scaffold\Operations
View source
class OperationFactory {
    
    /**
     * The Composer service.
     *
     * @var \Composer\Composer
     */
    protected $composer;
    
    /**
     * OperationFactory constructor.
     *
     * @param \Composer\Composer $composer
     *   Reference to the 'Composer' object, since the Scaffold Operation Factory
     *   is also responsible for evaluating relative package paths as it creates
     *   scaffold operations.
     */
    public function __construct(Composer $composer) {
        $this->composer = $composer;
    }
    
    /**
     * Creates a scaffolding operation object as determined by the metadata.
     *
     * @param \Composer\Package\PackageInterface $package
     *   The package that relative paths will be relative from.
     * @param OperationData $operation_data
     *   The parameter data for this operation object; varies by operation type.
     *
     * @return \Drupal\Composer\Plugin\Scaffold\Operations\OperationInterface
     *   The scaffolding operation object (skip, replace, etc.)
     *
     * @throws \RuntimeException
     *   Exception thrown when parameter data does not identify a known scaffold
     *   operation.
     */
    public function create(PackageInterface $package, OperationData $operation_data) {
        switch ($operation_data->mode()) {
            case SkipOp::ID:
                return new SkipOp();
            case ReplaceOp::ID:
                return $this->createReplaceOp($package, $operation_data);
            case AppendOp::ID:
                return $this->createAppendOp($package, $operation_data);
        }
        throw new \RuntimeException("Unknown scaffold operation mode <comment>{$operation_data->mode()}</comment>.");
    }
    
    /**
     * Creates a 'replace' scaffold op.
     *
     * Replace ops may copy or symlink, depending on settings.
     *
     * @param \Composer\Package\PackageInterface $package
     *   The package that relative paths will be relative from.
     * @param OperationData $operation_data
     *   The parameter data for this operation object, i.e. the relative 'path'.
     *
     * @return \Drupal\Composer\Plugin\Scaffold\Operations\OperationInterface
     *   A scaffold replace operation object.
     */
    protected function createReplaceOp(PackageInterface $package, OperationData $operation_data) {
        if (!$operation_data->hasPath()) {
            throw new \RuntimeException("'path' component required for 'replace' operations.");
        }
        $package_name = $package->getName();
        $package_path = $this->getPackagePath($package);
        $source = ScaffoldFilePath::sourcePath($package_name, $package_path, $operation_data->destination(), $operation_data->path());
        $op = new ReplaceOp($source, $operation_data->overwrite());
        return $op;
    }
    
    /**
     * Creates an 'append' (or 'prepend') scaffold op.
     *
     * @param \Composer\Package\PackageInterface $package
     *   The package that relative paths will be relative from.
     * @param OperationData $operation_data
     *   The parameter data for this operation object, i.e. the relative 'path'.
     *
     * @return \Drupal\Composer\Plugin\Scaffold\Operations\OperationInterface
     *   A scaffold replace operation object.
     */
    protected function createAppendOp(PackageInterface $package, OperationData $operation_data) {
        $package_name = $package->getName();
        $package_path = $this->getPackagePath($package);
        $prepend_source_file = NULL;
        $append_source_file = NULL;
        $default_data_file = NULL;
        if ($operation_data->hasPrepend()) {
            $prepend_source_file = ScaffoldFilePath::sourcePath($package_name, $package_path, $operation_data->destination(), $operation_data->prepend());
        }
        if ($operation_data->hasAppend()) {
            $append_source_file = ScaffoldFilePath::sourcePath($package_name, $package_path, $operation_data->destination(), $operation_data->append());
        }
        if ($operation_data->hasDefault()) {
            $default_data_file = ScaffoldFilePath::sourcePath($package_name, $package_path, $operation_data->destination(), $operation_data->default());
        }
        if (!$this->hasContent($prepend_source_file) && !$this->hasContent($append_source_file)) {
            $message = '  - Keep <info>[dest-rel-path]</info> unchanged: no content to prepend / append was provided.';
            return new SkipOp($message);
        }
        return new AppendOp($prepend_source_file, $append_source_file, $operation_data->forceAppend(), $default_data_file);
    }
    
    /**
     * Checks to see if the specified scaffold file exists and has content.
     *
     * @param Drupal\Composer\Plugin\Scaffold\ScaffoldFilePath $file
     *   Scaffold file to check.
     *
     * @return bool
     *   True if the file exists and has content.
     */
    protected function hasContent(ScaffoldFilePath $file = NULL) {
        if (!$file) {
            return FALSE;
        }
        $path = $file->fullPath();
        return is_file($path) && filesize($path) > 0;
    }
    
    /**
     * Gets the file path of a package.
     *
     * Note that if we call getInstallPath on the root package, we get the
     * wrong answer (the installation manager thinks our package is in
     * vendor). We therefore add special checking for this case.
     *
     * @param \Composer\Package\PackageInterface $package
     *   The package.
     *
     * @return string
     *   The file path.
     */
    protected function getPackagePath(PackageInterface $package) {
        if ($package->getName() == $this->composer
            ->getPackage()
            ->getName()) {
            // This will respect the --working-dir option if Composer is invoked with
            // it. There is no API or method to determine the filesystem path of
            // a package's composer.json file.
            return getcwd();
        }
        return $this->composer
            ->getInstallationManager()
            ->getInstallPath($package);
    }

}

Members

Title Sort descending Modifiers Object type Summary
OperationFactory::$composer protected property The Composer service.
OperationFactory::create public function Creates a scaffolding operation object as determined by the metadata.
OperationFactory::createAppendOp protected function Creates an &#039;append&#039; (or &#039;prepend&#039;) scaffold op.
OperationFactory::createReplaceOp protected function Creates a &#039;replace&#039; scaffold op.
OperationFactory::getPackagePath protected function Gets the file path of a package.
OperationFactory::hasContent protected function Checks to see if the specified scaffold file exists and has content.
OperationFactory::__construct public function OperationFactory constructor.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.