From d5672303a359be027c403e329d97193884161897 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 13 Sep 2015 18:44:50 +0200 Subject: [PATCH] [ticket/11150] Install from ACP PHPBB3-11150 --- phpBB/adm/style/detailled_message_body.html | 14 ++ phpBB/includes/acp/acp_extensions.php | 56 +++++++- phpBB/phpbb/composer/installer.php | 126 ++++++++++++++---- .../composer/io/translate_composer_trait.php | 12 ++ 4 files changed, 180 insertions(+), 28 deletions(-) create mode 100644 phpBB/adm/style/detailled_message_body.html diff --git a/phpBB/adm/style/detailled_message_body.html b/phpBB/adm/style/detailled_message_body.html new file mode 100644 index 0000000000..001fe921e1 --- /dev/null +++ b/phpBB/adm/style/detailled_message_body.html @@ -0,0 +1,14 @@ + + +
+ {%- if MESSAGE_DETAIL_LEGEND -%} + {{ MESSAGE_DETAIL_LEGEND|nl2br }} + {%- endif -%} +
{{ MESSAGE_DETAIL }}
+
+
+

{{ MESSAGE_TITLE }}

+

{{ MESSAGE_TEXT }}

+
+ + diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index 9506a168a4..a23ced9daa 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -427,18 +427,65 @@ class acp_extensions 'warning' => new \Symfony\Component\Console\Formatter\OutputFormatterStyle('black', 'yellow') ]); - $composer_io = new \phpbb\composer\io\web_io($language, '', \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL, $formatter); + $composer_io = new \phpbb\composer\io\web_io($language, '', \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_VERBOSE, $formatter); try { + $this->request->enable_super_globals(); $composer_manager->install((array) $extension, $composer_io); + $this->request->disable_super_globals(); } catch (\phpbb\exception\runtime_exception $e) { - trigger_error($language->lang_array($e->getMessage(), $e->get_parameters()) . '

' . $composer_io->getOutput() . adm_back_link($this->u_action), E_USER_WARNING); - } + $this->tpl_name = 'detailled_message_body'; - trigger_error($language->lang('EXTENSIONS_INSTALLED') . '

' . $composer_io->getOutput() . adm_back_link($this->u_action)); + if ($e->getPrevious()) + { + $message_title = $language->lang_array($e->getMessage(), $e->get_parameters()); + + if ($e->getPrevious() instanceof \phpbb\exception\exception_interface) + { + $message_text = $language->lang_array($e->getPrevious()->getMessage(), $e->getPrevious()->get_parameters()) . adm_back_link($this->u_action); + } + else + { + $message_text = $e->getPrevious()->getMessage(); + if (strpos($message_text, 'ext/') === 0 && strpos($message_text, 'does not exist and could not be created.') !== false) + {dump($e->getPrevious()->getTraceAsString()); + $message_text = $language->lang('EXTENSIONS_DIR_NOT_WRITABLE'); + } + $message_text .= adm_back_link($this->u_action); + } + } + else + { + $message_title = $language->lang('INFORMATION'); + $message_text = $language->lang_array($e->getMessage(), $e->get_parameters()) . adm_back_link($this->u_action); + } + + $this->template->assign_vars(array( + 'MESSAGE_TITLE' => $message_title, + 'MESSAGE_TEXT' => $message_text, + 'MESSAGE_DETAIL' => $composer_io->getOutput(), + 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'), + 'S_USER_ERROR' => true, + ) + ); + + return; + } + $this->tpl_name = 'detailled_message_body'; + + $this->template->assign_vars(array( + 'MESSAGE_TITLE' => $language->lang('ACP_EXTENSIONS_INSTALL'), + 'MESSAGE_TEXT' => $language->lang('EXTENSIONS_INSTALLED') . adm_back_link($this->u_action), + 'MESSAGE_DETAIL' => $composer_io->getOutput(), + 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'), + 'S_USER_NOTICE' => true, + ) + ); + + return; break; case 'remove': @@ -452,6 +499,7 @@ class acp_extensions $this->request->enable_super_globals(); $this->template->assign_var('extensions', $manager->get_available_packages()); + $this->template->assign_var('U_ACTION', $this->u_action); $this->request->disable_super_globals(); break; } diff --git a/phpBB/phpbb/composer/installer.php b/phpBB/phpbb/composer/installer.php index 442dcc3f43..856ef2f6eb 100644 --- a/phpBB/phpbb/composer/installer.php +++ b/phpBB/phpbb/composer/installer.php @@ -74,7 +74,7 @@ class installer $this->packages_vendor_dir = $config['exts_composer_vendor_dir']; } - $this->repositories = ['http://phpbb.local/ext/phpbb/titania/composer/']; + $this->repositories = [/*'http://phpbb.local/ext/phpbb/titania/composer/'*/]; $this->packagist = true; $this->root_path = $root_path; @@ -91,6 +91,36 @@ class installer * @throws runtime_exception */ public function install(array $packages, $whitelist, IOInterface $io = null) + { + // The composer installers works with a path relative to the current directory + $original_working_dir = getcwd(); + chdir($this->root_path); + + try + { + $this->do_install($packages, $whitelist, $io); + chdir($original_working_dir); + } + catch (\Exception $e) + { + chdir($original_working_dir); + throw $e; + } + } + + /** + * Update the current installed set of packages + * + * /!\ Doesn't change the current working directory + * + * @param array $packages Packages to install. + * Each entry may be a name or an array associating a version constraint to a name + * @param array $whitelist White-listed packages (packages that can be installed/updated/removed) + * @param IOInterface $io IO object used for the output + * + * @throws runtime_exception + */ + protected function do_install(array $packages, $whitelist, IOInterface $io = null) { if (!$io) { @@ -99,9 +129,6 @@ class installer $this->generate_ext_json_file($packages); - $original_vendor_dir = getenv('COMPOSER_VENDOR_DIR'); - putenv('COMPOSER_VENDOR_DIR=' . $this->root_path . $this->packages_vendor_dir); - $composer = Factory::create($io, $this->get_composer_ext_json_filename(), false); $install = \Composer\Installer::create($io, $composer); @@ -119,21 +146,15 @@ class installer ->setDumpAutoloader(false) ->setPreferStable(true) ->setRunScripts(false) - ->setDryRun(true); + ->setDryRun(false); try { $result = $install->run(); - - putenv('COMPOSER_VENDOR_DIR=' . $original_vendor_dir); - //$output = $io->getOutput(); - //$error_pos = strpos($output, 'Your requirements could not be resolved to an installable set of packages.'); } catch (\Exception $e) { - - putenv('COMPOSER_VENDOR_DIR=' . $original_vendor_dir); - throw new runtime_exception('Cannot install packages', [], $e); + throw new runtime_exception('COMPOSER_CANNOT_INSTALL', [], $e); } if ($result !== 0) @@ -151,14 +172,40 @@ class installer */ public function get_installed_packages($types) { - $types = (array) $types; + // The composer installers works with a path relative to the current directory + $original_working_dir = getcwd(); + chdir($this->root_path); - $original_vendor_dir = getenv('COMPOSER_VENDOR_DIR'); + try + { + $result = $this->do_get_installed_packages($types); + chdir($original_working_dir); + } + catch (\Exception $e) + { + chdir($original_working_dir); + throw $e; + } + + return $result; + } + + /** + * Returns the list of currently installed packages + * + * /!\ Doesn't change the current working directory + * + * @param string|array $types Returns only the packages with the given type(s) + * + * @return array The installed packages associated to their version. + */ + protected function do_get_installed_packages($types) + { + $types = (array) $types; try { $io = new NullIO(); - putenv('COMPOSER_VENDOR_DIR=' . $this->root_path . $this->packages_vendor_dir); $composer = Factory::create($io, $this->get_composer_ext_json_filename(), false); $installed = []; @@ -173,16 +220,43 @@ class installer } } - putenv('COMPOSER_VENDOR_DIR=' . $original_vendor_dir); return $installed; } catch (\Exception $e) { - putenv('COMPOSER_VENDOR_DIR=' . $original_vendor_dir); return []; } } + /** + * Gets the list of the available packages of the configured type in the configured repositories + * + * /!\ Doesn't change the current working directory + * + * @param string $type Returns only the packages with the given type + * + * @return array The name of the available packages, associated to their definition. Ordered by name. + */ + public function get_available_packages($type) + { + // The composer installers works with a path relative to the current directory + $original_working_dir = getcwd(); + chdir($this->root_path); + + try + { + $result = $this->do_get_available_packages($type); + chdir($original_working_dir); + } + catch (\Exception $e) + { + chdir($original_working_dir); + throw $e; + } + + return $result; + } + /** * Gets the list of the available packages of the configured type in the configured repositories * @@ -190,14 +264,13 @@ class installer * * @return array The name of the available packages, associated to their definition. Ordered by name. */ - public function get_available_packages($type) + protected function do_get_available_packages($type) { try { - $this->generate_ext_json_file($this->get_installed_packages(self::PHPBB_TYPES)); + $this->generate_ext_json_file($this->do_get_installed_packages(self::PHPBB_TYPES)); $io = new NullIO(); - $composer = Factory::create($io, $this->get_composer_ext_json_filename(), false); /** @var LinkConstraintInterface $core_constraint */ @@ -350,10 +423,11 @@ class installer protected function generate_ext_json_file(array $packages) { $io = new NullIO(); - $composer = Factory::create($io, $this->root_path . 'composer.json', false); + + $composer = Factory::create($io, null, false); $core_packages = $this->get_core_packages($composer); - $core_json_data = [ + $ext_json_data = [ 'require' => array_merge( ['php' => $this->get_core_php_requirement($composer)], $core_packages, @@ -361,10 +435,14 @@ class installer $packages), 'replace' => $core_packages, 'repositories' => $this->get_composer_repositories(), + 'config' => [ + 'cache-dir' => 'store/composer', + 'vendor-dir'=> $this->packages_vendor_dir, + ], ]; $json_file = new JsonFile($this->get_composer_ext_json_filename()); - $json_file->write($core_json_data); + $json_file->write($ext_json_data); } /** @@ -452,7 +530,7 @@ class installer */ protected function get_composer_ext_json_filename() { - return $this->root_path . $this->composer_filename; + return $this->composer_filename; } /** diff --git a/phpBB/phpbb/composer/io/translate_composer_trait.php b/phpBB/phpbb/composer/io/translate_composer_trait.php index 376ef28a80..e76244b977 100644 --- a/phpBB/phpbb/composer/io/translate_composer_trait.php +++ b/phpBB/phpbb/composer/io/translate_composer_trait.php @@ -50,6 +50,10 @@ trait translate_composer_trait $lang_key = 'COMPOSER_DELETING'; $parameters = [$elements[1]]; } + else + { + dump('WRITE | ' . $message); + } //$translated_message = $this->language->lang_array($lang_key, $parameters); $translated_message = call_user_func_array([$this->language, 'lang'], array_merge((array)$lang_key, $parameters)); @@ -153,10 +157,18 @@ trait translate_composer_trait { continue; } + else if ($message === ' Extracting archive') + { + continue; + } else if (empty($message)) { continue; } + else + { + dump('WRITE ERROR | ' . $message); + } //$translated_message = $this->language->lang_array($lang_key, $parameters); $translated_message = call_user_func_array([$this->language, 'lang'], array_merge((array)$lang_key, $parameters));