Class yii\composer\Installer

Inheritanceyii\composer\Installer » Composer\Installer\LibraryInstaller
Available since version2.0
Source Code https://github.com/yiisoft/yii2-composer/blob/master/Installer.php

Public Methods

Hide inherited methods

Method Description Defined By
copyFiles() Copy files to specified locations. yii\composer\Installer
generateCookieValidationKey() Generates a cookie validation key for every app config listed in "config" in extra section. yii\composer\Installer
install() yii\composer\Installer
postCreateProject() Special method to run tasks defined in [extra][yii\composer\Installer::postCreateProject] key in composer.json yii\composer\Installer
postInstall() Special method to run tasks defined in [extra][yii\composer\Installer::postInstall] key in composer.json yii\composer\Installer
setPermission() Sets the correct permission for the files and directories listed in the extra section. yii\composer\Installer
supports() yii\composer\Installer
uninstall() yii\composer\Installer
update() yii\composer\Installer

Constants

Hide inherited constants

Constant Value Description Defined By
EXTENSION_FILE 'yiisoft/extensions.php' yii\composer\Installer
EXTRA_BOOTSTRAP 'bootstrap' yii\composer\Installer

Method Details

Hide inherited methods

addPackage() protected method
protected addPackage( \Composer\Package\PackageInterface $package ): mixed
$package \Composer\Package\PackageInterface

                protected function addPackage(PackageInterface $package)
{
    $extension = [
        'name' => $package->getName(),
        'version' => $package->getVersion(),
    ];
    $alias = $this->generateDefaultAlias($package);
    if (!empty($alias)) {
        $extension['alias'] = $alias;
    }
    $extra = $package->getExtra();
    if (isset($extra[self::EXTRA_BOOTSTRAP])) {
        $extension['bootstrap'] = $extra[self::EXTRA_BOOTSTRAP];
    }
    $extensions = $this->loadExtensions();
    $extensions[$package->getName()] = $extension;
    $this->saveExtensions($extensions);
}

            
copyFiles() public static method (available since version 2.0.5)

Copy files to specified locations.

public static copyFiles( array $paths ): mixed
$paths array

