From d120d4508c3bfa2f19eb0f3d93efe9a9c829c0e4 Mon Sep 17 00:00:00 2001 From: ECYaz Date: Wed, 29 Jul 2026 22:18:03 -0400 Subject: [PATCH] Fix the style demo installation The demo board hook fatals on any current 3.3 board: acp_styles logs the installation through $phpbb_log->add() using the session's user id and ip, and style_demo_install.php never starts a session. The hook predates that core change; add_log() used to guard against an empty user. Begin a session before running the manager. The failure also surfaced badly on the Titania side. The hook's error page raised a warning inside file_get_contents() that error handlers convert to an exception, so the moderator saw a broken AJAX reply instead of a result, and a failed installation on the approval path aborted the page. Degrade a failed hook call to the existing error result instead, and answer the manage page's install request with a proper message when no URL was produced. Declares the two properties the demo classes created dynamically. --- contribution/style/demo/manager.php | 14 +++++++++++- contribution/style/type.php | 22 +++++++++++++------ controller/contribution/manage.php | 8 +++++++ language/en/contributions.php | 1 + .../phpBB_3.3.x/style_demo_install.php | 6 +++++ misc/style_demo_hooks/style_demo_hook.php | 3 +++ 6 files changed, 46 insertions(+), 8 deletions(-) diff --git a/contribution/style/demo/manager.php b/contribution/style/demo/manager.php index e25259be9..2933ee645 100644 --- a/contribution/style/demo/manager.php +++ b/contribution/style/demo/manager.php @@ -32,6 +32,9 @@ class manager /** @var \phpbb\db\db_interface */ protected $db; + /** @var string */ + protected $table_prefix; + /** @var int */ protected $branch; @@ -151,9 +154,18 @@ protected function perform_action($action) $hook_url = $this->ext_config->demo_style_hook[$this->branch]; $context = stream_context_create($options); - $result = file_get_contents($hook_url, false, $context, 0, 50); + // A failing hook must degrade to an error result; the warning would + // otherwise be turned into an exception and lose the JSON reply. + $result = @file_get_contents($hook_url, false, $context, 0, 50); $this->delete_auth_key($key); + if ($result === false) + { + return array( + 'id' => 0, + 'error' => $this->user->lang('UNKNOWN_ERROR'), + ); + } return $this->get_result($result); } diff --git a/contribution/style/type.php b/contribution/style/type.php index c151f2f29..ff9385281 100644 --- a/contribution/style/type.php +++ b/contribution/style/type.php @@ -208,17 +208,25 @@ public function install_demo(\titania_contribution $contrib, \titania_revision $ $demo_url = ''; - if ($this->demo_manager->configure($branch, $contrib, $package)) + // A demo failure must not abort the approval or the AJAX reply. + try { - $result = $this->demo_manager->install(); - - if (empty($result['error'])) + if ($this->demo_manager->configure($branch, $contrib, $package)) { - $demo_url = $this->demo_manager->get_demo_url($branch, $result['id']); - $contrib->set_demo_url($branch, $demo_url); - $contrib->submit(); + $result = $this->demo_manager->install(); + + if (empty($result['error'])) + { + $demo_url = $this->demo_manager->get_demo_url($branch, $result['id']); + $contrib->set_demo_url($branch, $demo_url); + $contrib->submit(); + } } } + catch (\Throwable $e) + { + $demo_url = ''; + } $package->cleanup(); return $demo_url; diff --git a/controller/contribution/manage.php b/controller/contribution/manage.php index a4ba5f753..3ba079cf3 100644 --- a/controller/contribution/manage.php +++ b/controller/contribution/manage.php @@ -629,6 +629,14 @@ protected function install_demo($branch) $revision->__set_array($this->contrib->download[$branch]); $demo_url = $this->contrib->type->install_demo($this->contrib, $revision); } + + if ($demo_url === '') + { + return array( + 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'), + 'MESSAGE_TEXT' => $this->user->lang('DEMO_INSTALL_FAILED'), + ); + } return array( 'url' => $demo_url, ); diff --git a/language/en/contributions.php b/language/en/contributions.php index b704695d3..35c9bdca8 100644 --- a/language/en/contributions.php +++ b/language/en/contributions.php @@ -101,6 +101,7 @@ 'DELETE_CONTRIBUTION_EXPLAIN' => 'Permanently remove this contribution (use the contribution status field if you need to hide it).', 'DELETE_REVISION' => 'Delete Revision', 'DELETE_REVISION_EXPLAIN' => 'Permanently remove this revision (use the revision status field if you need to hide it).', + 'DEMO_INSTALL_FAILED' => 'The style could not be installed on the demo board.', 'DEMO_URL' => 'Demo URL', 'DEMO_URL_EXPLAIN' => 'Location of the demonstration', 'DEPENDENCIES' => 'Dependencies', diff --git a/misc/style_demo_hooks/phpBB_3.3.x/style_demo_install.php b/misc/style_demo_hooks/phpBB_3.3.x/style_demo_install.php index 46a0f2030..683941d8c 100644 --- a/misc/style_demo_hooks/phpBB_3.3.x/style_demo_install.php +++ b/misc/style_demo_hooks/phpBB_3.3.x/style_demo_install.php @@ -20,6 +20,12 @@ include($phpbb_root_path . 'includes/style_demo_manager.' . $phpEx); include($phpbb_root_path . 'includes/style_demo_hook.' . $phpEx); +// acp_styles logs the installation and reads the user's id and ip from the +// session, so one has to exist before the manager runs. +$user->session_begin(); +$auth->acl($user->data); +$user->setup(); + $hook = new \titania_style_demo_hook($config, $db, $user, $phpbb_root_path, $phpEx); $result = $hook->run($request->variable('key', '')); diff --git a/misc/style_demo_hooks/style_demo_hook.php b/misc/style_demo_hooks/style_demo_hook.php index cae954255..2420986c5 100644 --- a/misc/style_demo_hooks/style_demo_hook.php +++ b/misc/style_demo_hooks/style_demo_hook.php @@ -25,6 +25,9 @@ class titania_style_demo_hook /** @var string */ protected $php_ext; + /** @var titania_demo_manager */ + protected $manager; + /** * Constructor. *