From d7db5d366b9a326237efc7576d7db3215a51bc81 Mon Sep 17 00:00:00 2001
From: Matt Friedman <maf675@gmail.com>
Date: Mon, 19 Mar 2018 16:42:53 -0700
Subject: [PATCH] [ticket/15595] Fix module exists tool when parent is false

PHPBB3-15595
---
 phpBB/phpbb/db/migration/tool/module.php |   9 +-
 tests/dbal/migrator_tool_module_test.php | 161 ++++++++++++++++++++++-
 2 files changed, 164 insertions(+), 6 deletions(-)

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;
 			}
diff --git a/tests/dbal/migrator_tool_module_test.php b/tests/dbal/migrator_tool_module_test.php
index c625b93ded..0f3febb24d 100644
--- a/tests/dbal/migrator_tool_module_test.php
+++ b/tests/dbal/migrator_tool_module_test.php
@@ -52,11 +52,39 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case
 			array(
 				'',
 				'ACP_CAT',
+				false,
 				true,
 			),
 			array(
 				0,
 				'ACP_CAT',
+				false,
+				true,
+			),
+			array(
+				false,
+				'ACP_CAT',
+				false,
+				true,
+			),
+
+			// Test the existing category lazily
+			array(
+				'',
+				'ACP_CAT',
+				true,
+				true,
+			),
+			array(
+				0,
+				'ACP_CAT',
+				true,
+				true,
+			),
+			array(
+				false,
+				'ACP_CAT',
+				true,
 				true,
 			),
 
@@ -65,15 +93,38 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case
 				'',
 				'ACP_MODULE',
 				false,
+				false,
 			),
 			array(
 				false,
 				'ACP_MODULE',
+				false,
 				true,
 			),
 			array(
 				'ACP_CAT',
 				'ACP_MODULE',
+				false,
+				true,
+			),
+
+			// Test the existing module lazily
+			array(
+				'',
+				'ACP_MODULE',
+				true,
+				false,
+			),
+			array(
+				false,
+				'ACP_MODULE',
+				true,
+				true,
+			),
+			array(
+				'ACP_CAT',
+				'ACP_MODULE',
+				true,
 				true,
 			),
 
@@ -82,11 +133,39 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case
 				'',
 				'ACP_NON_EXISTANT_CAT',
 				false,
+				false,
+			),
+			array(
+				false,
+				'ACP_NON_EXISTANT_CAT',
+				false,
+				false,
 			),
 			array(
 				'ACP_CAT',
 				'ACP_NON_EXISTANT_MODULE',
 				false,
+				false,
+			),
+
+			// Test for non-existant modules lazily
+			array(
+				'',
+				'ACP_NON_EXISTANT_CAT',
+				true,
+				false,
+			),
+			array(
+				false,
+				'ACP_NON_EXISTANT_CAT',
+				true,
+				false,
+			),
+			array(
+				'ACP_CAT',
+				'ACP_NON_EXISTANT_MODULE',
+				true,
+				false,
 			),
 		);
 	}
@@ -94,9 +173,9 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case
 	/**
 	* @dataProvider exists_data_acp
 	*/
-	public function test_exists_acp($parent, $module, $expected)
+	public function test_exists_acp($parent, $module, $lazy, $expected)
 	{
-		$this->assertEquals($expected, $this->tool->exists('acp', $parent, $module));
+		$this->assertEquals($expected, $this->tool->exists('acp', $parent, $module, $lazy));
 	}
 
 	public function exists_data_ucp()
@@ -106,11 +185,39 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case
 			array(
 				'',
 				'UCP_MAIN_CAT',
+				false,
 				true,
 			),
 			array(
 				0,
 				'UCP_MAIN_CAT',
+				false,
+				true,
+			),
+			array(
+				false,
+				'UCP_MAIN_CAT',
+				false,
+				true,
+			),
+
+			// Test the existing category lazily
+			array(
+				'',
+				'UCP_MAIN_CAT',
+				true,
+				true,
+			),
+			array(
+				0,
+				'UCP_MAIN_CAT',
+				true,
+				true,
+			),
+			array(
+				false,
+				'UCP_MAIN_CAT',
+				true,
 				true,
 			),
 
@@ -119,21 +226,51 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case
 				'',
 				'UCP_SUBCATEGORY',
 				false,
+				false,
 			),
 			array(
 				false,
 				'UCP_SUBCATEGORY',
+				false,
+				true,
+			),
+			array(
+				'UCP_MAIN_CAT',
+				'UCP_SUBCATEGORY',
+				false,
+				true,
+			),
+			array(
+				'UCP_SUBCATEGORY',
+				'UCP_MODULE',
+				false,
+				true,
+			),
+
+			// Test the existing module lazily
+			array(
+				'',
+				'UCP_SUBCATEGORY',
+				true,
+				false,
+			),
+			array(
+				false,
+				'UCP_SUBCATEGORY',
+				true,
 				true,
 			),
 			array(
 				'UCP_MAIN_CAT',
 				'UCP_SUBCATEGORY',
 				true,
+				true,
 			),
 			array(
 				'UCP_SUBCATEGORY',
 				'UCP_MODULE',
 				true,
+				true,
 			),
 
 			// Test for non-existant modules
@@ -141,11 +278,27 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case
 				'',
 				'UCP_NON_EXISTANT_CAT',
 				false,
+				false,
 			),
 			array(
 				'UCP_MAIN_CAT',
 				'UCP_NON_EXISTANT_MODULE',
 				false,
+				false,
+			),
+
+			// Test for non-existant modules lazily
+			array(
+				'',
+				'UCP_NON_EXISTANT_CAT',
+				true,
+				false,
+			),
+			array(
+				'UCP_MAIN_CAT',
+				'UCP_NON_EXISTANT_MODULE',
+				true,
+				false,
 			),
 		);
 	}
@@ -153,9 +306,9 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case
 	/**
 	* @dataProvider exists_data_ucp
 	*/
-	public function test_exists_ucp($parent, $module, $expected)
+	public function test_exists_ucp($parent, $module, $lazy, $expected)
 	{
-		$this->assertEquals($expected, $this->tool->exists('ucp', $parent, $module));
+		$this->assertEquals($expected, $this->tool->exists('ucp', $parent, $module, $lazy));
 	}
 
 	public function test_add()