diff options
Diffstat (limited to 'phpBB/phpbb/composer/manager.php')
-rw-r--r-- | phpBB/phpbb/composer/manager.php | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/phpBB/phpbb/composer/manager.php b/phpBB/phpbb/composer/manager.php new file mode 100644 index 0000000000..43ea8a2503 --- /dev/null +++ b/phpBB/phpbb/composer/manager.php @@ -0,0 +1,332 @@ +<?php +/** + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited <https://www.phpbb.com> + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer; + +use Composer\IO\IOInterface; +use phpbb\cache\driver\driver_interface; +use phpbb\composer\exception\runtime_exception; + +/** + * Class to manage packages through composer. + */ +class manager implements manager_interface +{ + /** + * @var installer Composer packages installer + */ + protected $installer; + + /** + * @var driver_interface Cache instance + */ + protected $cache; + + /** + * @var string Type of packages (phpbb-packages per example) + */ + protected $package_type; + + /** + * @var string Prefix used for the exception's language string + */ + protected $exception_prefix; + + /** + * @var array Caches the managed packages list (for the current type) + */ + private $managed_packages; + + /** + * @var array Caches the managed packages list (for all phpBB types) + */ + private $all_managed_packages; + + /** + * @var array Caches the available packages list + */ + private $available_packages; + + /** + * @param installer $installer Installer object + * @param driver_interface $cache Cache object + * @param string $package_type Composer type of managed packages + * @param string $exception_prefix Exception prefix to use + */ + public function __construct(installer $installer, driver_interface $cache, $package_type, $exception_prefix) + { + $this->installer = $installer; + $this->cache = $cache; + $this->package_type = $package_type; + $this->exception_prefix = $exception_prefix; + } + + /** + * {@inheritdoc} + */ + public function install(array $packages, IOInterface $io = null) + { + $packages = $this->normalize_version($packages); + + $already_managed = array_intersect(array_keys($this->get_managed_packages()), array_keys($packages)); + if (count($already_managed) !== 0) + { + throw new runtime_exception($this->exception_prefix, 'ALREADY_INSTALLED', [implode('|', $already_managed)]); + } + + $this->pre_install($packages, $io); + + $managed_packages = array_merge($this->get_all_managed_packages(), $packages); + ksort($managed_packages); + + $this->installer->install($managed_packages, array_keys($packages), $io); + + $this->post_install($packages, $io); + + $this->managed_packages = null; + } + + /** + * Hook called before installing the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function pre_install(array $packages, IOInterface $io = null) + { + } + + /** + * Hook called after installing the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function post_install(array $packages, IOInterface $io = null) + { + } + + /** + * {@inheritdoc} + */ + public function update(array $packages, IOInterface $io = null) + { + $packages = $this->normalize_version($packages); + + $not_managed = array_diff_key($packages, $this->get_managed_packages()); + if (count($not_managed) !== 0) + { + throw new runtime_exception($this->exception_prefix, 'NOT_MANAGED', [implode('|', array_keys($not_managed))]); + } + + $this->pre_update($packages, $io); + + $managed_packages = array_merge($this->get_all_managed_packages(), $packages); + ksort($managed_packages); + + $this->installer->install($managed_packages, array_keys($packages), $io); + + $this->post_update($packages, $io); + } + + /** + * Hook called before updating the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function pre_update(array $packages, IOInterface $io = null) + { + } + + /** + * Hook called after updating the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function post_update(array $packages, IOInterface $io = null) + { + } + + /** + * {@inheritdoc} + */ + public function remove(array $packages, IOInterface $io = null) + { + $packages = $this->normalize_version($packages); + + $not_managed = array_diff_key($packages, $this->get_managed_packages()); + if (count($not_managed) !== 0) + { + throw new runtime_exception($this->exception_prefix, 'NOT_MANAGED', [implode('|', array_keys($not_managed))]); + } + + $this->pre_remove($packages, $io); + + $managed_packages = array_diff_key($this->get_all_managed_packages(), $packages); + ksort($managed_packages); + + $this->installer->install($managed_packages, array_keys($packages), $io); + + $this->post_remove($packages, $io); + + $this->managed_packages = null; + } + + /** + * Hook called before removing the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function pre_remove(array $packages, IOInterface $io = null) + { + } + + /** + * Hook called after removing the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function post_remove(array $packages, IOInterface $io = null) + { + } + + /** + * {@inheritdoc} + */ + public function is_managed($package) + { + return array_key_exists($package, $this->get_managed_packages()); + } + + /** + * {@inheritdoc} + */ + public function get_managed_packages() + { + if ($this->managed_packages === null) + { + $this->managed_packages = $this->installer->get_installed_packages($this->package_type); + } + + return $this->managed_packages; + } + + /** + * {@inheritdoc} + */ + public function get_all_managed_packages() + { + if ($this->all_managed_packages === null) + { + $this->all_managed_packages = $this->installer->get_installed_packages(explode(',', installer::PHPBB_TYPES)); + } + + return $this->all_managed_packages; + } + + /** + * {@inheritdoc} + */ + public function get_available_packages() + { + if ($this->available_packages === null) + { + $this->available_packages = $this->cache->get('_composer_' . $this->package_type . '_available'); + + if (!$this->available_packages) + { + $this->available_packages = $this->installer->get_available_packages($this->package_type); + $this->cache->put('_composer_' . $this->package_type . '_available', $this->available_packages, 24*60*60); + } + } + + return $this->available_packages; + } + + /** + * {@inheritdoc} + */ + public function reset_cache() + { + $this->cache->destroy('_composer_' . $this->package_type . '_available'); + + $this->available_packages = null; + $this->managed_packages = null; + $this->all_managed_packages = null; + } + + /** + * {@inheritdoc} + */ + public function start_managing($package, $io) + { + throw new \phpbb\exception\runtime_exception('COMPOSER_UNSUPPORTED_OPERATION', (array) $this->package_type); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + return $this->installer->check_requirements(); + } + + /** + * Normalize a packages/version array. Every entry can have 3 different forms: + * - $package => $version + * - $indice => $package:$version + * - $indice => $package + * They are converted to he form: + * - $package => $version ($version is set to '*' for the third form) + * + * @param array $packages + * + * @return array + */ + protected function normalize_version(array $packages) + { + $normalized_packages = []; + + foreach ($packages as $package => $version) + { + if (is_numeric($package)) + { + if (strpos($version, ':') !== false) + { + $parts = explode(':', $version); + $normalized_packages[$parts[0]] = $parts[1]; + } + else + { + $normalized_packages[$version] = '*'; + } + } + else + { + $normalized_packages[$package] = $version; + } + } + + return $normalized_packages; + } +} |