1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-03-23 17:10:53 +01:00

[ticket/11150] Add extension:start-managing command

PHPBB3-11150
This commit is contained in:
Tristan Darricau 2015-09-11 18:01:56 +02:00 committed by Tristan Darricau
parent 779c9c8552
commit 00229c20f0
No known key found for this signature in database
GPG Key ID: 817043C2E29DB881
12 changed files with 331 additions and 32 deletions

View File

@ -183,6 +183,14 @@ services:
tags:
- { name: console.command }
console.command.extension.start_managing:
class: phpbb\console\command\extension\start_managing
arguments:
- @user
- @ext.composer.manager
tags:
- { name: console.command }
console.command.extension.update:
class: phpbb\console\command\extension\update
arguments:

View File

@ -22,6 +22,7 @@ services:
arguments:
- @ext.composer.installer
- @ext.manager
- @filesystem
- phpbb-extension
- EXTENSIONS_

View File

@ -240,6 +240,9 @@ $lang = array_merge($lang, array(
'EXCEPTION' => 'Exception',
'COLOUR_SWATCH' => 'Web-safe colour swatch',
'COMPOSER_UNSUPPORTED_OPERATION' => 'Operation unsupported for the package type “%s”.',
'CONFIG_UPDATED' => 'Configuration updated successfully.',
'CRON_LOCK_ERROR' => 'Could not obtain cron lock.',
'CRON_NO_SUCH_TASK' => 'Could not find cron task “%s”.',

View File

@ -35,6 +35,16 @@ if (empty($lang) || !is_array($lang))
// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
$lang = array_merge($lang, array(
'EXTENSION_ALREADY_INSTALLED' => 'The “%s” extension has already been installed.',
'EXTENSION_ALREADY_INSTALLED_MANUALLY' => 'The “%s” extension has already been installed manually.',
'EXTENSION_ALREADY_MANAGED' => 'The “%s” extension has already been installed manually.',
'EXTENSION_CANNOT_MANAGE_FILESYSTEM_ERROR' => 'The “%s” extension cannot be managed because the old files cannot be removed.',
'EXTENSION_CANNOT_MANAGE_INSTALL_ERROR' => 'The “%s” extension cannot be installed. The old extension have been restored.',
'EXTENSION_MANAGED_WITH_CLEAN_ERROR' => 'The “%1$s” extension has been installed but an error occurred and the old files have not been removed. You might want to delete the “%2$s” files manually.',
'EXTENSION_MANAGED_WITH_ENABLE_ERROR' => 'The “%s” extension has been installed but an error occurred when re-enabling it.',
'EXTENSION_NOT_INSTALLED' => 'The “%s” extension is not installed.',
'EXTENSION' => 'Extension',
'EXTENSIONS' => 'Extensions',
'EXTENSIONS_ADMIN' => 'Extensions Manager',

View File

@ -0,0 +1,35 @@
<?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\exception;
/**
* Packaged managed with success but error occurred when cleaning the filesystem
*/
class managed_with_clean_error_exception extends managed_with_error_exception
{
/**
* Constructor
*
* @param string $prefix The language string prefix
* @param string $message The Exception message to throw (must be a language variable).
* @param array $parameters The parameters to use with the language var.
* @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining.
* @param integer $code The Exception code.
*/
public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0)
{
parent::__construct($prefix . $message, $parameters, $previous, $code);
}
}

View File

@ -0,0 +1,35 @@
<?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\exception;
/**
* Packaged managed with success but error occurred when re-enabling the extension
*/
class managed_with_enable_error_exception extends managed_with_error_exception
{
/**
* Constructor
*
* @param string $prefix The language string prefix
* @param string $message The Exception message to throw (must be a language variable).
* @param array $parameters The parameters to use with the language var.
* @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining.
* @param integer $code The Exception code.
*/
public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0)
{
parent::__construct($prefix . $message, $parameters, $previous, $code);
}
}

View File

@ -0,0 +1,35 @@
<?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\exception;
/**
* Packaged managed with success but errored at some point
*/
class managed_with_error_exception extends runtime_exception
{
/**
* Constructor
*
* @param string $prefix The language string prefix
* @param string $message The Exception message to throw (must be a language variable).
* @param array $parameters The parameters to use with the language var.
* @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining.
* @param integer $code The Exception code.
*/
public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0)
{
parent::__construct($prefix . $message, $parameters, $previous, $code);
}
}

View File

@ -13,8 +13,13 @@
namespace phpbb\composer;
use phpbb\composer\exception\managed_with_clean_error_exception;
use phpbb\composer\exception\managed_with_enable_error_exception;
use phpbb\composer\exception\managed_with_error_exception;
use phpbb\composer\exception\runtime_exception;
use phpbb\extension\manager as ext_manager;
use phpbb\filesystem\exception\filesystem_exception;
use phpbb\filesystem\filesystem;
/**
* Class to safely manage extensions through composer.
@ -26,15 +31,22 @@ class extension_manager extends manager
*/
protected $extension_manager;
/**
* @var \phpbb\filesystem\filesystem
*/
protected $filesystem;
/**
* @param installer $installer Installer object
* @param ext_manager $extension_manager phpBB extension manager
* @param filesystem $filesystem Filesystem object
* @param string $package_type Composer type of managed packages
* @param string $exception_prefix Exception prefix to use
*/
public function __construct(installer $installer, ext_manager $extension_manager, $package_type, $exception_prefix)
public function __construct(installer $installer, ext_manager $extension_manager, filesystem $filesystem, $package_type, $exception_prefix)
{
$this->extension_manager = $extension_manager;
$this->filesystem = $filesystem;
parent::__construct($installer, $package_type, $exception_prefix);
}
@ -60,4 +72,66 @@ class extension_manager extends manager
$this->do_install($packages);
}
/**
* {@inheritdoc}
*/
public function start_managing($package)
{
if (!$this->extension_manager->is_available($package))
{
throw new runtime_exception($this->exception_prefix, 'NOT_INSTALLED', [$package]);
}
if ($this->is_managed($package))
{
throw new runtime_exception($this->exception_prefix, 'ALREADY_MANAGED', [$package]);
}
$enabled = false;
if ($this->extension_manager->is_enabled($package))
{
$enabled = true;
$this->extension_manager->disable($package);
}
$ext_path = $this->extension_manager->get_extension_path($package);
$backup_path = rtrim($ext_path, '/') . '__backup__';
try
{
$this->filesystem->rename($ext_path, $backup_path);
}
catch (filesystem_exception $e)
{
throw new runtime_exception($this->exception_prefix, 'CANNOT_MANAGE_FILESYSTEM_ERROR', [$package], $e);
}
try
{
$this->install((array) $package);
$this->filesystem->remove($backup_path);
}
catch (runtime_exception $e)
{
$this->filesystem->rename($backup_path, $ext_path);
throw new runtime_exception($this->exception_prefix, 'CANNOT_MANAGE_INSTALL_ERROR', [$package], $e);
}
catch (filesystem_exception $e)
{
throw new managed_with_clean_error_exception($this->exception_prefix, 'MANAGED_WITH_CLEAN_ERROR', [$package, $backup_path], $e);
}
if ($enabled)
{
try
{
$this->extension_manager->enable($package);
}
catch (\Exception $e)
{
throw new managed_with_enable_error_exception($this->exception_prefix, 'MANAGED_WITH_ENABLE_ERROR', [$package], $e);
}
}
}
}