The source files paths (keys) and the corresponding target locations for copied files (values). Location can be specified as an array - first element is target location, second defines whether file can be overwritten (by default method don't overwrite existing files).

                public static function copyFiles(array $paths)
{
    foreach ($paths as $source => $target) {
        // handle file target as array [path, overwrite]
        $target = (array) $target;
        echo "Copying file $source to $target[0] - ";
        if (!is_file($source)) {
            echo "source file not found.\n";
            continue;
        }
        if (is_file($target[0]) && empty($target[1])) {
            echo "target file exists - skip.\n";
            continue;
        } elseif (is_file($target[0]) && !empty($target[1])) {
            echo 'target file exists - overwrite - ';
        }
        try {
            if (!is_dir(dirname($target[0]))) {
                mkdir(dirname($target[0]), 0777, true);
            }
            if (copy($source, $target[0])) {
                echo "done.\n";
            }
        } catch (\Exception $e) {
            echo $e->getMessage() . "\n";
        }
    }
}

            
generateCookieValidationKey() public static method

Generates a cookie validation key for every app config listed in "config" in extra section.

You can provide one or multiple parameters as the configuration files which need to have validation key inserted.

public static generateCookieValidationKey( ): mixed

                public static function generateCookieValidationKey()
{
    $configs = func_get_args();
    $key = self::generateRandomString();
    foreach ($configs as $config) {
        if (is_file($config)) {
            $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($config), -1, $count);
            if ($count > 0) {
                file_put_contents($config, $content);
            }
        }
    }
}

            
generateDefaultAlias() protected method
protected generateDefaultAlias( \Composer\Package\PackageInterface $package ): mixed
$package \Composer\Package\PackageInterface

                protected function generateDefaultAlias(PackageInterface $package)
{
    $fs = new Filesystem();
    $vendorDir = $fs->normalizePath($this->vendorDir);
    $autoload = $package->getAutoload();
    $aliases = [];
    if (!empty($autoload['psr-0'])) {
        foreach ($autoload['psr-0'] as $name => $path) {
            $name = str_replace('\\', '/', trim($name, '\\'));
            if (!$fs->isAbsolutePath($path)) {
                $path = $this->vendorDir . '/' . $package->getPrettyName() . '/' . $path;
            }
            $path = $fs->normalizePath($path);
            if (strpos($path . '/', $vendorDir . '/') === 0) {
                $aliases["@$name"] = '<vendor-dir>' . substr($path, strlen($vendorDir)) . '/' . $name;
            } else {
                $aliases["@$name"] = $path . '/' . $name;
            }
        }
    }
    if (!empty($autoload['psr-4'])) {
        foreach ($autoload['psr-4'] as $name => $path) {
            if (is_array($path)) {
                // ignore psr-4 autoload specifications with multiple search paths
                // we can not convert them into aliases as they are ambiguous
                continue;
            }
            $name = str_replace('\\', '/', trim($name, '\\'));
            if (!$fs->isAbsolutePath($path)) {
                $path = $this->vendorDir . '/' . $package->getPrettyName() . '/' . $path;
            }
            $path = $fs->normalizePath($path);
            if (strpos($path . '/', $vendorDir . '/') === 0) {
                $aliases["@$name"] = '<vendor-dir>' . substr($path, strlen($vendorDir));
            } else {
                $aliases["@$name"] = $path;
            }
        }
    }
    return $aliases;
}

            
generateRandomBytes() protected static method
protected static generateRandomBytes( mixed $length ): mixed
$length mixed

                protected static function generateRandomBytes($length)
{
    if (function_exists('random_bytes')) {
        return random_bytes($length);
    }
    if (extension_loaded('openssl')) {
        return openssl_random_pseudo_bytes($length);
    }
    throw new \Exception('PHP >= 7.0 or the OpenSSL PHP extension is required by Yii2.');
}

            
generateRandomString() protected static method
protected static generateRandomString( ): mixed

                protected static function generateRandomString()
{
    $length = 32;
    $bytes = self::generateRandomBytes($length);
    return strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.');
}

            
install() public method
public install( \Composer\Repository\InstalledRepositoryInterface $repo, \Composer\Package\PackageInterface $package ):
$repo \Composer\Repository\InstalledRepositoryInterface
$package \Composer\Package\PackageInterface

                public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
{
    $afterInstall = function () use ($package) {
        // add the package to yiisoft/extensions.php
        $this->addPackage($package);
        // ensure the yii2-dev package also provides Yii.php in the same place as yii2 does
        if ($package->getName() == 'yiisoft/yii2-dev') {
            $this->linkBaseYiiFiles();
        }
    };
    // install the package the normal composer way
    $promise = parent::install($repo, $package);
    // Composer v2 might return a promise here
    if ($promise instanceof PromiseInterface) {
        return $promise->then($afterInstall);
    }
    // If not, execute the code right away as parent::install executed synchronously (composer v1, or v2 without async)
    $afterInstall();
}

            
linkBaseYiiFiles() protected method
protected linkBaseYiiFiles( ): mixed

                protected function linkBaseYiiFiles()
{
    $yiiDir = $this->vendorDir . '/yiisoft/yii2';
    if (!file_exists($yiiDir)) {
        mkdir($yiiDir, 0777, true);
    }
    foreach (['Yii.php', 'BaseYii.php', 'classes.php'] as $file) {
        file_put_contents($yiiDir . '/' . $file, <<<EOF
p
his is a link provided by the yiisoft/yii2-dev package via yii2-composer plugin.
link https://www.yiiframework.com/
copyright Copyright (c) 2008 Yii Software LLC
license https://www.yiiframework.com/license/
rn require(__DIR__ . '/../yii2-dev/framework/$file');
        );
    }
}

            
loadExtensions() protected method
protected loadExtensions( ): mixed

                protected function loadExtensions()
{
    $file = $this->vendorDir . '/' . static::EXTENSION_FILE;
    if (!is_file($file)) {
        return [];
    }
    // invalidate opcache of extensions.php if exists
    if (function_exists('opcache_invalidate')) {
        @opcache_invalidate($file, true);
    }
    $extensions = require($file);
    $vendorDir = str_replace('\\', '/', $this->vendorDir);
    $n = strlen($vendorDir);
    foreach ($extensions as &$extension) {
        if (isset($extension['alias'])) {
            foreach ($extension['alias'] as $alias => $path) {
                $path = str_replace('\\', '/', $path);
                if (strpos($path . '/', $vendorDir . '/') === 0) {
                    $extension['alias'][$alias] = '<vendor-dir>' . substr($path, $n);
                }
            }
        }
    }
    return $extensions;
}

            
postCreateProject() public static method

Special method to run tasks defined in [extra][yii\composer\Installer::postCreateProject] key in composer.json

public static postCreateProject( \Composer\Script\Event $event ): mixed
$event \Composer\Script\Event

                public static function postCreateProject($event)
{
    static::runCommands($event, __METHOD__);
}

            
postInstall() public static method (available since version 2.0.5)

Special method to run tasks defined in [extra][yii\composer\Installer::postInstall] key in composer.json

