From aa961991fdafc8a0371d22c7e42f2424ee1b8898 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Fri, 17 Nov 2017 01:29:38 +0100 Subject: [ticket/15339] Allow a module to have multiple parents Also restore old behaviour from Olympus regarding re-sorting modules PHPBB3-15339 --- phpBB/phpbb/db/migration/tool/module.php | 255 ++++++++++++++++--------------- 1 file changed, 132 insertions(+), 123 deletions(-) (limited to 'phpBB/phpbb/db/migration/tool/module.php') diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index b47c426110..3b4728c9d7 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -84,9 +84,11 @@ class module implements \phpbb\db\migration\tool\tool_interface * Use false to ignore the parent check and check class wide. * @param int|string $module The module_id|module_langname you would like to * check for to see if it exists - * @return bool true/false if module exists + * @param bool $lazy Checks lazily if the module exists. Returns true if it exists in at + * least one given parent. + * @return bool true if module exists in *all* given parents, false if not */ - public function exists($class, $parent, $module) + public function exists($class, $parent, $module, $lazy = false) { // the main root directory should return true if (!$module) @@ -94,33 +96,44 @@ class module implements \phpbb\db\migration\tool\tool_interface return true; } - $parent_sql = ''; + $parent_sqls = []; if ($parent !== false) { - $parent = $this->get_parent_module_id($parent, $module, false); - if ($parent === false) + $parents = $this->get_parent_module_id($parent, $module, false); + if ($parents === false) { return false; } - $parent_sql = 'AND parent_id = ' . (int) $parent; + foreach ((array) $parents as $parent_id) + { + $parent_sqls[] = 'AND parent_id = ' . (int) $parent_id; + } } - $sql = 'SELECT module_id - FROM ' . $this->modules_table . " - WHERE module_class = '" . $this->db->sql_escape($class) . "' - $parent_sql - AND " . ((is_numeric($module)) ? 'module_id = ' . (int) $module : "module_langname = '" . $this->db->sql_escape($module) . "'"); - $result = $this->db->sql_query($sql); - $module_id = $this->db->sql_fetchfield('module_id'); - $this->db->sql_freeresult($result); - - if ($module_id) + foreach ($parent_sqls as $parent_sql) { - return true; + $sql = 'SELECT module_id + FROM ' . $this->modules_table . " + WHERE module_class = '" . $this->db->sql_escape($class) . "' + $parent_sql + AND " . ((is_numeric($module)) ? 'module_id = ' . (int) $module : "module_langname = '" . $this->db->sql_escape($module) . "'"); + $result = $this->db->sql_query($sql); + $module_id = $this->db->sql_fetchfield('module_id'); + $this->db->sql_freeresult($result); + + if (!$lazy && !$module_id) + { + return false; + } + else if ($lazy && $module_id) + { + return true; + } } - return false; + // Returns true, if modules exist in all parents and false otherwise + return !$lazy; } /** @@ -172,7 +185,7 @@ class module implements \phpbb\db\migration\tool\tool_interface $data = array('module_langname' => $data); } - $parent = $data['parent_id'] = $this->get_parent_module_id($parent, $data); + $parents = (array) $this->get_parent_module_id($parent, $data); if (!isset($data['module_langname'])) { @@ -195,95 +208,129 @@ class module implements \phpbb\db\migration\tool\tool_interface ); // Run the "manual" way with the data we've collected. - $this->add($class, $parent, $new_module); + foreach ($parents as $parent) + { + $this->add($class, $parent, $new_module); + } } } return; } - // The "manual" way - if (!$this->exists($class, false, $parent)) + foreach ($parents as $parent) { - throw new \phpbb\db\migration\exception('MODULE_NOT_EXIST', $parent); - } + $data['parent_id'] = $parent; - if ($this->exists($class, $parent, $data['module_langname'])) - { - throw new \phpbb\db\migration\exception('MODULE_EXISTS', $data['module_langname']); - } - - $module_data = array( - 'module_enabled' => (isset($data['module_enabled'])) ? $data['module_enabled'] : 1, - 'module_display' => (isset($data['module_display'])) ? $data['module_display'] : 1, - 'module_basename' => (isset($data['module_basename'])) ? $data['module_basename'] : '', - 'module_class' => $class, - 'parent_id' => (int) $parent, - 'module_langname' => (isset($data['module_langname'])) ? $data['module_langname'] : '', - 'module_mode' => (isset($data['module_mode'])) ? $data['module_mode'] : '', - 'module_auth' => (isset($data['module_auth'])) ? $data['module_auth'] : '', - ); - - try - { - $this->module_manager->update_module_data($module_data); + // The "manual" way + if (!$this->exists($class, false, $parent)) + { + throw new \phpbb\db\migration\exception('MODULE_NOT_EXIST', $parent); + } - // Success - $module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']); - $phpbb_log->add('admin', (isset($user->data['user_id'])) ? $user->data['user_id'] : ANONYMOUS, $user->ip, 'LOG_MODULE_ADD', false, array($module_log_name)); + if ($this->exists($class, $parent, $data['module_langname'])) + { + throw new \phpbb\db\migration\exception('MODULE_EXISTS', $data['module_langname']); + } - // Move the module if requested above/below an existing one - if (isset($data['before']) && $data['before']) + $module_data = array( + 'module_enabled' => (isset($data['module_enabled'])) ? $data['module_enabled'] : 1, + 'module_display' => (isset($data['module_display'])) ? $data['module_display'] : 1, + 'module_basename' => (isset($data['module_basename'])) ? $data['module_basename'] : '', + 'module_class' => $class, + 'parent_id' => (int) $parent, + 'module_langname' => (isset($data['module_langname'])) ? $data['module_langname'] : '', + 'module_mode' => (isset($data['module_mode'])) ? $data['module_mode'] : '', + 'module_auth' => (isset($data['module_auth'])) ? $data['module_auth'] : '', + ); + + try { - $sql = 'SELECT left_id + $this->module_manager->update_module_data($module_data); + + // Success + $module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']); + $phpbb_log->add('admin', (isset($user->data['user_id'])) ? $user->data['user_id'] : ANONYMOUS, $user->ip, 'LOG_MODULE_ADD', false, array($module_log_name)); + + // Move the module if requested above/below an existing one + if (isset($data['before']) && $data['before']) + { + $before_mode = $before_langname = ''; + if (is_array($data['before'])) + { + // Restore legacy-legacy behaviour from phpBB 3.0 + list($before_mode, $before_langname) = $data['before']; + } + else + { + // Legacy behaviour from phpBB 3.1+ + $before_langname = $data['before']; + } + + $sql = 'SELECT left_id FROM ' . $this->modules_table . " WHERE module_class = '" . $this->db->sql_escape($class) . "' AND parent_id = " . (int) $parent . " - AND module_langname = '" . $this->db->sql_escape($data['before']) . "'"; - $this->db->sql_query($sql); - $to_left = (int) $this->db->sql_fetchfield('left_id'); + AND module_langname = '" . $this->db->sql_escape($before_langname) . "'" + . (($before_mode) ? " AND module_mode = '" . $this->db->sql_escape($before_mode) . "'" : ''); + $this->db->sql_query($sql); + $to_left = (int) $this->db->sql_fetchfield('left_id'); - $sql = 'UPDATE ' . $this->modules_table . " + $sql = 'UPDATE ' . $this->modules_table . " SET left_id = left_id + 2, right_id = right_id + 2 WHERE module_class = '" . $this->db->sql_escape($class) . "' AND left_id >= $to_left AND left_id < {$module_data['left_id']}"; - $this->db->sql_query($sql); + $this->db->sql_query($sql); - $sql = 'UPDATE ' . $this->modules_table . " + $sql = 'UPDATE ' . $this->modules_table . " SET left_id = $to_left, right_id = " . ($to_left + 1) . " WHERE module_class = '" . $this->db->sql_escape($class) . "' AND module_id = {$module_data['module_id']}"; - $this->db->sql_query($sql); - } - else if (isset($data['after']) && $data['after']) - { - $sql = 'SELECT right_id + $this->db->sql_query($sql); + } + else if (isset($data['after']) && $data['after']) + { + $after_mode = $after_langname = ''; + if (is_array($data['after'])) + { + // Restore legacy-legacy behaviour from phpBB 3.0 + list($after_mode, $after_langname) = $data['after']; + } + else + { + // Legacy behaviour from phpBB 3.1+ + $after_langname = $data['after']; + } + + $sql = 'SELECT right_id FROM ' . $this->modules_table . " WHERE module_class = '" . $this->db->sql_escape($class) . "' AND parent_id = " . (int) $parent . " - AND module_langname = '" . $this->db->sql_escape($data['after']) . "'"; - $this->db->sql_query($sql); - $to_right = (int) $this->db->sql_fetchfield('right_id'); + AND module_langname = '" . $this->db->sql_escape($after_langname) . "'" + . (($after_mode) ? " AND module_mode = '" . $this->db->sql_escape($after_mode) . "'" : ''); + $this->db->sql_query($sql); + $to_right = (int) $this->db->sql_fetchfield('right_id'); - $sql = 'UPDATE ' . $this->modules_table . " + $sql = 'UPDATE ' . $this->modules_table . " SET left_id = left_id + 2, right_id = right_id + 2 WHERE module_class = '" . $this->db->sql_escape($class) . "' AND left_id >= $to_right AND left_id < {$module_data['left_id']}"; - $this->db->sql_query($sql); + $this->db->sql_query($sql); - $sql = 'UPDATE ' . $this->modules_table . ' + $sql = 'UPDATE ' . $this->modules_table . ' SET left_id = ' . ($to_right + 1) . ', right_id = ' . ($to_right + 2) . " WHERE module_class = '" . $this->db->sql_escape($class) . "' AND module_id = {$module_data['module_id']}"; - $this->db->sql_query($sql); + $this->db->sql_query($sql); + } + } + catch (module_exception $e) + { + // Error + throw new \phpbb\db\migration\exception('MODULE_ERROR', $e->getMessage()); } - } - catch (module_exception $e) - { - // Error - throw new \phpbb\db\migration\exception('MODULE_ERROR', $e->getMessage()); } // Clear the Modules Cache @@ -334,7 +381,7 @@ class module implements \phpbb\db\migration\tool\tool_interface } else { - if (!$this->exists($class, $parent, $module)) + if (!$this->exists($class, $parent, $module, true)) { return; } @@ -342,8 +389,8 @@ class module implements \phpbb\db\migration\tool\tool_interface $parent_sql = ''; if ($parent !== false) { - $parent = $this->get_parent_module_id($parent, $module); - $parent_sql = 'AND parent_id = ' . (int) $parent; + $parents = (array)$this->get_parent_module_id($parent, $module); + $parent_sql = 'AND ' . $this->db->sql_in_set('parent_id', $parents); } $module_ids = array(); @@ -457,14 +504,11 @@ class module implements \phpbb\db\migration\tool\tool_interface * @param string|int $parent_id The parent module_id|module_langname * @param int|string|array $data The module_id, module_langname for existance checking or module data array for adding * @param bool $throw_exception The flag indicating if exception should be thrown on error - * @return mixed The int parent module_id or false + * @return mixed The int parent module_id, an array of int parent module_id values or false * @throws \phpbb\db\migration\exception */ public function get_parent_module_id($parent_id, $data = '', $throw_exception = true) { - // Initialize exception object placeholder - $exception = false; - // Allow '' to be sent as 0 $parent_id = $parent_id ?: 0; @@ -486,61 +530,26 @@ class module implements \phpbb\db\migration\tool\tool_interface { // No parent with the given module_langname exist case 0: - $exception = new \phpbb\db\migration\exception('MODULE_NOT_EXIST', $parent_id); + if ($throw_exception) + { + throw new \phpbb\db\migration\exception('MODULE_NOT_EXIST', $parent_id); + } + + return false; break; // Return the module id case 1: - $parent_id = (int) $ids[0]; + return (int) $ids[0]; break; - // Several modules with the given module_langname were found - // Try to determine the parent_id by the neighbour module parent default: - if (is_array($data) && (isset($data['before']) || isset($data['after']))) - { - $neighbour_module_langname = isset($data['before']) ? $data['before'] : $data['after']; - $sql = 'SELECT parent_id - FROM ' . $this->modules_table . " - WHERE module_langname = '" . $this->db->sql_escape($neighbour_module_langname) . "' - AND " . $this->db->sql_in_set('parent_id', $ids); - $result = $this->db->sql_query($sql); - $parent_id = (int) $this->db->sql_fetchfield('parent_id'); - if (!$parent_id) - { - $exception = new \phpbb\db\migration\exception('PARENT_MODULE_FIND_ERROR', $data['parent_id']); - } - } - else if (!empty($data) && !is_array($data)) - { - // The module_langname is set, checking for the module existance - // As more than 1 parents were found already, there's no way for null parent_id here - $sql = 'SELECT m2.module_id as module_parent_id - FROM ' . $this->modules_table . ' m1, ' . $this->modules_table . " m2 - WHERE " . ((is_numeric($data)) ? 'm1.module_id = ' . (int) $data : "m1.module_langname = '" . $this->db->sql_escape($data)) . "' - AND m2.module_id = m1.parent_id - AND " . $this->db->sql_in_set('m2.module_id', $ids); - $result = $this->db->sql_query($sql); - $parent_id = (int) $this->db->sql_fetchfield('module_parent_id'); - } - else - { - //Unable to get the parent module id, throwing an exception - $exception = new \phpbb\db\migration\exception('MODULE_EXIST_MULTIPLE', $parent_id); - } + // This represents the old behaviour of phpBB 3.0 + return $ids; break; } } - if ($exception !== false) - { - if ($throw_exception) - { - throw $exception; - } - return false; - } - return $parent_id; } } -- cgit v1.2.1 From 719a49d38793f1490988ed0fa3fea84da17d3886 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Fri, 17 Nov 2017 01:31:31 +0100 Subject: [ticket/15339] Free sql results in migration module tool PHPBB3-15339 --- phpBB/phpbb/db/migration/tool/module.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb/db/migration/tool/module.php') diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 3b4728c9d7..e1dfe40709 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -273,8 +273,9 @@ class module implements \phpbb\db\migration\tool\tool_interface AND parent_id = " . (int) $parent . " AND module_langname = '" . $this->db->sql_escape($before_langname) . "'" . (($before_mode) ? " AND module_mode = '" . $this->db->sql_escape($before_mode) . "'" : ''); - $this->db->sql_query($sql); + $result = $this->db->sql_query($sql); $to_left = (int) $this->db->sql_fetchfield('left_id'); + $this->db->sql_freeresult($result); $sql = 'UPDATE ' . $this->modules_table . " SET left_id = left_id + 2, right_id = right_id + 2 @@ -309,8 +310,9 @@ class module implements \phpbb\db\migration\tool\tool_interface AND parent_id = " . (int) $parent . " AND module_langname = '" . $this->db->sql_escape($after_langname) . "'" . (($after_mode) ? " AND module_mode = '" . $this->db->sql_escape($after_mode) . "'" : ''); - $this->db->sql_query($sql); + $result = $this->db->sql_query($sql); $to_right = (int) $this->db->sql_fetchfield('right_id'); + $this->db->sql_freeresult($result); $sql = 'UPDATE ' . $this->modules_table . " SET left_id = left_id + 2, right_id = right_id + 2 -- cgit v1.2.1 From 2b16b7cada85492b6312d126afa71a8a2e50a2a3 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sun, 24 Dec 2017 19:55:03 +0100 Subject: [ticket/15339] Fix tests PHPBB3-15339 --- phpBB/phpbb/db/migration/tool/module.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb/db/migration/tool/module.php') diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index e1dfe40709..238e063a87 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -391,7 +391,7 @@ class module implements \phpbb\db\migration\tool\tool_interface $parent_sql = ''; if ($parent !== false) { - $parents = (array)$this->get_parent_module_id($parent, $module); + $parents = (array) $this->get_parent_module_id($parent, $module); $parent_sql = 'AND ' . $this->db->sql_in_set('parent_id', $parents); } -- cgit v1.2.1 From f8fbe3793680af1dae2db2829cfc84068831c52f Mon Sep 17 00:00:00 2001 From: rxu Date: Wed, 28 Jun 2017 00:58:03 +0700 Subject: [ticket/14972] replace all occurrences of sizeof() with the count() PHPBB3-14972 --- phpBB/phpbb/db/migration/tool/module.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb/db/migration/tool/module.php') diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 238e063a87..7d2720c861 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -515,7 +515,7 @@ class module implements \phpbb\db\migration\tool\tool_interface $parent_id = $parent_id ?: 0; // If automatic adding is in action, convert array back to string to simplify things - if (is_array($data) && sizeof($data) == 1) + if (is_array($data) && count($data) == 1) { $data = $data['module_langname']; } @@ -528,7 +528,7 @@ class module implements \phpbb\db\migration\tool\tool_interface // Search for the parent module_langname $ids = array_keys($this->module_categories, $parent_id); - switch (sizeof($ids)) + switch (count($ids)) { // No parent with the given module_langname exist case 0: -- cgit v1.2.1 From 2d5fe90ed5735c44ae733959c96da3a67a5d2647 Mon Sep 17 00:00:00 2001 From: kasimi Date: Sun, 11 Mar 2018 15:24:29 +0100 Subject: [ticket/15586] Fixed adding module the automatic way without specifying modes PHPBB3-15586 --- phpBB/phpbb/db/migration/tool/module.php | 6 ------ 1 file changed, 6 deletions(-) (limited to 'phpBB/phpbb/db/migration/tool/module.php') diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 7d2720c861..8a48efb19c 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -514,12 +514,6 @@ class module implements \phpbb\db\migration\tool\tool_interface // Allow '' to be sent as 0 $parent_id = $parent_id ?: 0; - // If automatic adding is in action, convert array back to string to simplify things - if (is_array($data) && count($data) == 1) - { - $data = $data['module_langname']; - } - if (!is_numeric($parent_id)) { // Refresh the $module_categories array -- cgit v1.2.1 From d7db5d366b9a326237efc7576d7db3215a51bc81 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 19 Mar 2018 16:42:53 -0700 Subject: [ticket/15595] Fix module exists tool when parent is false PHPBB3-15595 --- phpBB/phpbb/db/migration/tool/module.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb/db/migration/tool/module.php') diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 7d2720c861..e24c78e228 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -86,7 +86,8 @@ class module implements \phpbb\db\migration\tool\tool_interface * check for to see if it exists * @param bool $lazy Checks lazily if the module exists. Returns true if it exists in at * least one given parent. - * @return bool true if module exists in *all* given parents, false if not + * @return bool true if module exists in *all* given parents, false if not in any given parent; + * true if ignoring parent check and module exists class wide, false if not found at all. */ public function exists($class, $parent, $module, $lazy = false) { @@ -110,6 +111,10 @@ class module implements \phpbb\db\migration\tool\tool_interface $parent_sqls[] = 'AND parent_id = ' . (int) $parent_id; } } + else + { + $parent_sqls[] = ''; + } foreach ($parent_sqls as $parent_sql) { @@ -126,7 +131,7 @@ class module implements \phpbb\db\migration\tool\tool_interface { return false; } - else if ($lazy && $module_id) + if ($lazy && $module_id) { return true; } -- cgit v1.2.1 From 3d2c1b8f9766bf914755904d685aba1a4665cc26 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Mon, 24 Sep 2018 02:54:50 +0200 Subject: [ticket/15544] Delete cache through module manager This might fix issues with migrations since the sql cache will be purged as well. In general, this puts all the logic in one place, so that's good. PHPBB3-15544 --- phpBB/phpbb/db/migration/tool/module.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb/db/migration/tool/module.php') diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 3893935723..e5133c8152 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -341,7 +341,7 @@ class module implements \phpbb\db\migration\tool\tool_interface } // Clear the Modules Cache - $this->cache->destroy("_modules_$class"); + $this->module_manager->remove_cache_file($class); } /** @@ -425,7 +425,7 @@ class module implements \phpbb\db\migration\tool\tool_interface $this->module_manager->delete_module($module_id, $class); } - $this->cache->destroy("_modules_$class"); + $this->module_manager->remove_cache_file($class); } } -- cgit v1.2.1