View File

@ -73,6 +73,9 @@ class installer
$this->packages_vendor_dir = $config['exts_composer_vendor_dir'];
}
$this->repositories = ['http://phpbb.local/ext/phpbb/titania/composer/'];
$this->packagist = true;
$this->root_path = $root_path;
}
@ -214,12 +217,18 @@ class installer
{
$packages = $repository->findPackages($package);
$package = array_pop($packages);
if (isset($available[$package->getName()]))
{
continue;
}
$available[$package->getName()] = ['name' => $package->getPrettyName()];
if ($package instanceof CompletePackage)
{
$available[$package->getName()]['description'] = $package->getDescription();
$available[$package->getName()]['url'] = $package->getHomepage();
$available[$package->getName()]['url'] = $package->getDistUrl();//getHomepage();
}
}
}
@ -236,7 +245,7 @@ class installer
if ($package instanceof CompletePackage)
{
$available[$package->getName()]['description'] = $package->getDescription();
$available[$package->getName()]['url'] = $package->getHomepage();
$available[$package->getName()]['url'] = $package->getDistUrl();//getHomepage();
}
}
}

View File

@ -63,11 +63,7 @@ class manager implements manager_interface
}
/**
* Installs (if necessary) a set of packages
*
* @param array $packages Packages to install.
* Each entry may be a name or an array associating a version constraint to a name
* @throws runtime_exception
* {@inheritdoc}
*/
public function install(array $packages)
{
@ -98,11 +94,7 @@ class manager implements manager_interface
}
/**
* Updates or installs a set of packages
*
* @param array $packages Packages to update.
* Each entry may be a name or an array associating a version constraint to a name
* @throws runtime_exception
* {@inheritdoc}
*/
public function update(array $packages)
{
@ -122,11 +114,7 @@ class manager implements manager_interface
}
/**
* Removes a set of packages
*
* @param array $packages Packages to remove.
* Each entry may be a name or an array associating a version constraint to a name
* @throws runtime_exception
* {@inheritdoc}
*/
public function remove(array $packages)
{
@ -148,10 +136,7 @@ class manager implements manager_interface
}
/**
* Tells whether or not a package is managed by Composer.
*
* @param string $package Package name
* @return bool
* {@inheritdoc}
*/
public function is_managed($package)
{
@ -159,9 +144,7 @@ class manager implements manager_interface
}
/**
* Returns the list of managed packages for the current type
*
* @return array The managed packages associated to their version.
* {@inheritdoc}
*/
public function get_managed_packages()
{
@ -174,9 +157,7 @@ class manager implements manager_interface
}
/**
* Returns the list of managed packages for all phpBB types
*
* @return array The managed packages associated to their version.
* {@inheritdoc}
*/
public function get_all_managed_packages()
{
@ -189,9 +170,7 @@ class manager implements manager_interface
}
/**
* Returns the list of available packages
*
* @return array The name of the available packages, associated to their definition. Ordered by name.
* {@inheritdoc}
*/
public function get_available_packages()
{
@ -203,6 +182,14 @@ class manager implements manager_interface
return $this->available_packages;
}
/**
* {@inheritdoc}
*/
public function start_managing($package)
{
throw new \phpbb\exception\runtime_exception('COMPOSER_UNSUPPORTED_OPERATION', (array) $this->package_type);
}
protected function normalize_version($packages)
{
$normalized_packages = [];

View File

@ -54,16 +54,34 @@ interface manager_interface
public function is_managed($packages);
/**
* Returns the list of managed packages
* Returns the list of managed packages for the current type
*
* @return array The managed packages associated to their version.
*/
public function get_managed_packages();
/**
* Returns the list of managed packages for all phpBB types
*
* @return array The managed packages associated to their version.
*/
public function get_all_managed_packages();
/**
* Returns the list of available packages
*
* @return array The name of the available packages, associated to their definition. Ordered by name.
*/
public function get_available_packages();
/**
* Start managing a manually installed package
*
* Remove a package installed manually and reinstall it using composer.
*
* @param string $package Package to manage
*
* @throws runtime_exception
*/
public function start_managing($package);
}