public static postInstall( \Composer\Script\Event $event ): mixed
$event \Composer\Script\Event

                public static function postInstall($event)
{
    static::runCommands($event, __METHOD__);
}

            
removeBaseYiiFiles() protected method
protected removeBaseYiiFiles( ): mixed

                protected function removeBaseYiiFiles()
{
    $yiiDir = $this->vendorDir . '/yiisoft/yii2';
    foreach (['Yii.php', 'BaseYii.php', 'classes.php'] as $file) {
        if (file_exists($yiiDir . '/' . $file)) {
            unlink($yiiDir . '/' . $file);
        }
    }
    if (file_exists($yiiDir)) {
        rmdir($yiiDir);
    }
}

            
removePackage() protected method
protected removePackage( \Composer\Package\PackageInterface $package ): mixed
$package \Composer\Package\PackageInterface

                protected function removePackage(PackageInterface $package)
{
    $packages = $this->loadExtensions();
    unset($packages[$package->getName()]);
    $this->saveExtensions($packages);
}

            
runCommands() protected static method (available since version 2.0.5)

Special method to run tasks defined in [extra][$extraKey] key in composer.json

protected static runCommands( \Composer\Script\Event $event, string $extraKey ): mixed
$event \Composer\Script\Event
$extraKey string

                protected static function runCommands($event, $extraKey)
{
    $params = $event->getComposer()->getPackage()->getExtra();
    if (isset($params[$extraKey]) && is_array($params[$extraKey])) {
        foreach ($params[$extraKey] as $method => $args) {
            call_user_func_array([__CLASS__, $method], (array) $args);
        }
    }
}

            
saveExtensions() protected method
protected saveExtensions( array $extensions ): mixed
$extensions array

                protected function saveExtensions(array $extensions)
{
    $file = $this->vendorDir . '/' . static::EXTENSION_FILE;
    if (!file_exists(dirname($file))) {
        mkdir(dirname($file), 0777, true);
    }
    $array = str_replace("'<vendor-dir>", '$vendorDir . \'', var_export($extensions, true));
    file_put_contents($file, "<?php\n\n\$vendorDir = dirname(__DIR__);\n\nreturn $array;\n");
    // invalidate opcache of extensions.php if exists
    if (function_exists('opcache_invalidate')) {
        @opcache_invalidate($file, true);
    }
}

            
setPermission() public static method

Sets the correct permission for the files and directories listed in the extra section.

public static setPermission( array $paths ): mixed
$paths array

The paths (keys) and the corresponding permission octal strings (values)

                public static function setPermission(array $paths)
{
    foreach ($paths as $path => $permission) {
        echo "chmod('$path', $permission)...";
        if (is_dir($path) || is_file($path)) {
            try {
                if (chmod($path, octdec($permission))) {
                    echo "done.\n";
                };
            } catch (\Exception $e) {
                echo $e->getMessage() . "\n";
            }
        } else {
            echo "file not found.\n";
        }
    }
}

            
supports() public method
public supports( mixed $packageType ):
$packageType mixed

                public function supports($packageType)
{
    return $packageType === 'yii2-extension';
}

            
uninstall() public method
public uninstall( \Composer\Repository\InstalledRepositoryInterface $repo, \Composer\Package\PackageInterface $package ):
$repo \Composer\Repository\InstalledRepositoryInterface
$package \Composer\Package\PackageInterface

                public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
{
    $afterUninstall = function () use ($package) {
        // remove the package from yiisoft/extensions.php
        $this->removePackage($package);
        // remove links for Yii.php
        if ($package->getName() == 'yiisoft/yii2-dev') {
            $this->removeBaseYiiFiles();
        }
    };
    // uninstall the package the normal composer way
    $promise = parent::uninstall($repo, $package);
    // Composer v2 might return a promise here
    if ($promise instanceof PromiseInterface) {
        return $promise->then($afterUninstall);
    }
    // If not, execute the code right away as parent::uninstall executed synchronously (composer v1, or v2 without async)
    $afterUninstall();
}

            
update() public method
public update( \Composer\Repository\InstalledRepositoryInterface $repo, \Composer\Package\PackageInterface $initial, \Composer\Package\PackageInterface $target ):
$repo \Composer\Repository\InstalledRepositoryInterface
$initial \Composer\Package\PackageInterface
$target \Composer\Package\PackageInterface

                public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
{
    $afterUpdate = function () use ($initial, $target) {
        $this->removePackage($initial);
        $this->addPackage($target);
        // ensure the yii2-dev package also provides Yii.php in the same place as yii2 does
        if ($initial->getName() == 'yiisoft/yii2-dev') {
            $this->linkBaseYiiFiles();
        }
    };
    // update the package the normal composer way
    $promise = parent::update($repo, $initial, $target);
    // Composer v2 might return a promise here
    if ($promise instanceof PromiseInterface) {
        return $promise->then($afterUpdate);
    }
    // If not, execute the code right away as parent::update executed synchronously (composer v1, or v2 without async)
    $afterUpdate();
}