diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html
index c5527c14bc..0b63302eed 100644
--- a/phpBB/adm/style/acp_ext_list.html
+++ b/phpBB/adm/style/acp_ext_list.html
@@ -60,7 +60,7 @@
{L_DETAILS} |
- title="{enabled.actions.L_ACTION_EXPLAIN}">{enabled.actions.L_ACTION}
+ style="color: #bc2a4d;" title="{enabled.actions.L_ACTION_EXPLAIN}">{enabled.actions.L_ACTION}
|
|
@@ -88,7 +88,7 @@
- title="{disabled.actions.L_ACTION_EXPLAIN}">{disabled.actions.L_ACTION}
+ style="color: #bc2a4d;" title="{disabled.actions.L_ACTION_EXPLAIN}">{disabled.actions.L_ACTION}
|
|
diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php
index 5bdb381d1b..de98bfadb1 100644
--- a/phpBB/includes/acp/acp_extensions.php
+++ b/phpBB/includes/acp/acp_extensions.php
@@ -838,10 +838,7 @@ class acp_extensions
{
$this->output_actions('enabled', [
'UPDATE' => $this->u_catalog_action . '&action=update&extension=' . urlencode($block_vars['META_NAME']),
- 'REMOVE' => [
- 'url' => $this->u_catalog_action . '&action=remove&extension=' . urlencode($block_vars['META_NAME']),
- 'color' => '#BC2A4D;',
- ]
+ 'REMOVE' => $this->u_catalog_action . '&action=remove&extension=' . urlencode($block_vars['META_NAME']),
]);
}
}
@@ -922,10 +919,7 @@ class acp_extensions
{
$this->output_actions('disabled', [
'UPDATE' => $this->u_catalog_action . '&action=update&extension=' . urlencode($block_vars['META_NAME']),
- 'REMOVE' => [
- 'url' => $this->u_catalog_action . '&action=remove&extension=' . urlencode($block_vars['META_NAME']),
- 'color' => '#BC2A4D;',
- ]
+ 'REMOVE' => $this->u_catalog_action . '&action=remove&extension=' . urlencode($block_vars['META_NAME']),
]);
}
}
@@ -997,6 +991,7 @@ class acp_extensions
$this->output_actions('disabled', array(
'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name),
+ 'REMOVE' => $this->u_catalog_action . '&action=remove&extension=' . urlencode($block_vars['META_NAME']),
));
}
}
@@ -1009,11 +1004,12 @@ class acp_extensions
*/
private function output_actions($block, $actions)
{
- foreach ($actions as $lang => $url)
+ foreach ($actions as $action => $url)
{
$this->template->assign_block_vars($block . '.actions', [
- 'L_ACTION' => $this->user->lang('EXTENSION_' . $lang),
- 'L_ACTION_EXPLAIN' => (isset($this->user->lang['EXTENSION_' . $lang . '_EXPLAIN'])) ? $this->user->lang('EXTENSION_' . $lang . '_EXPLAIN') : '',
+ 'ACTION' => $action,
+ 'L_ACTION' => $this->user->lang('EXTENSION_' . $action),
+ 'L_ACTION_EXPLAIN' => (isset($this->user->lang['EXTENSION_' . $action . '_EXPLAIN'])) ? $this->user->lang('EXTENSION_' . $action . '_EXPLAIN') : '',
'U_ACTION' => $url,
]);
}
diff --git a/phpBB/phpbb/composer/installer.php b/phpBB/phpbb/composer/installer.php
index 9910cb5a08..3e6d87d46f 100644
--- a/phpBB/phpbb/composer/installer.php
+++ b/phpBB/phpbb/composer/installer.php
@@ -152,7 +152,9 @@ class installer
{
if (!$io)
{
+ $this->restore_cwd();
$io = new null_io();
+ $this->move_to_root();
}
$this->generate_ext_json_file($packages);
@@ -184,6 +186,7 @@ class installer
catch (\Exception $e)
{
$this->restore_ext_json_file();
+ $this->restore_cwd();
throw new runtime_exception('COMPOSER_CANNOT_INSTALL', [], $e);
}
@@ -191,6 +194,7 @@ class installer
if ($result !== 0)
{
$this->restore_ext_json_file();
+ $this->restore_cwd();
throw new runtime_exception($io->get_composer_error(), []);
}
@@ -587,6 +591,7 @@ class installer
$repositories[] = [
'type' => 'composer',
'url' => $repository,
+ 'canonical' => $this->packagist ? false : true,
];
}
}
diff --git a/phpBB/phpbb/composer/manager.php b/phpBB/phpbb/composer/manager.php
index d5fe8935cf..e36a32d1e9 100644
--- a/phpBB/phpbb/composer/manager.php
+++ b/phpBB/phpbb/composer/manager.php
@@ -89,7 +89,7 @@ class manager implements manager_interface
$managed_packages = array_merge($this->get_all_managed_packages(), $packages);
ksort($managed_packages);
- $this->installer->install($managed_packages, array_keys($packages), $io);
+ $this->installer->install($managed_packages, [], $io);
$this->post_install($packages, $io);
diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php
index ab02831209..a4d45506f4 100644
--- a/tests/functional/extension_acp_test.php
+++ b/tests/functional/extension_acp_test.php
@@ -76,7 +76,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case
$this->login();
$this->admin_login();
- $this->add_lang('acp/extensions');
+ $this->add_lang(['acp/common', 'acp/extensions']);
}
public function test_list()
@@ -254,6 +254,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case
$form = $crawler->selectButton('Submit')->form();
$form['minimum_stability']->select('dev');
+ $form['repositories'] = 'https://satis.phpbb.com/';
$crawler = self::submit($form);
$this->assertContainsLang('CONFIG_UPDATED', $crawler->filter('div[class="successbox"] > p')->text());
@@ -264,4 +265,114 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case
// Ensure catalog has any records in extensions list
$this->assertGreaterThan(0, $crawler->filter('tbody > tr > td > strong')->count());
}
+
+ public function test_extensions_catalog_installing_extension()
+ {
+ // Lets check page 6 where 'Scroll Page' and 'Scroll To Top' should be listed
+ $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=catalog&start=100&sid=' . $this->sid);
+ $this->assertContainsLang('ACP_EXTENSIONS_CATALOG', $this->get_content());
+
+ // Get Install links for both extensions
+ $scrollpage_install_link = $crawler->filter('tr')->reduce(
+ function ($node, $i)
+ {
+ return (bool) (strpos($node->text(), 'Scroll Page') !== false);
+ }
+ )->selectLink($this->lang('INSTALL'))->link();
+
+ $scrolltotop_install_link = $crawler->filter('tr')->reduce(
+ function ($node, $i)
+ {
+ return (bool) (strpos($node->text(), 'Scroll To Top') !== false);
+ }
+ )->selectLink($this->lang('INSTALL'))->link();
+
+ // Attempt to install vse/scrollpage extension
+ $crawler = self::$client->click($scrollpage_install_link);
+ $this->assertContainsLang('EXTENSIONS_INSTALLED', $crawler->filter('.successbox > p')->text());
+ // Assert there's console log output
+ $this->assertStringContainsString('Installing vse/scrollpage', $crawler->filter('.console-output > pre')->text());
+
+ // Attempt to install vse/scrolltotop extension
+ $crawler = self::$client->click($scrolltotop_install_link);
+ $this->assertContainsLang('EXTENSIONS_INSTALLED', $crawler->filter('.successbox > p')->text());
+ // Assert there's console log output
+ $this->assertStringContainsString('Installing vse/scrolltotop', $crawler->filter('.console-output > pre')->text());
+
+ // Ensure installed extension appears in available extensions list
+ $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
+ $this->assertStringContainsString('Scroll To Top', $crawler->filter('strong[title="vse/scrolltotop"]')->text());
+ $this->assertStringContainsString('Scroll Page', $crawler->filter('strong[title="vse/scrollpage"]')->text());
+ }
+
+ public function test_extensions_catalog_updating_extension()
+ {
+ // Enable 'Scroll Page' extension installed earlier
+ $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
+ $extension_enable_link = $crawler->filter('tr')->reduce(
+ function ($node, $i)
+ {
+ return (bool) (strpos($node->text(), 'Scroll Page') !== false);
+ }
+ )->selectLink($this->lang('EXTENSION_ENABLE'))->link();
+ $crawler = self::$client->click($extension_enable_link);
+ $form = $crawler->selectButton($this->lang('EXTENSION_ENABLE'))->form();
+ $crawler = self::submit($form);
+ $this->assertContainsLang('EXTENSION_ENABLE_SUCCESS', $crawler->filter('.successbox')->text());
+
+ // Update 'Scroll Page' enabled extension
+ $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
+ $scrollpage_update_link = $crawler->filter('tr')->reduce(
+ function ($node, $i)
+ {
+ return (bool) (strpos($node->text(), 'Scroll Page') !== false);
+ }
+ )->selectLink($this->lang('EXTENSION_UPDATE'))->link();
+ $crawler = self::$client->click($scrollpage_update_link);
+ $this->assertContainsLang('EXTENSIONS_UPDATED', $crawler->filter('.successbox > p')->text());
+ // Assert there's console log output
+ $this->assertStringContainsString('Updating packages', $crawler->filter('.console-output > pre')->text());
+
+ // Ensure installed extension still appears in available extensions list
+ $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
+ $this->assertStringContainsString('Scroll Page', $crawler->filter('strong[title="vse/scrollpage"]')->text());
+ }
+
+ public function test_extensions_catalog_removing_extension()
+ {
+ $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
+
+ // Check if both enabled and disabled extensions have 'Remove' action available
+ $scrollpage_remove_link = $crawler->filter('tr')->reduce(
+ function ($node, $i)
+ {
+ return (bool) (strpos($node->text(), 'Scroll Page') !== false);
+ }
+ )->selectLink($this->lang('EXTENSION_REMOVE'))->link();
+
+ $scrolltotop_remove_link = $crawler->filter('tr')->reduce(
+ function ($node, $i)
+ {
+ return (bool) (strpos($node->text(), 'Scroll To Top') !== false);
+ }
+ )->selectLink($this->lang('EXTENSION_REMOVE'))->link();
+
+ // Test extensions removal
+ // Remove 'Scroll Page' enabled extension
+ $crawler = self::$client->click($scrollpage_remove_link);
+ $this->assertContainsLang('EXTENSIONS_REMOVED', $crawler->filter('.successbox > p')->text());
+ // Assert there's console log output
+ $this->assertStringContainsString('Deleting ext/vse/scrollpage', $crawler->filter('.console-output > pre')->text());
+
+ // Remove 'Scroll To Top' disabled extension
+ $crawler = self::$client->click($scrolltotop_remove_link);
+ $this->assertContainsLang('EXTENSIONS_REMOVED', $crawler->filter('.successbox > p')->text());
+ // Assert there's console log output
+ $this->assertStringContainsString('Deleting ext/vse/scrolltotop', $crawler->filter('.console-output > pre')->text());
+
+ // Ensure removed extensions do not appear in available extensions list
+ $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
+ $this->assertStringNotContainsString('Scroll Page', $this->get_content());
+ $this->assertStringNotContainsString('Scroll To Top', $this->get_content());
+ }
}