View File

@ -0,0 +1,84 @@
<?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\console\command\extension;
use phpbb\composer\exception\managed_with_error_exception;
use phpbb\composer\manager;
use phpbb\composer\manager_interface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
class start_managing extends \phpbb\console\command\command
{
/**
* @var manager_interface Composer extensions manager
*/
protected $manager;
public function __construct(\phpbb\user $user, manager_interface $manager)
{
$this->manager = $manager;
$user->add_lang('acp/extensions');
parent::__construct($user);
}
/**
* Sets the command name and description
*
* @return null
*/
protected function configure()
{
$this
->setName('extension:start-managing')
->setDescription($this->user->lang('CLI_DESCRIPTION_EXTENSION_START_MANAGING'))
->addArgument(
'extension',
InputArgument::REQUIRED,
$this->user->lang('CLI_DESCRIPTION_EXTENSION_START_MANAGING'))
;
}
/**
* Executes the command extension:install
*
* @param InputInterface $input
* @param OutputInterface $output
* @return integer
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$extension = $input->getArgument('extension');
try
{
$this->manager->start_managing($extension);
}
catch (managed_with_error_exception $e)
{
$io->warning(call_user_func_array([$this->user, 'lang'], [$e->getMessage(), $e->get_parameters()]));
return 1;
}
$io->success('The extension ' . $extension . ' is now managed automatically.');
return 0;
}
}