From a9cf558af7fc08539e15ceca1e889e087c815c8d Mon Sep 17 00:00:00 2001 From: Sajaki Date: Sat, 28 Apr 2012 10:43:43 +0200 Subject: [PATCH 01/90] [ticket/10854] sql server drop default constraint when dropping column drops default columns with T-SQL before attempting drop column to avoids sql exception. This is a huge annoyance in UMIL scripts running under sql server. --- phpBB/includes/db/db_tools.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index c6dd23e6bd..f63ff18cbe 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -1819,6 +1819,22 @@ class phpbb_db_tools case 'mssql': case 'mssqlnative': + // remove default cosntraints first + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) + SET @drop_default_name = + (SELECT so.name FROM sysobjects so + JOIN sysconstraints sc ON so.id = sc.constid + WHERE object_name(so.parent_obj) = '{$table_name}' + AND so.xtype = 'D' + AND sc.colid = (SELECT colid FROM syscolumns + WHERE id = object_id('{$table_name}') + AND name = '{$column_name}')) + IF @drop_default_name <> '' + BEGIN + SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' + EXEC(@cmd) + END"; $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']'; break; From 3e03f95cb73ad090e22514be856c9b0613e0448a Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Sun, 11 Nov 2012 19:07:00 +0100 Subject: [PATCH 02/90] [ticket/10431] CSS3 buttons CSS3 replacements for big buttons PHPBB3-10431 --- phpBB/styles/prosilver/theme/buttons.css | 81 ++++++++++++------ phpBB/styles/prosilver/theme/colours.css | 8 -- .../styles/prosilver/theme/en/stylesheet.css | 16 ---- .../styles/prosilver/theme/images/buttons.png | Bin 0 -> 2563 bytes 4 files changed, 56 insertions(+), 49 deletions(-) create mode 100644 phpBB/styles/prosilver/theme/images/buttons.png diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index e817380f8e..9a69956368 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -14,40 +14,71 @@ .buttons div { float: left; margin: 0 5px 0 0; - background-position: 0 100%; } /* Rolloff state */ .buttons div a { - display: block; - width: 100%; - height: 100%; - background-position: 0 0; - position: relative; - overflow: hidden; + display: inline-block; + line-height: 16px; + font-size: 13px; + white-space: nowrap; + border: 1px solid #c7c3bf; + border-radius: 4px; + background: #fff none 0 0 repeat-x; + background-image: -moz-linear-gradient(top, #fff, #e9e9e9); + background-image: -webkit-linear-gradient(top, #fff, #e9e9e9); + background-image: -o-linear-gradient(top, #fff, #e9e9e9); + background-image: linear-gradient(to bottom, #fff, #e9e9e9); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff', EndColorStr='#e9e9e9')"; + box-shadow: 0 0 0 1px #fff inset; + -webkit-box-shadow: 0 0 0 1px #fff inset; + text-shadow: 1px 1px 0 #fff, -1px -1px 0 rgba(188, 42, 77, 0.25); + padding: 3px 22px 3px 8px; + color: #bc2a4d !important; + position: relative; + text-decoration: none !important; + outline-style: none !important; } -/* Hide text and hide off-state image when rolling over (prevents flicker in IE) */ -/*.buttons div span { display: none; }*/ -/*.buttons div a:hover { background-image: none; }*/ -.buttons div span { position: absolute; width: 100%; height: 100%; cursor: pointer;} -.buttons div a:hover span { background-position: 0 100%; } +.buttons div span { display: none; } +.buttons div a:hover { + border-color: #0a8ed0; + background-image: -moz-linear-gradient(top, #e9e9e9, #fff); + background-image: -webkit-linear-gradient(top, #e9e9e9, #fff); + background-image: -o-linear-gradient(top, #e9e9e9, #fff); + background-image: linear-gradient(to bottom, #e9e9e9, #fff); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#e9e9e9', EndColorStr='#ffffff')"; + text-shadow: 1px 1px 0 #fff, -1px -1px 0 #fff, -1px -1px 0 rgba(188, 42, 77, 0.2); +} + +.buttons div a:after { + content: ''; + display: block; + position: absolute; + top: 50%; + right: 6px; + width: 12px; + height: 12px; + margin-top: -6px; + background: url("images/buttons.png") 0px 0 no-repeat; +} + +.buttons div a:hover:after { + background-position: 0 -20px; +} /* Big button images */ -.reply-icon span { background: transparent none 0 0 no-repeat; } -.post-icon span { background: transparent none 0 0 no-repeat; } -.locked-icon span { background: transparent none 0 0 no-repeat; } -.pmreply-icon span { background: none 0 0 no-repeat; } -.newpm-icon span { background: none 0 0 no-repeat; } -.forwardpm-icon span { background: none 0 0 no-repeat; } +.buttons div.reply-icon a:after, .buttons div.pmreply-icon a:after { background-position: -20px 0; } +.buttons div.reply-icon a:hover:after, .buttons div.pmreply-icon a:hover:after { background-position: -20px -20px; } -/* Set big button dimensions */ -.buttons div.reply-icon { width: 96px; height: 25px; } -.buttons div.post-icon { width: 96px; height: 25px; } -.buttons div.locked-icon { width: 88px; height: 25px; } -.buttons div.pmreply-icon { width: 96px; height: 25px; } -.buttons div.newpm-icon { width: 84px; height: 25px; } -.buttons div.forwardpm-icon { width: 96px; height: 25px; } +.buttons div.post-icon a:after, .buttons div.newpm-icon a:after { background-position: 0 0; } +.buttons div.post-icon a:hover:after, .buttons div.newpm-icon a:hover:after { background-position: 0 -20px; } + +.buttons div.locked-icon a:after { background-position: -60px 0; } +.buttons div.locked-icon a:hover:after { background-position: -60px -20px; } + +.buttons div.forwardpm-icon a:after { background-position: -40px 0; } +.buttons div.forwardpm-icon a:hover:after { background-position: -40px -20px; } /* Sub-header (navigation bar) --------------------------------------------- */ diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index d7ce9a7622..0a8e011171 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -649,14 +649,6 @@ fieldset.polls dd div { Colours and backgrounds for buttons.css -------------------------------------------------------------- */ -/* Big button images */ -.reply-icon span { background-image: url("./en/button_topic_reply.gif"); } -.post-icon span { background-image: url("./en/button_topic_new.gif"); } -.locked-icon span { background-image: url("./en/button_topic_locked.gif"); } -.pmreply-icon span { background-image: url("./en/button_pm_reply.gif") ;} -.newpm-icon span { background-image: url("./en/button_pm_new.gif") ;} -.forwardpm-icon span { background-image: url("./en/button_pm_forward.gif") ;} - a.print { background-image: url("./images/icon_print.gif"); } diff --git a/phpBB/styles/prosilver/theme/en/stylesheet.css b/phpBB/styles/prosilver/theme/en/stylesheet.css index d17f9a5be4..1a3d0acb4b 100644 --- a/phpBB/styles/prosilver/theme/en/stylesheet.css +++ b/phpBB/styles/prosilver/theme/en/stylesheet.css @@ -1,11 +1,3 @@ -/* Set big button dimensions */ -.buttons div.reply-icon { width: 96px; height: 25px; } -.buttons div.post-icon { width: 96px; height: 25px; } -.buttons div.locked-icon { width: 88px; height: 25px; } -.buttons div.pmreply-icon { width: 96px; height: 25px; } -.buttons div.newpm-icon { width: 84px; height: 25px; } -.buttons div.forwardpm-icon { width: 96px; height: 25px; } - /* Set profile icon dimensions */ ul.profile-icons li.pm-icon { width: 28px; height: 20px; } ul.profile-icons li.quote-icon { width: 54px; height: 20px; } @@ -14,14 +6,6 @@ ul.profile-icons li.edit-icon { width: 42px; height: 20px; } /* Online image */ .online { background-image: url("./icon_user_online.gif"); } -/* Big button images */ -.reply-icon span { background-image: url("./button_topic_reply.gif"); } -.post-icon span { background-image: url("./button_topic_new.gif"); } -.locked-icon span { background-image: url("./button_topic_locked.gif"); } -.pmreply-icon span { background-image: url("./button_pm_reply.gif") ;} -.newpm-icon span { background-image: url("./button_pm_new.gif") ;} -.forwardpm-icon span { background-image: url("./button_pm_forward.gif") ;} - /* Icon images */ .pm-icon, .pm-icon a { background-image: url("./icon_contact_pm.gif"); } .quote-icon, .quote-icon a { background-image: url("./icon_post_quote.gif"); } diff --git a/phpBB/styles/prosilver/theme/images/buttons.png b/phpBB/styles/prosilver/theme/images/buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..a19abdc2b8aeb3b344a1718d78314104082fa2ba GIT binary patch literal 2563 zcmbVOcT`hZ9?m9+fFlqA8?X~XuOXqN(Mdv)U<3rjfX3t@5mHD(LXkzHC|v?pnhdxK zQiQRhNOeIO2N+OMK*}Is1wkny>ONH5{lhbR&c6HJyXF19?^o`3&v_{{Z@0Bdo0T9C z$XX9~k`LI^z{f~I9(=QR$NvrNHi^iAB41vpNWu^R5N8%|4}kFCF!lmI0D~11c^9yQ zKwzP4zd%tS)r-L7aV!|iHWtwwK8S`u>>Q){3}!eWLhJ$dvbpxishbT*1e;}#46vbE zQu(ex7~4Ho0Qkmw`!Qp~nRph`(E(u>O#lfvfQW&J=0tFXglK!@7hVE5US38a5noJ1 z;r7U{K?PE22v?o}K-gGVnKLcXXoRh;1=`xi))sAsz*wR&C`<6RHAh<$Y-|Y_EaKaR z1icAZp#&ci<(n^XW{(ULiTDH*N+OY1NUSV)g1sm-9*ihktYAI3LJ@<@1XldALBHRy>v22xcslYzhYVcPt8zZ zFsNm5{Fhi(mOuqA55G$voP0k#02e$l0`O=QgdPckK;*4FNX~xIeXn*zx@!h({Old{ zqAT@}GNIyjHMc9pez2FKDsRn#^pC#%$1<)kG1k{#tL#kDNNP4SHgykpwC{XXj*cj= zxFEudeWjWZrIE8fHK^C5{E}13`E?l3lpPw0vZwXt3=qkzF?r^JjueY${m#NpgWCQg{|WIZk>DVWs+nrUC(MyD@L z58jH?qzOZs2(=liT}-%VE%U?>jxIs{6M(@tqIG-;0Yn+Pl$U zn_j6NT$=LyhPo6koV4~M3 z7bO-i!u9{DqMqmhgTa!NkCdp&aHq4f_$iwCd3jcWl@EP;dV26iXP+EV)?VCH<~Fu@ z18$t`1OQ_Wb9e6k>lk96bG2e>Bm7W_IV$1k5ZpkYh9wg7wAIvLn=@L6MTE67S-Ih6 zxTI@z`hb6VQgU+go3st6aSaWP$BLO4nBt7PU^r^Xdiatv>DlCD=*AoT5ov((?Rf6~ z&!0XX8$f2;T3InkZPuD(#^K+_+Tq?#GHi-qghrvX?iL7Uvb@^1ROjR$EGa2z$}-HA z$Hme0e!WT@+t_~Z-r4Z*@b}4TP_eFcheDlVasB zr^(8l*Su?=Os3b=ptsQJ1FYEC8*avl^p55Zld{~ccYcXgfcn7QrK;RS!>xr&s$)c0 zD#?juGd?yJKfN%`oNsUUj7~^M*j}Bc;ZHkZ_a_p0TwYyWztC)#&MJvaxh3FuVPWBg zg@uLM?(S|~_X&rDPy3B8++OcxL})#8scoSwB=&P!T1;@TcE&~1Y{j~>a+%shicB?G zmb}5r(ea`yxkU5I&%;H|F_Bp08>PFmfUfha?aC7^4RRl=cMFCndbA`dve-qR_O&H> z4)?Sgz_mXqHb^;V$TOc}g?%G@%g&05_> zkIue1lR(33@MfxNkE}088j-hV%^KCW<3Q_la4jJuVfN&v@%O|1P!kiAR3m7{tDe@Q zdU=q-k&I`L@vrqde0cfL#Wr1y3T8b4fslQ!P?sB0!|f}5&`b9kJU>o7I_}PyGC8H3ly-{olME^-f|@ec#JeH|)&=bm)EYq>Z+H^}G;D{icdTP?ofe|6TTtxln+ zlO=TXw&+kQ_P?&!KDcX#^ziCQ7x(ANAxA$1HC-Q2ur7H9P41F%jNxVlD%;|0P+G5Z z4~zTl8imh?(>tW%53sd`TkCd5f|^DYZizf=H8*Kw_-3}V_4LyDTQTw`4Sye9HJ>yp zNK1b3Jfwo%FnMS&#VuLyNUz-JRZGjgl!JKF&F?x7w@2lN=08QM63g@LrtR+ZjUr`N z%uPk>)+vPrKUTcnH}!ewQB}ZY%N{yRGD$!2@r-+=f!*bLJM3UYtWI4`uXs)V{h(Eg zrL?rW#KhbQr>2Yb4zji}hi=aSgiL5a8-8mFfk@vou3&qY`oP+X>{ z8v^T3LrcWM3$Hg37v3Mz3WBGc(lL& zmuYkRuu`|-rMEoXn+F^PaZR&Q>K$Jnl3vdNX|bG6DXs2U`D~7=6#DDp*fV4X$uWkP zX#4P8*Eq_Mc9PptTT_`JeW5q$-!)(tiUMbvMEQ literal 0 HcmV?d00001 From 8b1920adb59d2cc6e8bed558c56fb33ab5c4b0f7 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Mon, 12 Nov 2012 10:25:12 +0100 Subject: [PATCH 03/90] [ticket/10431] Different font for iOS Different font for buttons on iOS devices because Verdana looks incorrectly aligned in Safari/iOS. Also slightly changed text shadow. PHPBB3-10431 --- phpBB/styles/prosilver/theme/buttons.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index 9a69956368..2ba17a7717 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -32,8 +32,9 @@ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff', EndColorStr='#e9e9e9')"; box-shadow: 0 0 0 1px #fff inset; -webkit-box-shadow: 0 0 0 1px #fff inset; - text-shadow: 1px 1px 0 #fff, -1px -1px 0 rgba(188, 42, 77, 0.25); + text-shadow: 1px 1px 0 #fff, -1px -1px 1px rgba(188, 42, 77, 0.25); padding: 3px 22px 3px 8px; + font-family: "Futura-Medium", Verdana; color: #bc2a4d !important; position: relative; text-decoration: none !important; From 25124b361e8e23f338efb0f649abf46a37c66e3d Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Mon, 12 Nov 2012 10:42:11 +0100 Subject: [PATCH 04/90] [ticket/10431] Adjustments for IE7 Adjustments to buttons for IE7 PHPBB3-10431 --- phpBB/styles/prosilver/theme/buttons.css | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index 2ba17a7717..544f4d3def 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -39,6 +39,7 @@ position: relative; text-decoration: none !important; outline-style: none !important; + *padding-right: 8px; } .buttons div span { display: none; } From 8e700f7e2bfecc514f8ed4ae8db43dd37703ca1e Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Mon, 12 Nov 2012 11:03:30 +0100 Subject: [PATCH 05/90] [ticket/10431] Changed fonts for Linux Added backup fonts for Linux systems that do not have Verdana font PHPBB3-10431 --- phpBB/styles/prosilver/theme/buttons.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index 544f4d3def..02f973d0ff 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -34,7 +34,7 @@ -webkit-box-shadow: 0 0 0 1px #fff inset; text-shadow: 1px 1px 0 #fff, -1px -1px 1px rgba(188, 42, 77, 0.25); padding: 3px 22px 3px 8px; - font-family: "Futura-Medium", Verdana; + font-family: "Futura-Medium", Verdana, Arial, Helvetica; color: #bc2a4d !important; position: relative; text-decoration: none !important; From 02a1777fcbc550b4d91aaa585cffa9c052e4c525 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Wed, 26 Dec 2012 00:30:20 -0500 Subject: [PATCH 06/90] [ticket/11295] Drop tables rather than database for postgres in test suite. Doing so allows: 1. User running the tests no longer needs create database privilege. 2. Test database may be located in a non-default tablespace and generally have site-specific options applied to it. PHPBB3-11295 --- ...phpbb_database_test_connection_manager.php | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index d7c2804aa7..3b8c2e99ae 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -186,6 +186,16 @@ class phpbb_database_test_connection_manager $this->purge_extras(); break; + case 'postgres': + $this->connect(); + // Drop all of the tables + foreach ($this->get_tables() as $table) + { + $this->pdo->exec('DROP TABLE ' . $table . ' CASCADE'); + } + $this->purge_extras(); + break; + default: $this->connect(false); @@ -293,7 +303,7 @@ class phpbb_database_test_connection_manager protected function load_schema_from_file($directory) { $schema = $this->dbms['SCHEMA']; - + if ($this->config['dbms'] == 'mysql') { $sth = $this->pdo->query('SELECT VERSION() AS version'); @@ -313,7 +323,7 @@ class phpbb_database_test_connection_manager $queries = file_get_contents($filename); $sql = phpbb_remove_comments($queries); - + $sql = split_sql_file($sql, $this->dbms['DELIM']); foreach ($sql as $query) @@ -419,6 +429,19 @@ class phpbb_database_test_connection_manager $queries[] = 'DROP SEQUENCE ' . current($row); } break; + + case 'postgres': + $sql = 'SELECT sequence_name + FROM information_schema.sequences'; + $result = $this->pdo->query($sql); + + while ($row = $result->fetch(PDO::FETCH_NUM)) + { + $queries[] = 'DROP SEQUENCE ' . current($row); + } + + $queries[] = 'DROP TYPE IF EXISTS varchar_ci CASCADE'; + break; } foreach ($queries as $query) From f817e20f287a21e2dddfba9721f5e02dce162d29 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 15 Jul 2011 11:57:53 -0400 Subject: [PATCH 07/90] [feature/migrations] Basic migrations with schema and data changes The migrator takes care of applying migrations as necessary. RFC: http://area51.phpbb.com/phpBB/viewtopic.php?f=84&t=41337 PHPBB3-9737 --- phpBB/develop/create_schema_files.php | 14 ++ phpBB/includes/constants.php | 1 + phpBB/includes/db/migration.php | 79 ++++++++ phpBB/includes/db/migrator.php | 227 ++++++++++++++++++++++ phpBB/install/schemas/firebird_schema.sql | 12 ++ phpBB/install/schemas/mssql_schema.sql | 17 ++ phpBB/install/schemas/mysql_40_schema.sql | 12 ++ phpBB/install/schemas/mysql_41_schema.sql | 12 ++ phpBB/install/schemas/oracle_schema.sql | 15 ++ phpBB/install/schemas/postgres_schema.sql | 14 ++ phpBB/install/schemas/sqlite_schema.sql | 12 ++ tests/dbal/fixtures/migrator.xml | 27 +++ tests/dbal/migration/dummy.php | 26 +++ tests/dbal/migration/unfulfillable.php | 26 +++ tests/dbal/migrator_test.php | 80 ++++++++ 15 files changed, 574 insertions(+) create mode 100644 phpBB/includes/db/migration.php create mode 100644 phpBB/includes/db/migrator.php create mode 100644 tests/dbal/fixtures/migrator.xml create mode 100644 tests/dbal/migration/dummy.php create mode 100644 tests/dbal/migration/unfulfillable.php create mode 100644 tests/dbal/migrator_test.php diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 3d3e478032..82fbb183c1 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1258,6 +1258,20 @@ function get_schema_struct() ), ); + $schema_data['phpbb_migrations'] = array( + 'COLUMNS' => array( + 'migration_name' => array('VCHAR', ''), + 'migration_schema_done' => array('BOOL', 0), + 'migration_data_done' => array('BOOL', 0), + 'migration_data_state' => array('TEXT', ''), + 'migration_start_time' => array('TIMESTAMP', 0), + 'migration_end_time' => array('TIMESTAMP', 0), + ), + 'KEYS' => array( + 'migration_name' => array('UNIQUE', 'migration_name'), + ), + ); + $schema_data['phpbb_moderator_cache'] = array( 'COLUMNS' => array( 'forum_id' => array('UINT', 0), diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 68af41ab20..68c96a2759 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -237,6 +237,7 @@ define('ICONS_TABLE', $table_prefix . 'icons'); define('LANG_TABLE', $table_prefix . 'lang'); define('LOG_TABLE', $table_prefix . 'log'); define('LOGIN_ATTEMPT_TABLE', $table_prefix . 'login_attempts'); +define('MIGRATIONS_TABLE', $table_prefix . 'migrations'); define('MODERATOR_CACHE_TABLE', $table_prefix . 'moderator_cache'); define('MODULES_TABLE', $table_prefix . 'modules'); define('POLL_OPTIONS_TABLE', $table_prefix . 'poll_options'); diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration.php new file mode 100644 index 0000000000..f96fcb9568 --- /dev/null +++ b/phpBB/includes/db/migration.php @@ -0,0 +1,79 @@ +db = &$db; + $this->db_tools = &$db_tools; + } + + /** + * Defines other migrationsto be applied first (abstract method) + * + * @return array An array of migration class names + */ + function depends_on() + { + return array(); + } + + /** + * Updates the database schema + * + * @return null + */ + function update_schema() + { + } + + /** + * Updates data + * + * @return null + */ + function update_data() + { + } + + /** + * Adds a column to a database table + */ + function db_column_add($table_name, $column_name, $column_data) + { + $this->db_tools->sql_column_add($table_name, $column_name, $column_data); + } +} diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php new file mode 100644 index 0000000000..d5d938ca28 --- /dev/null +++ b/phpBB/includes/db/migrator.php @@ -0,0 +1,227 @@ +db = &$db; + $this->db_tools = &$db_tools; + $this->migrations_table = $migrations_table; + $this->migrations = array(); + + $this->load_migration_state(); + } + + /** + * Loads all migrations and their application state from the database. + * + * @return null + */ + function load_migration_state() + { + $sql = "SELECT * + FROM " . $this->migrations_table; + $result = $this->db->sql_query($sql); + + $this->migration_state = array(); + while ($migration = $this->db->sql_fetchrow($result)) + { + $this->migration_state[$migration['migration_name']] = $migration; + } + + $this->db->sql_freeresult($result); + } + + /** + * Sets the list of available migration class names to the given array. + * + * @param array $class_names An array of migration class names + * @return null + */ + function set_migrations($class_names) + { + $this->migrations = $class_names; + } + + /** + * Runs a single update step from the next migration to be applied. + * + * The update step can either be a schema or a (partial) data update. To + * check if update() needs to be called again use the finished() method. + * + * @return null + */ + function update() + { + foreach ($this->migrations as $name) + { + if (!isset($this->migration_state[$name]) || + !$this->migration_state[$name]['migration_schema_done'] || + !$this->migration_state[$name]['migration_data_done']) + { + if (!$this->try_apply($name)) + { + continue; + } + else + { + return; + } + } + } + } + + /** + * Attempts to apply a step of the given migration or one of its dependencies + * + * @param string The class name of the migration + * @return bool Whether any update step was successfully run + */ + function try_apply($name) + { + if (!class_exists($name)) + { + return false; + } + + $migration =& new $name($this->db, $this->db_tools); + $state = (isset($this->migration_state[$name])) ? + $this->migration_state[$name] : + array( + 'migration_schema_done' => false, + 'migration_data_done' => false, + 'migration_data_state' => '', + ); + + $depends = $migration->depends_on(); + + foreach ($depends as $depend) + { + if (!isset($this->migration_state[$depend]) || + !$this->migration_state[$depend]['migration_schema_done'] || + !$this->migration_state[$depend]['migration_data_done']) + { + return $this->try_apply($depend); + } + } + + if (!$state['migration_schema_done']) + { + $migration->update_schema(); + $state['migration_schema_done'] = true; + } + else + { + $migration->update_data(); + $state['migration_data_done'] = true; + } + + $sql = 'UPDATE ' . $this->migrations_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $state) . " + WHERE migration_name = '" . $this->db->sql_escape($name) . "'"; + $this->db->sql_query($sql); + + $this->migration_state[$name] = $state; + + return true; + } + + /** + * Checks if a migration's dependencies can even theoretically be satisfied. + * + * @param string $name The class name of the migration + * @return bool Whether the migration cannot be fulfilled + */ + function unfulfillable($name) + { + if (isset($this->migration_state[$name])) + { + return false; + } + + if (!class_exists($name)) + { + return true; + } + + $migration =& new $name($this->db, $this->db_tools); + $depends = $migration->depends_on(); + + foreach ($depends as $depend) + { + if ($this->unfulfillable($depend)) + { + return true; + } + } + + return false; + } + + /** + * Checks whether all available, fulfillable migrations have been applied. + * + * @return bool Whether the migrations have been applied + */ + function finished() + { + foreach ($this->migrations as $name) + { + if (!isset($this->migration_state[$name])) + { + // skip unfulfillable migrations, but fulfillables mean we + // are not finished yet + if ($this->unfulfillable($name)) + { + continue; + } + return false; + } + + $migration = $this->migration_state[$name]; + + if (!$migration['migration_schema_done'] || !$migration['migration_data_done']) + { + return false; + } + } + + return true; + } +} diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 767ce68b4a..43099fc33b 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -573,6 +573,18 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts(attempt_forwar CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts(attempt_time);; CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts(user_id);; +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + migration_schema_done INTEGER DEFAULT 0 NOT NULL, + migration_data_done INTEGER DEFAULT 0 NOT NULL, + migration_data_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, + migration_start_time INTEGER DEFAULT 0 NOT NULL, + migration_end_time INTEGER DEFAULT 0 NOT NULL +);; + +CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations(migration_name);; + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id INTEGER DEFAULT 0 NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 84c975942f..1174cdfa3d 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -696,6 +696,23 @@ CREATE INDEX [user_id] ON [phpbb_login_attempts]([user_id]) ON [PRIMARY] GO +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE [phpbb_migrations] ( + [migration_name] [varchar] (255) DEFAULT ('') NOT NULL , + [migration_schema_done] [int] DEFAULT (0) NOT NULL , + [migration_data_done] [int] DEFAULT (0) NOT NULL , + [migration_data_state] [varchar] (8000) DEFAULT ('') NOT NULL , + [migration_start_time] [int] DEFAULT (0) NOT NULL , + [migration_end_time] [int] DEFAULT (0) NOT NULL +) ON [PRIMARY] +GO + +CREATE UNIQUE INDEX [migration_name] ON [phpbb_migrations]([migration_name]) ON [PRIMARY] +GO + + /* Table: 'phpbb_moderator_cache' */ diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 8aab949103..d645c3384d 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -397,6 +397,18 @@ CREATE TABLE phpbb_login_attempts ( ); +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varbinary(255) DEFAULT '' NOT NULL, + migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_state blob NOT NULL, + migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + UNIQUE migration_name (migration_name) +); + + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index 04aef2844a..d10f2dc55a 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -397,6 +397,18 @@ CREATE TABLE phpbb_login_attempts ( ) CHARACTER SET `utf8` COLLATE `utf8_bin`; +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) DEFAULT '' NOT NULL, + migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_state text NOT NULL, + migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + UNIQUE migration_name (migration_name) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 91f906bc8b..9993caeb7a 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -780,6 +780,21 @@ CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id) / +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE phpbb_migrations ( + migration_name varchar2(255) DEFAULT '' , + migration_schema_done number(1) DEFAULT '0' NOT NULL, + migration_data_done number(1) DEFAULT '0' NOT NULL, + migration_data_state clob DEFAULT '' , + migration_start_time number(11) DEFAULT '0' NOT NULL, + migration_end_time number(11) DEFAULT '0' NOT NULL, + CONSTRAINT u_phpbb_migration_name UNIQUE (migration_name) +) +/ + + /* Table: 'phpbb_moderator_cache' */ diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index 619985e0d6..ef138dac0f 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -557,6 +557,20 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwa CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) DEFAULT '' NOT NULL, + migration_schema_done INT2 DEFAULT '0' NOT NULL CHECK (migration_schema_done >= 0), + migration_data_done INT2 DEFAULT '0' NOT NULL CHECK (migration_data_done >= 0), + migration_data_state varchar(8000) DEFAULT '' NOT NULL, + migration_start_time INT4 DEFAULT '0' NOT NULL CHECK (migration_start_time >= 0), + migration_end_time INT4 DEFAULT '0' NOT NULL CHECK (migration_end_time >= 0) +); + +CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations (migration_name); + /* Table: 'phpbb_moderator_cache' */ diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 1690a7dcab..309297779e 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -385,6 +385,18 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwa CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) NOT NULL DEFAULT '', + migration_schema_done INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_data_done INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_data_state text(65535) NOT NULL DEFAULT '', + migration_start_time INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_end_time INTEGER UNSIGNED NOT NULL DEFAULT '0' +); + +CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations (migration_name); + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', diff --git a/tests/dbal/fixtures/migrator.xml b/tests/dbal/fixtures/migrator.xml new file mode 100644 index 0000000000..1f9079c811 --- /dev/null +++ b/tests/dbal/fixtures/migrator.xml @@ -0,0 +1,27 @@ + + + + migration_name + migration_schema_done + migration_data_done + migration_data_state + migration_start_time + migration_end_time + + installed_migration + 1 + 1 + + 1234 + 5678 + +
+ + config_name + config_value + + foo + bar + +
+
diff --git a/tests/dbal/migration/dummy.php b/tests/dbal/migration/dummy.php new file mode 100644 index 0000000000..b286d44f77 --- /dev/null +++ b/tests/dbal/migration/dummy.php @@ -0,0 +1,26 @@ +db_column_add('phpbb_config', 'extra_column', array('UINT', 0)); + } + + function update_data() + { + $this->db->sql_query('UPDATE phpbb_config SET extra_column = 1'); + } +} diff --git a/tests/dbal/migration/unfulfillable.php b/tests/dbal/migration/unfulfillable.php new file mode 100644 index 0000000000..84136ffe6d --- /dev/null +++ b/tests/dbal/migration/unfulfillable.php @@ -0,0 +1,26 @@ +createXMLDataSet(dirname(__FILE__).'/fixtures/migrator.xml'); + } + + public function setup() + { + parent::setup(); + + $this->db = $this->new_dbal(); + $this->db_tools = new phpbb_db_tools($this->db); + $this->migrator = new phpbb_db_migrator($this->db, $this->db_tools, MIGRATIONS_TABLE); + } + + public function test_update() + { + $this->migrator->set_migrations(array('phpbb_dbal_migration_dummy')); + + // schema + $this->migrator->update(); + $this->assertFalse($this->migrator->finished()); + + // data + $this->migrator->update(); + $this->assertTrue($this->migrator->finished()); + + $this->assertSqlResultEquals( + array(array('extra_column' => '1')), + "SELECT extra_column FROM phpbb_config WHERE config_name = 'foo'", + 'Dummy migration created extra_column with value 1 in all rows.' + ); + + // cleanup + $this->db_tools->sql_column_remove('phpbb_config', 'extra_column'); + } + + public function test_unfulfillable() + { + $this->migrator->set_migrations(array('phpbb_dbal_migration_unfulfillable', 'phpbb_dbal_migration_dummy')); + + while (!$this->migrator->finished()) + { + $this->migrator->update(); + } + + $this->assertTrue($this->migrator->finished()); + + $this->assertSqlResultEquals( + array(array('extra_column' => '1')), + "SELECT extra_column FROM phpbb_config WHERE config_name = 'foo'", + 'Dummy migration was run, even though an unfulfillable migration was found.' + ); + + // cleanup + $this->db_tools->sql_column_remove('phpbb_config', 'extra_column'); + } +} From d304b6449db6e7c6f3c9058062aca0c641f023a4 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 7 Aug 2011 19:10:38 -0400 Subject: [PATCH 08/90] [feature/migrations] Store start and end time of migrations PHPBB3-9737 --- phpBB/includes/db/migrator.php | 21 +++++++++++++++++++++ tests/dbal/migrator_test.php | 33 +++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index d5d938ca28..f4613e3aec 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -127,6 +127,8 @@ class phpbb_db_migrator 'migration_schema_done' => false, 'migration_data_done' => false, 'migration_data_state' => '', + 'migration_start_time' => 0, + 'migration_end_time' => 0, ); $depends = $migration->depends_on(); @@ -141,6 +143,12 @@ class phpbb_db_migrator } } + if (!isset($this->migration_state[$name])) + { + $state['migration_start_time'] = time(); + $this->insert_migration($name, $state); + } + if (!$state['migration_schema_done']) { $migration->update_schema(); @@ -150,6 +158,7 @@ class phpbb_db_migrator { $migration->update_data(); $state['migration_data_done'] = true; + $state['migration_end_time'] = time(); } $sql = 'UPDATE ' . $this->migrations_table . ' @@ -162,6 +171,18 @@ class phpbb_db_migrator return true; } + function insert_migration($name, $state) + { + $migration_row = $state; + $migration_row['migration_name'] = $name; + + $sql = 'INSERT INTO ' . $this->migrations_table . ' + ' . $this->db->sql_build_array('INSERT', $migration_row); + $this->db->sql_query($sql); + + $this->migration_state[$name] = $state; + } + /** * Checks if a migration's dependencies can even theoretically be satisfied. * diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index 1e7d1343fc..dd194d7c05 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -26,7 +26,7 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/migrator.xml'); } - public function setup() + public function setUp() { parent::setup(); @@ -35,6 +35,12 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->migrator = new phpbb_db_migrator($this->db, $this->db_tools, MIGRATIONS_TABLE); } + public function tearDown() + { + // cleanup + $this->db_tools->sql_column_remove('phpbb_config', 'extra_column'); + } + public function test_update() { $this->migrator->set_migrations(array('phpbb_dbal_migration_dummy')); @@ -43,6 +49,16 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->migrator->update(); $this->assertFalse($this->migrator->finished()); + $this->assertSqlResultEquals( + array(array('success' => '1')), + "SELECT 1 as success + FROM phpbb_migrations + WHERE migration_name = 'phpbb_dbal_migration_dummy' + AND migration_start_time >= " . (time() - 1) . " + AND migration_start_time <= " . (time() + 1), + 'Start time set correctly' + ); + // data $this->migrator->update(); $this->assertTrue($this->migrator->finished()); @@ -53,8 +69,16 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case 'Dummy migration created extra_column with value 1 in all rows.' ); - // cleanup - $this->db_tools->sql_column_remove('phpbb_config', 'extra_column'); + $this->assertSqlResultEquals( + array(array('success' => '1')), + "SELECT 1 as success + FROM phpbb_migrations + WHERE migration_name = 'phpbb_dbal_migration_dummy' + AND migration_start_time <= migration_end_time + AND migration_end_time >= " . (time() - 1) . " + AND migration_end_time <= " . (time() + 1), + 'End time set correctly' + ); } public function test_unfulfillable() @@ -73,8 +97,5 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case "SELECT extra_column FROM phpbb_config WHERE config_name = 'foo'", 'Dummy migration was run, even though an unfulfillable migration was found.' ); - - // cleanup - $this->db_tools->sql_column_remove('phpbb_config', 'extra_column'); } } From 8645321f40d0b13de6201688c69f9f05bc649dcf Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 25 Oct 2012 12:26:44 -0700 Subject: [PATCH 09/90] [feature/migrations] Return schema changes in database update style array Returning the set of schema changes allows potentially aggregating to generate the overall install schema automatically from a set of migrations PHPBB3-9737 --- phpBB/includes/db/migration.php | 5 +++-- phpBB/includes/db/migrator.php | 7 ++++++- tests/dbal/migration/dummy.php | 8 +++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration.php index f96fcb9568..ee916aedc0 100644 --- a/phpBB/includes/db/migration.php +++ b/phpBB/includes/db/migration.php @@ -52,12 +52,13 @@ class phpbb_db_migration } /** - * Updates the database schema + * Updates the database schema by providing a set of change instructions * - * @return null + * @return array */ function update_schema() { + return array(); } /** diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index f4613e3aec..4a178af468 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -151,7 +151,7 @@ class phpbb_db_migrator if (!$state['migration_schema_done']) { - $migration->update_schema(); + $this->apply_schema_changes($migration->update_schema()); $state['migration_schema_done'] = true; } else @@ -245,4 +245,9 @@ class phpbb_db_migrator return true; } + + function apply_schema_changes($schema_changes) + { + $this->db_tools->perform_schema_changes($schema_changes); + } } diff --git a/tests/dbal/migration/dummy.php b/tests/dbal/migration/dummy.php index b286d44f77..0567b50740 100644 --- a/tests/dbal/migration/dummy.php +++ b/tests/dbal/migration/dummy.php @@ -16,7 +16,13 @@ class phpbb_dbal_migration_dummy extends phpbb_db_migration function update_schema() { - $this->db_column_add('phpbb_config', 'extra_column', array('UINT', 0)); + return array( + 'add_columns' => array( + 'phpbb_config' => array( + 'extra_column' => array('UINT', 0), + ), + ), + ); } function update_data() From c802f2a66c577781036b7bfd6d6689159028c3a6 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 25 Oct 2012 13:02:56 -0700 Subject: [PATCH 10/90] [feature/migrations] Standard vars for migrations and run sql with feedback PHPBB3-9737 --- phpBB/includes/db/migration.php | 52 ++++++++++++++++++++++++++++++--- phpBB/includes/db/migrator.php | 17 +++++++++-- tests/dbal/migrator_test.php | 2 +- 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration.php index ee916aedc0..09d4e31344 100644 --- a/phpBB/includes/db/migration.php +++ b/phpBB/includes/db/migration.php @@ -28,17 +28,32 @@ class phpbb_db_migration { var $db; var $db_tools; + var $table_prefix; + + var $phpbb_root_path; + var $php_ext; + + var $errors; /** * Migration constructor * * @param dbal $db Connected database abstraction instance * @param phpbb_db_tools $db_tools Instance of db schema manipulation tools + * @param string $table_prefix The prefix for all table names + * @param string $phpbb_root_path + * @param string $php_ext */ - function phpbb_db_migration(&$db, &$db_tools) + function phpbb_db_migration(&$db, &$db_tools, $table_prefix, $phpbb_root_path, $php_ext) { $this->db = &$db; $this->db_tools = &$db_tools; + $this->table_prefix = $table_prefix; + + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + $this->errors = array(); } /** @@ -71,10 +86,39 @@ class phpbb_db_migration } /** - * Adds a column to a database table + * Wrapper for running queries to generate user feedback on updates */ - function db_column_add($table_name, $column_name, $column_data) + function sql_query($sql) { - $this->db_tools->sql_column_add($table_name, $column_name, $column_data); + if (defined('DEBUG_EXTRA')) + { + echo "
\n{$sql}\n
"; + } + + $db->sql_return_on_error(true); + + if ($sql === 'begin') + { + $result = $db->sql_transaction('begin'); + } + else if ($sql === 'commit') + { + $result = $db->sql_transaction('commit'); + } + else + { + $result = $db->sql_query($sql); + if ($db->sql_error_triggered) + { + $this->errors[] = array( + 'sql' => $db->sql_error_sql, + 'code' => $db->sql_error_returned, + ); + } + } + + $db->sql_return_on_error(false); + + return $result; } } diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 4a178af468..4ce54a4b92 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -24,6 +24,10 @@ class phpbb_db_migrator { var $db; var $db_tools; + var $table_prefix; + + var $phpbb_root_path; + var $php_ext; var $migrations_table; var $migration_state; @@ -35,16 +39,23 @@ class phpbb_db_migrator * * @param dbal $db Connected database abstraction instance * @param phpbb_db_tools $db_tools Instance of db schema manipulation tools + * @param string $table_prefix The prefix for all table names * @param string $migrations_table The name of the db table storing * information on applied migrations + * @param string $phpbb_root_path + * @param string $php_ext */ - function phpbb_db_migrator(&$db, &$db_tools, $migrations_table) + function phpbb_db_migrator(&$db, &$db_tools, $table_prefix, $migrations_table, $phpbb_root_path, $php_ext) { $this->db = &$db; $this->db_tools = &$db_tools; + $this->table_prefix = $table_prefix; $this->migrations_table = $migrations_table; $this->migrations = array(); + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->load_migration_state(); } @@ -120,7 +131,7 @@ class phpbb_db_migrator return false; } - $migration =& new $name($this->db, $this->db_tools); + $migration =& new $name($this->db, $this->db_tools, $this->table_prefix, $this->phpbb_root_path, $this->php_ext); $state = (isset($this->migration_state[$name])) ? $this->migration_state[$name] : array( @@ -201,7 +212,7 @@ class phpbb_db_migrator return true; } - $migration =& new $name($this->db, $this->db_tools); + $migration =& new $name($this->db, $this->db_tools, $this->table_prefix, $this->phpbb_root_path, $this->php_ext); $depends = $migration->depends_on(); foreach ($depends as $depend) diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index dd194d7c05..898a197dfd 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -32,7 +32,7 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->db = $this->new_dbal(); $this->db_tools = new phpbb_db_tools($this->db); - $this->migrator = new phpbb_db_migrator($this->db, $this->db_tools, MIGRATIONS_TABLE); + $this->migrator = new phpbb_db_migrator($this->db, $this->db_tools, 'phpbb_', MIGRATIONS_TABLE, 'phpBB/', '.php'); } public function tearDown() From b1f9ca2f6541924c75a30c68dd8a4bc8db62205d Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 9 Nov 2012 17:10:48 +0100 Subject: [PATCH 11/90] [feature/migrations] Moved database_update info to individual migration classes --- phpBB/develop/create_schema_files.php | 14 - phpBB/includes/db/migration.php | 2 +- phpBB/includes/db/migration/v301.php | 25 + phpBB/includes/db/migration/v3010.php | 25 + phpBB/includes/db/migration/v3010rc1.php | 29 + phpBB/includes/db/migration/v3010rc2.php | 25 + phpBB/includes/db/migration/v3010rc3.php | 25 + phpBB/includes/db/migration/v3011.php | 25 + phpBB/includes/db/migration/v3011rc1.php | 83 ++ phpBB/includes/db/migration/v3011rc2.php | 31 + phpBB/includes/db/migration/v3012rc1.php | 26 + phpBB/includes/db/migration/v301rc1.php | 77 ++ phpBB/includes/db/migration/v302.php | 25 + phpBB/includes/db/migration/v302rc1.php | 30 + phpBB/includes/db/migration/v302rc2.php | 52 + phpBB/includes/db/migration/v303.php | 25 + phpBB/includes/db/migration/v303rc1.php | 135 ++ phpBB/includes/db/migration/v304.php | 40 + phpBB/includes/db/migration/v304rc1.php | 96 ++ phpBB/includes/db/migration/v305.php | 25 + phpBB/includes/db/migration/v305rc1.php | 146 +++ phpBB/includes/db/migration/v306.php | 25 + phpBB/includes/db/migration/v306rc1.php | 350 ++++++ phpBB/includes/db/migration/v306rc2.php | 25 + phpBB/includes/db/migration/v306rc3.php | 31 + phpBB/includes/db/migration/v306rc4.php | 25 + phpBB/includes/db/migration/v307.php | 25 + phpBB/includes/db/migration/v307pl1.php | 25 + phpBB/includes/db/migration/v307rc1.php | 46 + phpBB/includes/db/migration/v307rc2.php | 53 + phpBB/includes/db/migration/v308.php | 25 + phpBB/includes/db/migration/v308rc1.php | 222 ++++ phpBB/includes/db/migration/v309.php | 25 + phpBB/includes/db/migration/v309rc1.php | 100 ++ phpBB/includes/db/migration/v309rc2.php | 25 + phpBB/includes/db/migration/v309rc3.php | 25 + phpBB/includes/db/migration/v309rc4.php | 25 + phpBB/install/database_update.php | 1457 ---------------------- 38 files changed, 1998 insertions(+), 1472 deletions(-) create mode 100644 phpBB/includes/db/migration/v301.php create mode 100644 phpBB/includes/db/migration/v3010.php create mode 100644 phpBB/includes/db/migration/v3010rc1.php create mode 100644 phpBB/includes/db/migration/v3010rc2.php create mode 100644 phpBB/includes/db/migration/v3010rc3.php create mode 100644 phpBB/includes/db/migration/v3011.php create mode 100644 phpBB/includes/db/migration/v3011rc1.php create mode 100644 phpBB/includes/db/migration/v3011rc2.php create mode 100644 phpBB/includes/db/migration/v3012rc1.php create mode 100644 phpBB/includes/db/migration/v301rc1.php create mode 100644 phpBB/includes/db/migration/v302.php create mode 100644 phpBB/includes/db/migration/v302rc1.php create mode 100644 phpBB/includes/db/migration/v302rc2.php create mode 100644 phpBB/includes/db/migration/v303.php create mode 100644 phpBB/includes/db/migration/v303rc1.php create mode 100644 phpBB/includes/db/migration/v304.php create mode 100644 phpBB/includes/db/migration/v304rc1.php create mode 100644 phpBB/includes/db/migration/v305.php create mode 100644 phpBB/includes/db/migration/v305rc1.php create mode 100644 phpBB/includes/db/migration/v306.php create mode 100644 phpBB/includes/db/migration/v306rc1.php create mode 100644 phpBB/includes/db/migration/v306rc2.php create mode 100644 phpBB/includes/db/migration/v306rc3.php create mode 100644 phpBB/includes/db/migration/v306rc4.php create mode 100644 phpBB/includes/db/migration/v307.php create mode 100644 phpBB/includes/db/migration/v307pl1.php create mode 100644 phpBB/includes/db/migration/v307rc1.php create mode 100644 phpBB/includes/db/migration/v307rc2.php create mode 100644 phpBB/includes/db/migration/v308.php create mode 100644 phpBB/includes/db/migration/v308rc1.php create mode 100644 phpBB/includes/db/migration/v309.php create mode 100644 phpBB/includes/db/migration/v309rc1.php create mode 100644 phpBB/includes/db/migration/v309rc2.php create mode 100644 phpBB/includes/db/migration/v309rc3.php create mode 100644 phpBB/includes/db/migration/v309rc4.php diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 82fbb183c1..3d3e478032 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1258,20 +1258,6 @@ function get_schema_struct() ), ); - $schema_data['phpbb_migrations'] = array( - 'COLUMNS' => array( - 'migration_name' => array('VCHAR', ''), - 'migration_schema_done' => array('BOOL', 0), - 'migration_data_done' => array('BOOL', 0), - 'migration_data_state' => array('TEXT', ''), - 'migration_start_time' => array('TIMESTAMP', 0), - 'migration_end_time' => array('TIMESTAMP', 0), - ), - 'KEYS' => array( - 'migration_name' => array('UNIQUE', 'migration_name'), - ), - ); - $schema_data['phpbb_moderator_cache'] = array( 'COLUMNS' => array( 'forum_id' => array('UINT', 0), diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration.php index 09d4e31344..aca9d264bb 100644 --- a/phpBB/includes/db/migration.php +++ b/phpBB/includes/db/migration.php @@ -3,7 +3,7 @@ * * @package db * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 * */ diff --git a/phpBB/includes/db/migration/v301.php b/phpBB/includes/db/migration/v301.php new file mode 100644 index 0000000000..8a2a265a3c --- /dev/null +++ b/phpBB/includes/db/migration/v301.php @@ -0,0 +1,25 @@ +sql_query($sql); + + $deactivated_style_ids = array(); + while ($style_id = $db->sql_fetchfield('style_id', false, $result)) + { + $deactivated_style_ids[] = (int) $style_id; + } + $db->sql_freeresult($result); + + if (!empty($deactivated_style_ids)) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_style = ' . (int) $config['default_style'] .' + WHERE ' . $db->sql_in_set('user_style', $deactivated_style_ids); + _sql($sql, $errored, $error_ary); + } + + // Delete orphan private messages + $batch_size = 500; + + $sql_array = array( + 'SELECT' => 'p.msg_id', + 'FROM' => array( + PRIVMSGS_TABLE => 'p', + ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(PRIVMSGS_TO_TABLE => 't'), + 'ON' => 'p.msg_id = t.msg_id', + ), + ), + 'WHERE' => 't.user_id IS NULL', + ); + $sql = $db->sql_build_query('SELECT', $sql_array); + + do + { + $result = $db->sql_query_limit($sql, $batch_size); + + $delete_pms = array(); + while ($row = $db->sql_fetchrow($result)) + { + $delete_pms[] = (int) $row['msg_id']; + } + $db->sql_freeresult($result); + + if (!empty($delete_pms)) + { + $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' + WHERE ' . $db->sql_in_set('msg_id', $delete_pms); + _sql($sql, $errored, $error_ary); + } + } + while (sizeof($delete_pms) == $batch_size); + } +} diff --git a/phpBB/includes/db/migration/v3011rc2.php b/phpBB/includes/db/migration/v3011rc2.php new file mode 100644 index 0000000000..0f66eff156 --- /dev/null +++ b/phpBB/includes/db/migration/v3011rc2.php @@ -0,0 +1,31 @@ + array( + $this->table_prefix . 'profile_fields' => array( + 'field_show_novalue' => array('BOOL', 0), + ), + ), + ); + } + + function update_data() + { + } +} diff --git a/phpBB/includes/db/migration/v3012rc1.php b/phpBB/includes/db/migration/v3012rc1.php new file mode 100644 index 0000000000..67f7a29b02 --- /dev/null +++ b/phpBB/includes/db/migration/v3012rc1.php @@ -0,0 +1,26 @@ + array( + $this->table_prefix . 'forums' => array( + 'display_subforum_list' => array('BOOL', 1), + ), + $this->table_prefix . 'sessions' => array( + 'session_forum_id' => array('UINT', 0), + ), + ), + 'drop_keys' => array( + $this->table_prefix . 'groups' => array('group_legend'), + ), + 'add_index' => array( + $this->table_prefix . 'sessions' => array( + 'session_forum_id' => array('session_forum_id'), + ), + $this->table_prefix . 'groups' => array( + 'group_legend_name' => array('group_legend', 'group_name'), + ), + ), + ); + } + + function update_data() + { + return array( + array('custom', array(array(&$this, 'fix_unset_last_view_time'))), + array('custom', array(array(&$this, 'reset_smiley_size'))), + ); + } + + function fix_unset_last_view_time() + { + $sql = 'UPDATE ' . $this->table_prefix . "topics + SET topic_last_view_time = topic_last_post_time + WHERE topic_last_view_time = 0"; + $this->sql_query($sql); + } + + function reset_smiley_size() + { + // Update smiley sizes + $smileys = array('icon_e_surprised.gif', 'icon_eek.gif', 'icon_cool.gif', 'icon_lol.gif', 'icon_mad.gif', 'icon_razz.gif', 'icon_redface.gif', 'icon_cry.gif', 'icon_evil.gif', 'icon_twisted.gif', 'icon_rolleyes.gif', 'icon_exclaim.gif', 'icon_question.gif', 'icon_idea.gif', 'icon_arrow.gif', 'icon_neutral.gif', 'icon_mrgreen.gif', 'icon_e_ugeek.gif'); + + foreach ($smileys as $smiley) + { + if (file_exists($this->phpbb_root_path . 'images/smilies/' . $smiley)) + { + list($width, $height) = getimagesize($this->phpbb_root_path . 'images/smilies/' . $smiley); + + $sql = 'UPDATE ' . SMILIES_TABLE . ' + SET smiley_width = ' . $width . ', smiley_height = ' . $height . " + WHERE smiley_url = '" . $this->db->sql_escape($smiley) . "'"; + + $this->sql_query($sql); + } + } + } +} diff --git a/phpBB/includes/db/migration/v302.php b/phpBB/includes/db/migration/v302.php new file mode 100644 index 0000000000..942a0ac58c --- /dev/null +++ b/phpBB/includes/db/migration/v302.php @@ -0,0 +1,25 @@ + array( + $this->table_prefix . 'drafts' => array( + 'draft_subject' => array('STEXT_UNI', ''), + ), + $this->table_prefix . 'forums' => array( + 'forum_last_post_subject' => array('STEXT_UNI', ''), + ), + $this->table_prefix . 'posts' => array( + 'post_subject' => array('STEXT_UNI', '', 'true_sort'), + ), + $this->table_prefix . 'privmsgs' => array( + 'message_subject' => array('STEXT_UNI', ''), + ), + $this->table_prefix . 'topics' => array( + 'topic_title' => array('STEXT_UNI', '', 'true_sort'), + 'topic_last_post_subject' => array('STEXT_UNI', ''), + ), + ), + 'drop_keys' => array( + $this->table_prefix . 'sessions' => array('session_forum_id'), + ), + 'add_index' => array( + $this->table_prefix . 'sessions' => array( + 'session_fid' => array('session_forum_id'), + ), + ), + ); + } + + function update_data() + { + } +} diff --git a/phpBB/includes/db/migration/v303.php b/phpBB/includes/db/migration/v303.php new file mode 100644 index 0000000000..409c396baf --- /dev/null +++ b/phpBB/includes/db/migration/v303.php @@ -0,0 +1,25 @@ + array( + $this->table_prefix . 'styles_template' => array( + 'template_inherits_id' => array('UINT:4', 0), + 'template_inherit_path' => array('VCHAR', ''), + ), + $this->table_prefix . 'groups' => array( + 'group_max_recipients' => array('UINT', 0), + ), + ), + ); + } + + function update_data() + { + return array( + array('config.add', array('enable_queue_trigger', '0')), + array('config.add', array('queue_trigger_posts', '3')), + array('config.add', array('pm_max_recipients', '0')), + array('custom', array('set_group_default_max_recipients')) + + // Not prefilling yet + set_config('dbms_version', ''); + + // Add new permission u_masspm_group and duplicate settings from u_masspm + include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + $auth_admin = new auth_admin(); + + // Only add the new permission if it does not already exist + if (empty($auth_admin->acl_options['id']['u_masspm_group'])) + { + $auth_admin->acl_add_option(array('global' => array('u_masspm_group'))); + + // Now the tricky part, filling the permission + $old_id = $auth_admin->acl_options['id']['u_masspm']; + $new_id = $auth_admin->acl_options['id']['u_masspm_group']; + + $tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE); + + foreach ($tables as $table) + { + $sql = 'SELECT * + FROM ' . $table . ' + WHERE auth_option_id = ' . $old_id; + $result = _sql($sql, $errored, $error_ary); + + $sql_ary = array(); + while ($row = $db->sql_fetchrow($result)) + { + $row['auth_option_id'] = $new_id; + $sql_ary[] = $row; + } + $db->sql_freeresult($result); + + if (sizeof($sql_ary)) + { + $db->sql_multi_insert($table, $sql_ary); + } + } + + // Remove any old permission entries + $auth_admin->acl_clear_prefetch(); + } + + /** + * Do not resync post counts here. An admin may do this later from the ACP + $start = 0; + $step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000; + + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = 0'; + _sql($sql, $errored, $error_ary); + + do + { + $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id + FROM ' . POSTS_TABLE . ' + WHERE post_id BETWEEN ' . ($start + 1) . ' AND ' . ($start + $step) . ' + AND post_postcount = 1 AND post_approved = 1 + GROUP BY poster_id'; + $result = _sql($sql, $errored, $error_ary); + + if ($row = $db->sql_fetchrow($result)) + { + do + { + $sql = 'UPDATE ' . USERS_TABLE . " SET user_posts = user_posts + {$row['num_posts']} WHERE user_id = {$row['poster_id']}"; + _sql($sql, $errored, $error_ary); + } + while ($row = $db->sql_fetchrow($result)); + + $start += $step; + } + else + { + $start = 0; + } + $db->sql_freeresult($result); + } + while ($start); + */ + + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET module_auth = \'acl_a_email && cfg_email_enable\' + WHERE module_class = \'acp\' + AND module_basename = \'email\''; + _sql($sql, $errored, $error_ary); + } + + function set_group_default_max_recipients() + { + // Set maximum number of recipients for the registered users, bots, guests group + $sql = 'UPDATE ' . GROUPS_TABLE . ' SET group_max_recipients = 5 + WHERE ' . $this->db->sql_in_set('group_name', array('GUESTS', 'REGISTERED', 'REGISTERED_COPPA', 'BOTS')); + $this->sql_query($sql); + } + +} diff --git a/phpBB/includes/db/migration/v304.php b/phpBB/includes/db/migration/v304.php new file mode 100644 index 0000000000..2895caaa6d --- /dev/null +++ b/phpBB/includes/db/migration/v304.php @@ -0,0 +1,40 @@ +sql_layer == 'oracle') + { + // log_operation is CLOB - but we can change this later + $sql = 'UPDATE ' . LOG_TABLE . " + SET log_operation = 'LOG_DELETE_TOPIC' + WHERE log_operation LIKE 'LOG_TOPIC_DELETED'"; + _sql($sql, $errored, $error_ary); + } + else + { + $sql = 'UPDATE ' . LOG_TABLE . " + SET log_operation = 'LOG_DELETE_TOPIC' + WHERE log_operation = 'LOG_TOPIC_DELETED'"; + _sql($sql, $errored, $error_ary); + } + } +} diff --git a/phpBB/includes/db/migration/v304rc1.php b/phpBB/includes/db/migration/v304rc1.php new file mode 100644 index 0000000000..a7098ce62f --- /dev/null +++ b/phpBB/includes/db/migration/v304rc1.php @@ -0,0 +1,96 @@ + array( + $this->table_prefix . 'profile_fields' => array( + 'field_show_profile' => array('BOOL', 0), + ), + ), + 'change_columns' => array( + $this->table_prefix . 'styles' => array( + 'style_id' => array('UINT', NULL, 'auto_increment'), + 'template_id' => array('UINT', 0), + 'theme_id' => array('UINT', 0), + 'imageset_id' => array('UINT', 0), + ), + $this->table_prefix . 'styles_imageset' => array( + 'imageset_id' => array('UINT', NULL, 'auto_increment'), + ), + $this->table_prefix . 'styles_imageset_data' => array( + 'image_id' => array('UINT', NULL, 'auto_increment'), + 'imageset_id' => array('UINT', 0), + ), + $this->table_prefix . 'styles_theme' => array( + 'theme_id' => array('UINT', NULL, 'auto_increment'), + ), + $this->table_prefix . 'styles_template' => array( + 'template_id' => array('UINT', NULL, 'auto_increment'), + ), + $this->table_prefix . 'styles_template_data' => array( + 'template_id' => array('UINT', 0), + ), + $this->table_prefix . 'forums' => array( + 'forum_style' => array('UINT', 0), + ), + $this->table_prefix . 'users' => array( + 'user_style' => array('UINT', 0), + ), + ), + ); + } + + function update_data() + { + // Update the Custom Profile Fields based on previous settings to the new format + $sql = 'SELECT field_id, field_required, field_show_on_reg, field_hide + FROM ' . PROFILE_FIELDS_TABLE; + $result = _sql($sql, $errored, $error_ary); + + while ($row = $db->sql_fetchrow($result)) + { + $sql_ary = array( + 'field_required' => 0, + 'field_show_on_reg' => 0, + 'field_hide' => 0, + 'field_show_profile'=> 0, + ); + + if ($row['field_required']) + { + $sql_ary['field_required'] = $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; + } + else if ($row['field_show_on_reg']) + { + $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; + } + else if ($row['field_hide']) + { + // Only administrators and moderators can see this CPF, if the view is enabled, they can see it, otherwise just admins in the acp_users module + $sql_ary['field_hide'] = 1; + } + else + { + // equivelant to "none", which is the "Display in user control panel" option + $sql_ary['field_show_profile'] = 1; + } + + _sql('UPDATE ' . PROFILE_FIELDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary); + } + } +} diff --git a/phpBB/includes/db/migration/v305.php b/phpBB/includes/db/migration/v305.php new file mode 100644 index 0000000000..b4d676d72a --- /dev/null +++ b/phpBB/includes/db/migration/v305.php @@ -0,0 +1,25 @@ + array( + $this->table_prefix . 'forums' => array( + 'forum_style' => array('UINT', 0), + ), + ), + ); + } + + function update_data() + { + // Captcha config variables + set_config('captcha_gd_wave', 0); + set_config('captcha_gd_3d_noise', 1); + set_config('captcha_gd_fonts', 1); + set_config('confirm_refresh', 1); + + // Maximum number of keywords + set_config('max_num_search_keywords', 10); + + // Remove static config var and put it back as dynamic variable + $sql = 'UPDATE ' . CONFIG_TABLE . " + SET is_dynamic = 1 + WHERE config_name = 'search_indexing_state'"; + _sql($sql, $errored, $error_ary); + + // Hash old MD5 passwords + $sql = 'SELECT user_id, user_password + FROM ' . USERS_TABLE . ' + WHERE user_pass_convert = 1'; + $result = _sql($sql, $errored, $error_ary); + + while ($row = $db->sql_fetchrow($result)) + { + if (strlen($row['user_password']) == 32) + { + $sql_ary = array( + 'user_password' => phpbb_hash($row['user_password']), + ); + + _sql('UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id'], $errored, $error_ary); + } + } + $db->sql_freeresult($result); + + // Adjust bot entry + $sql = 'UPDATE ' . BOTS_TABLE . " + SET bot_agent = 'ichiro/' + WHERE bot_agent = 'ichiro/2'"; + _sql($sql, $errored, $error_ary); + + + // Before we are able to add a unique key to auth_option, we need to remove duplicate entries + + // We get duplicate entries first + $sql = 'SELECT auth_option + FROM ' . ACL_OPTIONS_TABLE . ' + GROUP BY auth_option + HAVING COUNT(*) >= 2'; + $result = $db->sql_query($sql); + + $auth_options = array(); + while ($row = $db->sql_fetchrow($result)) + { + $auth_options[] = $row['auth_option']; + } + $db->sql_freeresult($result); + + // Remove specific auth options + if (!empty($auth_options)) + { + foreach ($auth_options as $option) + { + // Select auth_option_ids... the largest id will be preserved + $sql = 'SELECT auth_option_id + FROM ' . ACL_OPTIONS_TABLE . " + WHERE auth_option = '" . $db->sql_escape($option) . "' + ORDER BY auth_option_id DESC"; + // sql_query_limit not possible here, due to bug in postgresql layer + $result = $db->sql_query($sql); + + // Skip first row, this is our original auth option we want to preserve + $row = $db->sql_fetchrow($result); + + while ($row = $db->sql_fetchrow($result)) + { + // Ok, remove this auth option... + _sql('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + _sql('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + _sql('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + _sql('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + } + $db->sql_freeresult($result); + } + } + + // Now make auth_option UNIQUE, by dropping the old index and adding a UNIQUE one. + $changes = array( + 'drop_keys' => array( + ACL_OPTIONS_TABLE => array('auth_option'), + ), + ); + + global $db_tools; + + $statements = $db_tools->perform_schema_changes($changes); + + foreach ($statements as $sql) + { + _sql($sql, $errored, $error_ary); + } + + $changes = array( + 'add_unique_index' => array( + ACL_OPTIONS_TABLE => array( + 'auth_option' => array('auth_option'), + ), + ), + ); + + $statements = $db_tools->perform_schema_changes($changes); + + foreach ($statements as $sql) + { + _sql($sql, $errored, $error_ary); + } + } +} diff --git a/phpBB/includes/db/migration/v306.php b/phpBB/includes/db/migration/v306.php new file mode 100644 index 0000000000..eec2f7c752 --- /dev/null +++ b/phpBB/includes/db/migration/v306.php @@ -0,0 +1,25 @@ + array( + $this->table_prefix . 'confirm' => array( + 'attempts' => array('UINT', 0), + ), + $this->table_prefix . 'users' => array( + 'user_new' => array('BOOL', 1), + 'user_reminded' => array('TINT:4', 0), + 'user_reminded_time' => array('TIMESTAMP', 0), + ), + $this->table_prefix . 'groups' => array( + 'group_skip_auth' => array('BOOL', 0, 'after' => 'group_founder_manage'), + ), + $this->table_prefix . 'privmsgs' => array( + 'message_reported' => array('BOOL', 0), + ), + $this->table_prefix . 'reports' => array( + 'pm_id' => array('UINT', 0), + ), + $this->table_prefix . 'fields' => array( + 'field_show_on_vt' => array('BOOL', 0), + ), + $this->table_prefix . 'forums' => array( + 'forum_options' => array('UINT:20', 0), + ), + ), + 'change_columns' => array( + $this->table_prefix . 'users' => array( + 'user_options' => array('UINT:11', 230271), + ), + ), + 'add_index' => array( + $this->table_prefix . 'reports' => array( + 'post_id' => array('post_id'), + 'pm_id' => array('pm_id'), + ), + $this->table_prefix . 'posts' => array( + 'post_username' => array('post_username:255'), + ), + ), + ); + } + + function update_data() + { + // Let's see if the GD Captcha can be enabled... we simply look for what *is* enabled... + if (!empty($config['captcha_gd']) && !isset($config['captcha_plugin'])) + { + set_config('captcha_plugin', 'phpbb_captcha_gd'); + } + else if (!isset($config['captcha_plugin'])) + { + set_config('captcha_plugin', 'phpbb_captcha_nogd'); + } + + // Entries for the Feed Feature + set_config('feed_enable', '0'); + set_config('feed_limit', '10'); + + set_config('feed_overall_forums', '1'); + set_config('feed_overall_forums_limit', '15'); + + set_config('feed_overall_topics', '0'); + set_config('feed_overall_topics_limit', '15'); + + set_config('feed_forum', '1'); + set_config('feed_topic', '1'); + set_config('feed_item_statistics', '1'); + + // Entries for smiley pagination + set_config('smilies_per_page', '50'); + + // Entry for reporting PMs + set_config('allow_pm_report', '1'); + + // Install modules + $modules_to_install = array( + 'feed' => array( + 'base' => 'board', + 'class' => 'acp', + 'title' => 'ACP_FEED_SETTINGS', + 'auth' => 'acl_a_board', + 'cat' => 'ACP_BOARD_CONFIGURATION', + 'after' => array('signature', 'ACP_SIGNATURE_SETTINGS') + ), + 'warnings' => array( + 'base' => 'users', + 'class' => 'acp', + 'title' => 'ACP_USER_WARNINGS', + 'auth' => 'acl_a_user', + 'display' => 0, + 'cat' => 'ACP_CAT_USERS', + 'after' => array('feedback', 'ACP_USER_FEEDBACK') + ), + 'send_statistics' => array( + 'base' => 'send_statistics', + 'class' => 'acp', + 'title' => 'ACP_SEND_STATISTICS', + 'auth' => 'acl_a_server', + 'cat' => 'ACP_SERVER_CONFIGURATION' + ), + 'setting_forum_copy' => array( + 'base' => 'permissions', + 'class' => 'acp', + 'title' => 'ACP_FORUM_PERMISSIONS_COPY', + 'auth' => 'acl_a_fauth && acl_a_authusers && acl_a_authgroups && acl_a_mauth', + 'cat' => 'ACP_FORUM_BASED_PERMISSIONS', + 'after' => array('setting_forum_local', 'ACP_FORUM_PERMISSIONS') + ), + 'pm_reports' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORTS_OPEN', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + 'pm_reports_closed' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORTS_CLOSED', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + 'pm_report_details' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORT_DETAILS', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + ); + + _add_modules($modules_to_install); + + // Add newly_registered group... but check if it already exists (we always supported running the updater on any schema) + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = 'NEWLY_REGISTERED'"; + $result = $db->sql_query($sql); + $group_id = (int) $db->sql_fetchfield('group_id'); + $db->sql_freeresult($result); + + if (!$group_id) + { + $sql = 'INSERT INTO ' . GROUPS_TABLE . " (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('NEWLY_REGISTERED', 3, 0, '', 0, '', '', '', 5)"; + _sql($sql, $errored, $error_ary); + + $group_id = $db->sql_nextid(); + } + + // Insert new user role... at the end of the chain + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = 'ROLE_USER_NEW_MEMBER' + AND role_type = 'u_'"; + $result = $db->sql_query($sql); + $u_role = (int) $db->sql_fetchfield('role_id'); + $db->sql_freeresult($result); + + if (!$u_role) + { + $sql = 'SELECT MAX(role_order) as max_order_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_type = 'u_'"; + $result = $db->sql_query($sql); + $next_order_id = (int) $db->sql_fetchfield('max_order_id'); + $db->sql_freeresult($result); + + $next_order_id++; + + $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_NEW_MEMBER', 'ROLE_DESCRIPTION_USER_NEW_MEMBER', 'u_', $next_order_id)"; + _sql($sql, $errored, $error_ary); + $u_role = $db->sql_nextid(); + + if (!$errored) + { + // Now add the correct data to the roles... + // The standard role says that new users are not able to send a PM, Mass PM, are not able to PM groups + $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $u_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_sendpm', 'u_masspm', 'u_masspm_group')"; + _sql($sql, $errored, $error_ary); + + // Add user role to group + $sql = 'INSERT INTO ' . ACL_GROUPS_TABLE . " (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES ($group_id, 0, 0, $u_role, 0)"; + _sql($sql, $errored, $error_ary); + } + } + + // Insert new forum role + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = 'ROLE_FORUM_NEW_MEMBER' + AND role_type = 'f_'"; + $result = $db->sql_query($sql); + $f_role = (int) $db->sql_fetchfield('role_id'); + $db->sql_freeresult($result); + + if (!$f_role) + { + $sql = 'SELECT MAX(role_order) as max_order_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_type = 'f_'"; + $result = $db->sql_query($sql); + $next_order_id = (int) $db->sql_fetchfield('max_order_id'); + $db->sql_freeresult($result); + + $next_order_id++; + + $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_NEW_MEMBER', 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER', 'f_', $next_order_id)"; + _sql($sql, $errored, $error_ary); + $f_role = $db->sql_nextid(); + + if (!$errored) + { + $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $f_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove')"; + _sql($sql, $errored, $error_ary); + } + } + + // Set every members user_new column to 0 (old users) only if there is no one yet (this makes sure we do not execute this more than once) + $sql = 'SELECT 1 + FROM ' . USERS_TABLE . ' + WHERE user_new = 0'; + $result = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!$row) + { + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new = 0'; + _sql($sql, $errored, $error_ary); + } + + // Newly registered users limit + if (!isset($config['new_member_post_limit'])) + { + set_config('new_member_post_limit', (!empty($config['enable_queue_trigger'])) ? $config['queue_trigger_posts'] : 0); + } + + if (!isset($config['new_member_group_default'])) + { + set_config('new_member_group_default', 0); + } + + // To mimick the old "feature" we will assign the forum role to every forum, regardless of the setting (this makes sure there are no "this does not work!!!! YUO!!!" posts... + // Check if the role is already assigned... + $sql = 'SELECT forum_id + FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id . ' + AND auth_role_id = ' . $f_role; + $result = $db->sql_query($sql); + $is_options = (int) $db->sql_fetchfield('forum_id'); + $db->sql_freeresult($result); + + // Not assigned at all... :/ + if (!$is_options) + { + // Get postable forums + $sql = 'SELECT forum_id + FROM ' . FORUMS_TABLE . ' + WHERE forum_type != ' . FORUM_LINK; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + _sql('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (' . $group_id . ', ' . (int) $row['forum_id'] . ', 0, ' . $f_role . ', 0)', $errored, $error_ary); + } + $db->sql_freeresult($result); + } + + // Clear permissions... + include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + $auth_admin = new auth_admin(); + $auth_admin->acl_clear_prefetch(); + + if (!isset($config['allow_avatar'])) + { + if ($config['allow_avatar_upload'] || $config['allow_avatar_local'] || $config['allow_avatar_remote']) + { + set_config('allow_avatar', '1'); + } + else + { + set_config('allow_avatar', '0'); + } + } + + if (!isset($config['allow_avatar_remote_upload'])) + { + if ($config['allow_avatar_remote'] && $config['allow_avatar_upload']) + { + set_config('allow_avatar_remote_upload', '1'); + } + else + { + set_config('allow_avatar_remote_upload', '0'); + } + } + + // Minimum number of characters + if (!isset($config['min_post_chars'])) + { + set_config('min_post_chars', '1'); + } + + if (!isset($config['allow_quick_reply'])) + { + set_config('allow_quick_reply', '1'); + } + + // Set every members user_options column to enable + // bbcode, smilies and URLs for signatures by default + $sql = 'SELECT user_options + FROM ' . USERS_TABLE . ' + WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; + $result = $db->sql_query_limit($sql, 1); + $user_option = (int) $db->sql_fetchfield('user_options'); + $db->sql_freeresult($result); + + // Check if we already updated the database by checking bit 15 which we used to store the sig_bbcode option + if (!($user_option & 1 << 15)) + { + // 229376 is the added value to enable all three signature options + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_options = user_options + 229376'; + _sql($sql, $errored, $error_ary); + } + + if (!isset($config['delete_time'])) + { + set_config('delete_time', $config['edit_time']); + } + } +} diff --git a/phpBB/includes/db/migration/v306rc2.php b/phpBB/includes/db/migration/v306rc2.php new file mode 100644 index 0000000000..0a6c388da6 --- /dev/null +++ b/phpBB/includes/db/migration/v306rc2.php @@ -0,0 +1,25 @@ + array( + $this->table_prefix . 'log' => array('log_time'), + ), + 'add_index' => array( + $this->table_prefix . 'topics_track' => array( + 'topic_id' => array('topic_id'), + ), + ), + ); + } + + function update_data() + { + // ATOM Feeds + set_config('feed_overall', '1'); + set_config('feed_http_auth', '0'); + set_config('feed_limit_post', (string) (isset($config['feed_limit']) ? (int) $config['feed_limit'] : 15)); + set_config('feed_limit_topic', (string) (isset($config['feed_overall_topics_limit']) ? (int) $config['feed_overall_topics_limit'] : 10)); + set_config('feed_topics_new', (!empty($config['feed_overall_topics']) ? '1' : '0')); + set_config('feed_topics_active', (!empty($config['feed_overall_topics']) ? '1' : '0')); + + // Delete all text-templates from the template_data + $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' + WHERE template_filename ' . $db->sql_like_expression($db->any_char . '.txt'); + _sql($sql, $errored, $error_ary); + } +} diff --git a/phpBB/includes/db/migration/v307rc2.php b/phpBB/includes/db/migration/v307rc2.php new file mode 100644 index 0000000000..f9492f3d1c --- /dev/null +++ b/phpBB/includes/db/migration/v307rc2.php @@ -0,0 +1,53 @@ + ' . USER_IGNORE . " + AND user_email <> ''"; + $result = $db->sql_query($sql); + + $i = 0; + while ($row = $db->sql_fetchrow($result)) + { + // Snapshot of the phpbb_email_hash() function + // We cannot call it directly because the auto updater updates the DB first. :/ + $user_email_hash = sprintf('%u', crc32(strtolower($row['user_email']))) . strlen($row['user_email']); + + if ($user_email_hash != $row['user_email_hash']) + { + $sql_ary = array( + 'user_email_hash' => $user_email_hash, + ); + + $sql = 'UPDATE ' . USERS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE user_id = ' . (int) $row['user_id']; + _sql($sql, $errored, $error_ary, ($i % 100 == 0)); + + ++$i; + } + } + $db->sql_freeresult($result); + } +} diff --git a/phpBB/includes/db/migration/v308.php b/phpBB/includes/db/migration/v308.php new file mode 100644 index 0000000000..8a0d96b2e7 --- /dev/null +++ b/phpBB/includes/db/migration/v308.php @@ -0,0 +1,25 @@ +sql_query($sql); + + $extension_groups_updated = array(); + while ($lang_dir = $db->sql_fetchfield('lang_dir')) + { + $lang_dir = basename($lang_dir); + + // The language strings we need are either in language/.../acp/attachments.php + // in the update package if we're updating to 3.0.8-RC1 or later, + // or they are in language/.../install.php when we're updating from 3.0.7-PL1 or earlier. + // On an already updated board, they can also already be in language/.../acp/attachments.php + // in the board root. + $lang_files = array( + "{$phpbb_root_path}install/update/new/language/$lang_dir/acp/attachments.$phpEx", + "{$phpbb_root_path}language/$lang_dir/install.$phpEx", + "{$phpbb_root_path}language/$lang_dir/acp/attachments.$phpEx", + ); + + foreach ($lang_files as $lang_file) + { + if (!file_exists($lang_file)) + { + continue; + } + + $lang = array(); + include($lang_file); + + foreach($lang as $lang_key => $lang_val) + { + if (isset($extension_groups_updated[$lang_key]) || strpos($lang_key, 'EXT_GROUP_') !== 0) + { + continue; + } + + $sql_ary = array( + 'group_name' => substr($lang_key, 10), // Strip off 'EXT_GROUP_' + ); + + $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " + WHERE group_name = '" . $db->sql_escape($lang_val) . "'"; + _sql($sql, $errored, $error_ary); + + $extension_groups_updated[$lang_key] = true; + } + } + } + $db->sql_freeresult($result); + + // Install modules + $modules_to_install = array( + 'post' => array( + 'base' => 'board', + 'class' => 'acp', + 'title' => 'ACP_POST_SETTINGS', + 'auth' => 'acl_a_board', + 'cat' => 'ACP_MESSAGES', + 'after' => array('message', 'ACP_MESSAGE_SETTINGS') + ), + ); + + _add_modules($modules_to_install); + + // update + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET module_auth = \'cfg_allow_avatar && (cfg_allow_avatar_local || cfg_allow_avatar_remote || cfg_allow_avatar_upload || cfg_allow_avatar_remote_upload)\' + WHERE module_class = \'ucp\' + AND module_basename = \'profile\' + AND module_mode = \'avatar\''; + _sql($sql, $errored, $error_ary); + + // add Bing Bot + $bot_name = 'Bing [Bot]'; + $bot_name_clean = utf8_clean_string($bot_name); + + $sql = 'SELECT user_id + FROM ' . USERS_TABLE . " + WHERE username_clean = '" . $db->sql_escape($bot_name_clean) . "'"; + $result = $db->sql_query($sql); + $bing_already_added = (bool) $db->sql_fetchfield('user_id'); + $db->sql_freeresult($result); + + if (!$bing_already_added) + { + $bot_agent = 'bingbot/'; + $bot_ip = ''; + $sql = 'SELECT group_id, group_colour + FROM ' . GROUPS_TABLE . " + WHERE group_name = 'BOTS'"; + $result = $db->sql_query($sql); + $group_row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!$group_row) + { + // default fallback, should never get here + $group_row['group_id'] = 6; + $group_row['group_colour'] = '9E8DA7'; + } + + if (!function_exists('user_add')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } + + $user_row = array( + 'user_type' => USER_IGNORE, + 'group_id' => $group_row['group_id'], + 'username' => $bot_name, + 'user_regdate' => time(), + 'user_password' => '', + 'user_colour' => $group_row['group_colour'], + 'user_email' => '', + 'user_lang' => $config['default_lang'], + 'user_style' => $config['default_style'], + 'user_timezone' => 0, + 'user_dateformat' => $config['default_dateformat'], + 'user_allow_massemail' => 0, + ); + + $user_id = user_add($user_row); + + $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( + 'bot_active' => 1, + 'bot_name' => (string) $bot_name, + 'user_id' => (int) $user_id, + 'bot_agent' => (string) $bot_agent, + 'bot_ip' => (string) $bot_ip, + )); + + _sql($sql, $errored, $error_ary); + } + // end Bing Bot addition + + // Delete shadow topics pointing to not existing topics + $batch_size = 500; + + // Set of affected forums we have to resync + $sync_forum_ids = array(); + + do + { + $sql_array = array( + 'SELECT' => 't1.topic_id, t1.forum_id', + 'FROM' => array( + TOPICS_TABLE => 't1', + ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(TOPICS_TABLE => 't2'), + 'ON' => 't1.topic_moved_id = t2.topic_id', + ), + ), + 'WHERE' => 't1.topic_moved_id <> 0 + AND t2.topic_id IS NULL', + ); + $sql = $db->sql_build_query('SELECT', $sql_array); + $result = $db->sql_query_limit($sql, $batch_size); + + $topic_ids = array(); + while ($row = $db->sql_fetchrow($result)) + { + $topic_ids[] = (int) $row['topic_id']; + + $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id']; + } + $db->sql_freeresult($result); + + if (!empty($topic_ids)) + { + $sql = 'DELETE FROM ' . TOPICS_TABLE . ' + WHERE ' . $db->sql_in_set('topic_id', $topic_ids); + $db->sql_query($sql); + } + } + while (sizeof($topic_ids) == $batch_size); + + // Sync the forums we have deleted shadow topics from. + sync('forum', 'forum_id', $sync_forum_ids, true, true); + + // Unread posts search load switch + set_config('load_unreads_search', '1'); + + // Reduce queue interval to 60 seconds, email package size to 20 + if ($config['queue_interval'] == 600) + { + set_config('queue_interval', '60'); + } + + if ($config['email_package_size'] == 50) + { + set_config('email_package_size', '20'); + } + } +} diff --git a/phpBB/includes/db/migration/v309.php b/phpBB/includes/db/migration/v309.php new file mode 100644 index 0000000000..ebb246da3a --- /dev/null +++ b/phpBB/includes/db/migration/v309.php @@ -0,0 +1,25 @@ + array( + $this->table_prefix . 'login_attempts' => array( + 'COLUMNS' => array( + // this column was removed from the database updater + // after 3.0.9-RC3 was released. It might still exist + // in 3.0.9-RCX installations and has to be dropped in + // 3.0.12 after the db_tools class is capable of properly + // removing a primary key. + // 'attempt_id' => array('UINT', NULL, 'auto_increment'), + 'attempt_ip' => array('VCHAR:40', ''), + 'attempt_browser' => array('VCHAR:150', ''), + 'attempt_forwarded_for' => array('VCHAR:255', ''), + 'attempt_time' => array('TIMESTAMP', 0), + 'user_id' => array('UINT', 0), + 'username' => array('VCHAR_UNI:255', 0), + 'username_clean' => array('VCHAR_CI', 0), + ), + //'PRIMARY_KEY' => 'attempt_id', + 'KEYS' => array( + 'att_ip' => array('INDEX', array('attempt_ip', 'attempt_time')), + 'att_for' => array('INDEX', array('attempt_forwarded_for', 'attempt_time')), + 'att_time' => array('INDEX', array('attempt_time')), + 'user_id' => array('INDEX', 'user_id'), + ), + ), + ), + 'change_columns' => array( + $this->table_prefix . 'bbcode' => array( + 'bbcode_id' => array('USINT', 0), + ), + ), + ); + } + + function update_data() + { + set_config('ip_login_limit_max', '50'); + set_config('ip_login_limit_time', '21600'); + set_config('ip_login_limit_use_forwarded', '0'); + + // Update file extension group names to use language strings, again. + $sql = 'SELECT group_id, group_name + FROM ' . EXTENSION_GROUPS_TABLE . ' + WHERE group_name ' . $db->sql_like_expression('EXT_GROUP_' . $db->any_char); + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $sql_ary = array( + 'group_name' => substr($row['group_name'], 10), // Strip off 'EXT_GROUP_' + ); + + $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE group_id = ' . $row['group_id']; + _sql($sql, $errored, $error_ary); + } + $db->sql_freeresult($result); + + global $db_tools, $table_prefix; + + // Recover from potentially broken Q&A CAPTCHA table on firebird + // Q&A CAPTCHA was uninstallable, so it's safe to remove these + // without data loss + if ($db_tools->sql_layer == 'firebird') + { + $tables = array( + $table_prefix . 'captcha_questions', + $table_prefix . 'captcha_answers', + $table_prefix . 'qa_confirm', + ); + foreach ($tables as $table) + { + if ($db_tools->sql_table_exists($table)) + { + $db_tools->sql_table_drop($table); + } + } + } + } +} diff --git a/phpBB/includes/db/migration/v309rc2.php b/phpBB/includes/db/migration/v309rc2.php new file mode 100644 index 0000000000..d552b95e7a --- /dev/null +++ b/phpBB/includes/db/migration/v309rc2.php @@ -0,0 +1,25 @@ + array( - // Add the following columns - 'add_columns' => array( - FORUMS_TABLE => array( - 'display_subforum_list' => array('BOOL', 1), - ), - SESSIONS_TABLE => array( - 'session_forum_id' => array('UINT', 0), - ), - ), - 'drop_keys' => array( - GROUPS_TABLE => array('group_legend'), - ), - 'add_index' => array( - SESSIONS_TABLE => array( - 'session_forum_id' => array('session_forum_id'), - ), - GROUPS_TABLE => array( - 'group_legend_name' => array('group_legend', 'group_name'), - ), - ), - ), - // No changes from 3.0.1-RC1 to 3.0.1 - '3.0.1-RC1' => array(), - // No changes from 3.0.1 to 3.0.2-RC1 - '3.0.1' => array(), - // Changes from 3.0.2-RC1 to 3.0.2-RC2 - '3.0.2-RC1' => array( - 'change_columns' => array( - DRAFTS_TABLE => array( - 'draft_subject' => array('STEXT_UNI', ''), - ), - FORUMS_TABLE => array( - 'forum_last_post_subject' => array('STEXT_UNI', ''), - ), - POSTS_TABLE => array( - 'post_subject' => array('STEXT_UNI', '', 'true_sort'), - ), - PRIVMSGS_TABLE => array( - 'message_subject' => array('STEXT_UNI', ''), - ), - TOPICS_TABLE => array( - 'topic_title' => array('STEXT_UNI', '', 'true_sort'), - 'topic_last_post_subject' => array('STEXT_UNI', ''), - ), - ), - 'drop_keys' => array( - SESSIONS_TABLE => array('session_forum_id'), - ), - 'add_index' => array( - SESSIONS_TABLE => array( - 'session_fid' => array('session_forum_id'), - ), - ), - ), - // No changes from 3.0.2-RC2 to 3.0.2 - '3.0.2-RC2' => array(), - - // Changes from 3.0.2 to 3.0.3-RC1 - '3.0.2' => array( - // Add the following columns - 'add_columns' => array( - STYLES_TEMPLATE_TABLE => array( - 'template_inherits_id' => array('UINT:4', 0), - 'template_inherit_path' => array('VCHAR', ''), - ), - GROUPS_TABLE => array( - 'group_max_recipients' => array('UINT', 0), - ), - ), - ), - - // No changes from 3.0.3-RC1 to 3.0.3 - '3.0.3-RC1' => array(), - - // Changes from 3.0.3 to 3.0.4-RC1 - '3.0.3' => array( - 'add_columns' => array( - PROFILE_FIELDS_TABLE => array( - 'field_show_profile' => array('BOOL', 0), - ), - ), - 'change_columns' => array( - STYLES_TABLE => array( - 'style_id' => array('UINT', NULL, 'auto_increment'), - 'template_id' => array('UINT', 0), - 'theme_id' => array('UINT', 0), - 'imageset_id' => array('UINT', 0), - ), - STYLES_IMAGESET_TABLE => array( - 'imageset_id' => array('UINT', NULL, 'auto_increment'), - ), - STYLES_IMAGESET_DATA_TABLE => array( - 'image_id' => array('UINT', NULL, 'auto_increment'), - 'imageset_id' => array('UINT', 0), - ), - STYLES_THEME_TABLE => array( - 'theme_id' => array('UINT', NULL, 'auto_increment'), - ), - STYLES_TEMPLATE_TABLE => array( - 'template_id' => array('UINT', NULL, 'auto_increment'), - ), - STYLES_TEMPLATE_DATA_TABLE => array( - 'template_id' => array('UINT', 0), - ), - FORUMS_TABLE => array( - 'forum_style' => array('UINT', 0), - ), - USERS_TABLE => array( - 'user_style' => array('UINT', 0), - ), - ), - ), - - // Changes from 3.0.4-RC1 to 3.0.4 - '3.0.4-RC1' => array(), - - // Changes from 3.0.4 to 3.0.5-RC1 - '3.0.4' => array( - 'change_columns' => array( - FORUMS_TABLE => array( - 'forum_style' => array('UINT', 0), - ), - ), - ), - - // No changes from 3.0.5-RC1 to 3.0.5 - '3.0.5-RC1' => array(), - - // Changes from 3.0.5 to 3.0.6-RC1 - '3.0.5' => array( - 'add_columns' => array( - CONFIRM_TABLE => array( - 'attempts' => array('UINT', 0), - ), - USERS_TABLE => array( - 'user_new' => array('BOOL', 1), - 'user_reminded' => array('TINT:4', 0), - 'user_reminded_time'=> array('TIMESTAMP', 0), - ), - GROUPS_TABLE => array( - 'group_skip_auth' => array('BOOL', 0, 'after' => 'group_founder_manage'), - ), - PRIVMSGS_TABLE => array( - 'message_reported' => array('BOOL', 0), - ), - REPORTS_TABLE => array( - 'pm_id' => array('UINT', 0), - ), - PROFILE_FIELDS_TABLE => array( - 'field_show_on_vt' => array('BOOL', 0), - ), - FORUMS_TABLE => array( - 'forum_options' => array('UINT:20', 0), - ), - ), - 'change_columns' => array( - USERS_TABLE => array( - 'user_options' => array('UINT:11', 230271), - ), - ), - 'add_index' => array( - REPORTS_TABLE => array( - 'post_id' => array('post_id'), - 'pm_id' => array('pm_id'), - ), - POSTS_TABLE => array( - 'post_username' => array('post_username:255'), - ), - ), - ), - - // No changes from 3.0.6-RC1 to 3.0.6-RC2 - '3.0.6-RC1' => array(), - // No changes from 3.0.6-RC2 to 3.0.6-RC3 - '3.0.6-RC2' => array(), - // No changes from 3.0.6-RC3 to 3.0.6-RC4 - '3.0.6-RC3' => array(), - // No changes from 3.0.6-RC4 to 3.0.6 - '3.0.6-RC4' => array(), - - // Changes from 3.0.6 to 3.0.7-RC1 - '3.0.6' => array( - 'drop_keys' => array( - LOG_TABLE => array('log_time'), - ), - 'add_index' => array( - TOPICS_TRACK_TABLE => array( - 'topic_id' => array('topic_id'), - ), - ), - ), - - // No changes from 3.0.7-RC1 to 3.0.7-RC2 - '3.0.7-RC1' => array(), - // No changes from 3.0.7-RC2 to 3.0.7 - '3.0.7-RC2' => array(), - // No changes from 3.0.7 to 3.0.7-PL1 - '3.0.7' => array(), - // No changes from 3.0.7-PL1 to 3.0.8-RC1 - '3.0.7-PL1' => array(), - // No changes from 3.0.8-RC1 to 3.0.8 - '3.0.8-RC1' => array(), - // Changes from 3.0.8 to 3.0.9-RC1 - '3.0.8' => array( - 'add_tables' => array( - LOGIN_ATTEMPT_TABLE => array( - 'COLUMNS' => array( - // this column was removed from the database updater - // after 3.0.9-RC3 was released. It might still exist - // in 3.0.9-RCX installations and has to be dropped in - // 3.0.12 after the db_tools class is capable of properly - // removing a primary key. - // 'attempt_id' => array('UINT', NULL, 'auto_increment'), - 'attempt_ip' => array('VCHAR:40', ''), - 'attempt_browser' => array('VCHAR:150', ''), - 'attempt_forwarded_for' => array('VCHAR:255', ''), - 'attempt_time' => array('TIMESTAMP', 0), - 'user_id' => array('UINT', 0), - 'username' => array('VCHAR_UNI:255', 0), - 'username_clean' => array('VCHAR_CI', 0), - ), - //'PRIMARY_KEY' => 'attempt_id', - 'KEYS' => array( - 'att_ip' => array('INDEX', array('attempt_ip', 'attempt_time')), - 'att_for' => array('INDEX', array('attempt_forwarded_for', 'attempt_time')), - 'att_time' => array('INDEX', array('attempt_time')), - 'user_id' => array('INDEX', 'user_id'), - ), - ), - ), - 'change_columns' => array( - BBCODES_TABLE => array( - 'bbcode_id' => array('USINT', 0), - ), - ), - ), - // No changes from 3.0.9-RC1 to 3.0.9-RC2 - '3.0.9-RC1' => array(), - // No changes from 3.0.9-RC2 to 3.0.9-RC3 - '3.0.9-RC2' => array(), - // No changes from 3.0.9-RC3 to 3.0.9-RC4 - '3.0.9-RC3' => array(), - // No changes from 3.0.9-RC4 to 3.0.9 - '3.0.9-RC4' => array(), - // No changes from 3.0.9 to 3.0.10-RC1 - '3.0.9' => array(), - // No changes from 3.0.10-RC1 to 3.0.10-RC2 - '3.0.10-RC1' => array(), - // No changes from 3.0.10-RC2 to 3.0.10-RC3 - '3.0.10-RC2' => array(), - // No changes from 3.0.10-RC3 to 3.0.10 - '3.0.10-RC3' => array(), - // No changes from 3.0.10 to 3.0.11-RC1 - '3.0.10' => array(), - // Changes from 3.0.11-RC1 to 3.0.11-RC2 - '3.0.11-RC1' => array( - 'add_columns' => array( - PROFILE_FIELDS_TABLE => array( - 'field_show_novalue' => array('BOOL', 0), - ), - ), - ), - // No changes from 3.0.11-RC2 to 3.0.11 - '3.0.11-RC2' => array(), - // No changes from 3.0.11 to 3.0.12-RC1 - '3.0.11' => array(), - - /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.12-RC1 */ - // Changes from 3.1.0-dev to 3.1.0-A1 '3.1.0-dev' => array( 'add_tables' => array( @@ -1210,1192 +939,6 @@ function change_database_data(&$no_updates, $version) switch ($version) { - case '3.0.0': - - $sql = 'UPDATE ' . TOPICS_TABLE . " - SET topic_last_view_time = topic_last_post_time - WHERE topic_last_view_time = 0"; - _sql($sql, $errored, $error_ary); - - // Update smiley sizes - $smileys = array('icon_e_surprised.gif', 'icon_eek.gif', 'icon_cool.gif', 'icon_lol.gif', 'icon_mad.gif', 'icon_razz.gif', 'icon_redface.gif', 'icon_cry.gif', 'icon_evil.gif', 'icon_twisted.gif', 'icon_rolleyes.gif', 'icon_exclaim.gif', 'icon_question.gif', 'icon_idea.gif', 'icon_arrow.gif', 'icon_neutral.gif', 'icon_mrgreen.gif', 'icon_e_ugeek.gif'); - - foreach ($smileys as $smiley) - { - if (file_exists($phpbb_root_path . 'images/smilies/' . $smiley)) - { - list($width, $height) = getimagesize($phpbb_root_path . 'images/smilies/' . $smiley); - - $sql = 'UPDATE ' . SMILIES_TABLE . ' - SET smiley_width = ' . $width . ', smiley_height = ' . $height . " - WHERE smiley_url = '" . $db->sql_escape($smiley) . "'"; - - _sql($sql, $errored, $error_ary); - } - } - - $no_updates = false; - break; - - // No changes from 3.0.1-RC1 to 3.0.1 - case '3.0.1-RC1': - break; - - // changes from 3.0.1 to 3.0.2-RC1 - case '3.0.1': - - set_config('referer_validation', '1'); - set_config('check_attachment_content', '1'); - set_config('mime_triggers', 'body|head|html|img|plaintext|a href|pre|script|table|title'); - - $no_updates = false; - break; - - // No changes from 3.0.2-RC1 to 3.0.2-RC2 - case '3.0.2-RC1': - break; - - // No changes from 3.0.2-RC2 to 3.0.2 - case '3.0.2-RC2': - break; - - // Changes from 3.0.2 to 3.0.3-RC1 - case '3.0.2': - set_config('enable_queue_trigger', '0'); - set_config('queue_trigger_posts', '3'); - - set_config('pm_max_recipients', '0'); - - // Set maximum number of recipients for the registered users, bots, guests group - $sql = 'UPDATE ' . GROUPS_TABLE . ' SET group_max_recipients = 5 - WHERE ' . $db->sql_in_set('group_name', array('GUESTS', 'REGISTERED', 'REGISTERED_COPPA', 'BOTS')); - _sql($sql, $errored, $error_ary); - - // Not prefilling yet - set_config('dbms_version', ''); - - // Add new permission u_masspm_group and duplicate settings from u_masspm - include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); - $auth_admin = new auth_admin(); - - // Only add the new permission if it does not already exist - if (empty($auth_admin->acl_options['id']['u_masspm_group'])) - { - $auth_admin->acl_add_option(array('global' => array('u_masspm_group'))); - - // Now the tricky part, filling the permission - $old_id = $auth_admin->acl_options['id']['u_masspm']; - $new_id = $auth_admin->acl_options['id']['u_masspm_group']; - - $tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE); - - foreach ($tables as $table) - { - $sql = 'SELECT * - FROM ' . $table . ' - WHERE auth_option_id = ' . $old_id; - $result = _sql($sql, $errored, $error_ary); - - $sql_ary = array(); - while ($row = $db->sql_fetchrow($result)) - { - $row['auth_option_id'] = $new_id; - $sql_ary[] = $row; - } - $db->sql_freeresult($result); - - if (sizeof($sql_ary)) - { - $db->sql_multi_insert($table, $sql_ary); - } - } - - // Remove any old permission entries - $auth_admin->acl_clear_prefetch(); - } - - /** - * Do not resync post counts here. An admin may do this later from the ACP - $start = 0; - $step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000; - - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = 0'; - _sql($sql, $errored, $error_ary); - - do - { - $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id - FROM ' . POSTS_TABLE . ' - WHERE post_id BETWEEN ' . ($start + 1) . ' AND ' . ($start + $step) . ' - AND post_postcount = 1 AND post_approved = 1 - GROUP BY poster_id'; - $result = _sql($sql, $errored, $error_ary); - - if ($row = $db->sql_fetchrow($result)) - { - do - { - $sql = 'UPDATE ' . USERS_TABLE . " SET user_posts = user_posts + {$row['num_posts']} WHERE user_id = {$row['poster_id']}"; - _sql($sql, $errored, $error_ary); - } - while ($row = $db->sql_fetchrow($result)); - - $start += $step; - } - else - { - $start = 0; - } - $db->sql_freeresult($result); - } - while ($start); - */ - - $sql = 'UPDATE ' . MODULES_TABLE . ' - SET module_auth = \'acl_a_email && cfg_email_enable\' - WHERE module_class = \'acp\' - AND module_basename = \'email\''; - _sql($sql, $errored, $error_ary); - - $no_updates = false; - break; - - // Changes from 3.0.3-RC1 to 3.0.3 - case '3.0.3-RC1': - if ($db->sql_layer == 'oracle') - { - // log_operation is CLOB - but we can change this later - $sql = 'UPDATE ' . LOG_TABLE . " - SET log_operation = 'LOG_DELETE_TOPIC' - WHERE log_operation LIKE 'LOG_TOPIC_DELETED'"; - _sql($sql, $errored, $error_ary); - } - else - { - $sql = 'UPDATE ' . LOG_TABLE . " - SET log_operation = 'LOG_DELETE_TOPIC' - WHERE log_operation = 'LOG_TOPIC_DELETED'"; - _sql($sql, $errored, $error_ary); - } - - $no_updates = false; - break; - - // Changes from 3.0.3 to 3.0.4-RC1 - case '3.0.3': - // Update the Custom Profile Fields based on previous settings to the new format - $sql = 'SELECT field_id, field_required, field_show_on_reg, field_hide - FROM ' . PROFILE_FIELDS_TABLE; - $result = _sql($sql, $errored, $error_ary); - - while ($row = $db->sql_fetchrow($result)) - { - $sql_ary = array( - 'field_required' => 0, - 'field_show_on_reg' => 0, - 'field_hide' => 0, - 'field_show_profile'=> 0, - ); - - if ($row['field_required']) - { - $sql_ary['field_required'] = $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; - } - else if ($row['field_show_on_reg']) - { - $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; - } - else if ($row['field_hide']) - { - // Only administrators and moderators can see this CPF, if the view is enabled, they can see it, otherwise just admins in the acp_users module - $sql_ary['field_hide'] = 1; - } - else - { - // equivelant to "none", which is the "Display in user control panel" option - $sql_ary['field_show_profile'] = 1; - } - - _sql('UPDATE ' . PROFILE_FIELDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary); - } - $no_updates = false; - - break; - - // Changes from 3.0.4-RC1 to 3.0.4 - case '3.0.4-RC1': - break; - - // Changes from 3.0.4 to 3.0.5-RC1 - case '3.0.4': - - // Captcha config variables - set_config('captcha_gd_wave', 0); - set_config('captcha_gd_3d_noise', 1); - set_config('captcha_gd_fonts', 1); - set_config('confirm_refresh', 1); - - // Maximum number of keywords - set_config('max_num_search_keywords', 10); - - // Remove static config var and put it back as dynamic variable - $sql = 'UPDATE ' . CONFIG_TABLE . " - SET is_dynamic = 1 - WHERE config_name = 'search_indexing_state'"; - _sql($sql, $errored, $error_ary); - - // Hash old MD5 passwords - $sql = 'SELECT user_id, user_password - FROM ' . USERS_TABLE . ' - WHERE user_pass_convert = 1'; - $result = _sql($sql, $errored, $error_ary); - - while ($row = $db->sql_fetchrow($result)) - { - if (strlen($row['user_password']) == 32) - { - $sql_ary = array( - 'user_password' => phpbb_hash($row['user_password']), - ); - - _sql('UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id'], $errored, $error_ary); - } - } - $db->sql_freeresult($result); - - // Adjust bot entry - $sql = 'UPDATE ' . BOTS_TABLE . " - SET bot_agent = 'ichiro/' - WHERE bot_agent = 'ichiro/2'"; - _sql($sql, $errored, $error_ary); - - - // Before we are able to add a unique key to auth_option, we need to remove duplicate entries - - // We get duplicate entries first - $sql = 'SELECT auth_option - FROM ' . ACL_OPTIONS_TABLE . ' - GROUP BY auth_option - HAVING COUNT(*) >= 2'; - $result = $db->sql_query($sql); - - $auth_options = array(); - while ($row = $db->sql_fetchrow($result)) - { - $auth_options[] = $row['auth_option']; - } - $db->sql_freeresult($result); - - // Remove specific auth options - if (!empty($auth_options)) - { - foreach ($auth_options as $option) - { - // Select auth_option_ids... the largest id will be preserved - $sql = 'SELECT auth_option_id - FROM ' . ACL_OPTIONS_TABLE . " - WHERE auth_option = '" . $db->sql_escape($option) . "' - ORDER BY auth_option_id DESC"; - // sql_query_limit not possible here, due to bug in postgresql layer - $result = $db->sql_query($sql); - - // Skip first row, this is our original auth option we want to preserve - $row = $db->sql_fetchrow($result); - - while ($row = $db->sql_fetchrow($result)) - { - // Ok, remove this auth option... - _sql('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - _sql('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - _sql('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - _sql('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - } - $db->sql_freeresult($result); - } - } - - // Now make auth_option UNIQUE, by dropping the old index and adding a UNIQUE one. - $changes = array( - 'drop_keys' => array( - ACL_OPTIONS_TABLE => array('auth_option'), - ), - ); - - $statements = $db_tools->perform_schema_changes($changes); - - foreach ($statements as $sql) - { - _sql($sql, $errored, $error_ary); - } - - $changes = array( - 'add_unique_index' => array( - ACL_OPTIONS_TABLE => array( - 'auth_option' => array('auth_option'), - ), - ), - ); - - $statements = $db_tools->perform_schema_changes($changes); - - foreach ($statements as $sql) - { - _sql($sql, $errored, $error_ary); - } - - $no_updates = false; - - break; - - // No changes from 3.0.5-RC1 to 3.0.5 - case '3.0.5-RC1': - break; - - // Changes from 3.0.5 to 3.0.6-RC1 - case '3.0.5': - // Let's see if the GD Captcha can be enabled... we simply look for what *is* enabled... - if (!empty($config['captcha_gd']) && !isset($config['captcha_plugin'])) - { - set_config('captcha_plugin', 'phpbb_captcha_gd'); - } - else if (!isset($config['captcha_plugin'])) - { - set_config('captcha_plugin', 'phpbb_captcha_nogd'); - } - - // Entries for the Feed Feature - set_config('feed_enable', '0'); - set_config('feed_limit', '10'); - - set_config('feed_overall_forums', '1'); - set_config('feed_overall_forums_limit', '15'); - - set_config('feed_overall_topics', '0'); - set_config('feed_overall_topics_limit', '15'); - - set_config('feed_forum', '1'); - set_config('feed_topic', '1'); - set_config('feed_item_statistics', '1'); - - // Entries for smiley pagination - set_config('smilies_per_page', '50'); - - // Entry for reporting PMs - set_config('allow_pm_report', '1'); - - // Install modules - $modules_to_install = array( - 'feed' => array( - 'base' => 'board', - 'class' => 'acp', - 'title' => 'ACP_FEED_SETTINGS', - 'auth' => 'acl_a_board', - 'cat' => 'ACP_BOARD_CONFIGURATION', - 'after' => array('signature', 'ACP_SIGNATURE_SETTINGS') - ), - 'warnings' => array( - 'base' => 'users', - 'class' => 'acp', - 'title' => 'ACP_USER_WARNINGS', - 'auth' => 'acl_a_user', - 'display' => 0, - 'cat' => 'ACP_CAT_USERS', - 'after' => array('feedback', 'ACP_USER_FEEDBACK') - ), - 'send_statistics' => array( - 'base' => 'send_statistics', - 'class' => 'acp', - 'title' => 'ACP_SEND_STATISTICS', - 'auth' => 'acl_a_server', - 'cat' => 'ACP_SERVER_CONFIGURATION' - ), - 'setting_forum_copy' => array( - 'base' => 'permissions', - 'class' => 'acp', - 'title' => 'ACP_FORUM_PERMISSIONS_COPY', - 'auth' => 'acl_a_fauth && acl_a_authusers && acl_a_authgroups && acl_a_mauth', - 'cat' => 'ACP_FORUM_BASED_PERMISSIONS', - 'after' => array('setting_forum_local', 'ACP_FORUM_PERMISSIONS') - ), - 'pm_reports' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORTS_OPEN', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' - ), - 'pm_reports_closed' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORTS_CLOSED', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' - ), - 'pm_report_details' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORT_DETAILS', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' - ), - ); - - _add_modules($modules_to_install); - - // Add newly_registered group... but check if it already exists (we always supported running the updater on any schema) - $sql = 'SELECT group_id - FROM ' . GROUPS_TABLE . " - WHERE group_name = 'NEWLY_REGISTERED'"; - $result = $db->sql_query($sql); - $group_id = (int) $db->sql_fetchfield('group_id'); - $db->sql_freeresult($result); - - if (!$group_id) - { - $sql = 'INSERT INTO ' . GROUPS_TABLE . " (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('NEWLY_REGISTERED', 3, 0, '', 0, '', '', '', 5)"; - _sql($sql, $errored, $error_ary); - - $group_id = $db->sql_nextid(); - } - - // Insert new user role... at the end of the chain - $sql = 'SELECT role_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_name = 'ROLE_USER_NEW_MEMBER' - AND role_type = 'u_'"; - $result = $db->sql_query($sql); - $u_role = (int) $db->sql_fetchfield('role_id'); - $db->sql_freeresult($result); - - if (!$u_role) - { - $sql = 'SELECT MAX(role_order) as max_order_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_type = 'u_'"; - $result = $db->sql_query($sql); - $next_order_id = (int) $db->sql_fetchfield('max_order_id'); - $db->sql_freeresult($result); - - $next_order_id++; - - $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_NEW_MEMBER', 'ROLE_DESCRIPTION_USER_NEW_MEMBER', 'u_', $next_order_id)"; - _sql($sql, $errored, $error_ary); - $u_role = $db->sql_nextid(); - - if (!$errored) - { - // Now add the correct data to the roles... - // The standard role says that new users are not able to send a PM, Mass PM, are not able to PM groups - $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $u_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_sendpm', 'u_masspm', 'u_masspm_group')"; - _sql($sql, $errored, $error_ary); - - // Add user role to group - $sql = 'INSERT INTO ' . ACL_GROUPS_TABLE . " (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES ($group_id, 0, 0, $u_role, 0)"; - _sql($sql, $errored, $error_ary); - } - } - - // Insert new forum role - $sql = 'SELECT role_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_name = 'ROLE_FORUM_NEW_MEMBER' - AND role_type = 'f_'"; - $result = $db->sql_query($sql); - $f_role = (int) $db->sql_fetchfield('role_id'); - $db->sql_freeresult($result); - - if (!$f_role) - { - $sql = 'SELECT MAX(role_order) as max_order_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_type = 'f_'"; - $result = $db->sql_query($sql); - $next_order_id = (int) $db->sql_fetchfield('max_order_id'); - $db->sql_freeresult($result); - - $next_order_id++; - - $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_NEW_MEMBER', 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER', 'f_', $next_order_id)"; - _sql($sql, $errored, $error_ary); - $f_role = $db->sql_nextid(); - - if (!$errored) - { - $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $f_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove')"; - _sql($sql, $errored, $error_ary); - } - } - - // Set every members user_new column to 0 (old users) only if there is no one yet (this makes sure we do not execute this more than once) - $sql = 'SELECT 1 - FROM ' . USERS_TABLE . ' - WHERE user_new = 0'; - $result = $db->sql_query_limit($sql, 1); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - if (!$row) - { - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new = 0'; - _sql($sql, $errored, $error_ary); - } - - // Newly registered users limit - if (!isset($config['new_member_post_limit'])) - { - set_config('new_member_post_limit', (!empty($config['enable_queue_trigger'])) ? $config['queue_trigger_posts'] : 0); - } - - if (!isset($config['new_member_group_default'])) - { - set_config('new_member_group_default', 0); - } - - // To mimick the old "feature" we will assign the forum role to every forum, regardless of the setting (this makes sure there are no "this does not work!!!! YUO!!!" posts... - // Check if the role is already assigned... - $sql = 'SELECT forum_id - FROM ' . ACL_GROUPS_TABLE . ' - WHERE group_id = ' . $group_id . ' - AND auth_role_id = ' . $f_role; - $result = $db->sql_query($sql); - $is_options = (int) $db->sql_fetchfield('forum_id'); - $db->sql_freeresult($result); - - // Not assigned at all... :/ - if (!$is_options) - { - // Get postable forums - $sql = 'SELECT forum_id - FROM ' . FORUMS_TABLE . ' - WHERE forum_type != ' . FORUM_LINK; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - _sql('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (' . $group_id . ', ' . (int) $row['forum_id'] . ', 0, ' . $f_role . ', 0)', $errored, $error_ary); - } - $db->sql_freeresult($result); - } - - // Clear permissions... - include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); - $auth_admin = new auth_admin(); - $auth_admin->acl_clear_prefetch(); - - if (!isset($config['allow_avatar'])) - { - if ($config['allow_avatar_upload'] || $config['allow_avatar_local'] || $config['allow_avatar_remote']) - { - set_config('allow_avatar', '1'); - } - else - { - set_config('allow_avatar', '0'); - } - } - - if (!isset($config['allow_avatar_remote_upload'])) - { - if ($config['allow_avatar_remote'] && $config['allow_avatar_upload']) - { - set_config('allow_avatar_remote_upload', '1'); - } - else - { - set_config('allow_avatar_remote_upload', '0'); - } - } - - // Minimum number of characters - if (!isset($config['min_post_chars'])) - { - set_config('min_post_chars', '1'); - } - - if (!isset($config['allow_quick_reply'])) - { - set_config('allow_quick_reply', '1'); - } - - // Set every members user_options column to enable - // bbcode, smilies and URLs for signatures by default - $sql = 'SELECT user_options - FROM ' . USERS_TABLE . ' - WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; - $result = $db->sql_query_limit($sql, 1); - $user_option = (int) $db->sql_fetchfield('user_options'); - $db->sql_freeresult($result); - - // Check if we already updated the database by checking bit 15 which we used to store the sig_bbcode option - if (!($user_option & 1 << 15)) - { - // 229376 is the added value to enable all three signature options - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_options = user_options + 229376'; - _sql($sql, $errored, $error_ary); - } - - if (!isset($config['delete_time'])) - { - set_config('delete_time', $config['edit_time']); - } - - $no_updates = false; - break; - - // No changes from 3.0.6-RC1 to 3.0.6-RC2 - case '3.0.6-RC1': - break; - - // Changes from 3.0.6-RC2 to 3.0.6-RC3 - case '3.0.6-RC2': - - // Update the Custom Profile Fields based on previous settings to the new format - $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . ' - SET field_show_on_vt = 1 - WHERE field_hide = 0 - AND (field_required = 1 OR field_show_on_reg = 1 OR field_show_profile = 1)'; - _sql($sql, $errored, $error_ary); - $no_updates = false; - - break; - - // No changes from 3.0.6-RC3 to 3.0.6-RC4 - case '3.0.6-RC3': - break; - - // No changes from 3.0.6-RC4 to 3.0.6 - case '3.0.6-RC4': - break; - - // Changes from 3.0.6 to 3.0.7-RC1 - case '3.0.6': - - // ATOM Feeds - set_config('feed_overall', '1'); - set_config('feed_http_auth', '0'); - set_config('feed_limit_post', (string) (isset($config['feed_limit']) ? (int) $config['feed_limit'] : 15)); - set_config('feed_limit_topic', (string) (isset($config['feed_overall_topics_limit']) ? (int) $config['feed_overall_topics_limit'] : 10)); - set_config('feed_topics_new', (!empty($config['feed_overall_topics']) ? '1' : '0')); - set_config('feed_topics_active', (!empty($config['feed_overall_topics']) ? '1' : '0')); - - // Delete all text-templates from the template_data - $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' - WHERE template_filename ' . $db->sql_like_expression($db->any_char . '.txt'); - _sql($sql, $errored, $error_ary); - - $no_updates = false; - break; - - // Changes from 3.0.7-RC1 to 3.0.7-RC2 - case '3.0.7-RC1': - - $sql = 'SELECT user_id, user_email, user_email_hash - FROM ' . USERS_TABLE . ' - WHERE user_type <> ' . USER_IGNORE . " - AND user_email <> ''"; - $result = $db->sql_query($sql); - - $i = 0; - while ($row = $db->sql_fetchrow($result)) - { - // Snapshot of the phpbb_email_hash() function - // We cannot call it directly because the auto updater updates the DB first. :/ - $user_email_hash = sprintf('%u', crc32(strtolower($row['user_email']))) . strlen($row['user_email']); - - if ($user_email_hash != $row['user_email_hash']) - { - $sql_ary = array( - 'user_email_hash' => $user_email_hash, - ); - - $sql = 'UPDATE ' . USERS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE user_id = ' . (int) $row['user_id']; - _sql($sql, $errored, $error_ary, ($i % 100 == 0)); - - ++$i; - } - } - $db->sql_freeresult($result); - - $no_updates = false; - - break; - - // No changes from 3.0.7-RC2 to 3.0.7 - case '3.0.7-RC2': - break; - - // No changes from 3.0.7 to 3.0.7-PL1 - case '3.0.7': - break; - - // Changes from 3.0.7-PL1 to 3.0.8-RC1 - case '3.0.7-PL1': - // Update file extension group names to use language strings. - $sql = 'SELECT lang_dir - FROM ' . LANG_TABLE; - $result = $db->sql_query($sql); - - $extension_groups_updated = array(); - while ($lang_dir = $db->sql_fetchfield('lang_dir')) - { - $lang_dir = basename($lang_dir); - - // The language strings we need are either in language/.../acp/attachments.php - // in the update package if we're updating to 3.0.8-RC1 or later, - // or they are in language/.../install.php when we're updating from 3.0.7-PL1 or earlier. - // On an already updated board, they can also already be in language/.../acp/attachments.php - // in the board root. - $lang_files = array( - "{$phpbb_root_path}install/update/new/language/$lang_dir/acp/attachments.$phpEx", - "{$phpbb_root_path}language/$lang_dir/install.$phpEx", - "{$phpbb_root_path}language/$lang_dir/acp/attachments.$phpEx", - ); - - foreach ($lang_files as $lang_file) - { - if (!file_exists($lang_file)) - { - continue; - } - - $lang = array(); - include($lang_file); - - foreach($lang as $lang_key => $lang_val) - { - if (isset($extension_groups_updated[$lang_key]) || strpos($lang_key, 'EXT_GROUP_') !== 0) - { - continue; - } - - $sql_ary = array( - 'group_name' => substr($lang_key, 10), // Strip off 'EXT_GROUP_' - ); - - $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " - WHERE group_name = '" . $db->sql_escape($lang_val) . "'"; - _sql($sql, $errored, $error_ary); - - $extension_groups_updated[$lang_key] = true; - } - } - } - $db->sql_freeresult($result); - - // Install modules - $modules_to_install = array( - 'post' => array( - 'base' => 'board', - 'class' => 'acp', - 'title' => 'ACP_POST_SETTINGS', - 'auth' => 'acl_a_board', - 'cat' => 'ACP_MESSAGES', - 'after' => array('message', 'ACP_MESSAGE_SETTINGS') - ), - ); - - _add_modules($modules_to_install); - - // update - $sql = 'UPDATE ' . MODULES_TABLE . ' - SET module_auth = \'cfg_allow_avatar && (cfg_allow_avatar_local || cfg_allow_avatar_remote || cfg_allow_avatar_upload || cfg_allow_avatar_remote_upload)\' - WHERE module_class = \'ucp\' - AND module_basename = \'profile\' - AND module_mode = \'avatar\''; - _sql($sql, $errored, $error_ary); - - // add Bing Bot - $bot_name = 'Bing [Bot]'; - $bot_name_clean = utf8_clean_string($bot_name); - - $sql = 'SELECT user_id - FROM ' . USERS_TABLE . " - WHERE username_clean = '" . $db->sql_escape($bot_name_clean) . "'"; - $result = $db->sql_query($sql); - $bing_already_added = (bool) $db->sql_fetchfield('user_id'); - $db->sql_freeresult($result); - - if (!$bing_already_added) - { - $bot_agent = 'bingbot/'; - $bot_ip = ''; - $sql = 'SELECT group_id, group_colour - FROM ' . GROUPS_TABLE . " - WHERE group_name = 'BOTS'"; - $result = $db->sql_query($sql); - $group_row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - if (!$group_row) - { - // default fallback, should never get here - $group_row['group_id'] = 6; - $group_row['group_colour'] = '9E8DA7'; - } - - if (!function_exists('user_add')) - { - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); - } - - $user_row = array( - 'user_type' => USER_IGNORE, - 'group_id' => $group_row['group_id'], - 'username' => $bot_name, - 'user_regdate' => time(), - 'user_password' => '', - 'user_colour' => $group_row['group_colour'], - 'user_email' => '', - 'user_lang' => $config['default_lang'], - 'user_style' => $config['default_style'], - 'user_timezone' => 'UTC', - 'user_dateformat' => $config['default_dateformat'], - 'user_allow_massemail' => 0, - ); - - $user_id = user_add($user_row); - - $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( - 'bot_active' => 1, - 'bot_name' => (string) $bot_name, - 'user_id' => (int) $user_id, - 'bot_agent' => (string) $bot_agent, - 'bot_ip' => (string) $bot_ip, - )); - - _sql($sql, $errored, $error_ary); - } - // end Bing Bot addition - - // Delete shadow topics pointing to not existing topics - $batch_size = 500; - - // Set of affected forums we have to resync - $sync_forum_ids = array(); - - do - { - $sql_array = array( - 'SELECT' => 't1.topic_id, t1.forum_id', - 'FROM' => array( - TOPICS_TABLE => 't1', - ), - 'LEFT_JOIN' => array( - array( - 'FROM' => array(TOPICS_TABLE => 't2'), - 'ON' => 't1.topic_moved_id = t2.topic_id', - ), - ), - 'WHERE' => 't1.topic_moved_id <> 0 - AND t2.topic_id IS NULL', - ); - $sql = $db->sql_build_query('SELECT', $sql_array); - $result = $db->sql_query_limit($sql, $batch_size); - - $topic_ids = array(); - while ($row = $db->sql_fetchrow($result)) - { - $topic_ids[] = (int) $row['topic_id']; - - $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id']; - } - $db->sql_freeresult($result); - - if (!empty($topic_ids)) - { - $sql = 'DELETE FROM ' . TOPICS_TABLE . ' - WHERE ' . $db->sql_in_set('topic_id', $topic_ids); - $db->sql_query($sql); - } - } - while (sizeof($topic_ids) == $batch_size); - - // Sync the forums we have deleted shadow topics from. - sync('forum', 'forum_id', $sync_forum_ids, true, true); - - // Unread posts search load switch - set_config('load_unreads_search', '1'); - - // Reduce queue interval to 60 seconds, email package size to 20 - if ($config['queue_interval'] == 600) - { - set_config('queue_interval', '60'); - } - - if ($config['email_package_size'] == 50) - { - set_config('email_package_size', '20'); - } - - $no_updates = false; - break; - - // No changes from 3.0.8-RC1 to 3.0.8 - case '3.0.8-RC1': - break; - - // Changes from 3.0.8 to 3.0.9-RC1 - case '3.0.8': - set_config('ip_login_limit_max', '50'); - set_config('ip_login_limit_time', '21600'); - set_config('ip_login_limit_use_forwarded', '0'); - - // Update file extension group names to use language strings, again. - $sql = 'SELECT group_id, group_name - FROM ' . EXTENSION_GROUPS_TABLE . ' - WHERE group_name ' . $db->sql_like_expression('EXT_GROUP_' . $db->any_char); - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $sql_ary = array( - 'group_name' => substr($row['group_name'], 10), // Strip off 'EXT_GROUP_' - ); - - $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE group_id = ' . $row['group_id']; - _sql($sql, $errored, $error_ary); - } - $db->sql_freeresult($result); - - /* - * Due to a bug, vanilla phpbb could not create captcha tables - * in 3.0.8 on firebird. It was possible for board administrators - * to adjust the code to work. If code was manually adjusted by - * board administrators, index names would not be the same as - * what 3.0.9 and newer expect. This code fragment drops captcha - * tables, destroying all entered Q&A captcha configuration, such - * that when Q&A is configured next the respective tables will be - * created with correct index names. - * - * If you wish to preserve your Q&A captcha configuration, you can - * manually rename indexes to the currently expected name: - * phpbb_captcha_questions_lang_iso => phpbb_captcha_questions_lang - * phpbb_captcha_answers_question_id => phpbb_captcha_answers_qid - * - * Again, this needs to be done only if a board was manually modified - * to fix broken captcha code. - * - if ($db_tools->sql_layer == 'firebird') - { - $changes = array( - 'drop_tables' => array( - $table_prefix . 'captcha_questions', - $table_prefix . 'captcha_answers', - $table_prefix . 'qa_confirm', - ), - ); - $statements = $db_tools->perform_schema_changes($changes); - - foreach ($statements as $sql) - { - _sql($sql, $errored, $error_ary); - } - } - */ - - $no_updates = false; - break; - - // No changes from 3.0.9-RC1 to 3.0.9-RC2 - case '3.0.9-RC1': - break; - - // No changes from 3.0.9-RC2 to 3.0.9-RC3 - case '3.0.9-RC2': - break; - - // No changes from 3.0.9-RC3 to 3.0.9-RC4 - case '3.0.9-RC3': - break; - - // No changes from 3.0.9-RC4 to 3.0.9 - case '3.0.9-RC4': - break; - - // Changes from 3.0.9 to 3.0.10-RC1 - case '3.0.9': - if (!isset($config['email_max_chunk_size'])) - { - set_config('email_max_chunk_size', '50'); - } - - $no_updates = false; - break; - - // No changes from 3.0.10-RC1 to 3.0.10-RC2 - case '3.0.10-RC1': - break; - - // No changes from 3.0.10-RC2 to 3.0.10-RC3 - case '3.0.10-RC2': - break; - - // No changes from 3.0.10-RC3 to 3.0.10 - case '3.0.10-RC3': - break; - - // Changes from 3.0.10 to 3.0.11-RC1 - case '3.0.10': - // Updates users having current style a deactivated one - $sql = 'SELECT style_id - FROM ' . STYLES_TABLE . ' - WHERE style_active = 0'; - $result = $db->sql_query($sql); - - $deactivated_style_ids = array(); - while ($style_id = $db->sql_fetchfield('style_id', false, $result)) - { - $deactivated_style_ids[] = (int) $style_id; - } - $db->sql_freeresult($result); - - if (!empty($deactivated_style_ids)) - { - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_style = ' . (int) $config['default_style'] .' - WHERE ' . $db->sql_in_set('user_style', $deactivated_style_ids); - _sql($sql, $errored, $error_ary); - } - - // Delete orphan private messages - $batch_size = 500; - - $sql_array = array( - 'SELECT' => 'p.msg_id', - 'FROM' => array( - PRIVMSGS_TABLE => 'p', - ), - 'LEFT_JOIN' => array( - array( - 'FROM' => array(PRIVMSGS_TO_TABLE => 't'), - 'ON' => 'p.msg_id = t.msg_id', - ), - ), - 'WHERE' => 't.user_id IS NULL', - ); - $sql = $db->sql_build_query('SELECT', $sql_array); - - do - { - $result = $db->sql_query_limit($sql, $batch_size); - - $delete_pms = array(); - while ($row = $db->sql_fetchrow($result)) - { - $delete_pms[] = (int) $row['msg_id']; - } - $db->sql_freeresult($result); - - if (!empty($delete_pms)) - { - $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' - WHERE ' . $db->sql_in_set('msg_id', $delete_pms); - _sql($sql, $errored, $error_ary); - } - } - while (sizeof($delete_pms) == $batch_size); - - $no_updates = false; - break; - - // No changes from 3.0.11-RC1 to 3.0.11-RC2 - case '3.0.11-RC1': - break; - - // No changes from 3.0.11-RC2 to 3.0.11 - case '3.0.11-RC2': - break; - - // Changes from 3.0.11 to 3.0.12-RC1 - case '3.0.11': - $sql = 'UPDATE ' . MODULES_TABLE . ' - SET module_auth = \'acl_u_sig\' - WHERE module_class = \'ucp\' - AND module_basename = \'profile\' - AND module_mode = \'signature\''; - _sql($sql, $errored, $error_ary); - - // Update bots - if (!function_exists('user_delete')) - { - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); - } - - $bots_updates = array( - // Bot Deletions - 'NG-Search [Bot]' => false, - 'Nutch/CVS [Bot]' => false, - 'OmniExplorer [Bot]' => false, - 'Seekport [Bot]' => false, - 'Synoo [Bot]' => false, - 'WiseNut [Bot]' => false, - - // Bot Updates - // Bot name to bot user agent map - 'Baidu [Spider]' => 'Baiduspider', - 'Exabot [Bot]' => 'Exabot', - 'Voyager [Bot]' => 'voyager/', - 'W3C [Validator]' => 'W3C_Validator', - ); - - foreach ($bots_updates as $bot_name => $bot_agent) - { - $sql = 'SELECT user_id - FROM ' . USERS_TABLE . ' - WHERE user_type = ' . USER_IGNORE . " - AND username_clean = '" . $db->sql_escape(utf8_clean_string($bot_name)) . "'"; - $result = $db->sql_query($sql); - $bot_user_id = (int) $db->sql_fetchfield('user_id'); - $db->sql_freeresult($result); - - if ($bot_user_id) - { - if ($bot_agent === false) - { - $sql = 'DELETE FROM ' . BOTS_TABLE . " - WHERE user_id = $bot_user_id"; - _sql($sql, $errored, $error_ary); - - user_delete('remove', $bot_user_id); - } - else - { - $sql = 'UPDATE ' . BOTS_TABLE . " - SET bot_agent = '" . $db->sql_escape($bot_agent) . "' - WHERE user_id = $bot_user_id"; - _sql($sql, $errored, $error_ary); - } - } - } - - // Disable receiving pms for bots - $sql = 'SELECT user_id - FROM ' . BOTS_TABLE; - $result = $db->sql_query($sql); - - $bot_user_ids = array(); - while ($row = $db->sql_fetchrow($result)) - { - $bot_user_ids[] = (int) $row['user_id']; - } - $db->sql_freeresult($result); - - if (!empty($bot_user_ids)) - { - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_allow_pm = 0 - WHERE ' . $db->sql_in_set('user_id', $bot_user_ids); - _sql($sql, $errored, $error_ary); - } - - $no_updates = false; - break; - // Changes from 3.1.0-dev to 3.1.0-A1 case '3.1.0-dev': From b999a75528156b2cf229cc2ceac04b5a8bac859d Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Fri, 9 Nov 2012 10:54:33 -0600 Subject: [PATCH 12/90] [feature/migrations] Some migrations data PHPBB3-9737 --- phpBB/includes/db/migration/v3010rc1.php | 7 ++- phpBB/includes/db/migration/v3011rc1.php | 61 ++++++++++++++---------- phpBB/includes/db/migration/v309rc1.php | 42 +++++++++------- 3 files changed, 65 insertions(+), 45 deletions(-) diff --git a/phpBB/includes/db/migration/v3010rc1.php b/phpBB/includes/db/migration/v3010rc1.php index 9a43b4c81d..847fe7c250 100644 --- a/phpBB/includes/db/migration/v3010rc1.php +++ b/phpBB/includes/db/migration/v3010rc1.php @@ -21,9 +21,8 @@ class phpbb_db_migration_v3010rc1 extends phpbb_db_migration function update_data() { - if (!isset($config['email_max_chunk_size'])) - { - set_config('email_max_chunk_size', '50'); - } + return array( + array('config.add', array('email_max_chunk_size', 50)), + ); } } diff --git a/phpBB/includes/db/migration/v3011rc1.php b/phpBB/includes/db/migration/v3011rc1.php index 04f86b47ae..aad80ba59f 100644 --- a/phpBB/includes/db/migration/v3011rc1.php +++ b/phpBB/includes/db/migration/v3011rc1.php @@ -20,28 +20,39 @@ class phpbb_db_migration_v3011rc1 extends phpbb_db_migration } function update_data() + { + return array( + array('custom', array(array(&$this, 'cleanup_deactivated_styles'))), + array('custom', array(array(&$this, 'delete_orphan_private_messages'))), + ); + } + + function cleanup_deactivated_styles() { // Updates users having current style a deactivated one $sql = 'SELECT style_id FROM ' . STYLES_TABLE . ' WHERE style_active = 0'; - $result = $db->sql_query($sql); + $result = $this->sql_query($sql); $deactivated_style_ids = array(); - while ($style_id = $db->sql_fetchfield('style_id', false, $result)) + while ($style_id = $this->db->sql_fetchfield('style_id', false, $result)) { $deactivated_style_ids[] = (int) $style_id; } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); if (!empty($deactivated_style_ids)) { $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_style = ' . (int) $config['default_style'] .' - WHERE ' . $db->sql_in_set('user_style', $deactivated_style_ids); - _sql($sql, $errored, $error_ary); + SET user_style = ' . (int) $this->config['default_style'] .' + WHERE ' . $this->db->sql_in_set('user_style', $deactivated_style_ids); + $this->sql_query($sql, $errored, $error_ary); } + } + function delete_orphan_private_messages() + { // Delete orphan private messages $batch_size = 500; @@ -58,26 +69,28 @@ class phpbb_db_migration_v3011rc1 extends phpbb_db_migration ), 'WHERE' => 't.user_id IS NULL', ); - $sql = $db->sql_build_query('SELECT', $sql_array); + $sql = $this->db->sql_build_query('SELECT', $sql_array); - do + $result = $this->db->sql_query_limit($sql, $batch_size); + + $delete_pms = array(); + while ($row = $this->db->sql_fetchrow($result)) { - $result = $db->sql_query_limit($sql, $batch_size); - - $delete_pms = array(); - while ($row = $db->sql_fetchrow($result)) - { - $delete_pms[] = (int) $row['msg_id']; - } - $db->sql_freeresult($result); - - if (!empty($delete_pms)) - { - $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' - WHERE ' . $db->sql_in_set('msg_id', $delete_pms); - _sql($sql, $errored, $error_ary); - } + $delete_pms[] = (int) $row['msg_id']; + } + $db->sql_freeresult($result); + + if (!empty($delete_pms)) + { + $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' + WHERE ' . $this->db->sql_in_set('msg_id', $delete_pms); + $this->sql_query($sql, $errored, $error_ary); + + return true; + } + else + { + return false; } - while (sizeof($delete_pms) == $batch_size); } } diff --git a/phpBB/includes/db/migration/v309rc1.php b/phpBB/includes/db/migration/v309rc1.php index ca56a4e7d9..ce51e54642 100644 --- a/phpBB/includes/db/migration/v309rc1.php +++ b/phpBB/includes/db/migration/v309rc1.php @@ -53,46 +53,54 @@ class phpbb_db_migration_v309rc1 extends phpbb_db_migration function update_data() { - set_config('ip_login_limit_max', '50'); - set_config('ip_login_limit_time', '21600'); - set_config('ip_login_limit_use_forwarded', '0'); + return array( + array('config.add', array('ip_login_limit_max', 50)), + array('config.add', array('ip_login_limit_time', 21600)), + array('config.add', array('ip_login_limit_use_forwarded', 0)), + array('custom', array(array(&$this, 'update_file_extension_group_names'))), + array('custom', array(array(&$this, 'fix_firebird_qa_captcha'))), + ); + } + function update_file_extension_group_names() + { // Update file extension group names to use language strings, again. $sql = 'SELECT group_id, group_name FROM ' . EXTENSION_GROUPS_TABLE . ' - WHERE group_name ' . $db->sql_like_expression('EXT_GROUP_' . $db->any_char); - $result = $db->sql_query($sql); + WHERE group_name ' . $this->db->sql_like_expression('EXT_GROUP_' . $this->db->any_char); + $result = $this->db->sql_query($sql); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { $sql_ary = array( 'group_name' => substr($row['group_name'], 10), // Strip off 'EXT_GROUP_' ); $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE group_id = ' . $row['group_id']; - _sql($sql, $errored, $error_ary); + $this->sql_query($sql, $errored, $error_ary); } - $db->sql_freeresult($result); - - global $db_tools, $table_prefix; + $this->db->sql_freeresult($result); + } + function fix_firebird_qa_captcha() + { // Recover from potentially broken Q&A CAPTCHA table on firebird // Q&A CAPTCHA was uninstallable, so it's safe to remove these // without data loss - if ($db_tools->sql_layer == 'firebird') + if ($this->db_tools->sql_layer == 'firebird') { $tables = array( - $table_prefix . 'captcha_questions', - $table_prefix . 'captcha_answers', - $table_prefix . 'qa_confirm', + $this->table_prefix . 'captcha_questions', + $this->table_prefix . 'captcha_answers', + $this->table_prefix . 'qa_confirm', ); foreach ($tables as $table) { - if ($db_tools->sql_table_exists($table)) + if ($this->db_tools->sql_table_exists($table)) { - $db_tools->sql_table_drop($table); + $this->db_tools->sql_table_drop($table); } } } From e7389e4c32f031fc6025880adf22b40d7d195f27 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 10 Nov 2012 04:00:38 -0600 Subject: [PATCH 13/90] [feature/migrations] 3.0.8-rc1 migration, fix some calls PHPBB3-9737 --- phpBB/includes/db/migration/v3011rc1.php | 4 +- phpBB/includes/db/migration/v308rc1.php | 177 ++++++++++++----------- phpBB/includes/db/migration/v309rc1.php | 2 +- 3 files changed, 93 insertions(+), 90 deletions(-) diff --git a/phpBB/includes/db/migration/v3011rc1.php b/phpBB/includes/db/migration/v3011rc1.php index aad80ba59f..3bae7a4a2d 100644 --- a/phpBB/includes/db/migration/v3011rc1.php +++ b/phpBB/includes/db/migration/v3011rc1.php @@ -47,7 +47,7 @@ class phpbb_db_migration_v3011rc1 extends phpbb_db_migration $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = ' . (int) $this->config['default_style'] .' WHERE ' . $this->db->sql_in_set('user_style', $deactivated_style_ids); - $this->sql_query($sql, $errored, $error_ary); + $this->sql_query($sql); } } @@ -84,7 +84,7 @@ class phpbb_db_migration_v3011rc1 extends phpbb_db_migration { $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' WHERE ' . $this->db->sql_in_set('msg_id', $delete_pms); - $this->sql_query($sql, $errored, $error_ary); + $this->sql_query($sql); return true; } diff --git a/phpBB/includes/db/migration/v308rc1.php b/phpBB/includes/db/migration/v308rc1.php index 13d0e98b1c..cbfedb1b53 100644 --- a/phpBB/includes/db/migration/v308rc1.php +++ b/phpBB/includes/db/migration/v308rc1.php @@ -20,14 +20,37 @@ class phpbb_db_migration_v308rc1 extends phpbb_db_migration } function update_data() + { + return array( + array('custom', array(array(&$this, 'update_file_extension_group_names'))), + array('custom', array(array(&$this, 'update_module_auth'))), + array('custom', array(array(&$this, 'update_bots'))), + array('custom', array(array(&$this, 'delete_orphan_shadow_topics'))), + array('module.add', array( + 'post' => array( + 'base' => 'board', + 'class' => 'acp', + 'title' => 'ACP_POST_SETTINGS', + 'auth' => 'acl_a_board', + 'cat' => 'ACP_MESSAGES', + 'after' => array('message', 'ACP_MESSAGE_SETTINGS') + ), + )), + array('config.add', array('load_unreads_search', 1)), + array('config.update_if', array(600, 'queue_interval', 60)), + array('config.update_if', array(50, 'email_package_size', 20)), + ); + } + + function update_file_extension_group_names() { // Update file extension group names to use language strings. $sql = 'SELECT lang_dir FROM ' . LANG_TABLE; - $result = $db->sql_query($sql); + $result = $this->db->sql_query($sql); $extension_groups_updated = array(); - while ($lang_dir = $db->sql_fetchfield('lang_dir')) + while ($lang_dir = $this->db->sql_fetchfield('lang_dir')) { $lang_dir = basename($lang_dir); @@ -37,9 +60,9 @@ class phpbb_db_migration_v308rc1 extends phpbb_db_migration // On an already updated board, they can also already be in language/.../acp/attachments.php // in the board root. $lang_files = array( - "{$phpbb_root_path}install/update/new/language/$lang_dir/acp/attachments.$phpEx", - "{$phpbb_root_path}language/$lang_dir/install.$phpEx", - "{$phpbb_root_path}language/$lang_dir/acp/attachments.$phpEx", + "{$this->phpbb_root_path}install/update/new/language/$lang_dir/acp/attachments.$this->phpEx", + "{$this->phpbb_root_path}language/$lang_dir/install.$this->phpEx", + "{$this->phpbb_root_path}language/$lang_dir/acp/attachments.$this->phpEx", ); foreach ($lang_files as $lang_file) @@ -64,48 +87,38 @@ class phpbb_db_migration_v308rc1 extends phpbb_db_migration ); $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " - WHERE group_name = '" . $db->sql_escape($lang_val) . "'"; - _sql($sql, $errored, $error_ary); + SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . " + WHERE group_name = '" . $this->db->sql_escape($lang_val) . "'"; + $this->sql_query($sql); $extension_groups_updated[$lang_key] = true; } } } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); + } - // Install modules - $modules_to_install = array( - 'post' => array( - 'base' => 'board', - 'class' => 'acp', - 'title' => 'ACP_POST_SETTINGS', - 'auth' => 'acl_a_board', - 'cat' => 'ACP_MESSAGES', - 'after' => array('message', 'ACP_MESSAGE_SETTINGS') - ), - ); - - _add_modules($modules_to_install); - - // update + function update_module_auth() + { $sql = 'UPDATE ' . MODULES_TABLE . ' SET module_auth = \'cfg_allow_avatar && (cfg_allow_avatar_local || cfg_allow_avatar_remote || cfg_allow_avatar_upload || cfg_allow_avatar_remote_upload)\' WHERE module_class = \'ucp\' AND module_basename = \'profile\' AND module_mode = \'avatar\''; - _sql($sql, $errored, $error_ary); + $this->sql_query($sql); + } - // add Bing Bot + function update_bots() + { $bot_name = 'Bing [Bot]'; $bot_name_clean = utf8_clean_string($bot_name); $sql = 'SELECT user_id FROM ' . USERS_TABLE . " - WHERE username_clean = '" . $db->sql_escape($bot_name_clean) . "'"; - $result = $db->sql_query($sql); - $bing_already_added = (bool) $db->sql_fetchfield('user_id'); - $db->sql_freeresult($result); + WHERE username_clean = '" . $this->db->sql_escape($bot_name_clean) . "'"; + $result = $this->db->sql_query($sql); + $bing_already_added = (bool) $this->db->sql_fetchfield('user_id'); + $this->db->sql_freeresult($result); if (!$bing_already_added) { @@ -114,9 +127,9 @@ class phpbb_db_migration_v308rc1 extends phpbb_db_migration $sql = 'SELECT group_id, group_colour FROM ' . GROUPS_TABLE . " WHERE group_name = 'BOTS'"; - $result = $db->sql_query($sql); - $group_row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + $result = $this->db->sql_query($sql); + $group_row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); if (!$group_row) { @@ -127,7 +140,7 @@ class phpbb_db_migration_v308rc1 extends phpbb_db_migration if (!function_exists('user_add')) { - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + include($this->phpbb_root_path . 'includes/functions_user.' . $this->phpEx); } $user_row = array( @@ -138,16 +151,16 @@ class phpbb_db_migration_v308rc1 extends phpbb_db_migration 'user_password' => '', 'user_colour' => $group_row['group_colour'], 'user_email' => '', - 'user_lang' => $config['default_lang'], - 'user_style' => $config['default_style'], + 'user_lang' => $this->config['default_lang'], + 'user_style' => $this->config['default_style'], 'user_timezone' => 0, - 'user_dateformat' => $config['default_dateformat'], + 'user_dateformat' => $this->config['default_dateformat'], 'user_allow_massemail' => 0, ); $user_id = user_add($user_row); - $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( + $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $this->db->sql_build_array('INSERT', array( 'bot_active' => 1, 'bot_name' => (string) $bot_name, 'user_id' => (int) $user_id, @@ -155,68 +168,58 @@ class phpbb_db_migration_v308rc1 extends phpbb_db_migration 'bot_ip' => (string) $bot_ip, )); - _sql($sql, $errored, $error_ary); + $this->sql_query($sql); } - // end Bing Bot addition + } + function delete_orphan_shadow_topics() + { // Delete shadow topics pointing to not existing topics $batch_size = 500; // Set of affected forums we have to resync $sync_forum_ids = array(); - do - { - $sql_array = array( - 'SELECT' => 't1.topic_id, t1.forum_id', - 'FROM' => array( - TOPICS_TABLE => 't1', + $sql_array = array( + 'SELECT' => 't1.topic_id, t1.forum_id', + 'FROM' => array( + TOPICS_TABLE => 't1', + ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(TOPICS_TABLE => 't2'), + 'ON' => 't1.topic_moved_id = t2.topic_id', ), - 'LEFT_JOIN' => array( - array( - 'FROM' => array(TOPICS_TABLE => 't2'), - 'ON' => 't1.topic_moved_id = t2.topic_id', - ), - ), - 'WHERE' => 't1.topic_moved_id <> 0 - AND t2.topic_id IS NULL', - ); - $sql = $db->sql_build_query('SELECT', $sql_array); - $result = $db->sql_query_limit($sql, $batch_size); + ), + 'WHERE' => 't1.topic_moved_id <> 0 + AND t2.topic_id IS NULL', + ); + $sql = $this->db->sql_build_query('SELECT', $sql_array); + $result = $this->db->sql_query_limit($sql, $batch_size); - $topic_ids = array(); - while ($row = $db->sql_fetchrow($result)) - { - $topic_ids[] = (int) $row['topic_id']; - - $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id']; - } - $db->sql_freeresult($result); - - if (!empty($topic_ids)) - { - $sql = 'DELETE FROM ' . TOPICS_TABLE . ' - WHERE ' . $db->sql_in_set('topic_id', $topic_ids); - $db->sql_query($sql); - } - } - while (sizeof($topic_ids) == $batch_size); - - // Sync the forums we have deleted shadow topics from. - sync('forum', 'forum_id', $sync_forum_ids, true, true); - - // Unread posts search load switch - set_config('load_unreads_search', '1'); - - // Reduce queue interval to 60 seconds, email package size to 20 - if ($config['queue_interval'] == 600) + $topic_ids = array(); + while ($row = $this->db->sql_fetchrow($result)) { - set_config('queue_interval', '60'); - } + $topic_ids[] = (int) $row['topic_id']; - if ($config['email_package_size'] == 50) + $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id']; + } + $this->db->sql_freeresult($result); + + if (!empty($topic_ids)) { - set_config('email_package_size', '20'); + $sql = 'DELETE FROM ' . TOPICS_TABLE . ' + WHERE ' . $this->db->sql_in_set('topic_id', $topic_ids); + $this->db->sql_query($sql); + + // Sync the forums we have deleted shadow topics from. + sync('forum', 'forum_id', $sync_forum_ids, true, true); + + return true; + } + else + { + return false; } } } diff --git a/phpBB/includes/db/migration/v309rc1.php b/phpBB/includes/db/migration/v309rc1.php index ce51e54642..e8db93c78d 100644 --- a/phpBB/includes/db/migration/v309rc1.php +++ b/phpBB/includes/db/migration/v309rc1.php @@ -79,7 +79,7 @@ class phpbb_db_migration_v309rc1 extends phpbb_db_migration $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE group_id = ' . $row['group_id']; - $this->sql_query($sql, $errored, $error_ary); + $this->sql_query($sql); } $this->db->sql_freeresult($result); } From 2a7985c26fcf558c30fa316262344307ffc99e9e Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 10 Nov 2012 05:59:01 -0600 Subject: [PATCH 14/90] [feature/migrations] Migrations back through 3.0.6 PHPBB3-9737 --- phpBB/includes/db/migration/v306rc1.php | 336 +++++++++++------------- phpBB/includes/db/migration/v306rc3.php | 9 +- phpBB/includes/db/migration/v307rc1.php | 23 +- phpBB/includes/db/migration/v307rc2.php | 29 +- phpBB/includes/db/migration/v308rc1.php | 4 +- 5 files changed, 197 insertions(+), 204 deletions(-) diff --git a/phpBB/includes/db/migration/v306rc1.php b/phpBB/includes/db/migration/v306rc1.php index 63d1c66c2d..45b597d56b 100644 --- a/phpBB/includes/db/migration/v306rc1.php +++ b/phpBB/includes/db/migration/v306rc1.php @@ -61,109 +61,141 @@ class phpbb_db_migration_v306rc1 extends phpbb_db_migration function update_data() { - // Let's see if the GD Captcha can be enabled... we simply look for what *is* enabled... - if (!empty($config['captcha_gd']) && !isset($config['captcha_plugin'])) - { - set_config('captcha_plugin', 'phpbb_captcha_gd'); - } - else if (!isset($config['captcha_plugin'])) - { - set_config('captcha_plugin', 'phpbb_captcha_nogd'); - } + return array( + //array('custom', array(array(&$this, ''))) + array('config.add', array('captcha_plugin', 'phpbb_captcha_nogd')), + array('config.update_if', array( + ($this->config['captcha_gd']), + 'captcha_plugin', + 'phpbb_captcha_gd', + )), - // Entries for the Feed Feature - set_config('feed_enable', '0'); - set_config('feed_limit', '10'); + array('config.add', array('feed_enable', 0)), + array('config.add', array('feed_limit', 10)), + array('config.add', array('feed_overall_forums', 1)), + array('config.add', array('feed_overall_forums_limit', 15)), + array('config.add', array('feed_overall_topics', 0)), + array('config.add', array('feed_overall_topics_limit', 15)), + array('config.add', array('feed_forum', 1)), + array('config.add', array('feed_topic', 1)), + array('config.add', array('feed_item_statistics', 1)), - set_config('feed_overall_forums', '1'); - set_config('feed_overall_forums_limit', '15'); + array('config.add', array('smilies_per_page', 50)), + array('config.add', array('allow_pm_report', 1)), + array('config.add', array('min_post_chars', 1)), + array('config.add', array('allow_quick_reply', 1)), + array('config.add', array('new_member_post_limit', 0)), + array('config.add', array('new_member_group_default', 0)), + array('config.add', array('delete_time', $this->config['edit_time'])), - set_config('feed_overall_topics', '0'); - set_config('feed_overall_topics_limit', '15'); + array('config.add', array('allow_avatar', 0)), + array('config.add_if', array( + ($this->config['allow_avatar_upload'] || $this->config['allow_avatar_local'] || $this->config['allow_avatar_remote']), + 'allow_avatar', + 1, + )), + array('config.add', array('allow_avatar_remote_upload', 0)), + array('config.add_if', array( + ($this->config['allow_avatar_remote'] && $this->config['allow_avatar_upload']), + 'allow_avatar_remote_upload', + 1, + )), - set_config('feed_forum', '1'); - set_config('feed_topic', '1'); - set_config('feed_item_statistics', '1'); - - // Entries for smiley pagination - set_config('smilies_per_page', '50'); - - // Entry for reporting PMs - set_config('allow_pm_report', '1'); - - // Install modules - $modules_to_install = array( - 'feed' => array( - 'base' => 'board', - 'class' => 'acp', - 'title' => 'ACP_FEED_SETTINGS', - 'auth' => 'acl_a_board', - 'cat' => 'ACP_BOARD_CONFIGURATION', - 'after' => array('signature', 'ACP_SIGNATURE_SETTINGS') - ), - 'warnings' => array( - 'base' => 'users', - 'class' => 'acp', - 'title' => 'ACP_USER_WARNINGS', - 'auth' => 'acl_a_user', - 'display' => 0, - 'cat' => 'ACP_CAT_USERS', - 'after' => array('feedback', 'ACP_USER_FEEDBACK') - ), - 'send_statistics' => array( - 'base' => 'send_statistics', - 'class' => 'acp', - 'title' => 'ACP_SEND_STATISTICS', - 'auth' => 'acl_a_server', - 'cat' => 'ACP_SERVER_CONFIGURATION' - ), - 'setting_forum_copy' => array( - 'base' => 'permissions', - 'class' => 'acp', - 'title' => 'ACP_FORUM_PERMISSIONS_COPY', - 'auth' => 'acl_a_fauth && acl_a_authusers && acl_a_authgroups && acl_a_mauth', - 'cat' => 'ACP_FORUM_BASED_PERMISSIONS', - 'after' => array('setting_forum_local', 'ACP_FORUM_PERMISSIONS') - ), - 'pm_reports' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORTS_OPEN', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' - ), - 'pm_reports_closed' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORTS_CLOSED', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' - ), - 'pm_report_details' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORT_DETAILS', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' - ), + array('module.add', array( + 'feed' => array( + 'base' => 'board', + 'class' => 'acp', + 'title' => 'ACP_FEED_SETTINGS', + 'auth' => 'acl_a_board', + 'cat' => 'ACP_BOARD_CONFIGURATION', + 'after' => array('signature', 'ACP_SIGNATURE_SETTINGS') + ), + )), + array('module.add', array( + 'warnings' => array( + 'base' => 'users', + 'class' => 'acp', + 'title' => 'ACP_USER_WARNINGS', + 'auth' => 'acl_a_user', + 'display' => 0, + 'cat' => 'ACP_CAT_USERS', + 'after' => array('feedback', 'ACP_USER_FEEDBACK') + ), + )), + array('module.add', array( + 'send_statistics' => array( + 'base' => 'send_statistics', + 'class' => 'acp', + 'title' => 'ACP_SEND_STATISTICS', + 'auth' => 'acl_a_server', + 'cat' => 'ACP_SERVER_CONFIGURATION' + ), + )), + array('module.add', array( + 'setting_forum_copy' => array( + 'base' => 'permissions', + 'class' => 'acp', + 'title' => 'ACP_FORUM_PERMISSIONS_COPY', + 'auth' => 'acl_a_fauth && acl_a_authusers && acl_a_authgroups && acl_a_mauth', + 'cat' => 'ACP_FORUM_BASED_PERMISSIONS', + 'after' => array('setting_forum_local', 'ACP_FORUM_PERMISSIONS') + ), + )), + array('module.add', array( + 'pm_reports' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORTS_OPEN', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + )), + array('module.add', array( + 'pm_reports_closed' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORTS_CLOSED', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + )), + array('module.add', array( + 'pm_report_details' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORT_DETAILS', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + )), + array('custom', array(array(&$this, 'add_newly_registered_group'))), + array('custom', array(array(&$this, 'set_user_options_default'))), ); + } - _add_modules($modules_to_install); + function set_user_options_default() + { + // 229376 is the added value to enable all three signature options + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_options = user_options + 229376'; + $this->sql_query($sql); + } + function add_newly_registered_group() + { // Add newly_registered group... but check if it already exists (we always supported running the updater on any schema) $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = 'NEWLY_REGISTERED'"; - $result = $db->sql_query($sql); - $group_id = (int) $db->sql_fetchfield('group_id'); - $db->sql_freeresult($result); + $result = $this->db->sql_query($sql); + $group_id = (int) $this->db->sql_fetchfield('group_id'); + $this->db->sql_freeresult($result); if (!$group_id) { $sql = 'INSERT INTO ' . GROUPS_TABLE . " (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('NEWLY_REGISTERED', 3, 0, '', 0, '', '', '', 5)"; - _sql($sql, $errored, $error_ary); + $this->sql_query($sql); - $group_id = $db->sql_nextid(); + $group_id = $this->db->sql_nextid(); } // Insert new user role... at the end of the chain @@ -171,35 +203,35 @@ class phpbb_db_migration_v306rc1 extends phpbb_db_migration FROM ' . ACL_ROLES_TABLE . " WHERE role_name = 'ROLE_USER_NEW_MEMBER' AND role_type = 'u_'"; - $result = $db->sql_query($sql); - $u_role = (int) $db->sql_fetchfield('role_id'); - $db->sql_freeresult($result); + $result = $this->db->sql_query($sql); + $u_role = (int) $this->db->sql_fetchfield('role_id'); + $this->db->sql_freeresult($result); if (!$u_role) { $sql = 'SELECT MAX(role_order) as max_order_id FROM ' . ACL_ROLES_TABLE . " WHERE role_type = 'u_'"; - $result = $db->sql_query($sql); - $next_order_id = (int) $db->sql_fetchfield('max_order_id'); - $db->sql_freeresult($result); + $result = $this->db->sql_query($sql); + $next_order_id = (int) $this->db->sql_fetchfield('max_order_id'); + $this->db->sql_freeresult($result); $next_order_id++; $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_NEW_MEMBER', 'ROLE_DESCRIPTION_USER_NEW_MEMBER', 'u_', $next_order_id)"; - _sql($sql, $errored, $error_ary); - $u_role = $db->sql_nextid(); + $this->sql_query($sql); + $u_role = $this->db->sql_nextid(); if (!$errored) { // Now add the correct data to the roles... // The standard role says that new users are not able to send a PM, Mass PM, are not able to PM groups $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $u_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_sendpm', 'u_masspm', 'u_masspm_group')"; - _sql($sql, $errored, $error_ary); + $this->sql_query($sql); // Add user role to group $sql = 'INSERT INTO ' . ACL_GROUPS_TABLE . " (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES ($group_id, 0, 0, $u_role, 0)"; - _sql($sql, $errored, $error_ary); + $this->sql_query($sql); } } @@ -208,29 +240,29 @@ class phpbb_db_migration_v306rc1 extends phpbb_db_migration FROM ' . ACL_ROLES_TABLE . " WHERE role_name = 'ROLE_FORUM_NEW_MEMBER' AND role_type = 'f_'"; - $result = $db->sql_query($sql); - $f_role = (int) $db->sql_fetchfield('role_id'); - $db->sql_freeresult($result); + $result = $this->db->sql_query($sql); + $f_role = (int) $this->db->sql_fetchfield('role_id'); + $this->db->sql_freeresult($result); if (!$f_role) { $sql = 'SELECT MAX(role_order) as max_order_id FROM ' . ACL_ROLES_TABLE . " WHERE role_type = 'f_'"; - $result = $db->sql_query($sql); - $next_order_id = (int) $db->sql_fetchfield('max_order_id'); - $db->sql_freeresult($result); + $result = $this->db->sql_query($sql); + $next_order_id = (int) $this->db->sql_fetchfield('max_order_id'); + $this->db->sql_freeresult($result); $next_order_id++; $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_NEW_MEMBER', 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER', 'f_', $next_order_id)"; - _sql($sql, $errored, $error_ary); - $f_role = $db->sql_nextid(); + $this->sql_query($sql); + $f_role = $this->db->sql_nextid(); if (!$errored) { $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $f_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove')"; - _sql($sql, $errored, $error_ary); + $this->sql_query($sql); } } @@ -238,25 +270,14 @@ class phpbb_db_migration_v306rc1 extends phpbb_db_migration $sql = 'SELECT 1 FROM ' . USERS_TABLE . ' WHERE user_new = 0'; - $result = $db->sql_query_limit($sql, 1); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + $result = $this->db->sql_query_limit($sql, 1); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); if (!$row) { $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new = 0'; - _sql($sql, $errored, $error_ary); - } - - // Newly registered users limit - if (!isset($config['new_member_post_limit'])) - { - set_config('new_member_post_limit', (!empty($config['enable_queue_trigger'])) ? $config['queue_trigger_posts'] : 0); - } - - if (!isset($config['new_member_group_default'])) - { - set_config('new_member_group_default', 0); + $this->sql_query($sql); } // To mimick the old "feature" we will assign the forum role to every forum, regardless of the setting (this makes sure there are no "this does not work!!!! YUO!!!" posts... @@ -265,9 +286,9 @@ class phpbb_db_migration_v306rc1 extends phpbb_db_migration FROM ' . ACL_GROUPS_TABLE . ' WHERE group_id = ' . $group_id . ' AND auth_role_id = ' . $f_role; - $result = $db->sql_query($sql); - $is_options = (int) $db->sql_fetchfield('forum_id'); - $db->sql_freeresult($result); + $result = $this->db->sql_query($sql); + $is_options = (int) $this->db->sql_fetchfield('forum_id'); + $this->db->sql_freeresult($result); // Not assigned at all... :/ if (!$is_options) @@ -276,75 +297,18 @@ class phpbb_db_migration_v306rc1 extends phpbb_db_migration $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE . ' WHERE forum_type != ' . FORUM_LINK; - $result = $db->sql_query($sql); + $result = $this->db->sql_query($sql); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { - _sql('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (' . $group_id . ', ' . (int) $row['forum_id'] . ', 0, ' . $f_role . ', 0)', $errored, $error_ary); + $this->sql_query('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (' . $group_id . ', ' . (int) $row['forum_id'] . ', 0, ' . $f_role . ', 0)'); } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); } // Clear permissions... - include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + include_once($this->phpbb_root_path . 'includes/acp/auth.' . $this->phpEx); $auth_admin = new auth_admin(); $auth_admin->acl_clear_prefetch(); - - if (!isset($config['allow_avatar'])) - { - if ($config['allow_avatar_upload'] || $config['allow_avatar_local'] || $config['allow_avatar_remote']) - { - set_config('allow_avatar', '1'); - } - else - { - set_config('allow_avatar', '0'); - } - } - - if (!isset($config['allow_avatar_remote_upload'])) - { - if ($config['allow_avatar_remote'] && $config['allow_avatar_upload']) - { - set_config('allow_avatar_remote_upload', '1'); - } - else - { - set_config('allow_avatar_remote_upload', '0'); - } - } - - // Minimum number of characters - if (!isset($config['min_post_chars'])) - { - set_config('min_post_chars', '1'); - } - - if (!isset($config['allow_quick_reply'])) - { - set_config('allow_quick_reply', '1'); - } - - // Set every members user_options column to enable - // bbcode, smilies and URLs for signatures by default - $sql = 'SELECT user_options - FROM ' . USERS_TABLE . ' - WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; - $result = $db->sql_query_limit($sql, 1); - $user_option = (int) $db->sql_fetchfield('user_options'); - $db->sql_freeresult($result); - - // Check if we already updated the database by checking bit 15 which we used to store the sig_bbcode option - if (!($user_option & 1 << 15)) - { - // 229376 is the added value to enable all three signature options - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_options = user_options + 229376'; - _sql($sql, $errored, $error_ary); - } - - if (!isset($config['delete_time'])) - { - set_config('delete_time', $config['edit_time']); - } } } diff --git a/phpBB/includes/db/migration/v306rc3.php b/phpBB/includes/db/migration/v306rc3.php index b3bd49eafa..e2c4e66ada 100644 --- a/phpBB/includes/db/migration/v306rc3.php +++ b/phpBB/includes/db/migration/v306rc3.php @@ -20,12 +20,19 @@ class phpbb_db_migration_v306rc3 extends phpbb_db_migration } function update_data() + { + return array( + array('custom', array(array(&$this, 'update_cp_fields'))), + ); + } + + function update_cp_fields() { // Update the Custom Profile Fields based on previous settings to the new format $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . ' SET field_show_on_vt = 1 WHERE field_hide = 0 AND (field_required = 1 OR field_show_on_reg = 1 OR field_show_profile = 1)'; - _sql($sql, $errored, $error_ary); + $this->sql_query($sql); } } diff --git a/phpBB/includes/db/migration/v307rc1.php b/phpBB/includes/db/migration/v307rc1.php index f1c8b3384a..9b55cb2757 100644 --- a/phpBB/includes/db/migration/v307rc1.php +++ b/phpBB/includes/db/migration/v307rc1.php @@ -30,17 +30,22 @@ class phpbb_db_migration_v307rc1 extends phpbb_db_migration function update_data() { - // ATOM Feeds - set_config('feed_overall', '1'); - set_config('feed_http_auth', '0'); - set_config('feed_limit_post', (string) (isset($config['feed_limit']) ? (int) $config['feed_limit'] : 15)); - set_config('feed_limit_topic', (string) (isset($config['feed_overall_topics_limit']) ? (int) $config['feed_overall_topics_limit'] : 10)); - set_config('feed_topics_new', (!empty($config['feed_overall_topics']) ? '1' : '0')); - set_config('feed_topics_active', (!empty($config['feed_overall_topics']) ? '1' : '0')); + return array( + array('config.add', array('feed_overall', 1)), + array('config.add', array('feed_http_auth', 0)), + array('config.add', array('feed_limit_post', $this->config['feed_limit'])), + array('config.add', array('feed_limit_topic', $this->config['feed_overall_topics_limit'])), + array('config.add', array('feed_topics_new', $this->config['feed_overall_topics'])), + array('config.add', array('feed_topics_active', $this->config['feed_overall_topics'])), + array('custom', array(array(&$this, 'delete_text_templates'))), + ); + } + function delete_text_templates() + { // Delete all text-templates from the template_data $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' - WHERE template_filename ' . $db->sql_like_expression($db->any_char . '.txt'); - _sql($sql, $errored, $error_ary); + WHERE template_filename ' . $this->db->sql_like_expression($this->db->any_char . '.txt'); + $this->sql_query($sql); } } diff --git a/phpBB/includes/db/migration/v307rc2.php b/phpBB/includes/db/migration/v307rc2.php index f9492f3d1c..438ebfb8c2 100644 --- a/phpBB/includes/db/migration/v307rc2.php +++ b/phpBB/includes/db/migration/v307rc2.php @@ -21,15 +21,26 @@ class phpbb_db_migration_v307rc2 extends phpbb_db_migration function update_data() { + return array( + array('custom', array(array(&$this, 'update_email_hash'))), + ); + } + + function update_email_hash($start = 0) + { + $limit = 1000; + $sql = 'SELECT user_id, user_email, user_email_hash FROM ' . USERS_TABLE . ' WHERE user_type <> ' . USER_IGNORE . " AND user_email <> ''"; - $result = $db->sql_query($sql); + $result = $this->db->sql_query_limit($sql, $limit, $start); $i = 0; - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { + $i++; + // Snapshot of the phpbb_email_hash() function // We cannot call it directly because the auto updater updates the DB first. :/ $user_email_hash = sprintf('%u', crc32(strtolower($row['user_email']))) . strlen($row['user_email']); @@ -41,13 +52,19 @@ class phpbb_db_migration_v307rc2 extends phpbb_db_migration ); $sql = 'UPDATE ' . USERS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . (int) $row['user_id']; - _sql($sql, $errored, $error_ary, ($i % 100 == 0)); - - ++$i; + $this->sql_query($sql); } } $db->sql_freeresult($result); + + if ($i < $limit) + { + // Completed + return false; + } + + return $start + $limit; } } diff --git a/phpBB/includes/db/migration/v308rc1.php b/phpBB/includes/db/migration/v308rc1.php index cbfedb1b53..f365695058 100644 --- a/phpBB/includes/db/migration/v308rc1.php +++ b/phpBB/includes/db/migration/v308rc1.php @@ -37,8 +37,8 @@ class phpbb_db_migration_v308rc1 extends phpbb_db_migration ), )), array('config.add', array('load_unreads_search', 1)), - array('config.update_if', array(600, 'queue_interval', 60)), - array('config.update_if', array(50, 'email_package_size', 20)), + array('config.update_if_equals', array(600, 'queue_interval', 60)), + array('config.update_if_equals', array(50, 'email_package_size', 20)), ); } From ae8edf7b0e74c54b5b02b66a8b2a436a4172c63e Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 10 Nov 2012 06:26:38 -0600 Subject: [PATCH 15/90] [feature/migrations] Use $this->db PHPBB3-9737 --- phpBB/includes/db/migration.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration.php index aca9d264bb..de9f6d07e3 100644 --- a/phpBB/includes/db/migration.php +++ b/phpBB/includes/db/migration.php @@ -95,29 +95,29 @@ class phpbb_db_migration echo "
\n{$sql}\n
"; } - $db->sql_return_on_error(true); + $this->db->sql_return_on_error(true); if ($sql === 'begin') { - $result = $db->sql_transaction('begin'); + $result = $this->db->sql_transaction('begin'); } else if ($sql === 'commit') { - $result = $db->sql_transaction('commit'); + $result = $this->db->sql_transaction('commit'); } else { - $result = $db->sql_query($sql); - if ($db->sql_error_triggered) + $result = $this->db->sql_query($sql); + if ($this->db->sql_error_triggered) { $this->errors[] = array( - 'sql' => $db->sql_error_sql, - 'code' => $db->sql_error_returned, + 'sql' => $this->db->sql_error_sql, + 'code' => $this->db->sql_error_returned, ); } } - $db->sql_return_on_error(false); + $this->db->sql_return_on_error(false); return $result; } From 167faed1630d01e3d592a6696f58316c1d832ff9 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 10 Nov 2012 06:32:02 -0600 Subject: [PATCH 16/90] [feature/migrations] Depend on part2 PHPBB3-9737 --- phpBB/includes/db/migration/v305.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/migration/v305.php b/phpBB/includes/db/migration/v305.php index b4d676d72a..71e28c6b7b 100644 --- a/phpBB/includes/db/migration/v305.php +++ b/phpBB/includes/db/migration/v305.php @@ -11,7 +11,7 @@ class phpbb_db_migration_v305 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_v305rc1'); + return array('phpbb_db_migration_v305rc1part2'); } function update_schema() From b52a0f50ab980ca941267ddb4f509f104b07db77 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sat, 10 Nov 2012 13:32:44 +0100 Subject: [PATCH 17/90] [feature/migrations] Update 3.0.3-3.0.5 migrations to work --- phpBB/includes/db/migration/305rc1part2.php | 34 +++++++ phpBB/includes/db/migration/v303rc1.php | 100 +++---------------- phpBB/includes/db/migration/v304.php | 15 ++- phpBB/includes/db/migration/v304rc1.php | 13 ++- phpBB/includes/db/migration/v305rc1.php | 105 ++++++++------------ 5 files changed, 107 insertions(+), 160 deletions(-) create mode 100644 phpBB/includes/db/migration/305rc1part2.php diff --git a/phpBB/includes/db/migration/305rc1part2.php b/phpBB/includes/db/migration/305rc1part2.php new file mode 100644 index 0000000000..238e533b06 --- /dev/null +++ b/phpBB/includes/db/migration/305rc1part2.php @@ -0,0 +1,34 @@ + array( + ACL_OPTIONS_TABLE => array('auth_option'), + ), + 'add_unique_index' => array( + ACL_OPTIONS_TABLE => array( + 'auth_option' => array('auth_option'), + ), + ), + ); + } + + function update_data() + { + } +} diff --git a/phpBB/includes/db/migration/v303rc1.php b/phpBB/includes/db/migration/v303rc1.php index b8ec5668fd..7518a6ed54 100644 --- a/phpBB/includes/db/migration/v303rc1.php +++ b/phpBB/includes/db/migration/v303rc1.php @@ -35,93 +35,20 @@ class phpbb_db_migration_v303rc1 extends phpbb_db_migration array('config.add', array('enable_queue_trigger', '0')), array('config.add', array('queue_trigger_posts', '3')), array('config.add', array('pm_max_recipients', '0')), - array('custom', array('set_group_default_max_recipients')) + array('custom', array(array(&$this, 'set_group_default_max_recipients'))), + array('config.add', array('dbms_version', '')), + array('permission.add', array('u_masspm_group', phpbb_auth::IS_GLOBAL), + array('custom', array(array(&$this, 'correct_acp_email_permissions'))), + )); + } - // Not prefilling yet - set_config('dbms_version', ''); - - // Add new permission u_masspm_group and duplicate settings from u_masspm - include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); - $auth_admin = new auth_admin(); - - // Only add the new permission if it does not already exist - if (empty($auth_admin->acl_options['id']['u_masspm_group'])) - { - $auth_admin->acl_add_option(array('global' => array('u_masspm_group'))); - - // Now the tricky part, filling the permission - $old_id = $auth_admin->acl_options['id']['u_masspm']; - $new_id = $auth_admin->acl_options['id']['u_masspm_group']; - - $tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE); - - foreach ($tables as $table) - { - $sql = 'SELECT * - FROM ' . $table . ' - WHERE auth_option_id = ' . $old_id; - $result = _sql($sql, $errored, $error_ary); - - $sql_ary = array(); - while ($row = $db->sql_fetchrow($result)) - { - $row['auth_option_id'] = $new_id; - $sql_ary[] = $row; - } - $db->sql_freeresult($result); - - if (sizeof($sql_ary)) - { - $db->sql_multi_insert($table, $sql_ary); - } - } - - // Remove any old permission entries - $auth_admin->acl_clear_prefetch(); - } - - /** - * Do not resync post counts here. An admin may do this later from the ACP - $start = 0; - $step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000; - - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = 0'; - _sql($sql, $errored, $error_ary); - - do - { - $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id - FROM ' . POSTS_TABLE . ' - WHERE post_id BETWEEN ' . ($start + 1) . ' AND ' . ($start + $step) . ' - AND post_postcount = 1 AND post_approved = 1 - GROUP BY poster_id'; - $result = _sql($sql, $errored, $error_ary); - - if ($row = $db->sql_fetchrow($result)) - { - do - { - $sql = 'UPDATE ' . USERS_TABLE . " SET user_posts = user_posts + {$row['num_posts']} WHERE user_id = {$row['poster_id']}"; - _sql($sql, $errored, $error_ary); - } - while ($row = $db->sql_fetchrow($result)); - - $start += $step; - } - else - { - $start = 0; - } - $db->sql_freeresult($result); - } - while ($start); - */ - - $sql = 'UPDATE ' . MODULES_TABLE . ' - SET module_auth = \'acl_a_email && cfg_email_enable\' - WHERE module_class = \'acp\' - AND module_basename = \'email\''; - _sql($sql, $errored, $error_ary); + function correct_acp_email_permissions() + { + $sql = 'UPDATE ' . $this->table_prefix . 'modules + SET module_auth = \'acl_a_email && cfg_email_enable\' + WHERE module_class = \'acp\' + AND module_basename = \'email\''; + $this->sql_query($sql); } function set_group_default_max_recipients() @@ -131,5 +58,4 @@ class phpbb_db_migration_v303rc1 extends phpbb_db_migration WHERE ' . $this->db->sql_in_set('group_name', array('GUESTS', 'REGISTERED', 'REGISTERED_COPPA', 'BOTS')); $this->sql_query($sql); } - } diff --git a/phpBB/includes/db/migration/v304.php b/phpBB/includes/db/migration/v304.php index 2895caaa6d..5358bcc20f 100644 --- a/phpBB/includes/db/migration/v304.php +++ b/phpBB/includes/db/migration/v304.php @@ -20,21 +20,28 @@ class phpbb_db_migration_v304 extends phpbb_db_migration } function update_data() + { + return array( + array('custom', array(array(&$this, 'rename_log_delete_topic'))), + ); + } + + function rename_log_delete_topic() { if ($db->sql_layer == 'oracle') { // log_operation is CLOB - but we can change this later - $sql = 'UPDATE ' . LOG_TABLE . " + $sql = 'UPDATE ' . $this->table_prefix . "log SET log_operation = 'LOG_DELETE_TOPIC' WHERE log_operation LIKE 'LOG_TOPIC_DELETED'"; - _sql($sql, $errored, $error_ary); + $this->sql_query($sql); } else { - $sql = 'UPDATE ' . LOG_TABLE . " + $sql = 'UPDATE ' . $this->table_prefix . "log SET log_operation = 'LOG_DELETE_TOPIC' WHERE log_operation = 'LOG_TOPIC_DELETED'"; - _sql($sql, $errored, $error_ary); + $this->sql_query($sql); } } } diff --git a/phpBB/includes/db/migration/v304rc1.php b/phpBB/includes/db/migration/v304rc1.php index a7098ce62f..2daad4e826 100644 --- a/phpBB/includes/db/migration/v304rc1.php +++ b/phpBB/includes/db/migration/v304rc1.php @@ -56,13 +56,20 @@ class phpbb_db_migration_v304rc1 extends phpbb_db_migration } function update_data() + { + return array( + array('custom', array(array(&$this, 'update_custom_profile_fields'))), + ); + } + + function update_custom_profile_fields() { // Update the Custom Profile Fields based on previous settings to the new format $sql = 'SELECT field_id, field_required, field_show_on_reg, field_hide FROM ' . PROFILE_FIELDS_TABLE; - $result = _sql($sql, $errored, $error_ary); + $result = $this->sql_query($sql); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { $sql_ary = array( 'field_required' => 0, @@ -90,7 +97,7 @@ class phpbb_db_migration_v304rc1 extends phpbb_db_migration $sql_ary['field_show_profile'] = 1; } - _sql('UPDATE ' . PROFILE_FIELDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary); + $this->sql_query('UPDATE ' . $this->table_prefix . 'profile_fields SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary); } } } diff --git a/phpBB/includes/db/migration/v305rc1.php b/phpBB/includes/db/migration/v305rc1.php index 8d9c4d2456..4f20796608 100644 --- a/phpBB/includes/db/migration/v305rc1.php +++ b/phpBB/includes/db/migration/v305rc1.php @@ -27,28 +27,29 @@ class phpbb_db_migration_v305rc1 extends phpbb_db_migration function update_data() { - // Captcha config variables - set_config('captcha_gd_wave', 0); - set_config('captcha_gd_3d_noise', 1); - set_config('captcha_gd_fonts', 1); - set_config('confirm_refresh', 1); + $search_indexing_state = $this->config['search_indexing_state']; - // Maximum number of keywords - set_config('max_num_search_keywords', 10); + return array( + array('config.add', array('captcha_gd_wave', 0)), + array('config.add', array('captcha_gd_3d_noise', 1)), + array('config.add', array('captcha_gd_refresh', 1)), + array('config.add', array('confirm_refresh', 1)), + array('config.add', array('max_num_search_keywords', 10)), + array('config.remove', array('search_indexing_state')), + array('config.add', array('search_indexing_state', $search_indexing_state, true)), + array('custom', array(array(&$this, 'hash_old_passwords'))), + array('custom', array(array(&$this, 'update_ichiro_bot'))), + ); + } - // Remove static config var and put it back as dynamic variable - $sql = 'UPDATE ' . CONFIG_TABLE . " - SET is_dynamic = 1 - WHERE config_name = 'search_indexing_state'"; - _sql($sql, $errored, $error_ary); - - // Hash old MD5 passwords + function hash_old_passwords() + { $sql = 'SELECT user_id, user_password - FROM ' . USERS_TABLE . ' + FROM ' . $this->table_prefix . 'users WHERE user_pass_convert = 1'; - $result = _sql($sql, $errored, $error_ary); + $result = $this->sql_query($sql); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { if (strlen($row['user_password']) == 32) { @@ -56,33 +57,36 @@ class phpbb_db_migration_v305rc1 extends phpbb_db_migration 'user_password' => phpbb_hash($row['user_password']), ); - _sql('UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id'], $errored, $error_ary); + $this->sql_query('UPDATE ' . $this->table_prefix . 'users SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id']); } } $db->sql_freeresult($result); + } + function update_ichiro_bot() + { // Adjust bot entry - $sql = 'UPDATE ' . BOTS_TABLE . " + $sql = 'UPDATE ' . $this->table_prefix . "bots SET bot_agent = 'ichiro/' WHERE bot_agent = 'ichiro/2'"; - _sql($sql, $errored, $error_ary); - + $this->sql_query($sql); + } + function remove_duplicate_auth_options() + { // Before we are able to add a unique key to auth_option, we need to remove duplicate entries - - // We get duplicate entries first $sql = 'SELECT auth_option - FROM ' . ACL_OPTIONS_TABLE . ' + FROM ' . $this->table_prefix . 'acl_options GROUP BY auth_option HAVING COUNT(*) >= 2'; - $result = $db->sql_query($sql); + $result = $this->db->sql_query($sql); $auth_options = array(); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { $auth_options[] = $row['auth_option']; } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); // Remove specific auth options if (!empty($auth_options)) @@ -95,52 +99,21 @@ class phpbb_db_migration_v305rc1 extends phpbb_db_migration WHERE auth_option = '" . $db->sql_escape($option) . "' ORDER BY auth_option_id DESC"; // sql_query_limit not possible here, due to bug in postgresql layer - $result = $db->sql_query($sql); + $result = $this->sql_query($sql); // Skip first row, this is our original auth option we want to preserve - $row = $db->sql_fetchrow($result); + $row = $this->db->sql_fetchrow($result); - while ($row = $db->sql_fetchrow($result)) + while ($row = $this->db->sql_fetchrow($result)) { // Ok, remove this auth option... - _sql('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - _sql('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - _sql('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - _sql('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + $this->sql_query('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id']); + $this->sql_query('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id']); + $this->sql_query('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id']); + $this->sql_query('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id']); } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); } } - - // Now make auth_option UNIQUE, by dropping the old index and adding a UNIQUE one. - $changes = array( - 'drop_keys' => array( - ACL_OPTIONS_TABLE => array('auth_option'), - ), - ); - - global $db_tools; - - $statements = $db_tools->perform_schema_changes($changes); - - foreach ($statements as $sql) - { - _sql($sql, $errored, $error_ary); - } - - $changes = array( - 'add_unique_index' => array( - ACL_OPTIONS_TABLE => array( - 'auth_option' => array('auth_option'), - ), - ), - ); - - $statements = $db_tools->perform_schema_changes($changes); - - foreach ($statements as $sql) - { - _sql($sql, $errored, $error_ary); - } } } From ce021710fbe4d594e4f66c3338da8bb2610a0c75 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 8 Jan 2013 22:07:01 -0600 Subject: [PATCH 18/90] [feature/migrations] Rename classes, depends on PHPBB3-9737 --- .../db/migration/{v3011.php => 3_0_1.php} | 4 +- .../db/migration/{v3010rc2.php => 3_0_10.php} | 4 +- .../{v3010rc1.php => 3_0_10_rc1.php} | 4 +- phpBB/includes/db/migration/3_0_10_rc2.php | 25 + phpBB/includes/db/migration/3_0_10_rc3.php | 25 + .../db/migration/{v3010rc3.php => 3_0_11.php} | 4 +- .../{v3011rc1.php => 3_0_11_rc1.php} | 4 +- .../db/migration/{v3011rc2.php => 3_0_11_rc2} | 4 +- .../{v3012rc1.php => 3_0_12_rc1.php} | 4 +- .../migration/{v301rc1.php => 3_0_1_rc1.php} | 2 +- .../db/migration/{v301.php => 3_0_2.php} | 4 +- .../migration/{v302rc1.php => 3_0_2_rc1.php} | 4 +- .../migration/{v302rc2.php => 3_0_2_rc2.php} | 4 +- .../db/migration/{v3010.php => 3_0_3.php} | 4 +- .../migration/{v303rc1.php => 3_0_3_rc1.php} | 4 +- .../db/migration/{v304.php => 3_0_4.php} | 4 +- .../migration/{v304rc1.php => 3_0_4_rc1.php} | 4 +- phpBB/includes/db/migration/3_0_5.php | 25 + .../migration/{v305rc1.php => 3_0_5_rc1.php} | 4 +- .../{305rc1part2.php => 3_0_5_rc1part2.php} | 4 +- .../db/migration/{v302.php => 3_0_6.php} | 4 +- .../migration/{v306rc1.php => 3_0_6_rc1.php} | 4 +- phpBB/includes/db/migration/3_0_6_rc2.php | 25 + .../migration/{v306rc3.php => 3_0_6_rc3.php} | 4 +- phpBB/includes/db/migration/3_0_6_rc4.php | 25 + phpBB/includes/db/migration/3_0_7.php | 25 + phpBB/includes/db/migration/3_0_7_pl1.php | 25 + .../migration/{v307rc1.php => 3_0_7_rc1.php} | 4 +- .../migration/{v307rc2.php => 3_0_7_rc2.php} | 4 +- phpBB/includes/db/migration/3_0_8.php | 25 + .../migration/{v308rc1.php => 3_0_8_rc1.php} | 4 +- phpBB/includes/db/migration/3_0_9.php | 25 + .../migration/{v309rc1.php => 3_0_9_rc1.php} | 4 +- phpBB/includes/db/migration/3_0_9_rc2.php | 25 + phpBB/includes/db/migration/3_0_9_rc3.php | 25 + phpBB/includes/db/migration/3_0_9_rc4.php | 25 + phpBB/includes/db/migration/v303.php | 25 - phpBB/includes/db/migration/v305.php | 25 - phpBB/includes/db/migration/v306.php | 25 - phpBB/includes/db/migration/v306rc2.php | 25 - phpBB/includes/db/migration/v306rc4.php | 25 - phpBB/includes/db/migration/v307.php | 25 - phpBB/includes/db/migration/v307pl1.php | 25 - phpBB/includes/db/migration/v308.php | 25 - phpBB/includes/db/migration/v309.php | 25 - phpBB/includes/db/migration/v309rc2.php | 25 - phpBB/includes/db/migration/v309rc3.php | 25 - phpBB/includes/db/migration/v309rc4.php | 25 - phpBB/includes/db/migrationtools/base.php | 15 + phpBB/includes/db/migrationtools/config.php | 121 + phpBB/includes/db/migrationtools/umil.php | 3037 +++++++++++++++++ 51 files changed, 3520 insertions(+), 347 deletions(-) rename phpBB/includes/db/migration/{v3011.php => 3_0_1.php} (71%) rename phpBB/includes/db/migration/{v3010rc2.php => 3_0_10.php} (71%) rename phpBB/includes/db/migration/{v3010rc1.php => 3_0_10_rc1.php} (76%) create mode 100644 phpBB/includes/db/migration/3_0_10_rc2.php create mode 100644 phpBB/includes/db/migration/3_0_10_rc3.php rename phpBB/includes/db/migration/{v3010rc3.php => 3_0_11.php} (71%) rename phpBB/includes/db/migration/{v3011rc1.php => 3_0_11_rc1.php} (94%) rename phpBB/includes/db/migration/{v3011rc2.php => 3_0_11_rc2} (78%) rename phpBB/includes/db/migration/{v3012rc1.php => 3_0_12_rc1.php} (75%) rename phpBB/includes/db/migration/{v301rc1.php => 3_0_1_rc1.php} (97%) rename phpBB/includes/db/migration/{v301.php => 3_0_2.php} (71%) rename phpBB/includes/db/migration/{v302rc1.php => 3_0_2_rc1.php} (83%) rename phpBB/includes/db/migration/{v302rc2.php => 3_0_2_rc2.php} (91%) rename phpBB/includes/db/migration/{v3010.php => 3_0_3.php} (71%) rename phpBB/includes/db/migration/{v303rc1.php => 3_0_3_rc1.php} (93%) rename phpBB/includes/db/migration/{v304.php => 3_0_4.php} (88%) rename phpBB/includes/db/migration/{v304rc1.php => 3_0_4_rc1.php} (96%) create mode 100644 phpBB/includes/db/migration/3_0_5.php rename phpBB/includes/db/migration/{v305rc1.php => 3_0_5_rc1.php} (97%) rename phpBB/includes/db/migration/{305rc1part2.php => 3_0_5_rc1part2.php} (80%) rename phpBB/includes/db/migration/{v302.php => 3_0_6.php} (71%) rename phpBB/includes/db/migration/{v306rc1.php => 3_0_6_rc1.php} (98%) create mode 100644 phpBB/includes/db/migration/3_0_6_rc2.php rename phpBB/includes/db/migration/{v306rc3.php => 3_0_6_rc3.php} (86%) create mode 100644 phpBB/includes/db/migration/3_0_6_rc4.php create mode 100644 phpBB/includes/db/migration/3_0_7.php create mode 100644 phpBB/includes/db/migration/3_0_7_pl1.php rename phpBB/includes/db/migration/{v307rc1.php => 3_0_7_rc1.php} (92%) rename phpBB/includes/db/migration/{v307rc2.php => 3_0_7_rc2.php} (92%) create mode 100644 phpBB/includes/db/migration/3_0_8.php rename phpBB/includes/db/migration/{v308rc1.php => 3_0_8_rc1.php} (98%) create mode 100644 phpBB/includes/db/migration/3_0_9.php rename phpBB/includes/db/migration/{v309rc1.php => 3_0_9_rc1.php} (96%) create mode 100644 phpBB/includes/db/migration/3_0_9_rc2.php create mode 100644 phpBB/includes/db/migration/3_0_9_rc3.php create mode 100644 phpBB/includes/db/migration/3_0_9_rc4.php delete mode 100644 phpBB/includes/db/migration/v303.php delete mode 100644 phpBB/includes/db/migration/v305.php delete mode 100644 phpBB/includes/db/migration/v306.php delete mode 100644 phpBB/includes/db/migration/v306rc2.php delete mode 100644 phpBB/includes/db/migration/v306rc4.php delete mode 100644 phpBB/includes/db/migration/v307.php delete mode 100644 phpBB/includes/db/migration/v307pl1.php delete mode 100644 phpBB/includes/db/migration/v308.php delete mode 100644 phpBB/includes/db/migration/v309.php delete mode 100644 phpBB/includes/db/migration/v309rc2.php delete mode 100644 phpBB/includes/db/migration/v309rc3.php delete mode 100644 phpBB/includes/db/migration/v309rc4.php create mode 100644 phpBB/includes/db/migrationtools/base.php create mode 100644 phpBB/includes/db/migrationtools/config.php create mode 100644 phpBB/includes/db/migrationtools/umil.php diff --git a/phpBB/includes/db/migration/v3011.php b/phpBB/includes/db/migration/3_0_1.php similarity index 71% rename from phpBB/includes/db/migration/v3011.php rename to phpBB/includes/db/migration/3_0_1.php index 7d506308b1..1cb069a2b1 100644 --- a/phpBB/includes/db/migration/v3011.php +++ b/phpBB/includes/db/migration/3_0_1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_v3011 extends phpbb_db_migration +class phpbb_db_migration_3_0_1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_v3011rc2'); + return array('phpbb_db_migration_3_0_1_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/v3010rc2.php b/phpBB/includes/db/migration/3_0_10.php similarity index 71% rename from phpBB/includes/db/migration/v3010rc2.php rename to phpBB/includes/db/migration/3_0_10.php index 8c1809227c..aae27a08c7 100644 --- a/phpBB/includes/db/migration/v3010rc2.php +++ b/phpBB/includes/db/migration/3_0_10.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_v3010rc2 extends phpbb_db_migration +class phpbb_db_migration_3_0_10 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_v3010rc1'); + return array('phpbb_db_migration_3_0_10_rc3'); } function update_schema() diff --git a/phpBB/includes/db/migration/v3010rc1.php b/phpBB/includes/db/migration/3_0_10_rc1.php similarity index 76% rename from phpBB/includes/db/migration/v3010rc1.php rename to phpBB/includes/db/migration/3_0_10_rc1.php index 847fe7c250..5d65ae15da 100644 --- a/phpBB/includes/db/migration/v3010rc1.php +++ b/phpBB/includes/db/migration/3_0_10_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_v3010rc1 extends phpbb_db_migration +class phpbb_db_migration_3_0_10_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_v309'); + return array('phpbb_db_migration_3_0_9'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_10_rc2.php b/phpBB/includes/db/migration/3_0_10_rc2.php new file mode 100644 index 0000000000..d5dc4caec9 --- /dev/null +++ b/phpBB/includes/db/migration/3_0_10_rc2.php @@ -0,0 +1,25 @@ +db->sql_escape($config_name) . "'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + if (!isset($this->config[$config_name])) + { + $this->config[$config_name] = $row['config_value']; + + if (!$row['is_dynamic']) + { + $this->cache->destroy('config'); + } + } + + return ($return_result) ? $row : true; + } + + // this should never happen, but if it does, we need to remove the config from the array + if (isset($this->config[$config_name])) + { + unset($this->config[$config_name]); + $this->cache->destroy('config'); + } + + return false; + } + + /** + * Config Add + * + * This function allows you to add a config setting. + * + * @param string $config_name The name of the config setting you would like to add + * @param mixed $config_value The value of the config setting + * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. + * + * @return result + */ + function config_add($config_name, $config_value = '', $is_dynamic = false) + { + if ($this->config_exists($config_name)) + { + return $this->umil_end('CONFIG_ALREADY_EXISTS', $config_name); + } + + set_config($config_name, $config_value, $is_dynamic); + } + + /** + * Config Update + * + * This function allows you to update an existing config setting. + * + * @param string $config_name The name of the config setting you would like to update + * @param mixed $config_value The value of the config setting + * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. + * + * @return result + */ + function config_update($config_name, $config_value = '') + { + if (!$this->config_exists($config_name)) + { + return $this->umil_end('CONFIG_NOT_EXIST', $config_name); + } + + set_config($config_name, $config_value); + } + + /** + * Config Remove + * + * This function allows you to remove an existing config setting. + * + * @param string $config_name The name of the config setting you would like to remove + * + * @return result + */ + function config_remove($config_name) + { + if (!$this->config_exists($config_name)) + { + return $this->umil_end('CONFIG_NOT_EXIST', $config_name); + } + + $sql = 'DELETE FROM ' . CONFIG_TABLE . " + WHERE config_name = '" . $this->db->sql_escape($config_name) . "'"; + $this->db->sql_query($sql); + + unset($this->config[$config_name]); + $this->cache->destroy('config'); + } +} \ No newline at end of file diff --git a/phpBB/includes/db/migrationtools/umil.php b/phpBB/includes/db/migrationtools/umil.php new file mode 100644 index 0000000000..ce7b8ff3be --- /dev/null +++ b/phpBB/includes/db/migrationtools/umil.php @@ -0,0 +1,3037 @@ +config_add(array( +* array('config_name', 'config_value'), +* array('config_name1', 'config_value1'), +* array('config_name2', 'config_value2', true), +* array('config_name3', 'config_value3', true), +* ); +*/ + +/** +* UMIL - Unified MOD Installation Library class +* +* Cache Functions +* cache_purge($type = '', $style_id = 0) +* +* Config Functions: +* config_exists($config_name, $return_result = false) +* config_add($config_name, $config_value = '', $is_dynamic = false) +* config_update($config_name, $config_value, $is_dynamic = false) +* config_remove($config_name) +* +* Module Functions +* module_exists($class, $parent, $module) +* module_add($class, $parent = 0, $data = array()) +* module_remove($class, $parent = 0, $module = '') +* +* Permissions/Auth Functions +* permission_exists($auth_option, $global = true) +* permission_add($auth_option, $global = true) +* permission_remove($auth_option, $global = true) +* permission_set($name, $auth_option = array(), $type = 'role', $global = true, $has_permission = true) +* permission_unset($name, $auth_option = array(), $type = 'role', $global = true) +* +* Table Functions +* table_exists($table_name) +* table_add($table_name, $table_data = array()) +* table_remove($table_name) +* +* Table Column Functions +* table_column_exists($table_name, $column_name) +* table_column_add($table_name, $column_name = '', $column_data = array()) +* table_column_update($table_name, $column_name = '', $column_data = array()) +* table_column_remove($table_name, $column_name = '') +* +* Table Key/Index Functions +* table_index_exists($table_name, $index_name) +* table_index_add($table_name, $index_name = '', $column = array()) +* table_index_remove($table_name, $index_name = '') +* +* Table Row Functions (note that these actions are not reversed automatically during uninstallation) +* table_row_insert($table_name, $data = array()) +* table_row_remove($table_name, $data = array()) +* table_row_update($table_name, $data = array(), $new_data = array()) +* +* Version Check Function +* version_check($url, $path, $file) +*/ +class umil +{ + /** + * This will hold the text output for the inputted command (if the mod author would like to display the command that was ran) + * + * @var string + */ + var $command = ''; + + /** + * This will hold the text output for the result of the command. $user->lang['SUCCESS'] if everything worked. + * + * @var string + */ + var $result = ''; + + /** + * Auto run $this->display_results after running a command + */ + var $auto_display_results = false; + + /** + * Stand Alone option (this makes it possible to just use the single umil file and not worry about any language stuff + */ + var $stand_alone = false; + + /** + * Were any new permissions added (used in umil_frontend)? + */ + var $permissions_added = false; + + /** + * Database Object + */ + var $db = false; + + /** + * Database Tools Object + */ + var $db_tools = false; + + /** + * Do we want a custom prefix besides the phpBB table prefix? You *probably* should not change this... + */ + var $table_prefix = false; + + /** + * Constructor + */ + function umil($stand_alone = false, $db = false) + { + // Setup $this->db + if ($db !== false) + { + if (!is_object($db) || !method_exists($db, 'sql_query')) + { + trigger_error('Invalid $db Object'); + } + + $this->db = $db; + } + else + { + global $db; + $this->db = $db; + } + + // Setup $this->db_tools + if (!class_exists('phpbb_db_tools')) + { + global $phpbb_root_path, $phpEx; + include($phpbb_root_path . 'includes/db/db_tools.' . $phpEx); + } + $this->db_tools = new phpbb_db_tools($this->db); + + $this->stand_alone = $stand_alone; + + if (!$stand_alone) + { + global $config, $user, $phpbb_root_path, $phpEx; + + /* Does not have the fall back option to use en/ if the user's language file does not exist, so we will not use it...unless that is changed. + if (method_exists('user', 'set_custom_lang_path')) + { + $user->set_custom_lang_path($phpbb_root_path . 'umil/language/'); + $user->add_lang('umil'); + $user->set_custom_lang_path($phpbb_root_path . 'language/'); + } + else + {*/ + // Include the umil language file. First we check if the language file for the user's language is available, if not we check if the board's default language is available, if not we use the english file. + if (isset($user->data['user_lang']) && file_exists("{$phpbb_root_path}umil/language/{$user->data['user_lang']}/umil.$phpEx")) + { + $path = $user->data['user_lang']; + } + else if (file_exists("{$phpbb_root_path}umil/language/" . basename($config['default_lang']) . "/umil.$phpEx")) + { + $path = basename($config['default_lang']); + } + else if (file_exists("{$phpbb_root_path}umil/language/en/umil.$phpEx")) + { + $path = 'en'; + } + else + { + trigger_error('Language Files Missing.

Please download the latest UMIL (Unified MOD Install Library) from:
phpBB.com/mods/umil', E_USER_ERROR); + } + + $user->add_lang('./../../umil/language/' . $path . '/umil'); + //} + + $user->add_lang(array('acp/common', 'acp/permissions')); + + // Check to see if a newer version is available. + $info = $this->version_check('version.phpbb.com', '/umil', ((defined('PHPBB_QA')) ? 'umil_qa.txt' : 'umil.txt')); + if (is_array($info) && isset($info[0]) && isset($info[1])) + { + if (version_compare(UMIL_VERSION, $info[0], '<')) + { + global $template; + + // Make sure user->setup() has been called + if (empty($user->lang)) + { + $user->setup(); + } + + page_header('', false); + + $user->lang['UPDATE_UMIL'] = (isset($user->lang['UPDATE_UMIL'])) ? $user->lang['UPDATE_UMIL'] : 'This version of UMIL is outdated.

Please download the latest UMIL (Unified MOD Install Library) from: %1$s'; + $template->assign_vars(array( + 'S_BOARD_DISABLED' => true, + 'L_BOARD_DISABLED' => sprintf($user->lang['UPDATE_UMIL'], $info[1]), + )); + } + } + } + } + + /** + * umil_start + * + * A function which runs (almost) every time a function here is ran + */ + function umil_start() + { + global $user; + + // Set up the command. This will get the arguments sent to the function. + $args = func_get_args(); + $this->command = call_user_func_array(array($this, 'get_output_text'), $args); + + $this->result = (isset($user->lang['SUCCESS'])) ? $user->lang['SUCCESS'] : 'SUCCESS'; + $this->db->sql_return_on_error(true); + + //$this->db->sql_transaction('begin'); + } + + /** + * umil_end + * + * A function which runs (almost) every time a function here is ran + */ + function umil_end() + { + global $user; + + // Set up the result. This will get the arguments sent to the function. + $args = func_get_args(); + $result = call_user_func_array(array($this, 'get_output_text'), $args); + $this->result = ($result) ? $result : $this->result; + + if ($this->db->sql_error_triggered) + { + if ($this->result == ((isset($user->lang['SUCCESS'])) ? $user->lang['SUCCESS'] : 'SUCCESS')) + { + $this->result = 'SQL ERROR ' . $this->db->sql_error_returned['message']; + } + else + { + $this->result .= '

SQL ERROR ' . $this->db->sql_error_returned['message']; + } + + //$this->db->sql_transaction('rollback'); + } + else + { + //$this->db->sql_transaction('commit'); + } + + $this->db->sql_return_on_error(false); + + // Auto output if requested. + if ($this->auto_display_results && method_exists($this, 'display_results')) + { + $this->display_results(); + } + + return '' . $this->command . '
' . $this->result; + } + + /** + * Get text for output + * + * Takes the given arguments and prepares them for the UI + * + * First argument sent is used as the language key + * Further arguments (if send) are used on the language key through vsprintf() + * + * @return string Returns the prepared string for output + */ + function get_output_text() + { + global $user; + + // Set up the command. This will get the arguments sent to the function. + $args = func_get_args(); + if (sizeof($args)) + { + $lang_key = array_shift($args); + + if (sizeof($args)) + { + $lang_args = array(); + foreach ($args as $arg) + { + $lang_args[] = (isset($user->lang[$arg])) ? $user->lang[$arg] : $arg; + } + + return @vsprintf(((isset($user->lang[$lang_key])) ? $user->lang[$lang_key] : $lang_key), $lang_args); + } + else + { + return ((isset($user->lang[$lang_key])) ? $user->lang[$lang_key] : $lang_key); + } + } + + return ''; + } + + /** + * Run Actions + * + * Do-It-All function that can do everything required for installing/updating/uninstalling a mod based on an array of actions and the versions. + * + * @param string $action The action. install|update|uninstall + * @param array $versions The array of versions and the actions for each + * @param string $version_config_name The name of the config setting which holds/will hold the currently installed version + * @param string $version_select Added for the UMIL Auto system to allow you to select the version you want to install/update/uninstall to. + */ + function run_actions($action, $versions, $version_config_name, $version_select = '') + { + // We will sort the actions to prevent issues from mod authors incorrectly listing the version numbers + uksort($versions, 'version_compare'); + + // Find the current version to install + $current_version = '0.0.0'; + foreach ($versions as $version => $actions) + { + $current_version = $version; + } + + $db_version = ''; + if ($this->config_exists($version_config_name)) + { + global $config; + $db_version = $config[$version_config_name]; + } + + // Set the action to install from update if nothing is currently installed + if ($action == 'update' && !$db_version) + { + $action = 'install'; + } + + if ($action == 'install' || $action == 'update') + { + $version_installed = $db_version; + foreach ($versions as $version => $version_actions) + { + // If we are updating + if ($db_version && version_compare($version, $db_version, '<=')) + { + continue; + } + + if ($version_select && version_compare($version, $version_select, '>')) + { + break; + } + + foreach ($version_actions as $method => $params) + { + if ($method == 'custom') + { + $this->_call_custom_function($params, $action, $version); + } + else + { + if (method_exists($this, $method)) + { + call_user_func(array($this, $method), $params); + } + } + } + + $version_installed = $version; + } + + // update the version number or add it + if ($this->config_exists($version_config_name)) + { + $this->config_update($version_config_name, $version_installed); + } + else + { + $this->config_add($version_config_name, $version_installed); + } + } + else if ($action == 'uninstall' && $db_version) + { + // reverse version list + $versions = array_reverse($versions); + + foreach ($versions as $version => $version_actions) + { + // Uninstalling and this listed version is newer than installed + if (version_compare($version, $db_version, '>')) + { + continue; + } + + // Version selection stuff + if ($version_select && version_compare($version, $version_select, '<=')) + { + // update the version number + $this->config_update($version_config_name, $version); + break; + } + + $cache_purge = false; + $version_actions = array_reverse($version_actions); + foreach ($version_actions as $method => $params) + { + if ($method == 'custom') + { + $this->_call_custom_function($params, $action, $version); + } + else + { + // This way we always run the cache purge at the end of the version (done for the uninstall because the instructions are reversed, which would cause the cache purge to be run at the beginning if it was meant to run at the end). + if ($method == 'cache_purge') + { + $cache_purge = $params; + continue; + } + + // A few things are not possible for uninstallations update actions and table_row actions + if (strpos($method, 'update') !== false || strpos($method, 'table_insert') !== false || strpos($method, 'table_row_') !== false) + { + continue; + } + + // reverse function call + $method = str_replace(array('add', 'remove', 'temp'), array('temp', 'add', 'remove'), $method); + $method = str_replace(array('set', 'unset', 'temp'), array('temp', 'set', 'unset'), $method); + + if (method_exists($this, $method)) + { + call_user_func(array($this, $method), ((is_array($params) ? array_reverse($params) : $params))); + } + } + } + + if ($cache_purge !== false) + { + $this->cache_purge($cache_purge); + } + } + + if (!$version_select) + { + // Unset the version number + $this->config_remove($version_config_name); + } + } + } + + /** + * Call custom function helper + */ + function _call_custom_function($functions, $action, $version) + { + if (!is_array($functions)) + { + $functions = array($functions); + } + + $return = ''; + + foreach ($functions as $function) + { + if (function_exists($function)) + { + // Must reset before calling the function + $this->umil_start(); + + $returned = call_user_func($function, $action, $version); + if (is_string($returned)) + { + $this->command = $this->get_output_text($returned); + } + else if (is_array($returned) && isset($returned['command'])) + { + if (is_array($returned['command'])) + { + $this->command = call_user_func_array(array($this, 'get_output_text'), $returned['command']); + } + else + { + $this->command = $this->get_output_text($returned['command']); + } + + if (isset($returned['result'])) + { + $this->result = $this->get_output_text($returned['result']); + } + } + else + { + $this->command = $this->get_output_text('UNKNOWN'); + } + + $return .= $this->umil_end() . '
'; + } + } + + return $return; + } + + /** + * Multicall Helper + * + * @param mixed $function Function name to call + * @param mixed $params The parameters array + * + * @return bool True if we have done a multicall ($params is an array), false if not ($params is not an array) + */ + function multicall($function, $params) + { + if (is_array($params) && !empty($params)) + { + foreach ($params as $param) + { + if (!is_array($param)) + { + call_user_func(array($this, $function), $param); + } + else + { + call_user_func_array(array($this, $function), $param); + } + } + return true; + } + + return false; + } + + /** + * Cache Purge + * + * This function is for purging either phpBB3’s data cache, authorization cache, or the styles cache. + * + * @param string $type The type of cache you want purged. Available types: auth, imageset, template, theme. Anything else sent will purge the forum's cache. + * @param int $style_id The id of the item you want purged (if the type selected is imageset/template/theme, 0 for all items in that section) + */ + function cache_purge($type = '', $style_id = 0) + { + global $auth, $cache, $user, $phpbb_root_path, $phpEx; + + // Multicall + if ($this->multicall(__FUNCTION__, $type)) + { + return; + } + + $style_id = (int) $style_id; + $type = (string) $type; // Prevent PHP bug. + + switch ($type) + { + case 'auth' : + $this->umil_start('AUTH_CACHE_PURGE'); + $cache->destroy('_acl_options'); + $auth->acl_clear_prefetch(); + + return $this->umil_end(); + break; + + case 'imageset' : + if ($style_id == 0) + { + $return = array(); + $sql = 'SELECT imageset_id + FROM ' . STYLES_IMAGESET_TABLE; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $return[] = $this->cache_purge('imageset', $row['imageset_id']); + } + $this->db->sql_freeresult($result); + + return implode('

', $return); + } + else + { + $sql = 'SELECT * + FROM ' . STYLES_IMAGESET_TABLE . " + WHERE imageset_id = $style_id"; + $result = $this->db->sql_query($sql); + $imageset_row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$imageset_row) + { + $this->umil_start('IMAGESET_CACHE_PURGE', 'UNKNOWN'); + return $this->umil_end('FAIL'); + } + + $this->umil_start('IMAGESET_CACHE_PURGE', $imageset_row['imageset_name']); + + // The following is from includes/acp/acp_styles.php (edited) + $sql_ary = array(); + + $cfg_data_imageset = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/imageset.cfg"); + + $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . ' + WHERE imageset_id = ' . $style_id; + $result = $this->db->sql_query($sql); + + foreach ($cfg_data_imageset as $image_name => $value) + { + if (strpos($value, '*') !== false) + { + if (substr($value, -1, 1) === '*') + { + list($image_filename, $image_height) = explode('*', $value); + $image_width = 0; + } + else + { + list($image_filename, $image_height, $image_width) = explode('*', $value); + } + } + else + { + $image_filename = $value; + $image_height = $image_width = 0; + } + + if (strpos($image_name, 'img_') === 0 && $image_filename) + { + $image_name = substr($image_name, 4); + + $sql_ary[] = array( + 'image_name' => (string) $image_name, + 'image_filename' => (string) $image_filename, + 'image_height' => (int) $image_height, + 'image_width' => (int) $image_width, + 'imageset_id' => (int) $style_id, + 'image_lang' => '', + ); + } + } + + $sql = 'SELECT lang_dir + FROM ' . LANG_TABLE; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg")) + { + $cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg"); + foreach ($cfg_data_imageset_data as $image_name => $value) + { + if (strpos($value, '*') !== false) + { + if (substr($value, -1, 1) === '*') + { + list($image_filename, $image_height) = explode('*', $value); + $image_width = 0; + } + else + { + list($image_filename, $image_height, $image_width) = explode('*', $value); + } + } + else + { + $image_filename = $value; + $image_height = $image_width = 0; + } + + if (strpos($image_name, 'img_') === 0 && $image_filename) + { + $image_name = substr($image_name, 4); + $sql_ary[] = array( + 'image_name' => (string) $image_name, + 'image_filename' => (string) $image_filename, + 'image_height' => (int) $image_height, + 'image_width' => (int) $image_width, + 'imageset_id' => (int) $style_id, + 'image_lang' => (string) $row['lang_dir'], + ); + } + } + } + } + $this->db->sql_freeresult($result); + + $this->db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary); + + $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE); + + return $this->umil_end(); + } + break; + //case 'imageset' : + + case 'template' : + if ($style_id == 0) + { + $return = array(); + $sql = 'SELECT template_id + FROM ' . STYLES_TEMPLATE_TABLE; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $return[] = $this->cache_purge('template', $row['template_id']); + } + $this->db->sql_freeresult($result); + + return implode('

', $return); + } + else + { + $sql = 'SELECT * + FROM ' . STYLES_TEMPLATE_TABLE . " + WHERE template_id = $style_id"; + $result = $this->db->sql_query($sql); + $template_row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$template_row) + { + $this->umil_start('TEMPLATE_CACHE_PURGE', 'UNKNOWN'); + return $this->umil_end('FAIL'); + } + + $this->umil_start('TEMPLATE_CACHE_PURGE', $template_row['template_name']); + + // The following is from includes/acp/acp_styles.php + if ($template_row['template_storedb'] && file_exists("{$phpbb_root_path}styles/{$template_row['template_path']}/template/")) + { + $filelist = array('' => array()); + + $sql = 'SELECT template_filename, template_mtime + FROM ' . STYLES_TEMPLATE_DATA_TABLE . " + WHERE template_id = $style_id"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { +// if (@filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/" . $row['template_filename']) > $row['template_mtime']) +// { + // get folder info from the filename + if (($slash_pos = strrpos($row['template_filename'], '/')) === false) + { + $filelist[''][] = $row['template_filename']; + } + else + { + $filelist[substr($row['template_filename'], 0, $slash_pos + 1)][] = substr($row['template_filename'], $slash_pos + 1, strlen($row['template_filename']) - $slash_pos - 1); + } +// } + } + $this->db->sql_freeresult($result); + + $includes = array(); + foreach ($filelist as $pathfile => $file_ary) + { + foreach ($file_ary as $file) + { + if (!($fp = @fopen("{$phpbb_root_path}styles/{$template_row['template_path']}$pathfile$file", 'r'))) + { + return $this->umil_end('FILE_COULD_NOT_READ', "{$phpbb_root_path}styles/{$template_row['template_path']}$pathfile$file"); + } + $template_data = fread($fp, filesize("{$phpbb_root_path}styles/{$template_row['template_path']}$pathfile$file")); + fclose($fp); + + if (preg_match_all('##is', $template_data, $matches)) + { + foreach ($matches[1] as $match) + { + $includes[trim($match)][] = $file; + } + } + } + } + + foreach ($filelist as $pathfile => $file_ary) + { + foreach ($file_ary as $file) + { + // Skip index. + if (strpos($file, 'index.') === 0) + { + continue; + } + + // We could do this using extended inserts ... but that could be one + // heck of a lot of data ... + $sql_ary = array( + 'template_id' => (int) $style_id, + 'template_filename' => "$pathfile$file", + 'template_included' => (isset($includes[$file])) ? implode(':', $includes[$file]) . ':' : '', + 'template_mtime' => (int) filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}$pathfile$file"), + 'template_data' => (string) file_get_contents("{$phpbb_root_path}styles/{$template_row['template_path']}$pathfile$file"), + ); + + $sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . ' SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . " + WHERE template_id = $style_id + AND template_filename = '" . $this->db->sql_escape("$pathfile$file") . "'"; + $this->db->sql_query($sql); + } + } + unset($filelist); + } + + // Purge the forum's cache as well. + $cache->purge(); + + return $this->umil_end(); + } + break; + //case 'template' : + + case 'theme' : + if ($style_id == 0) + { + $return = array(); + $sql = 'SELECT theme_id + FROM ' . STYLES_THEME_TABLE; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $return[] = $this->cache_purge('theme', $row['theme_id']); + } + $this->db->sql_freeresult($result); + + return implode('

', $return); + } + else + { + $sql = 'SELECT * + FROM ' . STYLES_THEME_TABLE . " + WHERE theme_id = $style_id"; + $result = $this->db->sql_query($sql); + $theme_row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$theme_row) + { + $this->umil_start('THEME_CACHE_PURGE', 'UNKNOWN'); + return $this->umil_end('FAIL'); + } + + $this->umil_start('THEME_CACHE_PURGE', $theme_row['theme_name']); + + // The following is from includes/acp/acp_styles.php + if ($theme_row['theme_storedb'] && file_exists("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css")) + { + $stylesheet = file_get_contents($phpbb_root_path . 'styles/' . $theme_row['theme_path'] . '/theme/stylesheet.css'); + + // Match CSS imports + $matches = array(); + preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches); + + if (sizeof($matches)) + { + foreach ($matches[0] as $idx => $match) + { + if (!file_exists("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/{$matches[1][$idx]}")) + { + continue; + } + + $content = trim(file_get_contents("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/{$matches[1][$idx]}")); + $stylesheet = str_replace($match, $content, $stylesheet); + } + } + + // adjust paths + $db_theme_data = str_replace('./', 'styles/' . $theme_row['theme_path'] . '/theme/', $stylesheet); + + // Save CSS contents + $sql_ary = array( + 'theme_mtime' => (int) filemtime("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"), + 'theme_data' => $db_theme_data, + ); + + $sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . " + WHERE theme_id = $style_id"; + $this->db->sql_query($sql); + + $cache->destroy('sql', STYLES_THEME_TABLE); + } + + return $this->umil_end(); + } + break; + //case 'theme' : + + default: + $this->umil_start('CACHE_PURGE'); + $cache->purge(); + + return $this->umil_end(); + break; + } + } + + /** + * Config Exists + * + * This function is to check to see if a config variable exists or if it does not. + * + * @param string $config_name The name of the config setting you wish to check for. + * @param bool $return_result - return the config value/default if true : default false. + * + * @return bool true/false if config exists + */ + function config_exists($config_name, $return_result = false) + { + global $config, $cache; + + $sql = 'SELECT * + FROM ' . CONFIG_TABLE . " + WHERE config_name = '" . $this->db->sql_escape($config_name) . "'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + if (!isset($config[$config_name])) + { + $config[$config_name] = $row['config_value']; + + if (!$row['is_dynamic']) + { + $cache->destroy('config'); + } + } + + return ($return_result) ? $row : true; + } + + // this should never happen, but if it does, we need to remove the config from the array + if (isset($config[$config_name])) + { + unset($config[$config_name]); + $cache->destroy('config'); + } + + return false; + } + + /** + * Config Add + * + * This function allows you to add a config setting. + * + * @param string $config_name The name of the config setting you would like to add + * @param mixed $config_value The value of the config setting + * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. + * + * @return result + */ + function config_add($config_name, $config_value = '', $is_dynamic = false) + { + // Multicall + if ($this->multicall(__FUNCTION__, $config_name)) + { + return; + } + + $this->umil_start('CONFIG_ADD', $config_name); + + if ($this->config_exists($config_name)) + { + return $this->umil_end('CONFIG_ALREADY_EXISTS', $config_name); + } + + set_config($config_name, $config_value, $is_dynamic); + + return $this->umil_end(); + } + + /** + * Config Update + * + * This function allows you to update an existing config setting. + * + * @param string $config_name The name of the config setting you would like to update + * @param mixed $config_value The value of the config setting + * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. + * + * @return result + */ + function config_update($config_name, $config_value = '', $is_dynamic = false) + { + // Multicall + if ($this->multicall(__FUNCTION__, $config_name)) + { + return; + } + + $this->umil_start('CONFIG_UPDATE', $config_name); + + if (!$this->config_exists($config_name)) + { + return $this->umil_end('CONFIG_NOT_EXIST', $config_name); + } + + set_config($config_name, $config_value, $is_dynamic); + + return $this->umil_end(); + } + + /** + * Config Remove + * + * This function allows you to remove an existing config setting. + * + * @param string $config_name The name of the config setting you would like to remove + * + * @return result + */ + function config_remove($config_name) + { + global $cache, $config; + + // Multicall + if ($this->multicall(__FUNCTION__, $config_name)) + { + return; + } + + $this->umil_start('CONFIG_REMOVE', $config_name); + + if (!$this->config_exists($config_name)) + { + return $this->umil_end('CONFIG_NOT_EXIST', $config_name); + } + + $sql = 'DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = '" . $this->db->sql_escape($config_name) . "'"; + $this->db->sql_query($sql); + + unset($config[$config_name]); + $cache->destroy('config'); + + return $this->umil_end(); + } + + /** + * Module Exists + * + * Check if a module exists + * + * @param string $class The module class(acp|mcp|ucp) + * @param int|string|bool $parent The parent module_id|module_langname (0 for no parent). 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 + */ + function module_exists($class, $parent, $module) + { + // the main root directory should return true + if (!$module) + { + return true; + } + + $class = $this->db->sql_escape($class); + $module = $this->db->sql_escape($module); + + $parent_sql = ''; + if ($parent !== false) + { + // Allows '' to be sent as 0 + $parent = (!$parent) ? 0 : $parent; + + if (!is_numeric($parent)) + { + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($parent) . "' + AND module_class = '$class'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row) + { + return false; + } + + $parent_sql = 'AND parent_id = ' . (int) $row['module_id']; + } + else + { + $parent_sql = 'AND parent_id = ' . (int) $parent; + } + } + + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_class = '$class' + $parent_sql + AND " . ((is_numeric($module)) ? 'module_id = ' . (int) $module : "module_langname = '$module'"); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + return true; + } + + return false; + } + + /** + * Module Add + * + * Add a new module + * + * @param string $class The module class(acp|mcp|ucp) + * @param int|string $parent The parent module_id|module_langname (0 for no parent) + * @param array $data an array of the data on the new module. This can be setup in two different ways. + * 1. The "manual" way. For inserting a category or one at a time. It will be merged with the base array shown a bit below, + * but at the least requires 'module_langname' to be sent, and, if you want to create a module (instead of just a category) you must send module_basename and module_mode. + * array( + * 'module_enabled' => 1, + * 'module_display' => 1, + * 'module_basename' => '', + * 'module_class' => $class, + * 'parent_id' => (int) $parent, + * 'module_langname' => '', + * 'module_mode' => '', + * 'module_auth' => '', + * ) + * 2. The "automatic" way. For inserting multiple at a time based on the specs in the info file for the module(s). For this to work the modules must be correctly setup in the info file. + * An example follows (this would insert the settings, log, and flag modes from the includes/acp/info/acp_asacp.php file): + * array( + * 'module_basename' => 'asacp', + * 'modes' => array('settings', 'log', 'flag'), + * ) + * Optionally you may not send 'modes' and it will insert all of the modules in that info file. + * @param string|bool $include_path If you would like to use a custom include path, specify that here + */ + function module_add($class, $parent = 0, $data = array(), $include_path = false) + { + global $cache, $user, $phpbb_root_path, $phpEx; + + // Multicall + if ($this->multicall(__FUNCTION__, $class)) + { + return; + } + + // Prevent stupid things like trying to add a module with no name or any data on it + if (empty($data)) + { + $this->umil_start('MODULE_ADD', $class, 'UNKNOWN'); + return $this->umil_end('FAIL'); + } + + // Allows '' to be sent as 0 + $parent = (!$parent) ? 0 : $parent; + + // allow sending the name as a string in $data to create a category + if (!is_array($data)) + { + $data = array('module_langname' => $data); + } + + if (!isset($data['module_langname'])) + { + // The "automatic" way + $basename = (isset($data['module_basename'])) ? $data['module_basename'] : ''; + $basename = str_replace(array('/', '\\'), '', $basename); + $class = str_replace(array('/', '\\'), '', $class); + $info_file = "$class/info/{$class}_$basename.$phpEx"; + + // The manual and automatic ways both failed... + if (!file_exists((($include_path === false) ? $phpbb_root_path . 'includes/' : $include_path) . $info_file)) + { + $this->umil_start('MODULE_ADD', $class, $info_file); + return $this->umil_end('FAIL'); + } + + $classname = "{$class}_{$basename}_info"; + + if (!class_exists($classname)) + { + include((($include_path === false) ? $phpbb_root_path . 'includes/' : $include_path) . $info_file); + } + + $info = new $classname; + $module = $info->module(); + unset($info); + + $result = ''; + foreach ($module['modes'] as $mode => $module_info) + { + if (!isset($data['modes']) || in_array($mode, $data['modes'])) + { + $new_module = array( + 'module_basename' => $basename, + 'module_langname' => $module_info['title'], + 'module_mode' => $mode, + 'module_auth' => $module_info['auth'], + 'module_display' => (isset($module_info['display'])) ? $module_info['display'] : true, + 'before' => (isset($module_info['before'])) ? $module_info['before'] : false, + 'after' => (isset($module_info['after'])) ? $module_info['after'] : false, + ); + + // Run the "manual" way with the data we've collected. + $result .= ((isset($data['spacer'])) ? $data['spacer'] : '
') . $this->module_add($class, $parent, $new_module); + } + } + + return $result; + } + + // The "manual" way + $this->umil_start('MODULE_ADD', $class, ((isset($user->lang[$data['module_langname']])) ? $user->lang[$data['module_langname']] : $data['module_langname'])); + add_log('admin', 'LOG_MODULE_ADD', ((isset($user->lang[$data['module_langname']])) ? $user->lang[$data['module_langname']] : $data['module_langname'])); + + $class = $this->db->sql_escape($class); + + if (!is_numeric($parent)) + { + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($parent) . "' + AND module_class = '$class'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row) + { + return $this->umil_end('PARENT_NOT_EXIST'); + } + + $parent = $data['parent_id'] = $row['module_id']; + } + else if (!$this->module_exists($class, false, $parent)) + { + return $this->umil_end('PARENT_NOT_EXIST'); + } + + if ($this->module_exists($class, $parent, $data['module_langname'])) + { + return $this->umil_end('MODULE_ALREADY_EXIST'); + } + + if (!class_exists('acp_modules')) + { + include($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx); + $user->add_lang('acp/modules'); + } + $acp_modules = new acp_modules(); + + $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'] : '', + ); + $result = $acp_modules->update_module_data($module_data, true); + + // update_module_data can either return a string or an empty array... + if (is_string($result)) + { + // Error + $this->result = $this->get_output_text($result); + } + else + { + // Success + + // Move the module if requested above/below an existing one + if (isset($data['before']) && $data['before']) + { + $sql = 'SELECT left_id FROM ' . MODULES_TABLE . ' + WHERE module_class = \'' . $class . '\' + AND parent_id = ' . (int) $parent . ' + AND module_langname = \'' . $this->db->sql_escape($data['before']) . '\''; + $this->db->sql_query($sql); + $to_left = $this->db->sql_fetchfield('left_id'); + + $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 + WHERE module_class = '$class' + AND left_id >= $to_left + AND left_id < {$module_data['left_id']}"; + $this->db->sql_query($sql); + + $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = $to_left, right_id = " . ($to_left + 1) . " + WHERE module_class = '$class' + AND module_id = {$module_data['module_id']}"; + $this->db->sql_query($sql); + } + else if (isset($data['after']) && $data['after']) + { + $sql = 'SELECT right_id FROM ' . MODULES_TABLE . ' + WHERE module_class = \'' . $class . '\' + AND parent_id = ' . (int) $parent . ' + AND module_langname = \'' . $this->db->sql_escape($data['after']) . '\''; + $this->db->sql_query($sql); + $to_right = $this->db->sql_fetchfield('right_id'); + + $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 + WHERE module_class = '$class' + AND left_id >= $to_right + AND left_id < {$module_data['left_id']}"; + $this->db->sql_query($sql); + + $sql = 'UPDATE ' . MODULES_TABLE . ' SET left_id = ' . ($to_right + 1) . ', right_id = ' . ($to_right + 2) . " + WHERE module_class = '$class' + AND module_id = {$module_data['module_id']}"; + $this->db->sql_query($sql); + } + } + + // Clear the Modules Cache + $cache->destroy("_modules_$class"); + + return $this->umil_end(); + } + + /** + * Module Remove + * + * Remove a module + * + * @param string $class The module class(acp|mcp|ucp) + * @param int|string|bool $parent The parent module_id|module_langname (0 for no parent). Use false to ignore the parent check and check class wide. + * @param int|string $module The module id|module_langname + * @param string|bool $include_path If you would like to use a custom include path, specify that here + */ + function module_remove($class, $parent = 0, $module = '', $include_path = false) + { + global $cache, $user, $phpbb_root_path, $phpEx; + + // Multicall + if ($this->multicall(__FUNCTION__, $class)) + { + return; + } + + // Imitation of module_add's "automatic" and "manual" method so the uninstaller works from the same set of instructions for umil_auto + if (is_array($module)) + { + if (isset($module['module_langname'])) + { + // Manual Method + return $this->module_remove($class, $parent, $module['module_langname'], $include_path); + } + + // Failed. + if (!isset($module['module_basename'])) + { + $this->umil_start('MODULE_REMOVE', $class, 'UNKNOWN'); + return $this->umil_end('FAIL'); + } + + // Automatic method + $basename = str_replace(array('/', '\\'), '', $module['module_basename']); + $class = str_replace(array('/', '\\'), '', $class); + $info_file = "$class/info/{$class}_$basename.$phpEx"; + + if (!file_exists((($include_path === false) ? $phpbb_root_path . 'includes/' : $include_path) . $info_file)) + { + $this->umil_start('MODULE_REMOVE', $class, $info_file); + return $this->umil_end('FAIL'); + } + + $classname = "{$class}_{$basename}_info"; + + if (!class_exists($classname)) + { + include((($include_path === false) ? $phpbb_root_path . 'includes/' : $include_path) . $info_file); + } + + $info = new $classname; + $module_info = $info->module(); + unset($info); + + $result = ''; + foreach ($module_info['modes'] as $mode => $info) + { + if (!isset($module['modes']) || in_array($mode, $module['modes'])) + { + $result .= $this->module_remove($class, $parent, $info['title']) . '
'; + } + } + return $result; + } + else + { + $class = $this->db->sql_escape($class); + + if (!$this->module_exists($class, $parent, $module)) + { + $this->umil_start('MODULE_REMOVE', $class, ((isset($user->lang[$module])) ? $user->lang[$module] : $module)); + return $this->umil_end('MODULE_NOT_EXIST'); + } + + $parent_sql = ''; + if ($parent !== false) + { + // Allows '' to be sent as 0 + $parent = (!$parent) ? 0 : $parent; + + if (!is_numeric($parent)) + { + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($parent) . "' + AND module_class = '$class'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + // we know it exists from the module_exists check + $parent_sql = 'AND parent_id = ' . (int) $row['module_id']; + } + else + { + $parent_sql = 'AND parent_id = ' . (int) $parent; + } + } + + $module_ids = array(); + if (!is_numeric($module)) + { + $module = $this->db->sql_escape($module); + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '$module' + AND module_class = '$class' + $parent_sql"; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $module_ids[] = (int) $row['module_id']; + } + $this->db->sql_freeresult($result); + + $module_name = $module; + } + else + { + $module = (int) $module; + $sql = 'SELECT module_langname FROM ' . MODULES_TABLE . " + WHERE module_id = $module + AND module_class = '$class' + $parent_sql"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $module_name = $row['module_langname']; + $module_ids[] = $module; + } + + $this->umil_start('MODULE_REMOVE', $class, ((isset($user->lang[$module_name])) ? $user->lang[$module_name] : $module_name)); + add_log('admin', 'LOG_MODULE_REMOVED', ((isset($user->lang[$module_name])) ? $user->lang[$module_name] : $module_name)); + + if (!class_exists('acp_modules')) + { + include($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx); + $user->add_lang('acp/modules'); + } + $acp_modules = new acp_modules(); + $acp_modules->module_class = $class; + + foreach ($module_ids as $module_id) + { + $result = $acp_modules->delete_module($module_id); + if (!empty($result)) + { + if ($this->result == ((isset($user->lang['SUCCESS'])) ? $user->lang['SUCCESS'] : 'SUCCESS')) + { + $this->result = implode('
', $result); + } + else + { + $this->result .= '
' . implode('
', $result); + } + } + } + + $cache->destroy("_modules_$class"); + + return $this->umil_end(); + } + } + + /** + * Permission Exists + * + * Check if a permission (auth) setting exists + * + * @param string $auth_option The name of the permission (auth) option + * @param bool $global True for checking a global permission setting, False for a local permission setting + * + * @return bool true if it exists, false if not + */ + function permission_exists($auth_option, $global = true) + { + if ($global) + { + $type_sql = ' AND is_global = 1'; + } + else + { + $type_sql = ' AND is_local = 1'; + } + + $sql = 'SELECT auth_option_id + FROM ' . ACL_OPTIONS_TABLE . " + WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" + . $type_sql; + $result = $this->db->sql_query($sql); + + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + return true; + } + + return false; + } + + /** + * Permission Add + * + * Add a permission (auth) option + * + * @param string $auth_option The name of the permission (auth) option + * @param bool $global True for checking a global permission setting, False for a local permission setting + * + * @return result + */ + function permission_add($auth_option, $global = true) + { + // Multicall + if ($this->multicall(__FUNCTION__, $auth_option)) + { + return; + } + + $this->umil_start('PERMISSION_ADD', $auth_option); + + if ($this->permission_exists($auth_option, $global)) + { + return $this->umil_end('PERMISSION_ALREADY_EXISTS', $auth_option); + } + + // We've added permissions, so set to true to notify the user. + $this->permissions_added = true; + + if (!class_exists('auth_admin')) + { + global $phpbb_root_path, $phpEx; + + include($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + } + $auth_admin = new auth_admin(); + + // We have to add a check to see if the !$global (if global, local, and if local, global) permission already exists. If it does, acl_add_option currently has a bug which would break the ACL system, so we are having a work-around here. + if ($this->permission_exists($auth_option, !$global)) + { + $sql_ary = array( + 'is_global' => 1, + 'is_local' => 1, + ); + $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' + SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE auth_option = \'' . $this->db->sql_escape($auth_option) . "'"; + $this->db->sql_query($sql); + } + else + { + if ($global) + { + $auth_admin->acl_add_option(array('global' => array($auth_option))); + } + else + { + $auth_admin->acl_add_option(array('local' => array($auth_option))); + } + } + + return $this->umil_end(); + } + + /** + * Permission Remove + * + * Remove a permission (auth) option + * + * @param string $auth_option The name of the permission (auth) option + * @param bool $global True for checking a global permission setting, False for a local permission setting + * + * @return result + */ + function permission_remove($auth_option, $global = true) + { + global $auth, $cache; + + // Multicall + if ($this->multicall(__FUNCTION__, $auth_option)) + { + return; + } + + $this->umil_start('PERMISSION_REMOVE', $auth_option); + + if (!$this->permission_exists($auth_option, $global)) + { + return $this->umil_end('PERMISSION_NOT_EXIST', $auth_option); + } + + if ($global) + { + $type_sql = ' AND is_global = 1'; + } + else + { + $type_sql = ' AND is_local = 1'; + } + $sql = 'SELECT auth_option_id, is_global, is_local FROM ' . ACL_OPTIONS_TABLE . " + WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" . + $type_sql; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $id = $row['auth_option_id']; + + // If it is a local and global permission, do not remove the row! :P + if ($row['is_global'] && $row['is_local']) + { + $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' + SET ' . (($global) ? 'is_global = 0' : 'is_local = 0') . ' + WHERE auth_option_id = ' . $id; + $this->db->sql_query($sql); + } + else + { + // Delete time + $this->db->sql_query('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $id); + $this->db->sql_query('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $id); + $this->db->sql_query('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $id); + $this->db->sql_query('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $id); + } + + // Purge the auth cache + $cache->destroy('_acl_options'); + $auth->acl_clear_prefetch(); + + return $this->umil_end(); + } + + /** + * Add a new permission role + * + * @param string $role_name The new role name + * @param sting $role_type The type (u_, m_, a_) + */ + function permission_role_add($role_name, $role_type = '', $role_description = '') + { + // Multicall + if ($this->multicall(__FUNCTION__, $role_name)) + { + return; + } + + $this->umil_start('PERMISSION_ROLE_ADD', $role_name); + + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($role_name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if ($role_id) + { + return $this->umil_end('ROLE_ALREADY_EXISTS', $old_role_name); + } + + $sql = 'SELECT MAX(role_order) AS max FROM ' . ACL_ROLES_TABLE . ' + WHERE role_type = \'' . $this->db->sql_escape($role_type) . '\''; + $this->db->sql_query($sql); + $role_order = $this->db->sql_fetchfield('max'); + $role_order = (!$role_order) ? 1 : $role_order + 1; + + $sql_ary = array( + 'role_name' => $role_name, + 'role_description' => $role_description, + 'role_type' => $role_type, + 'role_order' => $role_order, + ); + + $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); + $this->db->sql_query($sql); + + return $this->umil_end(); + } + + /** + * Update the name on a permission role + * + * @param string $old_role_name The old role name + * @param string $new_role_name The new role name + */ + function permission_role_update($old_role_name, $new_role_name = '') + { + // Multicall + if ($this->multicall(__FUNCTION__, $role_name)) + { + return; + } + + $this->umil_start('PERMISSION_ROLE_UPDATE', $old_role_name); + + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($old_role_name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + return $this->umil_end('ROLE_NOT_EXIST', $old_role_name); + } + + $sql = 'UPDATE ' . ACL_ROLES_TABLE . ' + SET role_name = \'' . $this->db->sql_escape($new_role_name) . '\' + WHERE role_name = \'' . $this->db->sql_escape($old_role_name) . '\''; + $this->db->sql_query($sql); + + return $this->umil_end(); + } + + /** + * Remove a permission role + * + * @param string $role_name The role name to remove + */ + function permission_role_remove($role_name) + { + global $auth; + + // Multicall + if ($this->multicall(__FUNCTION__, $role_name)) + { + return; + } + + $this->umil_start('PERMISSION_ROLE_REMOVE', $role_name); + + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($role_name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + return $this->umil_end('ROLE_NOT_EXIST', $role_name); + } + + $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + + $sql = 'DELETE FROM ' . ACL_ROLES_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + + $auth->acl_clear_prefetch(); + + return $this->umil_end(); + } + + /** + * Permission Set + * + * Allows you to set permissions for a certain group/role + * + * @param string $name The name of the role/group + * @param string|array $auth_option The auth_option or array of auth_options you would like to set + * @param string $type The type (role|group) + * @param bool $has_permission True if you want to give them permission, false if you want to deny them permission + */ + function permission_set($name, $auth_option = array(), $type = 'role', $has_permission = true) + { + global $auth; + + // Multicall + if ($this->multicall(__FUNCTION__, $name)) + { + return; + } + + if (!is_array($auth_option)) + { + $auth_option = array($auth_option); + } + + $new_auth = array(); + $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $new_auth[] = $row['auth_option_id']; + } + $this->db->sql_freeresult($result); + + if (!sizeof($new_auth)) + { + return false; + } + + $current_auth = array(); + + $type = (string) $type; // Prevent PHP bug. + + switch ($type) + { + case 'role' : + $this->umil_start('PERMISSION_SET_ROLE', $name); + + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + return $this->umil_end('ROLE_NOT_EXIST'); + } + + $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_ROLES_DATA_TABLE . ' + WHERE role_id = ' . $role_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $current_auth[$row['auth_option_id']] = $row['auth_setting']; + } + $this->db->sql_freeresult($result); + break; + + case 'group' : + $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' WHERE group_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $group_id = $this->db->sql_fetchfield('group_id'); + + if (!$group_id) + { + $this->umil_start('PERMISSION_SET_GROUP', $name); + return $this->umil_end('GROUP_NOT_EXIST'); + } + + // If the group has a role set for them we will add the requested permissions to that role. + $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id . ' + AND auth_role_id <> 0 + AND forum_id = 0'; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('auth_role_id'); + if ($role_id) + { + $sql = 'SELECT role_name FROM ' . ACL_ROLES_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + $role_name = $this->db->sql_fetchfield('role_name'); + + return $this->permission_set($role_name, $auth_option, 'role', $has_permission); + } + + $this->umil_start('PERMISSION_SET_GROUP', $name); + + $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $current_auth[$row['auth_option_id']] = $row['auth_setting']; + } + $this->db->sql_freeresult($result); + break; + } + + $sql_ary = array(); + switch ($type) + { + case 'role' : + foreach ($new_auth as $auth_option_id) + { + if (!isset($current_auth[$auth_option_id])) + { + $sql_ary[] = array( + 'role_id' => $role_id, + 'auth_option_id' => $auth_option_id, + 'auth_setting' => $has_permission, + ); + } + } + + $this->db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); + break; + + case 'group' : + foreach ($new_auth as $auth_option_id) + { + if (!isset($current_auth[$auth_option_id])) + { + $sql_ary[] = array( + 'group_id' => $group_id, + 'auth_option_id' => $auth_option_id, + 'auth_setting' => $has_permission, + ); + } + } + + $this->db->sql_multi_insert(ACL_GROUPS_TABLE, $sql_ary); + break; + } + + $auth->acl_clear_prefetch(); + + return $this->umil_end(); + } + + /** + * Permission Unset + * + * Allows you to unset (remove) permissions for a certain group/role + * + * @param string $name The name of the role/group + * @param string|array $auth_option The auth_option or array of auth_options you would like to set + * @param string $type The type (role|group) + */ + function permission_unset($name, $auth_option = array(), $type = 'role') + { + global $auth; + + // Multicall + if ($this->multicall(__FUNCTION__, $name)) + { + return; + } + + if (!is_array($auth_option)) + { + $auth_option = array($auth_option); + } + + $to_remove = array(); + $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $to_remove[] = $row['auth_option_id']; + } + $this->db->sql_freeresult($result); + + if (!sizeof($to_remove)) + { + return false; + } + + $type = (string) $type; // Prevent PHP bug. + + switch ($type) + { + case 'role' : + $this->umil_start('PERMISSION_UNSET_ROLE', $name); + + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + return $this->umil_end('ROLE_NOT_EXIST'); + } + + $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); + $this->db->sql_query($sql); + break; + + case 'group' : + $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' WHERE group_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $group_id = $this->db->sql_fetchfield('group_id'); + + if (!$group_id) + { + $this->umil_start('PERMISSION_UNSET_GROUP', $name); + return $this->umil_end('GROUP_NOT_EXIST'); + } + + // If the group has a role set for them we will remove the requested permissions from that role. + $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id . ' + AND auth_role_id <> 0'; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('auth_role_id'); + if ($role_id) + { + $sql = 'SELECT role_name FROM ' . ACL_ROLES_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + $role_name = $this->db->sql_fetchfield('role_name'); + + return $this->permission_unset($role_name, $auth_option, 'role'); + } + + $this->umil_start('PERMISSION_UNSET_GROUP', $name); + + $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); + $this->db->sql_query($sql); + break; + } + + $auth->acl_clear_prefetch(); + + return $this->umil_end(); + } + + /** + * Table Exists + * + * Check if a table exists in the DB or not + * + * @param string $table_name The table name to check for + * + * @return bool true if the table exists, false if not + */ + function table_exists($table_name) + { + $this->get_table_name($table_name); + + // Use sql_table_exists if available + if (method_exists($this->db_tools, 'sql_table_exists')) + { + $roe = $this->db->return_on_error; + $result = $this->db_tools->sql_table_exists($table_name); + + // db_tools::sql_table_exists resets the return_on_error to false always after completing, so we must make sure we set it to true again if it was before + if ($roe) + { + $this->db->sql_return_on_error(true); + } + + return $result; + } + + if (!function_exists('get_tables')) + { + global $phpbb_root_path, $phpEx; + include($phpbb_root_path . 'includes/functions_install.' . $phpEx); + } + + $tables = get_tables($this->db); + + if (in_array($table_name, $tables)) + { + return true; + } + else + { + return false; + } + } + + /** + * Table Add + * + * This only supports input from the array format of db_tools or create_schema_files. + */ + function table_add($table_name, $table_data = array()) + { + global $dbms, $user; + + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + /** + * $table_data can be empty when uninstalling a mod and table_remove was used, but no 2rd argument was given. + * In that case we'll assume that it was a column previously added by the mod (if not the author should specify a 2rd argument) and skip this to prevent an error + */ + if (empty($table_data)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_ADD', $table_name); + + if ($this->table_exists($table_name)) + { + return $this->umil_end('TABLE_ALREADY_EXISTS', $table_name); + } + + if (!is_array($table_data)) + { + return $this->umil_end('NO_TABLE_DATA'); + } + + if (!function_exists('get_available_dbms')) + { + global $phpbb_root_path, $phpEx; + include("{$phpbb_root_path}includes/functions_install.$phpEx"); + } + + /* + * This function has had numerous problems and is currently broken, so until phpBB uses it I will not be anymore + if (method_exists($this->db_tools, 'sql_create_table')) + { + // Added in 3.0.5 + $this->db_tools->sql_create_table($table_name, $table_data); + } + else + {*/ + $available_dbms = get_available_dbms($dbms); + + $sql_query = $this->create_table_sql($table_name, $table_data); + $sql_query = split_sql_file($sql_query, $available_dbms[$dbms]['DELIM']); + + foreach ($sql_query as $sql) + { + $this->db->sql_query($sql); + } + //} + + return $this->umil_end(); + } + + /** + * Table Remove + * + * Delete/Drop a DB table + */ + function table_remove($table_name) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_REMOVE', $table_name); + + if (!$this->table_exists($table_name)) + { + return $this->umil_end('TABLE_NOT_EXIST', $table_name); + } + + if (method_exists($this->db_tools, 'sql_table_drop')) + { + // Added in 3.0.5 + $this->db_tools->sql_table_drop($table_name); + } + else + { + $this->db->sql_query('DROP TABLE ' . $table_name); + } + + return $this->umil_end(); + } + + /** + * Table Column Exists + * + * Check to see if a column exists in a table + */ + function table_column_exists($table_name, $column_name) + { + $this->get_table_name($table_name); + + return $this->db_tools->sql_column_exists($table_name, $column_name); + } + + /** + * Table Column Add + * + * Add a new column to a table. + */ + function table_column_add($table_name, $column_name = '', $column_data = array()) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + /** + * $column_data can be empty when uninstalling a mod and table_column_remove was used, but no 3rd argument was given. + * In that case we'll assume that it was a column previously added by the mod (if not the author should specify a 3rd argument) and skip this to prevent an error + */ + if (empty($column_data)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_COLUMN_ADD', $table_name, $column_name); + + if ($this->table_column_exists($table_name, $column_name)) + { + return $this->umil_end('TABLE_COLUMN_ALREADY_EXISTS', $table_name, $column_name); + } + + $this->db_tools->sql_column_add($table_name, $column_name, $column_data); + + return $this->umil_end(); + } + + /** + * Table Column Update + * + * Alter/Update a column in a table. You can not change a column name with this. + */ + function table_column_update($table_name, $column_name = '', $column_data = array()) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_COLUMN_UPDATE', $table_name, $column_name); + + if (!$this->table_column_exists($table_name, $column_name)) + { + return $this->umil_end('TABLE_COLUMN_NOT_EXIST', $table_name, $column_name); + } + + $this->db_tools->sql_column_change($table_name, $column_name, $column_data); + + return $this->umil_end(); + } + + /** + * Table Column Remove + * + * Remove a column from a table + */ + function table_column_remove($table_name, $column_name = '') + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_COLUMN_REMOVE', $table_name, $column_name); + + if (!$this->table_column_exists($table_name, $column_name)) + { + return $this->umil_end('TABLE_COLUMN_NOT_EXIST', $table_name, $column_name); + } + + $this->db_tools->sql_column_remove($table_name, $column_name); + + return $this->umil_end(); + } + + /** + * Table Index Exists + * + * Check if a table key/index exists on a table (can not check primary or unique) + */ + function table_index_exists($table_name, $index_name) + { + $this->get_table_name($table_name); + + $indexes = $this->db_tools->sql_list_index($table_name); + + if (in_array($index_name, $indexes)) + { + return true; + } + + return false; + } + + /** + * Table Index Add + * + * Add a new key/index to a table + */ + function table_index_add($table_name, $index_name = '', $column = array()) + { + global $config; + + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + // Let them skip the column field and just use the index name in that case as the column as well + if (empty($column)) + { + $column = array($index_name); + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_KEY_ADD', $table_name, $index_name); + + if ($this->table_index_exists($table_name, $index_name)) + { + return $this->umil_end('TABLE_KEY_ALREADY_EXIST', $table_name, $index_name); + } + + if (!is_array($column)) + { + $column = array($column); + } + + // remove index length if we are before 3.0.8 + // the feature (required for some types when using MySQL4) + // was added in that release (ticket PHPBB3-8944) + if (version_compare($config['version'], '3.0.7-pl1', '<=')) + { + $column = preg_replace('#:.*$#', '', $column); + } + + $this->db_tools->sql_create_index($table_name, $index_name, $column); + + return $this->umil_end(); + } + + /** + * Table Index Remove + * + * Remove a key/index from a table + */ + function table_index_remove($table_name, $index_name = '') + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_KEY_REMOVE', $table_name, $index_name); + + if (!$this->table_index_exists($table_name, $index_name)) + { + return $this->umil_end('TABLE_KEY_NOT_EXIST', $table_name, $index_name); + } + + $this->db_tools->sql_index_drop($table_name, $index_name); + + return $this->umil_end(); + } + + // Ignore, function was renamed to table_row_insert and keeping for backwards compatibility + function table_insert($table_name, $data = array()) { $this->table_row_insert($table_name, $data); } + + /** + * Table Insert + * + * Insert data into a table + */ + function table_row_insert($table_name, $data = array()) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_ROW_INSERT_DATA', $table_name); + + if (!$this->table_exists($table_name)) + { + return $this->umil_end('TABLE_NOT_EXIST', $table_name); + } + + $this->db->sql_multi_insert($table_name, $data); + + return $this->umil_end(); + } + + /** + * Table Row Update + * + * Update a row in a table + * + * $data should be an array with the column names as keys and values as the items to check for each column. Example: + * array('user_id' => 123, 'user_name' => 'test user') would become: + * WHERE user_id = 123 AND user_name = 'test user' + * + * $new_data is the new data it will be updated to (same format as you'd enter into $db->sql_build_array('UPDATE' ). + */ + function table_row_update($table_name, $data = array(), $new_data = array()) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + if (!sizeof($data)) + { + return $this->umil_end('FAIL'); + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_ROW_UPDATE_DATA', $table_name); + + if (!$this->table_exists($table_name)) + { + return $this->umil_end('TABLE_NOT_EXIST', $table_name); + } + + $sql = 'UPDATE ' . $table_name . ' + SET ' . $this->db->sql_build_array('UPDATE', $new_data) . ' + WHERE ' . $this->db->sql_build_array('SELECT', $data); + $this->db->sql_query($sql); + + return $this->umil_end(); + } + + /** + * Table Row Remove + * + * Remove a row from a table + * + * $data should be an array with the column names as keys and values as the items to check for each column. Example: + * array('user_id' => 123, 'user_name' => 'test user') would become: + * WHERE user_id = 123 AND user_name = 'test user' + */ + function table_row_remove($table_name, $data = array()) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + if (!sizeof($data)) + { + return $this->umil_end('FAIL'); + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_ROW_REMOVE_DATA', $table_name); + + if (!$this->table_exists($table_name)) + { + return $this->umil_end('TABLE_NOT_EXIST', $table_name); + } + + $sql = 'DELETE FROM ' . $table_name . ' WHERE ' . $this->db->sql_build_array('SELECT', $data); + $this->db->sql_query($sql); + + return $this->umil_end(); + } + + /** + * Version Checker + * + * Format the file like the following: + * http://www.phpbb.com/updatecheck/30x.txt + * + * @param string $url The url to access (ex: www.phpbb.com) + * @param string $path The path to access (ex: /updatecheck) + * @param string $file The name of the file to access (ex: 30x.txt) + * + * @return array|string Error Message if there was any error, or an array (each line in the file as a value) + */ + function version_check($url, $path, $file, $timeout = 10, $port = 80) + { + if (!function_exists('get_remote_file')) + { + global $phpbb_root_path, $phpEx; + + include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); + } + + $errstr = $errno = ''; + + $info = get_remote_file($url, $path, $file, $errstr, $errno, $port, $timeout); + + if ($info === false) + { + return $errstr . ' [ ' . $errno . ' ]'; + } + + $info = str_replace("\r\n", "\n", $info); + $info = explode("\n", $info); + + return $info; + } + + /** + * Create table SQL + * + * Create the SQL query for the specified DBMS on the fly from a create_schema_files type of table array + * + * @param string $table_name The name of the table + * @param array $table_data The table data (formatted in the array format used by create_schema_files) + * @param string $dbms The dbms this will be built for (for testing only, leave blank to use the current DBMS) + * + * @return The sql query to run for the submitted dbms to insert the table + */ + function create_table_sql($table_name, $table_data, $dbms = '') + { + // To allow testing + $dbms = ($dbms) ? $dbms : $this->db_tools->sql_layer; + + // A list of types being unsigned for better reference in some db's + $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); + $supported_dbms = array('firebird', 'mssql', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite'); + + $sql = ''; + + // Create Table statement + $generator = $textimage = false; + + switch ($dbms) + { + case 'mysql_40': + case 'mysql_41': + case 'firebird': + case 'oracle': + case 'sqlite': + case 'postgres': + $sql .= "CREATE TABLE {$table_name} (\n"; + break; + + case 'mssql': + $sql .= "CREATE TABLE [{$table_name}] (\n"; + break; + } + + // Table specific so we don't get overlap + $modded_array = array(); + + // Write columns one by one... + foreach ($table_data['COLUMNS'] as $column_name => $column_data) + { + // Get type + if (strpos($column_data[0], ':') !== false) + { + list($orig_column_type, $column_length) = explode(':', $column_data[0]); + if (!is_array($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'])) + { + $column_type = sprintf($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'], $column_length); + } + else + { + if (isset($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['rule'])) + { + switch ($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['rule'][0]) + { + case 'div': + $column_length /= $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['rule'][1]; + $column_length = ceil($column_length); + $column_type = sprintf($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length); + break; + } + } + + if (isset($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'])) + { + switch ($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][0]) + { + case 'mult': + $column_length *= $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][1]; + if ($column_length > $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][2]) + { + $column_type = $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][3]; + $modded_array[$column_name] = $column_type; + } + else + { + $column_type = sprintf($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length); + } + break; + } + } + } + $orig_column_type .= ':'; + } + else + { + $orig_column_type = $column_data[0]; + $column_type = $this->db_tools->dbms_type_map[$dbms][$column_data[0]]; + if ($column_type == 'text' || $column_type == 'blob') + { + $modded_array[$column_name] = $column_type; + } + } + + // Adjust default value if db-dependant specified + if (is_array($column_data[1])) + { + $column_data[1] = (isset($column_data[1][$dbms])) ? $column_data[1][$dbms] : $column_data[1]['default']; + } + + switch ($dbms) + { + case 'mysql_40': + case 'mysql_41': + $sql .= "\t{$column_name} {$column_type} "; + + // For hexadecimal values do not use single quotes + if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob') + { + $sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' "; + } + $sql .= 'NOT NULL'; + + if (isset($column_data[2])) + { + if ($column_data[2] == 'auto_increment') + { + $sql .= ' auto_increment'; + } + else if ($dbms === 'mysql_41' && $column_data[2] == 'true_sort') + { + $sql .= ' COLLATE utf8_unicode_ci'; + } + } + + $sql .= ",\n"; + break; + + case 'sqlite': + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $sql .= "\t{$column_name} INTEGER PRIMARY KEY "; + $generator = $column_name; + } + else + { + $sql .= "\t{$column_name} {$column_type} "; + } + + $sql .= 'NOT NULL '; + $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : ''; + $sql .= ",\n"; + break; + + case 'firebird': + $sql .= "\t{$column_name} {$column_type} "; + + if (!is_null($column_data[1])) + { + $sql .= 'DEFAULT ' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' '; + } + + $sql .= 'NOT NULL'; + + // This is a UNICODE column and thus should be given it's fair share + if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0])) + { + $sql .= ' COLLATE UNICODE'; + } + + $sql .= ",\n"; + + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $generator = $column_name; + } + break; + + case 'mssql': + if ($column_type == '[text]') + { + $textimage = true; + } + + $sql .= "\t[{$column_name}] {$column_type} "; + + if (!is_null($column_data[1])) + { + // For hexadecimal values do not use single quotes + if (strpos($column_data[1], '0x') === 0) + { + $sql .= 'DEFAULT (' . $column_data[1] . ') '; + } + else + { + $sql .= 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; + } + } + + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $sql .= 'IDENTITY (1, 1) '; + } + + $sql .= 'NOT NULL'; + $sql .= " ,\n"; + break; + + case 'oracle': + $sql .= "\t{$column_name} {$column_type} "; + $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : ''; + + // In Oracle empty strings ('') are treated as NULL. + // Therefore in oracle we allow NULL's for all DEFAULT '' entries + $sql .= ($column_data[1] === '') ? ",\n" : "NOT NULL,\n"; + + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $generator = $column_name; + } + break; + + case 'postgres': + $sql .= "\t{$column_name} {$column_type} "; + + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $sql .= "DEFAULT nextval('{$table_name}_seq'),\n"; + + // Make sure the sequence will be created before creating the table + $sql = "CREATE SEQUENCE {$table_name}_seq;\n\n" . $sql; + } + else + { + $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : ''; + $sql .= "NOT NULL"; + + // Unsigned? Then add a CHECK contraint + if (in_array($orig_column_type, $unsigned_types)) + { + $sql .= " CHECK ({$column_name} >= 0)"; + } + + $sql .= ",\n"; + } + break; + } + } + + switch ($dbms) + { + case 'firebird': + // Remove last line delimiter... + $sql = substr($sql, 0, -2); + $sql .= "\n);;\n\n"; + break; + + case 'mssql': + $sql = substr($sql, 0, -2); + $sql .= "\n) ON [PRIMARY]" . (($textimage) ? ' TEXTIMAGE_ON [PRIMARY]' : '') . "\n"; + $sql .= "GO\n\n"; + break; + } + + // Write primary key + if (isset($table_data['PRIMARY_KEY'])) + { + if (!is_array($table_data['PRIMARY_KEY'])) + { + $table_data['PRIMARY_KEY'] = array($table_data['PRIMARY_KEY']); + } + + switch ($dbms) + { + case 'mysql_40': + case 'mysql_41': + case 'postgres': + $sql .= "\tPRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . "),\n"; + break; + + case 'firebird': + $sql .= "ALTER TABLE {$table_name} ADD PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ");;\n\n"; + break; + + case 'sqlite': + if ($generator === false || !in_array($generator, $table_data['PRIMARY_KEY'])) + { + $sql .= "\tPRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . "),\n"; + } + break; + + case 'mssql': + $sql .= "ALTER TABLE [{$table_name}] WITH NOCHECK ADD \n"; + $sql .= "\tCONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED \n"; + $sql .= "\t(\n"; + $sql .= "\t\t[" . implode("],\n\t\t[", $table_data['PRIMARY_KEY']) . "]\n"; + $sql .= "\t) ON [PRIMARY] \n"; + $sql .= "GO\n\n"; + break; + + case 'oracle': + $sql .= "\tCONSTRAINT pk_{$table_name} PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . "),\n"; + break; + } + } + + switch ($dbms) + { + case 'oracle': + // UNIQUE contrains to be added? + if (isset($table_data['KEYS'])) + { + foreach ($table_data['KEYS'] as $key_name => $key_data) + { + if (!is_array($key_data[1])) + { + $key_data[1] = array($key_data[1]); + } + + if ($key_data[0] == 'UNIQUE') + { + $sql .= "\tCONSTRAINT u_phpbb_{$key_name} UNIQUE (" . implode(', ', $key_data[1]) . "),\n"; + } + } + } + + // Remove last line delimiter... + $sql = substr($sql, 0, -2); + $sql .= "\n)\n/\n\n"; + break; + + case 'postgres': + // Remove last line delimiter... + $sql = substr($sql, 0, -2); + $sql .= "\n);\n\n"; + break; + + case 'sqlite': + // Remove last line delimiter... + $sql = substr($sql, 0, -2); + $sql .= "\n);\n\n"; + break; + } + + // Write Keys + if (isset($table_data['KEYS'])) + { + foreach ($table_data['KEYS'] as $key_name => $key_data) + { + if (!is_array($key_data[1])) + { + $key_data[1] = array($key_data[1]); + } + + switch ($dbms) + { + case 'mysql_40': + case 'mysql_41': + $sql .= ($key_data[0] == 'INDEX') ? "\tKEY" : ''; + $sql .= ($key_data[0] == 'UNIQUE') ? "\tUNIQUE" : ''; + foreach ($key_data[1] as $key => $col_name) + { + if (isset($modded_array[$col_name])) + { + switch ($modded_array[$col_name]) + { + case 'text': + case 'blob': + $key_data[1][$key] = $col_name . '(255)'; + break; + } + } + } + $sql .= ' ' . $key_name . ' (' . implode(', ', $key_data[1]) . "),\n"; + break; + + case 'firebird': + $sql .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; + $sql .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; + + $sql .= ' ' . $table_name . '_' . $key_name . ' ON ' . $table_name . '(' . implode(', ', $key_data[1]) . ");;\n"; + break; + + case 'mssql': + $sql .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; + $sql .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; + $sql .= " [{$key_name}] ON [{$table_name}]([" . implode('], [', $key_data[1]) . "]) ON [PRIMARY]\n"; + $sql .= "GO\n\n"; + break; + + case 'oracle': + if ($key_data[0] == 'UNIQUE') + { + continue; + } + + $sql .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; + + $sql .= " {$table_name}_{$key_name} ON {$table_name} (" . implode(', ', $key_data[1]) . ")\n"; + $sql .= "/\n"; + break; + + case 'sqlite': + $sql .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; + $sql .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; + + $sql .= " {$table_name}_{$key_name} ON {$table_name} (" . implode(', ', $key_data[1]) . ");\n"; + break; + + case 'postgres': + $sql .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; + $sql .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; + + $sql .= " {$table_name}_{$key_name} ON {$table_name} (" . implode(', ', $key_data[1]) . ");\n"; + break; + } + } + } + + switch ($dbms) + { + case 'mysql_40': + // Remove last line delimiter... + $sql = substr($sql, 0, -2); + $sql .= "\n);\n\n"; + break; + + case 'mysql_41': + // Remove last line delimiter... + $sql = substr($sql, 0, -2); + $sql .= "\n) CHARACTER SET utf8 COLLATE utf8_bin;\n\n"; + break; + + // Create Generator + case 'firebird': + if ($generator !== false) + { + $sql .= "\nCREATE GENERATOR {$table_name}_gen;;\n"; + $sql .= 'SET GENERATOR ' . $table_name . "_gen TO 0;;\n\n"; + + $sql .= 'CREATE TRIGGER t_' . $table_name . ' FOR ' . $table_name . "\n"; + $sql .= "BEFORE INSERT\nAS\nBEGIN\n"; + $sql .= "\tNEW.{$generator} = GEN_ID({$table_name}_gen, 1);\nEND;;\n\n"; + } + break; + + case 'oracle': + if ($generator !== false) + { + $sql .= "\nCREATE SEQUENCE {$table_name}_seq\n/\n\n"; + + $sql .= "CREATE OR REPLACE TRIGGER t_{$table_name}\n"; + $sql .= "BEFORE INSERT ON {$table_name}\n"; + $sql .= "FOR EACH ROW WHEN (\n"; + $sql .= "\tnew.{$generator} IS NULL OR new.{$generator} = 0\n"; + $sql .= ")\nBEGIN\n"; + $sql .= "\tSELECT {$table_name}_seq.nextval\n"; + $sql .= "\tINTO :new.{$generator}\n"; + $sql .= "\tFROM dual;\nEND;\n/\n\n"; + } + break; + } + + return $sql; + } + + /** + * Get the real table name + * By A_Jelly_Doughnut + * + * @param string $table_name The table name to get the real table name from + */ + function get_table_name(&$table_name) + { + // Use the global table prefix if a custom one is not specified + if ($this->table_prefix === false) + { + global $table_prefix; + } + else + { + $table_prefix = $this->table_prefix; + } + + static $constants = NULL; + + if (is_null($constants)) + { + $constants = get_defined_constants(); + } + + /** + * only do the replace if the table prefix is not already present + * this is required since UMIL supports specifying a table via phpbb_foo + * (where a replace would be needed) + * or by FOO_TABLE (where a replace is already done at constant-define time) + */ + if (!preg_match('#^' . preg_quote($table_prefix, '#') . '#', $table_name) || !in_array($table_name, $constants, true)) + { + $table_name = preg_replace('#^phpbb_#i', $table_prefix, $table_name); + } + } +} + +?> \ No newline at end of file From 91a921a96bf26607879de850fca105be78eadf1d Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 11 Nov 2012 09:43:07 +0100 Subject: [PATCH 19/90] [feature/migrations] Change migration data processing to run step by step --- phpBB/includes/db/migrator.php | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 4ce54a4b92..912a7b34ba 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -167,7 +167,7 @@ class phpbb_db_migrator } else { - $migration->update_data(); + $this->process_data_step($migration); $state['migration_data_done'] = true; $state['migration_end_time'] = time(); } @@ -182,6 +182,28 @@ class phpbb_db_migrator return true; } + function process_data_step(&$migration) + { + $continue = false; + $steps = $migration->update_data(); + + foreach ($steps as $step) + { + $continue = $this->run_step($step); + if (!$continue) + { + return false; + } + } + + return $continue; + } + + function run_step(&$step) + { + + } + function insert_migration($name, $state) { $migration_row = $state; From 82efb3e446efbb8ef05c6a777e3866901abfd07a Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 8 Jan 2013 22:07:12 -0600 Subject: [PATCH 20/90] [feature/migrations] Remove references as it is now 3.1 code PHPBB3-9737 --- phpBB/includes/db/migration.php | 6 +- .../db/migration/{ => data}/3_0_1.php | 4 +- .../db/migration/{ => data}/3_0_10.php | 4 +- .../db/migration/{ => data}/3_0_10_rc1.php | 4 +- .../db/migration/{ => data}/3_0_10_rc2.php | 4 +- .../db/migration/{ => data}/3_0_10_rc3.php | 4 +- .../db/migration/{ => data}/3_0_11.php | 4 +- .../db/migration/{ => data}/3_0_11_rc1.php | 4 +- .../db/migration/{ => data}/3_0_11_rc2 | 4 +- .../db/migration/{ => data}/3_0_12_rc1.php | 4 +- .../db/migration/{ => data}/3_0_1_rc1.php | 2 +- .../db/migration/{ => data}/3_0_2.php | 4 +- .../db/migration/{ => data}/3_0_2_rc1.php | 4 +- .../db/migration/{ => data}/3_0_2_rc2.php | 4 +- .../db/migration/{ => data}/3_0_3.php | 4 +- .../db/migration/{ => data}/3_0_3_rc1.php | 4 +- .../db/migration/{ => data}/3_0_4.php | 4 +- .../db/migration/{ => data}/3_0_4_rc1.php | 4 +- .../db/migration/{ => data}/3_0_5.php | 4 +- .../db/migration/{ => data}/3_0_5_rc1.php | 4 +- .../migration/{ => data}/3_0_5_rc1part2.php | 4 +- .../db/migration/{ => data}/3_0_6.php | 4 +- .../db/migration/{ => data}/3_0_6_rc1.php | 101 ++-- .../db/migration/{ => data}/3_0_6_rc2.php | 4 +- .../db/migration/{ => data}/3_0_6_rc3.php | 4 +- .../db/migration/{ => data}/3_0_6_rc4.php | 4 +- .../db/migration/{ => data}/3_0_7.php | 4 +- .../db/migration/{ => data}/3_0_7_pl1.php | 4 +- .../db/migration/{ => data}/3_0_7_rc1.php | 4 +- .../db/migration/{ => data}/3_0_7_rc2.php | 4 +- .../db/migration/{ => data}/3_0_8.php | 4 +- .../db/migration/{ => data}/3_0_8_rc1.php | 16 +- .../db/migration/{ => data}/3_0_9.php | 4 +- .../db/migration/{ => data}/3_0_9_rc1.php | 4 +- .../db/migration/{ => data}/3_0_9_rc2.php | 4 +- .../db/migration/{ => data}/3_0_9_rc3.php | 4 +- .../db/migration/{ => data}/3_0_9_rc4.php | 4 +- phpBB/includes/db/migration/tools/base.php | 47 ++ phpBB/includes/db/migration/tools/config.php | 106 ++++ phpBB/includes/db/migration/tools/module.php | 419 +++++++++++++++ .../db/migration/tools/permission.php | 480 ++++++++++++++++++ .../tools}/umil.php | 0 phpBB/includes/db/migrationtools/base.php | 15 - phpBB/includes/db/migrationtools/config.php | 121 ----- phpBB/includes/db/migrator.php | 14 +- 45 files changed, 1179 insertions(+), 280 deletions(-) rename phpBB/includes/db/migration/{ => data}/3_0_1.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_10.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_10_rc1.php (74%) rename phpBB/includes/db/migration/{ => data}/3_0_10_rc2.php (68%) rename phpBB/includes/db/migration/{ => data}/3_0_10_rc3.php (68%) rename phpBB/includes/db/migration/{ => data}/3_0_11.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_11_rc1.php (94%) rename phpBB/includes/db/migration/{ => data}/3_0_11_rc2 (77%) rename phpBB/includes/db/migration/{ => data}/3_0_12_rc1.php (73%) rename phpBB/includes/db/migration/{ => data}/3_0_1_rc1.php (96%) rename phpBB/includes/db/migration/{ => data}/3_0_2.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_2_rc1.php (81%) rename phpBB/includes/db/migration/{ => data}/3_0_2_rc2.php (90%) rename phpBB/includes/db/migration/{ => data}/3_0_3.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_3_rc1.php (93%) rename phpBB/includes/db/migration/{ => data}/3_0_4.php (88%) rename phpBB/includes/db/migration/{ => data}/3_0_4_rc1.php (96%) rename phpBB/includes/db/migration/{ => data}/3_0_5.php (68%) rename phpBB/includes/db/migration/{ => data}/3_0_5_rc1.php (96%) rename phpBB/includes/db/migration/{ => data}/3_0_5_rc1part2.php (79%) rename phpBB/includes/db/migration/{ => data}/3_0_6.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_6_rc1.php (81%) rename phpBB/includes/db/migration/{ => data}/3_0_6_rc2.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_6_rc3.php (84%) rename phpBB/includes/db/migration/{ => data}/3_0_6_rc4.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_7.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_7_pl1.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_7_rc1.php (91%) rename phpBB/includes/db/migration/{ => data}/3_0_7_rc2.php (92%) rename phpBB/includes/db/migration/{ => data}/3_0_8.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_8_rc1.php (94%) rename phpBB/includes/db/migration/{ => data}/3_0_9.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_9_rc1.php (96%) rename phpBB/includes/db/migration/{ => data}/3_0_9_rc2.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_9_rc3.php (69%) rename phpBB/includes/db/migration/{ => data}/3_0_9_rc4.php (69%) create mode 100644 phpBB/includes/db/migration/tools/base.php create mode 100644 phpBB/includes/db/migration/tools/config.php create mode 100644 phpBB/includes/db/migration/tools/module.php create mode 100644 phpBB/includes/db/migration/tools/permission.php rename phpBB/includes/db/{migrationtools => migration/tools}/umil.php (100%) delete mode 100644 phpBB/includes/db/migrationtools/base.php delete mode 100644 phpBB/includes/db/migrationtools/config.php diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration.php index de9f6d07e3..c98ac8728a 100644 --- a/phpBB/includes/db/migration.php +++ b/phpBB/includes/db/migration.php @@ -44,10 +44,10 @@ class phpbb_db_migration * @param string $phpbb_root_path * @param string $php_ext */ - function phpbb_db_migration(&$db, &$db_tools, $table_prefix, $phpbb_root_path, $php_ext) + function phpbb_db_migration($db, $db_tools, $table_prefix, $phpbb_root_path, $php_ext) { - $this->db = &$db; - $this->db_tools = &$db_tools; + $this->db = $db; + $this->db_tools = $db_tools; $this->table_prefix = $table_prefix; $this->phpbb_root_path = $phpbb_root_path; diff --git a/phpBB/includes/db/migration/3_0_1.php b/phpBB/includes/db/migration/data/3_0_1.php similarity index 69% rename from phpBB/includes/db/migration/3_0_1.php rename to phpBB/includes/db/migration/data/3_0_1.php index 1cb069a2b1..294db3d946 100644 --- a/phpBB/includes/db/migration/3_0_1.php +++ b/phpBB/includes/db/migration/data/3_0_1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_1_rc1'); + return array('phpbb_db_migration_data_3_0_1_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_10.php b/phpBB/includes/db/migration/data/3_0_10.php similarity index 69% rename from phpBB/includes/db/migration/3_0_10.php rename to phpBB/includes/db/migration/data/3_0_10.php index aae27a08c7..6d39969d48 100644 --- a/phpBB/includes/db/migration/3_0_10.php +++ b/phpBB/includes/db/migration/data/3_0_10.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_10 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_10 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_10_rc3'); + return array('phpbb_db_migration_data_3_0_10_rc3'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_10_rc1.php b/phpBB/includes/db/migration/data/3_0_10_rc1.php similarity index 74% rename from phpBB/includes/db/migration/3_0_10_rc1.php rename to phpBB/includes/db/migration/data/3_0_10_rc1.php index 5d65ae15da..06105c5b0d 100644 --- a/phpBB/includes/db/migration/3_0_10_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_10_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_10_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_10_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_9'); + return array('phpbb_db_migration_data_3_0_9'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_10_rc2.php b/phpBB/includes/db/migration/data/3_0_10_rc2.php similarity index 68% rename from phpBB/includes/db/migration/3_0_10_rc2.php rename to phpBB/includes/db/migration/data/3_0_10_rc2.php index d5dc4caec9..04161caf28 100644 --- a/phpBB/includes/db/migration/3_0_10_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_10_rc2.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_10_rc2 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_10_rc2 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_10_rc1'); + return array('phpbb_db_migration_data_3_0_10_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_10_rc3.php b/phpBB/includes/db/migration/data/3_0_10_rc3.php similarity index 68% rename from phpBB/includes/db/migration/3_0_10_rc3.php rename to phpBB/includes/db/migration/data/3_0_10_rc3.php index dc962b73c8..539f0b8fec 100644 --- a/phpBB/includes/db/migration/3_0_10_rc3.php +++ b/phpBB/includes/db/migration/data/3_0_10_rc3.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_10_rc3 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_10_rc3 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_10_rc2'); + return array('phpbb_db_migration_data_3_0_10_rc2'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_11.php b/phpBB/includes/db/migration/data/3_0_11.php similarity index 69% rename from phpBB/includes/db/migration/3_0_11.php rename to phpBB/includes/db/migration/data/3_0_11.php index 89ffe310f4..3404272ef9 100644 --- a/phpBB/includes/db/migration/3_0_11.php +++ b/phpBB/includes/db/migration/data/3_0_11.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_11 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_11 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_11_rc2'); + return array('phpbb_db_migration_data_3_0_11_rc2'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_11_rc1.php b/phpBB/includes/db/migration/data/3_0_11_rc1.php similarity index 94% rename from phpBB/includes/db/migration/3_0_11_rc1.php rename to phpBB/includes/db/migration/data/3_0_11_rc1.php index 1b74aa9a4c..f44226df02 100644 --- a/phpBB/includes/db/migration/3_0_11_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_11_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_11_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_11_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_10'); + return array('phpbb_db_migration_data_3_0_10'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_11_rc2 b/phpBB/includes/db/migration/data/3_0_11_rc2 similarity index 77% rename from phpBB/includes/db/migration/3_0_11_rc2 rename to phpBB/includes/db/migration/data/3_0_11_rc2 index f4e64871ed..6add980c73 100644 --- a/phpBB/includes/db/migration/3_0_11_rc2 +++ b/phpBB/includes/db/migration/data/3_0_11_rc2 @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_11_rc2 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_11_rc2 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_11_rc1'); + return array('phpbb_db_migration_data_3_0_11_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_12_rc1.php b/phpBB/includes/db/migration/data/3_0_12_rc1.php similarity index 73% rename from phpBB/includes/db/migration/3_0_12_rc1.php rename to phpBB/includes/db/migration/data/3_0_12_rc1.php index 58e112a43a..734a57ecee 100644 --- a/phpBB/includes/db/migration/3_0_12_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_12_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_12_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_12_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_11'); + return array('phpbb_db_migration_data_3_0_11'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_1_rc1.php b/phpBB/includes/db/migration/data/3_0_1_rc1.php similarity index 96% rename from phpBB/includes/db/migration/3_0_1_rc1.php rename to phpBB/includes/db/migration/data/3_0_1_rc1.php index e3be8b36d4..1a696e0003 100644 --- a/phpBB/includes/db/migration/3_0_1_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_1_rc1.php @@ -7,7 +7,7 @@ * */ -class phpbb_db_migration_3_0_1_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_1_rc1 extends phpbb_db_migration { function depends_on() { diff --git a/phpBB/includes/db/migration/3_0_2.php b/phpBB/includes/db/migration/data/3_0_2.php similarity index 69% rename from phpBB/includes/db/migration/3_0_2.php rename to phpBB/includes/db/migration/data/3_0_2.php index 36e8d52e6b..a5f94e644b 100644 --- a/phpBB/includes/db/migration/3_0_2.php +++ b/phpBB/includes/db/migration/data/3_0_2.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_2 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_2 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_2_rc2'); + return array('phpbb_db_migration_data_3_0_2_rc2'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_2_rc1.php b/phpBB/includes/db/migration/data/3_0_2_rc1.php similarity index 81% rename from phpBB/includes/db/migration/3_0_2_rc1.php rename to phpBB/includes/db/migration/data/3_0_2_rc1.php index cd21b7f64f..1b4d3bc2b8 100644 --- a/phpBB/includes/db/migration/3_0_2_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_2_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_1_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_1_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_1'); + return array('phpbb_db_migration_data_3_0_1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_2_rc2.php b/phpBB/includes/db/migration/data/3_0_2_rc2.php similarity index 90% rename from phpBB/includes/db/migration/3_0_2_rc2.php rename to phpBB/includes/db/migration/data/3_0_2_rc2.php index a1fab753e2..9ddeb60a14 100644 --- a/phpBB/includes/db/migration/3_0_2_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_2_rc2.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_2_rc2 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_2_rc2 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_2_rc1'); + return array('phpbb_db_migration_data_3_0_2_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_3.php b/phpBB/includes/db/migration/data/3_0_3.php similarity index 69% rename from phpBB/includes/db/migration/3_0_3.php rename to phpBB/includes/db/migration/data/3_0_3.php index c9ca33ee88..f989eea025 100644 --- a/phpBB/includes/db/migration/3_0_3.php +++ b/phpBB/includes/db/migration/data/3_0_3.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_3 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_3 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_2_rc2'); + return array('phpbb_db_migration_data_3_0_2_rc2'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_3_rc1.php b/phpBB/includes/db/migration/data/3_0_3_rc1.php similarity index 93% rename from phpBB/includes/db/migration/3_0_3_rc1.php rename to phpBB/includes/db/migration/data/3_0_3_rc1.php index 0cd99457ee..737eab4bd3 100644 --- a/phpBB/includes/db/migration/3_0_3_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_3_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_3_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_3_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_2'); + return array('phpbb_db_migration_data_3_0_2'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_4.php b/phpBB/includes/db/migration/data/3_0_4.php similarity index 88% rename from phpBB/includes/db/migration/3_0_4.php rename to phpBB/includes/db/migration/data/3_0_4.php index bbaaea54c9..cd34fda9ab 100644 --- a/phpBB/includes/db/migration/3_0_4.php +++ b/phpBB/includes/db/migration/data/3_0_4.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_4 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_4 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_4_rc1'); + return array('phpbb_db_migration_data_3_0_4_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_4_rc1.php b/phpBB/includes/db/migration/data/3_0_4_rc1.php similarity index 96% rename from phpBB/includes/db/migration/3_0_4_rc1.php rename to phpBB/includes/db/migration/data/3_0_4_rc1.php index b783e58e24..342f1fa910 100644 --- a/phpBB/includes/db/migration/3_0_4_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_4_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_4_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_4_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_3'); + return array('phpbb_db_migration_data_3_0_3'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_5.php b/phpBB/includes/db/migration/data/3_0_5.php similarity index 68% rename from phpBB/includes/db/migration/3_0_5.php rename to phpBB/includes/db/migration/data/3_0_5.php index 272779f083..5671832a82 100644 --- a/phpBB/includes/db/migration/3_0_5.php +++ b/phpBB/includes/db/migration/data/3_0_5.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_5 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_5 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_5_rc1part2'); + return array('phpbb_db_migration_data_3_0_5_rc1part2'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_5_rc1.php b/phpBB/includes/db/migration/data/3_0_5_rc1.php similarity index 96% rename from phpBB/includes/db/migration/3_0_5_rc1.php rename to phpBB/includes/db/migration/data/3_0_5_rc1.php index 8975728cca..9205f0d5f8 100644 --- a/phpBB/includes/db/migration/3_0_5_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_5_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_5_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_5_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_4'); + return array('phpbb_db_migration_data_3_0_4'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_5_rc1part2.php b/phpBB/includes/db/migration/data/3_0_5_rc1part2.php similarity index 79% rename from phpBB/includes/db/migration/3_0_5_rc1part2.php rename to phpBB/includes/db/migration/data/3_0_5_rc1part2.php index 710c8dce91..6be8ea9845 100644 --- a/phpBB/includes/db/migration/3_0_5_rc1part2.php +++ b/phpBB/includes/db/migration/data/3_0_5_rc1part2.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_5_rc1part2 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_5_rc1part2 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_5_rc1'); + return array('phpbb_db_migration_data_3_0_5_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_6.php b/phpBB/includes/db/migration/data/3_0_6.php similarity index 69% rename from phpBB/includes/db/migration/3_0_6.php rename to phpBB/includes/db/migration/data/3_0_6.php index 9582038b36..c2cb59e62a 100644 --- a/phpBB/includes/db/migration/3_0_6.php +++ b/phpBB/includes/db/migration/data/3_0_6.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_6 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_6 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_6_rc4'); + return array('phpbb_db_migration_data_3_0_6_rc4'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_6_rc1.php b/phpBB/includes/db/migration/data/3_0_6_rc1.php similarity index 81% rename from phpBB/includes/db/migration/3_0_6_rc1.php rename to phpBB/includes/db/migration/data/3_0_6_rc1.php index 0aa5746164..eefdc1692d 100644 --- a/phpBB/includes/db/migration/3_0_6_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_6_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_6_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_5'); + return array('phpbb_db_migration_data_3_0_5'); } function update_schema() @@ -62,12 +62,10 @@ class phpbb_db_migration_3_0_6_rc1 extends phpbb_db_migration function update_data() { return array( - //array('custom', array(array(&$this, ''))) array('config.add', array('captcha_plugin', 'phpbb_captcha_nogd')), - array('config.update_if', array( + array('if', array( ($this->config['captcha_gd']), - 'captcha_plugin', - 'phpbb_captcha_gd', + array('config.update', array('captcha_plugin', 'phpbb_captcha_gd')), )), array('config.add', array('feed_enable', 0)), @@ -89,83 +87,70 @@ class phpbb_db_migration_3_0_6_rc1 extends phpbb_db_migration array('config.add', array('delete_time', $this->config['edit_time'])), array('config.add', array('allow_avatar', 0)), - array('config.add_if', array( + array('if', array( ($this->config['allow_avatar_upload'] || $this->config['allow_avatar_local'] || $this->config['allow_avatar_remote']), - 'allow_avatar', - 1, + array('config.add', array('allow_avatar', 1)), )), array('config.add', array('allow_avatar_remote_upload', 0)), - array('config.add_if', array( + array('if', array( ($this->config['allow_avatar_remote'] && $this->config['allow_avatar_upload']), - 'allow_avatar_remote_upload', - 1, + array('config.add', array('allow_avatar_remote_upload', 1)), )), array('module.add', array( - 'feed' => array( - 'base' => 'board', - 'class' => 'acp', - 'title' => 'ACP_FEED_SETTINGS', - 'auth' => 'acl_a_board', - 'cat' => 'ACP_BOARD_CONFIGURATION', - 'after' => array('signature', 'ACP_SIGNATURE_SETTINGS') + 'acp', + 'ACP_BOARD_CONFIGURATION', + array( + 'module_basename' => 'board', + 'modes' => array('feed'), ), )), array('module.add', array( - 'warnings' => array( - 'base' => 'users', - 'class' => 'acp', - 'title' => 'ACP_USER_WARNINGS', - 'auth' => 'acl_a_user', - 'display' => 0, - 'cat' => 'ACP_CAT_USERS', - 'after' => array('feedback', 'ACP_USER_FEEDBACK') + 'acp', + 'ACP_CAT_USERS', + array( + 'module_basename' => 'users', + 'modes' => array('warnings'), ), )), array('module.add', array( - 'send_statistics' => array( - 'base' => 'send_statistics', - 'class' => 'acp', - 'title' => 'ACP_SEND_STATISTICS', - 'auth' => 'acl_a_server', - 'cat' => 'ACP_SERVER_CONFIGURATION' + 'acp', + 'ACP_SERVER_CONFIGURATION', + array( + 'module_basename' => 'send_statistics', + 'modes' => array('send_statistics'), ), )), array('module.add', array( - 'setting_forum_copy' => array( - 'base' => 'permissions', - 'class' => 'acp', - 'title' => 'ACP_FORUM_PERMISSIONS_COPY', - 'auth' => 'acl_a_fauth && acl_a_authusers && acl_a_authgroups && acl_a_mauth', - 'cat' => 'ACP_FORUM_BASED_PERMISSIONS', - 'after' => array('setting_forum_local', 'ACP_FORUM_PERMISSIONS') + 'acp', + 'ACP_FORUM_BASED_PERMISSIONS', + array( + 'module_basename' => 'permissions', + 'modes' => array('setting_forum_copy'), ), )), array('module.add', array( - 'pm_reports' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORTS_OPEN', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' + 'mcp', + 'MCP_REPORTS', + array( + 'module_basename' => 'pm_reports', + 'modes' => array('pm_reports'), ), )), array('module.add', array( - 'pm_reports_closed' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORTS_CLOSED', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' + 'mcp', + 'MCP_REPORTS', + array( + 'module_basename' => 'pm_reports', + 'modes' => array('pm_reports_closed'), ), )), array('module.add', array( - 'pm_report_details' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORT_DETAILS', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' + 'mcp', + 'MCP_REPORTS', + array( + 'module_basename' => 'pm_reports', + 'modes' => array('pm_report_details'), ), )), array('custom', array(array(&$this, 'add_newly_registered_group'))), diff --git a/phpBB/includes/db/migration/3_0_6_rc2.php b/phpBB/includes/db/migration/data/3_0_6_rc2.php similarity index 69% rename from phpBB/includes/db/migration/3_0_6_rc2.php rename to phpBB/includes/db/migration/data/3_0_6_rc2.php index 1552485d0a..07b31a53b9 100644 --- a/phpBB/includes/db/migration/3_0_6_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_6_rc2.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_6_rc2 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_6_rc2 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_6_rc1'); + return array('phpbb_db_migration_data_3_0_6_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_6_rc3.php b/phpBB/includes/db/migration/data/3_0_6_rc3.php similarity index 84% rename from phpBB/includes/db/migration/3_0_6_rc3.php rename to phpBB/includes/db/migration/data/3_0_6_rc3.php index 6a7ad1c56d..c19a792bad 100644 --- a/phpBB/includes/db/migration/3_0_6_rc3.php +++ b/phpBB/includes/db/migration/data/3_0_6_rc3.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_6_rc3 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_6_rc3 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_6_rc2'); + return array('phpbb_db_migration_data_3_0_6_rc2'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_6_rc4.php b/phpBB/includes/db/migration/data/3_0_6_rc4.php similarity index 69% rename from phpBB/includes/db/migration/3_0_6_rc4.php rename to phpBB/includes/db/migration/data/3_0_6_rc4.php index 00161456b6..c48b1ca394 100644 --- a/phpBB/includes/db/migration/3_0_6_rc4.php +++ b/phpBB/includes/db/migration/data/3_0_6_rc4.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_6_rc4 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_6_rc4 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_6_rc3'); + return array('phpbb_db_migration_data_3_0_6_rc3'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_7.php b/phpBB/includes/db/migration/data/3_0_7.php similarity index 69% rename from phpBB/includes/db/migration/3_0_7.php rename to phpBB/includes/db/migration/data/3_0_7.php index 2b5ec15fa9..05781b7b49 100644 --- a/phpBB/includes/db/migration/3_0_7.php +++ b/phpBB/includes/db/migration/data/3_0_7.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_7 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_7 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_7_rc2'); + return array('phpbb_db_migration_data_3_0_7_rc2'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_7_pl1.php b/phpBB/includes/db/migration/data/3_0_7_pl1.php similarity index 69% rename from phpBB/includes/db/migration/3_0_7_pl1.php rename to phpBB/includes/db/migration/data/3_0_7_pl1.php index 22c04f1daf..cee7a91a2e 100644 --- a/phpBB/includes/db/migration/3_0_7_pl1.php +++ b/phpBB/includes/db/migration/data/3_0_7_pl1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_7_pl1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_7_pl1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_7'); + return array('phpbb_db_migration_data_3_0_7'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_7_rc1.php b/phpBB/includes/db/migration/data/3_0_7_rc1.php similarity index 91% rename from phpBB/includes/db/migration/3_0_7_rc1.php rename to phpBB/includes/db/migration/data/3_0_7_rc1.php index d08a468941..b2d49cce63 100644 --- a/phpBB/includes/db/migration/3_0_7_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_7_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_7_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_7_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_6'); + return array('phpbb_db_migration_data_3_0_6'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_7_rc2.php b/phpBB/includes/db/migration/data/3_0_7_rc2.php similarity index 92% rename from phpBB/includes/db/migration/3_0_7_rc2.php rename to phpBB/includes/db/migration/data/3_0_7_rc2.php index 4ab4e906d7..8a751328bf 100644 --- a/phpBB/includes/db/migration/3_0_7_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_7_rc2.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_7_rc2 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_7_rc2 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_7_rc1'); + return array('phpbb_db_migration_data_3_0_7_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_8.php b/phpBB/includes/db/migration/data/3_0_8.php similarity index 69% rename from phpBB/includes/db/migration/3_0_8.php rename to phpBB/includes/db/migration/data/3_0_8.php index 3e7f843a65..a714a3d2f6 100644 --- a/phpBB/includes/db/migration/3_0_8.php +++ b/phpBB/includes/db/migration/data/3_0_8.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_8 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_8 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_8_rc1'); + return array('phpbb_db_migration_data_3_0_8_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_8_rc1.php b/phpBB/includes/db/migration/data/3_0_8_rc1.php similarity index 94% rename from phpBB/includes/db/migration/3_0_8_rc1.php rename to phpBB/includes/db/migration/data/3_0_8_rc1.php index 0d93efedce..73838d9d29 100644 --- a/phpBB/includes/db/migration/3_0_8_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_8_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_8_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_8_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_7_pl1'); + return array('phpbb_db_migration_data_3_0_7_pl1'); } function update_schema() @@ -27,13 +27,11 @@ class phpbb_db_migration_3_0_8_rc1 extends phpbb_db_migration array('custom', array(array(&$this, 'update_bots'))), array('custom', array(array(&$this, 'delete_orphan_shadow_topics'))), array('module.add', array( - 'post' => array( - 'base' => 'board', - 'class' => 'acp', - 'title' => 'ACP_POST_SETTINGS', - 'auth' => 'acl_a_board', - 'cat' => 'ACP_MESSAGES', - 'after' => array('message', 'ACP_MESSAGE_SETTINGS') + 'acp', + 'ACP_MESSAGES', + array( + 'module_basename' => 'board', + 'modes' => array('post'), ), )), array('config.add', array('load_unreads_search', 1)), diff --git a/phpBB/includes/db/migration/3_0_9.php b/phpBB/includes/db/migration/data/3_0_9.php similarity index 69% rename from phpBB/includes/db/migration/3_0_9.php rename to phpBB/includes/db/migration/data/3_0_9.php index 2e1eab26e7..4b2c08a256 100644 --- a/phpBB/includes/db/migration/3_0_9.php +++ b/phpBB/includes/db/migration/data/3_0_9.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_9 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_9 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_9_rc4'); + return array('phpbb_db_migration_data_3_0_9_rc4'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_9_rc1.php b/phpBB/includes/db/migration/data/3_0_9_rc1.php similarity index 96% rename from phpBB/includes/db/migration/3_0_9_rc1.php rename to phpBB/includes/db/migration/data/3_0_9_rc1.php index 4ee18349ce..98d3a26481 100644 --- a/phpBB/includes/db/migration/3_0_9_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_9_rc1.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_9_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_9_rc1 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_8'); + return array('phpbb_db_migration_data_3_0_8'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_9_rc2.php b/phpBB/includes/db/migration/data/3_0_9_rc2.php similarity index 69% rename from phpBB/includes/db/migration/3_0_9_rc2.php rename to phpBB/includes/db/migration/data/3_0_9_rc2.php index 96782b2b01..589047670a 100644 --- a/phpBB/includes/db/migration/3_0_9_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_9_rc2.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_9_rc2 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_9_rc2 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_9_rc1'); + return array('phpbb_db_migration_data_3_0_9_rc1'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_9_rc3.php b/phpBB/includes/db/migration/data/3_0_9_rc3.php similarity index 69% rename from phpBB/includes/db/migration/3_0_9_rc3.php rename to phpBB/includes/db/migration/data/3_0_9_rc3.php index ac0f3cb972..06061cbcb6 100644 --- a/phpBB/includes/db/migration/3_0_9_rc3.php +++ b/phpBB/includes/db/migration/data/3_0_9_rc3.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_9_rc3 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_9_rc3 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_9_rc2'); + return array('phpbb_db_migration_data_3_0_9_rc2'); } function update_schema() diff --git a/phpBB/includes/db/migration/3_0_9_rc4.php b/phpBB/includes/db/migration/data/3_0_9_rc4.php similarity index 69% rename from phpBB/includes/db/migration/3_0_9_rc4.php rename to phpBB/includes/db/migration/data/3_0_9_rc4.php index 7880e1b864..04b3ae4b39 100644 --- a/phpBB/includes/db/migration/3_0_9_rc4.php +++ b/phpBB/includes/db/migration/data/3_0_9_rc4.php @@ -7,11 +7,11 @@ * */ -class phpbb_db_migration_3_0_9_rc4 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_9_rc4 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_3_0_9_rc3'); + return array('phpbb_db_migration_data_3_0_9_rc3'); } function update_schema() diff --git a/phpBB/includes/db/migration/tools/base.php b/phpBB/includes/db/migration/tools/base.php new file mode 100644 index 0000000000..61116d8b55 --- /dev/null +++ b/phpBB/includes/db/migration/tools/base.php @@ -0,0 +1,47 @@ +db = $db; + $this->cache = $cache; + $this->template = $template; + $this->user = $user; + $this->auth = $auth; + $this->config = $config; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + } +} \ No newline at end of file diff --git a/phpBB/includes/db/migration/tools/config.php b/phpBB/includes/db/migration/tools/config.php new file mode 100644 index 0000000000..965ba1d136 --- /dev/null +++ b/phpBB/includes/db/migration/tools/config.php @@ -0,0 +1,106 @@ +config->offsetExists($config_name); + } + + /** + * Config Add + * + * This function allows you to add a config setting. + * + * @param string $config_name The name of the config setting you would like to add + * @param mixed $config_value The value of the config setting + * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. + */ + public function add($config_name, $config_value = '', $is_dynamic = false) + { + if ($this->config_exists($config_name)) + { + throw new phpbb_db_migration_exception('CONFIG_ALREADY_EXISTS', $config_name); + } + + $this->config->set($config_name, $config_value, $is_dynamic); + + return false; + } + + /** + * Config Update + * + * This function allows you to update an existing config setting. + * + * @param string $config_name The name of the config setting you would like to update + * @param mixed $config_value The value of the config setting + */ + public function update($config_name, $config_value = '') + { + if (!$this->config_exists($config_name)) + { + throw new phpbb_db_migration_exception('CONFIG_NOT_EXIST', $config_name); + } + + $this->config->set($config_name, $config_value); + + return false; + } + + /** + * Config Update If Equals + * + * This function allows you to update a config setting if the first argument equal to the current config value + * + * @param bool $compare If equal to the current config value, will be updated to the new config value, otherwise not + * @param string $config_name The name of the config setting you would like to update + * @param mixed $config_value The value of the config setting + */ + public function update_if_equals($compare, $config_name, $config_value = '') + { + if (!$this->config_exists($config_name)) + { + throw new phpbb_db_migration_exception('CONFIG_NOT_EXIST', $config_name); + } + + $this->config->set_atomic($config_name, $compare, $config_value); + + return false; + } + + /** + * Config Remove + * + * This function allows you to remove an existing config setting. + * + * @param string $config_name The name of the config setting you would like to remove + */ + public function remove($config_name) + { + if (!$this->config_exists($config_name)) + { + throw new phpbb_db_migration_exception('CONFIG_NOT_EXIST', $config_name); + } + + $this->config->delete($config_name); + + return false; + } +} \ No newline at end of file diff --git a/phpBB/includes/db/migration/tools/module.php b/phpBB/includes/db/migration/tools/module.php new file mode 100644 index 0000000000..df1912a022 --- /dev/null +++ b/phpBB/includes/db/migration/tools/module.php @@ -0,0 +1,419 @@ +db->sql_escape($class); + $module = $this->db->sql_escape($module); + + $parent_sql = ''; + if ($parent !== false) + { + // Allows '' to be sent as 0 + $parent = (!$parent) ? 0 : $parent; + + if (!is_numeric($parent)) + { + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($parent) . "' + AND module_class = '$class'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row) + { + return false; + } + + $parent_sql = 'AND parent_id = ' . (int) $row['module_id']; + } + else + { + $parent_sql = 'AND parent_id = ' . (int) $parent; + } + } + + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_class = '$class' + $parent_sql + AND " . ((is_numeric($module)) ? 'module_id = ' . (int) $module : "module_langname = '$module'"); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + return true; + } + + return false; + } + + /** + * Module Add + * + * Add a new module + * + * @param string $class The module class(acp|mcp|ucp) + * @param int|string $parent The parent module_id|module_langname (0 for no parent) + * @param array $data an array of the data on the new module. This can be setup in two different ways. + * 1. The "manual" way. For inserting a category or one at a time. It will be merged with the base array shown a bit below, + * but at the least requires 'module_langname' to be sent, and, if you want to create a module (instead of just a category) you must send module_basename and module_mode. + * array( + * 'module_enabled' => 1, + * 'module_display' => 1, + * 'module_basename' => '', + * 'module_class' => $class, + * 'parent_id' => (int) $parent, + * 'module_langname' => '', + * 'module_mode' => '', + * 'module_auth' => '', + * ) + * 2. The "automatic" way. For inserting multiple at a time based on the specs in the info file for the module(s). For this to work the modules must be correctly setup in the info file. + * An example follows (this would insert the settings, log, and flag modes from the includes/acp/info/acp_asacp.php file): + * array( + * 'module_basename' => 'asacp', + * 'modes' => array('settings', 'log', 'flag'), + * ) + * Optionally you may not send 'modes' and it will insert all of the modules in that info file. + * @param string|bool $include_path If you would like to use a custom include path, specify that here + */ + public function add($class, $parent = 0, $data = array(), $include_path = false) + { + // Allows '' to be sent as 0 + $parent = (!$parent) ? 0 : $parent; + + // allow sending the name as a string in $data to create a category + if (!is_array($data)) + { + $data = array('module_langname' => $data); + } + + if (!isset($data['module_langname'])) + { + // The "automatic" way + $basename = (isset($data['module_basename'])) ? $data['module_basename'] : ''; + $basename = str_replace(array('/', '\\'), '', $basename); + $class = str_replace(array('/', '\\'), '', $class); + $info_file = "$class/info/{$class}_$basename.$this->phpEx"; + + // The manual and automatic ways both failed... + if (!file_exists((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file)) + { + throw new phpbb_db_migration_exception('MODULE_ADD', $class, $info_file); + } + + $classname = "{$class}_{$basename}_info"; + + if (!class_exists($classname)) + { + include((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file); + } + + $info = new $classname; + $module = $info->module(); + unset($info); + + $result = ''; + foreach ($module['modes'] as $mode => $module_info) + { + if (!isset($data['modes']) || in_array($mode, $data['modes'])) + { + $new_module = array( + 'module_basename' => $basename, + 'module_langname' => $module_info['title'], + 'module_mode' => $mode, + 'module_auth' => $module_info['auth'], + 'module_display' => (isset($module_info['display'])) ? $module_info['display'] : true, + 'before' => (isset($module_info['before'])) ? $module_info['before'] : false, + 'after' => (isset($module_info['after'])) ? $module_info['after'] : false, + ); + + // Run the "manual" way with the data we've collected. + $result .= ((isset($data['spacer'])) ? $data['spacer'] : '
') . $this->add($class, $parent, $new_module); + } + } + + return $result; + } + + // The "manual" way + add_log('admin', 'LOG_MODULE_ADD', ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname'])); + + $class = $this->db->sql_escape($class); + + if (!is_numeric($parent)) + { + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($parent) . "' + AND module_class = '$class'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row) + { + throw new phpbb_db_migration_exception('MODULE_PARENT_NOT_EXIST', $parent); + } + + $parent = $data['parent_id'] = $row['module_id']; + } + else if (!$this->exists($class, false, $parent)) + { + throw new phpbb_db_migration_exception('MODULE_PARENT_NOT_EXIST', $parent); + } + + if ($this->exists($class, $parent, $data['module_langname'])) + { + throw new phpbb_db_migration_exception('MODULE_ALREADY_EXIST', $data['module_langname']); + } + + if (!class_exists('acp_modules')) + { + include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->phpEx); + $this->user->add_lang('acp/modules'); + } + $acp_modules = new acp_modules(); + + $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'] : '', + ); + $result = $acp_modules->update_module_data($module_data, true); + + // update_module_data can either return a string or an empty array... + if (is_string($result)) + { + // Error + throw new phpbb_db_migration_exception('MODULE_ERROR', $result); + } + else + { + // Success + + // Move the module if requested above/below an existing one + if (isset($data['before']) && $data['before']) + { + $sql = 'SELECT left_id FROM ' . MODULES_TABLE . ' + WHERE module_class = \'' . $class . '\' + AND parent_id = ' . (int) $parent . ' + AND module_langname = \'' . $this->db->sql_escape($data['before']) . '\''; + $this->db->sql_query($sql); + $to_left = $this->db->sql_fetchfield('left_id'); + + $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 + WHERE module_class = '$class' + AND left_id >= $to_left + AND left_id < {$module_data['left_id']}"; + $this->db->sql_query($sql); + + $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = $to_left, right_id = " . ($to_left + 1) . " + WHERE module_class = '$class' + AND module_id = {$module_data['module_id']}"; + $this->db->sql_query($sql); + } + else if (isset($data['after']) && $data['after']) + { + $sql = 'SELECT right_id FROM ' . MODULES_TABLE . ' + WHERE module_class = \'' . $class . '\' + AND parent_id = ' . (int) $parent . ' + AND module_langname = \'' . $this->db->sql_escape($data['after']) . '\''; + $this->db->sql_query($sql); + $to_right = $this->db->sql_fetchfield('right_id'); + + $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 + WHERE module_class = '$class' + AND left_id >= $to_right + AND left_id < {$module_data['left_id']}"; + $this->db->sql_query($sql); + + $sql = 'UPDATE ' . MODULES_TABLE . ' SET left_id = ' . ($to_right + 1) . ', right_id = ' . ($to_right + 2) . " + WHERE module_class = '$class' + AND module_id = {$module_data['module_id']}"; + $this->db->sql_query($sql); + } + } + + // Clear the Modules Cache + $this->cache->destroy("_modules_$class"); + + return false; + } + + /** + * Module Remove + * + * Remove a module + * + * @param string $class The module class(acp|mcp|ucp) + * @param int|string|bool $parent The parent module_id|module_langname (0 for no parent). Use false to ignore the parent check and check class wide. + * @param int|string $module The module id|module_langname + * @param string|bool $include_path If you would like to use a custom include path, specify that here + */ + public function remove($class, $parent = 0, $module = '', $include_path = false) + { + // Imitation of module_add's "automatic" and "manual" method so the uninstaller works from the same set of instructions for umil_auto + if (is_array($module)) + { + if (isset($module['module_langname'])) + { + // Manual Method + return $this->remove($class, $parent, $module['module_langname'], $include_path); + } + + // Failed. + if (!isset($module['module_basename'])) + { + throw new phpbb_db_migration_exception('MODULE_NOT_EXIST'); + } + + // Automatic method + $basename = str_replace(array('/', '\\'), '', $module['module_basename']); + $class = str_replace(array('/', '\\'), '', $class); + $info_file = "$class/info/{$class}_$basename.$this->phpEx"; + + if (!file_exists((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file)) + { + throw new phpbb_db_migration_exception('MODULE_NOT_EXIST', $info_file); + } + + $classname = "{$class}_{$basename}_info"; + + if (!class_exists($classname)) + { + include((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file); + } + + $info = new $classname; + $module_info = $info->module(); + unset($info); + + foreach ($module_info['modes'] as $mode => $info) + { + if (!isset($module['modes']) || in_array($mode, $module['modes'])) + { + $this->remove($class, $parent, $info['title']) . '
'; + } + } + return false; + } + else + { + $class = $this->db->sql_escape($class); + + if (!$this->exists($class, $parent, $module)) + { + throw new phpbb_db_migration_exception('MODULE_NOT_EXIST', ((isset($this->user->lang[$module])) ? $this->user->lang[$module] : $module)); + } + + $parent_sql = ''; + if ($parent !== false) + { + // Allows '' to be sent as 0 + $parent = (!$parent) ? 0 : $parent; + + if (!is_numeric($parent)) + { + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($parent) . "' + AND module_class = '$class'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + // we know it exists from the module_exists check + $parent_sql = 'AND parent_id = ' . (int) $row['module_id']; + } + else + { + $parent_sql = 'AND parent_id = ' . (int) $parent; + } + } + + $module_ids = array(); + if (!is_numeric($module)) + { + $module = $this->db->sql_escape($module); + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '$module' + AND module_class = '$class' + $parent_sql"; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $module_ids[] = (int) $row['module_id']; + } + $this->db->sql_freeresult($result); + + $module_name = $module; + } + else + { + $module = (int) $module; + $sql = 'SELECT module_langname FROM ' . MODULES_TABLE . " + WHERE module_id = $module + AND module_class = '$class' + $parent_sql"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $module_name = $row['module_langname']; + $module_ids[] = $module; + } + + if (!class_exists('acp_modules')) + { + include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->phpEx); + $this->user->add_lang('acp/modules'); + } + $acp_modules = new acp_modules(); + $acp_modules->module_class = $class; + + foreach ($module_ids as $module_id) + { + $result = $acp_modules->delete_module($module_id); + if (!empty($result)) + { + throw new phpbb_db_migration_exception('CANNOT_REMOVE_MODULE', $module_id); + } + } + + $cache->destroy("_modules_$class"); + + return false; + } + } +} \ No newline at end of file diff --git a/phpBB/includes/db/migration/tools/permission.php b/phpBB/includes/db/migration/tools/permission.php new file mode 100644 index 0000000000..3fbe7c649c --- /dev/null +++ b/phpBB/includes/db/migration/tools/permission.php @@ -0,0 +1,480 @@ +db->sql_escape($auth_option) . "'" + . $type_sql; + $result = $this->db->sql_query($sql); + + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + return true; + } + + return false; + } + + /** + * Permission Add + * + * Add a permission (auth) option + * + * @param string $auth_option The name of the permission (auth) option + * @param bool $global True for checking a global permission setting, False for a local permission setting + * + * @return result + */ + public function add($auth_option, $global = true) + { + if ($this->exists($auth_option, $global)) + { + throw new phpbb_db_migration_exception('PERMISSION_ALREADY_EXISTS', $auth_option); + } + + // We've added permissions, so set to true to notify the user. + $this->permissions_added = true; + + if (!class_exists('auth_admin')) + { + include($this->phpbb_root_path . 'includes/acp/auth.' . $this->phpEx); + } + $auth_admin = new auth_admin(); + + // We have to add a check to see if the !$global (if global, local, and if local, global) permission already exists. If it does, acl_add_option currently has a bug which would break the ACL system, so we are having a work-around here. + if ($this->exists($auth_option, !$global)) + { + $sql_ary = array( + 'is_global' => 1, + 'is_local' => 1, + ); + $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' + SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE auth_option = \'' . $this->db->sql_escape($auth_option) . "'"; + $this->db->sql_query($sql); + } + else + { + if ($global) + { + $auth_admin->acl_add_option(array('global' => array($auth_option))); + } + else + { + $auth_admin->acl_add_option(array('local' => array($auth_option))); + } + } + + return false; + } + + /** + * Permission Remove + * + * Remove a permission (auth) option + * + * @param string $auth_option The name of the permission (auth) option + * @param bool $global True for checking a global permission setting, False for a local permission setting + * + * @return result + */ + public function remove($auth_option, $global = true) + { + if (!$this->exists($auth_option, $global)) + { + throw new phpbb_db_migration_exception('PERMISSION_NOT_EXIST', $auth_option); + } + + if ($global) + { + $type_sql = ' AND is_global = 1'; + } + else + { + $type_sql = ' AND is_local = 1'; + } + $sql = 'SELECT auth_option_id, is_global, is_local FROM ' . ACL_OPTIONS_TABLE . " + WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" . + $type_sql; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $id = $row['auth_option_id']; + + // If it is a local and global permission, do not remove the row! :P + if ($row['is_global'] && $row['is_local']) + { + $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' + SET ' . (($global) ? 'is_global = 0' : 'is_local = 0') . ' + WHERE auth_option_id = ' . $id; + $this->db->sql_query($sql); + } + else + { + // Delete time + $this->db->sql_query('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $id); + $this->db->sql_query('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $id); + $this->db->sql_query('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $id); + $this->db->sql_query('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $id); + } + + // Purge the auth cache + $this->cache->destroy('_acl_options'); + $this->auth->acl_clear_prefetch(); + + return false; + } + + /** + * Add a new permission role + * + * @param string $role_name The new role name + * @param sting $role_type The type (u_, m_, a_) + */ + public function role_add($role_name, $role_type = '', $role_description = '') + { + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($role_name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if ($role_id) + { + throw new phpbb_db_migration_exception('ROLE_ALREADY_EXISTS', $old_role_name); + } + + $sql = 'SELECT MAX(role_order) AS max FROM ' . ACL_ROLES_TABLE . ' + WHERE role_type = \'' . $this->db->sql_escape($role_type) . '\''; + $this->db->sql_query($sql); + $role_order = $this->db->sql_fetchfield('max'); + $role_order = (!$role_order) ? 1 : $role_order + 1; + + $sql_ary = array( + 'role_name' => $role_name, + 'role_description' => $role_description, + 'role_type' => $role_type, + 'role_order' => $role_order, + ); + + $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); + $this->db->sql_query($sql); + + return false; + } + + /** + * Update the name on a permission role + * + * @param string $old_role_name The old role name + * @param string $new_role_name The new role name + */ + public function role_update($old_role_name, $new_role_name = '') + { + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($old_role_name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + throw new phpbb_db_migration_exception('ROLE_NOT_EXISTS', $old_role_name); + } + + $sql = 'UPDATE ' . ACL_ROLES_TABLE . ' + SET role_name = \'' . $this->db->sql_escape($new_role_name) . '\' + WHERE role_name = \'' . $this->db->sql_escape($old_role_name) . '\''; + $this->db->sql_query($sql); + + return false; + } + + /** + * Remove a permission role + * + * @param string $role_name The role name to remove + */ + public function role_remove($role_name) + { + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($role_name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + throw new phpbb_db_migration_exception('ROLE_NOT_EXIST', $role_name); + } + + $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + + $sql = 'DELETE FROM ' . ACL_ROLES_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + + $this->auth->acl_clear_prefetch(); + + return false; + } + + /** + * Permission Set + * + * Allows you to set permissions for a certain group/role + * + * @param string $name The name of the role/group + * @param string|array $auth_option The auth_option or array of auth_options you would like to set + * @param string $type The type (role|group) + * @param bool $has_permission True if you want to give them permission, false if you want to deny them permission + */ + public function permission_set($name, $auth_option = array(), $type = 'role', $has_permission = true) + { + if (!is_array($auth_option)) + { + $auth_option = array($auth_option); + } + + $new_auth = array(); + $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $new_auth[] = $row['auth_option_id']; + } + $this->db->sql_freeresult($result); + + if (!sizeof($new_auth)) + { + return false; + } + + $current_auth = array(); + + $type = (string) $type; // Prevent PHP bug. + + switch ($type) + { + case 'role' : + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + throw new phpbb_db_migration_exception('ROLE_NOT_EXIST', $name); + } + + $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_ROLES_DATA_TABLE . ' + WHERE role_id = ' . $role_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $current_auth[$row['auth_option_id']] = $row['auth_setting']; + } + $this->db->sql_freeresult($result); + break; + + case 'group' : + $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' WHERE group_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $group_id = $this->db->sql_fetchfield('group_id'); + + if (!$group_id) + { + throw new phpbb_db_migration_exception('GROUP_NOT_EXIST', $name); + } + + // If the group has a role set for them we will add the requested permissions to that role. + $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id . ' + AND auth_role_id <> 0 + AND forum_id = 0'; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('auth_role_id'); + if ($role_id) + { + $sql = 'SELECT role_name FROM ' . ACL_ROLES_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + $role_name = $this->db->sql_fetchfield('role_name'); + + return $this->set($role_name, $auth_option, 'role', $has_permission); + } + + $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $current_auth[$row['auth_option_id']] = $row['auth_setting']; + } + $this->db->sql_freeresult($result); + break; + } + + $sql_ary = array(); + switch ($type) + { + case 'role' : + foreach ($new_auth as $auth_option_id) + { + if (!isset($current_auth[$auth_option_id])) + { + $sql_ary[] = array( + 'role_id' => $role_id, + 'auth_option_id' => $auth_option_id, + 'auth_setting' => $has_permission, + ); + } + } + + $this->db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); + break; + + case 'group' : + foreach ($new_auth as $auth_option_id) + { + if (!isset($current_auth[$auth_option_id])) + { + $sql_ary[] = array( + 'group_id' => $group_id, + 'auth_option_id' => $auth_option_id, + 'auth_setting' => $has_permission, + ); + } + } + + $this->db->sql_multi_insert(ACL_GROUPS_TABLE, $sql_ary); + break; + } + + $this->auth->acl_clear_prefetch(); + + return false; + } + + /** + * Permission Unset + * + * Allows you to unset (remove) permissions for a certain group/role + * + * @param string $name The name of the role/group + * @param string|array $auth_option The auth_option or array of auth_options you would like to set + * @param string $type The type (role|group) + */ + public function permission_unset($name, $auth_option = array(), $type = 'role') + { + if (!is_array($auth_option)) + { + $auth_option = array($auth_option); + } + + $to_remove = array(); + $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $to_remove[] = $row['auth_option_id']; + } + $this->db->sql_freeresult($result); + + if (!sizeof($to_remove)) + { + return false; + } + + $type = (string) $type; // Prevent PHP bug. + + switch ($type) + { + case 'role' : + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + throw new phpbb_db_migration_exception('ROLE_NOT_EXIST', $name); + } + + $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); + $this->db->sql_query($sql); + break; + + case 'group' : + $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' + WHERE group_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $group_id = $this->db->sql_fetchfield('group_id'); + + if (!$group_id) + { + throw new phpbb_db_migration_exception('GROUP_NOT_EXIST', $name); + } + + // If the group has a role set for them we will remove the requested permissions from that role. + $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id . ' + AND auth_role_id <> 0'; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('auth_role_id'); + if ($role_id) + { + $sql = 'SELECT role_name FROM ' . ACL_ROLES_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + $role_name = $this->db->sql_fetchfield('role_name'); + + return $this->permission_unset($role_name, $auth_option, 'role'); + } + + $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); + $this->db->sql_query($sql); + break; + } + + $this->auth->acl_clear_prefetch(); + + return false; + } +} \ No newline at end of file diff --git a/phpBB/includes/db/migrationtools/umil.php b/phpBB/includes/db/migration/tools/umil.php similarity index 100% rename from phpBB/includes/db/migrationtools/umil.php rename to phpBB/includes/db/migration/tools/umil.php diff --git a/phpBB/includes/db/migrationtools/base.php b/phpBB/includes/db/migrationtools/base.php deleted file mode 100644 index 7fc6057e3a..0000000000 --- a/phpBB/includes/db/migrationtools/base.php +++ /dev/null @@ -1,15 +0,0 @@ -db->sql_escape($config_name) . "'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if ($row) - { - if (!isset($this->config[$config_name])) - { - $this->config[$config_name] = $row['config_value']; - - if (!$row['is_dynamic']) - { - $this->cache->destroy('config'); - } - } - - return ($return_result) ? $row : true; - } - - // this should never happen, but if it does, we need to remove the config from the array - if (isset($this->config[$config_name])) - { - unset($this->config[$config_name]); - $this->cache->destroy('config'); - } - - return false; - } - - /** - * Config Add - * - * This function allows you to add a config setting. - * - * @param string $config_name The name of the config setting you would like to add - * @param mixed $config_value The value of the config setting - * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. - * - * @return result - */ - function config_add($config_name, $config_value = '', $is_dynamic = false) - { - if ($this->config_exists($config_name)) - { - return $this->umil_end('CONFIG_ALREADY_EXISTS', $config_name); - } - - set_config($config_name, $config_value, $is_dynamic); - } - - /** - * Config Update - * - * This function allows you to update an existing config setting. - * - * @param string $config_name The name of the config setting you would like to update - * @param mixed $config_value The value of the config setting - * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. - * - * @return result - */ - function config_update($config_name, $config_value = '') - { - if (!$this->config_exists($config_name)) - { - return $this->umil_end('CONFIG_NOT_EXIST', $config_name); - } - - set_config($config_name, $config_value); - } - - /** - * Config Remove - * - * This function allows you to remove an existing config setting. - * - * @param string $config_name The name of the config setting you would like to remove - * - * @return result - */ - function config_remove($config_name) - { - if (!$this->config_exists($config_name)) - { - return $this->umil_end('CONFIG_NOT_EXIST', $config_name); - } - - $sql = 'DELETE FROM ' . CONFIG_TABLE . " - WHERE config_name = '" . $this->db->sql_escape($config_name) . "'"; - $this->db->sql_query($sql); - - unset($this->config[$config_name]); - $this->cache->destroy('config'); - } -} \ No newline at end of file diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 912a7b34ba..9f94273c63 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -45,10 +45,10 @@ class phpbb_db_migrator * @param string $phpbb_root_path * @param string $php_ext */ - function phpbb_db_migrator(&$db, &$db_tools, $table_prefix, $migrations_table, $phpbb_root_path, $php_ext) + function phpbb_db_migrator($db, $db_tools, $table_prefix, $migrations_table, $phpbb_root_path, $php_ext) { - $this->db = &$db; - $this->db_tools = &$db_tools; + $this->db = $db; + $this->db_tools = $db_tools; $this->table_prefix = $table_prefix; $this->migrations_table = $migrations_table; $this->migrations = array(); @@ -131,7 +131,7 @@ class phpbb_db_migrator return false; } - $migration =& new $name($this->db, $this->db_tools, $this->table_prefix, $this->phpbb_root_path, $this->php_ext); + $migration = new $name($this->db, $this->db_tools, $this->table_prefix, $this->phpbb_root_path, $this->php_ext); $state = (isset($this->migration_state[$name])) ? $this->migration_state[$name] : array( @@ -182,7 +182,7 @@ class phpbb_db_migrator return true; } - function process_data_step(&$migration) + function process_data_step($migration) { $continue = false; $steps = $migration->update_data(); @@ -199,7 +199,7 @@ class phpbb_db_migrator return $continue; } - function run_step(&$step) + function run_step($step) { } @@ -234,7 +234,7 @@ class phpbb_db_migrator return true; } - $migration =& new $name($this->db, $this->db_tools, $this->table_prefix, $this->phpbb_root_path, $this->php_ext); + $migration = new $name($this->db, $this->db_tools, $this->table_prefix, $this->phpbb_root_path, $this->php_ext); $depends = $migration->depends_on(); foreach ($depends as $depend) From 41de95bc11c0b64eafa294f03432f619d3d712d5 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 11 Nov 2012 12:12:05 +0100 Subject: [PATCH 21/90] [feature/migrations] Process migration steps and move to PHP5 code --- phpBB/includes/db/migration.php | 26 +++---- phpBB/includes/db/migrator.php | 126 +++++++++++++++++++++++++++----- tests/dbal/migration/dummy.php | 9 ++- 3 files changed, 128 insertions(+), 33 deletions(-) diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration.php index c98ac8728a..4e83d2570c 100644 --- a/phpBB/includes/db/migration.php +++ b/phpBB/includes/db/migration.php @@ -26,14 +26,14 @@ if (!defined('IN_PHPBB')) */ class phpbb_db_migration { - var $db; - var $db_tools; - var $table_prefix; + protected $db; + protected $db_tools; + protected $table_prefix; - var $phpbb_root_path; - var $php_ext; + protected $phpbb_root_path; + protected $php_ext; - var $errors; + protected $errors; /** * Migration constructor @@ -44,7 +44,7 @@ class phpbb_db_migration * @param string $phpbb_root_path * @param string $php_ext */ - function phpbb_db_migration($db, $db_tools, $table_prefix, $phpbb_root_path, $php_ext) + public function phpbb_db_migration($db, $db_tools, $table_prefix, $phpbb_root_path, $php_ext) { $this->db = $db; $this->db_tools = $db_tools; @@ -61,7 +61,7 @@ class phpbb_db_migration * * @return array An array of migration class names */ - function depends_on() + public function depends_on() { return array(); } @@ -71,24 +71,24 @@ class phpbb_db_migration * * @return array */ - function update_schema() + public function update_schema() { return array(); } /** - * Updates data + * Updates data by returning a list of instructions to be executed * - * @return null + * @return array */ - function update_data() + public function update_data() { } /** * Wrapper for running queries to generate user feedback on updates */ - function sql_query($sql) + protected function sql_query($sql) { if (defined('DEBUG_EXTRA')) { diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 9f94273c63..9187e09869 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -22,17 +22,17 @@ if (!defined('IN_PHPBB')) */ class phpbb_db_migrator { - var $db; - var $db_tools; - var $table_prefix; + protected $db; + protected $db_tools; + protected $table_prefix; - var $phpbb_root_path; - var $php_ext; + protected $phpbb_root_path; + protected $php_ext; - var $migrations_table; - var $migration_state; + protected $migrations_table; + protected $migration_state; - var $migrations; + protected $migrations; /** * Constructor of the database migrator @@ -45,7 +45,7 @@ class phpbb_db_migrator * @param string $phpbb_root_path * @param string $php_ext */ - function phpbb_db_migrator($db, $db_tools, $table_prefix, $migrations_table, $phpbb_root_path, $php_ext) + public function phpbb_db_migrator($db, $db_tools, $table_prefix, $migrations_table, $phpbb_root_path, $php_ext) { $this->db = $db; $this->db_tools = $db_tools; @@ -64,7 +64,7 @@ class phpbb_db_migrator * * @return null */ - function load_migration_state() + public function load_migration_state() { $sql = "SELECT * FROM " . $this->migrations_table; @@ -85,7 +85,7 @@ class phpbb_db_migrator * @param array $class_names An array of migration class names * @return null */ - function set_migrations($class_names) + public function set_migrations($class_names) { $this->migrations = $class_names; } @@ -98,7 +98,7 @@ class phpbb_db_migrator * * @return null */ - function update() + public function update() { foreach ($this->migrations as $name) { @@ -124,7 +124,7 @@ class phpbb_db_migrator * @param string The class name of the migration * @return bool Whether any update step was successfully run */ - function try_apply($name) + protected function try_apply($name) { if (!class_exists($name)) { @@ -182,7 +182,7 @@ class phpbb_db_migrator return true; } - function process_data_step($migration) + protected function process_data_step($migration) { $continue = false; $steps = $migration->update_data(); @@ -190,6 +190,7 @@ class phpbb_db_migrator foreach ($steps as $step) { $continue = $this->run_step($step); + if (!$continue) { return false; @@ -199,12 +200,99 @@ class phpbb_db_migrator return $continue; } - function run_step($step) + protected function run_step($step) { + try + { + $callable_and_parameters = $this->get_callable_from_step($step); + $callable = $callable_and_parameters[0]; + $parameters = $callable_and_parameters[1]; + call_user_func_array($callable, $parameters); + + return false; + } + catch (phpbb_db_migration_exception $e) + { + echo $e;die(); + } } - function insert_migration($name, $state) + public function get_callable_from_step($step) + { + $type = $step[0]; + $parameters = $step[1]; + + $parts = explode('.', $type); + + $class = $parts[0]; + $method = false; + + if (isset($parts[1])) + { + $method = $parts[1]; + } + + switch ($class) + { + case 'if': + if (!isset($parameters[0])) + { + throw new phpbb_db_migration_exception('MIGRATION_INVALID_DATA_MISSING_CONDITION', $step); + } + + if (!isset($parameters[1])) + { + throw new phpbb_db_migration_exception('MIGRATION_INVALID_DATA_MISSING_STEP', $step); + } + + $condition = $parameters[0]; + $step = $parameters[1]; + + $callable_and_parameters = $this->get_callable_from_step($step); + $callable = $callable_and_parameters[0]; + $sub_parameters = $callable_and_parameters[1]; + return array( + function ($condition) use ($callable, $sub_parameters) { + return call_user_func_array($callable, $sub_parameters); + }, + array($condition) + ); + break; + case 'custom': + if (!is_callable($parameters[0])) + { + throw new phpbb_db_migration_exception('MIGRATION_INVALID_DATA_CUSTOM_NOT_CALLABLE', $step); + } + + return array($parameters[0], array()); + break; + + default: + if (!$method) + { + throw new phpbb_db_migration_exception('MIGRATION_INVALID_DATA_UNKNOWN_TYPE', $step); + } + + if (!isset($this->tools[$class])) + { + throw new phpbb_db_migration_exception('MIGRATION_INVALID_DATA_UNDEFINED_TOOL', $step); + } + + if (!method_exists(get_class($this->tools[$class]), $method)) + { + throw new phpbb_db_migration_exception('MIGRATION_INVALID_DATA_UNDEFINED_METHOD', $step); + } + + return array( + array($this->tools[$class], $method), + $parameters + ); + break; + } + } + + protected function insert_migration($name, $state) { $migration_row = $state; $migration_row['migration_name'] = $name; @@ -222,7 +310,7 @@ class phpbb_db_migrator * @param string $name The class name of the migration * @return bool Whether the migration cannot be fulfilled */ - function unfulfillable($name) + public function unfulfillable($name) { if (isset($this->migration_state[$name])) { @@ -253,7 +341,7 @@ class phpbb_db_migrator * * @return bool Whether the migrations have been applied */ - function finished() + public function finished() { foreach ($this->migrations as $name) { @@ -279,7 +367,7 @@ class phpbb_db_migrator return true; } - function apply_schema_changes($schema_changes) + protected function apply_schema_changes($schema_changes) { $this->db_tools->perform_schema_changes($schema_changes); } diff --git a/tests/dbal/migration/dummy.php b/tests/dbal/migration/dummy.php index 0567b50740..942c499bb5 100644 --- a/tests/dbal/migration/dummy.php +++ b/tests/dbal/migration/dummy.php @@ -27,6 +27,13 @@ class phpbb_dbal_migration_dummy extends phpbb_db_migration function update_data() { - $this->db->sql_query('UPDATE phpbb_config SET extra_column = 1'); + return array( + array('if', array(true, array('custom', array(array($this, 'set_extra_column'))))), + ); + } + + public function set_extra_column() + { + $this->sql_query('UPDATE phpbb_config SET extra_column = 1'); } } From 6c44dadecbf50d6550f98dd1e1694519f39be680 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 8 Jan 2013 22:07:26 -0600 Subject: [PATCH 22/90] [feature/migrations] Move migrator to service container Version numbers 3.1 updates Restore database_update.php file to what it was in develop Get first forum to place global announcements in PHPBB3-9737 --- phpBB/config/services.yml | 45 + phpBB/config/tables.yml | 1 + phpBB/develop/create_schema_files.php | 14 +- phpBB/includes/db/db_tools.php | 10 + phpBB/includes/db/migration.php | 20 +- phpBB/includes/db/migration/data/3_0_1.php | 3 + phpBB/includes/db/migration/data/3_0_10.php | 3 + .../includes/db/migration/data/3_0_10_rc1.php | 2 + .../includes/db/migration/data/3_0_10_rc2.php | 3 + .../includes/db/migration/data/3_0_10_rc3.php | 3 + phpBB/includes/db/migration/data/3_0_11.php | 3 + .../includes/db/migration/data/3_0_11_rc1.php | 2 + .../data/{3_0_11_rc2 => 3_0_11_rc2.php} | 3 + .../includes/db/migration/data/3_0_12_rc1.php | 8 +- .../includes/db/migration/data/3_0_1_rc1.php | 2 + phpBB/includes/db/migration/data/3_0_2.php | 3 + .../includes/db/migration/data/3_0_2_rc1.php | 4 +- .../includes/db/migration/data/3_0_2_rc2.php | 3 + phpBB/includes/db/migration/data/3_0_3.php | 5 +- .../includes/db/migration/data/3_0_3_rc1.php | 2 + phpBB/includes/db/migration/data/3_0_4.php | 2 + .../includes/db/migration/data/3_0_4_rc1.php | 2 + phpBB/includes/db/migration/data/3_0_5.php | 3 + .../db/migration/data/3_0_5_rc1part2.php | 3 + phpBB/includes/db/migration/data/3_0_6.php | 3 + .../includes/db/migration/data/3_0_6_rc1.php | 2 + .../includes/db/migration/data/3_0_6_rc2.php | 3 + .../includes/db/migration/data/3_0_6_rc3.php | 2 + .../includes/db/migration/data/3_0_6_rc4.php | 3 + phpBB/includes/db/migration/data/3_0_7.php | 3 + .../includes/db/migration/data/3_0_7_pl1.php | 3 + .../includes/db/migration/data/3_0_7_rc1.php | 2 + .../includes/db/migration/data/3_0_7_rc2.php | 2 + phpBB/includes/db/migration/data/3_0_8.php | 3 + .../includes/db/migration/data/3_0_8_rc1.php | 2 + phpBB/includes/db/migration/data/3_0_9.php | 3 + .../includes/db/migration/data/3_0_9_rc1.php | 2 + .../includes/db/migration/data/3_0_9_rc2.php | 3 + .../includes/db/migration/data/3_0_9_rc3.php | 3 + .../includes/db/migration/data/3_0_9_rc4.php | 3 + .../includes/db/migration/data/3_1_0_dev.php | 283 ++++ .../includes/db/migration/data/extensions.php | 48 + .../db/migration/data/style_update_p1.php | 99 ++ .../db/migration/data/style_update_p2.php | 83 + .../migration/data/timezone.php} | 60 +- phpBB/includes/db/migration/tools/base.php | 47 - phpBB/includes/db/migration/tools/config.php | 26 +- phpBB/includes/db/migration/tools/module.php | 38 +- .../db/migration/tools/permission.php | 26 +- phpBB/includes/db/migrator.php | 33 +- phpBB/install/database_update.php | 1424 +++++++++++++++++ 51 files changed, 2252 insertions(+), 106 deletions(-) rename phpBB/includes/db/migration/data/{3_0_11_rc2 => 3_0_11_rc2.php} (86%) create mode 100644 phpBB/includes/db/migration/data/3_1_0_dev.php create mode 100644 phpBB/includes/db/migration/data/extensions.php create mode 100644 phpBB/includes/db/migration/data/style_update_p1.php create mode 100644 phpBB/includes/db/migration/data/style_update_p2.php rename phpBB/includes/{update_helpers.php => db/migration/data/timezone.php} (74%) delete mode 100644 phpBB/includes/db/migration/tools/base.php diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 5c450a5cf6..4125491dd0 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -94,6 +94,12 @@ services: calls: - [sql_connect, [%dbal.dbhost%, %dbal.dbuser%, %dbal.dbpasswd%, %dbal.dbname%, %dbal.dbport%, false, %dbal.new_link%]] + dbal.tools: + file: %core.root_path%includes/db/db_tools.%core.php_ext% + class: phpbb_db_tools + arguments: + - @dbal.conn + event.subscriber_loader: class: phpbb_event_extension_subscriber_loader arguments: @@ -156,6 +162,45 @@ services: tags: - { name: kernel.event_subscriber } + migrator: + class: phpbb_db_migrator + arguments: + - @service_container + + migrator.tools_collection + class: phpbb_di_service_collection + arguments: + - @service_container + + migrator.tools.config: + class: phpbb_db_migration_tools_config + arguments: + - @config + tags: + - { name: migrator:tool } + + migrator.tools.module: + class: phpbb_db_migration_tools_module + arguments: + - @db + - @cache + - @user + - %core.root_path% + - %core.php_ext% + tags: + - { name: migrator:tool } + + migrator.tools.permission: + class: phpbb_db_migration_tools_permission + arguments: + - @db + - @cache + - @auth + - %core.root_path% + - %core.php_ext% + tags: + - { name: migrator:tool } + request: class: phpbb_request diff --git a/phpBB/config/tables.yml b/phpBB/config/tables.yml index cfc6dbcfed..a9414cf66c 100644 --- a/phpBB/config/tables.yml +++ b/phpBB/config/tables.yml @@ -1,3 +1,4 @@ parameters: tables.config: %core.table_prefix%config tables.ext: %core.table_prefix%ext + tables.migrations: %core.table_prefix%migrations diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 3d3e478032..1abafb3b6d 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1258,7 +1258,7 @@ function get_schema_struct() ), ); - $schema_data['phpbb_moderator_cache'] = array( + $schema_data['phpbb_migrations'] = array( 'COLUMNS' => array( 'forum_id' => array('UINT', 0), 'user_id' => array('UINT', 0), @@ -1273,6 +1273,18 @@ function get_schema_struct() ), ); + $schema_data['phpbb_moderator_cache'] = array( + 'COLUMNS' => array( + 'migration_name' => array('VCHAR', ''), + 'migration_schema_done' => array('BOOL', 0), + 'migration_data_done' => array('BOOL', 0), + 'migration_data_state' => array('TEXT', ''), + 'migration_start_time' => array('TIMESTAMP', 0), + 'migration_end_time' => array('TIMESTAMP', 0), + ), + 'PRIMARY_KEY' => 'migration_name', + ); + $schema_data['phpbb_modules'] = array( 'COLUMNS' => array( 'module_id' => array('UINT', NULL, 'auto_increment'), diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index 2bb016cebd..5329d871c8 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -345,6 +345,16 @@ class phpbb_db_tools } } + /** + * Setter for {@link $return_statements return_statements}. + * + * @param bool $return_statements True if SQL should not be executed but returned as strings + */ + public function set_return_statements($return_statements) + { + $this->return_statements = $return_statements; + } + /** * Gets a list of tables in the database. * diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration.php index 4e83d2570c..1acef2d429 100644 --- a/phpBB/includes/db/migration.php +++ b/phpBB/includes/db/migration.php @@ -26,6 +26,7 @@ if (!defined('IN_PHPBB')) */ class phpbb_db_migration { + protected $config; protected $db; protected $db_tools; protected $table_prefix; @@ -38,20 +39,17 @@ class phpbb_db_migration /** * Migration constructor * - * @param dbal $db Connected database abstraction instance - * @param phpbb_db_tools $db_tools Instance of db schema manipulation tools - * @param string $table_prefix The prefix for all table names - * @param string $phpbb_root_path - * @param string $php_ext + * @param \Symfony\Component\DependencyInjection\ContainerInterface $container Container supplying dependencies */ - public function phpbb_db_migration($db, $db_tools, $table_prefix, $phpbb_root_path, $php_ext) + public function phpbb_db_migration(\Symfony\Component\DependencyInjection\ContainerInterface $container) { - $this->db = $db; - $this->db_tools = $db_tools; - $this->table_prefix = $table_prefix; + $this->config = $this->container->get('config'); + $this->db = $this->container->get('dbal.conn'); + $this->db_tools = $this->container->get('dbal.tools'); + $this->table_prefix = $this->container->getParameters('core.table_prefix'); - $this->phpbb_root_path = $phpbb_root_path; - $this->php_ext = $php_ext; + $this->phpbb_root_path = $this->container->getParameters('core.root_path'); + $this->php_ext = $this->container->getParameters('core.php_ext'); $this->errors = array(); } diff --git a/phpBB/includes/db/migration/data/3_0_1.php b/phpBB/includes/db/migration/data/3_0_1.php index 294db3d946..a2332c9b59 100644 --- a/phpBB/includes/db/migration/data/3_0_1.php +++ b/phpBB/includes/db/migration/data/3_0_1.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_1 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.1')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_10.php b/phpBB/includes/db/migration/data/3_0_10.php index 6d39969d48..07410c5ba1 100644 --- a/phpBB/includes/db/migration/data/3_0_10.php +++ b/phpBB/includes/db/migration/data/3_0_10.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_10 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.10')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_10_rc1.php b/phpBB/includes/db/migration/data/3_0_10_rc1.php index 06105c5b0d..daac50a631 100644 --- a/phpBB/includes/db/migration/data/3_0_10_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_10_rc1.php @@ -23,6 +23,8 @@ class phpbb_db_migration_data_3_0_10_rc1 extends phpbb_db_migration { return array( array('config.add', array('email_max_chunk_size', 50)), + + array('config.update', array('version', '3.0.10-rc1')), ); } } diff --git a/phpBB/includes/db/migration/data/3_0_10_rc2.php b/phpBB/includes/db/migration/data/3_0_10_rc2.php index 04161caf28..234e4c5fc7 100644 --- a/phpBB/includes/db/migration/data/3_0_10_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_10_rc2.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_10_rc2 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.10-rc2')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_10_rc3.php b/phpBB/includes/db/migration/data/3_0_10_rc3.php index 539f0b8fec..075ce35e3e 100644 --- a/phpBB/includes/db/migration/data/3_0_10_rc3.php +++ b/phpBB/includes/db/migration/data/3_0_10_rc3.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_10_rc3 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.10-rc3')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_11.php b/phpBB/includes/db/migration/data/3_0_11.php index 3404272ef9..0bc9b6c4a5 100644 --- a/phpBB/includes/db/migration/data/3_0_11.php +++ b/phpBB/includes/db/migration/data/3_0_11.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_11 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.11')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_11_rc1.php b/phpBB/includes/db/migration/data/3_0_11_rc1.php index f44226df02..1509120f68 100644 --- a/phpBB/includes/db/migration/data/3_0_11_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_11_rc1.php @@ -24,6 +24,8 @@ class phpbb_db_migration_data_3_0_11_rc1 extends phpbb_db_migration return array( array('custom', array(array(&$this, 'cleanup_deactivated_styles'))), array('custom', array(array(&$this, 'delete_orphan_private_messages'))), + + array('config.update', array('version', '3.0.11-rc1')), ); } diff --git a/phpBB/includes/db/migration/data/3_0_11_rc2 b/phpBB/includes/db/migration/data/3_0_11_rc2.php similarity index 86% rename from phpBB/includes/db/migration/data/3_0_11_rc2 rename to phpBB/includes/db/migration/data/3_0_11_rc2.php index 6add980c73..f2bed54085 100644 --- a/phpBB/includes/db/migration/data/3_0_11_rc2 +++ b/phpBB/includes/db/migration/data/3_0_11_rc2.php @@ -27,5 +27,8 @@ class phpbb_db_migration_data_3_0_11_rc2 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.11-rc2')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_12_rc1.php b/phpBB/includes/db/migration/data/3_0_12_rc1.php index 734a57ecee..e5ff8c5814 100644 --- a/phpBB/includes/db/migration/data/3_0_12_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_12_rc1.php @@ -7,6 +7,9 @@ * */ +/** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.12-RC1 **/ + +/* class phpbb_db_migration_data_3_0_12_rc1 extends phpbb_db_migration { function depends_on() @@ -16,11 +19,14 @@ class phpbb_db_migration_data_3_0_12_rc1 extends phpbb_db_migration function update_schema() { - /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.12-RC1 */ return array(); } function update_data() { + return array( + array('config.update', array('version', '3.0.12-rc1')), + ); } } +*/ \ No newline at end of file diff --git a/phpBB/includes/db/migration/data/3_0_1_rc1.php b/phpBB/includes/db/migration/data/3_0_1_rc1.php index 1a696e0003..a3b4810d21 100644 --- a/phpBB/includes/db/migration/data/3_0_1_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_1_rc1.php @@ -44,6 +44,8 @@ class phpbb_db_migration_data_3_0_1_rc1 extends phpbb_db_migration return array( array('custom', array(array(&$this, 'fix_unset_last_view_time'))), array('custom', array(array(&$this, 'reset_smiley_size'))), + + array('config.update', array('version', '3.0.1-rc1')), ); } diff --git a/phpBB/includes/db/migration/data/3_0_2.php b/phpBB/includes/db/migration/data/3_0_2.php index a5f94e644b..3469d8d178 100644 --- a/phpBB/includes/db/migration/data/3_0_2.php +++ b/phpBB/includes/db/migration/data/3_0_2.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_2 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.2')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_2_rc1.php b/phpBB/includes/db/migration/data/3_0_2_rc1.php index 1b4d3bc2b8..d3c2200f14 100644 --- a/phpBB/includes/db/migration/data/3_0_2_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_2_rc1.php @@ -7,7 +7,7 @@ * */ -class phpbb_db_migration_data_3_0_1_rc1 extends phpbb_db_migration +class phpbb_db_migration_data_3_0_2_rc1 extends phpbb_db_migration { function depends_on() { @@ -25,6 +25,8 @@ class phpbb_db_migration_data_3_0_1_rc1 extends phpbb_db_migration array('config.add', array('referer_validation', '1')), array('config.add', array('check_attachment_content', '1')), array('config.add', array('mime_triggers', 'body|head|html|img|plaintext|a href|pre|script|table|title')), + + array('config.update', array('version', '3.0.2-rc1')), ); } } diff --git a/phpBB/includes/db/migration/data/3_0_2_rc2.php b/phpBB/includes/db/migration/data/3_0_2_rc2.php index 9ddeb60a14..67fd1faec6 100644 --- a/phpBB/includes/db/migration/data/3_0_2_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_2_rc2.php @@ -48,5 +48,8 @@ class phpbb_db_migration_data_3_0_2_rc2 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.2-rc2')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_3.php b/phpBB/includes/db/migration/data/3_0_3.php index f989eea025..dff375f438 100644 --- a/phpBB/includes/db/migration/data/3_0_3.php +++ b/phpBB/includes/db/migration/data/3_0_3.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_3_0_3 extends phpbb_db_migration { function depends_on() { - return array('phpbb_db_migration_data_3_0_2_rc2'); + return array('phpbb_db_migration_data_3_0_3_rc1'); } function update_schema() @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_3 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.3')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_3_rc1.php b/phpBB/includes/db/migration/data/3_0_3_rc1.php index 737eab4bd3..d5c110eb7d 100644 --- a/phpBB/includes/db/migration/data/3_0_3_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_3_rc1.php @@ -39,6 +39,8 @@ class phpbb_db_migration_data_3_0_3_rc1 extends phpbb_db_migration array('config.add', array('dbms_version', '')), array('permission.add', array('u_masspm_group', phpbb_auth::IS_GLOBAL), array('custom', array(array(&$this, 'correct_acp_email_permissions'))), + + array('config.update', array('version', '3.0.3-rc1')), )); } diff --git a/phpBB/includes/db/migration/data/3_0_4.php b/phpBB/includes/db/migration/data/3_0_4.php index cd34fda9ab..4965ac38d0 100644 --- a/phpBB/includes/db/migration/data/3_0_4.php +++ b/phpBB/includes/db/migration/data/3_0_4.php @@ -23,6 +23,8 @@ class phpbb_db_migration_data_3_0_4 extends phpbb_db_migration { return array( array('custom', array(array(&$this, 'rename_log_delete_topic'))), + + array('config.update', array('version', '3.0.4')), ); } diff --git a/phpBB/includes/db/migration/data/3_0_4_rc1.php b/phpBB/includes/db/migration/data/3_0_4_rc1.php index 342f1fa910..2964dcebc9 100644 --- a/phpBB/includes/db/migration/data/3_0_4_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_4_rc1.php @@ -59,6 +59,8 @@ class phpbb_db_migration_data_3_0_4_rc1 extends phpbb_db_migration { return array( array('custom', array(array(&$this, 'update_custom_profile_fields'))), + + array('config.update', array('version', '3.0.4-rc1')), ); } diff --git a/phpBB/includes/db/migration/data/3_0_5.php b/phpBB/includes/db/migration/data/3_0_5.php index 5671832a82..2f80970781 100644 --- a/phpBB/includes/db/migration/data/3_0_5.php +++ b/phpBB/includes/db/migration/data/3_0_5.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_5 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.5')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_5_rc1part2.php b/phpBB/includes/db/migration/data/3_0_5_rc1part2.php index 6be8ea9845..1fab0f8873 100644 --- a/phpBB/includes/db/migration/data/3_0_5_rc1part2.php +++ b/phpBB/includes/db/migration/data/3_0_5_rc1part2.php @@ -30,5 +30,8 @@ class phpbb_db_migration_data_3_0_5_rc1part2 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.5-rc1')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_6.php b/phpBB/includes/db/migration/data/3_0_6.php index c2cb59e62a..26176b9437 100644 --- a/phpBB/includes/db/migration/data/3_0_6.php +++ b/phpBB/includes/db/migration/data/3_0_6.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_6 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.6')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_6_rc1.php b/phpBB/includes/db/migration/data/3_0_6_rc1.php index eefdc1692d..a868d70684 100644 --- a/phpBB/includes/db/migration/data/3_0_6_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_6_rc1.php @@ -155,6 +155,8 @@ class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration )), array('custom', array(array(&$this, 'add_newly_registered_group'))), array('custom', array(array(&$this, 'set_user_options_default'))), + + array('config.update', array('version', '3.0.6-rc1')), ); } diff --git a/phpBB/includes/db/migration/data/3_0_6_rc2.php b/phpBB/includes/db/migration/data/3_0_6_rc2.php index 07b31a53b9..4092a5fa61 100644 --- a/phpBB/includes/db/migration/data/3_0_6_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_6_rc2.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_6_rc2 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.6-rc2')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_6_rc3.php b/phpBB/includes/db/migration/data/3_0_6_rc3.php index c19a792bad..ec22d1da77 100644 --- a/phpBB/includes/db/migration/data/3_0_6_rc3.php +++ b/phpBB/includes/db/migration/data/3_0_6_rc3.php @@ -23,6 +23,8 @@ class phpbb_db_migration_data_3_0_6_rc3 extends phpbb_db_migration { return array( array('custom', array(array(&$this, 'update_cp_fields'))), + + array('config.update', array('version', '3.0.6-rc3')), ); } diff --git a/phpBB/includes/db/migration/data/3_0_6_rc4.php b/phpBB/includes/db/migration/data/3_0_6_rc4.php index c48b1ca394..e748c7a4ff 100644 --- a/phpBB/includes/db/migration/data/3_0_6_rc4.php +++ b/phpBB/includes/db/migration/data/3_0_6_rc4.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_6_rc4 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.6-rc4')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_7.php b/phpBB/includes/db/migration/data/3_0_7.php index 05781b7b49..f27b56f778 100644 --- a/phpBB/includes/db/migration/data/3_0_7.php +++ b/phpBB/includes/db/migration/data/3_0_7.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_7 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.7')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_7_pl1.php b/phpBB/includes/db/migration/data/3_0_7_pl1.php index cee7a91a2e..5543d6437a 100644 --- a/phpBB/includes/db/migration/data/3_0_7_pl1.php +++ b/phpBB/includes/db/migration/data/3_0_7_pl1.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_7_pl1 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.7-pl1')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_7_rc1.php b/phpBB/includes/db/migration/data/3_0_7_rc1.php index b2d49cce63..71584382e8 100644 --- a/phpBB/includes/db/migration/data/3_0_7_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_7_rc1.php @@ -38,6 +38,8 @@ class phpbb_db_migration_data_3_0_7_rc1 extends phpbb_db_migration array('config.add', array('feed_topics_new', $this->config['feed_overall_topics'])), array('config.add', array('feed_topics_active', $this->config['feed_overall_topics'])), array('custom', array(array(&$this, 'delete_text_templates'))), + + array('config.update', array('version', '3.0.7-rc1')), ); } diff --git a/phpBB/includes/db/migration/data/3_0_7_rc2.php b/phpBB/includes/db/migration/data/3_0_7_rc2.php index 8a751328bf..e043f35705 100644 --- a/phpBB/includes/db/migration/data/3_0_7_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_7_rc2.php @@ -23,6 +23,8 @@ class phpbb_db_migration_data_3_0_7_rc2 extends phpbb_db_migration { return array( array('custom', array(array(&$this, 'update_email_hash'))), + + array('config.update', array('version', '3.0.7-rc2')), ); } diff --git a/phpBB/includes/db/migration/data/3_0_8.php b/phpBB/includes/db/migration/data/3_0_8.php index a714a3d2f6..a5defc8278 100644 --- a/phpBB/includes/db/migration/data/3_0_8.php +++ b/phpBB/includes/db/migration/data/3_0_8.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_8 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.8')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_8_rc1.php b/phpBB/includes/db/migration/data/3_0_8_rc1.php index 73838d9d29..3f51806fd9 100644 --- a/phpBB/includes/db/migration/data/3_0_8_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_8_rc1.php @@ -37,6 +37,8 @@ class phpbb_db_migration_data_3_0_8_rc1 extends phpbb_db_migration array('config.add', array('load_unreads_search', 1)), array('config.update_if_equals', array(600, 'queue_interval', 60)), array('config.update_if_equals', array(50, 'email_package_size', 20)), + + array('config.update', array('version', '3.0.8-rc1')), ); } diff --git a/phpBB/includes/db/migration/data/3_0_9.php b/phpBB/includes/db/migration/data/3_0_9.php index 4b2c08a256..eb359e2697 100644 --- a/phpBB/includes/db/migration/data/3_0_9.php +++ b/phpBB/includes/db/migration/data/3_0_9.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_9 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.9')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_9_rc1.php b/phpBB/includes/db/migration/data/3_0_9_rc1.php index 98d3a26481..256426849c 100644 --- a/phpBB/includes/db/migration/data/3_0_9_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_9_rc1.php @@ -59,6 +59,8 @@ class phpbb_db_migration_data_3_0_9_rc1 extends phpbb_db_migration array('config.add', array('ip_login_limit_use_forwarded', 0)), array('custom', array(array(&$this, 'update_file_extension_group_names'))), array('custom', array(array(&$this, 'fix_firebird_qa_captcha'))), + + array('config.update', array('version', '3.0.9-rc1')), ); } diff --git a/phpBB/includes/db/migration/data/3_0_9_rc2.php b/phpBB/includes/db/migration/data/3_0_9_rc2.php index 589047670a..e3c4716665 100644 --- a/phpBB/includes/db/migration/data/3_0_9_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_9_rc2.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_9_rc2 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.9-rc2')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_9_rc3.php b/phpBB/includes/db/migration/data/3_0_9_rc3.php index 06061cbcb6..3cdecb96ae 100644 --- a/phpBB/includes/db/migration/data/3_0_9_rc3.php +++ b/phpBB/includes/db/migration/data/3_0_9_rc3.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_9_rc3 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.9-rc3')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_0_9_rc4.php b/phpBB/includes/db/migration/data/3_0_9_rc4.php index 04b3ae4b39..c2a92e618a 100644 --- a/phpBB/includes/db/migration/data/3_0_9_rc4.php +++ b/phpBB/includes/db/migration/data/3_0_9_rc4.php @@ -21,5 +21,8 @@ class phpbb_db_migration_data_3_0_9_rc4 extends phpbb_db_migration function update_data() { + return array( + array('config.update', array('version', '3.0.9-rc4')), + ); } } diff --git a/phpBB/includes/db/migration/data/3_1_0_dev.php b/phpBB/includes/db/migration/data/3_1_0_dev.php new file mode 100644 index 0000000000..987ab94646 --- /dev/null +++ b/phpBB/includes/db/migration/data/3_1_0_dev.php @@ -0,0 +1,283 @@ + array( + GROUPS_TABLE => array( + 'group_teampage' => array('UINT', 0, 'after' => 'group_legend'), + ), + PROFILE_FIELDS_TABLE => array( + 'field_show_on_pm' => array('BOOL', 0), + ), + STYLES_TABLE => array( + 'style_path' => array('VCHAR:100', ''), + 'bbcode_bitfield' => array('VCHAR:255', 'kNg='), + 'style_parent_id' => array('UINT:4', 0), + 'style_parent_tree' => array('TEXT', ''), + ), + REPORTS_TABLE => array( + 'reported_post_text' => array('MTEXT_UNI', ''), + 'reported_post_uid' => array('VCHAR:8', ''), + 'reported_post_bitfield' => array('VCHAR:255', ''), + ), + ), + 'change_columns' => array( + GROUPS_TABLE => array( + 'group_legend' => array('UINT', 0), + ), + ), + ); + } + + public function update_data() + { + return array( + array('config.update', array('search_type', 'phpbb_search_' . $this->config['search_type'])), + + array('config.add', array('fulltext_postgres_ts_name', 'simple')), + array('config.add', array('fulltext_postgres_min_word_len', 4)), + array('config.add', array('fulltext_postgres_max_word_len', 254)), + array('config.add', array('fulltext_sphinx_stopwords', 0)), + array('config.add', array('fulltext_sphinx_indexer_mem_limit', 512)), + + array('config.add', array('load_jquery_cdn', 0)), + array('config.add', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js')), + + array('config.add', array('use_system_cron', 0)), + + array('config.add', array('legend_sort_groupname', 0)), + array('config.add', array('teampage_forums', 1)), + array('config.add', array('teampage_memberships', 1)), + + array('config.add', array('load_cpf_pm', 0)), + + array('config.add', array('display_last_subject', 1)), + + array('config.add', array('assets_version', 1)), + + array('config.add', array('site_home_url', '')), + array('config.add', array('site_home_text', '')), + + array('module.add', array( + 'acp', + 'ACP_GROUPS', + array( + 'module_basename' => 'acp_groups', + 'modes' => array('position'), + ), + )), + array('module.add', array( + 'acp', + 'ACP_ATTACHMENTS', + array( + 'module_basename' => 'acp_attachments', + 'modes' => array('manage'), + ), + )), + array('module.add', array( + 'acp', + 'ACP_STYLE_MANAGEMENT', + array( + 'module_basename' => 'acp_styles', + 'modes' => array('install', 'cache'), + ), + )), + array('module.add', array( + 'acp', + 'UCP_PROFILE', + array( + 'module_basename' => 'ucp_profile', + 'modes' => array('autologin_keys'), + ), + )), + + array('module.remove', array( + 'acp', + 'ACP_CAT_STYLES', + array( + 'module_basename' => 'styles', + 'modes' => array('imageset', 'theme', 'template'), + ), + )), + + array('custom', array(array($this, 'rename_module_basenames'))), + array('custom', array(array($this, 'add_group_teampage'))), + array('custom', array(array($this, 'update_group_legend'))), + array('custom', array(array($this, 'localise_global_announcements'))), + ); + } + + public function rename_module_basenames() + { + // rename all module basenames to full classname + $sql = 'SELECT module_id, module_basename, module_class + FROM ' . MODULES_TABLE; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $module_id = (int) $row['module_id']; + unset($row['module_id']); + + if (!empty($row['module_basename']) && !empty($row['module_class'])) + { + // all the class names start with class name or with phpbb_ for auto loading + if (strpos($row['module_basename'], $row['module_class'] . '_') !== 0 && + strpos($row['module_basename'], 'phpbb_') !== 0) + { + $row['module_basename'] = $row['module_class'] . '_' . $row['module_basename']; + + $sql_update = $this->db->sql_build_array('UPDATE', $row); + + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET ' . $sql_update . ' + WHERE module_id = ' . $module_id; + $this->sql_query($sql); + } + } + } + + $this->db->sql_freeresult($result); + } + + public function add_group_teampage() + { + $sql = 'UPDATE ' . GROUPS_TABLE . ' + SET group_teampage = 1 + WHERE group_type = ' . GROUP_SPECIAL . " + AND group_name = 'ADMINISTRATORS'"; + $this->sql_query($sql); + + $sql = 'UPDATE ' . GROUPS_TABLE . ' + SET group_teampage = 2 + WHERE group_type = ' . GROUP_SPECIAL . " + AND group_name = 'GLOBAL_MODERATORS'"; + $this->sql_query($sql); + } + + public function update_group_legend() + { + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . ' + WHERE group_legend = 1 + ORDER BY group_name ASC'; + $result = $this->db->sql_query($sql); + + $next_legend = 1; + while ($row = $this->db->sql_fetchrow($result)) + { + $sql = 'UPDATE ' . GROUPS_TABLE . ' + SET group_legend = ' . $next_legend . ' + WHERE group_id = ' . (int) $row['group_id']; + $this->sql_query($sql); + + $next_legend++; + } + $this->db->sql_freeresult($result); + } + + public function localise_global_announcements() + { + // Localise Global Announcements + $sql = 'SELECT topic_id, topic_approved, (topic_replies + 1) AS topic_posts, topic_last_post_id, topic_last_post_subject, topic_last_post_time, topic_last_poster_id, topic_last_poster_name, topic_last_poster_colour + FROM ' . TOPICS_TABLE . ' + WHERE forum_id = 0 + AND topic_type = ' . POST_GLOBAL; + $result = $this->db->sql_query($sql); + + $global_announcements = $update_lastpost_data = array(); + $update_lastpost_data['forum_last_post_time'] = 0; + $update_forum_data = array( + 'forum_posts' => 0, + 'forum_topics' => 0, + 'forum_topics_real' => 0, + ); + + while ($row = $this->db->sql_fetchrow($result)) + { + $global_announcements[] = (int) $row['topic_id']; + + $update_forum_data['forum_posts'] += (int) $row['topic_posts']; + $update_forum_data['forum_topics_real']++; + if ($row['topic_approved']) + { + $update_forum_data['forum_topics']++; + } + + if ($update_lastpost_data['forum_last_post_time'] < $row['topic_last_post_time']) + { + $update_lastpost_data = array( + 'forum_last_post_id' => (int) $row['topic_last_post_id'], + 'forum_last_post_subject' => $row['topic_last_post_subject'], + 'forum_last_post_time' => (int) $row['topic_last_post_time'], + 'forum_last_poster_id' => (int) $row['topic_last_poster_id'], + 'forum_last_poster_name' => $row['topic_last_poster_name'], + 'forum_last_poster_colour' => $row['topic_last_poster_colour'], + ); + } + } + $this->db->sql_freeresult($result); + + if (!empty($global_announcements)) + { + // Update the post/topic-count for the forum and the last-post if needed + $sql = 'SELECT forum_id + FROM ' . FORUMS_TABLE . ' + WHERE forum_type = ' . FORUM_POST; + $result = $this->db->sql_query_limit($sql, 1); + $ga_forum_id = $this->db->sql_fetchfield('forum_id'); + $this->db->sql_freeresult($result); + + $sql = 'SELECT forum_last_post_time + FROM ' . FORUMS_TABLE . ' + WHERE forum_id = ' . $ga_forum_id; + $result = $this->db->sql_query($sql); + $lastpost = (int) $this->db->sql_fetchfield('forum_last_post_time'); + $this->db->sql_freeresult($result); + + $sql_update = 'forum_posts = forum_posts + ' . $update_forum_data['forum_posts'] . ', '; + $sql_update .= 'forum_topics_real = forum_topics_real + ' . $update_forum_data['forum_topics_real'] . ', '; + $sql_update .= 'forum_topics = forum_topics + ' . $update_forum_data['forum_topics']; + if ($lastpost < $update_lastpost_data['forum_last_post_time']) + { + $sql_update .= ', ' . $this->db->sql_build_array('UPDATE', $update_lastpost_data); + } + + $sql = 'UPDATE ' . FORUMS_TABLE . ' + SET ' . $sql_update . ' + WHERE forum_id = ' . $ga_forum_id; + $this->sql_query($sql); + + // Update some forum_ids + $table_ary = array(TOPICS_TABLE, POSTS_TABLE, LOG_TABLE, DRAFTS_TABLE, TOPICS_TRACK_TABLE); + foreach ($table_ary as $table) + { + $sql = "UPDATE $table + SET forum_id = $ga_forum_id + WHERE " . $this->db->sql_in_set('topic_id', $global_announcements); + $this->sql_query($sql); + } + unset($table_ary); + } + } +} diff --git a/phpBB/includes/db/migration/data/extensions.php b/phpBB/includes/db/migration/data/extensions.php new file mode 100644 index 0000000000..85d5511ef0 --- /dev/null +++ b/phpBB/includes/db/migration/data/extensions.php @@ -0,0 +1,48 @@ + array( + EXT_TABLE => array( + 'COLUMNS' => array( + 'ext_name' => array('VCHAR', ''), + 'ext_active' => array('BOOL', 0), + 'ext_state' => array('TEXT', ''), + ), + 'KEYS' => array( + 'ext_name' => array('UNIQUE', 'ext_name'), + ), + ), + ), + ); + } + + public function update_data() + { + return array( + array('module.add', array( + 'acp', + 'ACP_GENERAL_TASKS', + array( + 'module_basename' => 'extensions', + 'modes' => array('main'), + ), + )), + ); + } +} diff --git a/phpBB/includes/db/migration/data/style_update_p1.php b/phpBB/includes/db/migration/data/style_update_p1.php new file mode 100644 index 0000000000..d570caae04 --- /dev/null +++ b/phpBB/includes/db/migration/data/style_update_p1.php @@ -0,0 +1,99 @@ +isDir() && !in_array($fileinfo->getFilename(), $skip_dirs) && file_exists($fileinfo->getPathname() . '/style.cfg')) + { + $style_cfg = parse_cfg_file($fileinfo->getPathname() . '/style.cfg'); + if (isset($style_cfg['phpbb_version']) && version_compare($style_cfg['phpbb_version'], '3.1.0-dev', '>=')) + { + // 3.1 style + $available_styles[] = $fileinfo->getFilename(); + } + } + } + + // Get all installed styles + if ($this->db_tools->sql_table_exists(STYLES_IMAGESET_TABLE)) + { + $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_id, i.imageset_path + FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i + WHERE t.template_id = s.template_id + AND c.theme_id = s.theme_id + AND i.imageset_id = s.imageset_id"; + } + else + { + $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_id + FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . " c + WHERE t.template_id = s.template_id + AND c.theme_id = s.theme_id"; + } + $result = $this->db->sql_query($sql); + + $styles = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $styles[] = $row; + } + $this->db->sql_freeresult($result); + + // Decide which styles to keep, all others will be deleted + $valid_styles = array(); + foreach ($styles as $style_row) + { + if ( + // Delete styles with parent style (not supported yet) + $style_row['template_inherits_id'] == 0 && + // Check if components match + $style_row['template_path'] == $style_row['theme_path'] && (!isset($style_row['imageset_path']) || $style_row['template_path'] == $style_row['imageset_path']) && + // Check if components are valid + in_array($style_row['template_path'], $available_styles) + ) + { + // Valid style. Keep it + $sql_ary = array( + 'style_path' => $style_row['template_path'], + 'bbcode_bitfield' => $style_row['bbcode_bitfield'], + 'style_parent_id' => 0, + 'style_parent_tree' => '', + ); + $this->sql_query('UPDATE ' . STYLES_TABLE . ' SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE style_id = ' . $style_row['style_id'], $errored, $error_ary); + $valid_styles[] = (int) $style_row['style_id']; + } + } + } +} diff --git a/phpBB/includes/db/migration/data/style_update_p2.php b/phpBB/includes/db/migration/data/style_update_p2.php new file mode 100644 index 0000000000..2c0991de59 --- /dev/null +++ b/phpBB/includes/db/migration/data/style_update_p2.php @@ -0,0 +1,83 @@ + array( + STYLES_TABLE => array( + 'imageset_id', + 'template_id', + 'theme_id', + ), + ), + + 'drop_tables' => array( + STYLES_IMAGESET_TABLE, + STYLES_IMAGESET_DATA_TABLE, + STYLES_TEMPLATE_TABLE, + STYLES_TEMPLATE_DATA_TABLE, + STYLES_THEME_TABLE, + ), + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'styles_update'))), + ); + } + + public function styles_update() + { + // Remove old entries from styles table + if (!sizeof($valid_styles)) + { + // No valid styles: remove everything and add prosilver + $this->sql_query('DELETE FROM ' . STYLES_TABLE, $errored, $error_ary); + + $sql = 'INSERT INTO ' . STYLES_TABLE . " (style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES ('prosilver', '© phpBB Group', 1, 'prosilver', 'kNg=', 0, '')"; + $this->sql_query($sql); + + $sql = 'SELECT style_id + FROM ' . $table . " + WHERE style_name = 'prosilver'"; + $result = $this->sql_query($sql); + $default_style = $this->db->sql_fetchfield($result); + $this->db->sql_freeresult($result); + + set_config('default_style', $default_style); + + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = 0'; + $this->sql_query($sql); + } + else + { + // There are valid styles in styles table. Remove styles that are outdated + $this->sql_query('DELETE FROM ' . STYLES_TABLE . ' WHERE ' . $this->db->sql_in_set('style_id', $valid_styles, true), $errored, $error_ary); + + // Change default style + if (!in_array($config['default_style'], $valid_styles)) + { + set_config('default_style', $valid_styles[0]); + } + + // Reset styles for users + $this->sql_query('UPDATE ' . USERS_TABLE . ' SET user_style = 0 WHERE ' . $this->db->sql_in_set('user_style', $valid_styles, true), $errored, $error_ary); + } + } +} diff --git a/phpBB/includes/update_helpers.php b/phpBB/includes/db/migration/data/timezone.php similarity index 74% rename from phpBB/includes/update_helpers.php rename to phpBB/includes/db/migration/data/timezone.php index 69d678b2f8..89fafbad28 100644 --- a/phpBB/includes/update_helpers.php +++ b/phpBB/includes/db/migration/data/timezone.php @@ -1,16 +1,62 @@ array( + USERS_TABLE => array( + 'user_timezone' => array('VCHAR:100', ''), + ), + ), + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'update_timezones'))), + ); + } + + public function update_timezones() + { + // Update user timezones + $sql = 'SELECT user_dst, user_timezone + FROM ' . USERS_TABLE . ' + GROUP BY user_timezone, user_dst'; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $sql = 'UPDATE ' . USERS_TABLE . " + SET user_timezone = '" . $this->db->sql_escape($this->convert_phpbb30_timezone($row['user_timezone'], $row['user_dst'])) . "' + WHERE user_timezone = '" . $this->db->sql_escape($row['user_timezone']) . "' + AND user_dst = " . (int) $row['user_dst']; + $this->sql_query($sql); + } + $this->db->sql_freeresult($result); + + // Update board default timezone + set_config('board_timezone', $this->convert_phpbb30_timezone($config['board_timezone'], $config['board_dst'])); + + // After we have calculated the timezones we can delete user_dst column from user table. + $this->db_tools->sql_column_remove(USERS_TABLE, 'user_dst'); + } + /** * Determine the new timezone for a given phpBB 3.0 timezone and * "Daylight Saving Time" option @@ -19,7 +65,7 @@ class phpbb_update_helpers * @param $dst int Users daylight saving time * @return string Users new php Timezone which is used since 3.1 */ - function convert_phpbb30_timezone($timezone, $dst) + public function convert_phpbb30_timezone($timezone, $dst) { $offset = $timezone + $dst; diff --git a/phpBB/includes/db/migration/tools/base.php b/phpBB/includes/db/migration/tools/base.php deleted file mode 100644 index 61116d8b55..0000000000 --- a/phpBB/includes/db/migration/tools/base.php +++ /dev/null @@ -1,47 +0,0 @@ -db = $db; - $this->cache = $cache; - $this->template = $template; - $this->user = $user; - $this->auth = $auth; - $this->config = $config; - $this->phpbb_root_path = $phpbb_root_path; - $this->php_ext = $php_ext; - } -} \ No newline at end of file diff --git a/phpBB/includes/db/migration/tools/config.php b/phpBB/includes/db/migration/tools/config.php index 965ba1d136..2d58c8093c 100644 --- a/phpBB/includes/db/migration/tools/config.php +++ b/phpBB/includes/db/migration/tools/config.php @@ -7,20 +7,14 @@ * */ -class phpbb_db_migration_tools_config extends phpbb_db_migration_tools_base +class phpbb_db_migration_tools_config { - /** - * Config Exists - * - * This function is to check to see if a config variable exists or if it does not. - * - * @param string $config_name The name of the config setting you wish to check for. - * - * @return bool true/false if config exists - */ - public function exists($config_name) + /** @var phpbb_config */ + protected $config = null; + + public function __construct(phpbb_config $config) { - return (bool) $this->config->offsetExists($config_name); + $this->config = $config; } /** @@ -34,7 +28,7 @@ class phpbb_db_migration_tools_config extends phpbb_db_migration_tools_base */ public function add($config_name, $config_value = '', $is_dynamic = false) { - if ($this->config_exists($config_name)) + if (isset($this->config[$config_name])) { throw new phpbb_db_migration_exception('CONFIG_ALREADY_EXISTS', $config_name); } @@ -54,7 +48,7 @@ class phpbb_db_migration_tools_config extends phpbb_db_migration_tools_base */ public function update($config_name, $config_value = '') { - if (!$this->config_exists($config_name)) + if (!isset($this->config[$config_name])) { throw new phpbb_db_migration_exception('CONFIG_NOT_EXIST', $config_name); } @@ -75,7 +69,7 @@ class phpbb_db_migration_tools_config extends phpbb_db_migration_tools_base */ public function update_if_equals($compare, $config_name, $config_value = '') { - if (!$this->config_exists($config_name)) + if (!isset($this->config[$config_name])) { throw new phpbb_db_migration_exception('CONFIG_NOT_EXIST', $config_name); } @@ -94,7 +88,7 @@ class phpbb_db_migration_tools_config extends phpbb_db_migration_tools_base */ public function remove($config_name) { - if (!$this->config_exists($config_name)) + if (!isset($this->config[$config_name])) { throw new phpbb_db_migration_exception('CONFIG_NOT_EXIST', $config_name); } diff --git a/phpBB/includes/db/migration/tools/module.php b/phpBB/includes/db/migration/tools/module.php index df1912a022..e17197d73e 100644 --- a/phpBB/includes/db/migration/tools/module.php +++ b/phpBB/includes/db/migration/tools/module.php @@ -7,8 +7,32 @@ * */ -class phpbb_db_migration_tools_module extends phpbb_db_migration_tools_base +class phpbb_db_migration_tools_module { + /** @var phpbb_cache_service */ + protected $cache = null; + + /** @var dbal */ + protected $db = null; + + /** @var phpbb_user */ + protected $user = null; + + /** @var string */ + protected $phpbb_root_path = null; + + /** @var string */ + protected $php_ext = null; + + public function __construct(dbal $db, phpbb_cache_driver_interface $cache, $user, $phpbb_root_path, $php_ext) + { + $this->db = $db; + $this->cache = $cache; + $this->user = $user; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + } + /** * Module Exists * @@ -117,11 +141,15 @@ class phpbb_db_migration_tools_module extends phpbb_db_migration_tools_base if (!isset($data['module_langname'])) { + /** + * @TODO does not work with 3.1 modules yet, but must continue for old 3.0 versions for + * upgrades from a 3.0.x version to 3.1 + */ // The "automatic" way $basename = (isset($data['module_basename'])) ? $data['module_basename'] : ''; $basename = str_replace(array('/', '\\'), '', $basename); $class = str_replace(array('/', '\\'), '', $class); - $info_file = "$class/info/{$class}_$basename.$this->phpEx"; + $info_file = "$class/info/{$class}_$basename.{$this->php_ext}"; // The manual and automatic ways both failed... if (!file_exists((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file)) @@ -196,7 +224,7 @@ class phpbb_db_migration_tools_module extends phpbb_db_migration_tools_base if (!class_exists('acp_modules')) { - include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->phpEx); + include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext); $this->user->add_lang('acp/modules'); } $acp_modules = new acp_modules(); @@ -302,7 +330,7 @@ class phpbb_db_migration_tools_module extends phpbb_db_migration_tools_base // Automatic method $basename = str_replace(array('/', '\\'), '', $module['module_basename']); $class = str_replace(array('/', '\\'), '', $class); - $info_file = "$class/info/{$class}_$basename.$this->phpEx"; + $info_file = "$class/info/{$class}_$basename.{$this->php_ext}"; if (!file_exists((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file)) { @@ -396,7 +424,7 @@ class phpbb_db_migration_tools_module extends phpbb_db_migration_tools_base if (!class_exists('acp_modules')) { - include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->phpEx); + include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext); $this->user->add_lang('acp/modules'); } $acp_modules = new acp_modules(); diff --git a/phpBB/includes/db/migration/tools/permission.php b/phpBB/includes/db/migration/tools/permission.php index 3fbe7c649c..7694bae0cb 100644 --- a/phpBB/includes/db/migration/tools/permission.php +++ b/phpBB/includes/db/migration/tools/permission.php @@ -9,6 +9,30 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base { + /** @var phpbb_auth */ + protected $auth = null; + + /** @var phpbb_cache_service */ + protected $cache = null; + + /** @var dbal */ + protected $db = null; + + /** @var string */ + protected $phpbb_root_path = null; + + /** @var string */ + protected $php_ext = null; + + public function __construct(dbal $db, phpbb_cache_driver_interface $cache, phpbb_auth $auth, $phpbb_root_path, $php_ext) + { + $this->db = $db; + $this->cache = $cache; + $this->auth = $auth; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + } + /** * Permission Exists * @@ -69,7 +93,7 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base if (!class_exists('auth_admin')) { - include($this->phpbb_root_path . 'includes/acp/auth.' . $this->phpEx); + include($this->phpbb_root_path . 'includes/acp/auth.' . $this->php_ext); } $auth_admin = new auth_admin(); diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 9187e09869..c9590fccf6 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -22,6 +22,7 @@ if (!defined('IN_PHPBB')) */ class phpbb_db_migrator { + protected $container; protected $db; protected $db_tools; protected $table_prefix; @@ -37,24 +38,26 @@ class phpbb_db_migrator /** * Constructor of the database migrator * - * @param dbal $db Connected database abstraction instance - * @param phpbb_db_tools $db_tools Instance of db schema manipulation tools - * @param string $table_prefix The prefix for all table names - * @param string $migrations_table The name of the db table storing - * information on applied migrations - * @param string $phpbb_root_path - * @param string $php_ext + * @param \Symfony\Component\DependencyInjection\ContainerInterface $container Container supplying dependencies */ - public function phpbb_db_migrator($db, $db_tools, $table_prefix, $migrations_table, $phpbb_root_path, $php_ext) + public function phpbb_db_migrator(\Symfony\Component\DependencyInjection\ContainerInterface $container, $migrations) { - $this->db = $db; - $this->db_tools = $db_tools; - $this->table_prefix = $table_prefix; - $this->migrations_table = $migrations_table; - $this->migrations = array(); + $this->container = $container; + $this->db = $this->container->get('dbal.conn'); + $this->db_tools = $this->container->get('dbal.tools'); + $this->table_prefix = $this->container->getParameters('core.table_prefix'); + $this->migrations_table = $this->container->getParameters('tables.migrations'); + $this->migrations = $migrations; - $this->phpbb_root_path = $phpbb_root_path; - $this->php_ext = $php_ext; + $this->phpbb_root_path = $this->container->getParameters('core.root_path'); + $this->php_ext = $this->container->getParameters('core.php_ext'); + + /** @todo replace with collection_pass when merged */ + $this->tools = array( + 'config' => new phpbb_db_migration_tools_config, + 'module' => new phpbb_db_migration_tools_module, + 'permission' => new phpbb_db_migration_tools_permission, + ); $this->load_migration_state(); } diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 1f89035b43..207ad716de 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -881,6 +881,277 @@ function _add_permission(auth_admin $auth_admin, phpbb_db_driver $db, $permissio function database_update_info() { return array( + // Changes from 3.0.0 to the next version + '3.0.0' => array( + // Add the following columns + 'add_columns' => array( + FORUMS_TABLE => array( + 'display_subforum_list' => array('BOOL', 1), + ), + SESSIONS_TABLE => array( + 'session_forum_id' => array('UINT', 0), + ), + ), + 'drop_keys' => array( + GROUPS_TABLE => array('group_legend'), + ), + 'add_index' => array( + SESSIONS_TABLE => array( + 'session_forum_id' => array('session_forum_id'), + ), + GROUPS_TABLE => array( + 'group_legend_name' => array('group_legend', 'group_name'), + ), + ), + ), + // No changes from 3.0.1-RC1 to 3.0.1 + '3.0.1-RC1' => array(), + // No changes from 3.0.1 to 3.0.2-RC1 + '3.0.1' => array(), + // Changes from 3.0.2-RC1 to 3.0.2-RC2 + '3.0.2-RC1' => array( + 'change_columns' => array( + DRAFTS_TABLE => array( + 'draft_subject' => array('STEXT_UNI', ''), + ), + FORUMS_TABLE => array( + 'forum_last_post_subject' => array('STEXT_UNI', ''), + ), + POSTS_TABLE => array( + 'post_subject' => array('STEXT_UNI', '', 'true_sort'), + ), + PRIVMSGS_TABLE => array( + 'message_subject' => array('STEXT_UNI', ''), + ), + TOPICS_TABLE => array( + 'topic_title' => array('STEXT_UNI', '', 'true_sort'), + 'topic_last_post_subject' => array('STEXT_UNI', ''), + ), + ), + 'drop_keys' => array( + SESSIONS_TABLE => array('session_forum_id'), + ), + 'add_index' => array( + SESSIONS_TABLE => array( + 'session_fid' => array('session_forum_id'), + ), + ), + ), + // No changes from 3.0.2-RC2 to 3.0.2 + '3.0.2-RC2' => array(), + + // Changes from 3.0.2 to 3.0.3-RC1 + '3.0.2' => array( + // Add the following columns + 'add_columns' => array( + STYLES_TEMPLATE_TABLE => array( + 'template_inherits_id' => array('UINT:4', 0), + 'template_inherit_path' => array('VCHAR', ''), + ), + GROUPS_TABLE => array( + 'group_max_recipients' => array('UINT', 0), + ), + ), + ), + + // No changes from 3.0.3-RC1 to 3.0.3 + '3.0.3-RC1' => array(), + + // Changes from 3.0.3 to 3.0.4-RC1 + '3.0.3' => array( + 'add_columns' => array( + PROFILE_FIELDS_TABLE => array( + 'field_show_profile' => array('BOOL', 0), + ), + ), + 'change_columns' => array( + STYLES_TABLE => array( + 'style_id' => array('UINT', NULL, 'auto_increment'), + 'template_id' => array('UINT', 0), + 'theme_id' => array('UINT', 0), + 'imageset_id' => array('UINT', 0), + ), + STYLES_IMAGESET_TABLE => array( + 'imageset_id' => array('UINT', NULL, 'auto_increment'), + ), + STYLES_IMAGESET_DATA_TABLE => array( + 'image_id' => array('UINT', NULL, 'auto_increment'), + 'imageset_id' => array('UINT', 0), + ), + STYLES_THEME_TABLE => array( + 'theme_id' => array('UINT', NULL, 'auto_increment'), + ), + STYLES_TEMPLATE_TABLE => array( + 'template_id' => array('UINT', NULL, 'auto_increment'), + ), + STYLES_TEMPLATE_DATA_TABLE => array( + 'template_id' => array('UINT', 0), + ), + FORUMS_TABLE => array( + 'forum_style' => array('UINT', 0), + ), + USERS_TABLE => array( + 'user_style' => array('UINT', 0), + ), + ), + ), + + // Changes from 3.0.4-RC1 to 3.0.4 + '3.0.4-RC1' => array(), + + // Changes from 3.0.4 to 3.0.5-RC1 + '3.0.4' => array( + 'change_columns' => array( + FORUMS_TABLE => array( + 'forum_style' => array('UINT', 0), + ), + ), + ), + + // No changes from 3.0.5-RC1 to 3.0.5 + '3.0.5-RC1' => array(), + + // Changes from 3.0.5 to 3.0.6-RC1 + '3.0.5' => array( + 'add_columns' => array( + CONFIRM_TABLE => array( + 'attempts' => array('UINT', 0), + ), + USERS_TABLE => array( + 'user_new' => array('BOOL', 1), + 'user_reminded' => array('TINT:4', 0), + 'user_reminded_time'=> array('TIMESTAMP', 0), + ), + GROUPS_TABLE => array( + 'group_skip_auth' => array('BOOL', 0, 'after' => 'group_founder_manage'), + ), + PRIVMSGS_TABLE => array( + 'message_reported' => array('BOOL', 0), + ), + REPORTS_TABLE => array( + 'pm_id' => array('UINT', 0), + ), + PROFILE_FIELDS_TABLE => array( + 'field_show_on_vt' => array('BOOL', 0), + ), + FORUMS_TABLE => array( + 'forum_options' => array('UINT:20', 0), + ), + ), + 'change_columns' => array( + USERS_TABLE => array( + 'user_options' => array('UINT:11', 230271), + ), + ), + 'add_index' => array( + REPORTS_TABLE => array( + 'post_id' => array('post_id'), + 'pm_id' => array('pm_id'), + ), + POSTS_TABLE => array( + 'post_username' => array('post_username:255'), + ), + ), + ), + + // No changes from 3.0.6-RC1 to 3.0.6-RC2 + '3.0.6-RC1' => array(), + // No changes from 3.0.6-RC2 to 3.0.6-RC3 + '3.0.6-RC2' => array(), + // No changes from 3.0.6-RC3 to 3.0.6-RC4 + '3.0.6-RC3' => array(), + // No changes from 3.0.6-RC4 to 3.0.6 + '3.0.6-RC4' => array(), + + // Changes from 3.0.6 to 3.0.7-RC1 + '3.0.6' => array( + 'drop_keys' => array( + LOG_TABLE => array('log_time'), + ), + 'add_index' => array( + TOPICS_TRACK_TABLE => array( + 'topic_id' => array('topic_id'), + ), + ), + ), + + // No changes from 3.0.7-RC1 to 3.0.7-RC2 + '3.0.7-RC1' => array(), + // No changes from 3.0.7-RC2 to 3.0.7 + '3.0.7-RC2' => array(), + // No changes from 3.0.7 to 3.0.7-PL1 + '3.0.7' => array(), + // No changes from 3.0.7-PL1 to 3.0.8-RC1 + '3.0.7-PL1' => array(), + // No changes from 3.0.8-RC1 to 3.0.8 + '3.0.8-RC1' => array(), + // Changes from 3.0.8 to 3.0.9-RC1 + '3.0.8' => array( + 'add_tables' => array( + LOGIN_ATTEMPT_TABLE => array( + 'COLUMNS' => array( + // this column was removed from the database updater + // after 3.0.9-RC3 was released. It might still exist + // in 3.0.9-RCX installations and has to be dropped in + // 3.0.12 after the db_tools class is capable of properly + // removing a primary key. + // 'attempt_id' => array('UINT', NULL, 'auto_increment'), + 'attempt_ip' => array('VCHAR:40', ''), + 'attempt_browser' => array('VCHAR:150', ''), + 'attempt_forwarded_for' => array('VCHAR:255', ''), + 'attempt_time' => array('TIMESTAMP', 0), + 'user_id' => array('UINT', 0), + 'username' => array('VCHAR_UNI:255', 0), + 'username_clean' => array('VCHAR_CI', 0), + ), + //'PRIMARY_KEY' => 'attempt_id', + 'KEYS' => array( + 'att_ip' => array('INDEX', array('attempt_ip', 'attempt_time')), + 'att_for' => array('INDEX', array('attempt_forwarded_for', 'attempt_time')), + 'att_time' => array('INDEX', array('attempt_time')), + 'user_id' => array('INDEX', 'user_id'), + ), + ), + ), + 'change_columns' => array( + BBCODES_TABLE => array( + 'bbcode_id' => array('USINT', 0), + ), + ), + ), + // No changes from 3.0.9-RC1 to 3.0.9-RC2 + '3.0.9-RC1' => array(), + // No changes from 3.0.9-RC2 to 3.0.9-RC3 + '3.0.9-RC2' => array(), + // No changes from 3.0.9-RC3 to 3.0.9-RC4 + '3.0.9-RC3' => array(), + // No changes from 3.0.9-RC4 to 3.0.9 + '3.0.9-RC4' => array(), + // No changes from 3.0.9 to 3.0.10-RC1 + '3.0.9' => array(), + // No changes from 3.0.10-RC1 to 3.0.10-RC2 + '3.0.10-RC1' => array(), + // No changes from 3.0.10-RC2 to 3.0.10-RC3 + '3.0.10-RC2' => array(), + // No changes from 3.0.10-RC3 to 3.0.10 + '3.0.10-RC3' => array(), + // No changes from 3.0.10 to 3.0.11-RC1 + '3.0.10' => array(), + // Changes from 3.0.11-RC1 to 3.0.11-RC2 + '3.0.11-RC1' => array( + 'add_columns' => array( + PROFILE_FIELDS_TABLE => array( + 'field_show_novalue' => array('BOOL', 0), + ), + ), + ), + // No changes from 3.0.11-RC2 to 3.0.11 + '3.0.11-RC2' => array(), + // No changes from 3.0.11 to 3.0.12-RC1 + '3.0.11' => array(), + + /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.12-RC1 */ + // Changes from 3.1.0-dev to 3.1.0-A1 '3.1.0-dev' => array( 'add_tables' => array( @@ -939,6 +1210,1159 @@ function change_database_data(&$no_updates, $version) switch ($version) { + case '3.0.0': + + $sql = 'UPDATE ' . TOPICS_TABLE . " + SET topic_last_view_time = topic_last_post_time + WHERE topic_last_view_time = 0"; + _sql($sql, $errored, $error_ary); + + // Update smiley sizes + $smileys = array('icon_e_surprised.gif', 'icon_eek.gif', 'icon_cool.gif', 'icon_lol.gif', 'icon_mad.gif', 'icon_razz.gif', 'icon_redface.gif', 'icon_cry.gif', 'icon_evil.gif', 'icon_twisted.gif', 'icon_rolleyes.gif', 'icon_exclaim.gif', 'icon_question.gif', 'icon_idea.gif', 'icon_arrow.gif', 'icon_neutral.gif', 'icon_mrgreen.gif', 'icon_e_ugeek.gif'); + + foreach ($smileys as $smiley) + { + if (file_exists($phpbb_root_path . 'images/smilies/' . $smiley)) + { + list($width, $height) = getimagesize($phpbb_root_path . 'images/smilies/' . $smiley); + + $sql = 'UPDATE ' . SMILIES_TABLE . ' + SET smiley_width = ' . $width . ', smiley_height = ' . $height . " + WHERE smiley_url = '" . $db->sql_escape($smiley) . "'"; + + _sql($sql, $errored, $error_ary); + } + } + + $no_updates = false; + break; + + // No changes from 3.0.1-RC1 to 3.0.1 + case '3.0.1-RC1': + break; + + // changes from 3.0.1 to 3.0.2-RC1 + case '3.0.1': + + set_config('referer_validation', '1'); + set_config('check_attachment_content', '1'); + set_config('mime_triggers', 'body|head|html|img|plaintext|a href|pre|script|table|title'); + + $no_updates = false; + break; + + // No changes from 3.0.2-RC1 to 3.0.2-RC2 + case '3.0.2-RC1': + break; + + // No changes from 3.0.2-RC2 to 3.0.2 + case '3.0.2-RC2': + break; + + // Changes from 3.0.2 to 3.0.3-RC1 + case '3.0.2': + set_config('enable_queue_trigger', '0'); + set_config('queue_trigger_posts', '3'); + + set_config('pm_max_recipients', '0'); + + // Set maximum number of recipients for the registered users, bots, guests group + $sql = 'UPDATE ' . GROUPS_TABLE . ' SET group_max_recipients = 5 + WHERE ' . $db->sql_in_set('group_name', array('GUESTS', 'REGISTERED', 'REGISTERED_COPPA', 'BOTS')); + _sql($sql, $errored, $error_ary); + + // Not prefilling yet + set_config('dbms_version', ''); + + // Add new permission u_masspm_group and duplicate settings from u_masspm + include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + $auth_admin = new auth_admin(); + + // Only add the new permission if it does not already exist + if (empty($auth_admin->acl_options['id']['u_masspm_group'])) + { + $auth_admin->acl_add_option(array('global' => array('u_masspm_group'))); + + // Now the tricky part, filling the permission + $old_id = $auth_admin->acl_options['id']['u_masspm']; + $new_id = $auth_admin->acl_options['id']['u_masspm_group']; + + $tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE); + + foreach ($tables as $table) + { + $sql = 'SELECT * + FROM ' . $table . ' + WHERE auth_option_id = ' . $old_id; + $result = _sql($sql, $errored, $error_ary); + + $sql_ary = array(); + while ($row = $db->sql_fetchrow($result)) + { + $row['auth_option_id'] = $new_id; + $sql_ary[] = $row; + } + $db->sql_freeresult($result); + + if (sizeof($sql_ary)) + { + $db->sql_multi_insert($table, $sql_ary); + } + } + + // Remove any old permission entries + $auth_admin->acl_clear_prefetch(); + } + + /** + * Do not resync post counts here. An admin may do this later from the ACP + $start = 0; + $step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000; + + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = 0'; + _sql($sql, $errored, $error_ary); + + do + { + $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id + FROM ' . POSTS_TABLE . ' + WHERE post_id BETWEEN ' . ($start + 1) . ' AND ' . ($start + $step) . ' + AND post_postcount = 1 AND post_approved = 1 + GROUP BY poster_id'; + $result = _sql($sql, $errored, $error_ary); + + if ($row = $db->sql_fetchrow($result)) + { + do + { + $sql = 'UPDATE ' . USERS_TABLE . " SET user_posts = user_posts + {$row['num_posts']} WHERE user_id = {$row['poster_id']}"; + _sql($sql, $errored, $error_ary); + } + while ($row = $db->sql_fetchrow($result)); + + $start += $step; + } + else + { + $start = 0; + } + $db->sql_freeresult($result); + } + while ($start); + */ + + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET module_auth = \'acl_a_email && cfg_email_enable\' + WHERE module_class = \'acp\' + AND module_basename = \'email\''; + _sql($sql, $errored, $error_ary); + + $no_updates = false; + break; + + // Changes from 3.0.3-RC1 to 3.0.3 + case '3.0.3-RC1': + if ($db->sql_layer == 'oracle') + { + // log_operation is CLOB - but we can change this later + $sql = 'UPDATE ' . LOG_TABLE . " + SET log_operation = 'LOG_DELETE_TOPIC' + WHERE log_operation LIKE 'LOG_TOPIC_DELETED'"; + _sql($sql, $errored, $error_ary); + } + else + { + $sql = 'UPDATE ' . LOG_TABLE . " + SET log_operation = 'LOG_DELETE_TOPIC' + WHERE log_operation = 'LOG_TOPIC_DELETED'"; + _sql($sql, $errored, $error_ary); + } + + $no_updates = false; + break; + + // Changes from 3.0.3 to 3.0.4-RC1 + case '3.0.3': + // Update the Custom Profile Fields based on previous settings to the new format + $sql = 'SELECT field_id, field_required, field_show_on_reg, field_hide + FROM ' . PROFILE_FIELDS_TABLE; + $result = _sql($sql, $errored, $error_ary); + + while ($row = $db->sql_fetchrow($result)) + { + $sql_ary = array( + 'field_required' => 0, + 'field_show_on_reg' => 0, + 'field_hide' => 0, + 'field_show_profile'=> 0, + ); + + if ($row['field_required']) + { + $sql_ary['field_required'] = $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; + } + else if ($row['field_show_on_reg']) + { + $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; + } + else if ($row['field_hide']) + { + // Only administrators and moderators can see this CPF, if the view is enabled, they can see it, otherwise just admins in the acp_users module + $sql_ary['field_hide'] = 1; + } + else + { + // equivelant to "none", which is the "Display in user control panel" option + $sql_ary['field_show_profile'] = 1; + } + + _sql('UPDATE ' . PROFILE_FIELDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary); + } + $no_updates = false; + + break; + + // Changes from 3.0.4-RC1 to 3.0.4 + case '3.0.4-RC1': + break; + + // Changes from 3.0.4 to 3.0.5-RC1 + case '3.0.4': + + // Captcha config variables + set_config('captcha_gd_wave', 0); + set_config('captcha_gd_3d_noise', 1); + set_config('captcha_gd_fonts', 1); + set_config('confirm_refresh', 1); + + // Maximum number of keywords + set_config('max_num_search_keywords', 10); + + // Remove static config var and put it back as dynamic variable + $sql = 'UPDATE ' . CONFIG_TABLE . " + SET is_dynamic = 1 + WHERE config_name = 'search_indexing_state'"; + _sql($sql, $errored, $error_ary); + + // Hash old MD5 passwords + $sql = 'SELECT user_id, user_password + FROM ' . USERS_TABLE . ' + WHERE user_pass_convert = 1'; + $result = _sql($sql, $errored, $error_ary); + + while ($row = $db->sql_fetchrow($result)) + { + if (strlen($row['user_password']) == 32) + { + $sql_ary = array( + 'user_password' => phpbb_hash($row['user_password']), + ); + + _sql('UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id'], $errored, $error_ary); + } + } + $db->sql_freeresult($result); + + // Adjust bot entry + $sql = 'UPDATE ' . BOTS_TABLE . " + SET bot_agent = 'ichiro/' + WHERE bot_agent = 'ichiro/2'"; + _sql($sql, $errored, $error_ary); + + + // Before we are able to add a unique key to auth_option, we need to remove duplicate entries + + // We get duplicate entries first + $sql = 'SELECT auth_option + FROM ' . ACL_OPTIONS_TABLE . ' + GROUP BY auth_option + HAVING COUNT(*) >= 2'; + $result = $db->sql_query($sql); + + $auth_options = array(); + while ($row = $db->sql_fetchrow($result)) + { + $auth_options[] = $row['auth_option']; + } + $db->sql_freeresult($result); + + // Remove specific auth options + if (!empty($auth_options)) + { + foreach ($auth_options as $option) + { + // Select auth_option_ids... the largest id will be preserved + $sql = 'SELECT auth_option_id + FROM ' . ACL_OPTIONS_TABLE . " + WHERE auth_option = '" . $db->sql_escape($option) . "' + ORDER BY auth_option_id DESC"; + // sql_query_limit not possible here, due to bug in postgresql layer + $result = $db->sql_query($sql); + + // Skip first row, this is our original auth option we want to preserve + $row = $db->sql_fetchrow($result); + + while ($row = $db->sql_fetchrow($result)) + { + // Ok, remove this auth option... + _sql('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + _sql('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + _sql('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + _sql('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + } + $db->sql_freeresult($result); + } + } + + // Now make auth_option UNIQUE, by dropping the old index and adding a UNIQUE one. + $changes = array( + 'drop_keys' => array( + ACL_OPTIONS_TABLE => array('auth_option'), + ), + ); + + global $db_tools; + + $statements = $db_tools->perform_schema_changes($changes); + + foreach ($statements as $sql) + { + _sql($sql, $errored, $error_ary); + } + + $changes = array( + 'add_unique_index' => array( + ACL_OPTIONS_TABLE => array( + 'auth_option' => array('auth_option'), + ), + ), + ); + + $statements = $db_tools->perform_schema_changes($changes); + + foreach ($statements as $sql) + { + _sql($sql, $errored, $error_ary); + } + + $no_updates = false; + + break; + + // No changes from 3.0.5-RC1 to 3.0.5 + case '3.0.5-RC1': + break; + + // Changes from 3.0.5 to 3.0.6-RC1 + case '3.0.5': + // Let's see if the GD Captcha can be enabled... we simply look for what *is* enabled... + if (!empty($config['captcha_gd']) && !isset($config['captcha_plugin'])) + { + set_config('captcha_plugin', 'phpbb_captcha_gd'); + } + else if (!isset($config['captcha_plugin'])) + { + set_config('captcha_plugin', 'phpbb_captcha_nogd'); + } + + // Entries for the Feed Feature + set_config('feed_enable', '0'); + set_config('feed_limit', '10'); + + set_config('feed_overall_forums', '1'); + set_config('feed_overall_forums_limit', '15'); + + set_config('feed_overall_topics', '0'); + set_config('feed_overall_topics_limit', '15'); + + set_config('feed_forum', '1'); + set_config('feed_topic', '1'); + set_config('feed_item_statistics', '1'); + + // Entries for smiley pagination + set_config('smilies_per_page', '50'); + + // Entry for reporting PMs + set_config('allow_pm_report', '1'); + + // Install modules + $modules_to_install = array( + 'feed' => array( + 'base' => 'board', + 'class' => 'acp', + 'title' => 'ACP_FEED_SETTINGS', + 'auth' => 'acl_a_board', + 'cat' => 'ACP_BOARD_CONFIGURATION', + 'after' => array('signature', 'ACP_SIGNATURE_SETTINGS') + ), + 'warnings' => array( + 'base' => 'users', + 'class' => 'acp', + 'title' => 'ACP_USER_WARNINGS', + 'auth' => 'acl_a_user', + 'display' => 0, + 'cat' => 'ACP_CAT_USERS', + 'after' => array('feedback', 'ACP_USER_FEEDBACK') + ), + 'send_statistics' => array( + 'base' => 'send_statistics', + 'class' => 'acp', + 'title' => 'ACP_SEND_STATISTICS', + 'auth' => 'acl_a_server', + 'cat' => 'ACP_SERVER_CONFIGURATION' + ), + 'setting_forum_copy' => array( + 'base' => 'permissions', + 'class' => 'acp', + 'title' => 'ACP_FORUM_PERMISSIONS_COPY', + 'auth' => 'acl_a_fauth && acl_a_authusers && acl_a_authgroups && acl_a_mauth', + 'cat' => 'ACP_FORUM_BASED_PERMISSIONS', + 'after' => array('setting_forum_local', 'ACP_FORUM_PERMISSIONS') + ), + 'pm_reports' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORTS_OPEN', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + 'pm_reports_closed' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORTS_CLOSED', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + 'pm_report_details' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORT_DETAILS', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + ); + + _add_modules($modules_to_install); + + // Add newly_registered group... but check if it already exists (we always supported running the updater on any schema) + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = 'NEWLY_REGISTERED'"; + $result = $db->sql_query($sql); + $group_id = (int) $db->sql_fetchfield('group_id'); + $db->sql_freeresult($result); + + if (!$group_id) + { + $sql = 'INSERT INTO ' . GROUPS_TABLE . " (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('NEWLY_REGISTERED', 3, 0, '', 0, '', '', '', 5)"; + _sql($sql, $errored, $error_ary); + + $group_id = $db->sql_nextid(); + } + + // Insert new user role... at the end of the chain + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = 'ROLE_USER_NEW_MEMBER' + AND role_type = 'u_'"; + $result = $db->sql_query($sql); + $u_role = (int) $db->sql_fetchfield('role_id'); + $db->sql_freeresult($result); + + if (!$u_role) + { + $sql = 'SELECT MAX(role_order) as max_order_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_type = 'u_'"; + $result = $db->sql_query($sql); + $next_order_id = (int) $db->sql_fetchfield('max_order_id'); + $db->sql_freeresult($result); + + $next_order_id++; + + $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_NEW_MEMBER', 'ROLE_DESCRIPTION_USER_NEW_MEMBER', 'u_', $next_order_id)"; + _sql($sql, $errored, $error_ary); + $u_role = $db->sql_nextid(); + + if (!$errored) + { + // Now add the correct data to the roles... + // The standard role says that new users are not able to send a PM, Mass PM, are not able to PM groups + $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $u_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_sendpm', 'u_masspm', 'u_masspm_group')"; + _sql($sql, $errored, $error_ary); + + // Add user role to group + $sql = 'INSERT INTO ' . ACL_GROUPS_TABLE . " (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES ($group_id, 0, 0, $u_role, 0)"; + _sql($sql, $errored, $error_ary); + } + } + + // Insert new forum role + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = 'ROLE_FORUM_NEW_MEMBER' + AND role_type = 'f_'"; + $result = $db->sql_query($sql); + $f_role = (int) $db->sql_fetchfield('role_id'); + $db->sql_freeresult($result); + + if (!$f_role) + { + $sql = 'SELECT MAX(role_order) as max_order_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_type = 'f_'"; + $result = $db->sql_query($sql); + $next_order_id = (int) $db->sql_fetchfield('max_order_id'); + $db->sql_freeresult($result); + + $next_order_id++; + + $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_NEW_MEMBER', 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER', 'f_', $next_order_id)"; + _sql($sql, $errored, $error_ary); + $f_role = $db->sql_nextid(); + + if (!$errored) + { + $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $f_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove')"; + _sql($sql, $errored, $error_ary); + } + } + + // Set every members user_new column to 0 (old users) only if there is no one yet (this makes sure we do not execute this more than once) + $sql = 'SELECT 1 + FROM ' . USERS_TABLE . ' + WHERE user_new = 0'; + $result = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!$row) + { + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new = 0'; + _sql($sql, $errored, $error_ary); + } + + // Newly registered users limit + if (!isset($config['new_member_post_limit'])) + { + set_config('new_member_post_limit', (!empty($config['enable_queue_trigger'])) ? $config['queue_trigger_posts'] : 0); + } + + if (!isset($config['new_member_group_default'])) + { + set_config('new_member_group_default', 0); + } + + // To mimick the old "feature" we will assign the forum role to every forum, regardless of the setting (this makes sure there are no "this does not work!!!! YUO!!!" posts... + // Check if the role is already assigned... + $sql = 'SELECT forum_id + FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id . ' + AND auth_role_id = ' . $f_role; + $result = $db->sql_query($sql); + $is_options = (int) $db->sql_fetchfield('forum_id'); + $db->sql_freeresult($result); + + // Not assigned at all... :/ + if (!$is_options) + { + // Get postable forums + $sql = 'SELECT forum_id + FROM ' . FORUMS_TABLE . ' + WHERE forum_type != ' . FORUM_LINK; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + _sql('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (' . $group_id . ', ' . (int) $row['forum_id'] . ', 0, ' . $f_role . ', 0)', $errored, $error_ary); + } + $db->sql_freeresult($result); + } + + // Clear permissions... + include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + $auth_admin = new auth_admin(); + $auth_admin->acl_clear_prefetch(); + + if (!isset($config['allow_avatar'])) + { + if ($config['allow_avatar_upload'] || $config['allow_avatar_local'] || $config['allow_avatar_remote']) + { + set_config('allow_avatar', '1'); + } + else + { + set_config('allow_avatar', '0'); + } + } + + if (!isset($config['allow_avatar_remote_upload'])) + { + if ($config['allow_avatar_remote'] && $config['allow_avatar_upload']) + { + set_config('allow_avatar_remote_upload', '1'); + } + else + { + set_config('allow_avatar_remote_upload', '0'); + } + } + + // Minimum number of characters + if (!isset($config['min_post_chars'])) + { + set_config('min_post_chars', '1'); + } + + if (!isset($config['allow_quick_reply'])) + { + set_config('allow_quick_reply', '1'); + } + + // Set every members user_options column to enable + // bbcode, smilies and URLs for signatures by default + $sql = 'SELECT user_options + FROM ' . USERS_TABLE . ' + WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; + $result = $db->sql_query_limit($sql, 1); + $user_option = (int) $db->sql_fetchfield('user_options'); + $db->sql_freeresult($result); + + // Check if we already updated the database by checking bit 15 which we used to store the sig_bbcode option + if (!($user_option & 1 << 15)) + { + // 229376 is the added value to enable all three signature options + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_options = user_options + 229376'; + _sql($sql, $errored, $error_ary); + } + + if (!isset($config['delete_time'])) + { + set_config('delete_time', $config['edit_time']); + } + + $no_updates = false; + break; + + // No changes from 3.0.6-RC1 to 3.0.6-RC2 + case '3.0.6-RC1': + break; + + // Changes from 3.0.6-RC2 to 3.0.6-RC3 + case '3.0.6-RC2': + + // Update the Custom Profile Fields based on previous settings to the new format + $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . ' + SET field_show_on_vt = 1 + WHERE field_hide = 0 + AND (field_required = 1 OR field_show_on_reg = 1 OR field_show_profile = 1)'; + _sql($sql, $errored, $error_ary); + $no_updates = false; + + break; + + // No changes from 3.0.6-RC3 to 3.0.6-RC4 + case '3.0.6-RC3': + break; + + // No changes from 3.0.6-RC4 to 3.0.6 + case '3.0.6-RC4': + break; + + // Changes from 3.0.6 to 3.0.7-RC1 + case '3.0.6': + + // ATOM Feeds + set_config('feed_overall', '1'); + set_config('feed_http_auth', '0'); + set_config('feed_limit_post', (string) (isset($config['feed_limit']) ? (int) $config['feed_limit'] : 15)); + set_config('feed_limit_topic', (string) (isset($config['feed_overall_topics_limit']) ? (int) $config['feed_overall_topics_limit'] : 10)); + set_config('feed_topics_new', (!empty($config['feed_overall_topics']) ? '1' : '0')); + set_config('feed_topics_active', (!empty($config['feed_overall_topics']) ? '1' : '0')); + + // Delete all text-templates from the template_data + $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' + WHERE template_filename ' . $db->sql_like_expression($db->any_char . '.txt'); + _sql($sql, $errored, $error_ary); + + $no_updates = false; + break; + + // Changes from 3.0.7-RC1 to 3.0.7-RC2 + case '3.0.7-RC1': + + $sql = 'SELECT user_id, user_email, user_email_hash + FROM ' . USERS_TABLE . ' + WHERE user_type <> ' . USER_IGNORE . " + AND user_email <> ''"; + $result = $db->sql_query($sql); + + $i = 0; + while ($row = $db->sql_fetchrow($result)) + { + // Snapshot of the phpbb_email_hash() function + // We cannot call it directly because the auto updater updates the DB first. :/ + $user_email_hash = sprintf('%u', crc32(strtolower($row['user_email']))) . strlen($row['user_email']); + + if ($user_email_hash != $row['user_email_hash']) + { + $sql_ary = array( + 'user_email_hash' => $user_email_hash, + ); + + $sql = 'UPDATE ' . USERS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE user_id = ' . (int) $row['user_id']; + _sql($sql, $errored, $error_ary, ($i % 100 == 0)); + + ++$i; + } + } + $db->sql_freeresult($result); + + $no_updates = false; + + break; + + // No changes from 3.0.7-RC2 to 3.0.7 + case '3.0.7-RC2': + break; + + // No changes from 3.0.7 to 3.0.7-PL1 + case '3.0.7': + break; + + // Changes from 3.0.7-PL1 to 3.0.8-RC1 + case '3.0.7-PL1': + // Update file extension group names to use language strings. + $sql = 'SELECT lang_dir + FROM ' . LANG_TABLE; + $result = $db->sql_query($sql); + + $extension_groups_updated = array(); + while ($lang_dir = $db->sql_fetchfield('lang_dir')) + { + $lang_dir = basename($lang_dir); + + // The language strings we need are either in language/.../acp/attachments.php + // in the update package if we're updating to 3.0.8-RC1 or later, + // or they are in language/.../install.php when we're updating from 3.0.7-PL1 or earlier. + // On an already updated board, they can also already be in language/.../acp/attachments.php + // in the board root. + $lang_files = array( + "{$phpbb_root_path}install/update/new/language/$lang_dir/acp/attachments.$phpEx", + "{$phpbb_root_path}language/$lang_dir/install.$phpEx", + "{$phpbb_root_path}language/$lang_dir/acp/attachments.$phpEx", + ); + + foreach ($lang_files as $lang_file) + { + if (!file_exists($lang_file)) + { + continue; + } + + $lang = array(); + include($lang_file); + + foreach($lang as $lang_key => $lang_val) + { + if (isset($extension_groups_updated[$lang_key]) || strpos($lang_key, 'EXT_GROUP_') !== 0) + { + continue; + } + + $sql_ary = array( + 'group_name' => substr($lang_key, 10), // Strip off 'EXT_GROUP_' + ); + + $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " + WHERE group_name = '" . $db->sql_escape($lang_val) . "'"; + _sql($sql, $errored, $error_ary); + + $extension_groups_updated[$lang_key] = true; + } + } + } + $db->sql_freeresult($result); + + // Install modules + $modules_to_install = array( + 'post' => array( + 'base' => 'board', + 'class' => 'acp', + 'title' => 'ACP_POST_SETTINGS', + 'auth' => 'acl_a_board', + 'cat' => 'ACP_MESSAGES', + 'after' => array('message', 'ACP_MESSAGE_SETTINGS') + ), + ); + + _add_modules($modules_to_install); + + // update + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET module_auth = \'cfg_allow_avatar && (cfg_allow_avatar_local || cfg_allow_avatar_remote || cfg_allow_avatar_upload || cfg_allow_avatar_remote_upload)\' + WHERE module_class = \'ucp\' + AND module_basename = \'profile\' + AND module_mode = \'avatar\''; + _sql($sql, $errored, $error_ary); + + // add Bing Bot + $bot_name = 'Bing [Bot]'; + $bot_name_clean = utf8_clean_string($bot_name); + + $sql = 'SELECT user_id + FROM ' . USERS_TABLE . " + WHERE username_clean = '" . $db->sql_escape($bot_name_clean) . "'"; + $result = $db->sql_query($sql); + $bing_already_added = (bool) $db->sql_fetchfield('user_id'); + $db->sql_freeresult($result); + + if (!$bing_already_added) + { + $bot_agent = 'bingbot/'; + $bot_ip = ''; + $sql = 'SELECT group_id, group_colour + FROM ' . GROUPS_TABLE . " + WHERE group_name = 'BOTS'"; + $result = $db->sql_query($sql); + $group_row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!$group_row) + { + // default fallback, should never get here + $group_row['group_id'] = 6; + $group_row['group_colour'] = '9E8DA7'; + } + + if (!function_exists('user_add')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } + + $user_row = array( + 'user_type' => USER_IGNORE, + 'group_id' => $group_row['group_id'], + 'username' => $bot_name, + 'user_regdate' => time(), + 'user_password' => '', + 'user_colour' => $group_row['group_colour'], + 'user_email' => '', + 'user_lang' => $config['default_lang'], + 'user_style' => $config['default_style'], + 'user_timezone' => 'UTC', + 'user_dateformat' => $config['default_dateformat'], + 'user_allow_massemail' => 0, + ); + + $user_id = user_add($user_row); + + $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( + 'bot_active' => 1, + 'bot_name' => (string) $bot_name, + 'user_id' => (int) $user_id, + 'bot_agent' => (string) $bot_agent, + 'bot_ip' => (string) $bot_ip, + )); + + _sql($sql, $errored, $error_ary); + } + // end Bing Bot addition + + // Delete shadow topics pointing to not existing topics + $batch_size = 500; + + // Set of affected forums we have to resync + $sync_forum_ids = array(); + + do + { + $sql_array = array( + 'SELECT' => 't1.topic_id, t1.forum_id', + 'FROM' => array( + TOPICS_TABLE => 't1', + ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(TOPICS_TABLE => 't2'), + 'ON' => 't1.topic_moved_id = t2.topic_id', + ), + ), + 'WHERE' => 't1.topic_moved_id <> 0 + AND t2.topic_id IS NULL', + ); + $sql = $db->sql_build_query('SELECT', $sql_array); + $result = $db->sql_query_limit($sql, $batch_size); + + $topic_ids = array(); + while ($row = $db->sql_fetchrow($result)) + { + $topic_ids[] = (int) $row['topic_id']; + + $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id']; + } + $db->sql_freeresult($result); + + if (!empty($topic_ids)) + { + $sql = 'DELETE FROM ' . TOPICS_TABLE . ' + WHERE ' . $db->sql_in_set('topic_id', $topic_ids); + $db->sql_query($sql); + } + } + while (sizeof($topic_ids) == $batch_size); + + // Sync the forums we have deleted shadow topics from. + sync('forum', 'forum_id', $sync_forum_ids, true, true); + + // Unread posts search load switch + set_config('load_unreads_search', '1'); + + // Reduce queue interval to 60 seconds, email package size to 20 + if ($config['queue_interval'] == 600) + { + set_config('queue_interval', '60'); + } + + if ($config['email_package_size'] == 50) + { + set_config('email_package_size', '20'); + } + + $no_updates = false; + break; + + // No changes from 3.0.8-RC1 to 3.0.8 + case '3.0.8-RC1': + break; + + // Changes from 3.0.8 to 3.0.9-RC1 + case '3.0.8': + set_config('ip_login_limit_max', '50'); + set_config('ip_login_limit_time', '21600'); + set_config('ip_login_limit_use_forwarded', '0'); + + // Update file extension group names to use language strings, again. + $sql = 'SELECT group_id, group_name + FROM ' . EXTENSION_GROUPS_TABLE . ' + WHERE group_name ' . $db->sql_like_expression('EXT_GROUP_' . $db->any_char); + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $sql_ary = array( + 'group_name' => substr($row['group_name'], 10), // Strip off 'EXT_GROUP_' + ); + + $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE group_id = ' . $row['group_id']; + _sql($sql, $errored, $error_ary); + } + $db->sql_freeresult($result); + + global $db_tools, $table_prefix; + + // Recover from potentially broken Q&A CAPTCHA table on firebird + // Q&A CAPTCHA was uninstallable, so it's safe to remove these + // without data loss + if ($db_tools->sql_layer == 'firebird') + { + $tables = array( + $table_prefix . 'captcha_questions', + $table_prefix . 'captcha_answers', + $table_prefix . 'qa_confirm', + ); + foreach ($tables as $table) + { + if ($db_tools->sql_table_exists($table)) + { + $db_tools->sql_table_drop($table); + } + } + } + + $no_updates = false; + break; + + // No changes from 3.0.9-RC1 to 3.0.9-RC2 + case '3.0.9-RC1': + break; + + // No changes from 3.0.9-RC2 to 3.0.9-RC3 + case '3.0.9-RC2': + break; + + // No changes from 3.0.9-RC3 to 3.0.9-RC4 + case '3.0.9-RC3': + break; + + // No changes from 3.0.9-RC4 to 3.0.9 + case '3.0.9-RC4': + break; + + // Changes from 3.0.9 to 3.0.10-RC1 + case '3.0.9': + if (!isset($config['email_max_chunk_size'])) + { + set_config('email_max_chunk_size', '50'); + } + + $no_updates = false; + break; + + // No changes from 3.0.10-RC1 to 3.0.10-RC2 + case '3.0.10-RC1': + break; + + // No changes from 3.0.10-RC2 to 3.0.10-RC3 + case '3.0.10-RC2': + break; + + // No changes from 3.0.10-RC3 to 3.0.10 + case '3.0.10-RC3': + break; + + // Changes from 3.0.10 to 3.0.11-RC1 + case '3.0.10': + // Updates users having current style a deactivated one + $sql = 'SELECT style_id + FROM ' . STYLES_TABLE . ' + WHERE style_active = 0'; + $result = $db->sql_query($sql); + + $deactivated_style_ids = array(); + while ($style_id = $db->sql_fetchfield('style_id', false, $result)) + { + $deactivated_style_ids[] = (int) $style_id; + } + $db->sql_freeresult($result); + + if (!empty($deactivated_style_ids)) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_style = ' . (int) $config['default_style'] .' + WHERE ' . $db->sql_in_set('user_style', $deactivated_style_ids); + _sql($sql, $errored, $error_ary); + } + + // Delete orphan private messages + $batch_size = 500; + + $sql_array = array( + 'SELECT' => 'p.msg_id', + 'FROM' => array( + PRIVMSGS_TABLE => 'p', + ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(PRIVMSGS_TO_TABLE => 't'), + 'ON' => 'p.msg_id = t.msg_id', + ), + ), + 'WHERE' => 't.user_id IS NULL', + ); + $sql = $db->sql_build_query('SELECT', $sql_array); + + do + { + $result = $db->sql_query_limit($sql, $batch_size); + + $delete_pms = array(); + while ($row = $db->sql_fetchrow($result)) + { + $delete_pms[] = (int) $row['msg_id']; + } + $db->sql_freeresult($result); + + if (!empty($delete_pms)) + { + $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' + WHERE ' . $db->sql_in_set('msg_id', $delete_pms); + _sql($sql, $errored, $error_ary); + } + } + while (sizeof($delete_pms) == $batch_size); + + $no_updates = false; + break; + + // No changes from 3.0.11-RC1 to 3.0.11-RC2 + case '3.0.11-RC1': + break; + + // No changes from 3.0.11-RC2 to 3.0.11 + case '3.0.11-RC2': + break; + + // Changes from 3.0.11 to 3.0.12-RC1 + case '3.0.11': + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET module_auth = \'acl_u_sig\' + WHERE module_class = \'ucp\' + AND module_basename = \'profile\' + AND module_mode = \'signature\''; + _sql($sql, $errored, $error_ary); + + // Update bots + if (!function_exists('user_delete')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } + + $bots_updates = array( + // Bot Deletions + 'NG-Search [Bot]' => false, + 'Nutch/CVS [Bot]' => false, + 'OmniExplorer [Bot]' => false, + 'Seekport [Bot]' => false, + 'Synoo [Bot]' => false, + 'WiseNut [Bot]' => false, + + // Bot Updates + // Bot name to bot user agent map + 'Baidu [Spider]' => 'Baiduspider', + 'Exabot [Bot]' => 'Exabot', + 'Voyager [Bot]' => 'voyager/', + 'W3C [Validator]' => 'W3C_Validator', + ); + + foreach ($bots_updates as $bot_name => $bot_agent) + { + $sql = 'SELECT user_id + FROM ' . USERS_TABLE . ' + WHERE user_type = ' . USER_IGNORE . " + AND username_clean = '" . $db->sql_escape(utf8_clean_string($bot_name)) . "'"; + $result = $db->sql_query($sql); + $bot_user_id = (int) $db->sql_fetchfield('user_id'); + $db->sql_freeresult($result); + + if ($bot_user_id) + { + if ($bot_agent === false) + { + $sql = 'DELETE FROM ' . BOTS_TABLE . " + WHERE user_id = $bot_user_id"; + _sql($sql, $errored, $error_ary); + + user_delete('remove', $bot_user_id); + } + else + { + $sql = 'UPDATE ' . BOTS_TABLE . " + SET bot_agent = '" . $db->sql_escape($bot_agent) . "' + WHERE user_id = $bot_user_id"; + _sql($sql, $errored, $error_ary); + } + } + } + + $no_updates = false; + break; + // Changes from 3.1.0-dev to 3.1.0-A1 case '3.1.0-dev': From ced035788b0654614e07f483bf4b6f9f9ea4eac2 Mon Sep 17 00:00:00 2001 From: David King Date: Mon, 12 Nov 2012 16:41:02 -0500 Subject: [PATCH 23/90] [feature/migrations] Update phpbb_db_migration class for PHP 5.3.3 PHPBB3-9737 --- phpBB/includes/db/migration.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration.php index 1acef2d429..fb030ded44 100644 --- a/phpBB/includes/db/migration.php +++ b/phpBB/includes/db/migration.php @@ -24,7 +24,7 @@ if (!defined('IN_PHPBB')) * * @package db */ -class phpbb_db_migration +abstract class phpbb_db_migration { protected $config; protected $db; @@ -88,7 +88,7 @@ class phpbb_db_migration */ protected function sql_query($sql) { - if (defined('DEBUG_EXTRA')) + if (defined('DEBUG')) { echo "
\n{$sql}\n
"; } From 61debcf14ca14afbb503b2535ef392a75002e8ae Mon Sep 17 00:00:00 2001 From: David King Date: Mon, 12 Nov 2012 16:46:19 -0500 Subject: [PATCH 24/90] [feature/migrations] Update phpbb_db_migrator class for PHP 5.3.3 PHPBB3-9737 --- phpBB/includes/db/migrator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index c9590fccf6..216faf9866 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -40,7 +40,7 @@ class phpbb_db_migrator * * @param \Symfony\Component\DependencyInjection\ContainerInterface $container Container supplying dependencies */ - public function phpbb_db_migrator(\Symfony\Component\DependencyInjection\ContainerInterface $container, $migrations) + public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container, $migrations) { $this->container = $container; $this->db = $this->container->get('dbal.conn'); From 826607a40509d40ba5a85e5b0bc72a54f77d41d6 Mon Sep 17 00:00:00 2001 From: David King Date: Mon, 12 Nov 2012 16:54:10 -0500 Subject: [PATCH 25/90] [feature/migrations] Add method and property visibility, use __construct() PHPBB3-9737 --- phpBB/includes/db/migration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration.php index fb030ded44..10f7b71551 100644 --- a/phpBB/includes/db/migration.php +++ b/phpBB/includes/db/migration.php @@ -41,7 +41,7 @@ abstract class phpbb_db_migration * * @param \Symfony\Component\DependencyInjection\ContainerInterface $container Container supplying dependencies */ - public function phpbb_db_migration(\Symfony\Component\DependencyInjection\ContainerInterface $container) + public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container) { $this->config = $this->container->get('config'); $this->db = $this->container->get('dbal.conn'); From 5c91e2569cb3a400acd20bf06cc0e609dd63a778 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 8 Jan 2013 22:09:14 -0600 Subject: [PATCH 26/90] [feature/migrations] Migrations now somewhat works PHPBB3-9737 --- phpBB/config/migrator.yml | 49 + phpBB/config/services.yml | 40 +- phpBB/config/tables.yml | 1 + phpBB/develop/create_schema_files.php | 4 +- phpBB/includes/db/driver/mysqli.php | 1 + .../includes/db/migration/data/3_0_11_rc1.php | 2 +- .../includes/db/migration/data/3_0_12_rc1.php | 101 +- .../includes/db/migration/data/3_0_3_rc1.php | 6 +- phpBB/includes/db/migration/data/3_0_4.php | 2 +- .../includes/db/migration/data/3_0_4_rc1.php | 4 +- .../includes/db/migration/data/3_0_5_rc1.php | 8 +- .../includes/db/migration/data/3_0_6_rc1.php | 60 +- .../includes/db/migration/data/3_0_7_rc2.php | 2 +- .../includes/db/migration/data/3_0_8_rc1.php | 10 +- .../includes/db/migration/data/3_0_9_rc1.php | 2 +- .../includes/db/migration/data/3_1_0_dev.php | 100 +- .../includes/db/migration/data/extensions.php | 3 +- .../db/migration/data/style_update_p1.php | 62 +- .../db/migration/data/style_update_p2.php | 43 +- phpBB/includes/db/migration/data/timezone.php | 5 +- phpBB/includes/db/migration/exception.php | 40 + .../includes/db/{ => migration}/migration.php | 33 +- .../db/migration/{tools => tool}/config.php | 14 +- .../includes/db/migration/tool/interface.php | 18 + .../db/migration/{tools => tool}/module.php | 66 +- .../migration/{tools => tool}/permission.php | 124 +- phpBB/includes/db/migration/tools/umil.php | 3037 ----------------- phpBB/includes/db/migrator.php | 109 +- phpBB/includes/functions.php | 3 +- phpBB/install/database_update.php | 65 +- phpBB/install/schemas/firebird_schema.sql | 29 +- phpBB/install/schemas/mssql_schema.sql | 42 +- phpBB/install/schemas/mysql_40_schema.sql | 26 +- phpBB/install/schemas/mysql_41_schema.sql | 26 +- phpBB/install/schemas/oracle_schema.sql | 32 +- phpBB/install/schemas/postgres_schema.sql | 30 +- phpBB/install/schemas/sqlite_schema.sql | 28 +- phpBB/test.php | 121 + tests/dbal/fixtures/migrator_module.xml | 42 + tests/dbal/fixtures/migrator_permission.xml | 31 + tests/dbal/migrator_test.php | 12 +- tests/dbal/migrator_tool_config_test.php | 97 + tests/dbal/migrator_tool_module.php | 128 + tests/dbal/migrator_tool_permission.php | 136 + 44 files changed, 1375 insertions(+), 3419 deletions(-) create mode 100644 phpBB/config/migrator.yml create mode 100644 phpBB/includes/db/migration/exception.php rename phpBB/includes/db/{ => migration}/migration.php (73%) rename phpBB/includes/db/migration/{tools => tool}/config.php (91%) create mode 100644 phpBB/includes/db/migration/tool/interface.php rename phpBB/includes/db/migration/{tools => tool}/module.php (88%) rename phpBB/includes/db/migration/{tools => tool}/permission.php (78%) delete mode 100644 phpBB/includes/db/migration/tools/umil.php create mode 100644 phpBB/test.php create mode 100644 tests/dbal/fixtures/migrator_module.xml create mode 100644 tests/dbal/fixtures/migrator_permission.xml create mode 100644 tests/dbal/migrator_tool_config_test.php create mode 100644 tests/dbal/migrator_tool_module.php create mode 100644 tests/dbal/migrator_tool_permission.php diff --git a/phpBB/config/migrator.yml b/phpBB/config/migrator.yml new file mode 100644 index 0000000000..999a2d41a3 --- /dev/null +++ b/phpBB/config/migrator.yml @@ -0,0 +1,49 @@ +services: + migrator: + class: phpbb_db_migrator + arguments: + - @config + - @dbal.conn + - @dbal.tools + - %tables.migrations% + - %core.root_path% + - %core.php_ext% + - %core.table_prefix% + - @migrator.tool_collection + + migrator.tool_collection: + class: phpbb_di_service_collection + arguments: + - @service_container + tags: + - { name: service_collection, tag: migrator.tool } + + migrator.tool.config: + class: phpbb_db_migration_tool_config + arguments: + - @config + tags: + - { name: migrator.tool } + + migrator.tool.module: + class: phpbb_db_migration_tool_module + arguments: + - @dbal.conn + - @cache + - @user + - %core.root_path% + - %core.php_ext% + - %tables.modules% + tags: + - { name: migrator.tool } + + migrator.tool.permission: + class: phpbb_db_migration_tool_permission + arguments: + - @dbal.conn + - @cache + - @auth + - %core.root_path% + - %core.php_ext% + tags: + - { name: migrator.tool } diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 4125491dd0..ee52ca2800 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -1,6 +1,7 @@ imports: - { resource: tables.yml } - { resource: cron_tasks.yml } + - { resource: migrator.yml } services: auth: @@ -162,45 +163,6 @@ services: tags: - { name: kernel.event_subscriber } - migrator: - class: phpbb_db_migrator - arguments: - - @service_container - - migrator.tools_collection - class: phpbb_di_service_collection - arguments: - - @service_container - - migrator.tools.config: - class: phpbb_db_migration_tools_config - arguments: - - @config - tags: - - { name: migrator:tool } - - migrator.tools.module: - class: phpbb_db_migration_tools_module - arguments: - - @db - - @cache - - @user - - %core.root_path% - - %core.php_ext% - tags: - - { name: migrator:tool } - - migrator.tools.permission: - class: phpbb_db_migration_tools_permission - arguments: - - @db - - @cache - - @auth - - %core.root_path% - - %core.php_ext% - tags: - - { name: migrator:tool } - request: class: phpbb_request diff --git a/phpBB/config/tables.yml b/phpBB/config/tables.yml index a9414cf66c..dd53417b1c 100644 --- a/phpBB/config/tables.yml +++ b/phpBB/config/tables.yml @@ -2,3 +2,4 @@ parameters: tables.config: %core.table_prefix%config tables.ext: %core.table_prefix%ext tables.migrations: %core.table_prefix%migrations + tables.modules: %core.table_prefix%modules diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 1abafb3b6d..b37dcc246f 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1258,7 +1258,7 @@ function get_schema_struct() ), ); - $schema_data['phpbb_migrations'] = array( + $schema_data['phpbb_moderator_cache'] = array( 'COLUMNS' => array( 'forum_id' => array('UINT', 0), 'user_id' => array('UINT', 0), @@ -1273,7 +1273,7 @@ function get_schema_struct() ), ); - $schema_data['phpbb_moderator_cache'] = array( + $schema_data['phpbb_migrations'] = array( 'COLUMNS' => array( 'migration_name' => array('VCHAR', ''), 'migration_schema_done' => array('BOOL', 0), diff --git a/phpBB/includes/db/driver/mysqli.php b/phpBB/includes/db/driver/mysqli.php index 7448bf1670..94921a22b7 100644 --- a/phpBB/includes/db/driver/mysqli.php +++ b/phpBB/includes/db/driver/mysqli.php @@ -24,6 +24,7 @@ if (!defined('IN_PHPBB')) class phpbb_db_driver_mysqli extends phpbb_db_driver { var $multi_insert = true; + var $connect_error = ''; /** diff --git a/phpBB/includes/db/migration/data/3_0_11_rc1.php b/phpBB/includes/db/migration/data/3_0_11_rc1.php index 1509120f68..daf106accf 100644 --- a/phpBB/includes/db/migration/data/3_0_11_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_11_rc1.php @@ -80,7 +80,7 @@ class phpbb_db_migration_data_3_0_11_rc1 extends phpbb_db_migration { $delete_pms[] = (int) $row['msg_id']; } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); if (!empty($delete_pms)) { diff --git a/phpBB/includes/db/migration/data/3_0_12_rc1.php b/phpBB/includes/db/migration/data/3_0_12_rc1.php index e5ff8c5814..0d8702f19e 100644 --- a/phpBB/includes/db/migration/data/3_0_12_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_12_rc1.php @@ -9,24 +9,115 @@ /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.12-RC1 **/ -/* class phpbb_db_migration_data_3_0_12_rc1 extends phpbb_db_migration { - function depends_on() + public function depends_on() { return array('phpbb_db_migration_data_3_0_11'); } - function update_schema() + public function update_schema() { return array(); } - function update_data() + public function update_data() { return array( + array('custom', array(array(&$this, 'update_module_auth'))), + array('custom', array(array(&$this, 'update_bots'))), + array('custom', array(array(&$this, 'disable_bots_from_receiving_pms'))), + array('config.update', array('version', '3.0.12-rc1')), ); } + + public function disable_bots_from_receiving_pms() + { + // Disable receiving pms for bots + $sql = 'SELECT user_id + FROM ' . BOTS_TABLE; + $result = $this->db->sql_query($sql); + + $bot_user_ids = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $bot_user_ids[] = (int) $row['user_id']; + } + $this->db->sql_freeresult($result); + + if (!empty($bot_user_ids)) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_allow_pm = 0 + WHERE ' . $this->db->sql_in_set('user_id', $bot_user_ids); + $this->sql_query($sql); + } + } + + public function update_module_auth() + { + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET module_auth = \'acl_u_sig\' + WHERE module_class = \'ucp\' + AND module_basename = \'profile\' + AND module_mode = \'signature\''; + $this->sql_query($sql); + } + + public function update_bots() + { + // Update bots + if (!function_exists('user_delete')) + { + include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); + } + + $bots_updates = array( + // Bot Deletions + 'NG-Search [Bot]' => false, + 'Nutch/CVS [Bot]' => false, + 'OmniExplorer [Bot]' => false, + 'Seekport [Bot]' => false, + 'Synoo [Bot]' => false, + 'WiseNut [Bot]' => false, + + // Bot Updates + // Bot name to bot user agent map + 'Baidu [Spider]' => 'Baiduspider', + 'Exabot [Bot]' => 'Exabot', + 'Voyager [Bot]' => 'voyager/', + 'W3C [Validator]' => 'W3C_Validator', + ); + + foreach ($bots_updates as $bot_name => $bot_agent) + { + $sql = 'SELECT user_id + FROM ' . USERS_TABLE . ' + WHERE user_type = ' . USER_IGNORE . " + AND username_clean = '" . $this->db->sql_escape(utf8_clean_string($bot_name)) . "'"; + $result = $this->db->sql_query($sql); + $bot_user_id = (int) $this->db->sql_fetchfield('user_id'); + $this->db->sql_freeresult($result); + + if ($bot_user_id) + { + if ($bot_agent === false) + { + $sql = 'DELETE FROM ' . BOTS_TABLE . " + WHERE user_id = $bot_user_id"; + $this->sql_query($sql); + + user_delete('remove', $bot_user_id); + } + else + { + $sql = 'UPDATE ' . BOTS_TABLE . " + SET bot_agent = '" . $this->db->sql_escape($bot_agent) . "' + WHERE user_id = $bot_user_id"; + $this->sql_query($sql); + } + } + } + } } -*/ \ No newline at end of file diff --git a/phpBB/includes/db/migration/data/3_0_3_rc1.php b/phpBB/includes/db/migration/data/3_0_3_rc1.php index d5c110eb7d..2320c4ac4b 100644 --- a/phpBB/includes/db/migration/data/3_0_3_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_3_rc1.php @@ -36,12 +36,12 @@ class phpbb_db_migration_data_3_0_3_rc1 extends phpbb_db_migration array('config.add', array('queue_trigger_posts', '3')), array('config.add', array('pm_max_recipients', '0')), array('custom', array(array(&$this, 'set_group_default_max_recipients'))), - array('config.add', array('dbms_version', '')), - array('permission.add', array('u_masspm_group', phpbb_auth::IS_GLOBAL), + array('config.add', array('dbms_version', $this->db->sql_server_info(true))), + array('permission.add', array('u_masspm_group', true, 'u_masspm')), array('custom', array(array(&$this, 'correct_acp_email_permissions'))), array('config.update', array('version', '3.0.3-rc1')), - )); + ); } function correct_acp_email_permissions() diff --git a/phpBB/includes/db/migration/data/3_0_4.php b/phpBB/includes/db/migration/data/3_0_4.php index 4965ac38d0..1af4508331 100644 --- a/phpBB/includes/db/migration/data/3_0_4.php +++ b/phpBB/includes/db/migration/data/3_0_4.php @@ -30,7 +30,7 @@ class phpbb_db_migration_data_3_0_4 extends phpbb_db_migration function rename_log_delete_topic() { - if ($db->sql_layer == 'oracle') + if ($this->db->sql_layer == 'oracle') { // log_operation is CLOB - but we can change this later $sql = 'UPDATE ' . $this->table_prefix . "log diff --git a/phpBB/includes/db/migration/data/3_0_4_rc1.php b/phpBB/includes/db/migration/data/3_0_4_rc1.php index 2964dcebc9..e9bb0e01f5 100644 --- a/phpBB/includes/db/migration/data/3_0_4_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_4_rc1.php @@ -69,7 +69,7 @@ class phpbb_db_migration_data_3_0_4_rc1 extends phpbb_db_migration // Update the Custom Profile Fields based on previous settings to the new format $sql = 'SELECT field_id, field_required, field_show_on_reg, field_hide FROM ' . PROFILE_FIELDS_TABLE; - $result = $this->sql_query($sql); + $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { @@ -101,5 +101,7 @@ class phpbb_db_migration_data_3_0_4_rc1 extends phpbb_db_migration $this->sql_query('UPDATE ' . $this->table_prefix . 'profile_fields SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary); } + + $this->db->sql_freeresult($result); } } diff --git a/phpBB/includes/db/migration/data/3_0_5_rc1.php b/phpBB/includes/db/migration/data/3_0_5_rc1.php index 9205f0d5f8..cbf28c0be6 100644 --- a/phpBB/includes/db/migration/data/3_0_5_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_5_rc1.php @@ -32,7 +32,7 @@ class phpbb_db_migration_data_3_0_5_rc1 extends phpbb_db_migration return array( array('config.add', array('captcha_gd_wave', 0)), array('config.add', array('captcha_gd_3d_noise', 1)), - array('config.add', array('captcha_gd_refresh', 1)), + array('config.add', array('captcha_gd_fonts', 1)), array('config.add', array('confirm_refresh', 1)), array('config.add', array('max_num_search_keywords', 10)), array('config.remove', array('search_indexing_state')), @@ -47,7 +47,7 @@ class phpbb_db_migration_data_3_0_5_rc1 extends phpbb_db_migration $sql = 'SELECT user_id, user_password FROM ' . $this->table_prefix . 'users WHERE user_pass_convert = 1'; - $result = $this->sql_query($sql); + $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { @@ -60,7 +60,7 @@ class phpbb_db_migration_data_3_0_5_rc1 extends phpbb_db_migration $this->sql_query('UPDATE ' . $this->table_prefix . 'users SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id']); } } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); } function update_ichiro_bot() @@ -99,7 +99,7 @@ class phpbb_db_migration_data_3_0_5_rc1 extends phpbb_db_migration WHERE auth_option = '" . $db->sql_escape($option) . "' ORDER BY auth_option_id DESC"; // sql_query_limit not possible here, due to bug in postgresql layer - $result = $this->sql_query($sql); + $result = $this->db->sql_query($sql); // Skip first row, this is our original auth option we want to preserve $row = $this->db->sql_fetchrow($result); diff --git a/phpBB/includes/db/migration/data/3_0_6_rc1.php b/phpBB/includes/db/migration/data/3_0_6_rc1.php index a868d70684..35adcf52be 100644 --- a/phpBB/includes/db/migration/data/3_0_6_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_6_rc1.php @@ -35,7 +35,7 @@ class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration $this->table_prefix . 'reports' => array( 'pm_id' => array('UINT', 0), ), - $this->table_prefix . 'fields' => array( + $this->table_prefix . 'profile_fields' => array( 'field_show_on_vt' => array('BOOL', 0), ), $this->table_prefix . 'forums' => array( @@ -89,19 +89,19 @@ class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration array('config.add', array('allow_avatar', 0)), array('if', array( ($this->config['allow_avatar_upload'] || $this->config['allow_avatar_local'] || $this->config['allow_avatar_remote']), - array('config.add', array('allow_avatar', 1)), + array('config.update', array('allow_avatar', 1)), )), array('config.add', array('allow_avatar_remote_upload', 0)), array('if', array( ($this->config['allow_avatar_remote'] && $this->config['allow_avatar_upload']), - array('config.add', array('allow_avatar_remote_upload', 1)), + array('config.update', array('allow_avatar_remote_upload', 1)), )), array('module.add', array( 'acp', 'ACP_BOARD_CONFIGURATION', array( - 'module_basename' => 'board', + 'module_basename' => 'acp_board', 'modes' => array('feed'), ), )), @@ -109,7 +109,7 @@ class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration 'acp', 'ACP_CAT_USERS', array( - 'module_basename' => 'users', + 'module_basename' => 'acp_users', 'modes' => array('warnings'), ), )), @@ -117,7 +117,7 @@ class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration 'acp', 'ACP_SERVER_CONFIGURATION', array( - 'module_basename' => 'send_statistics', + 'module_basename' => 'acp_send_statistics', 'modes' => array('send_statistics'), ), )), @@ -125,7 +125,7 @@ class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration 'acp', 'ACP_FORUM_BASED_PERMISSIONS', array( - 'module_basename' => 'permissions', + 'module_basename' => 'acp_permissions', 'modes' => array('setting_forum_copy'), ), )), @@ -133,24 +133,8 @@ class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration 'mcp', 'MCP_REPORTS', array( - 'module_basename' => 'pm_reports', - 'modes' => array('pm_reports'), - ), - )), - array('module.add', array( - 'mcp', - 'MCP_REPORTS', - array( - 'module_basename' => 'pm_reports', - 'modes' => array('pm_reports_closed'), - ), - )), - array('module.add', array( - 'mcp', - 'MCP_REPORTS', - array( - 'module_basename' => 'pm_reports', - 'modes' => array('pm_report_details'), + 'module_basename' => 'mcp_pm_reports', + 'modes' => array('pm_reports','pm_reports_closed','pm_report_details'), ), )), array('custom', array(array(&$this, 'add_newly_registered_group'))), @@ -209,17 +193,14 @@ class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration $this->sql_query($sql); $u_role = $this->db->sql_nextid(); - if (!$errored) - { - // Now add the correct data to the roles... - // The standard role says that new users are not able to send a PM, Mass PM, are not able to PM groups - $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $u_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_sendpm', 'u_masspm', 'u_masspm_group')"; - $this->sql_query($sql); + // Now add the correct data to the roles... + // The standard role says that new users are not able to send a PM, Mass PM, are not able to PM groups + $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $u_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_sendpm', 'u_masspm', 'u_masspm_group')"; + $this->sql_query($sql); - // Add user role to group - $sql = 'INSERT INTO ' . ACL_GROUPS_TABLE . " (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES ($group_id, 0, 0, $u_role, 0)"; - $this->sql_query($sql); - } + // Add user role to group + $sql = 'INSERT INTO ' . ACL_GROUPS_TABLE . " (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES ($group_id, 0, 0, $u_role, 0)"; + $this->sql_query($sql); } // Insert new forum role @@ -246,11 +227,8 @@ class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration $this->sql_query($sql); $f_role = $this->db->sql_nextid(); - if (!$errored) - { - $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $f_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove')"; - $this->sql_query($sql); - } + $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $f_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove')"; + $this->sql_query($sql); } // Set every members user_new column to 0 (old users) only if there is no one yet (this makes sure we do not execute this more than once) @@ -294,7 +272,7 @@ class phpbb_db_migration_data_3_0_6_rc1 extends phpbb_db_migration } // Clear permissions... - include_once($this->phpbb_root_path . 'includes/acp/auth.' . $this->phpEx); + include_once($this->phpbb_root_path . 'includes/acp/auth.' . $this->php_ext); $auth_admin = new auth_admin(); $auth_admin->acl_clear_prefetch(); } diff --git a/phpBB/includes/db/migration/data/3_0_7_rc2.php b/phpBB/includes/db/migration/data/3_0_7_rc2.php index e043f35705..e2c6acce1e 100644 --- a/phpBB/includes/db/migration/data/3_0_7_rc2.php +++ b/phpBB/includes/db/migration/data/3_0_7_rc2.php @@ -59,7 +59,7 @@ class phpbb_db_migration_data_3_0_7_rc2 extends phpbb_db_migration $this->sql_query($sql); } } - $db->sql_freeresult($result); + $this->db->sql_freeresult($result); if ($i < $limit) { diff --git a/phpBB/includes/db/migration/data/3_0_8_rc1.php b/phpBB/includes/db/migration/data/3_0_8_rc1.php index 3f51806fd9..b58b0966a5 100644 --- a/phpBB/includes/db/migration/data/3_0_8_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_8_rc1.php @@ -30,7 +30,7 @@ class phpbb_db_migration_data_3_0_8_rc1 extends phpbb_db_migration 'acp', 'ACP_MESSAGES', array( - 'module_basename' => 'board', + 'module_basename' => 'acp_board', 'modes' => array('post'), ), )), @@ -60,9 +60,9 @@ class phpbb_db_migration_data_3_0_8_rc1 extends phpbb_db_migration // On an already updated board, they can also already be in language/.../acp/attachments.php // in the board root. $lang_files = array( - "{$this->phpbb_root_path}install/update/new/language/$lang_dir/acp/attachments.$this->phpEx", - "{$this->phpbb_root_path}language/$lang_dir/install.$this->phpEx", - "{$this->phpbb_root_path}language/$lang_dir/acp/attachments.$this->phpEx", + "{$this->phpbb_root_path}install/update/new/language/$lang_dir/acp/attachments.{$this->php_ext}", + "{$this->phpbb_root_path}language/$lang_dir/install.{$this->php_ext}", + "{$this->phpbb_root_path}language/$lang_dir/acp/attachments.{$this->php_ext}", ); foreach ($lang_files as $lang_file) @@ -140,7 +140,7 @@ class phpbb_db_migration_data_3_0_8_rc1 extends phpbb_db_migration if (!function_exists('user_add')) { - include($this->phpbb_root_path . 'includes/functions_user.' . $this->phpEx); + include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); } $user_row = array( diff --git a/phpBB/includes/db/migration/data/3_0_9_rc1.php b/phpBB/includes/db/migration/data/3_0_9_rc1.php index 256426849c..ea49cdbba9 100644 --- a/phpBB/includes/db/migration/data/3_0_9_rc1.php +++ b/phpBB/includes/db/migration/data/3_0_9_rc1.php @@ -44,7 +44,7 @@ class phpbb_db_migration_data_3_0_9_rc1 extends phpbb_db_migration ), ), 'change_columns' => array( - $this->table_prefix . 'bbcode' => array( + $this->table_prefix . 'bbcodes' => array( 'bbcode_id' => array('USINT', 0), ), ), diff --git a/phpBB/includes/db/migration/data/3_1_0_dev.php b/phpBB/includes/db/migration/data/3_1_0_dev.php index 987ab94646..6eb5a6ddee 100644 --- a/phpBB/includes/db/migration/data/3_1_0_dev.php +++ b/phpBB/includes/db/migration/data/3_1_0_dev.php @@ -7,7 +7,7 @@ * */ -class phpbb_db_migration_data_extensions extends phpbb_db_migration +class phpbb_db_migration_data_3_1_0_dev extends phpbb_db_migration { public function depends_on() { @@ -78,6 +78,8 @@ class phpbb_db_migration_data_extensions extends phpbb_db_migration array('config.add', array('site_home_url', '')), array('config.add', array('site_home_text', '')), + array('permission.add', array('u_chgprofileinfo', true, 'u_sig')), + array('module.add', array( 'acp', 'ACP_GROUPS', @@ -103,7 +105,7 @@ class phpbb_db_migration_data_extensions extends phpbb_db_migration ), )), array('module.add', array( - 'acp', + 'ucp', 'UCP_PROFILE', array( 'module_basename' => 'ucp_profile', @@ -113,20 +115,104 @@ class phpbb_db_migration_data_extensions extends phpbb_db_migration array('module.remove', array( 'acp', - 'ACP_CAT_STYLES', - array( - 'module_basename' => 'styles', - 'modes' => array('imageset', 'theme', 'template'), - ), + false, + 'ACP_TEMPLATES', + )), + array('module.remove', array( + 'acp', + false, + 'ACP_THEMES', + )), + array('module.remove', array( + 'acp', + false, + 'ACP_IMAGESETS', )), array('custom', array(array($this, 'rename_module_basenames'))), + array('custom', array(array($this, 'rename_styles_module'))), array('custom', array(array($this, 'add_group_teampage'))), array('custom', array(array($this, 'update_group_legend'))), array('custom', array(array($this, 'localise_global_announcements'))), + array('custom', array(array($this, 'update_ucp_pm_basename'))), + array('custom', array(array($this, 'update_ucp_profile_auth'))), + array('custom', array(array($this, 'move_customise_modules'))), + + array('config.update', array('version', '3.1.0-dev')), ); } + public function move_customise_modules() + { + // Move language management to new location in the Customise tab + // First get language module id + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_basename = 'acp_language'"; + $result = $this->db->sql_query($sql); + $language_module_id = $this->db->sql_fetchfield('module_id'); + $this->db->sql_freeresult($result); + // Next get language management module id of the one just created + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = 'ACP_LANGUAGE'"; + $result = $this->db->sql_query($sql); + $language_management_module_id = $this->db->sql_fetchfield('module_id'); + $this->db->sql_freeresult($result); + + if (!class_exists('acp_modules')) + { + include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext); + } + // acp_modules calls adm_back_link, which is undefined at this point + if (!function_exists('adm_back_link')) + { + include($this->phpbb_root_path . 'includes/functions_acp.' . $this->php_ext); + } + $module_manager = new acp_modules(); + $module_manager->module_class = 'acp'; + $module_manager->move_module($language_module_id, $language_management_module_id); + } + + public function update_ucp_pm_basename() + { + $sql = 'SELECT module_id, module_basename + FROM ' . MODULES_TABLE . " + WHERE module_basename <> 'ucp_pm' AND + module_langname='UCP_PM'"; + $result = $this->db->sql_query_limit($sql, 1); + + if ($row = $this->db->sql_fetchrow($result)) + { + // This update is still not applied. Applying it + + $sql = 'UPDATE ' . MODULES_TABLE . " + SET module_basename = 'ucp_pm' + WHERE module_id = " . (int) $row['module_id']; + + $this->sql_query($sql); + } + $this->db->sql_freeresult($result); + } + + public function update_ucp_profile_auth() + { + // Update the auth setting for the module + $sql = 'UPDATE ' . MODULES_TABLE . " + SET module_auth = 'acl_u_chgprofileinfo' + WHERE module_class = 'ucp' + AND module_basename = 'ucp_profile' + AND module_mode = 'profile_info'"; + $this->sql_query($sql); + } + + public function rename_styles_module() + { + // Rename styles module to Customise + $sql = 'UPDATE ' . MODULES_TABLE . " + SET module_langname = 'ACP_CAT_CUSTOMISE' + WHERE module_langname = 'ACP_CAT_STYLES'"; + $this->sql_query($sql); + } + public function rename_module_basenames() { // rename all module basenames to full classname diff --git a/phpBB/includes/db/migration/data/extensions.php b/phpBB/includes/db/migration/data/extensions.php index 85d5511ef0..d28e0ebabb 100644 --- a/phpBB/includes/db/migration/data/extensions.php +++ b/phpBB/includes/db/migration/data/extensions.php @@ -39,10 +39,11 @@ class phpbb_db_migration_data_extensions extends phpbb_db_migration 'acp', 'ACP_GENERAL_TASKS', array( - 'module_basename' => 'extensions', + 'module_basename' => 'acp_extensions', 'modes' => array('main'), ), )), + array('permission.add', array('a_extensions', true, 'a_styles')), ); } } diff --git a/phpBB/includes/db/migration/data/style_update_p1.php b/phpBB/includes/db/migration/data/style_update_p1.php index d570caae04..1c46e4147b 100644 --- a/phpBB/includes/db/migration/data/style_update_p1.php +++ b/phpBB/includes/db/migration/data/style_update_p1.php @@ -31,7 +31,7 @@ class phpbb_db_migration_data_style_update_p1 extends phpbb_db_migration // Get list of valid 3.1 styles $available_styles = array('prosilver'); - $iterator = new DirectoryIterator($phpbb_root_path . 'styles'); + $iterator = new DirectoryIterator($this->phpbb_root_path . 'styles'); $skip_dirs = array('.', '..', 'prosilver'); foreach ($iterator as $fileinfo) { @@ -91,9 +91,67 @@ class phpbb_db_migration_data_style_update_p1 extends phpbb_db_migration 'style_parent_id' => 0, 'style_parent_tree' => '', ); - $this->sql_query('UPDATE ' . STYLES_TABLE . ' SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE style_id = ' . $style_row['style_id'], $errored, $error_ary); + $this->sql_query('UPDATE ' . STYLES_TABLE . ' + SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE style_id = ' . $style_row['style_id']); $valid_styles[] = (int) $style_row['style_id']; } } + + // Remove old entries from styles table + if (!sizeof($valid_styles)) + { + // No valid styles: remove everything and add prosilver + $this->sql_query('DELETE FROM ' . STYLES_TABLE, $errored, $error_ary); + + $sql_ary = array( + 'style_name' => 'prosilver', + 'style_copyright' => '© phpBB Group', + 'style_active' => 1, + 'style_path' => 'prosilver', + 'bbcode_bitfield' => 'kNg=', + 'style_parent_id' => 0, + 'style_parent_tree' => '', + + // Will be removed in the next step + 'imageset_id' => 0, + 'template_id' => 0, + 'theme_id' => 0, + ); + + $sql = 'INSERT INTO ' . STYLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); + $this->sql_query($sql); + + $sql = 'SELECT style_id + FROM ' . $table . " + WHERE style_name = 'prosilver'"; + $result = $this->sql_query($sql); + $default_style = $this->db->sql_fetchfield($result); + $this->db->sql_freeresult($result); + + set_config('default_style', $default_style); + + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = 0'; + $this->sql_query($sql); + } + else + { + // There are valid styles in styles table. Remove styles that are outdated + $this->sql_query('DELETE FROM ' . STYLES_TABLE . ' + WHERE ' . $this->db->sql_in_set('style_id', $valid_styles, true)); + + // Change default style + if (!in_array($this->config['default_style'], $valid_styles)) + { + $this->sql_query('UPDATE ' . CONFIG_TABLE . " + SET config_value = '" . $valid_styles[0] . "' + WHERE config_name = 'default_style'"); + } + + // Reset styles for users + $this->sql_query('UPDATE ' . USERS_TABLE . ' + SET user_style = 0 + WHERE ' . $this->db->sql_in_set('user_style', $valid_styles, true)); + } } } diff --git a/phpBB/includes/db/migration/data/style_update_p2.php b/phpBB/includes/db/migration/data/style_update_p2.php index 2c0991de59..db4b7f1753 100644 --- a/phpBB/includes/db/migration/data/style_update_p2.php +++ b/phpBB/includes/db/migration/data/style_update_p2.php @@ -37,47 +37,6 @@ class phpbb_db_migration_data_style_update_p2 extends phpbb_db_migration public function update_data() { - return array( - array('custom', array(array($this, 'styles_update'))), - ); - } - - public function styles_update() - { - // Remove old entries from styles table - if (!sizeof($valid_styles)) - { - // No valid styles: remove everything and add prosilver - $this->sql_query('DELETE FROM ' . STYLES_TABLE, $errored, $error_ary); - - $sql = 'INSERT INTO ' . STYLES_TABLE . " (style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES ('prosilver', '© phpBB Group', 1, 'prosilver', 'kNg=', 0, '')"; - $this->sql_query($sql); - - $sql = 'SELECT style_id - FROM ' . $table . " - WHERE style_name = 'prosilver'"; - $result = $this->sql_query($sql); - $default_style = $this->db->sql_fetchfield($result); - $this->db->sql_freeresult($result); - - set_config('default_style', $default_style); - - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = 0'; - $this->sql_query($sql); - } - else - { - // There are valid styles in styles table. Remove styles that are outdated - $this->sql_query('DELETE FROM ' . STYLES_TABLE . ' WHERE ' . $this->db->sql_in_set('style_id', $valid_styles, true), $errored, $error_ary); - - // Change default style - if (!in_array($config['default_style'], $valid_styles)) - { - set_config('default_style', $valid_styles[0]); - } - - // Reset styles for users - $this->sql_query('UPDATE ' . USERS_TABLE . ' SET user_style = 0 WHERE ' . $this->db->sql_in_set('user_style', $valid_styles, true), $errored, $error_ary); - } + return array(); } } diff --git a/phpBB/includes/db/migration/data/timezone.php b/phpBB/includes/db/migration/data/timezone.php index 89fafbad28..7734ed4b76 100644 --- a/phpBB/includes/db/migration/data/timezone.php +++ b/phpBB/includes/db/migration/data/timezone.php @@ -51,7 +51,10 @@ class phpbb_db_migration_data_timezone extends phpbb_db_migration $this->db->sql_freeresult($result); // Update board default timezone - set_config('board_timezone', $this->convert_phpbb30_timezone($config['board_timezone'], $config['board_dst'])); + $sql = 'UPDATE ' . CONFIG_TABLE . " + SET config_value = '" . $this->convert_phpbb30_timezone($this->config['board_timezone'], $this->config['board_dst']) . "' + WHERE config_name = 'board_timezone'"; + $this->sql_query($sql); // After we have calculated the timezones we can delete user_dst column from user table. $this->db_tools->sql_column_remove(USERS_TABLE, 'user_dst'); diff --git a/phpBB/includes/db/migration/exception.php b/phpBB/includes/db/migration/exception.php new file mode 100644 index 0000000000..19fb39ab23 --- /dev/null +++ b/phpBB/includes/db/migration/exception.php @@ -0,0 +1,40 @@ +parameters = $parameters; + } + + public function __toString() + { + return $this->message . ': ' . var_export($this->parameters, true); + } +} diff --git a/phpBB/includes/db/migration.php b/phpBB/includes/db/migration/migration.php similarity index 73% rename from phpBB/includes/db/migration.php rename to phpBB/includes/db/migration/migration.php index 10f7b71551..c2c6da855b 100644 --- a/phpBB/includes/db/migration.php +++ b/phpBB/includes/db/migration/migration.php @@ -36,20 +36,20 @@ abstract class phpbb_db_migration protected $errors; + private $queries = array(); + /** * Migration constructor - * - * @param \Symfony\Component\DependencyInjection\ContainerInterface $container Container supplying dependencies */ - public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container) + public function __construct($config, phpbb_db_driver $db, $db_tools, $phpbb_root_path, $php_ext, $table_prefix) { - $this->config = $this->container->get('config'); - $this->db = $this->container->get('dbal.conn'); - $this->db_tools = $this->container->get('dbal.tools'); - $this->table_prefix = $this->container->getParameters('core.table_prefix'); + $this->config = $config; + $this->db = $db; + $this->db_tools = $db_tools; + $this->table_prefix = $table_prefix; - $this->phpbb_root_path = $this->container->getParameters('core.root_path'); - $this->php_ext = $this->container->getParameters('core.php_ext'); + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; $this->errors = array(); } @@ -88,10 +88,7 @@ abstract class phpbb_db_migration */ protected function sql_query($sql) { - if (defined('DEBUG')) - { - echo "
\n{$sql}\n
"; - } + $this->queries[] = $sql; $this->db->sql_return_on_error(true); @@ -119,4 +116,14 @@ abstract class phpbb_db_migration return $result; } + + /** + * Get the list of queries run + * + * @return array + */ + public function get_queries() + { + return $this->queries; + } } diff --git a/phpBB/includes/db/migration/tools/config.php b/phpBB/includes/db/migration/tool/config.php similarity index 91% rename from phpBB/includes/db/migration/tools/config.php rename to phpBB/includes/db/migration/tool/config.php index 2d58c8093c..35fa3ce566 100644 --- a/phpBB/includes/db/migration/tools/config.php +++ b/phpBB/includes/db/migration/tool/config.php @@ -7,7 +7,7 @@ * */ -class phpbb_db_migration_tools_config +class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interface { /** @var phpbb_config */ protected $config = null; @@ -17,6 +17,14 @@ class phpbb_db_migration_tools_config $this->config = $config; } + /** + * {@inheritdoc} + */ + public function get_name() + { + return 'config'; + } + /** * Config Add * @@ -33,7 +41,7 @@ class phpbb_db_migration_tools_config throw new phpbb_db_migration_exception('CONFIG_ALREADY_EXISTS', $config_name); } - $this->config->set($config_name, $config_value, $is_dynamic); + $this->config->set($config_name, $config_value, !$is_dynamic); return false; } @@ -97,4 +105,4 @@ class phpbb_db_migration_tools_config return false; } -} \ No newline at end of file +} diff --git a/phpBB/includes/db/migration/tool/interface.php b/phpBB/includes/db/migration/tool/interface.php new file mode 100644 index 0000000000..1815f5e8a2 --- /dev/null +++ b/phpBB/includes/db/migration/tool/interface.php @@ -0,0 +1,18 @@ +db = $db; $this->cache = $cache; $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; + $this->modules_table = $modules_table; + } + + /** + * {@inheritdoc} + */ + public function get_name() + { + return 'module'; } /** @@ -63,7 +75,8 @@ class phpbb_db_migration_tools_module if (!is_numeric($parent)) { - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + $sql = 'SELECT module_id + FROM ' . $this->modules_table . " WHERE module_langname = '" . $this->db->sql_escape($parent) . "' AND module_class = '$class'"; $result = $this->db->sql_query($sql); @@ -83,7 +96,8 @@ class phpbb_db_migration_tools_module } } - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + $sql = 'SELECT module_id + FROM ' . $this->modules_table . " WHERE module_class = '$class' $parent_sql AND " . ((is_numeric($module)) ? 'module_id = ' . (int) $module : "module_langname = '$module'"); @@ -149,15 +163,15 @@ class phpbb_db_migration_tools_module $basename = (isset($data['module_basename'])) ? $data['module_basename'] : ''; $basename = str_replace(array('/', '\\'), '', $basename); $class = str_replace(array('/', '\\'), '', $class); - $info_file = "$class/info/{$class}_$basename.{$this->php_ext}"; + $info_file = "$class/info/$basename.{$this->php_ext}"; // The manual and automatic ways both failed... if (!file_exists((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file)) { - throw new phpbb_db_migration_exception('MODULE_ADD', $class, $info_file); + throw new phpbb_db_migration_exception('MODULE_INFO_FILE_NOT_EXIST', $class, $info_file); } - $classname = "{$class}_{$basename}_info"; + $classname = "{$basename}_info"; if (!class_exists($classname)) { @@ -198,7 +212,8 @@ class phpbb_db_migration_tools_module if (!is_numeric($parent)) { - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + $sql = 'SELECT module_id + FROM ' . $this->modules_table . " WHERE module_langname = '" . $this->db->sql_escape($parent) . "' AND module_class = '$class'"; $result = $this->db->sql_query($sql); @@ -254,40 +269,46 @@ class phpbb_db_migration_tools_module // Move the module if requested above/below an existing one if (isset($data['before']) && $data['before']) { - $sql = 'SELECT left_id FROM ' . MODULES_TABLE . ' + $sql = 'SELECT left_id + FROM ' . $this->modules_table . ' WHERE module_class = \'' . $class . '\' AND parent_id = ' . (int) $parent . ' AND module_langname = \'' . $this->db->sql_escape($data['before']) . '\''; $this->db->sql_query($sql); $to_left = $this->db->sql_fetchfield('left_id'); - $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 + $sql = 'UPDATE ' . $this->modules_table . " + SET left_id = left_id + 2, right_id = right_id + 2 WHERE module_class = '$class' AND left_id >= $to_left AND left_id < {$module_data['left_id']}"; $this->db->sql_query($sql); - $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = $to_left, right_id = " . ($to_left + 1) . " + $sql = 'UPDATE ' . $this->modules_table . " + SET left_id = $to_left, right_id = " . ($to_left + 1) . " WHERE module_class = '$class' AND module_id = {$module_data['module_id']}"; $this->db->sql_query($sql); } else if (isset($data['after']) && $data['after']) { - $sql = 'SELECT right_id FROM ' . MODULES_TABLE . ' + $sql = 'SELECT right_id + FROM ' . $this->modules_table . ' WHERE module_class = \'' . $class . '\' AND parent_id = ' . (int) $parent . ' AND module_langname = \'' . $this->db->sql_escape($data['after']) . '\''; $this->db->sql_query($sql); $to_right = $this->db->sql_fetchfield('right_id'); - $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 + $sql = 'UPDATE ' . $this->modules_table . " + SET left_id = left_id + 2, right_id = right_id + 2 WHERE module_class = '$class' AND left_id >= $to_right AND left_id < {$module_data['left_id']}"; $this->db->sql_query($sql); - $sql = 'UPDATE ' . MODULES_TABLE . ' SET left_id = ' . ($to_right + 1) . ', right_id = ' . ($to_right + 2) . " + $sql = 'UPDATE ' . $this->modules_table . ' + SET left_id = ' . ($to_right + 1) . ', right_id = ' . ($to_right + 2) . " WHERE module_class = '$class' AND module_id = {$module_data['module_id']}"; $this->db->sql_query($sql); @@ -330,14 +351,14 @@ class phpbb_db_migration_tools_module // Automatic method $basename = str_replace(array('/', '\\'), '', $module['module_basename']); $class = str_replace(array('/', '\\'), '', $class); - $info_file = "$class/info/{$class}_$basename.{$this->php_ext}"; + $info_file = "$class/info/$basename.{$this->php_ext}"; if (!file_exists((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file)) { throw new phpbb_db_migration_exception('MODULE_NOT_EXIST', $info_file); } - $classname = "{$class}_{$basename}_info"; + $classname = "{$basename}_info"; if (!class_exists($classname)) { @@ -374,7 +395,8 @@ class phpbb_db_migration_tools_module if (!is_numeric($parent)) { - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + $sql = 'SELECT module_id + FROM ' . $this->modules_table . " WHERE module_langname = '" . $this->db->sql_escape($parent) . "' AND module_class = '$class'"; $result = $this->db->sql_query($sql); @@ -394,7 +416,8 @@ class phpbb_db_migration_tools_module if (!is_numeric($module)) { $module = $this->db->sql_escape($module); - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + $sql = 'SELECT module_id + FROM ' . $this->modules_table . " WHERE module_langname = '$module' AND module_class = '$class' $parent_sql"; @@ -410,7 +433,8 @@ class phpbb_db_migration_tools_module else { $module = (int) $module; - $sql = 'SELECT module_langname FROM ' . MODULES_TABLE . " + $sql = 'SELECT module_langname + FROM ' . $this->modules_table . " WHERE module_id = $module AND module_class = '$class' $parent_sql"; @@ -439,9 +463,9 @@ class phpbb_db_migration_tools_module } } - $cache->destroy("_modules_$class"); + $this->cache->destroy("_modules_$class"); return false; } } -} \ No newline at end of file +} diff --git a/phpBB/includes/db/migration/tools/permission.php b/phpBB/includes/db/migration/tool/permission.php similarity index 78% rename from phpBB/includes/db/migration/tools/permission.php rename to phpBB/includes/db/migration/tool/permission.php index 7694bae0cb..ebe404bc62 100644 --- a/phpBB/includes/db/migration/tools/permission.php +++ b/phpBB/includes/db/migration/tool/permission.php @@ -7,7 +7,7 @@ * */ -class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base +class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_interface { /** @var phpbb_auth */ protected $auth = null; @@ -24,7 +24,7 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base /** @var string */ protected $php_ext = null; - public function __construct(dbal $db, phpbb_cache_driver_interface $cache, phpbb_auth $auth, $phpbb_root_path, $php_ext) + public function __construct(phpbb_db_driver $db, $cache, phpbb_auth $auth, $phpbb_root_path, $php_ext) { $this->db = $db; $this->cache = $cache; @@ -33,6 +33,14 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base $this->php_ext = $php_ext; } + /** + * {@inheritdoc} + */ + public function get_name() + { + return 'permission'; + } + /** * Permission Exists * @@ -81,7 +89,7 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base * * @return result */ - public function add($auth_option, $global = true) + public function add($auth_option, $global = true, $copy_from = false) { if ($this->exists($auth_option, $global)) { @@ -105,8 +113,8 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base 'is_local' => 1, ); $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' - SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE auth_option = \'' . $this->db->sql_escape($auth_option) . "'"; + SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . " + WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'"; $this->db->sql_query($sql); } else @@ -121,6 +129,38 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base } } + // The permission has been added, now we can copy it if needed + if ($copy_from && isset($auth_admin->acl_options['id'][$copy_from])) + { + $old_id = $auth_admin->acl_options['id'][$copy_from]; + $new_id = $auth_admin->acl_options['id'][$auth_option]; + + $tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE); + + foreach ($tables as $table) + { + $sql = 'SELECT * + FROM ' . $table . ' + WHERE auth_option_id = ' . $old_id; + $result = $this->db->sql_query($sql); + + $sql_ary = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $row['auth_option_id'] = $new_id; + $sql_ary[] = $row; + } + $this->db->sql_freeresult($result); + + if (sizeof($sql_ary)) + { + $this->db->sql_multi_insert($table, $sql_ary); + } + } + + $auth_admin->acl_clear_prefetch(); + } + return false; } @@ -149,7 +189,8 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base { $type_sql = ' AND is_local = 1'; } - $sql = 'SELECT auth_option_id, is_global, is_local FROM ' . ACL_OPTIONS_TABLE . " + $sql = 'SELECT auth_option_id, is_global, is_local + FROM ' . ACL_OPTIONS_TABLE . " WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" . $type_sql; $result = $this->db->sql_query($sql); @@ -190,8 +231,9 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base */ public function role_add($role_name, $role_type = '', $role_description = '') { - $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' - WHERE role_name = \'' . $this->db->sql_escape($role_name) . '\''; + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = '" . $this->db->sql_escape($role_name) . "'"; $this->db->sql_query($sql); $role_id = $this->db->sql_fetchfield('role_id'); @@ -200,8 +242,9 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base throw new phpbb_db_migration_exception('ROLE_ALREADY_EXISTS', $old_role_name); } - $sql = 'SELECT MAX(role_order) AS max FROM ' . ACL_ROLES_TABLE . ' - WHERE role_type = \'' . $this->db->sql_escape($role_type) . '\''; + $sql = 'SELECT MAX(role_order) AS max + FROM ' . ACL_ROLES_TABLE . " + WHERE role_type = '" . $this->db->sql_escape($role_type) . "'"; $this->db->sql_query($sql); $role_order = $this->db->sql_fetchfield('max'); $role_order = (!$role_order) ? 1 : $role_order + 1; @@ -227,8 +270,9 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base */ public function role_update($old_role_name, $new_role_name = '') { - $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' - WHERE role_name = \'' . $this->db->sql_escape($old_role_name) . '\''; + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = '" . $this->db->sql_escape($old_role_name) . "'"; $this->db->sql_query($sql); $role_id = $this->db->sql_fetchfield('role_id'); @@ -237,9 +281,9 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base throw new phpbb_db_migration_exception('ROLE_NOT_EXISTS', $old_role_name); } - $sql = 'UPDATE ' . ACL_ROLES_TABLE . ' - SET role_name = \'' . $this->db->sql_escape($new_role_name) . '\' - WHERE role_name = \'' . $this->db->sql_escape($old_role_name) . '\''; + $sql = 'UPDATE ' . ACL_ROLES_TABLE . " + SET role_name = '" . $this->db->sql_escape($new_role_name) . "' + WHERE role_name = '" . $this->db->sql_escape($old_role_name) . "'"; $this->db->sql_query($sql); return false; @@ -252,8 +296,9 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base */ public function role_remove($role_name) { - $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' - WHERE role_name = \'' . $this->db->sql_escape($role_name) . '\''; + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = '" . $this->db->sql_escape($role_name) . "'"; $this->db->sql_query($sql); $role_id = $this->db->sql_fetchfield('role_id'); @@ -293,7 +338,8 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base } $new_auth = array(); - $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' + $sql = 'SELECT auth_option_id + FROM ' . ACL_OPTIONS_TABLE . ' WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) @@ -314,8 +360,9 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base switch ($type) { case 'role' : - $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' - WHERE role_name = \'' . $this->db->sql_escape($name) . '\''; + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); $role_id = $this->db->sql_fetchfield('role_id'); @@ -324,7 +371,8 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base throw new phpbb_db_migration_exception('ROLE_NOT_EXIST', $name); } - $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_ROLES_DATA_TABLE . ' + $sql = 'SELECT auth_option_id, auth_setting + FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE role_id = ' . $role_id; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) @@ -335,7 +383,9 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base break; case 'group' : - $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' WHERE group_name = \'' . $this->db->sql_escape($name) . '\''; + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); $group_id = $this->db->sql_fetchfield('group_id'); @@ -345,7 +395,8 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base } // If the group has a role set for them we will add the requested permissions to that role. - $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' + $sql = 'SELECT auth_role_id + FROM ' . ACL_GROUPS_TABLE . ' WHERE group_id = ' . $group_id . ' AND auth_role_id <> 0 AND forum_id = 0'; @@ -353,7 +404,8 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base $role_id = $this->db->sql_fetchfield('auth_role_id'); if ($role_id) { - $sql = 'SELECT role_name FROM ' . ACL_ROLES_TABLE . ' + $sql = 'SELECT role_name + FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; $this->db->sql_query($sql); $role_name = $this->db->sql_fetchfield('role_name'); @@ -361,7 +413,8 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base return $this->set($role_name, $auth_option, 'role', $has_permission); } - $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_GROUPS_TABLE . ' + $sql = 'SELECT auth_option_id, auth_setting + FROM ' . ACL_GROUPS_TABLE . ' WHERE group_id = ' . $group_id; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) @@ -430,7 +483,8 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base } $to_remove = array(); - $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' + $sql = 'SELECT auth_option_id + FROM ' . ACL_OPTIONS_TABLE . ' WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) @@ -449,8 +503,9 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base switch ($type) { case 'role' : - $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' - WHERE role_name = \'' . $this->db->sql_escape($name) . '\''; + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); $role_id = $this->db->sql_fetchfield('role_id'); @@ -465,8 +520,9 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base break; case 'group' : - $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' - WHERE group_name = \'' . $this->db->sql_escape($name) . '\''; + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); $group_id = $this->db->sql_fetchfield('group_id'); @@ -476,14 +532,16 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base } // If the group has a role set for them we will remove the requested permissions from that role. - $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' + $sql = 'SELECT auth_role_id + FROM ' . ACL_GROUPS_TABLE . ' WHERE group_id = ' . $group_id . ' AND auth_role_id <> 0'; $this->db->sql_query($sql); $role_id = $this->db->sql_fetchfield('auth_role_id'); if ($role_id) { - $sql = 'SELECT role_name FROM ' . ACL_ROLES_TABLE . ' + $sql = 'SELECT role_name + FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; $this->db->sql_query($sql); $role_name = $this->db->sql_fetchfield('role_name'); @@ -501,4 +559,4 @@ class phpbb_db_migration_tools_permission extends phpbb_db_migration_tools_base return false; } -} \ No newline at end of file +} diff --git a/phpBB/includes/db/migration/tools/umil.php b/phpBB/includes/db/migration/tools/umil.php deleted file mode 100644 index ce7b8ff3be..0000000000 --- a/phpBB/includes/db/migration/tools/umil.php +++ /dev/null @@ -1,3037 +0,0 @@ -config_add(array( -* array('config_name', 'config_value'), -* array('config_name1', 'config_value1'), -* array('config_name2', 'config_value2', true), -* array('config_name3', 'config_value3', true), -* ); -*/ - -/** -* UMIL - Unified MOD Installation Library class -* -* Cache Functions -* cache_purge($type = '', $style_id = 0) -* -* Config Functions: -* config_exists($config_name, $return_result = false) -* config_add($config_name, $config_value = '', $is_dynamic = false) -* config_update($config_name, $config_value, $is_dynamic = false) -* config_remove($config_name) -* -* Module Functions -* module_exists($class, $parent, $module) -* module_add($class, $parent = 0, $data = array()) -* module_remove($class, $parent = 0, $module = '') -* -* Permissions/Auth Functions -* permission_exists($auth_option, $global = true) -* permission_add($auth_option, $global = true) -* permission_remove($auth_option, $global = true) -* permission_set($name, $auth_option = array(), $type = 'role', $global = true, $has_permission = true) -* permission_unset($name, $auth_option = array(), $type = 'role', $global = true) -* -* Table Functions -* table_exists($table_name) -* table_add($table_name, $table_data = array()) -* table_remove($table_name) -* -* Table Column Functions -* table_column_exists($table_name, $column_name) -* table_column_add($table_name, $column_name = '', $column_data = array()) -* table_column_update($table_name, $column_name = '', $column_data = array()) -* table_column_remove($table_name, $column_name = '') -* -* Table Key/Index Functions -* table_index_exists($table_name, $index_name) -* table_index_add($table_name, $index_name = '', $column = array()) -* table_index_remove($table_name, $index_name = '') -* -* Table Row Functions (note that these actions are not reversed automatically during uninstallation) -* table_row_insert($table_name, $data = array()) -* table_row_remove($table_name, $data = array()) -* table_row_update($table_name, $data = array(), $new_data = array()) -* -* Version Check Function -* version_check($url, $path, $file) -*/ -class umil -{ - /** - * This will hold the text output for the inputted command (if the mod author would like to display the command that was ran) - * - * @var string - */ - var $command = ''; - - /** - * This will hold the text output for the result of the command. $user->lang['SUCCESS'] if everything worked. - * - * @var string - */ - var $result = ''; - - /** - * Auto run $this->display_results after running a command - */ - var $auto_display_results = false; - - /** - * Stand Alone option (this makes it possible to just use the single umil file and not worry about any language stuff - */ - var $stand_alone = false; - - /** - * Were any new permissions added (used in umil_frontend)? - */ - var $permissions_added = false; - - /** - * Database Object - */ - var $db = false; - - /** - * Database Tools Object - */ - var $db_tools = false; - - /** - * Do we want a custom prefix besides the phpBB table prefix? You *probably* should not change this... - */ - var $table_prefix = false; - - /** - * Constructor - */ - function umil($stand_alone = false, $db = false) - { - // Setup $this->db - if ($db !== false) - { - if (!is_object($db) || !method_exists($db, 'sql_query')) - { - trigger_error('Invalid $db Object'); - } - - $this->db = $db; - } - else - { - global $db; - $this->db = $db; - } - - // Setup $this->db_tools - if (!class_exists('phpbb_db_tools')) - { - global $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/db/db_tools.' . $phpEx); - } - $this->db_tools = new phpbb_db_tools($this->db); - - $this->stand_alone = $stand_alone; - - if (!$stand_alone) - { - global $config, $user, $phpbb_root_path, $phpEx; - - /* Does not have the fall back option to use en/ if the user's language file does not exist, so we will not use it...unless that is changed. - if (method_exists('user', 'set_custom_lang_path')) - { - $user->set_custom_lang_path($phpbb_root_path . 'umil/language/'); - $user->add_lang('umil'); - $user->set_custom_lang_path($phpbb_root_path . 'language/'); - } - else - {*/ - // Include the umil language file. First we check if the language file for the user's language is available, if not we check if the board's default language is available, if not we use the english file. - if (isset($user->data['user_lang']) && file_exists("{$phpbb_root_path}umil/language/{$user->data['user_lang']}/umil.$phpEx")) - { - $path = $user->data['user_lang']; - } - else if (file_exists("{$phpbb_root_path}umil/language/" . basename($config['default_lang']) . "/umil.$phpEx")) - { - $path = basename($config['default_lang']); - } - else if (file_exists("{$phpbb_root_path}umil/language/en/umil.$phpEx")) - { - $path = 'en'; - } - else - { - trigger_error('Language Files Missing.

Please download the latest UMIL (Unified MOD Install Library) from: phpBB.com/mods/umil', E_USER_ERROR); - } - - $user->add_lang('./../../umil/language/' . $path . '/umil'); - //} - - $user->add_lang(array('acp/common', 'acp/permissions')); - - // Check to see if a newer version is available. - $info = $this->version_check('version.phpbb.com', '/umil', ((defined('PHPBB_QA')) ? 'umil_qa.txt' : 'umil.txt')); - if (is_array($info) && isset($info[0]) && isset($info[1])) - { - if (version_compare(UMIL_VERSION, $info[0], '<')) - { - global $template; - - // Make sure user->setup() has been called - if (empty($user->lang)) - { - $user->setup(); - } - - page_header('', false); - - $user->lang['UPDATE_UMIL'] = (isset($user->lang['UPDATE_UMIL'])) ? $user->lang['UPDATE_UMIL'] : 'This version of UMIL is outdated.

Please download the latest UMIL (Unified MOD Install Library) from: %1$s'; - $template->assign_vars(array( - 'S_BOARD_DISABLED' => true, - 'L_BOARD_DISABLED' => sprintf($user->lang['UPDATE_UMIL'], $info[1]), - )); - } - } - } - } - - /** - * umil_start - * - * A function which runs (almost) every time a function here is ran - */ - function umil_start() - { - global $user; - - // Set up the command. This will get the arguments sent to the function. - $args = func_get_args(); - $this->command = call_user_func_array(array($this, 'get_output_text'), $args); - - $this->result = (isset($user->lang['SUCCESS'])) ? $user->lang['SUCCESS'] : 'SUCCESS'; - $this->db->sql_return_on_error(true); - - //$this->db->sql_transaction('begin'); - } - - /** - * umil_end - * - * A function which runs (almost) every time a function here is ran - */ - function umil_end() - { - global $user; - - // Set up the result. This will get the arguments sent to the function. - $args = func_get_args(); - $result = call_user_func_array(array($this, 'get_output_text'), $args); - $this->result = ($result) ? $result : $this->result; - - if ($this->db->sql_error_triggered) - { - if ($this->result == ((isset($user->lang['SUCCESS'])) ? $user->lang['SUCCESS'] : 'SUCCESS')) - { - $this->result = 'SQL ERROR ' . $this->db->sql_error_returned['message']; - } - else - { - $this->result .= '

SQL ERROR ' . $this->db->sql_error_returned['message']; - } - - //$this->db->sql_transaction('rollback'); - } - else - { - //$this->db->sql_transaction('commit'); - } - - $this->db->sql_return_on_error(false); - - // Auto output if requested. - if ($this->auto_display_results && method_exists($this, 'display_results')) - { - $this->display_results(); - } - - return '' . $this->command . '
' . $this->result; - } - - /** - * Get text for output - * - * Takes the given arguments and prepares them for the UI - * - * First argument sent is used as the language key - * Further arguments (if send) are used on the language key through vsprintf() - * - * @return string Returns the prepared string for output - */ - function get_output_text() - { - global $user; - - // Set up the command. This will get the arguments sent to the function. - $args = func_get_args(); - if (sizeof($args)) - { - $lang_key = array_shift($args); - - if (sizeof($args)) - { - $lang_args = array(); - foreach ($args as $arg) - { - $lang_args[] = (isset($user->lang[$arg])) ? $user->lang[$arg] : $arg; - } - - return @vsprintf(((isset($user->lang[$lang_key])) ? $user->lang[$lang_key] : $lang_key), $lang_args); - } - else - { - return ((isset($user->lang[$lang_key])) ? $user->lang[$lang_key] : $lang_key); - } - } - - return ''; - } - - /** - * Run Actions - * - * Do-It-All function that can do everything required for installing/updating/uninstalling a mod based on an array of actions and the versions. - * - * @param string $action The action. install|update|uninstall - * @param array $versions The array of versions and the actions for each - * @param string $version_config_name The name of the config setting which holds/will hold the currently installed version - * @param string $version_select Added for the UMIL Auto system to allow you to select the version you want to install/update/uninstall to. - */ - function run_actions($action, $versions, $version_config_name, $version_select = '') - { - // We will sort the actions to prevent issues from mod authors incorrectly listing the version numbers - uksort($versions, 'version_compare'); - - // Find the current version to install - $current_version = '0.0.0'; - foreach ($versions as $version => $actions) - { - $current_version = $version; - } - - $db_version = ''; - if ($this->config_exists($version_config_name)) - { - global $config; - $db_version = $config[$version_config_name]; - } - - // Set the action to install from update if nothing is currently installed - if ($action == 'update' && !$db_version) - { - $action = 'install'; - } - - if ($action == 'install' || $action == 'update') - { - $version_installed = $db_version; - foreach ($versions as $version => $version_actions) - { - // If we are updating - if ($db_version && version_compare($version, $db_version, '<=')) - { - continue; - } - - if ($version_select && version_compare($version, $version_select, '>')) - { - break; - } - - foreach ($version_actions as $method => $params) - { - if ($method == 'custom') - { - $this->_call_custom_function($params, $action, $version); - } - else - { - if (method_exists($this, $method)) - { - call_user_func(array($this, $method), $params); - } - } - } - - $version_installed = $version; - } - - // update the version number or add it - if ($this->config_exists($version_config_name)) - { - $this->config_update($version_config_name, $version_installed); - } - else - { - $this->config_add($version_config_name, $version_installed); - } - } - else if ($action == 'uninstall' && $db_version) - { - // reverse version list - $versions = array_reverse($versions); - - foreach ($versions as $version => $version_actions) - { - // Uninstalling and this listed version is newer than installed - if (version_compare($version, $db_version, '>')) - { - continue; - } - - // Version selection stuff - if ($version_select && version_compare($version, $version_select, '<=')) - { - // update the version number - $this->config_update($version_config_name, $version); - break; - } - - $cache_purge = false; - $version_actions = array_reverse($version_actions); - foreach ($version_actions as $method => $params) - { - if ($method == 'custom') - { - $this->_call_custom_function($params, $action, $version); - } - else - { - // This way we always run the cache purge at the end of the version (done for the uninstall because the instructions are reversed, which would cause the cache purge to be run at the beginning if it was meant to run at the end). - if ($method == 'cache_purge') - { - $cache_purge = $params; - continue; - } - - // A few things are not possible for uninstallations update actions and table_row actions - if (strpos($method, 'update') !== false || strpos($method, 'table_insert') !== false || strpos($method, 'table_row_') !== false) - { - continue; - } - - // reverse function call - $method = str_replace(array('add', 'remove', 'temp'), array('temp', 'add', 'remove'), $method); - $method = str_replace(array('set', 'unset', 'temp'), array('temp', 'set', 'unset'), $method); - - if (method_exists($this, $method)) - { - call_user_func(array($this, $method), ((is_array($params) ? array_reverse($params) : $params))); - } - } - } - - if ($cache_purge !== false) - { - $this->cache_purge($cache_purge); - } - } - - if (!$version_select) - { - // Unset the version number - $this->config_remove($version_config_name); - } - } - } - - /** - * Call custom function helper - */ - function _call_custom_function($functions, $action, $version) - { - if (!is_array($functions)) - { - $functions = array($functions); - } - - $return = ''; - - foreach ($functions as $function) - { - if (function_exists($function)) - { - // Must reset before calling the function - $this->umil_start(); - - $returned = call_user_func($function, $action, $version); - if (is_string($returned)) - { - $this->command = $this->get_output_text($returned); - } - else if (is_array($returned) && isset($returned['command'])) - { - if (is_array($returned['command'])) - { - $this->command = call_user_func_array(array($this, 'get_output_text'), $returned['command']); - } - else - { - $this->command = $this->get_output_text($returned['command']); - } - - if (isset($returned['result'])) - { - $this->result = $this->get_output_text($returned['result']); - } - } - else - { - $this->command = $this->get_output_text('UNKNOWN'); - } - - $return .= $this->umil_end() . '
'; - } - } - - return $return; - } - - /** - * Multicall Helper - * - * @param mixed $function Function name to call - * @param mixed $params The parameters array - * - * @return bool True if we have done a multicall ($params is an array), false if not ($params is not an array) - */ - function multicall($function, $params) - { - if (is_array($params) && !empty($params)) - { - foreach ($params as $param) - { - if (!is_array($param)) - { - call_user_func(array($this, $function), $param); - } - else - { - call_user_func_array(array($this, $function), $param); - } - } - return true; - } - - return false; - } - - /** - * Cache Purge - * - * This function is for purging either phpBB3’s data cache, authorization cache, or the styles cache. - * - * @param string $type The type of cache you want purged. Available types: auth, imageset, template, theme. Anything else sent will purge the forum's cache. - * @param int $style_id The id of the item you want purged (if the type selected is imageset/template/theme, 0 for all items in that section) - */ - function cache_purge($type = '', $style_id = 0) - { - global $auth, $cache, $user, $phpbb_root_path, $phpEx; - - // Multicall - if ($this->multicall(__FUNCTION__, $type)) - { - return; - } - - $style_id = (int) $style_id; - $type = (string) $type; // Prevent PHP bug. - - switch ($type) - { - case 'auth' : - $this->umil_start('AUTH_CACHE_PURGE'); - $cache->destroy('_acl_options'); - $auth->acl_clear_prefetch(); - - return $this->umil_end(); - break; - - case 'imageset' : - if ($style_id == 0) - { - $return = array(); - $sql = 'SELECT imageset_id - FROM ' . STYLES_IMAGESET_TABLE; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $return[] = $this->cache_purge('imageset', $row['imageset_id']); - } - $this->db->sql_freeresult($result); - - return implode('

', $return); - } - else - { - $sql = 'SELECT * - FROM ' . STYLES_IMAGESET_TABLE . " - WHERE imageset_id = $style_id"; - $result = $this->db->sql_query($sql); - $imageset_row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if (!$imageset_row) - { - $this->umil_start('IMAGESET_CACHE_PURGE', 'UNKNOWN'); - return $this->umil_end('FAIL'); - } - - $this->umil_start('IMAGESET_CACHE_PURGE', $imageset_row['imageset_name']); - - // The following is from includes/acp/acp_styles.php (edited) - $sql_ary = array(); - - $cfg_data_imageset = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/imageset.cfg"); - - $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . ' - WHERE imageset_id = ' . $style_id; - $result = $this->db->sql_query($sql); - - foreach ($cfg_data_imageset as $image_name => $value) - { - if (strpos($value, '*') !== false) - { - if (substr($value, -1, 1) === '*') - { - list($image_filename, $image_height) = explode('*', $value); - $image_width = 0; - } - else - { - list($image_filename, $image_height, $image_width) = explode('*', $value); - } - } - else - { - $image_filename = $value; - $image_height = $image_width = 0; - } - - if (strpos($image_name, 'img_') === 0 && $image_filename) - { - $image_name = substr($image_name, 4); - - $sql_ary[] = array( - 'image_name' => (string) $image_name, - 'image_filename' => (string) $image_filename, - 'image_height' => (int) $image_height, - 'image_width' => (int) $image_width, - 'imageset_id' => (int) $style_id, - 'image_lang' => '', - ); - } - } - - $sql = 'SELECT lang_dir - FROM ' . LANG_TABLE; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg")) - { - $cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg"); - foreach ($cfg_data_imageset_data as $image_name => $value) - { - if (strpos($value, '*') !== false) - { - if (substr($value, -1, 1) === '*') - { - list($image_filename, $image_height) = explode('*', $value); - $image_width = 0; - } - else - { - list($image_filename, $image_height, $image_width) = explode('*', $value); - } - } - else - { - $image_filename = $value; - $image_height = $image_width = 0; - } - - if (strpos($image_name, 'img_') === 0 && $image_filename) - { - $image_name = substr($image_name, 4); - $sql_ary[] = array( - 'image_name' => (string) $image_name, - 'image_filename' => (string) $image_filename, - 'image_height' => (int) $image_height, - 'image_width' => (int) $image_width, - 'imageset_id' => (int) $style_id, - 'image_lang' => (string) $row['lang_dir'], - ); - } - } - } - } - $this->db->sql_freeresult($result); - - $this->db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary); - - $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE); - - return $this->umil_end(); - } - break; - //case 'imageset' : - - case 'template' : - if ($style_id == 0) - { - $return = array(); - $sql = 'SELECT template_id - FROM ' . STYLES_TEMPLATE_TABLE; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $return[] = $this->cache_purge('template', $row['template_id']); - } - $this->db->sql_freeresult($result); - - return implode('

', $return); - } - else - { - $sql = 'SELECT * - FROM ' . STYLES_TEMPLATE_TABLE . " - WHERE template_id = $style_id"; - $result = $this->db->sql_query($sql); - $template_row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if (!$template_row) - { - $this->umil_start('TEMPLATE_CACHE_PURGE', 'UNKNOWN'); - return $this->umil_end('FAIL'); - } - - $this->umil_start('TEMPLATE_CACHE_PURGE', $template_row['template_name']); - - // The following is from includes/acp/acp_styles.php - if ($template_row['template_storedb'] && file_exists("{$phpbb_root_path}styles/{$template_row['template_path']}/template/")) - { - $filelist = array('' => array()); - - $sql = 'SELECT template_filename, template_mtime - FROM ' . STYLES_TEMPLATE_DATA_TABLE . " - WHERE template_id = $style_id"; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { -// if (@filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/" . $row['template_filename']) > $row['template_mtime']) -// { - // get folder info from the filename - if (($slash_pos = strrpos($row['template_filename'], '/')) === false) - { - $filelist[''][] = $row['template_filename']; - } - else - { - $filelist[substr($row['template_filename'], 0, $slash_pos + 1)][] = substr($row['template_filename'], $slash_pos + 1, strlen($row['template_filename']) - $slash_pos - 1); - } -// } - } - $this->db->sql_freeresult($result); - - $includes = array(); - foreach ($filelist as $pathfile => $file_ary) - { - foreach ($file_ary as $file) - { - if (!($fp = @fopen("{$phpbb_root_path}styles/{$template_row['template_path']}$pathfile$file", 'r'))) - { - return $this->umil_end('FILE_COULD_NOT_READ', "{$phpbb_root_path}styles/{$template_row['template_path']}$pathfile$file"); - } - $template_data = fread($fp, filesize("{$phpbb_root_path}styles/{$template_row['template_path']}$pathfile$file")); - fclose($fp); - - if (preg_match_all('##is', $template_data, $matches)) - { - foreach ($matches[1] as $match) - { - $includes[trim($match)][] = $file; - } - } - } - } - - foreach ($filelist as $pathfile => $file_ary) - { - foreach ($file_ary as $file) - { - // Skip index. - if (strpos($file, 'index.') === 0) - { - continue; - } - - // We could do this using extended inserts ... but that could be one - // heck of a lot of data ... - $sql_ary = array( - 'template_id' => (int) $style_id, - 'template_filename' => "$pathfile$file", - 'template_included' => (isset($includes[$file])) ? implode(':', $includes[$file]) . ':' : '', - 'template_mtime' => (int) filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}$pathfile$file"), - 'template_data' => (string) file_get_contents("{$phpbb_root_path}styles/{$template_row['template_path']}$pathfile$file"), - ); - - $sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . ' SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . " - WHERE template_id = $style_id - AND template_filename = '" . $this->db->sql_escape("$pathfile$file") . "'"; - $this->db->sql_query($sql); - } - } - unset($filelist); - } - - // Purge the forum's cache as well. - $cache->purge(); - - return $this->umil_end(); - } - break; - //case 'template' : - - case 'theme' : - if ($style_id == 0) - { - $return = array(); - $sql = 'SELECT theme_id - FROM ' . STYLES_THEME_TABLE; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $return[] = $this->cache_purge('theme', $row['theme_id']); - } - $this->db->sql_freeresult($result); - - return implode('

', $return); - } - else - { - $sql = 'SELECT * - FROM ' . STYLES_THEME_TABLE . " - WHERE theme_id = $style_id"; - $result = $this->db->sql_query($sql); - $theme_row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if (!$theme_row) - { - $this->umil_start('THEME_CACHE_PURGE', 'UNKNOWN'); - return $this->umil_end('FAIL'); - } - - $this->umil_start('THEME_CACHE_PURGE', $theme_row['theme_name']); - - // The following is from includes/acp/acp_styles.php - if ($theme_row['theme_storedb'] && file_exists("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css")) - { - $stylesheet = file_get_contents($phpbb_root_path . 'styles/' . $theme_row['theme_path'] . '/theme/stylesheet.css'); - - // Match CSS imports - $matches = array(); - preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches); - - if (sizeof($matches)) - { - foreach ($matches[0] as $idx => $match) - { - if (!file_exists("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/{$matches[1][$idx]}")) - { - continue; - } - - $content = trim(file_get_contents("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/{$matches[1][$idx]}")); - $stylesheet = str_replace($match, $content, $stylesheet); - } - } - - // adjust paths - $db_theme_data = str_replace('./', 'styles/' . $theme_row['theme_path'] . '/theme/', $stylesheet); - - // Save CSS contents - $sql_ary = array( - 'theme_mtime' => (int) filemtime("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"), - 'theme_data' => $db_theme_data, - ); - - $sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . " - WHERE theme_id = $style_id"; - $this->db->sql_query($sql); - - $cache->destroy('sql', STYLES_THEME_TABLE); - } - - return $this->umil_end(); - } - break; - //case 'theme' : - - default: - $this->umil_start('CACHE_PURGE'); - $cache->purge(); - - return $this->umil_end(); - break; - } - } - - /** - * Config Exists - * - * This function is to check to see if a config variable exists or if it does not. - * - * @param string $config_name The name of the config setting you wish to check for. - * @param bool $return_result - return the config value/default if true : default false. - * - * @return bool true/false if config exists - */ - function config_exists($config_name, $return_result = false) - { - global $config, $cache; - - $sql = 'SELECT * - FROM ' . CONFIG_TABLE . " - WHERE config_name = '" . $this->db->sql_escape($config_name) . "'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if ($row) - { - if (!isset($config[$config_name])) - { - $config[$config_name] = $row['config_value']; - - if (!$row['is_dynamic']) - { - $cache->destroy('config'); - } - } - - return ($return_result) ? $row : true; - } - - // this should never happen, but if it does, we need to remove the config from the array - if (isset($config[$config_name])) - { - unset($config[$config_name]); - $cache->destroy('config'); - } - - return false; - } - - /** - * Config Add - * - * This function allows you to add a config setting. - * - * @param string $config_name The name of the config setting you would like to add - * @param mixed $config_value The value of the config setting - * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. - * - * @return result - */ - function config_add($config_name, $config_value = '', $is_dynamic = false) - { - // Multicall - if ($this->multicall(__FUNCTION__, $config_name)) - { - return; - } - - $this->umil_start('CONFIG_ADD', $config_name); - - if ($this->config_exists($config_name)) - { - return $this->umil_end('CONFIG_ALREADY_EXISTS', $config_name); - } - - set_config($config_name, $config_value, $is_dynamic); - - return $this->umil_end(); - } - - /** - * Config Update - * - * This function allows you to update an existing config setting. - * - * @param string $config_name The name of the config setting you would like to update - * @param mixed $config_value The value of the config setting - * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. - * - * @return result - */ - function config_update($config_name, $config_value = '', $is_dynamic = false) - { - // Multicall - if ($this->multicall(__FUNCTION__, $config_name)) - { - return; - } - - $this->umil_start('CONFIG_UPDATE', $config_name); - - if (!$this->config_exists($config_name)) - { - return $this->umil_end('CONFIG_NOT_EXIST', $config_name); - } - - set_config($config_name, $config_value, $is_dynamic); - - return $this->umil_end(); - } - - /** - * Config Remove - * - * This function allows you to remove an existing config setting. - * - * @param string $config_name The name of the config setting you would like to remove - * - * @return result - */ - function config_remove($config_name) - { - global $cache, $config; - - // Multicall - if ($this->multicall(__FUNCTION__, $config_name)) - { - return; - } - - $this->umil_start('CONFIG_REMOVE', $config_name); - - if (!$this->config_exists($config_name)) - { - return $this->umil_end('CONFIG_NOT_EXIST', $config_name); - } - - $sql = 'DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = '" . $this->db->sql_escape($config_name) . "'"; - $this->db->sql_query($sql); - - unset($config[$config_name]); - $cache->destroy('config'); - - return $this->umil_end(); - } - - /** - * Module Exists - * - * Check if a module exists - * - * @param string $class The module class(acp|mcp|ucp) - * @param int|string|bool $parent The parent module_id|module_langname (0 for no parent). 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 - */ - function module_exists($class, $parent, $module) - { - // the main root directory should return true - if (!$module) - { - return true; - } - - $class = $this->db->sql_escape($class); - $module = $this->db->sql_escape($module); - - $parent_sql = ''; - if ($parent !== false) - { - // Allows '' to be sent as 0 - $parent = (!$parent) ? 0 : $parent; - - if (!is_numeric($parent)) - { - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " - WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '$class'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if (!$row) - { - return false; - } - - $parent_sql = 'AND parent_id = ' . (int) $row['module_id']; - } - else - { - $parent_sql = 'AND parent_id = ' . (int) $parent; - } - } - - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " - WHERE module_class = '$class' - $parent_sql - AND " . ((is_numeric($module)) ? 'module_id = ' . (int) $module : "module_langname = '$module'"); - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if ($row) - { - return true; - } - - return false; - } - - /** - * Module Add - * - * Add a new module - * - * @param string $class The module class(acp|mcp|ucp) - * @param int|string $parent The parent module_id|module_langname (0 for no parent) - * @param array $data an array of the data on the new module. This can be setup in two different ways. - * 1. The "manual" way. For inserting a category or one at a time. It will be merged with the base array shown a bit below, - * but at the least requires 'module_langname' to be sent, and, if you want to create a module (instead of just a category) you must send module_basename and module_mode. - * array( - * 'module_enabled' => 1, - * 'module_display' => 1, - * 'module_basename' => '', - * 'module_class' => $class, - * 'parent_id' => (int) $parent, - * 'module_langname' => '', - * 'module_mode' => '', - * 'module_auth' => '', - * ) - * 2. The "automatic" way. For inserting multiple at a time based on the specs in the info file for the module(s). For this to work the modules must be correctly setup in the info file. - * An example follows (this would insert the settings, log, and flag modes from the includes/acp/info/acp_asacp.php file): - * array( - * 'module_basename' => 'asacp', - * 'modes' => array('settings', 'log', 'flag'), - * ) - * Optionally you may not send 'modes' and it will insert all of the modules in that info file. - * @param string|bool $include_path If you would like to use a custom include path, specify that here - */ - function module_add($class, $parent = 0, $data = array(), $include_path = false) - { - global $cache, $user, $phpbb_root_path, $phpEx; - - // Multicall - if ($this->multicall(__FUNCTION__, $class)) - { - return; - } - - // Prevent stupid things like trying to add a module with no name or any data on it - if (empty($data)) - { - $this->umil_start('MODULE_ADD', $class, 'UNKNOWN'); - return $this->umil_end('FAIL'); - } - - // Allows '' to be sent as 0 - $parent = (!$parent) ? 0 : $parent; - - // allow sending the name as a string in $data to create a category - if (!is_array($data)) - { - $data = array('module_langname' => $data); - } - - if (!isset($data['module_langname'])) - { - // The "automatic" way - $basename = (isset($data['module_basename'])) ? $data['module_basename'] : ''; - $basename = str_replace(array('/', '\\'), '', $basename); - $class = str_replace(array('/', '\\'), '', $class); - $info_file = "$class/info/{$class}_$basename.$phpEx"; - - // The manual and automatic ways both failed... - if (!file_exists((($include_path === false) ? $phpbb_root_path . 'includes/' : $include_path) . $info_file)) - { - $this->umil_start('MODULE_ADD', $class, $info_file); - return $this->umil_end('FAIL'); - } - - $classname = "{$class}_{$basename}_info"; - - if (!class_exists($classname)) - { - include((($include_path === false) ? $phpbb_root_path . 'includes/' : $include_path) . $info_file); - } - - $info = new $classname; - $module = $info->module(); - unset($info); - - $result = ''; - foreach ($module['modes'] as $mode => $module_info) - { - if (!isset($data['modes']) || in_array($mode, $data['modes'])) - { - $new_module = array( - 'module_basename' => $basename, - 'module_langname' => $module_info['title'], - 'module_mode' => $mode, - 'module_auth' => $module_info['auth'], - 'module_display' => (isset($module_info['display'])) ? $module_info['display'] : true, - 'before' => (isset($module_info['before'])) ? $module_info['before'] : false, - 'after' => (isset($module_info['after'])) ? $module_info['after'] : false, - ); - - // Run the "manual" way with the data we've collected. - $result .= ((isset($data['spacer'])) ? $data['spacer'] : '
') . $this->module_add($class, $parent, $new_module); - } - } - - return $result; - } - - // The "manual" way - $this->umil_start('MODULE_ADD', $class, ((isset($user->lang[$data['module_langname']])) ? $user->lang[$data['module_langname']] : $data['module_langname'])); - add_log('admin', 'LOG_MODULE_ADD', ((isset($user->lang[$data['module_langname']])) ? $user->lang[$data['module_langname']] : $data['module_langname'])); - - $class = $this->db->sql_escape($class); - - if (!is_numeric($parent)) - { - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " - WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '$class'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if (!$row) - { - return $this->umil_end('PARENT_NOT_EXIST'); - } - - $parent = $data['parent_id'] = $row['module_id']; - } - else if (!$this->module_exists($class, false, $parent)) - { - return $this->umil_end('PARENT_NOT_EXIST'); - } - - if ($this->module_exists($class, $parent, $data['module_langname'])) - { - return $this->umil_end('MODULE_ALREADY_EXIST'); - } - - if (!class_exists('acp_modules')) - { - include($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx); - $user->add_lang('acp/modules'); - } - $acp_modules = new acp_modules(); - - $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'] : '', - ); - $result = $acp_modules->update_module_data($module_data, true); - - // update_module_data can either return a string or an empty array... - if (is_string($result)) - { - // Error - $this->result = $this->get_output_text($result); - } - else - { - // Success - - // Move the module if requested above/below an existing one - if (isset($data['before']) && $data['before']) - { - $sql = 'SELECT left_id FROM ' . MODULES_TABLE . ' - WHERE module_class = \'' . $class . '\' - AND parent_id = ' . (int) $parent . ' - AND module_langname = \'' . $this->db->sql_escape($data['before']) . '\''; - $this->db->sql_query($sql); - $to_left = $this->db->sql_fetchfield('left_id'); - - $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 - WHERE module_class = '$class' - AND left_id >= $to_left - AND left_id < {$module_data['left_id']}"; - $this->db->sql_query($sql); - - $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = $to_left, right_id = " . ($to_left + 1) . " - WHERE module_class = '$class' - AND module_id = {$module_data['module_id']}"; - $this->db->sql_query($sql); - } - else if (isset($data['after']) && $data['after']) - { - $sql = 'SELECT right_id FROM ' . MODULES_TABLE . ' - WHERE module_class = \'' . $class . '\' - AND parent_id = ' . (int) $parent . ' - AND module_langname = \'' . $this->db->sql_escape($data['after']) . '\''; - $this->db->sql_query($sql); - $to_right = $this->db->sql_fetchfield('right_id'); - - $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 - WHERE module_class = '$class' - AND left_id >= $to_right - AND left_id < {$module_data['left_id']}"; - $this->db->sql_query($sql); - - $sql = 'UPDATE ' . MODULES_TABLE . ' SET left_id = ' . ($to_right + 1) . ', right_id = ' . ($to_right + 2) . " - WHERE module_class = '$class' - AND module_id = {$module_data['module_id']}"; - $this->db->sql_query($sql); - } - } - - // Clear the Modules Cache - $cache->destroy("_modules_$class"); - - return $this->umil_end(); - } - - /** - * Module Remove - * - * Remove a module - * - * @param string $class The module class(acp|mcp|ucp) - * @param int|string|bool $parent The parent module_id|module_langname (0 for no parent). Use false to ignore the parent check and check class wide. - * @param int|string $module The module id|module_langname - * @param string|bool $include_path If you would like to use a custom include path, specify that here - */ - function module_remove($class, $parent = 0, $module = '', $include_path = false) - { - global $cache, $user, $phpbb_root_path, $phpEx; - - // Multicall - if ($this->multicall(__FUNCTION__, $class)) - { - return; - } - - // Imitation of module_add's "automatic" and "manual" method so the uninstaller works from the same set of instructions for umil_auto - if (is_array($module)) - { - if (isset($module['module_langname'])) - { - // Manual Method - return $this->module_remove($class, $parent, $module['module_langname'], $include_path); - } - - // Failed. - if (!isset($module['module_basename'])) - { - $this->umil_start('MODULE_REMOVE', $class, 'UNKNOWN'); - return $this->umil_end('FAIL'); - } - - // Automatic method - $basename = str_replace(array('/', '\\'), '', $module['module_basename']); - $class = str_replace(array('/', '\\'), '', $class); - $info_file = "$class/info/{$class}_$basename.$phpEx"; - - if (!file_exists((($include_path === false) ? $phpbb_root_path . 'includes/' : $include_path) . $info_file)) - { - $this->umil_start('MODULE_REMOVE', $class, $info_file); - return $this->umil_end('FAIL'); - } - - $classname = "{$class}_{$basename}_info"; - - if (!class_exists($classname)) - { - include((($include_path === false) ? $phpbb_root_path . 'includes/' : $include_path) . $info_file); - } - - $info = new $classname; - $module_info = $info->module(); - unset($info); - - $result = ''; - foreach ($module_info['modes'] as $mode => $info) - { - if (!isset($module['modes']) || in_array($mode, $module['modes'])) - { - $result .= $this->module_remove($class, $parent, $info['title']) . '
'; - } - } - return $result; - } - else - { - $class = $this->db->sql_escape($class); - - if (!$this->module_exists($class, $parent, $module)) - { - $this->umil_start('MODULE_REMOVE', $class, ((isset($user->lang[$module])) ? $user->lang[$module] : $module)); - return $this->umil_end('MODULE_NOT_EXIST'); - } - - $parent_sql = ''; - if ($parent !== false) - { - // Allows '' to be sent as 0 - $parent = (!$parent) ? 0 : $parent; - - if (!is_numeric($parent)) - { - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " - WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '$class'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - // we know it exists from the module_exists check - $parent_sql = 'AND parent_id = ' . (int) $row['module_id']; - } - else - { - $parent_sql = 'AND parent_id = ' . (int) $parent; - } - } - - $module_ids = array(); - if (!is_numeric($module)) - { - $module = $this->db->sql_escape($module); - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " - WHERE module_langname = '$module' - AND module_class = '$class' - $parent_sql"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $module_ids[] = (int) $row['module_id']; - } - $this->db->sql_freeresult($result); - - $module_name = $module; - } - else - { - $module = (int) $module; - $sql = 'SELECT module_langname FROM ' . MODULES_TABLE . " - WHERE module_id = $module - AND module_class = '$class' - $parent_sql"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $module_name = $row['module_langname']; - $module_ids[] = $module; - } - - $this->umil_start('MODULE_REMOVE', $class, ((isset($user->lang[$module_name])) ? $user->lang[$module_name] : $module_name)); - add_log('admin', 'LOG_MODULE_REMOVED', ((isset($user->lang[$module_name])) ? $user->lang[$module_name] : $module_name)); - - if (!class_exists('acp_modules')) - { - include($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx); - $user->add_lang('acp/modules'); - } - $acp_modules = new acp_modules(); - $acp_modules->module_class = $class; - - foreach ($module_ids as $module_id) - { - $result = $acp_modules->delete_module($module_id); - if (!empty($result)) - { - if ($this->result == ((isset($user->lang['SUCCESS'])) ? $user->lang['SUCCESS'] : 'SUCCESS')) - { - $this->result = implode('
', $result); - } - else - { - $this->result .= '
' . implode('
', $result); - } - } - } - - $cache->destroy("_modules_$class"); - - return $this->umil_end(); - } - } - - /** - * Permission Exists - * - * Check if a permission (auth) setting exists - * - * @param string $auth_option The name of the permission (auth) option - * @param bool $global True for checking a global permission setting, False for a local permission setting - * - * @return bool true if it exists, false if not - */ - function permission_exists($auth_option, $global = true) - { - if ($global) - { - $type_sql = ' AND is_global = 1'; - } - else - { - $type_sql = ' AND is_local = 1'; - } - - $sql = 'SELECT auth_option_id - FROM ' . ACL_OPTIONS_TABLE . " - WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" - . $type_sql; - $result = $this->db->sql_query($sql); - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if ($row) - { - return true; - } - - return false; - } - - /** - * Permission Add - * - * Add a permission (auth) option - * - * @param string $auth_option The name of the permission (auth) option - * @param bool $global True for checking a global permission setting, False for a local permission setting - * - * @return result - */ - function permission_add($auth_option, $global = true) - { - // Multicall - if ($this->multicall(__FUNCTION__, $auth_option)) - { - return; - } - - $this->umil_start('PERMISSION_ADD', $auth_option); - - if ($this->permission_exists($auth_option, $global)) - { - return $this->umil_end('PERMISSION_ALREADY_EXISTS', $auth_option); - } - - // We've added permissions, so set to true to notify the user. - $this->permissions_added = true; - - if (!class_exists('auth_admin')) - { - global $phpbb_root_path, $phpEx; - - include($phpbb_root_path . 'includes/acp/auth.' . $phpEx); - } - $auth_admin = new auth_admin(); - - // We have to add a check to see if the !$global (if global, local, and if local, global) permission already exists. If it does, acl_add_option currently has a bug which would break the ACL system, so we are having a work-around here. - if ($this->permission_exists($auth_option, !$global)) - { - $sql_ary = array( - 'is_global' => 1, - 'is_local' => 1, - ); - $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' - SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE auth_option = \'' . $this->db->sql_escape($auth_option) . "'"; - $this->db->sql_query($sql); - } - else - { - if ($global) - { - $auth_admin->acl_add_option(array('global' => array($auth_option))); - } - else - { - $auth_admin->acl_add_option(array('local' => array($auth_option))); - } - } - - return $this->umil_end(); - } - - /** - * Permission Remove - * - * Remove a permission (auth) option - * - * @param string $auth_option The name of the permission (auth) option - * @param bool $global True for checking a global permission setting, False for a local permission setting - * - * @return result - */ - function permission_remove($auth_option, $global = true) - { - global $auth, $cache; - - // Multicall - if ($this->multicall(__FUNCTION__, $auth_option)) - { - return; - } - - $this->umil_start('PERMISSION_REMOVE', $auth_option); - - if (!$this->permission_exists($auth_option, $global)) - { - return $this->umil_end('PERMISSION_NOT_EXIST', $auth_option); - } - - if ($global) - { - $type_sql = ' AND is_global = 1'; - } - else - { - $type_sql = ' AND is_local = 1'; - } - $sql = 'SELECT auth_option_id, is_global, is_local FROM ' . ACL_OPTIONS_TABLE . " - WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" . - $type_sql; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $id = $row['auth_option_id']; - - // If it is a local and global permission, do not remove the row! :P - if ($row['is_global'] && $row['is_local']) - { - $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' - SET ' . (($global) ? 'is_global = 0' : 'is_local = 0') . ' - WHERE auth_option_id = ' . $id; - $this->db->sql_query($sql); - } - else - { - // Delete time - $this->db->sql_query('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $id); - $this->db->sql_query('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $id); - $this->db->sql_query('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $id); - $this->db->sql_query('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $id); - } - - // Purge the auth cache - $cache->destroy('_acl_options'); - $auth->acl_clear_prefetch(); - - return $this->umil_end(); - } - - /** - * Add a new permission role - * - * @param string $role_name The new role name - * @param sting $role_type The type (u_, m_, a_) - */ - function permission_role_add($role_name, $role_type = '', $role_description = '') - { - // Multicall - if ($this->multicall(__FUNCTION__, $role_name)) - { - return; - } - - $this->umil_start('PERMISSION_ROLE_ADD', $role_name); - - $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' - WHERE role_name = \'' . $this->db->sql_escape($role_name) . '\''; - $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('role_id'); - - if ($role_id) - { - return $this->umil_end('ROLE_ALREADY_EXISTS', $old_role_name); - } - - $sql = 'SELECT MAX(role_order) AS max FROM ' . ACL_ROLES_TABLE . ' - WHERE role_type = \'' . $this->db->sql_escape($role_type) . '\''; - $this->db->sql_query($sql); - $role_order = $this->db->sql_fetchfield('max'); - $role_order = (!$role_order) ? 1 : $role_order + 1; - - $sql_ary = array( - 'role_name' => $role_name, - 'role_description' => $role_description, - 'role_type' => $role_type, - 'role_order' => $role_order, - ); - - $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); - $this->db->sql_query($sql); - - return $this->umil_end(); - } - - /** - * Update the name on a permission role - * - * @param string $old_role_name The old role name - * @param string $new_role_name The new role name - */ - function permission_role_update($old_role_name, $new_role_name = '') - { - // Multicall - if ($this->multicall(__FUNCTION__, $role_name)) - { - return; - } - - $this->umil_start('PERMISSION_ROLE_UPDATE', $old_role_name); - - $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' - WHERE role_name = \'' . $this->db->sql_escape($old_role_name) . '\''; - $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('role_id'); - - if (!$role_id) - { - return $this->umil_end('ROLE_NOT_EXIST', $old_role_name); - } - - $sql = 'UPDATE ' . ACL_ROLES_TABLE . ' - SET role_name = \'' . $this->db->sql_escape($new_role_name) . '\' - WHERE role_name = \'' . $this->db->sql_escape($old_role_name) . '\''; - $this->db->sql_query($sql); - - return $this->umil_end(); - } - - /** - * Remove a permission role - * - * @param string $role_name The role name to remove - */ - function permission_role_remove($role_name) - { - global $auth; - - // Multicall - if ($this->multicall(__FUNCTION__, $role_name)) - { - return; - } - - $this->umil_start('PERMISSION_ROLE_REMOVE', $role_name); - - $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' - WHERE role_name = \'' . $this->db->sql_escape($role_name) . '\''; - $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('role_id'); - - if (!$role_id) - { - return $this->umil_end('ROLE_NOT_EXIST', $role_name); - } - - $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' - WHERE role_id = ' . $role_id; - $this->db->sql_query($sql); - - $sql = 'DELETE FROM ' . ACL_ROLES_TABLE . ' - WHERE role_id = ' . $role_id; - $this->db->sql_query($sql); - - $auth->acl_clear_prefetch(); - - return $this->umil_end(); - } - - /** - * Permission Set - * - * Allows you to set permissions for a certain group/role - * - * @param string $name The name of the role/group - * @param string|array $auth_option The auth_option or array of auth_options you would like to set - * @param string $type The type (role|group) - * @param bool $has_permission True if you want to give them permission, false if you want to deny them permission - */ - function permission_set($name, $auth_option = array(), $type = 'role', $has_permission = true) - { - global $auth; - - // Multicall - if ($this->multicall(__FUNCTION__, $name)) - { - return; - } - - if (!is_array($auth_option)) - { - $auth_option = array($auth_option); - } - - $new_auth = array(); - $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' - WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $new_auth[] = $row['auth_option_id']; - } - $this->db->sql_freeresult($result); - - if (!sizeof($new_auth)) - { - return false; - } - - $current_auth = array(); - - $type = (string) $type; // Prevent PHP bug. - - switch ($type) - { - case 'role' : - $this->umil_start('PERMISSION_SET_ROLE', $name); - - $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' - WHERE role_name = \'' . $this->db->sql_escape($name) . '\''; - $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('role_id'); - - if (!$role_id) - { - return $this->umil_end('ROLE_NOT_EXIST'); - } - - $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_ROLES_DATA_TABLE . ' - WHERE role_id = ' . $role_id; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $current_auth[$row['auth_option_id']] = $row['auth_setting']; - } - $this->db->sql_freeresult($result); - break; - - case 'group' : - $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' WHERE group_name = \'' . $this->db->sql_escape($name) . '\''; - $this->db->sql_query($sql); - $group_id = $this->db->sql_fetchfield('group_id'); - - if (!$group_id) - { - $this->umil_start('PERMISSION_SET_GROUP', $name); - return $this->umil_end('GROUP_NOT_EXIST'); - } - - // If the group has a role set for them we will add the requested permissions to that role. - $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' - WHERE group_id = ' . $group_id . ' - AND auth_role_id <> 0 - AND forum_id = 0'; - $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('auth_role_id'); - if ($role_id) - { - $sql = 'SELECT role_name FROM ' . ACL_ROLES_TABLE . ' - WHERE role_id = ' . $role_id; - $this->db->sql_query($sql); - $role_name = $this->db->sql_fetchfield('role_name'); - - return $this->permission_set($role_name, $auth_option, 'role', $has_permission); - } - - $this->umil_start('PERMISSION_SET_GROUP', $name); - - $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_GROUPS_TABLE . ' - WHERE group_id = ' . $group_id; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $current_auth[$row['auth_option_id']] = $row['auth_setting']; - } - $this->db->sql_freeresult($result); - break; - } - - $sql_ary = array(); - switch ($type) - { - case 'role' : - foreach ($new_auth as $auth_option_id) - { - if (!isset($current_auth[$auth_option_id])) - { - $sql_ary[] = array( - 'role_id' => $role_id, - 'auth_option_id' => $auth_option_id, - 'auth_setting' => $has_permission, - ); - } - } - - $this->db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); - break; - - case 'group' : - foreach ($new_auth as $auth_option_id) - { - if (!isset($current_auth[$auth_option_id])) - { - $sql_ary[] = array( - 'group_id' => $group_id, - 'auth_option_id' => $auth_option_id, - 'auth_setting' => $has_permission, - ); - } - } - - $this->db->sql_multi_insert(ACL_GROUPS_TABLE, $sql_ary); - break; - } - - $auth->acl_clear_prefetch(); - - return $this->umil_end(); - } - - /** - * Permission Unset - * - * Allows you to unset (remove) permissions for a certain group/role - * - * @param string $name The name of the role/group - * @param string|array $auth_option The auth_option or array of auth_options you would like to set - * @param string $type The type (role|group) - */ - function permission_unset($name, $auth_option = array(), $type = 'role') - { - global $auth; - - // Multicall - if ($this->multicall(__FUNCTION__, $name)) - { - return; - } - - if (!is_array($auth_option)) - { - $auth_option = array($auth_option); - } - - $to_remove = array(); - $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' - WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $to_remove[] = $row['auth_option_id']; - } - $this->db->sql_freeresult($result); - - if (!sizeof($to_remove)) - { - return false; - } - - $type = (string) $type; // Prevent PHP bug. - - switch ($type) - { - case 'role' : - $this->umil_start('PERMISSION_UNSET_ROLE', $name); - - $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' - WHERE role_name = \'' . $this->db->sql_escape($name) . '\''; - $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('role_id'); - - if (!$role_id) - { - return $this->umil_end('ROLE_NOT_EXIST'); - } - - $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' - WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); - $this->db->sql_query($sql); - break; - - case 'group' : - $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' WHERE group_name = \'' . $this->db->sql_escape($name) . '\''; - $this->db->sql_query($sql); - $group_id = $this->db->sql_fetchfield('group_id'); - - if (!$group_id) - { - $this->umil_start('PERMISSION_UNSET_GROUP', $name); - return $this->umil_end('GROUP_NOT_EXIST'); - } - - // If the group has a role set for them we will remove the requested permissions from that role. - $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' - WHERE group_id = ' . $group_id . ' - AND auth_role_id <> 0'; - $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('auth_role_id'); - if ($role_id) - { - $sql = 'SELECT role_name FROM ' . ACL_ROLES_TABLE . ' - WHERE role_id = ' . $role_id; - $this->db->sql_query($sql); - $role_name = $this->db->sql_fetchfield('role_name'); - - return $this->permission_unset($role_name, $auth_option, 'role'); - } - - $this->umil_start('PERMISSION_UNSET_GROUP', $name); - - $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' - WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); - $this->db->sql_query($sql); - break; - } - - $auth->acl_clear_prefetch(); - - return $this->umil_end(); - } - - /** - * Table Exists - * - * Check if a table exists in the DB or not - * - * @param string $table_name The table name to check for - * - * @return bool true if the table exists, false if not - */ - function table_exists($table_name) - { - $this->get_table_name($table_name); - - // Use sql_table_exists if available - if (method_exists($this->db_tools, 'sql_table_exists')) - { - $roe = $this->db->return_on_error; - $result = $this->db_tools->sql_table_exists($table_name); - - // db_tools::sql_table_exists resets the return_on_error to false always after completing, so we must make sure we set it to true again if it was before - if ($roe) - { - $this->db->sql_return_on_error(true); - } - - return $result; - } - - if (!function_exists('get_tables')) - { - global $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/functions_install.' . $phpEx); - } - - $tables = get_tables($this->db); - - if (in_array($table_name, $tables)) - { - return true; - } - else - { - return false; - } - } - - /** - * Table Add - * - * This only supports input from the array format of db_tools or create_schema_files. - */ - function table_add($table_name, $table_data = array()) - { - global $dbms, $user; - - // Multicall - if ($this->multicall(__FUNCTION__, $table_name)) - { - return; - } - - /** - * $table_data can be empty when uninstalling a mod and table_remove was used, but no 2rd argument was given. - * In that case we'll assume that it was a column previously added by the mod (if not the author should specify a 2rd argument) and skip this to prevent an error - */ - if (empty($table_data)) - { - return; - } - - $this->get_table_name($table_name); - - $this->umil_start('TABLE_ADD', $table_name); - - if ($this->table_exists($table_name)) - { - return $this->umil_end('TABLE_ALREADY_EXISTS', $table_name); - } - - if (!is_array($table_data)) - { - return $this->umil_end('NO_TABLE_DATA'); - } - - if (!function_exists('get_available_dbms')) - { - global $phpbb_root_path, $phpEx; - include("{$phpbb_root_path}includes/functions_install.$phpEx"); - } - - /* - * This function has had numerous problems and is currently broken, so until phpBB uses it I will not be anymore - if (method_exists($this->db_tools, 'sql_create_table')) - { - // Added in 3.0.5 - $this->db_tools->sql_create_table($table_name, $table_data); - } - else - {*/ - $available_dbms = get_available_dbms($dbms); - - $sql_query = $this->create_table_sql($table_name, $table_data); - $sql_query = split_sql_file($sql_query, $available_dbms[$dbms]['DELIM']); - - foreach ($sql_query as $sql) - { - $this->db->sql_query($sql); - } - //} - - return $this->umil_end(); - } - - /** - * Table Remove - * - * Delete/Drop a DB table - */ - function table_remove($table_name) - { - // Multicall - if ($this->multicall(__FUNCTION__, $table_name)) - { - return; - } - - $this->get_table_name($table_name); - - $this->umil_start('TABLE_REMOVE', $table_name); - - if (!$this->table_exists($table_name)) - { - return $this->umil_end('TABLE_NOT_EXIST', $table_name); - } - - if (method_exists($this->db_tools, 'sql_table_drop')) - { - // Added in 3.0.5 - $this->db_tools->sql_table_drop($table_name); - } - else - { - $this->db->sql_query('DROP TABLE ' . $table_name); - } - - return $this->umil_end(); - } - - /** - * Table Column Exists - * - * Check to see if a column exists in a table - */ - function table_column_exists($table_name, $column_name) - { - $this->get_table_name($table_name); - - return $this->db_tools->sql_column_exists($table_name, $column_name); - } - - /** - * Table Column Add - * - * Add a new column to a table. - */ - function table_column_add($table_name, $column_name = '', $column_data = array()) - { - // Multicall - if ($this->multicall(__FUNCTION__, $table_name)) - { - return; - } - - /** - * $column_data can be empty when uninstalling a mod and table_column_remove was used, but no 3rd argument was given. - * In that case we'll assume that it was a column previously added by the mod (if not the author should specify a 3rd argument) and skip this to prevent an error - */ - if (empty($column_data)) - { - return; - } - - $this->get_table_name($table_name); - - $this->umil_start('TABLE_COLUMN_ADD', $table_name, $column_name); - - if ($this->table_column_exists($table_name, $column_name)) - { - return $this->umil_end('TABLE_COLUMN_ALREADY_EXISTS', $table_name, $column_name); - } - - $this->db_tools->sql_column_add($table_name, $column_name, $column_data); - - return $this->umil_end(); - } - - /** - * Table Column Update - * - * Alter/Update a column in a table. You can not change a column name with this. - */ - function table_column_update($table_name, $column_name = '', $column_data = array()) - { - // Multicall - if ($this->multicall(__FUNCTION__, $table_name)) - { - return; - } - - $this->get_table_name($table_name); - - $this->umil_start('TABLE_COLUMN_UPDATE', $table_name, $column_name); - - if (!$this->table_column_exists($table_name, $column_name)) - { - return $this->umil_end('TABLE_COLUMN_NOT_EXIST', $table_name, $column_name); - } - - $this->db_tools->sql_column_change($table_name, $column_name, $column_data); - - return $this->umil_end(); - } - - /** - * Table Column Remove - * - * Remove a column from a table - */ - function table_column_remove($table_name, $column_name = '') - { - // Multicall - if ($this->multicall(__FUNCTION__, $table_name)) - { - return; - } - - $this->get_table_name($table_name); - - $this->umil_start('TABLE_COLUMN_REMOVE', $table_name, $column_name); - - if (!$this->table_column_exists($table_name, $column_name)) - { - return $this->umil_end('TABLE_COLUMN_NOT_EXIST', $table_name, $column_name); - } - - $this->db_tools->sql_column_remove($table_name, $column_name); - - return $this->umil_end(); - } - - /** - * Table Index Exists - * - * Check if a table key/index exists on a table (can not check primary or unique) - */ - function table_index_exists($table_name, $index_name) - { - $this->get_table_name($table_name); - - $indexes = $this->db_tools->sql_list_index($table_name); - - if (in_array($index_name, $indexes)) - { - return true; - } - - return false; - } - - /** - * Table Index Add - * - * Add a new key/index to a table - */ - function table_index_add($table_name, $index_name = '', $column = array()) - { - global $config; - - // Multicall - if ($this->multicall(__FUNCTION__, $table_name)) - { - return; - } - - // Let them skip the column field and just use the index name in that case as the column as well - if (empty($column)) - { - $column = array($index_name); - } - - $this->get_table_name($table_name); - - $this->umil_start('TABLE_KEY_ADD', $table_name, $index_name); - - if ($this->table_index_exists($table_name, $index_name)) - { - return $this->umil_end('TABLE_KEY_ALREADY_EXIST', $table_name, $index_name); - } - - if (!is_array($column)) - { - $column = array($column); - } - - // remove index length if we are before 3.0.8 - // the feature (required for some types when using MySQL4) - // was added in that release (ticket PHPBB3-8944) - if (version_compare($config['version'], '3.0.7-pl1', '<=')) - { - $column = preg_replace('#:.*$#', '', $column); - } - - $this->db_tools->sql_create_index($table_name, $index_name, $column); - - return $this->umil_end(); - } - - /** - * Table Index Remove - * - * Remove a key/index from a table - */ - function table_index_remove($table_name, $index_name = '') - { - // Multicall - if ($this->multicall(__FUNCTION__, $table_name)) - { - return; - } - - $this->get_table_name($table_name); - - $this->umil_start('TABLE_KEY_REMOVE', $table_name, $index_name); - - if (!$this->table_index_exists($table_name, $index_name)) - { - return $this->umil_end('TABLE_KEY_NOT_EXIST', $table_name, $index_name); - } - - $this->db_tools->sql_index_drop($table_name, $index_name); - - return $this->umil_end(); - } - - // Ignore, function was renamed to table_row_insert and keeping for backwards compatibility - function table_insert($table_name, $data = array()) { $this->table_row_insert($table_name, $data); } - - /** - * Table Insert - * - * Insert data into a table - */ - function table_row_insert($table_name, $data = array()) - { - // Multicall - if ($this->multicall(__FUNCTION__, $table_name)) - { - return; - } - - $this->get_table_name($table_name); - - $this->umil_start('TABLE_ROW_INSERT_DATA', $table_name); - - if (!$this->table_exists($table_name)) - { - return $this->umil_end('TABLE_NOT_EXIST', $table_name); - } - - $this->db->sql_multi_insert($table_name, $data); - - return $this->umil_end(); - } - - /** - * Table Row Update - * - * Update a row in a table - * - * $data should be an array with the column names as keys and values as the items to check for each column. Example: - * array('user_id' => 123, 'user_name' => 'test user') would become: - * WHERE user_id = 123 AND user_name = 'test user' - * - * $new_data is the new data it will be updated to (same format as you'd enter into $db->sql_build_array('UPDATE' ). - */ - function table_row_update($table_name, $data = array(), $new_data = array()) - { - // Multicall - if ($this->multicall(__FUNCTION__, $table_name)) - { - return; - } - - if (!sizeof($data)) - { - return $this->umil_end('FAIL'); - } - - $this->get_table_name($table_name); - - $this->umil_start('TABLE_ROW_UPDATE_DATA', $table_name); - - if (!$this->table_exists($table_name)) - { - return $this->umil_end('TABLE_NOT_EXIST', $table_name); - } - - $sql = 'UPDATE ' . $table_name . ' - SET ' . $this->db->sql_build_array('UPDATE', $new_data) . ' - WHERE ' . $this->db->sql_build_array('SELECT', $data); - $this->db->sql_query($sql); - - return $this->umil_end(); - } - - /** - * Table Row Remove - * - * Remove a row from a table - * - * $data should be an array with the column names as keys and values as the items to check for each column. Example: - * array('user_id' => 123, 'user_name' => 'test user') would become: - * WHERE user_id = 123 AND user_name = 'test user' - */ - function table_row_remove($table_name, $data = array()) - { - // Multicall - if ($this->multicall(__FUNCTION__, $table_name)) - { - return; - } - - if (!sizeof($data)) - { - return $this->umil_end('FAIL'); - } - - $this->get_table_name($table_name); - - $this->umil_start('TABLE_ROW_REMOVE_DATA', $table_name); - - if (!$this->table_exists($table_name)) - { - return $this->umil_end('TABLE_NOT_EXIST', $table_name); - } - - $sql = 'DELETE FROM ' . $table_name . ' WHERE ' . $this->db->sql_build_array('SELECT', $data); - $this->db->sql_query($sql); - - return $this->umil_end(); - } - - /** - * Version Checker - * - * Format the file like the following: - * http://www.phpbb.com/updatecheck/30x.txt - * - * @param string $url The url to access (ex: www.phpbb.com) - * @param string $path The path to access (ex: /updatecheck) - * @param string $file The name of the file to access (ex: 30x.txt) - * - * @return array|string Error Message if there was any error, or an array (each line in the file as a value) - */ - function version_check($url, $path, $file, $timeout = 10, $port = 80) - { - if (!function_exists('get_remote_file')) - { - global $phpbb_root_path, $phpEx; - - include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); - } - - $errstr = $errno = ''; - - $info = get_remote_file($url, $path, $file, $errstr, $errno, $port, $timeout); - - if ($info === false) - { - return $errstr . ' [ ' . $errno . ' ]'; - } - - $info = str_replace("\r\n", "\n", $info); - $info = explode("\n", $info); - - return $info; - } - - /** - * Create table SQL - * - * Create the SQL query for the specified DBMS on the fly from a create_schema_files type of table array - * - * @param string $table_name The name of the table - * @param array $table_data The table data (formatted in the array format used by create_schema_files) - * @param string $dbms The dbms this will be built for (for testing only, leave blank to use the current DBMS) - * - * @return The sql query to run for the submitted dbms to insert the table - */ - function create_table_sql($table_name, $table_data, $dbms = '') - { - // To allow testing - $dbms = ($dbms) ? $dbms : $this->db_tools->sql_layer; - - // A list of types being unsigned for better reference in some db's - $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); - $supported_dbms = array('firebird', 'mssql', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite'); - - $sql = ''; - - // Create Table statement - $generator = $textimage = false; - - switch ($dbms) - { - case 'mysql_40': - case 'mysql_41': - case 'firebird': - case 'oracle': - case 'sqlite': - case 'postgres': - $sql .= "CREATE TABLE {$table_name} (\n"; - break; - - case 'mssql': - $sql .= "CREATE TABLE [{$table_name}] (\n"; - break; - } - - // Table specific so we don't get overlap - $modded_array = array(); - - // Write columns one by one... - foreach ($table_data['COLUMNS'] as $column_name => $column_data) - { - // Get type - if (strpos($column_data[0], ':') !== false) - { - list($orig_column_type, $column_length) = explode(':', $column_data[0]); - if (!is_array($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'])) - { - $column_type = sprintf($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'], $column_length); - } - else - { - if (isset($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['rule'])) - { - switch ($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['rule'][0]) - { - case 'div': - $column_length /= $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['rule'][1]; - $column_length = ceil($column_length); - $column_type = sprintf($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length); - break; - } - } - - if (isset($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'])) - { - switch ($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][0]) - { - case 'mult': - $column_length *= $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][1]; - if ($column_length > $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][2]) - { - $column_type = $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][3]; - $modded_array[$column_name] = $column_type; - } - else - { - $column_type = sprintf($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length); - } - break; - } - } - } - $orig_column_type .= ':'; - } - else - { - $orig_column_type = $column_data[0]; - $column_type = $this->db_tools->dbms_type_map[$dbms][$column_data[0]]; - if ($column_type == 'text' || $column_type == 'blob') - { - $modded_array[$column_name] = $column_type; - } - } - - // Adjust default value if db-dependant specified - if (is_array($column_data[1])) - { - $column_data[1] = (isset($column_data[1][$dbms])) ? $column_data[1][$dbms] : $column_data[1]['default']; - } - - switch ($dbms) - { - case 'mysql_40': - case 'mysql_41': - $sql .= "\t{$column_name} {$column_type} "; - - // For hexadecimal values do not use single quotes - if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob') - { - $sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' "; - } - $sql .= 'NOT NULL'; - - if (isset($column_data[2])) - { - if ($column_data[2] == 'auto_increment') - { - $sql .= ' auto_increment'; - } - else if ($dbms === 'mysql_41' && $column_data[2] == 'true_sort') - { - $sql .= ' COLLATE utf8_unicode_ci'; - } - } - - $sql .= ",\n"; - break; - - case 'sqlite': - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $sql .= "\t{$column_name} INTEGER PRIMARY KEY "; - $generator = $column_name; - } - else - { - $sql .= "\t{$column_name} {$column_type} "; - } - - $sql .= 'NOT NULL '; - $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : ''; - $sql .= ",\n"; - break; - - case 'firebird': - $sql .= "\t{$column_name} {$column_type} "; - - if (!is_null($column_data[1])) - { - $sql .= 'DEFAULT ' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' '; - } - - $sql .= 'NOT NULL'; - - // This is a UNICODE column and thus should be given it's fair share - if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0])) - { - $sql .= ' COLLATE UNICODE'; - } - - $sql .= ",\n"; - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $generator = $column_name; - } - break; - - case 'mssql': - if ($column_type == '[text]') - { - $textimage = true; - } - - $sql .= "\t[{$column_name}] {$column_type} "; - - if (!is_null($column_data[1])) - { - // For hexadecimal values do not use single quotes - if (strpos($column_data[1], '0x') === 0) - { - $sql .= 'DEFAULT (' . $column_data[1] . ') '; - } - else - { - $sql .= 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; - } - } - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $sql .= 'IDENTITY (1, 1) '; - } - - $sql .= 'NOT NULL'; - $sql .= " ,\n"; - break; - - case 'oracle': - $sql .= "\t{$column_name} {$column_type} "; - $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : ''; - - // In Oracle empty strings ('') are treated as NULL. - // Therefore in oracle we allow NULL's for all DEFAULT '' entries - $sql .= ($column_data[1] === '') ? ",\n" : "NOT NULL,\n"; - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $generator = $column_name; - } - break; - - case 'postgres': - $sql .= "\t{$column_name} {$column_type} "; - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $sql .= "DEFAULT nextval('{$table_name}_seq'),\n"; - - // Make sure the sequence will be created before creating the table - $sql = "CREATE SEQUENCE {$table_name}_seq;\n\n" . $sql; - } - else - { - $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : ''; - $sql .= "NOT NULL"; - - // Unsigned? Then add a CHECK contraint - if (in_array($orig_column_type, $unsigned_types)) - { - $sql .= " CHECK ({$column_name} >= 0)"; - } - - $sql .= ",\n"; - } - break; - } - } - - switch ($dbms) - { - case 'firebird': - // Remove last line delimiter... - $sql = substr($sql, 0, -2); - $sql .= "\n);;\n\n"; - break; - - case 'mssql': - $sql = substr($sql, 0, -2); - $sql .= "\n) ON [PRIMARY]" . (($textimage) ? ' TEXTIMAGE_ON [PRIMARY]' : '') . "\n"; - $sql .= "GO\n\n"; - break; - } - - // Write primary key - if (isset($table_data['PRIMARY_KEY'])) - { - if (!is_array($table_data['PRIMARY_KEY'])) - { - $table_data['PRIMARY_KEY'] = array($table_data['PRIMARY_KEY']); - } - - switch ($dbms) - { - case 'mysql_40': - case 'mysql_41': - case 'postgres': - $sql .= "\tPRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . "),\n"; - break; - - case 'firebird': - $sql .= "ALTER TABLE {$table_name} ADD PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ");;\n\n"; - break; - - case 'sqlite': - if ($generator === false || !in_array($generator, $table_data['PRIMARY_KEY'])) - { - $sql .= "\tPRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . "),\n"; - } - break; - - case 'mssql': - $sql .= "ALTER TABLE [{$table_name}] WITH NOCHECK ADD \n"; - $sql .= "\tCONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED \n"; - $sql .= "\t(\n"; - $sql .= "\t\t[" . implode("],\n\t\t[", $table_data['PRIMARY_KEY']) . "]\n"; - $sql .= "\t) ON [PRIMARY] \n"; - $sql .= "GO\n\n"; - break; - - case 'oracle': - $sql .= "\tCONSTRAINT pk_{$table_name} PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . "),\n"; - break; - } - } - - switch ($dbms) - { - case 'oracle': - // UNIQUE contrains to be added? - if (isset($table_data['KEYS'])) - { - foreach ($table_data['KEYS'] as $key_name => $key_data) - { - if (!is_array($key_data[1])) - { - $key_data[1] = array($key_data[1]); - } - - if ($key_data[0] == 'UNIQUE') - { - $sql .= "\tCONSTRAINT u_phpbb_{$key_name} UNIQUE (" . implode(', ', $key_data[1]) . "),\n"; - } - } - } - - // Remove last line delimiter... - $sql = substr($sql, 0, -2); - $sql .= "\n)\n/\n\n"; - break; - - case 'postgres': - // Remove last line delimiter... - $sql = substr($sql, 0, -2); - $sql .= "\n);\n\n"; - break; - - case 'sqlite': - // Remove last line delimiter... - $sql = substr($sql, 0, -2); - $sql .= "\n);\n\n"; - break; - } - - // Write Keys - if (isset($table_data['KEYS'])) - { - foreach ($table_data['KEYS'] as $key_name => $key_data) - { - if (!is_array($key_data[1])) - { - $key_data[1] = array($key_data[1]); - } - - switch ($dbms) - { - case 'mysql_40': - case 'mysql_41': - $sql .= ($key_data[0] == 'INDEX') ? "\tKEY" : ''; - $sql .= ($key_data[0] == 'UNIQUE') ? "\tUNIQUE" : ''; - foreach ($key_data[1] as $key => $col_name) - { - if (isset($modded_array[$col_name])) - { - switch ($modded_array[$col_name]) - { - case 'text': - case 'blob': - $key_data[1][$key] = $col_name . '(255)'; - break; - } - } - } - $sql .= ' ' . $key_name . ' (' . implode(', ', $key_data[1]) . "),\n"; - break; - - case 'firebird': - $sql .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; - $sql .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; - - $sql .= ' ' . $table_name . '_' . $key_name . ' ON ' . $table_name . '(' . implode(', ', $key_data[1]) . ");;\n"; - break; - - case 'mssql': - $sql .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; - $sql .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; - $sql .= " [{$key_name}] ON [{$table_name}]([" . implode('], [', $key_data[1]) . "]) ON [PRIMARY]\n"; - $sql .= "GO\n\n"; - break; - - case 'oracle': - if ($key_data[0] == 'UNIQUE') - { - continue; - } - - $sql .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; - - $sql .= " {$table_name}_{$key_name} ON {$table_name} (" . implode(', ', $key_data[1]) . ")\n"; - $sql .= "/\n"; - break; - - case 'sqlite': - $sql .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; - $sql .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; - - $sql .= " {$table_name}_{$key_name} ON {$table_name} (" . implode(', ', $key_data[1]) . ");\n"; - break; - - case 'postgres': - $sql .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; - $sql .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; - - $sql .= " {$table_name}_{$key_name} ON {$table_name} (" . implode(', ', $key_data[1]) . ");\n"; - break; - } - } - } - - switch ($dbms) - { - case 'mysql_40': - // Remove last line delimiter... - $sql = substr($sql, 0, -2); - $sql .= "\n);\n\n"; - break; - - case 'mysql_41': - // Remove last line delimiter... - $sql = substr($sql, 0, -2); - $sql .= "\n) CHARACTER SET utf8 COLLATE utf8_bin;\n\n"; - break; - - // Create Generator - case 'firebird': - if ($generator !== false) - { - $sql .= "\nCREATE GENERATOR {$table_name}_gen;;\n"; - $sql .= 'SET GENERATOR ' . $table_name . "_gen TO 0;;\n\n"; - - $sql .= 'CREATE TRIGGER t_' . $table_name . ' FOR ' . $table_name . "\n"; - $sql .= "BEFORE INSERT\nAS\nBEGIN\n"; - $sql .= "\tNEW.{$generator} = GEN_ID({$table_name}_gen, 1);\nEND;;\n\n"; - } - break; - - case 'oracle': - if ($generator !== false) - { - $sql .= "\nCREATE SEQUENCE {$table_name}_seq\n/\n\n"; - - $sql .= "CREATE OR REPLACE TRIGGER t_{$table_name}\n"; - $sql .= "BEFORE INSERT ON {$table_name}\n"; - $sql .= "FOR EACH ROW WHEN (\n"; - $sql .= "\tnew.{$generator} IS NULL OR new.{$generator} = 0\n"; - $sql .= ")\nBEGIN\n"; - $sql .= "\tSELECT {$table_name}_seq.nextval\n"; - $sql .= "\tINTO :new.{$generator}\n"; - $sql .= "\tFROM dual;\nEND;\n/\n\n"; - } - break; - } - - return $sql; - } - - /** - * Get the real table name - * By A_Jelly_Doughnut - * - * @param string $table_name The table name to get the real table name from - */ - function get_table_name(&$table_name) - { - // Use the global table prefix if a custom one is not specified - if ($this->table_prefix === false) - { - global $table_prefix; - } - else - { - $table_prefix = $this->table_prefix; - } - - static $constants = NULL; - - if (is_null($constants)) - { - $constants = get_defined_constants(); - } - - /** - * only do the replace if the table prefix is not already present - * this is required since UMIL supports specifying a table via phpbb_foo - * (where a replace would be needed) - * or by FOO_TABLE (where a replace is already done at constant-define time) - */ - if (!preg_match('#^' . preg_quote($table_prefix, '#') . '#', $table_name) || !in_array($table_name, $constants, true)) - { - $table_name = preg_replace('#^phpbb_#i', $table_prefix, $table_name); - } - } -} - -?> \ No newline at end of file diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 216faf9866..2fd795b659 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -22,7 +22,7 @@ if (!defined('IN_PHPBB')) */ class phpbb_db_migrator { - protected $container; + protected $config; protected $db; protected $db_tools; protected $table_prefix; @@ -33,31 +33,31 @@ class phpbb_db_migrator protected $migrations_table; protected $migration_state; - protected $migrations; + protected $migrations = array(); + + /** @var string Name of the last migration run */ + public $last_run_migration = false; /** * Constructor of the database migrator - * - * @param \Symfony\Component\DependencyInjection\ContainerInterface $container Container supplying dependencies */ - public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container, $migrations) + public function __construct($config, phpbb_db_driver $db, $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools) { - $this->container = $container; - $this->db = $this->container->get('dbal.conn'); - $this->db_tools = $this->container->get('dbal.tools'); - $this->table_prefix = $this->container->getParameters('core.table_prefix'); - $this->migrations_table = $this->container->getParameters('tables.migrations'); - $this->migrations = $migrations; + $this->config = $config; + $this->db = $db; + $this->db_tools = $db_tools; - $this->phpbb_root_path = $this->container->getParameters('core.root_path'); - $this->php_ext = $this->container->getParameters('core.php_ext'); + $this->migrations_table = $migrations_table; - /** @todo replace with collection_pass when merged */ - $this->tools = array( - 'config' => new phpbb_db_migration_tools_config, - 'module' => new phpbb_db_migration_tools_module, - 'permission' => new phpbb_db_migration_tools_permission, - ); + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + $this->table_prefix = $table_prefix; + + foreach ($tools as $tool) + { + $this->tools[$tool->get_name()] = $tool; + } $this->load_migration_state(); } @@ -93,13 +93,44 @@ class phpbb_db_migrator $this->migrations = $class_names; } + /** + * Load migration data files from a directory + * + * @param string $path + * @return array Array of migrations with names + */ + public function load_migrations($path) + { + $handle = opendir($path); + while (($file = readdir($handle)) !== false) + { + if (strpos($file, '_') !== 0 && strrpos($file, '.' . $this->php_ext) === (strlen($file) - strlen($this->php_ext) - 1)) + { + $name = 'phpbb_db_migration_data_' . substr($file, 0, -(strlen($this->php_ext) + 1)); + + if (!in_array($name, $this->migrations)) + { + $this->migrations[] = $name; + } + } + } + + foreach ($this->migrations as $name) + { + if ($this->unfulfillable($name)) + { + throw new phpbb_db_migration_exception('MIGRATION NOT FULFILLABLE', $name); + } + } + + return $this->migrations; + } + /** * Runs a single update step from the next migration to be applied. * * The update step can either be a schema or a (partial) data update. To * check if update() needs to be called again use the finished() method. - * - * @return null */ public function update() { @@ -134,7 +165,8 @@ class phpbb_db_migrator return false; } - $migration = new $name($this->db, $this->db_tools, $this->table_prefix, $this->phpbb_root_path, $this->php_ext); + $migration = $this->get_migration($name); + $state = (isset($this->migration_state[$name])) ? $this->migration_state[$name] : array( @@ -157,6 +189,11 @@ class phpbb_db_migrator } } + $this->last_run_migration = array( + 'name' => $name, + 'class' => $migration, + ); + if (!isset($this->migration_state[$name])) { $state['migration_start_time'] = time(); @@ -187,20 +224,20 @@ class phpbb_db_migrator protected function process_data_step($migration) { - $continue = false; + //$continue = false; $steps = $migration->update_data(); foreach ($steps as $step) { $continue = $this->run_step($step); - if (!$continue) + /*if ($continue === false) { return false; - } + }*/ } - return $continue; + //return $continue; } protected function run_step($step) @@ -211,13 +248,12 @@ class phpbb_db_migrator $callable = $callable_and_parameters[0]; $parameters = $callable_and_parameters[1]; - call_user_func_array($callable, $parameters); - - return false; + return call_user_func_array($callable, $parameters); } catch (phpbb_db_migration_exception $e) { - echo $e;die(); + echo $e; + die(); } } @@ -325,7 +361,7 @@ class phpbb_db_migrator return true; } - $migration = new $name($this->db, $this->db_tools, $this->table_prefix, $this->phpbb_root_path, $this->php_ext); + $migration = $this->get_migration($name); $depends = $migration->depends_on(); foreach ($depends as $depend) @@ -374,4 +410,15 @@ class phpbb_db_migrator { $this->db_tools->perform_schema_changes($schema_changes); } + + /** + * Helper to get a migration + * + * @param string $name Name of the migration + * @return phpbb_db_migration + */ + protected function get_migration($name) + { + return new $name($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix); + } } diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index d0ef2759d5..057bdba0e3 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2868,6 +2868,7 @@ function send_status_line($code, $message) else { $version = phpbb_request_http_version(); + header("$version $code $message", true, $code); } } @@ -5582,7 +5583,7 @@ function phpbb_convert_30_dbms_to_31($dbms) /* $reflection = new \ReflectionClass($dbms); - + if ($reflection->isSubclassOf('phpbb_db_driver')) { return $dbms; diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 207ad716de..8950d677ae 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -1521,8 +1521,6 @@ function change_database_data(&$no_updates, $version) ), ); - global $db_tools; - $statements = $db_tools->perform_schema_changes($changes); foreach ($statements as $sql) @@ -2164,26 +2162,41 @@ function change_database_data(&$no_updates, $version) } $db->sql_freeresult($result); - global $db_tools, $table_prefix; - - // Recover from potentially broken Q&A CAPTCHA table on firebird - // Q&A CAPTCHA was uninstallable, so it's safe to remove these - // without data loss + /* + * Due to a bug, vanilla phpbb could not create captcha tables + * in 3.0.8 on firebird. It was possible for board administrators + * to adjust the code to work. If code was manually adjusted by + * board administrators, index names would not be the same as + * what 3.0.9 and newer expect. This code fragment drops captcha + * tables, destroying all entered Q&A captcha configuration, such + * that when Q&A is configured next the respective tables will be + * created with correct index names. + * + * If you wish to preserve your Q&A captcha configuration, you can + * manually rename indexes to the currently expected name: + * phpbb_captcha_questions_lang_iso => phpbb_captcha_questions_lang + * phpbb_captcha_answers_question_id => phpbb_captcha_answers_qid + * + * Again, this needs to be done only if a board was manually modified + * to fix broken captcha code. + * if ($db_tools->sql_layer == 'firebird') { - $tables = array( - $table_prefix . 'captcha_questions', - $table_prefix . 'captcha_answers', - $table_prefix . 'qa_confirm', + $changes = array( + 'drop_tables' => array( + $table_prefix . 'captcha_questions', + $table_prefix . 'captcha_answers', + $table_prefix . 'qa_confirm', + ), ); - foreach ($tables as $table) + $statements = $db_tools->perform_schema_changes($changes); + + foreach ($statements as $sql) { - if ($db_tools->sql_table_exists($table)) - { - $db_tools->sql_table_drop($table); - } + _sql($sql, $errored, $error_ary); } } + */ $no_updates = false; break; @@ -2360,6 +2373,26 @@ function change_database_data(&$no_updates, $version) } } + // Disable receiving pms for bots + $sql = 'SELECT user_id + FROM ' . BOTS_TABLE; + $result = $db->sql_query($sql); + + $bot_user_ids = array(); + while ($row = $db->sql_fetchrow($result)) + { + $bot_user_ids[] = (int) $row['user_id']; + } + $db->sql_freeresult($result); + + if (!empty($bot_user_ids)) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_allow_pm = 0 + WHERE ' . $db->sql_in_set('user_id', $bot_user_ids); + _sql($sql, $errored, $error_ary); + } + $no_updates = false; break; diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 43099fc33b..535cbb0df4 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -573,18 +573,6 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts(attempt_forwar CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts(attempt_time);; CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts(user_id);; -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - migration_schema_done INTEGER DEFAULT 0 NOT NULL, - migration_data_done INTEGER DEFAULT 0 NOT NULL, - migration_data_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, - migration_start_time INTEGER DEFAULT 0 NOT NULL, - migration_end_time INTEGER DEFAULT 0 NOT NULL -);; - -CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations(migration_name);; - # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id INTEGER DEFAULT 0 NOT NULL, @@ -598,6 +586,19 @@ CREATE TABLE phpbb_moderator_cache ( CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache(display_on_index);; CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache(forum_id);; +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + migration_schema_done INTEGER DEFAULT 0 NOT NULL, + migration_data_done INTEGER DEFAULT 0 NOT NULL, + migration_data_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, + migration_start_time INTEGER DEFAULT 0 NOT NULL, + migration_end_time INTEGER DEFAULT 0 NOT NULL +);; + +ALTER TABLE phpbb_migrations ADD PRIMARY KEY (migration_name);; + + # Table: 'phpbb_modules' CREATE TABLE phpbb_modules ( module_id INTEGER NOT NULL, @@ -924,8 +925,8 @@ CREATE TABLE phpbb_reports ( report_time INTEGER DEFAULT 0 NOT NULL, report_text BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, reported_post_text BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - reported_post_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - reported_post_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL + reported_post_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, + reported_post_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL );; ALTER TABLE phpbb_reports ADD PRIMARY KEY (report_id);; diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 1174cdfa3d..43b8f3e556 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -696,23 +696,6 @@ CREATE INDEX [user_id] ON [phpbb_login_attempts]([user_id]) ON [PRIMARY] GO -/* - Table: 'phpbb_migrations' -*/ -CREATE TABLE [phpbb_migrations] ( - [migration_name] [varchar] (255) DEFAULT ('') NOT NULL , - [migration_schema_done] [int] DEFAULT (0) NOT NULL , - [migration_data_done] [int] DEFAULT (0) NOT NULL , - [migration_data_state] [varchar] (8000) DEFAULT ('') NOT NULL , - [migration_start_time] [int] DEFAULT (0) NOT NULL , - [migration_end_time] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -CREATE UNIQUE INDEX [migration_name] ON [phpbb_migrations]([migration_name]) ON [PRIMARY] -GO - - /* Table: 'phpbb_moderator_cache' */ @@ -733,6 +716,27 @@ CREATE INDEX [forum_id] ON [phpbb_moderator_cache]([forum_id]) ON [PRIMARY] GO +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE [phpbb_migrations] ( + [migration_name] [varchar] (255) DEFAULT ('') NOT NULL , + [migration_schema_done] [int] DEFAULT (0) NOT NULL , + [migration_data_done] [int] DEFAULT (0) NOT NULL , + [migration_data_state] [varchar] (8000) DEFAULT ('') NOT NULL , + [migration_start_time] [int] DEFAULT (0) NOT NULL , + [migration_end_time] [int] DEFAULT (0) NOT NULL +) ON [PRIMARY] +GO + +ALTER TABLE [phpbb_migrations] WITH NOCHECK ADD + CONSTRAINT [PK_phpbb_migrations] PRIMARY KEY CLUSTERED + ( + [migration_name] + ) ON [PRIMARY] +GO + + /* Table: 'phpbb_modules' */ @@ -1128,8 +1132,8 @@ CREATE TABLE [phpbb_reports] ( [report_time] [int] DEFAULT (0) NOT NULL , [report_text] [text] DEFAULT ('') NOT NULL , [reported_post_text] [text] DEFAULT ('') NOT NULL , - [reported_post_bitfield] [varchar] (255) DEFAULT ('') NOT NULL , - [reported_post_uid] [varchar] (8) DEFAULT ('') NOT NULL + [reported_post_uid] [varchar] (8) DEFAULT ('') NOT NULL , + [reported_post_bitfield] [varchar] (255) DEFAULT ('') NOT NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index d645c3384d..c46230744a 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -397,18 +397,6 @@ CREATE TABLE phpbb_login_attempts ( ); -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name varbinary(255) DEFAULT '' NOT NULL, - migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_state blob NOT NULL, - migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - UNIQUE migration_name (migration_name) -); - - # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, @@ -422,6 +410,18 @@ CREATE TABLE phpbb_moderator_cache ( ); +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varbinary(255) DEFAULT '' NOT NULL, + migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_state blob NOT NULL, + migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + PRIMARY KEY (migration_name) +); + + # Table: 'phpbb_modules' CREATE TABLE phpbb_modules ( module_id mediumint(8) UNSIGNED NOT NULL auto_increment, @@ -661,8 +661,8 @@ CREATE TABLE phpbb_reports ( report_time int(11) UNSIGNED DEFAULT '0' NOT NULL, report_text mediumblob NOT NULL, reported_post_text mediumblob NOT NULL, - reported_post_bitfield varbinary(255) DEFAULT '' NOT NULL, reported_post_uid varbinary(8) DEFAULT '' NOT NULL, + reported_post_bitfield varbinary(255) DEFAULT '' NOT NULL, PRIMARY KEY (report_id), KEY post_id (post_id), KEY pm_id (pm_id) diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index d10f2dc55a..fa94598e9c 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -397,18 +397,6 @@ CREATE TABLE phpbb_login_attempts ( ) CHARACTER SET `utf8` COLLATE `utf8_bin`; -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name varchar(255) DEFAULT '' NOT NULL, - migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_state text NOT NULL, - migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - UNIQUE migration_name (migration_name) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, @@ -422,6 +410,18 @@ CREATE TABLE phpbb_moderator_cache ( ) CHARACTER SET `utf8` COLLATE `utf8_bin`; +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) DEFAULT '' NOT NULL, + migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_state text NOT NULL, + migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + PRIMARY KEY (migration_name) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + + # Table: 'phpbb_modules' CREATE TABLE phpbb_modules ( module_id mediumint(8) UNSIGNED NOT NULL auto_increment, @@ -661,8 +661,8 @@ CREATE TABLE phpbb_reports ( report_time int(11) UNSIGNED DEFAULT '0' NOT NULL, report_text mediumtext NOT NULL, reported_post_text mediumtext NOT NULL, - reported_post_bitfield varchar(255) DEFAULT '' NOT NULL, reported_post_uid varchar(8) DEFAULT '' NOT NULL, + reported_post_bitfield varchar(255) DEFAULT '' NOT NULL, PRIMARY KEY (report_id), KEY post_id (post_id), KEY pm_id (pm_id) diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 9993caeb7a..f8a9d5e1a6 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -780,21 +780,6 @@ CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id) / -/* - Table: 'phpbb_migrations' -*/ -CREATE TABLE phpbb_migrations ( - migration_name varchar2(255) DEFAULT '' , - migration_schema_done number(1) DEFAULT '0' NOT NULL, - migration_data_done number(1) DEFAULT '0' NOT NULL, - migration_data_state clob DEFAULT '' , - migration_start_time number(11) DEFAULT '0' NOT NULL, - migration_end_time number(11) DEFAULT '0' NOT NULL, - CONSTRAINT u_phpbb_migration_name UNIQUE (migration_name) -) -/ - - /* Table: 'phpbb_moderator_cache' */ @@ -813,6 +798,21 @@ CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache (display_on CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id) / +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE phpbb_migrations ( + migration_name varchar2(255) DEFAULT '' , + migration_schema_done number(1) DEFAULT '0' NOT NULL, + migration_data_done number(1) DEFAULT '0' NOT NULL, + migration_data_state clob DEFAULT '' , + migration_start_time number(11) DEFAULT '0' NOT NULL, + migration_end_time number(11) DEFAULT '0' NOT NULL, + CONSTRAINT pk_phpbb_migrations PRIMARY KEY (migration_name) +) +/ + + /* Table: 'phpbb_modules' */ @@ -1231,8 +1231,8 @@ CREATE TABLE phpbb_reports ( report_time number(11) DEFAULT '0' NOT NULL, report_text clob DEFAULT '' , reported_post_text clob DEFAULT '' , - reported_post_bitfield varchar2(255) DEFAULT '' , reported_post_uid varchar2(8) DEFAULT '' , + reported_post_bitfield varchar2(255) DEFAULT '' , CONSTRAINT pk_phpbb_reports PRIMARY KEY (report_id) ) / diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index ef138dac0f..c976659f05 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -557,20 +557,6 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwa CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); -/* - Table: 'phpbb_migrations' -*/ -CREATE TABLE phpbb_migrations ( - migration_name varchar(255) DEFAULT '' NOT NULL, - migration_schema_done INT2 DEFAULT '0' NOT NULL CHECK (migration_schema_done >= 0), - migration_data_done INT2 DEFAULT '0' NOT NULL CHECK (migration_data_done >= 0), - migration_data_state varchar(8000) DEFAULT '' NOT NULL, - migration_start_time INT4 DEFAULT '0' NOT NULL CHECK (migration_start_time >= 0), - migration_end_time INT4 DEFAULT '0' NOT NULL CHECK (migration_end_time >= 0) -); - -CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations (migration_name); - /* Table: 'phpbb_moderator_cache' */ @@ -586,6 +572,20 @@ CREATE TABLE phpbb_moderator_cache ( CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache (display_on_index); CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id); +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) DEFAULT '' NOT NULL, + migration_schema_done INT2 DEFAULT '0' NOT NULL CHECK (migration_schema_done >= 0), + migration_data_done INT2 DEFAULT '0' NOT NULL CHECK (migration_data_done >= 0), + migration_data_state varchar(8000) DEFAULT '' NOT NULL, + migration_start_time INT4 DEFAULT '0' NOT NULL CHECK (migration_start_time >= 0), + migration_end_time INT4 DEFAULT '0' NOT NULL CHECK (migration_end_time >= 0), + PRIMARY KEY (migration_name) +); + + /* Table: 'phpbb_modules' */ @@ -869,8 +869,8 @@ CREATE TABLE phpbb_reports ( report_time INT4 DEFAULT '0' NOT NULL CHECK (report_time >= 0), report_text TEXT DEFAULT '' NOT NULL, reported_post_text TEXT DEFAULT '' NOT NULL, - reported_post_bitfield varchar(255) DEFAULT '' NOT NULL, reported_post_uid varchar(8) DEFAULT '' NOT NULL, + reported_post_bitfield varchar(255) DEFAULT '' NOT NULL, PRIMARY KEY (report_id) ); diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 309297779e..31a6f715a0 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -385,18 +385,6 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwa CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name varchar(255) NOT NULL DEFAULT '', - migration_schema_done INTEGER UNSIGNED NOT NULL DEFAULT '0', - migration_data_done INTEGER UNSIGNED NOT NULL DEFAULT '0', - migration_data_state text(65535) NOT NULL DEFAULT '', - migration_start_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - migration_end_time INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations (migration_name); - # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', @@ -410,6 +398,18 @@ CREATE TABLE phpbb_moderator_cache ( CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache (display_on_index); CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id); +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) NOT NULL DEFAULT '', + migration_schema_done INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_data_done INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_data_state text(65535) NOT NULL DEFAULT '', + migration_start_time INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_end_time INTEGER UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (migration_name) +); + + # Table: 'phpbb_modules' CREATE TABLE phpbb_modules ( module_id INTEGER PRIMARY KEY NOT NULL , @@ -642,8 +642,8 @@ CREATE TABLE phpbb_reports ( report_time INTEGER UNSIGNED NOT NULL DEFAULT '0', report_text mediumtext(16777215) NOT NULL DEFAULT '', reported_post_text mediumtext(16777215) NOT NULL DEFAULT '', - reported_post_bitfield varchar(255) NOT NULL DEFAULT '', - reported_post_uid varchar(8) NOT NULL DEFAULT '' + reported_post_uid varchar(8) NOT NULL DEFAULT '', + reported_post_bitfield varchar(255) NOT NULL DEFAULT '' ); CREATE INDEX phpbb_reports_post_id ON phpbb_reports (post_id); diff --git a/phpBB/test.php b/phpBB/test.php new file mode 100644 index 0000000000..5887c08d2f --- /dev/null +++ b/phpBB/test.php @@ -0,0 +1,121 @@ +register(); + +/*$phpbb_container = phpbb_create_container( + array( + new phpbb_di_extension_config($phpbb_root_path . 'config.' . $phpEx), + new phpbb_di_extension_core($phpbb_root_path), + ), + array( + new phpbb_di_pass_collection_pass(), + new phpbb_di_pass_kernel_pass(), + ), + $phpbb_root_path, $phpEx); +$phpbb_container->compile();*/ + +// Set up container +$container_extensions = array( + new phpbb_di_extension_config($phpbb_root_path . 'config.' . $phpEx), + new phpbb_di_extension_core($phpbb_root_path), +); +$container_passes = array( + new phpbb_di_pass_collection_pass(), + //new phpbb_di_pass_kernel_pass(), +); +$phpbb_container = phpbb_create_container($container_extensions, $phpbb_root_path, $phpEx); + +// Compile the container +foreach ($container_passes as $pass) +{ + $phpbb_container->addCompilerPass($pass); +} +$phpbb_container->compile(); + +// set up caching +$cache = $phpbb_container->get('cache'); + +// Instantiate some basic classes +$phpbb_dispatcher = $phpbb_container->get('dispatcher'); +$request = $phpbb_container->get('request'); +$user = $phpbb_container->get('user'); +$auth = $phpbb_container->get('auth'); +$db = $phpbb_container->get('dbal.conn'); + +// make sure request_var uses this request instance +request_var('', 0, false, false, $request); // "dependency injection" for a function + +// Grab global variables, re-cache if necessary +$config = $phpbb_container->get('config'); +set_config(null, null, null, $config); +set_config_count(null, null, null, $config); + +// End startup code + +$db_tools = $phpbb_container->get('dbal.tools'); +if (!$db_tools->sql_table_exists(MIGRATIONS_TABLE)) +{ + $db_tools->sql_create_table(MIGRATIONS_TABLE, array( + 'COLUMNS' => array( + 'migration_name' => array('VCHAR', ''), + 'migration_schema_done' => array('BOOL', 0), + 'migration_data_done' => array('BOOL', 0), + 'migration_data_state' => array('TEXT', ''), + 'migration_start_time' => array('TIMESTAMP', 0), + 'migration_end_time' => array('TIMESTAMP', 0), + ), + 'PRIMARY_KEY' => 'migration_name', + )); +} + +$migrator = $phpbb_container->get('migrator'); +$migrator->load_migrations($phpbb_root_path . 'includes/db/migration/data/'); + +while (!$migrator->finished()) +{ + $migrator->update(); + + echo $migrator->last_run_migration['name'] . '
'; +} + +echo 'Finished'; diff --git a/tests/dbal/fixtures/migrator_module.xml b/tests/dbal/fixtures/migrator_module.xml new file mode 100644 index 0000000000..32afe7e6f3 --- /dev/null +++ b/tests/dbal/fixtures/migrator_module.xml @@ -0,0 +1,42 @@ + + + + module_id + module_enabled + module_display + module_basename + module_class + parent_id + left_id + right_id + module_langname + module_mode + module_auth + + 1 + 1 + 1 + + acp + 0 + 1 + 4 + ACP_CAT + + + + + 2 + 1 + 1 + acp_test + acp + 1 + 2 + 3 + ACP_MODULE + test + + +
+
diff --git a/tests/dbal/fixtures/migrator_permission.xml b/tests/dbal/fixtures/migrator_permission.xml new file mode 100644 index 0000000000..08cec42a42 --- /dev/null +++ b/tests/dbal/fixtures/migrator_permission.xml @@ -0,0 +1,31 @@ + + + + auth_option_id + auth_option + is_global + is_local + founder_only + + 1 + global + 1 + 0 + 0 + + + 2 + local + 0 + 1 + 0 + + + 3 + both + 1 + 1 + 0 + +
+
diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index 898a197dfd..463cf9fcec 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -9,7 +9,7 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/db/migrator.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/db/migration.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/db/migration/migration.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/db/db_tools.php'; require_once dirname(__FILE__) . '/migration/dummy.php'; @@ -28,11 +28,17 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case public function setUp() { - parent::setup(); + parent::setUp(); $this->db = $this->new_dbal(); $this->db_tools = new phpbb_db_tools($this->db); - $this->migrator = new phpbb_db_migrator($this->db, $this->db_tools, 'phpbb_', MIGRATIONS_TABLE, 'phpBB/', '.php'); + + $this->config = new phpbb_config_db($this->db, new phpbb_mock_cache, 'phpbb_config'); + + $tools = array( + new phpbb_db_migration_tool_config($this->config), + ); + $this->migrator = new phpbb_db_migrator($this->config, $this->db, $this->db_tools, 'phpbb_migrations', dirname(__FILE__) . '/../../phpBB/', 'php', 'phpbb_', $tools); } public function tearDown() diff --git a/tests/dbal/migrator_tool_config_test.php b/tests/dbal/migrator_tool_config_test.php new file mode 100644 index 0000000000..27511519ca --- /dev/null +++ b/tests/dbal/migrator_tool_config_test.php @@ -0,0 +1,97 @@ +config = new phpbb_config(array()); + + $this->tool = new phpbb_db_migration_tool_config($this->config); + + parent::setup(); + } + + public function test_add() + { + try + { + $this->tool->add('foo', 'bar'); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals('bar', $this->config['foo']); + + try + { + $this->tool->add('foo', 'bar'); + $this->fail('Exception not thrown'); + } + catch (Exception $e) {} + } + + public function test_update() + { + $this->config->set('foo', 'bar'); + try + { + $this->tool->update('foo', 'bar2'); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals('bar2', $this->config['foo']); + } + + public function test_update_if_equals() + { + $this->config->set('foo', 'bar'); + + try + { + $this->tool->update_if_equals('', 'foo', 'bar2'); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals('bar', $this->config['foo']); + + try + { + $this->tool->update_if_equals('bar', 'foo', 'bar2'); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals('bar2', $this->config['foo']); + } + + public function test_remove() + { + $this->config->set('foo', 'bar'); + + try + { + $this->tool->remove('foo'); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertFalse(isset($this->config['foo'])); + } +} diff --git a/tests/dbal/migrator_tool_module.php b/tests/dbal/migrator_tool_module.php new file mode 100644 index 0000000000..0b57cbfbcb --- /dev/null +++ b/tests/dbal/migrator_tool_module.php @@ -0,0 +1,128 @@ +createXMLDataSet(dirname(__FILE__).'/fixtures/migrator_module.xml'); + } + + public function setup() + { + // Need global $db, $user for delete_module function in acp_modules + global $phpbb_root_path, $phpEx, $skip_add_log, $db, $user; + + parent::setup(); + + // Force add_log function to not be used + $skip_add_log = true; + + $db = $this->db = $this->new_dbal(); + $this->cache = new phpbb_cache_service(new phpbb_cache_driver_null()); + $user = $this->user = new phpbb_user(); + + $this->tool = new phpbb_db_migration_tool_module($this->db, $this->cache, $this->user, $phpbb_root_path, $phpEx); + } + + public function exists_data() + { + return array( + // Test the category + array( + '', + 'ACP_CAT', + true, + ), + array( + 0, + 'ACP_CAT', + true, + ), + + // Test the module + array( + '', + 'ACP_MODULE', + false, + ), + array( + false, + 'ACP_MODULE', + true, + ), + array( + 'ACP_CAT', + 'ACP_MODULE', + true, + ), + ); + } + + /** + * @dataProvider exists_data + */ + public function test_exists($parent, $module, $expected) + { + $this->assertEquals($expected, $this->tool->exists('acp', $parent, $module)); + } + + public function test_add() + { + try + { + $this->tool->add('acp', 0, 'ACP_NEW_CAT'); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(true, $this->tool->exists('acp', 0, 'ACP_NEW_CAT')); + + // Should throw an exception when trying to add a module that already exists + try + { + $this->tool->add('acp', 0, 'ACP_NEW_CAT'); + $this->fail('Exception not thrown'); + } + catch (Exception $e) {} + + try + { + $this->tool->add('acp', ACP_NEW_CAT, array( + 'module_basename' => 'acp_new_module', + 'module_langname' => 'ACP_NEW_MODULE', + 'module_mode' => 'test', + 'module_auth' => '', + )); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(true, $this->tool->exists('acp', 'ACP_NEW_CAT', 'ACP_NEW_MODULE')); + } + + public function test_remove() + { + try + { + $this->tool->remove('acp', 'ACP_CAT', 'ACP_MODULE'); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(false, $this->tool->exists('acp', 'ACP_CAT', 'ACP_MODULE')); + } +} diff --git a/tests/dbal/migrator_tool_permission.php b/tests/dbal/migrator_tool_permission.php new file mode 100644 index 0000000000..2229576cd9 --- /dev/null +++ b/tests/dbal/migrator_tool_permission.php @@ -0,0 +1,136 @@ +createXMLDataSet(dirname(__FILE__).'/fixtures/migrator_permission.xml'); + } + + public function setup() + { + // Global $db and $cache are needed in acp/auth.php constructor + global $phpbb_root_path, $phpEx, $db, $cache; + + parent::setup(); + + $db = $this->db = $this->new_dbal(); + $cache = $this->cache = new phpbb_cache_service(new phpbb_cache_driver_null()); + $this->auth = new phpbb_auth(); + + $this->tool = new phpbb_db_migration_tool_permission($this->db, $this->cache, $this->auth, $phpbb_root_path, $phpEx); + } + + public function exists_data() + { + return array( + array( + 'global', + true, + true, + ), + array( + 'local', + false, + true, + ), + array( + 'both', + true, + true, + ), + array( + 'both', + false, + true, + ), + array( + 'does_not_exist', + true, + false, + ), + ); + } + + /** + * @dataProvider exists_data + */ + public function test_exists($auth_option, $global, $expected) + { + $this->assertEquals($expected, $this->tool->exists($auth_option, $global)); + } + + public function test_add() + { + try + { + $this->tool->add('new', true); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(true, $this->tool->exists('new', true)); + $this->assertEquals(false, $this->tool->exists('new', false)); + + try + { + $this->tool->add('new', false); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(true, $this->tool->exists('new', false)); + + // Should fail (duplicate) + try + { + $this->tool->add('new', true); + $this->fail('Did not throw exception on duplicate'); + } + catch (Exception $e) {} + } + + public function test_remove() + { + try + { + $this->tool->remove('global', true); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(false, $this->tool->exists('global', true)); + + try + { + $this->tool->remove('both', false); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(false, $this->tool->exists('both', false)); + + // Should fail (does not exist) + try + { + $this->tool->remove('new', true); + $this->fail('Did not throw exception on duplicate'); + } + catch (Exception $e) {} + } +} From aceadfd77b620677a838c61085c88db4d28e4a8a Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 8 Jan 2013 22:19:56 -0600 Subject: [PATCH 27/90] [feature/migrations] Remove migration data (separate PR) PHPBB3-9737 --- phpBB/includes/db/migration/data/3_0_1.php | 28 -- phpBB/includes/db/migration/data/3_0_10.php | 28 -- .../includes/db/migration/data/3_0_10_rc1.php | 30 -- .../includes/db/migration/data/3_0_10_rc2.php | 28 -- .../includes/db/migration/data/3_0_10_rc3.php | 28 -- phpBB/includes/db/migration/data/3_0_11.php | 28 -- .../includes/db/migration/data/3_0_11_rc1.php | 98 ----- .../includes/db/migration/data/3_0_11_rc2.php | 34 -- .../includes/db/migration/data/3_0_12_rc1.php | 123 ------ .../includes/db/migration/data/3_0_1_rc1.php | 79 ---- phpBB/includes/db/migration/data/3_0_2.php | 28 -- .../includes/db/migration/data/3_0_2_rc1.php | 32 -- .../includes/db/migration/data/3_0_2_rc2.php | 55 --- phpBB/includes/db/migration/data/3_0_3.php | 28 -- .../includes/db/migration/data/3_0_3_rc1.php | 63 --- phpBB/includes/db/migration/data/3_0_4.php | 49 --- .../includes/db/migration/data/3_0_4_rc1.php | 107 ----- phpBB/includes/db/migration/data/3_0_5.php | 28 -- .../includes/db/migration/data/3_0_5_rc1.php | 119 ------ .../db/migration/data/3_0_5_rc1part2.php | 37 -- phpBB/includes/db/migration/data/3_0_6.php | 28 -- .../includes/db/migration/data/3_0_6_rc1.php | 279 ------------- .../includes/db/migration/data/3_0_6_rc2.php | 28 -- .../includes/db/migration/data/3_0_6_rc3.php | 40 -- .../includes/db/migration/data/3_0_6_rc4.php | 28 -- phpBB/includes/db/migration/data/3_0_7.php | 28 -- .../includes/db/migration/data/3_0_7_pl1.php | 28 -- .../includes/db/migration/data/3_0_7_rc1.php | 53 --- .../includes/db/migration/data/3_0_7_rc2.php | 72 ---- phpBB/includes/db/migration/data/3_0_8.php | 28 -- .../includes/db/migration/data/3_0_8_rc1.php | 225 ----------- phpBB/includes/db/migration/data/3_0_9.php | 28 -- .../includes/db/migration/data/3_0_9_rc1.php | 110 ------ .../includes/db/migration/data/3_0_9_rc2.php | 28 -- .../includes/db/migration/data/3_0_9_rc3.php | 28 -- .../includes/db/migration/data/3_0_9_rc4.php | 28 -- .../includes/db/migration/data/3_1_0_dev.php | 369 ------------------ .../includes/db/migration/data/extensions.php | 49 --- .../db/migration/data/style_update_p1.php | 157 -------- .../db/migration/data/style_update_p2.php | 42 -- phpBB/includes/db/migration/data/timezone.php | 161 -------- 41 files changed, 2887 deletions(-) delete mode 100644 phpBB/includes/db/migration/data/3_0_1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_10.php delete mode 100644 phpBB/includes/db/migration/data/3_0_10_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_10_rc2.php delete mode 100644 phpBB/includes/db/migration/data/3_0_10_rc3.php delete mode 100644 phpBB/includes/db/migration/data/3_0_11.php delete mode 100644 phpBB/includes/db/migration/data/3_0_11_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_11_rc2.php delete mode 100644 phpBB/includes/db/migration/data/3_0_12_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_1_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_2.php delete mode 100644 phpBB/includes/db/migration/data/3_0_2_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_2_rc2.php delete mode 100644 phpBB/includes/db/migration/data/3_0_3.php delete mode 100644 phpBB/includes/db/migration/data/3_0_3_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_4.php delete mode 100644 phpBB/includes/db/migration/data/3_0_4_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_5.php delete mode 100644 phpBB/includes/db/migration/data/3_0_5_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_5_rc1part2.php delete mode 100644 phpBB/includes/db/migration/data/3_0_6.php delete mode 100644 phpBB/includes/db/migration/data/3_0_6_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_6_rc2.php delete mode 100644 phpBB/includes/db/migration/data/3_0_6_rc3.php delete mode 100644 phpBB/includes/db/migration/data/3_0_6_rc4.php delete mode 100644 phpBB/includes/db/migration/data/3_0_7.php delete mode 100644 phpBB/includes/db/migration/data/3_0_7_pl1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_7_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_7_rc2.php delete mode 100644 phpBB/includes/db/migration/data/3_0_8.php delete mode 100644 phpBB/includes/db/migration/data/3_0_8_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_9.php delete mode 100644 phpBB/includes/db/migration/data/3_0_9_rc1.php delete mode 100644 phpBB/includes/db/migration/data/3_0_9_rc2.php delete mode 100644 phpBB/includes/db/migration/data/3_0_9_rc3.php delete mode 100644 phpBB/includes/db/migration/data/3_0_9_rc4.php delete mode 100644 phpBB/includes/db/migration/data/3_1_0_dev.php delete mode 100644 phpBB/includes/db/migration/data/extensions.php delete mode 100644 phpBB/includes/db/migration/data/style_update_p1.php delete mode 100644 phpBB/includes/db/migration/data/style_update_p2.php delete mode 100644 phpBB/includes/db/migration/data/timezone.php diff --git a/phpBB/includes/db/migration/data/3_0_1.php b/phpBB/includes/db/migration/data/3_0_1.php deleted file mode 100644 index a2332c9b59..0000000000 --- a/phpBB/includes/db/migration/data/3_0_1.php +++ /dev/null @@ -1,28 +0,0 @@ -sql_query($sql); - - $deactivated_style_ids = array(); - while ($style_id = $this->db->sql_fetchfield('style_id', false, $result)) - { - $deactivated_style_ids[] = (int) $style_id; - } - $this->db->sql_freeresult($result); - - if (!empty($deactivated_style_ids)) - { - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_style = ' . (int) $this->config['default_style'] .' - WHERE ' . $this->db->sql_in_set('user_style', $deactivated_style_ids); - $this->sql_query($sql); - } - } - - function delete_orphan_private_messages() - { - // Delete orphan private messages - $batch_size = 500; - - $sql_array = array( - 'SELECT' => 'p.msg_id', - 'FROM' => array( - PRIVMSGS_TABLE => 'p', - ), - 'LEFT_JOIN' => array( - array( - 'FROM' => array(PRIVMSGS_TO_TABLE => 't'), - 'ON' => 'p.msg_id = t.msg_id', - ), - ), - 'WHERE' => 't.user_id IS NULL', - ); - $sql = $this->db->sql_build_query('SELECT', $sql_array); - - $result = $this->db->sql_query_limit($sql, $batch_size); - - $delete_pms = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $delete_pms[] = (int) $row['msg_id']; - } - $this->db->sql_freeresult($result); - - if (!empty($delete_pms)) - { - $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' - WHERE ' . $this->db->sql_in_set('msg_id', $delete_pms); - $this->sql_query($sql); - - return true; - } - else - { - return false; - } - } -} diff --git a/phpBB/includes/db/migration/data/3_0_11_rc2.php b/phpBB/includes/db/migration/data/3_0_11_rc2.php deleted file mode 100644 index f2bed54085..0000000000 --- a/phpBB/includes/db/migration/data/3_0_11_rc2.php +++ /dev/null @@ -1,34 +0,0 @@ - array( - $this->table_prefix . 'profile_fields' => array( - 'field_show_novalue' => array('BOOL', 0), - ), - ), - ); - } - - function update_data() - { - return array( - array('config.update', array('version', '3.0.11-rc2')), - ); - } -} diff --git a/phpBB/includes/db/migration/data/3_0_12_rc1.php b/phpBB/includes/db/migration/data/3_0_12_rc1.php deleted file mode 100644 index 0d8702f19e..0000000000 --- a/phpBB/includes/db/migration/data/3_0_12_rc1.php +++ /dev/null @@ -1,123 +0,0 @@ -db->sql_query($sql); - - $bot_user_ids = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $bot_user_ids[] = (int) $row['user_id']; - } - $this->db->sql_freeresult($result); - - if (!empty($bot_user_ids)) - { - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_allow_pm = 0 - WHERE ' . $this->db->sql_in_set('user_id', $bot_user_ids); - $this->sql_query($sql); - } - } - - public function update_module_auth() - { - $sql = 'UPDATE ' . MODULES_TABLE . ' - SET module_auth = \'acl_u_sig\' - WHERE module_class = \'ucp\' - AND module_basename = \'profile\' - AND module_mode = \'signature\''; - $this->sql_query($sql); - } - - public function update_bots() - { - // Update bots - if (!function_exists('user_delete')) - { - include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); - } - - $bots_updates = array( - // Bot Deletions - 'NG-Search [Bot]' => false, - 'Nutch/CVS [Bot]' => false, - 'OmniExplorer [Bot]' => false, - 'Seekport [Bot]' => false, - 'Synoo [Bot]' => false, - 'WiseNut [Bot]' => false, - - // Bot Updates - // Bot name to bot user agent map - 'Baidu [Spider]' => 'Baiduspider', - 'Exabot [Bot]' => 'Exabot', - 'Voyager [Bot]' => 'voyager/', - 'W3C [Validator]' => 'W3C_Validator', - ); - - foreach ($bots_updates as $bot_name => $bot_agent) - { - $sql = 'SELECT user_id - FROM ' . USERS_TABLE . ' - WHERE user_type = ' . USER_IGNORE . " - AND username_clean = '" . $this->db->sql_escape(utf8_clean_string($bot_name)) . "'"; - $result = $this->db->sql_query($sql); - $bot_user_id = (int) $this->db->sql_fetchfield('user_id'); - $this->db->sql_freeresult($result); - - if ($bot_user_id) - { - if ($bot_agent === false) - { - $sql = 'DELETE FROM ' . BOTS_TABLE . " - WHERE user_id = $bot_user_id"; - $this->sql_query($sql); - - user_delete('remove', $bot_user_id); - } - else - { - $sql = 'UPDATE ' . BOTS_TABLE . " - SET bot_agent = '" . $this->db->sql_escape($bot_agent) . "' - WHERE user_id = $bot_user_id"; - $this->sql_query($sql); - } - } - } - } -} diff --git a/phpBB/includes/db/migration/data/3_0_1_rc1.php b/phpBB/includes/db/migration/data/3_0_1_rc1.php deleted file mode 100644 index a3b4810d21..0000000000 --- a/phpBB/includes/db/migration/data/3_0_1_rc1.php +++ /dev/null @@ -1,79 +0,0 @@ - array( - $this->table_prefix . 'forums' => array( - 'display_subforum_list' => array('BOOL', 1), - ), - $this->table_prefix . 'sessions' => array( - 'session_forum_id' => array('UINT', 0), - ), - ), - 'drop_keys' => array( - $this->table_prefix . 'groups' => array('group_legend'), - ), - 'add_index' => array( - $this->table_prefix . 'sessions' => array( - 'session_forum_id' => array('session_forum_id'), - ), - $this->table_prefix . 'groups' => array( - 'group_legend_name' => array('group_legend', 'group_name'), - ), - ), - ); - } - - function update_data() - { - return array( - array('custom', array(array(&$this, 'fix_unset_last_view_time'))), - array('custom', array(array(&$this, 'reset_smiley_size'))), - - array('config.update', array('version', '3.0.1-rc1')), - ); - } - - function fix_unset_last_view_time() - { - $sql = 'UPDATE ' . $this->table_prefix . "topics - SET topic_last_view_time = topic_last_post_time - WHERE topic_last_view_time = 0"; - $this->sql_query($sql); - } - - function reset_smiley_size() - { - // Update smiley sizes - $smileys = array('icon_e_surprised.gif', 'icon_eek.gif', 'icon_cool.gif', 'icon_lol.gif', 'icon_mad.gif', 'icon_razz.gif', 'icon_redface.gif', 'icon_cry.gif', 'icon_evil.gif', 'icon_twisted.gif', 'icon_rolleyes.gif', 'icon_exclaim.gif', 'icon_question.gif', 'icon_idea.gif', 'icon_arrow.gif', 'icon_neutral.gif', 'icon_mrgreen.gif', 'icon_e_ugeek.gif'); - - foreach ($smileys as $smiley) - { - if (file_exists($this->phpbb_root_path . 'images/smilies/' . $smiley)) - { - list($width, $height) = getimagesize($this->phpbb_root_path . 'images/smilies/' . $smiley); - - $sql = 'UPDATE ' . SMILIES_TABLE . ' - SET smiley_width = ' . $width . ', smiley_height = ' . $height . " - WHERE smiley_url = '" . $this->db->sql_escape($smiley) . "'"; - - $this->sql_query($sql); - } - } - } -} diff --git a/phpBB/includes/db/migration/data/3_0_2.php b/phpBB/includes/db/migration/data/3_0_2.php deleted file mode 100644 index 3469d8d178..0000000000 --- a/phpBB/includes/db/migration/data/3_0_2.php +++ /dev/null @@ -1,28 +0,0 @@ - array( - $this->table_prefix . 'drafts' => array( - 'draft_subject' => array('STEXT_UNI', ''), - ), - $this->table_prefix . 'forums' => array( - 'forum_last_post_subject' => array('STEXT_UNI', ''), - ), - $this->table_prefix . 'posts' => array( - 'post_subject' => array('STEXT_UNI', '', 'true_sort'), - ), - $this->table_prefix . 'privmsgs' => array( - 'message_subject' => array('STEXT_UNI', ''), - ), - $this->table_prefix . 'topics' => array( - 'topic_title' => array('STEXT_UNI', '', 'true_sort'), - 'topic_last_post_subject' => array('STEXT_UNI', ''), - ), - ), - 'drop_keys' => array( - $this->table_prefix . 'sessions' => array('session_forum_id'), - ), - 'add_index' => array( - $this->table_prefix . 'sessions' => array( - 'session_fid' => array('session_forum_id'), - ), - ), - ); - } - - function update_data() - { - return array( - array('config.update', array('version', '3.0.2-rc2')), - ); - } -} diff --git a/phpBB/includes/db/migration/data/3_0_3.php b/phpBB/includes/db/migration/data/3_0_3.php deleted file mode 100644 index dff375f438..0000000000 --- a/phpBB/includes/db/migration/data/3_0_3.php +++ /dev/null @@ -1,28 +0,0 @@ - array( - $this->table_prefix . 'styles_template' => array( - 'template_inherits_id' => array('UINT:4', 0), - 'template_inherit_path' => array('VCHAR', ''), - ), - $this->table_prefix . 'groups' => array( - 'group_max_recipients' => array('UINT', 0), - ), - ), - ); - } - - function update_data() - { - return array( - array('config.add', array('enable_queue_trigger', '0')), - array('config.add', array('queue_trigger_posts', '3')), - array('config.add', array('pm_max_recipients', '0')), - array('custom', array(array(&$this, 'set_group_default_max_recipients'))), - array('config.add', array('dbms_version', $this->db->sql_server_info(true))), - array('permission.add', array('u_masspm_group', true, 'u_masspm')), - array('custom', array(array(&$this, 'correct_acp_email_permissions'))), - - array('config.update', array('version', '3.0.3-rc1')), - ); - } - - function correct_acp_email_permissions() - { - $sql = 'UPDATE ' . $this->table_prefix . 'modules - SET module_auth = \'acl_a_email && cfg_email_enable\' - WHERE module_class = \'acp\' - AND module_basename = \'email\''; - $this->sql_query($sql); - } - - function set_group_default_max_recipients() - { - // Set maximum number of recipients for the registered users, bots, guests group - $sql = 'UPDATE ' . GROUPS_TABLE . ' SET group_max_recipients = 5 - WHERE ' . $this->db->sql_in_set('group_name', array('GUESTS', 'REGISTERED', 'REGISTERED_COPPA', 'BOTS')); - $this->sql_query($sql); - } -} diff --git a/phpBB/includes/db/migration/data/3_0_4.php b/phpBB/includes/db/migration/data/3_0_4.php deleted file mode 100644 index 1af4508331..0000000000 --- a/phpBB/includes/db/migration/data/3_0_4.php +++ /dev/null @@ -1,49 +0,0 @@ -db->sql_layer == 'oracle') - { - // log_operation is CLOB - but we can change this later - $sql = 'UPDATE ' . $this->table_prefix . "log - SET log_operation = 'LOG_DELETE_TOPIC' - WHERE log_operation LIKE 'LOG_TOPIC_DELETED'"; - $this->sql_query($sql); - } - else - { - $sql = 'UPDATE ' . $this->table_prefix . "log - SET log_operation = 'LOG_DELETE_TOPIC' - WHERE log_operation = 'LOG_TOPIC_DELETED'"; - $this->sql_query($sql); - } - } -} diff --git a/phpBB/includes/db/migration/data/3_0_4_rc1.php b/phpBB/includes/db/migration/data/3_0_4_rc1.php deleted file mode 100644 index e9bb0e01f5..0000000000 --- a/phpBB/includes/db/migration/data/3_0_4_rc1.php +++ /dev/null @@ -1,107 +0,0 @@ - array( - $this->table_prefix . 'profile_fields' => array( - 'field_show_profile' => array('BOOL', 0), - ), - ), - 'change_columns' => array( - $this->table_prefix . 'styles' => array( - 'style_id' => array('UINT', NULL, 'auto_increment'), - 'template_id' => array('UINT', 0), - 'theme_id' => array('UINT', 0), - 'imageset_id' => array('UINT', 0), - ), - $this->table_prefix . 'styles_imageset' => array( - 'imageset_id' => array('UINT', NULL, 'auto_increment'), - ), - $this->table_prefix . 'styles_imageset_data' => array( - 'image_id' => array('UINT', NULL, 'auto_increment'), - 'imageset_id' => array('UINT', 0), - ), - $this->table_prefix . 'styles_theme' => array( - 'theme_id' => array('UINT', NULL, 'auto_increment'), - ), - $this->table_prefix . 'styles_template' => array( - 'template_id' => array('UINT', NULL, 'auto_increment'), - ), - $this->table_prefix . 'styles_template_data' => array( - 'template_id' => array('UINT', 0), - ), - $this->table_prefix . 'forums' => array( - 'forum_style' => array('UINT', 0), - ), - $this->table_prefix . 'users' => array( - 'user_style' => array('UINT', 0), - ), - ), - ); - } - - function update_data() - { - return array( - array('custom', array(array(&$this, 'update_custom_profile_fields'))), - - array('config.update', array('version', '3.0.4-rc1')), - ); - } - - function update_custom_profile_fields() - { - // Update the Custom Profile Fields based on previous settings to the new format - $sql = 'SELECT field_id, field_required, field_show_on_reg, field_hide - FROM ' . PROFILE_FIELDS_TABLE; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - $sql_ary = array( - 'field_required' => 0, - 'field_show_on_reg' => 0, - 'field_hide' => 0, - 'field_show_profile'=> 0, - ); - - if ($row['field_required']) - { - $sql_ary['field_required'] = $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; - } - else if ($row['field_show_on_reg']) - { - $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; - } - else if ($row['field_hide']) - { - // Only administrators and moderators can see this CPF, if the view is enabled, they can see it, otherwise just admins in the acp_users module - $sql_ary['field_hide'] = 1; - } - else - { - // equivelant to "none", which is the "Display in user control panel" option - $sql_ary['field_show_profile'] = 1; - } - - $this->sql_query('UPDATE ' . $this->table_prefix . 'profile_fields SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary); - } - - $this->db->sql_freeresult($result); - } -} diff --git a/phpBB/includes/db/migration/data/3_0_5.php b/phpBB/includes/db/migration/data/3_0_5.php deleted file mode 100644 index 2f80970781..0000000000 --- a/phpBB/includes/db/migration/data/3_0_5.php +++ /dev/null @@ -1,28 +0,0 @@ - array( - $this->table_prefix . 'forums' => array( - 'forum_style' => array('UINT', 0), - ), - ), - ); - } - - function update_data() - { - $search_indexing_state = $this->config['search_indexing_state']; - - return array( - array('config.add', array('captcha_gd_wave', 0)), - array('config.add', array('captcha_gd_3d_noise', 1)), - array('config.add', array('captcha_gd_fonts', 1)), - array('config.add', array('confirm_refresh', 1)), - array('config.add', array('max_num_search_keywords', 10)), - array('config.remove', array('search_indexing_state')), - array('config.add', array('search_indexing_state', $search_indexing_state, true)), - array('custom', array(array(&$this, 'hash_old_passwords'))), - array('custom', array(array(&$this, 'update_ichiro_bot'))), - ); - } - - function hash_old_passwords() - { - $sql = 'SELECT user_id, user_password - FROM ' . $this->table_prefix . 'users - WHERE user_pass_convert = 1'; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - if (strlen($row['user_password']) == 32) - { - $sql_ary = array( - 'user_password' => phpbb_hash($row['user_password']), - ); - - $this->sql_query('UPDATE ' . $this->table_prefix . 'users SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id']); - } - } - $this->db->sql_freeresult($result); - } - - function update_ichiro_bot() - { - // Adjust bot entry - $sql = 'UPDATE ' . $this->table_prefix . "bots - SET bot_agent = 'ichiro/' - WHERE bot_agent = 'ichiro/2'"; - $this->sql_query($sql); - } - - function remove_duplicate_auth_options() - { - // Before we are able to add a unique key to auth_option, we need to remove duplicate entries - $sql = 'SELECT auth_option - FROM ' . $this->table_prefix . 'acl_options - GROUP BY auth_option - HAVING COUNT(*) >= 2'; - $result = $this->db->sql_query($sql); - - $auth_options = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $auth_options[] = $row['auth_option']; - } - $this->db->sql_freeresult($result); - - // Remove specific auth options - if (!empty($auth_options)) - { - foreach ($auth_options as $option) - { - // Select auth_option_ids... the largest id will be preserved - $sql = 'SELECT auth_option_id - FROM ' . ACL_OPTIONS_TABLE . " - WHERE auth_option = '" . $db->sql_escape($option) . "' - ORDER BY auth_option_id DESC"; - // sql_query_limit not possible here, due to bug in postgresql layer - $result = $this->db->sql_query($sql); - - // Skip first row, this is our original auth option we want to preserve - $row = $this->db->sql_fetchrow($result); - - while ($row = $this->db->sql_fetchrow($result)) - { - // Ok, remove this auth option... - $this->sql_query('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id']); - $this->sql_query('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id']); - $this->sql_query('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id']); - $this->sql_query('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id']); - } - $this->db->sql_freeresult($result); - } - } - } -} diff --git a/phpBB/includes/db/migration/data/3_0_5_rc1part2.php b/phpBB/includes/db/migration/data/3_0_5_rc1part2.php deleted file mode 100644 index 1fab0f8873..0000000000 --- a/phpBB/includes/db/migration/data/3_0_5_rc1part2.php +++ /dev/null @@ -1,37 +0,0 @@ - array( - ACL_OPTIONS_TABLE => array('auth_option'), - ), - 'add_unique_index' => array( - ACL_OPTIONS_TABLE => array( - 'auth_option' => array('auth_option'), - ), - ), - ); - } - - function update_data() - { - return array( - array('config.update', array('version', '3.0.5-rc1')), - ); - } -} diff --git a/phpBB/includes/db/migration/data/3_0_6.php b/phpBB/includes/db/migration/data/3_0_6.php deleted file mode 100644 index 26176b9437..0000000000 --- a/phpBB/includes/db/migration/data/3_0_6.php +++ /dev/null @@ -1,28 +0,0 @@ - array( - $this->table_prefix . 'confirm' => array( - 'attempts' => array('UINT', 0), - ), - $this->table_prefix . 'users' => array( - 'user_new' => array('BOOL', 1), - 'user_reminded' => array('TINT:4', 0), - 'user_reminded_time' => array('TIMESTAMP', 0), - ), - $this->table_prefix . 'groups' => array( - 'group_skip_auth' => array('BOOL', 0, 'after' => 'group_founder_manage'), - ), - $this->table_prefix . 'privmsgs' => array( - 'message_reported' => array('BOOL', 0), - ), - $this->table_prefix . 'reports' => array( - 'pm_id' => array('UINT', 0), - ), - $this->table_prefix . 'profile_fields' => array( - 'field_show_on_vt' => array('BOOL', 0), - ), - $this->table_prefix . 'forums' => array( - 'forum_options' => array('UINT:20', 0), - ), - ), - 'change_columns' => array( - $this->table_prefix . 'users' => array( - 'user_options' => array('UINT:11', 230271), - ), - ), - 'add_index' => array( - $this->table_prefix . 'reports' => array( - 'post_id' => array('post_id'), - 'pm_id' => array('pm_id'), - ), - $this->table_prefix . 'posts' => array( - 'post_username' => array('post_username:255'), - ), - ), - ); - } - - function update_data() - { - return array( - array('config.add', array('captcha_plugin', 'phpbb_captcha_nogd')), - array('if', array( - ($this->config['captcha_gd']), - array('config.update', array('captcha_plugin', 'phpbb_captcha_gd')), - )), - - array('config.add', array('feed_enable', 0)), - array('config.add', array('feed_limit', 10)), - array('config.add', array('feed_overall_forums', 1)), - array('config.add', array('feed_overall_forums_limit', 15)), - array('config.add', array('feed_overall_topics', 0)), - array('config.add', array('feed_overall_topics_limit', 15)), - array('config.add', array('feed_forum', 1)), - array('config.add', array('feed_topic', 1)), - array('config.add', array('feed_item_statistics', 1)), - - array('config.add', array('smilies_per_page', 50)), - array('config.add', array('allow_pm_report', 1)), - array('config.add', array('min_post_chars', 1)), - array('config.add', array('allow_quick_reply', 1)), - array('config.add', array('new_member_post_limit', 0)), - array('config.add', array('new_member_group_default', 0)), - array('config.add', array('delete_time', $this->config['edit_time'])), - - array('config.add', array('allow_avatar', 0)), - array('if', array( - ($this->config['allow_avatar_upload'] || $this->config['allow_avatar_local'] || $this->config['allow_avatar_remote']), - array('config.update', array('allow_avatar', 1)), - )), - array('config.add', array('allow_avatar_remote_upload', 0)), - array('if', array( - ($this->config['allow_avatar_remote'] && $this->config['allow_avatar_upload']), - array('config.update', array('allow_avatar_remote_upload', 1)), - )), - - array('module.add', array( - 'acp', - 'ACP_BOARD_CONFIGURATION', - array( - 'module_basename' => 'acp_board', - 'modes' => array('feed'), - ), - )), - array('module.add', array( - 'acp', - 'ACP_CAT_USERS', - array( - 'module_basename' => 'acp_users', - 'modes' => array('warnings'), - ), - )), - array('module.add', array( - 'acp', - 'ACP_SERVER_CONFIGURATION', - array( - 'module_basename' => 'acp_send_statistics', - 'modes' => array('send_statistics'), - ), - )), - array('module.add', array( - 'acp', - 'ACP_FORUM_BASED_PERMISSIONS', - array( - 'module_basename' => 'acp_permissions', - 'modes' => array('setting_forum_copy'), - ), - )), - array('module.add', array( - 'mcp', - 'MCP_REPORTS', - array( - 'module_basename' => 'mcp_pm_reports', - 'modes' => array('pm_reports','pm_reports_closed','pm_report_details'), - ), - )), - array('custom', array(array(&$this, 'add_newly_registered_group'))), - array('custom', array(array(&$this, 'set_user_options_default'))), - - array('config.update', array('version', '3.0.6-rc1')), - ); - } - - function set_user_options_default() - { - // 229376 is the added value to enable all three signature options - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_options = user_options + 229376'; - $this->sql_query($sql); - } - - function add_newly_registered_group() - { - // Add newly_registered group... but check if it already exists (we always supported running the updater on any schema) - $sql = 'SELECT group_id - FROM ' . GROUPS_TABLE . " - WHERE group_name = 'NEWLY_REGISTERED'"; - $result = $this->db->sql_query($sql); - $group_id = (int) $this->db->sql_fetchfield('group_id'); - $this->db->sql_freeresult($result); - - if (!$group_id) - { - $sql = 'INSERT INTO ' . GROUPS_TABLE . " (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('NEWLY_REGISTERED', 3, 0, '', 0, '', '', '', 5)"; - $this->sql_query($sql); - - $group_id = $this->db->sql_nextid(); - } - - // Insert new user role... at the end of the chain - $sql = 'SELECT role_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_name = 'ROLE_USER_NEW_MEMBER' - AND role_type = 'u_'"; - $result = $this->db->sql_query($sql); - $u_role = (int) $this->db->sql_fetchfield('role_id'); - $this->db->sql_freeresult($result); - - if (!$u_role) - { - $sql = 'SELECT MAX(role_order) as max_order_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_type = 'u_'"; - $result = $this->db->sql_query($sql); - $next_order_id = (int) $this->db->sql_fetchfield('max_order_id'); - $this->db->sql_freeresult($result); - - $next_order_id++; - - $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_NEW_MEMBER', 'ROLE_DESCRIPTION_USER_NEW_MEMBER', 'u_', $next_order_id)"; - $this->sql_query($sql); - $u_role = $this->db->sql_nextid(); - - // Now add the correct data to the roles... - // The standard role says that new users are not able to send a PM, Mass PM, are not able to PM groups - $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $u_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_sendpm', 'u_masspm', 'u_masspm_group')"; - $this->sql_query($sql); - - // Add user role to group - $sql = 'INSERT INTO ' . ACL_GROUPS_TABLE . " (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES ($group_id, 0, 0, $u_role, 0)"; - $this->sql_query($sql); - } - - // Insert new forum role - $sql = 'SELECT role_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_name = 'ROLE_FORUM_NEW_MEMBER' - AND role_type = 'f_'"; - $result = $this->db->sql_query($sql); - $f_role = (int) $this->db->sql_fetchfield('role_id'); - $this->db->sql_freeresult($result); - - if (!$f_role) - { - $sql = 'SELECT MAX(role_order) as max_order_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_type = 'f_'"; - $result = $this->db->sql_query($sql); - $next_order_id = (int) $this->db->sql_fetchfield('max_order_id'); - $this->db->sql_freeresult($result); - - $next_order_id++; - - $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_NEW_MEMBER', 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER', 'f_', $next_order_id)"; - $this->sql_query($sql); - $f_role = $this->db->sql_nextid(); - - $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $f_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove')"; - $this->sql_query($sql); - } - - // Set every members user_new column to 0 (old users) only if there is no one yet (this makes sure we do not execute this more than once) - $sql = 'SELECT 1 - FROM ' . USERS_TABLE . ' - WHERE user_new = 0'; - $result = $this->db->sql_query_limit($sql, 1); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if (!$row) - { - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new = 0'; - $this->sql_query($sql); - } - - // To mimick the old "feature" we will assign the forum role to every forum, regardless of the setting (this makes sure there are no "this does not work!!!! YUO!!!" posts... - // Check if the role is already assigned... - $sql = 'SELECT forum_id - FROM ' . ACL_GROUPS_TABLE . ' - WHERE group_id = ' . $group_id . ' - AND auth_role_id = ' . $f_role; - $result = $this->db->sql_query($sql); - $is_options = (int) $this->db->sql_fetchfield('forum_id'); - $this->db->sql_freeresult($result); - - // Not assigned at all... :/ - if (!$is_options) - { - // Get postable forums - $sql = 'SELECT forum_id - FROM ' . FORUMS_TABLE . ' - WHERE forum_type != ' . FORUM_LINK; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - $this->sql_query('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (' . $group_id . ', ' . (int) $row['forum_id'] . ', 0, ' . $f_role . ', 0)'); - } - $this->db->sql_freeresult($result); - } - - // Clear permissions... - include_once($this->phpbb_root_path . 'includes/acp/auth.' . $this->php_ext); - $auth_admin = new auth_admin(); - $auth_admin->acl_clear_prefetch(); - } -} diff --git a/phpBB/includes/db/migration/data/3_0_6_rc2.php b/phpBB/includes/db/migration/data/3_0_6_rc2.php deleted file mode 100644 index 4092a5fa61..0000000000 --- a/phpBB/includes/db/migration/data/3_0_6_rc2.php +++ /dev/null @@ -1,28 +0,0 @@ -sql_query($sql); - } -} diff --git a/phpBB/includes/db/migration/data/3_0_6_rc4.php b/phpBB/includes/db/migration/data/3_0_6_rc4.php deleted file mode 100644 index e748c7a4ff..0000000000 --- a/phpBB/includes/db/migration/data/3_0_6_rc4.php +++ /dev/null @@ -1,28 +0,0 @@ - array( - $this->table_prefix . 'log' => array('log_time'), - ), - 'add_index' => array( - $this->table_prefix . 'topics_track' => array( - 'topic_id' => array('topic_id'), - ), - ), - ); - } - - function update_data() - { - return array( - array('config.add', array('feed_overall', 1)), - array('config.add', array('feed_http_auth', 0)), - array('config.add', array('feed_limit_post', $this->config['feed_limit'])), - array('config.add', array('feed_limit_topic', $this->config['feed_overall_topics_limit'])), - array('config.add', array('feed_topics_new', $this->config['feed_overall_topics'])), - array('config.add', array('feed_topics_active', $this->config['feed_overall_topics'])), - array('custom', array(array(&$this, 'delete_text_templates'))), - - array('config.update', array('version', '3.0.7-rc1')), - ); - } - - function delete_text_templates() - { - // Delete all text-templates from the template_data - $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' - WHERE template_filename ' . $this->db->sql_like_expression($this->db->any_char . '.txt'); - $this->sql_query($sql); - } -} diff --git a/phpBB/includes/db/migration/data/3_0_7_rc2.php b/phpBB/includes/db/migration/data/3_0_7_rc2.php deleted file mode 100644 index e2c6acce1e..0000000000 --- a/phpBB/includes/db/migration/data/3_0_7_rc2.php +++ /dev/null @@ -1,72 +0,0 @@ - ' . USER_IGNORE . " - AND user_email <> ''"; - $result = $this->db->sql_query_limit($sql, $limit, $start); - - $i = 0; - while ($row = $this->db->sql_fetchrow($result)) - { - $i++; - - // Snapshot of the phpbb_email_hash() function - // We cannot call it directly because the auto updater updates the DB first. :/ - $user_email_hash = sprintf('%u', crc32(strtolower($row['user_email']))) . strlen($row['user_email']); - - if ($user_email_hash != $row['user_email_hash']) - { - $sql_ary = array( - 'user_email_hash' => $user_email_hash, - ); - - $sql = 'UPDATE ' . USERS_TABLE . ' - SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE user_id = ' . (int) $row['user_id']; - $this->sql_query($sql); - } - } - $this->db->sql_freeresult($result); - - if ($i < $limit) - { - // Completed - return false; - } - - return $start + $limit; - } -} diff --git a/phpBB/includes/db/migration/data/3_0_8.php b/phpBB/includes/db/migration/data/3_0_8.php deleted file mode 100644 index a5defc8278..0000000000 --- a/phpBB/includes/db/migration/data/3_0_8.php +++ /dev/null @@ -1,28 +0,0 @@ - 'acp_board', - 'modes' => array('post'), - ), - )), - array('config.add', array('load_unreads_search', 1)), - array('config.update_if_equals', array(600, 'queue_interval', 60)), - array('config.update_if_equals', array(50, 'email_package_size', 20)), - - array('config.update', array('version', '3.0.8-rc1')), - ); - } - - function update_file_extension_group_names() - { - // Update file extension group names to use language strings. - $sql = 'SELECT lang_dir - FROM ' . LANG_TABLE; - $result = $this->db->sql_query($sql); - - $extension_groups_updated = array(); - while ($lang_dir = $this->db->sql_fetchfield('lang_dir')) - { - $lang_dir = basename($lang_dir); - - // The language strings we need are either in language/.../acp/attachments.php - // in the update package if we're updating to 3.0.8-RC1 or later, - // or they are in language/.../install.php when we're updating from 3.0.7-PL1 or earlier. - // On an already updated board, they can also already be in language/.../acp/attachments.php - // in the board root. - $lang_files = array( - "{$this->phpbb_root_path}install/update/new/language/$lang_dir/acp/attachments.{$this->php_ext}", - "{$this->phpbb_root_path}language/$lang_dir/install.{$this->php_ext}", - "{$this->phpbb_root_path}language/$lang_dir/acp/attachments.{$this->php_ext}", - ); - - foreach ($lang_files as $lang_file) - { - if (!file_exists($lang_file)) - { - continue; - } - - $lang = array(); - include($lang_file); - - foreach($lang as $lang_key => $lang_val) - { - if (isset($extension_groups_updated[$lang_key]) || strpos($lang_key, 'EXT_GROUP_') !== 0) - { - continue; - } - - $sql_ary = array( - 'group_name' => substr($lang_key, 10), // Strip off 'EXT_GROUP_' - ); - - $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' - SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . " - WHERE group_name = '" . $this->db->sql_escape($lang_val) . "'"; - $this->sql_query($sql); - - $extension_groups_updated[$lang_key] = true; - } - } - } - $this->db->sql_freeresult($result); - } - - function update_module_auth() - { - $sql = 'UPDATE ' . MODULES_TABLE . ' - SET module_auth = \'cfg_allow_avatar && (cfg_allow_avatar_local || cfg_allow_avatar_remote || cfg_allow_avatar_upload || cfg_allow_avatar_remote_upload)\' - WHERE module_class = \'ucp\' - AND module_basename = \'profile\' - AND module_mode = \'avatar\''; - $this->sql_query($sql); - } - - function update_bots() - { - $bot_name = 'Bing [Bot]'; - $bot_name_clean = utf8_clean_string($bot_name); - - $sql = 'SELECT user_id - FROM ' . USERS_TABLE . " - WHERE username_clean = '" . $this->db->sql_escape($bot_name_clean) . "'"; - $result = $this->db->sql_query($sql); - $bing_already_added = (bool) $this->db->sql_fetchfield('user_id'); - $this->db->sql_freeresult($result); - - if (!$bing_already_added) - { - $bot_agent = 'bingbot/'; - $bot_ip = ''; - $sql = 'SELECT group_id, group_colour - FROM ' . GROUPS_TABLE . " - WHERE group_name = 'BOTS'"; - $result = $this->db->sql_query($sql); - $group_row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if (!$group_row) - { - // default fallback, should never get here - $group_row['group_id'] = 6; - $group_row['group_colour'] = '9E8DA7'; - } - - if (!function_exists('user_add')) - { - include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); - } - - $user_row = array( - 'user_type' => USER_IGNORE, - 'group_id' => $group_row['group_id'], - 'username' => $bot_name, - 'user_regdate' => time(), - 'user_password' => '', - 'user_colour' => $group_row['group_colour'], - 'user_email' => '', - 'user_lang' => $this->config['default_lang'], - 'user_style' => $this->config['default_style'], - 'user_timezone' => 0, - 'user_dateformat' => $this->config['default_dateformat'], - 'user_allow_massemail' => 0, - ); - - $user_id = user_add($user_row); - - $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $this->db->sql_build_array('INSERT', array( - 'bot_active' => 1, - 'bot_name' => (string) $bot_name, - 'user_id' => (int) $user_id, - 'bot_agent' => (string) $bot_agent, - 'bot_ip' => (string) $bot_ip, - )); - - $this->sql_query($sql); - } - } - - function delete_orphan_shadow_topics() - { - // Delete shadow topics pointing to not existing topics - $batch_size = 500; - - // Set of affected forums we have to resync - $sync_forum_ids = array(); - - $sql_array = array( - 'SELECT' => 't1.topic_id, t1.forum_id', - 'FROM' => array( - TOPICS_TABLE => 't1', - ), - 'LEFT_JOIN' => array( - array( - 'FROM' => array(TOPICS_TABLE => 't2'), - 'ON' => 't1.topic_moved_id = t2.topic_id', - ), - ), - 'WHERE' => 't1.topic_moved_id <> 0 - AND t2.topic_id IS NULL', - ); - $sql = $this->db->sql_build_query('SELECT', $sql_array); - $result = $this->db->sql_query_limit($sql, $batch_size); - - $topic_ids = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $topic_ids[] = (int) $row['topic_id']; - - $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id']; - } - $this->db->sql_freeresult($result); - - if (!empty($topic_ids)) - { - $sql = 'DELETE FROM ' . TOPICS_TABLE . ' - WHERE ' . $this->db->sql_in_set('topic_id', $topic_ids); - $this->db->sql_query($sql); - - // Sync the forums we have deleted shadow topics from. - sync('forum', 'forum_id', $sync_forum_ids, true, true); - - return true; - } - else - { - return false; - } - } -} diff --git a/phpBB/includes/db/migration/data/3_0_9.php b/phpBB/includes/db/migration/data/3_0_9.php deleted file mode 100644 index eb359e2697..0000000000 --- a/phpBB/includes/db/migration/data/3_0_9.php +++ /dev/null @@ -1,28 +0,0 @@ - array( - $this->table_prefix . 'login_attempts' => array( - 'COLUMNS' => array( - // this column was removed from the database updater - // after 3.0.9-RC3 was released. It might still exist - // in 3.0.9-RCX installations and has to be dropped in - // 3.0.12 after the db_tools class is capable of properly - // removing a primary key. - // 'attempt_id' => array('UINT', NULL, 'auto_increment'), - 'attempt_ip' => array('VCHAR:40', ''), - 'attempt_browser' => array('VCHAR:150', ''), - 'attempt_forwarded_for' => array('VCHAR:255', ''), - 'attempt_time' => array('TIMESTAMP', 0), - 'user_id' => array('UINT', 0), - 'username' => array('VCHAR_UNI:255', 0), - 'username_clean' => array('VCHAR_CI', 0), - ), - //'PRIMARY_KEY' => 'attempt_id', - 'KEYS' => array( - 'att_ip' => array('INDEX', array('attempt_ip', 'attempt_time')), - 'att_for' => array('INDEX', array('attempt_forwarded_for', 'attempt_time')), - 'att_time' => array('INDEX', array('attempt_time')), - 'user_id' => array('INDEX', 'user_id'), - ), - ), - ), - 'change_columns' => array( - $this->table_prefix . 'bbcodes' => array( - 'bbcode_id' => array('USINT', 0), - ), - ), - ); - } - - function update_data() - { - return array( - array('config.add', array('ip_login_limit_max', 50)), - array('config.add', array('ip_login_limit_time', 21600)), - array('config.add', array('ip_login_limit_use_forwarded', 0)), - array('custom', array(array(&$this, 'update_file_extension_group_names'))), - array('custom', array(array(&$this, 'fix_firebird_qa_captcha'))), - - array('config.update', array('version', '3.0.9-rc1')), - ); - } - - function update_file_extension_group_names() - { - // Update file extension group names to use language strings, again. - $sql = 'SELECT group_id, group_name - FROM ' . EXTENSION_GROUPS_TABLE . ' - WHERE group_name ' . $this->db->sql_like_expression('EXT_GROUP_' . $this->db->any_char); - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - $sql_ary = array( - 'group_name' => substr($row['group_name'], 10), // Strip off 'EXT_GROUP_' - ); - - $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' - SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE group_id = ' . $row['group_id']; - $this->sql_query($sql); - } - $this->db->sql_freeresult($result); - } - - function fix_firebird_qa_captcha() - { - // Recover from potentially broken Q&A CAPTCHA table on firebird - // Q&A CAPTCHA was uninstallable, so it's safe to remove these - // without data loss - if ($this->db_tools->sql_layer == 'firebird') - { - $tables = array( - $this->table_prefix . 'captcha_questions', - $this->table_prefix . 'captcha_answers', - $this->table_prefix . 'qa_confirm', - ); - foreach ($tables as $table) - { - if ($this->db_tools->sql_table_exists($table)) - { - $this->db_tools->sql_table_drop($table); - } - } - } - } -} diff --git a/phpBB/includes/db/migration/data/3_0_9_rc2.php b/phpBB/includes/db/migration/data/3_0_9_rc2.php deleted file mode 100644 index e3c4716665..0000000000 --- a/phpBB/includes/db/migration/data/3_0_9_rc2.php +++ /dev/null @@ -1,28 +0,0 @@ - array( - GROUPS_TABLE => array( - 'group_teampage' => array('UINT', 0, 'after' => 'group_legend'), - ), - PROFILE_FIELDS_TABLE => array( - 'field_show_on_pm' => array('BOOL', 0), - ), - STYLES_TABLE => array( - 'style_path' => array('VCHAR:100', ''), - 'bbcode_bitfield' => array('VCHAR:255', 'kNg='), - 'style_parent_id' => array('UINT:4', 0), - 'style_parent_tree' => array('TEXT', ''), - ), - REPORTS_TABLE => array( - 'reported_post_text' => array('MTEXT_UNI', ''), - 'reported_post_uid' => array('VCHAR:8', ''), - 'reported_post_bitfield' => array('VCHAR:255', ''), - ), - ), - 'change_columns' => array( - GROUPS_TABLE => array( - 'group_legend' => array('UINT', 0), - ), - ), - ); - } - - public function update_data() - { - return array( - array('config.update', array('search_type', 'phpbb_search_' . $this->config['search_type'])), - - array('config.add', array('fulltext_postgres_ts_name', 'simple')), - array('config.add', array('fulltext_postgres_min_word_len', 4)), - array('config.add', array('fulltext_postgres_max_word_len', 254)), - array('config.add', array('fulltext_sphinx_stopwords', 0)), - array('config.add', array('fulltext_sphinx_indexer_mem_limit', 512)), - - array('config.add', array('load_jquery_cdn', 0)), - array('config.add', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js')), - - array('config.add', array('use_system_cron', 0)), - - array('config.add', array('legend_sort_groupname', 0)), - array('config.add', array('teampage_forums', 1)), - array('config.add', array('teampage_memberships', 1)), - - array('config.add', array('load_cpf_pm', 0)), - - array('config.add', array('display_last_subject', 1)), - - array('config.add', array('assets_version', 1)), - - array('config.add', array('site_home_url', '')), - array('config.add', array('site_home_text', '')), - - array('permission.add', array('u_chgprofileinfo', true, 'u_sig')), - - array('module.add', array( - 'acp', - 'ACP_GROUPS', - array( - 'module_basename' => 'acp_groups', - 'modes' => array('position'), - ), - )), - array('module.add', array( - 'acp', - 'ACP_ATTACHMENTS', - array( - 'module_basename' => 'acp_attachments', - 'modes' => array('manage'), - ), - )), - array('module.add', array( - 'acp', - 'ACP_STYLE_MANAGEMENT', - array( - 'module_basename' => 'acp_styles', - 'modes' => array('install', 'cache'), - ), - )), - array('module.add', array( - 'ucp', - 'UCP_PROFILE', - array( - 'module_basename' => 'ucp_profile', - 'modes' => array('autologin_keys'), - ), - )), - - array('module.remove', array( - 'acp', - false, - 'ACP_TEMPLATES', - )), - array('module.remove', array( - 'acp', - false, - 'ACP_THEMES', - )), - array('module.remove', array( - 'acp', - false, - 'ACP_IMAGESETS', - )), - - array('custom', array(array($this, 'rename_module_basenames'))), - array('custom', array(array($this, 'rename_styles_module'))), - array('custom', array(array($this, 'add_group_teampage'))), - array('custom', array(array($this, 'update_group_legend'))), - array('custom', array(array($this, 'localise_global_announcements'))), - array('custom', array(array($this, 'update_ucp_pm_basename'))), - array('custom', array(array($this, 'update_ucp_profile_auth'))), - array('custom', array(array($this, 'move_customise_modules'))), - - array('config.update', array('version', '3.1.0-dev')), - ); - } - - public function move_customise_modules() - { - // Move language management to new location in the Customise tab - // First get language module id - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " - WHERE module_basename = 'acp_language'"; - $result = $this->db->sql_query($sql); - $language_module_id = $this->db->sql_fetchfield('module_id'); - $this->db->sql_freeresult($result); - // Next get language management module id of the one just created - $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " - WHERE module_langname = 'ACP_LANGUAGE'"; - $result = $this->db->sql_query($sql); - $language_management_module_id = $this->db->sql_fetchfield('module_id'); - $this->db->sql_freeresult($result); - - if (!class_exists('acp_modules')) - { - include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext); - } - // acp_modules calls adm_back_link, which is undefined at this point - if (!function_exists('adm_back_link')) - { - include($this->phpbb_root_path . 'includes/functions_acp.' . $this->php_ext); - } - $module_manager = new acp_modules(); - $module_manager->module_class = 'acp'; - $module_manager->move_module($language_module_id, $language_management_module_id); - } - - public function update_ucp_pm_basename() - { - $sql = 'SELECT module_id, module_basename - FROM ' . MODULES_TABLE . " - WHERE module_basename <> 'ucp_pm' AND - module_langname='UCP_PM'"; - $result = $this->db->sql_query_limit($sql, 1); - - if ($row = $this->db->sql_fetchrow($result)) - { - // This update is still not applied. Applying it - - $sql = 'UPDATE ' . MODULES_TABLE . " - SET module_basename = 'ucp_pm' - WHERE module_id = " . (int) $row['module_id']; - - $this->sql_query($sql); - } - $this->db->sql_freeresult($result); - } - - public function update_ucp_profile_auth() - { - // Update the auth setting for the module - $sql = 'UPDATE ' . MODULES_TABLE . " - SET module_auth = 'acl_u_chgprofileinfo' - WHERE module_class = 'ucp' - AND module_basename = 'ucp_profile' - AND module_mode = 'profile_info'"; - $this->sql_query($sql); - } - - public function rename_styles_module() - { - // Rename styles module to Customise - $sql = 'UPDATE ' . MODULES_TABLE . " - SET module_langname = 'ACP_CAT_CUSTOMISE' - WHERE module_langname = 'ACP_CAT_STYLES'"; - $this->sql_query($sql); - } - - public function rename_module_basenames() - { - // rename all module basenames to full classname - $sql = 'SELECT module_id, module_basename, module_class - FROM ' . MODULES_TABLE; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - $module_id = (int) $row['module_id']; - unset($row['module_id']); - - if (!empty($row['module_basename']) && !empty($row['module_class'])) - { - // all the class names start with class name or with phpbb_ for auto loading - if (strpos($row['module_basename'], $row['module_class'] . '_') !== 0 && - strpos($row['module_basename'], 'phpbb_') !== 0) - { - $row['module_basename'] = $row['module_class'] . '_' . $row['module_basename']; - - $sql_update = $this->db->sql_build_array('UPDATE', $row); - - $sql = 'UPDATE ' . MODULES_TABLE . ' - SET ' . $sql_update . ' - WHERE module_id = ' . $module_id; - $this->sql_query($sql); - } - } - } - - $this->db->sql_freeresult($result); - } - - public function add_group_teampage() - { - $sql = 'UPDATE ' . GROUPS_TABLE . ' - SET group_teampage = 1 - WHERE group_type = ' . GROUP_SPECIAL . " - AND group_name = 'ADMINISTRATORS'"; - $this->sql_query($sql); - - $sql = 'UPDATE ' . GROUPS_TABLE . ' - SET group_teampage = 2 - WHERE group_type = ' . GROUP_SPECIAL . " - AND group_name = 'GLOBAL_MODERATORS'"; - $this->sql_query($sql); - } - - public function update_group_legend() - { - $sql = 'SELECT group_id - FROM ' . GROUPS_TABLE . ' - WHERE group_legend = 1 - ORDER BY group_name ASC'; - $result = $this->db->sql_query($sql); - - $next_legend = 1; - while ($row = $this->db->sql_fetchrow($result)) - { - $sql = 'UPDATE ' . GROUPS_TABLE . ' - SET group_legend = ' . $next_legend . ' - WHERE group_id = ' . (int) $row['group_id']; - $this->sql_query($sql); - - $next_legend++; - } - $this->db->sql_freeresult($result); - } - - public function localise_global_announcements() - { - // Localise Global Announcements - $sql = 'SELECT topic_id, topic_approved, (topic_replies + 1) AS topic_posts, topic_last_post_id, topic_last_post_subject, topic_last_post_time, topic_last_poster_id, topic_last_poster_name, topic_last_poster_colour - FROM ' . TOPICS_TABLE . ' - WHERE forum_id = 0 - AND topic_type = ' . POST_GLOBAL; - $result = $this->db->sql_query($sql); - - $global_announcements = $update_lastpost_data = array(); - $update_lastpost_data['forum_last_post_time'] = 0; - $update_forum_data = array( - 'forum_posts' => 0, - 'forum_topics' => 0, - 'forum_topics_real' => 0, - ); - - while ($row = $this->db->sql_fetchrow($result)) - { - $global_announcements[] = (int) $row['topic_id']; - - $update_forum_data['forum_posts'] += (int) $row['topic_posts']; - $update_forum_data['forum_topics_real']++; - if ($row['topic_approved']) - { - $update_forum_data['forum_topics']++; - } - - if ($update_lastpost_data['forum_last_post_time'] < $row['topic_last_post_time']) - { - $update_lastpost_data = array( - 'forum_last_post_id' => (int) $row['topic_last_post_id'], - 'forum_last_post_subject' => $row['topic_last_post_subject'], - 'forum_last_post_time' => (int) $row['topic_last_post_time'], - 'forum_last_poster_id' => (int) $row['topic_last_poster_id'], - 'forum_last_poster_name' => $row['topic_last_poster_name'], - 'forum_last_poster_colour' => $row['topic_last_poster_colour'], - ); - } - } - $this->db->sql_freeresult($result); - - if (!empty($global_announcements)) - { - // Update the post/topic-count for the forum and the last-post if needed - $sql = 'SELECT forum_id - FROM ' . FORUMS_TABLE . ' - WHERE forum_type = ' . FORUM_POST; - $result = $this->db->sql_query_limit($sql, 1); - $ga_forum_id = $this->db->sql_fetchfield('forum_id'); - $this->db->sql_freeresult($result); - - $sql = 'SELECT forum_last_post_time - FROM ' . FORUMS_TABLE . ' - WHERE forum_id = ' . $ga_forum_id; - $result = $this->db->sql_query($sql); - $lastpost = (int) $this->db->sql_fetchfield('forum_last_post_time'); - $this->db->sql_freeresult($result); - - $sql_update = 'forum_posts = forum_posts + ' . $update_forum_data['forum_posts'] . ', '; - $sql_update .= 'forum_topics_real = forum_topics_real + ' . $update_forum_data['forum_topics_real'] . ', '; - $sql_update .= 'forum_topics = forum_topics + ' . $update_forum_data['forum_topics']; - if ($lastpost < $update_lastpost_data['forum_last_post_time']) - { - $sql_update .= ', ' . $this->db->sql_build_array('UPDATE', $update_lastpost_data); - } - - $sql = 'UPDATE ' . FORUMS_TABLE . ' - SET ' . $sql_update . ' - WHERE forum_id = ' . $ga_forum_id; - $this->sql_query($sql); - - // Update some forum_ids - $table_ary = array(TOPICS_TABLE, POSTS_TABLE, LOG_TABLE, DRAFTS_TABLE, TOPICS_TRACK_TABLE); - foreach ($table_ary as $table) - { - $sql = "UPDATE $table - SET forum_id = $ga_forum_id - WHERE " . $this->db->sql_in_set('topic_id', $global_announcements); - $this->sql_query($sql); - } - unset($table_ary); - } - } -} diff --git a/phpBB/includes/db/migration/data/extensions.php b/phpBB/includes/db/migration/data/extensions.php deleted file mode 100644 index d28e0ebabb..0000000000 --- a/phpBB/includes/db/migration/data/extensions.php +++ /dev/null @@ -1,49 +0,0 @@ - array( - EXT_TABLE => array( - 'COLUMNS' => array( - 'ext_name' => array('VCHAR', ''), - 'ext_active' => array('BOOL', 0), - 'ext_state' => array('TEXT', ''), - ), - 'KEYS' => array( - 'ext_name' => array('UNIQUE', 'ext_name'), - ), - ), - ), - ); - } - - public function update_data() - { - return array( - array('module.add', array( - 'acp', - 'ACP_GENERAL_TASKS', - array( - 'module_basename' => 'acp_extensions', - 'modes' => array('main'), - ), - )), - array('permission.add', array('a_extensions', true, 'a_styles')), - ); - } -} diff --git a/phpBB/includes/db/migration/data/style_update_p1.php b/phpBB/includes/db/migration/data/style_update_p1.php deleted file mode 100644 index 1c46e4147b..0000000000 --- a/phpBB/includes/db/migration/data/style_update_p1.php +++ /dev/null @@ -1,157 +0,0 @@ -phpbb_root_path . 'styles'); - $skip_dirs = array('.', '..', 'prosilver'); - foreach ($iterator as $fileinfo) - { - if ($fileinfo->isDir() && !in_array($fileinfo->getFilename(), $skip_dirs) && file_exists($fileinfo->getPathname() . '/style.cfg')) - { - $style_cfg = parse_cfg_file($fileinfo->getPathname() . '/style.cfg'); - if (isset($style_cfg['phpbb_version']) && version_compare($style_cfg['phpbb_version'], '3.1.0-dev', '>=')) - { - // 3.1 style - $available_styles[] = $fileinfo->getFilename(); - } - } - } - - // Get all installed styles - if ($this->db_tools->sql_table_exists(STYLES_IMAGESET_TABLE)) - { - $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_id, i.imageset_path - FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i - WHERE t.template_id = s.template_id - AND c.theme_id = s.theme_id - AND i.imageset_id = s.imageset_id"; - } - else - { - $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_id - FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . " c - WHERE t.template_id = s.template_id - AND c.theme_id = s.theme_id"; - } - $result = $this->db->sql_query($sql); - - $styles = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $styles[] = $row; - } - $this->db->sql_freeresult($result); - - // Decide which styles to keep, all others will be deleted - $valid_styles = array(); - foreach ($styles as $style_row) - { - if ( - // Delete styles with parent style (not supported yet) - $style_row['template_inherits_id'] == 0 && - // Check if components match - $style_row['template_path'] == $style_row['theme_path'] && (!isset($style_row['imageset_path']) || $style_row['template_path'] == $style_row['imageset_path']) && - // Check if components are valid - in_array($style_row['template_path'], $available_styles) - ) - { - // Valid style. Keep it - $sql_ary = array( - 'style_path' => $style_row['template_path'], - 'bbcode_bitfield' => $style_row['bbcode_bitfield'], - 'style_parent_id' => 0, - 'style_parent_tree' => '', - ); - $this->sql_query('UPDATE ' . STYLES_TABLE . ' - SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE style_id = ' . $style_row['style_id']); - $valid_styles[] = (int) $style_row['style_id']; - } - } - - // Remove old entries from styles table - if (!sizeof($valid_styles)) - { - // No valid styles: remove everything and add prosilver - $this->sql_query('DELETE FROM ' . STYLES_TABLE, $errored, $error_ary); - - $sql_ary = array( - 'style_name' => 'prosilver', - 'style_copyright' => '© phpBB Group', - 'style_active' => 1, - 'style_path' => 'prosilver', - 'bbcode_bitfield' => 'kNg=', - 'style_parent_id' => 0, - 'style_parent_tree' => '', - - // Will be removed in the next step - 'imageset_id' => 0, - 'template_id' => 0, - 'theme_id' => 0, - ); - - $sql = 'INSERT INTO ' . STYLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); - $this->sql_query($sql); - - $sql = 'SELECT style_id - FROM ' . $table . " - WHERE style_name = 'prosilver'"; - $result = $this->sql_query($sql); - $default_style = $this->db->sql_fetchfield($result); - $this->db->sql_freeresult($result); - - set_config('default_style', $default_style); - - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = 0'; - $this->sql_query($sql); - } - else - { - // There are valid styles in styles table. Remove styles that are outdated - $this->sql_query('DELETE FROM ' . STYLES_TABLE . ' - WHERE ' . $this->db->sql_in_set('style_id', $valid_styles, true)); - - // Change default style - if (!in_array($this->config['default_style'], $valid_styles)) - { - $this->sql_query('UPDATE ' . CONFIG_TABLE . " - SET config_value = '" . $valid_styles[0] . "' - WHERE config_name = 'default_style'"); - } - - // Reset styles for users - $this->sql_query('UPDATE ' . USERS_TABLE . ' - SET user_style = 0 - WHERE ' . $this->db->sql_in_set('user_style', $valid_styles, true)); - } - } -} diff --git a/phpBB/includes/db/migration/data/style_update_p2.php b/phpBB/includes/db/migration/data/style_update_p2.php deleted file mode 100644 index db4b7f1753..0000000000 --- a/phpBB/includes/db/migration/data/style_update_p2.php +++ /dev/null @@ -1,42 +0,0 @@ - array( - STYLES_TABLE => array( - 'imageset_id', - 'template_id', - 'theme_id', - ), - ), - - 'drop_tables' => array( - STYLES_IMAGESET_TABLE, - STYLES_IMAGESET_DATA_TABLE, - STYLES_TEMPLATE_TABLE, - STYLES_TEMPLATE_DATA_TABLE, - STYLES_THEME_TABLE, - ), - ); - } - - public function update_data() - { - return array(); - } -} diff --git a/phpBB/includes/db/migration/data/timezone.php b/phpBB/includes/db/migration/data/timezone.php deleted file mode 100644 index 7734ed4b76..0000000000 --- a/phpBB/includes/db/migration/data/timezone.php +++ /dev/null @@ -1,161 +0,0 @@ - array( - USERS_TABLE => array( - 'user_timezone' => array('VCHAR:100', ''), - ), - ), - ); - } - - public function update_data() - { - return array( - array('custom', array(array($this, 'update_timezones'))), - ); - } - - public function update_timezones() - { - // Update user timezones - $sql = 'SELECT user_dst, user_timezone - FROM ' . USERS_TABLE . ' - GROUP BY user_timezone, user_dst'; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - $sql = 'UPDATE ' . USERS_TABLE . " - SET user_timezone = '" . $this->db->sql_escape($this->convert_phpbb30_timezone($row['user_timezone'], $row['user_dst'])) . "' - WHERE user_timezone = '" . $this->db->sql_escape($row['user_timezone']) . "' - AND user_dst = " . (int) $row['user_dst']; - $this->sql_query($sql); - } - $this->db->sql_freeresult($result); - - // Update board default timezone - $sql = 'UPDATE ' . CONFIG_TABLE . " - SET config_value = '" . $this->convert_phpbb30_timezone($this->config['board_timezone'], $this->config['board_dst']) . "' - WHERE config_name = 'board_timezone'"; - $this->sql_query($sql); - - // After we have calculated the timezones we can delete user_dst column from user table. - $this->db_tools->sql_column_remove(USERS_TABLE, 'user_dst'); - } - - /** - * Determine the new timezone for a given phpBB 3.0 timezone and - * "Daylight Saving Time" option - * - * @param $timezone float Users timezone in 3.0 - * @param $dst int Users daylight saving time - * @return string Users new php Timezone which is used since 3.1 - */ - public function convert_phpbb30_timezone($timezone, $dst) - { - $offset = $timezone + $dst; - - switch ($timezone) - { - case '-12': - return 'Etc/GMT+' . abs($offset); //'[UTC - 12] Baker Island Time' - case '-11': - return 'Etc/GMT+' . abs($offset); //'[UTC - 11] Niue Time, Samoa Standard Time' - case '-10': - return 'Etc/GMT+' . abs($offset); //'[UTC - 10] Hawaii-Aleutian Standard Time, Cook Island Time' - case '-9.5': - return 'Pacific/Marquesas'; //'[UTC - 9:30] Marquesas Islands Time' - case '-9': - return 'Etc/GMT+' . abs($offset); //'[UTC - 9] Alaska Standard Time, Gambier Island Time' - case '-8': - return 'Etc/GMT+' . abs($offset); //'[UTC - 8] Pacific Standard Time' - case '-7': - return 'Etc/GMT+' . abs($offset); //'[UTC - 7] Mountain Standard Time' - case '-6': - return 'Etc/GMT+' . abs($offset); //'[UTC - 6] Central Standard Time' - case '-5': - return 'Etc/GMT+' . abs($offset); //'[UTC - 5] Eastern Standard Time' - case '-4.5': - return 'America/Caracas'; //'[UTC - 4:30] Venezuelan Standard Time' - case '-4': - return 'Etc/GMT+' . abs($offset); //'[UTC - 4] Atlantic Standard Time' - case '-3.5': - return 'America/St_Johns'; //'[UTC - 3:30] Newfoundland Standard Time' - case '-3': - return 'Etc/GMT+' . abs($offset); //'[UTC - 3] Amazon Standard Time, Central Greenland Time' - case '-2': - return 'Etc/GMT+' . abs($offset); //'[UTC - 2] Fernando de Noronha Time, South Georgia & the South Sandwich Islands Time' - case '-1': - return 'Etc/GMT+' . abs($offset); //'[UTC - 1] Azores Standard Time, Cape Verde Time, Eastern Greenland Time' - case '0': - return (!$dst) ? 'UTC' : 'Etc/GMT-1'; //'[UTC] Western European Time, Greenwich Mean Time' - case '1': - return 'Etc/GMT-' . $offset; //'[UTC + 1] Central European Time, West African Time' - case '2': - return 'Etc/GMT-' . $offset; //'[UTC + 2] Eastern European Time, Central African Time' - case '3': - return 'Etc/GMT-' . $offset; //'[UTC + 3] Moscow Standard Time, Eastern African Time' - case '3.5': - return 'Asia/Tehran'; //'[UTC + 3:30] Iran Standard Time' - case '4': - return 'Etc/GMT-' . $offset; //'[UTC + 4] Gulf Standard Time, Samara Standard Time' - case '4.5': - return 'Asia/Kabul'; //'[UTC + 4:30] Afghanistan Time' - case '5': - return 'Etc/GMT-' . $offset; //'[UTC + 5] Pakistan Standard Time, Yekaterinburg Standard Time' - case '5.5': - return 'Asia/Kolkata'; //'[UTC + 5:30] Indian Standard Time, Sri Lanka Time' - case '5.75': - return 'Asia/Kathmandu'; //'[UTC + 5:45] Nepal Time' - case '6': - return 'Etc/GMT-' . $offset; //'[UTC + 6] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time' - case '6.5': - return 'Indian/Cocos'; //'[UTC + 6:30] Cocos Islands Time, Myanmar Time' - case '7': - return 'Etc/GMT-' . $offset; //'[UTC + 7] Indochina Time, Krasnoyarsk Standard Time' - case '8': - return 'Etc/GMT-' . $offset; //'[UTC + 8] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time' - case '8.75': - return 'Australia/Eucla'; //'[UTC + 8:45] Southeastern Western Australia Standard Time' - case '9': - return 'Etc/GMT-' . $offset; //'[UTC + 9] Japan Standard Time, Korea Standard Time, Chita Standard Time' - case '9.5': - return 'Australia/ACT'; //'[UTC + 9:30] Australian Central Standard Time' - case '10': - return 'Etc/GMT-' . $offset; //'[UTC + 10] Australian Eastern Standard Time, Vladivostok Standard Time' - case '10.5': - return 'Australia/Lord_Howe'; //'[UTC + 10:30] Lord Howe Standard Time' - case '11': - return 'Etc/GMT-' . $offset; //'[UTC + 11] Solomon Island Time, Magadan Standard Time' - case '11.5': - return 'Pacific/Norfolk'; //'[UTC + 11:30] Norfolk Island Time' - case '12': - return 'Etc/GMT-12'; //'[UTC + 12] New Zealand Time, Fiji Time, Kamchatka Standard Time' - case '12.75': - return 'Pacific/Chatham'; //'[UTC + 12:45] Chatham Islands Time' - case '13': - return 'Pacific/Tongatapu'; //'[UTC + 13] Tonga Time, Phoenix Islands Time' - case '14': - return 'Pacific/Kiritimati'; //'[UTC + 14] Line Island Time' - default: - return 'UTC'; - } - } -} From e9bcea5d82fd086ebcf7634ab386623f34ea8d03 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 8 Jan 2013 22:22:44 -0600 Subject: [PATCH 28/90] [feature/migrations] Restore update_helpers.php file This should be removed by the data branch PHPBB3-9737 --- phpBB/includes/update_helpers.php | 112 ++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 phpBB/includes/update_helpers.php diff --git a/phpBB/includes/update_helpers.php b/phpBB/includes/update_helpers.php new file mode 100644 index 0000000000..69d678b2f8 --- /dev/null +++ b/phpBB/includes/update_helpers.php @@ -0,0 +1,112 @@ + Date: Wed, 9 Jan 2013 14:27:01 -0600 Subject: [PATCH 29/90] [feature/migrations] Fixing returns of callables and handling data state Lots of comments and some other miscellaneous fixes. PHPBB3-9737 --- phpBB/includes/db/db_tools.php | 1 + phpBB/includes/db/driver/mysqli.php | 1 - phpBB/includes/db/migration/exception.php | 10 + phpBB/includes/db/migration/migration.php | 35 +++- phpBB/includes/db/migration/tool/config.php | 40 ++-- .../includes/db/migration/tool/interface.php | 5 + phpBB/includes/db/migration/tool/module.php | 177 +++++++++--------- .../includes/db/migration/tool/permission.php | 106 ++++++----- phpBB/includes/db/migrator.php | 158 ++++++++++++---- 9 files changed, 329 insertions(+), 204 deletions(-) diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index 5329d871c8..1d6823d37a 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -349,6 +349,7 @@ class phpbb_db_tools * Setter for {@link $return_statements return_statements}. * * @param bool $return_statements True if SQL should not be executed but returned as strings + * @return null */ public function set_return_statements($return_statements) { diff --git a/phpBB/includes/db/driver/mysqli.php b/phpBB/includes/db/driver/mysqli.php index 94921a22b7..7448bf1670 100644 --- a/phpBB/includes/db/driver/mysqli.php +++ b/phpBB/includes/db/driver/mysqli.php @@ -24,7 +24,6 @@ if (!defined('IN_PHPBB')) class phpbb_db_driver_mysqli extends phpbb_db_driver { var $multi_insert = true; - var $connect_error = ''; /** diff --git a/phpBB/includes/db/migration/exception.php b/phpBB/includes/db/migration/exception.php index 19fb39ab23..bd46a4e064 100644 --- a/phpBB/includes/db/migration/exception.php +++ b/phpBB/includes/db/migration/exception.php @@ -22,8 +22,15 @@ if (!defined('IN_PHPBB')) */ class phpbb_db_migration_exception extends \Exception { + /** @var array Extra parameters sent to exception to aid in debugging */ protected $parameters; + /** + * Throw an exception. + * + * First argument is the error message. + * Additional arguments will be output with the error message. + */ public function __construct() { $parameters = func_get_args(); @@ -33,6 +40,9 @@ class phpbb_db_migration_exception extends \Exception $this->parameters = $parameters; } + /** + * Output the error as a string + */ public function __toString() { return $this->message . ': ' . var_export($this->parameters, true); diff --git a/phpBB/includes/db/migration/migration.php b/phpBB/includes/db/migration/migration.php index c2c6da855b..5f1f0443db 100644 --- a/phpBB/includes/db/migration/migration.php +++ b/phpBB/includes/db/migration/migration.php @@ -26,22 +26,41 @@ if (!defined('IN_PHPBB')) */ abstract class phpbb_db_migration { + /** @var phpbb_config */ protected $config; + + /** @var phpbb_db_driver */ protected $db; + + /** @var phpbb_db_tools */ protected $db_tools; + + /** @var string */ protected $table_prefix; + /** @var string */ protected $phpbb_root_path; + + /** @var string */ protected $php_ext; + /** @var array Errors, if any occured */ protected $errors; - private $queries = array(); + /** @var array List of queries executed through $this->sql_query() */ + protected $queries = array(); /** - * Migration constructor + * Constructor + * + * @param phpbb_config $config + * @param phpbb_db_driver $db + * @param phpbb_db_tools $db_tools + * @param string $phpbb_root_path + * @param string $php_ext + * @param string $table_prefix */ - public function __construct($config, phpbb_db_driver $db, $db_tools, $phpbb_root_path, $php_ext, $table_prefix) + public function __construct(phpbb_config $config, phpbb_db_driver $db, phpbb_db_tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix) { $this->config = $config; $this->db = $db; @@ -55,7 +74,7 @@ abstract class phpbb_db_migration } /** - * Defines other migrationsto be applied first (abstract method) + * Defines other migrations to be applied first (abstract method) * * @return array An array of migration class names */ @@ -67,7 +86,7 @@ abstract class phpbb_db_migration /** * Updates the database schema by providing a set of change instructions * - * @return array + * @return array Array of schema changes (compatible with db_tools->perform_schema_changes()) */ public function update_schema() { @@ -77,14 +96,18 @@ abstract class phpbb_db_migration /** * Updates data by returning a list of instructions to be executed * - * @return array + * @return array Array of data update instructions */ public function update_data() { + return array(); } /** * Wrapper for running queries to generate user feedback on updates + * + * @param string $sql SQL query to run on the database + * @return mixed Query result from db->sql_query() */ protected function sql_query($sql) { diff --git a/phpBB/includes/db/migration/tool/config.php b/phpBB/includes/db/migration/tool/config.php index 35fa3ce566..e7239436d2 100644 --- a/phpBB/includes/db/migration/tool/config.php +++ b/phpBB/includes/db/migration/tool/config.php @@ -7,11 +7,21 @@ * */ +/** +* Migration config tool +* +* @package db +*/ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interface { /** @var phpbb_config */ - protected $config = null; + protected $config; + /** + * Constructor + * + * @param phpbb_config $config + */ public function __construct(phpbb_config $config) { $this->config = $config; @@ -26,13 +36,12 @@ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interfac } /** - * Config Add - * - * This function allows you to add a config setting. + * Add a config setting. * * @param string $config_name The name of the config setting you would like to add * @param mixed $config_value The value of the config setting * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. + * @return null */ public function add($config_name, $config_value = '', $is_dynamic = false) { @@ -42,17 +51,14 @@ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interfac } $this->config->set($config_name, $config_value, !$is_dynamic); - - return false; } /** - * Config Update - * - * This function allows you to update an existing config setting. + * Update an existing config setting. * * @param string $config_name The name of the config setting you would like to update * @param mixed $config_value The value of the config setting + * @return null */ public function update($config_name, $config_value = '') { @@ -62,18 +68,15 @@ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interfac } $this->config->set($config_name, $config_value); - - return false; } /** - * Config Update If Equals - * - * This function allows you to update a config setting if the first argument equal to the current config value + * Update a config setting if the first argument equal to the current config value * * @param bool $compare If equal to the current config value, will be updated to the new config value, otherwise not * @param string $config_name The name of the config setting you would like to update * @param mixed $config_value The value of the config setting + * @return null */ public function update_if_equals($compare, $config_name, $config_value = '') { @@ -83,16 +86,13 @@ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interfac } $this->config->set_atomic($config_name, $compare, $config_value); - - return false; } /** - * Config Remove - * - * This function allows you to remove an existing config setting. + * Remove an existing config setting. * * @param string $config_name The name of the config setting you would like to remove + * @return null */ public function remove($config_name) { @@ -102,7 +102,5 @@ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interfac } $this->config->delete($config_name); - - return false; } } diff --git a/phpBB/includes/db/migration/tool/interface.php b/phpBB/includes/db/migration/tool/interface.php index 1815f5e8a2..5d10246ba1 100644 --- a/phpBB/includes/db/migration/tool/interface.php +++ b/phpBB/includes/db/migration/tool/interface.php @@ -7,6 +7,11 @@ * */ +/** +* Migration tool interface +* +* @package db +*/ interface phpbb_db_migration_tool_interface { /** diff --git a/phpBB/includes/db/migration/tool/module.php b/phpBB/includes/db/migration/tool/module.php index a503f08c01..f1b527bf21 100644 --- a/phpBB/includes/db/migration/tool/module.php +++ b/phpBB/includes/db/migration/tool/module.php @@ -7,27 +7,42 @@ * */ +/** +* Migration module management tool +* +* @package db +*/ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interface { /** @var phpbb_cache_service */ - protected $cache = null; + protected $cache; /** @var dbal */ - protected $db = null; + protected $db; /** @var phpbb_user */ - protected $user = null; + protected $user; /** @var string */ - protected $phpbb_root_path = null; + protected $phpbb_root_path; /** @var string */ - protected $php_ext = null; + protected $php_ext; /** @var string */ - protected $modules_table = null; + protected $modules_table; - public function __construct(phpbb_db_driver $db, $cache, $user, $phpbb_root_path, $php_ext, $modules_table) + /** + * Constructor + * + * @param phpbb_db_driver $db + * @param mixed $cache + * @param phpbb_user $user + * @param string $phpbb_root_path + * @param string $php_ext + * @param string $modules_table + */ + public function __construct(phpbb_db_driver $db, phpbb_cache_service $cache, phpbb_user $user, $phpbb_root_path, $php_ext, $modules_table) { $this->db = $db; $this->cache = $cache; @@ -53,7 +68,6 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac * @param string $class The module class(acp|mcp|ucp) * @param int|string|bool $parent The parent module_id|module_langname (0 for no parent). 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 */ public function exists($class, $parent, $module) @@ -64,31 +78,28 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac return true; } - $class = $this->db->sql_escape($class); - $module = $this->db->sql_escape($module); - $parent_sql = ''; if ($parent !== false) { // Allows '' to be sent as 0 - $parent = (!$parent) ? 0 : $parent; + $parent = $parent ?: 0; if (!is_numeric($parent)) { $sql = 'SELECT module_id FROM ' . $this->modules_table . " WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '$class'"; + AND module_class = '" . $this->db->sql_escape($class) . "'"; $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); + $module_id = $this->db->sql_fetchfield('module_id'); $this->db->sql_freeresult($result); - if (!$row) + if (!$module_id) { return false; } - $parent_sql = 'AND parent_id = ' . (int) $row['module_id']; + $parent_sql = 'AND parent_id = ' . (int) $module_id; } else { @@ -98,14 +109,14 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac $sql = 'SELECT module_id FROM ' . $this->modules_table . " - WHERE module_class = '$class' + WHERE module_class = '" . $this->db->sql_escape($class) . "' $parent_sql - AND " . ((is_numeric($module)) ? 'module_id = ' . (int) $module : "module_langname = '$module'"); + AND " . ((is_numeric($module)) ? 'module_id = ' . (int) $module : "module_langname = '" . $this->db->sql_escape($module) . "'"); $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); + $module_id = $this->db->sql_fetchfield('module_id'); $this->db->sql_freeresult($result); - if ($row) + if ($module_id) { return true; } @@ -123,29 +134,30 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac * @param array $data an array of the data on the new module. This can be setup in two different ways. * 1. The "manual" way. For inserting a category or one at a time. It will be merged with the base array shown a bit below, * but at the least requires 'module_langname' to be sent, and, if you want to create a module (instead of just a category) you must send module_basename and module_mode. - * array( - * 'module_enabled' => 1, - * 'module_display' => 1, - * 'module_basename' => '', - * 'module_class' => $class, - * 'parent_id' => (int) $parent, - * 'module_langname' => '', - * 'module_mode' => '', - * 'module_auth' => '', - * ) + * array( + * 'module_enabled' => 1, + * 'module_display' => 1, + * 'module_basename' => '', + * 'module_class' => $class, + * 'parent_id' => (int) $parent, + * 'module_langname' => '', + * 'module_mode' => '', + * 'module_auth' => '', + * ) * 2. The "automatic" way. For inserting multiple at a time based on the specs in the info file for the module(s). For this to work the modules must be correctly setup in the info file. * An example follows (this would insert the settings, log, and flag modes from the includes/acp/info/acp_asacp.php file): - * array( - * 'module_basename' => 'asacp', - * 'modes' => array('settings', 'log', 'flag'), - * ) + * array( + * 'module_basename' => 'asacp', + * 'modes' => array('settings', 'log', 'flag'), + * ) * Optionally you may not send 'modes' and it will insert all of the modules in that info file. - * @param string|bool $include_path If you would like to use a custom include path, specify that here + * @param string|bool $include_path If you would like to use a custom include path, specify that here + * @return null */ public function add($class, $parent = 0, $data = array(), $include_path = false) { - // Allows '' to be sent as 0 - $parent = (!$parent) ? 0 : $parent; + // Allows '' to be sent as 0 + $parent = $parent ?: 0; // allow sending the name as a string in $data to create a category if (!is_array($data)) @@ -155,18 +167,16 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac if (!isset($data['module_langname'])) { - /** - * @TODO does not work with 3.1 modules yet, but must continue for old 3.0 versions for - * upgrades from a 3.0.x version to 3.1 - */ // The "automatic" way $basename = (isset($data['module_basename'])) ? $data['module_basename'] : ''; $basename = str_replace(array('/', '\\'), '', $basename); $class = str_replace(array('/', '\\'), '', $class); + + $include_path = ($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path; $info_file = "$class/info/$basename.{$this->php_ext}"; // The manual and automatic ways both failed... - if (!file_exists((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file)) + if (!file_exists($include_path . $info_file)) { throw new phpbb_db_migration_exception('MODULE_INFO_FILE_NOT_EXIST', $class, $info_file); } @@ -175,7 +185,7 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac if (!class_exists($classname)) { - include((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file); + include($include_path . $info_file); } $info = new $classname; @@ -206,26 +216,25 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac } // The "manual" way - add_log('admin', 'LOG_MODULE_ADD', ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname'])); - - $class = $this->db->sql_escape($class); + $module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']); + add_log('admin', 'LOG_MODULE_ADD', $module_log_name); if (!is_numeric($parent)) { $sql = 'SELECT module_id FROM ' . $this->modules_table . " WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '$class'"; + AND module_class = '" . $this->db->sql_escape($class) . "'"; $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); + $module_id = $this->db->sql_fetchfield('module_id'); $this->db->sql_freeresult($result); - if (!$row) + if (!$module_id) { throw new phpbb_db_migration_exception('MODULE_PARENT_NOT_EXIST', $parent); } - $parent = $data['parent_id'] = $row['module_id']; + $parent = $data['parent_id'] = $module_id; } else if (!$this->exists($class, false, $parent)) { @@ -270,46 +279,46 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac if (isset($data['before']) && $data['before']) { $sql = 'SELECT left_id - FROM ' . $this->modules_table . ' - WHERE module_class = \'' . $class . '\' - AND parent_id = ' . (int) $parent . ' - AND module_langname = \'' . $this->db->sql_escape($data['before']) . '\''; + 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 = $this->db->sql_fetchfield('left_id'); + $to_left = (int) $this->db->sql_fetchfield('left_id'); $sql = 'UPDATE ' . $this->modules_table . " SET left_id = left_id + 2, right_id = right_id + 2 - WHERE module_class = '$class' + 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); $sql = 'UPDATE ' . $this->modules_table . " SET left_id = $to_left, right_id = " . ($to_left + 1) . " - WHERE module_class = '$class' + 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 - FROM ' . $this->modules_table . ' - WHERE module_class = \'' . $class . '\' - AND parent_id = ' . (int) $parent . ' - AND module_langname = \'' . $this->db->sql_escape($data['after']) . '\''; + 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 = $this->db->sql_fetchfield('right_id'); + $to_right = (int) $this->db->sql_fetchfield('right_id'); $sql = 'UPDATE ' . $this->modules_table . " SET left_id = left_id + 2, right_id = right_id + 2 - WHERE module_class = '$class' + 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); $sql = 'UPDATE ' . $this->modules_table . ' SET left_id = ' . ($to_right + 1) . ', right_id = ' . ($to_right + 2) . " - WHERE module_class = '$class' + WHERE module_class = '" . $this->db->sql_escape($class) . "' AND module_id = {$module_data['module_id']}"; $this->db->sql_query($sql); } @@ -317,8 +326,6 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac // Clear the Modules Cache $this->cache->destroy("_modules_$class"); - - return false; } /** @@ -330,6 +337,7 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac * @param int|string|bool $parent The parent module_id|module_langname (0 for no parent). Use false to ignore the parent check and check class wide. * @param int|string $module The module id|module_langname * @param string|bool $include_path If you would like to use a custom include path, specify that here + * @return null */ public function remove($class, $parent = 0, $module = '', $include_path = false) { @@ -351,9 +359,11 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac // Automatic method $basename = str_replace(array('/', '\\'), '', $module['module_basename']); $class = str_replace(array('/', '\\'), '', $class); + + $include_path = ($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path; $info_file = "$class/info/$basename.{$this->php_ext}"; - if (!file_exists((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file)) + if (!file_exists($include_path . $info_file)) { throw new phpbb_db_migration_exception('MODULE_NOT_EXIST', $info_file); } @@ -362,7 +372,7 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac if (!class_exists($classname)) { - include((($include_path === false) ? $this->phpbb_root_path . 'includes/' : $include_path) . $info_file); + include($include_path . $info_file); } $info = new $classname; @@ -376,12 +386,9 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac $this->remove($class, $parent, $info['title']) . '
'; } } - return false; } else { - $class = $this->db->sql_escape($class); - if (!$this->exists($class, $parent, $module)) { throw new phpbb_db_migration_exception('MODULE_NOT_EXIST', ((isset($this->user->lang[$module])) ? $this->user->lang[$module] : $module)); @@ -391,20 +398,20 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac if ($parent !== false) { // Allows '' to be sent as 0 - $parent = (!$parent) ? 0 : $parent; + $parent = ($parent) ?: 0; if (!is_numeric($parent)) { $sql = 'SELECT module_id FROM ' . $this->modules_table . " WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '$class'"; + AND module_class = '" . $this->db->sql_escape($class) . "'"; $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); + $module_id = $this->db->sql_fetchfield('module_id'); $this->db->sql_freeresult($result); // we know it exists from the module_exists check - $parent_sql = 'AND parent_id = ' . (int) $row['module_id']; + $parent_sql = 'AND parent_id = ' . (int) $module_id; } else { @@ -415,16 +422,15 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac $module_ids = array(); if (!is_numeric($module)) { - $module = $this->db->sql_escape($module); $sql = 'SELECT module_id FROM ' . $this->modules_table . " - WHERE module_langname = '$module' - AND module_class = '$class' - $parent_sql"; + WHERE module_langname = '" . $this->db->sql_escape($module) . "' + AND module_class = '" . $this->db->sql_escape($class) . "' + $parent_sql"; $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) + while ($module_id = $this->db->sql_fetchfield('module_id')) { - $module_ids[] = (int) $row['module_id']; + $module_ids[] = (int) $module_id; } $this->db->sql_freeresult($result); @@ -436,13 +442,12 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac $sql = 'SELECT module_langname FROM ' . $this->modules_table . " WHERE module_id = $module - AND module_class = '$class' - $parent_sql"; + AND module_class = '" . $this->db->sql_escape($class) . "' + $parent_sql"; $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); + $module_name = $this->db->sql_fetchfield('module_id'); $this->db->sql_freeresult($result); - $module_name = $row['module_langname']; $module_ids[] = $module; } @@ -464,8 +469,6 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac } $this->cache->destroy("_modules_$class"); - - return false; } } } diff --git a/phpBB/includes/db/migration/tool/permission.php b/phpBB/includes/db/migration/tool/permission.php index ebe404bc62..97fdbc0df9 100644 --- a/phpBB/includes/db/migration/tool/permission.php +++ b/phpBB/includes/db/migration/tool/permission.php @@ -7,24 +7,38 @@ * */ +/** +* Migration permission management tool +* +* @package db +*/ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_interface { /** @var phpbb_auth */ - protected $auth = null; + protected $auth; /** @var phpbb_cache_service */ - protected $cache = null; + protected $cache; /** @var dbal */ - protected $db = null; + protected $db; /** @var string */ - protected $phpbb_root_path = null; + protected $phpbb_root_path; /** @var string */ - protected $php_ext = null; + protected $php_ext; - public function __construct(phpbb_db_driver $db, $cache, phpbb_auth $auth, $phpbb_root_path, $php_ext) + /** + * Constructor + * + * @param phpbb_db_driver $db + * @param mixed $cache + * @param phpbb_auth $auth + * @param string $phpbb_root_path + * @param string $php_ext + */ + public function __construct(phpbb_db_driver $db, phpbb_cache_service $cache, phpbb_auth $auth, $phpbb_root_path, $php_ext) { $this->db = $db; $this->cache = $cache; @@ -48,7 +62,6 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte * * @param string $auth_option The name of the permission (auth) option * @param bool $global True for checking a global permission setting, False for a local permission setting - * * @return bool true if it exists, false if not */ public function exists($auth_option, $global = true) @@ -86,8 +99,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte * * @param string $auth_option The name of the permission (auth) option * @param bool $global True for checking a global permission setting, False for a local permission setting - * - * @return result + * @return null */ public function add($auth_option, $global = true, $copy_from = false) { @@ -152,7 +164,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte } $this->db->sql_freeresult($result); - if (sizeof($sql_ary)) + if (!empty($sql_ary)) { $this->db->sql_multi_insert($table, $sql_ary); } @@ -160,8 +172,6 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $auth_admin->acl_clear_prefetch(); } - - return false; } /** @@ -171,8 +181,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte * * @param string $auth_option The name of the permission (auth) option * @param bool $global True for checking a global permission setting, False for a local permission setting - * - * @return result + * @return null */ public function remove($auth_option, $global = true) { @@ -197,7 +206,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $row = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - $id = $row['auth_option_id']; + $id = (int) $row['auth_option_id']; // If it is a local and global permission, do not remove the row! :P if ($row['is_global'] && $row['is_local']) @@ -210,17 +219,17 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte else { // Delete time - $this->db->sql_query('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $id); - $this->db->sql_query('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $id); - $this->db->sql_query('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $id); - $this->db->sql_query('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $id); + $tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE, ACL_OPTIONS_TABLE); + foreach ($tables as $table) + { + $this->db->sql_query('DELETE FROM ' . $table . ' + WHERE auth_option_id = ' . $id); + } } // Purge the auth cache $this->cache->destroy('_acl_options'); $this->auth->acl_clear_prefetch(); - - return false; } /** @@ -228,6 +237,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte * * @param string $role_name The new role name * @param sting $role_type The type (u_, m_, a_) + * @return null */ public function role_add($role_name, $role_type = '', $role_description = '') { @@ -235,18 +245,18 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte FROM ' . ACL_ROLES_TABLE . " WHERE role_name = '" . $this->db->sql_escape($role_name) . "'"; $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('role_id'); + $role_id = (int) $this->db->sql_fetchfield('role_id'); if ($role_id) { throw new phpbb_db_migration_exception('ROLE_ALREADY_EXISTS', $old_role_name); } - $sql = 'SELECT MAX(role_order) AS max + $sql = 'SELECT MAX(role_order) AS max_role_order FROM ' . ACL_ROLES_TABLE . " WHERE role_type = '" . $this->db->sql_escape($role_type) . "'"; $this->db->sql_query($sql); - $role_order = $this->db->sql_fetchfield('max'); + $role_order = (int) $this->db->sql_fetchfield('max_role_order'); $role_order = (!$role_order) ? 1 : $role_order + 1; $sql_ary = array( @@ -258,8 +268,6 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); $this->db->sql_query($sql); - - return false; } /** @@ -267,6 +275,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte * * @param string $old_role_name The old role name * @param string $new_role_name The new role name + * @return null */ public function role_update($old_role_name, $new_role_name = '') { @@ -274,7 +283,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte FROM ' . ACL_ROLES_TABLE . " WHERE role_name = '" . $this->db->sql_escape($old_role_name) . "'"; $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('role_id'); + $role_id = (int) $this->db->sql_fetchfield('role_id'); if (!$role_id) { @@ -285,14 +294,13 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte SET role_name = '" . $this->db->sql_escape($new_role_name) . "' WHERE role_name = '" . $this->db->sql_escape($old_role_name) . "'"; $this->db->sql_query($sql); - - return false; } /** * Remove a permission role * * @param string $role_name The role name to remove + * @return null */ public function role_remove($role_name) { @@ -300,7 +308,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte FROM ' . ACL_ROLES_TABLE . " WHERE role_name = '" . $this->db->sql_escape($role_name) . "'"; $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('role_id'); + $role_id = (int) $this->db->sql_fetchfield('role_id'); if (!$role_id) { @@ -316,8 +324,6 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $this->db->sql_query($sql); $this->auth->acl_clear_prefetch(); - - return false; } /** @@ -329,6 +335,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte * @param string|array $auth_option The auth_option or array of auth_options you would like to set * @param string $type The type (role|group) * @param bool $has_permission True if you want to give them permission, false if you want to deny them permission + * @return null */ public function permission_set($name, $auth_option = array(), $type = 'role', $has_permission = true) { @@ -344,13 +351,13 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - $new_auth[] = $row['auth_option_id']; + $new_auth[] = (int) $row['auth_option_id']; } $this->db->sql_freeresult($result); - if (!sizeof($new_auth)) + if (empty($new_auth)) { - return false; + return; } $current_auth = array(); @@ -364,7 +371,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte FROM ' . ACL_ROLES_TABLE . " WHERE role_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('role_id'); + $role_id = (int) $this->db->sql_fetchfield('role_id'); if (!$role_id) { @@ -387,7 +394,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte FROM ' . GROUPS_TABLE . " WHERE group_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); - $group_id = $this->db->sql_fetchfield('group_id'); + $group_id = (int) $this->db->sql_fetchfield('group_id'); if (!$group_id) { @@ -401,7 +408,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte AND auth_role_id <> 0 AND forum_id = 0'; $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('auth_role_id'); + $role_id = (int) $this->db->sql_fetchfield('auth_role_id'); if ($role_id) { $sql = 'SELECT role_name @@ -437,7 +444,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte 'role_id' => $role_id, 'auth_option_id' => $auth_option_id, 'auth_setting' => $has_permission, - ); + ); } } @@ -453,7 +460,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte 'group_id' => $group_id, 'auth_option_id' => $auth_option_id, 'auth_setting' => $has_permission, - ); + ); } } @@ -462,8 +469,6 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte } $this->auth->acl_clear_prefetch(); - - return false; } /** @@ -474,6 +479,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte * @param string $name The name of the role/group * @param string|array $auth_option The auth_option or array of auth_options you would like to set * @param string $type The type (role|group) + * @return null */ public function permission_unset($name, $auth_option = array(), $type = 'role') { @@ -489,13 +495,13 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - $to_remove[] = $row['auth_option_id']; + $to_remove[] = (int) $row['auth_option_id']; } $this->db->sql_freeresult($result); - if (!sizeof($to_remove)) + if (empty($to_remove)) { - return false; + return; } $type = (string) $type; // Prevent PHP bug. @@ -507,11 +513,11 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte FROM ' . ACL_ROLES_TABLE . " WHERE role_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('role_id'); + $role_id = (int) $this->db->sql_fetchfield('role_id'); if (!$role_id) { - throw new phpbb_db_migration_exception('ROLE_NOT_EXIST', $name); + throw new phpbb_db_migration_exception('ROLE_NOT_EXIST', $name); } $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' @@ -524,7 +530,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte FROM ' . GROUPS_TABLE . " WHERE group_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); - $group_id = $this->db->sql_fetchfield('group_id'); + $group_id = (int) $this->db->sql_fetchfield('group_id'); if (!$group_id) { @@ -537,7 +543,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte WHERE group_id = ' . $group_id . ' AND auth_role_id <> 0'; $this->db->sql_query($sql); - $role_id = $this->db->sql_fetchfield('auth_role_id'); + $role_id = (int) $this->db->sql_fetchfield('auth_role_id'); if ($role_id) { $sql = 'SELECT role_name @@ -556,7 +562,5 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte } $this->auth->acl_clear_prefetch(); - - return false; } } diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 2fd795b659..2ba1eba427 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -22,26 +22,40 @@ if (!defined('IN_PHPBB')) */ class phpbb_db_migrator { + /** @var phpbb_config */ protected $config; + + /** @var phpbb_db_driver */ protected $db; + + /** @var phpbb_db_tools */ protected $db_tools; + + /** @var string */ protected $table_prefix; + /** @var string */ protected $phpbb_root_path; + + /** @var string */ protected $php_ext; + /** @var string */ protected $migrations_table; + + /** @var array State of all migrations (SELECT * FROM migrations table) */ protected $migration_state; + /** @var array Array of all migrations available to be run */ protected $migrations = array(); - /** @var string Name of the last migration run */ + /** @var array 'name' and 'class' of the last migration run */ public $last_run_migration = false; /** * Constructor of the database migrator */ - public function __construct($config, phpbb_db_driver $db, $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools) + public function __construct(phpbb_config $config, phpbb_db_driver $db, phpbb_db_tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools) { $this->config = $config; $this->db = $db; @@ -96,17 +110,42 @@ class phpbb_db_migrator /** * Load migration data files from a directory * - * @param string $path + * This does not loop through sub-directories. + * Migration data files loaded with this function MUST contain + * ONLY ONE class in them (or an exception will be thrown). + * + * @param string $path Path to migration data files + * @param bool $check_fulfillable If TRUE (default), we will check + * if all of the migrations are fulfillable after loading them. + * If FALSE, we will not check. You SHOULD check at least once + * to prevent errors (if including multiple directories, check + * with the last call to prevent throwing errors unnecessarily). * @return array Array of migrations with names */ - public function load_migrations($path) + public function load_migrations($path, $check_fulfillable = true) { $handle = opendir($path); while (($file = readdir($handle)) !== false) { if (strpos($file, '_') !== 0 && strrpos($file, '.' . $this->php_ext) === (strlen($file) - strlen($this->php_ext) - 1)) { - $name = 'phpbb_db_migration_data_' . substr($file, 0, -(strlen($this->php_ext) + 1)); + // We try to find what class existed by comparing the classes declared before and after including the file. + $declared_classes = get_declared_classes(); + + include ($path . $file); + + $added_classes = array_diff(get_declared_classes(), $declared_classes); + + if ( + // The phpbb_db_migrations class may not have been loaded until now, so make sure to ignore it. + !(sizeof($added_classes) == 2 && in_array('phpbb_db_migration', $added_classes)) && + sizeof($added_classes) != 1 + ) + { + throw new phpbb_db_migration_exception('MIGRATION DATA FILE INVALID', $path . $file); + } + + $name = array_pop($added_classes); if (!in_array($name, $this->migrations)) { @@ -115,11 +154,14 @@ class phpbb_db_migrator } } - foreach ($this->migrations as $name) + if ($check_fulfillable) { - if ($this->unfulfillable($name)) + foreach ($this->migrations as $name) { - throw new phpbb_db_migration_exception('MIGRATION NOT FULFILLABLE', $name); + if ($this->unfulfillable($name)) + { + throw new phpbb_db_migration_exception('MIGRATION NOT FULFILLABLE', $name); + } } } @@ -131,6 +173,8 @@ class phpbb_db_migrator * * The update step can either be a schema or a (partial) data update. To * check if update() needs to be called again use the finished() method. + * + * @return null */ public function update() { @@ -207,9 +251,11 @@ class phpbb_db_migrator } else { - $this->process_data_step($migration); - $state['migration_data_done'] = true; - $state['migration_end_time'] = time(); + $state = $this->process_data_step($migration); + + $state['migration_data_state'] = $state; + $state['migration_data_done'] = ($state === true); + $state['migration_end_time'] = ($state === true) ? time() : 0; } $sql = 'UPDATE ' . $this->migrations_table . ' @@ -222,41 +268,74 @@ class phpbb_db_migrator return true; } + /** + * Apply schema changes from a migration + * + * Just calls db_tools->perform_schema_changes + * + * @param array $schema_changes from migration + */ + protected function apply_schema_changes($schema_changes) + { + $this->db_tools->perform_schema_changes($schema_changes); + } + + /** + * Process the data step of the migration + * + * @param phpbb_db_migration $migration + * @return mixed migration status or bool true if everything completed successfully + */ protected function process_data_step($migration) { - //$continue = false; $steps = $migration->update_data(); foreach ($steps as $step) { - $continue = $this->run_step($step); - - /*if ($continue === false) + try { - return false; - }*/ + // Result will be null or true if everything completed correctly + $result = $this->run_step($step); + if ($result !== null && $result !== true) + { + return $result; + } + } + catch (phpbb_db_migration_exception $e) + { + // We should try rolling back here + + echo $e; + die(); + } } - //return $continue; + return true; } + /** + * Run a single step + * + * An exception should be thrown if an error occurs + * + * @param mixed $step + * @return null + */ protected function run_step($step) { - try - { - $callable_and_parameters = $this->get_callable_from_step($step); - $callable = $callable_and_parameters[0]; - $parameters = $callable_and_parameters[1]; + $callable_and_parameters = $this->get_callable_from_step($step); + $callable = $callable_and_parameters[0]; + $parameters = $callable_and_parameters[1]; - return call_user_func_array($callable, $parameters); - } - catch (phpbb_db_migration_exception $e) - { - echo $e; - die(); - } + return call_user_func_array($callable, $parameters); } + /** + * Get a callable statement from a data step + * + * @param mixed $step Data step from migration + * @return array Array with parameters for call_user_func_array(), 0 is the callable, 1 is parameters + */ public function get_callable_from_step($step) { $type = $step[0]; @@ -291,6 +370,7 @@ class phpbb_db_migrator $callable_and_parameters = $this->get_callable_from_step($step); $callable = $callable_and_parameters[0]; $sub_parameters = $callable_and_parameters[1]; + return array( function ($condition) use ($callable, $sub_parameters) { return call_user_func_array($callable, $sub_parameters); @@ -325,12 +405,19 @@ class phpbb_db_migrator return array( array($this->tools[$class], $method), - $parameters + $parameters, ); break; } } + /** + * Insert migration row into the database + * + * @param string $name Name of the migration + * @param array $state + * @return null + */ protected function insert_migration($name, $state) { $migration_row = $state; @@ -346,8 +433,8 @@ class phpbb_db_migrator /** * Checks if a migration's dependencies can even theoretically be satisfied. * - * @param string $name The class name of the migration - * @return bool Whether the migration cannot be fulfilled + * @param string $name The class name of the migration + * @return bool Whether the migration cannot be fulfilled */ public function unfulfillable($name) { @@ -406,11 +493,6 @@ class phpbb_db_migrator return true; } - protected function apply_schema_changes($schema_changes) - { - $this->db_tools->perform_schema_changes($schema_changes); - } - /** * Helper to get a migration * From edf693e3bd4352ab75c62311b34f12fc98e7ef63 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 9 Jan 2013 15:28:08 -0600 Subject: [PATCH 30/90] [feature/migrations] Store state properly and send past result to callable Fix return on module add PHPBB3-9737 --- phpBB/includes/db/migration/tool/module.php | 4 +- phpBB/includes/db/migrator.php | 56 +++++++++++++++------ 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/phpBB/includes/db/migration/tool/module.php b/phpBB/includes/db/migration/tool/module.php index f1b527bf21..70a246849a 100644 --- a/phpBB/includes/db/migration/tool/module.php +++ b/phpBB/includes/db/migration/tool/module.php @@ -208,11 +208,11 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac ); // Run the "manual" way with the data we've collected. - $result .= ((isset($data['spacer'])) ? $data['spacer'] : '
') . $this->add($class, $parent, $new_module); + $this->add($class, $parent, $new_module); } } - return $result; + return; } // The "manual" way diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 2ba1eba427..7aa4cfa719 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -251,11 +251,11 @@ class phpbb_db_migrator } else { - $state = $this->process_data_step($migration); + $result = $this->process_data_step($migration, $state['migration_data_state']); - $state['migration_data_state'] = $state; - $state['migration_data_done'] = ($state === true); - $state['migration_end_time'] = ($state === true) ? time() : 0; + $state['migration_data_state'] = ($result === true) ? '' : $result; + $state['migration_data_done'] = ($result === true); + $state['migration_end_time'] = ($result === true) ? time() : 0; } $sql = 'UPDATE ' . $this->migrations_table . ' @@ -284,27 +284,50 @@ class phpbb_db_migrator * Process the data step of the migration * * @param phpbb_db_migration $migration - * @return mixed migration status or bool true if everything completed successfully + * @param bool|string $state Current state of the migration + * @return bool|string migration state. True if completed, serialized array if not finished */ - protected function process_data_step($migration) + protected function process_data_step($migration, $state) { + $state = ($state) ? unserialize($state) : false; + $steps = $migration->update_data(); foreach ($steps as $step) { + $last_result = false; + if ($state) + { + // Continue until we reach the step that matches the last step called + if ($state['step'] != $step) + { + continue; + } + + // We send the result from last time to the callable function + $last_result = $state['result']; + + // Set state to false since we reached the point we were at + $state = false; + } + try { // Result will be null or true if everything completed correctly - $result = $this->run_step($step); + $result = $this->run_step($step, $last_result); if ($result !== null && $result !== true) { - return $result; + return serialize(array( + 'result' => $result, + 'step' => $step, + )); } } catch (phpbb_db_migration_exception $e) { // We should try rolling back here + var_dump($step); echo $e; die(); } @@ -318,12 +341,13 @@ class phpbb_db_migrator * * An exception should be thrown if an error occurs * - * @param mixed $step + * @param mixed $step Data step from migration + * @param mixed $last_result Result to pass to the callable (only for 'custom' method) * @return null */ - protected function run_step($step) + protected function run_step($step, $last_result = false) { - $callable_and_parameters = $this->get_callable_from_step($step); + $callable_and_parameters = $this->get_callable_from_step($step, $last_result); $callable = $callable_and_parameters[0]; $parameters = $callable_and_parameters[1]; @@ -334,9 +358,10 @@ class phpbb_db_migrator * Get a callable statement from a data step * * @param mixed $step Data step from migration + * @param mixed $last_result Result to pass to the callable (only for 'custom' method) * @return array Array with parameters for call_user_func_array(), 0 is the callable, 1 is parameters */ - public function get_callable_from_step($step) + public function get_callable_from_step($step, $last_result = false) { $type = $step[0]; $parameters = $step[1]; @@ -375,7 +400,7 @@ class phpbb_db_migrator function ($condition) use ($callable, $sub_parameters) { return call_user_func_array($callable, $sub_parameters); }, - array($condition) + array($condition), ); break; case 'custom': @@ -384,7 +409,10 @@ class phpbb_db_migrator throw new phpbb_db_migration_exception('MIGRATION_INVALID_DATA_CUSTOM_NOT_CALLABLE', $step); } - return array($parameters[0], array()); + return array( + $parameters[0], + array($last_result), + ); break; default: From f56e400cd36b6d17ffde90a91e6e221cb83d2dbd Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 9 Jan 2013 15:41:04 -0600 Subject: [PATCH 31/90] [feature/migrations] Comments PHPBB3-9737 --- .../includes/db/migration/tool/permission.php | 12 ++++---- phpBB/includes/db/migrator.php | 28 +++++++++++++++---- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/phpBB/includes/db/migration/tool/permission.php b/phpBB/includes/db/migration/tool/permission.php index 97fdbc0df9..7b45b24361 100644 --- a/phpBB/includes/db/migration/tool/permission.php +++ b/phpBB/includes/db/migration/tool/permission.php @@ -366,7 +366,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte switch ($type) { - case 'role' : + case 'role': $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . " WHERE role_name = '" . $this->db->sql_escape($name) . "'"; @@ -389,7 +389,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $this->db->sql_freeresult($result); break; - case 'group' : + case 'group': $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = '" . $this->db->sql_escape($name) . "'"; @@ -435,7 +435,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $sql_ary = array(); switch ($type) { - case 'role' : + case 'role': foreach ($new_auth as $auth_option_id) { if (!isset($current_auth[$auth_option_id])) @@ -451,7 +451,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $this->db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); break; - case 'group' : + case 'group': foreach ($new_auth as $auth_option_id) { if (!isset($current_auth[$auth_option_id])) @@ -508,7 +508,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte switch ($type) { - case 'role' : + case 'role': $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . " WHERE role_name = '" . $this->db->sql_escape($name) . "'"; @@ -525,7 +525,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $this->db->sql_query($sql); break; - case 'group' : + case 'group': $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = '" . $this->db->sql_escape($name) . "'"; diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 7aa4cfa719..5d8dc12f58 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -43,13 +43,27 @@ class phpbb_db_migrator /** @var string */ protected $migrations_table; - /** @var array State of all migrations (SELECT * FROM migrations table) */ - protected $migration_state; + /** + * State of all migrations + * + * (SELECT * FROM migrations table) + * + * @var array + */ + protected $migration_state = array(); - /** @var array Array of all migrations available to be run */ + /** + * Array of all migrations available to be run + * + * @var array + */ protected $migrations = array(); - /** @var array 'name' and 'class' of the last migration run */ + /** + * 'name' and 'class' of the last migration run + * + * @var array + */ public $last_run_migration = false; /** @@ -83,11 +97,12 @@ class phpbb_db_migrator */ public function load_migration_state() { + $this->migration_state = array(); + $sql = "SELECT * FROM " . $this->migrations_table; $result = $this->db->sql_query($sql); - $this->migration_state = array(); while ($migration = $this->db->sql_fetchrow($result)) { $this->migration_state[$migration['migration_name']] = $migration; @@ -137,8 +152,9 @@ class phpbb_db_migrator $added_classes = array_diff(get_declared_classes(), $declared_classes); if ( - // The phpbb_db_migrations class may not have been loaded until now, so make sure to ignore it. + // If two classes have been added and phpbb_db_migration is one of them, we've only added one real migration !(sizeof($added_classes) == 2 && in_array('phpbb_db_migration', $added_classes)) && + // Otherwise there should only be one class added sizeof($added_classes) != 1 ) { From 445667a62e80c42b5406c981d1116ef99a23df3b Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 9 Jan 2013 16:31:56 -0600 Subject: [PATCH 32/90] [feature/migrations] Fix if method (and create a test for it) PHPBB3-9737 --- phpBB/includes/db/migrator.php | 20 ++++++++++---- tests/dbal/migration/dummy.php | 14 +--------- tests/dbal/migration/if.php | 49 ++++++++++++++++++++++++++++++++++ tests/dbal/migrator_test.php | 35 +++++++++++++++++++----- 4 files changed, 94 insertions(+), 24 deletions(-) create mode 100644 tests/dbal/migration/if.php diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 5d8dc12f58..1042b767e8 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -364,6 +364,12 @@ class phpbb_db_migrator protected function run_step($step, $last_result = false) { $callable_and_parameters = $this->get_callable_from_step($step, $last_result); + + if ($callable_and_parameters === false) + { + return; + } + $callable = $callable_and_parameters[0]; $parameters = $callable_and_parameters[1]; @@ -377,7 +383,7 @@ class phpbb_db_migrator * @param mixed $last_result Result to pass to the callable (only for 'custom' method) * @return array Array with parameters for call_user_func_array(), 0 is the callable, 1 is parameters */ - public function get_callable_from_step($step, $last_result = false) + protected function get_callable_from_step($step, $last_result = false) { $type = $step[0]; $parameters = $step[1]; @@ -406,6 +412,12 @@ class phpbb_db_migrator } $condition = $parameters[0]; + + if (!$condition) + { + return false; + } + $step = $parameters[1]; $callable_and_parameters = $this->get_callable_from_step($step); @@ -413,10 +425,8 @@ class phpbb_db_migrator $sub_parameters = $callable_and_parameters[1]; return array( - function ($condition) use ($callable, $sub_parameters) { - return call_user_func_array($callable, $sub_parameters); - }, - array($condition), + $callable, + $sub_parameters, ); break; case 'custom': diff --git a/tests/dbal/migration/dummy.php b/tests/dbal/migration/dummy.php index 942c499bb5..e542493f9f 100644 --- a/tests/dbal/migration/dummy.php +++ b/tests/dbal/migration/dummy.php @@ -19,21 +19,9 @@ class phpbb_dbal_migration_dummy extends phpbb_db_migration return array( 'add_columns' => array( 'phpbb_config' => array( - 'extra_column' => array('UINT', 0), + 'extra_column' => array('UINT', 1), ), ), ); } - - function update_data() - { - return array( - array('if', array(true, array('custom', array(array($this, 'set_extra_column'))))), - ); - } - - public function set_extra_column() - { - $this->sql_query('UPDATE phpbb_config SET extra_column = 1'); - } } diff --git a/tests/dbal/migration/if.php b/tests/dbal/migration/if.php new file mode 100644 index 0000000000..aa9a5dab87 --- /dev/null +++ b/tests/dbal/migration/if.php @@ -0,0 +1,49 @@ +migrator = new phpbb_db_migrator($this->config, $this->db, $this->db_tools, 'phpbb_migrations', dirname(__FILE__) . '/../../phpBB/', 'php', 'phpbb_', $tools); } - public function tearDown() - { - // cleanup - $this->db_tools->sql_column_remove('phpbb_config', 'extra_column'); - } - public function test_update() { $this->migrator->set_migrations(array('phpbb_dbal_migration_dummy')); @@ -85,6 +80,9 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case AND migration_end_time <= " . (time() + 1), 'End time set correctly' ); + + // cleanup + $this->db_tools->sql_column_remove('phpbb_config', 'extra_column'); } public function test_unfulfillable() @@ -104,4 +102,29 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case 'Dummy migration was run, even though an unfulfillable migration was found.' ); } + + public function test_if() + { + $this->migrator->set_migrations(array('phpbb_dbal_migration_if')); + + // Don't like this, but I'm not sure there is any other way to do this + global $migrator_test_if_true_failed, $migrator_test_if_false_failed; + $migrator_test_if_true_failed = true; + $migrator_test_if_false_failed = false; + + while (!$this->migrator->finished()) + { + $this->migrator->update(); + } + + if ($migrator_test_if_true_failed) + { + $this->fail('True test failed'); + } + + if ($migrator_test_if_false_failed) + { + $this->fail('False test failed'); + } + } } From 5f9e1f1e89f8df5420fd82b5256a461de0f98604 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 9 Jan 2013 16:56:26 -0600 Subject: [PATCH 33/90] [feature/migrations] Make sure the path sent to load_migrations is a directory Prevent a lot++ of errors PHPBB3-9737 --- phpBB/includes/db/migrator.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 1042b767e8..359c34bf5d 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -139,6 +139,11 @@ class phpbb_db_migrator */ public function load_migrations($path, $check_fulfillable = true) { + if (!is_dir($path)) + { + throw new phpbb_db_migration_exception('DIRECTORY INVALID', $path); + } + $handle = opendir($path); while (($file = readdir($handle)) !== false) { From 79818c2139c305147d53ffb7217bec7568ff8b9c Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 9 Jan 2013 17:20:12 -0600 Subject: [PATCH 34/90] [feature/migrations] Stop the update process if we are approaching time limit PHPBB3-9737 --- phpBB/test.php | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/phpBB/test.php b/phpBB/test.php index 5887c08d2f..ed4c1928ee 100644 --- a/phpBB/test.php +++ b/phpBB/test.php @@ -7,6 +7,8 @@ * */ +$update_start_time = time(); + use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; @@ -42,18 +44,6 @@ set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handle $phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", ".$phpEx"); $phpbb_class_loader->register(); -/*$phpbb_container = phpbb_create_container( - array( - new phpbb_di_extension_config($phpbb_root_path . 'config.' . $phpEx), - new phpbb_di_extension_core($phpbb_root_path), - ), - array( - new phpbb_di_pass_collection_pass(), - new phpbb_di_pass_kernel_pass(), - ), - $phpbb_root_path, $phpEx); -$phpbb_container->compile();*/ - // Set up container $container_extensions = array( new phpbb_di_extension_config($phpbb_root_path . 'config.' . $phpEx), @@ -111,11 +101,27 @@ if (!$db_tools->sql_table_exists(MIGRATIONS_TABLE)) $migrator = $phpbb_container->get('migrator'); $migrator->load_migrations($phpbb_root_path . 'includes/db/migration/data/'); +$safe_time_limit = (ini_get('max_execution_time') / 2); + while (!$migrator->finished()) { $migrator->update(); echo $migrator->last_run_migration['name'] . '
'; + + // Are we approaching the time limit? If so we want to pause the update and continue after refreshing + if ((time() - $update_start_time) >= $safe_time_limit) + { + //echo ''; + echo 'Update not yet completed.
'; + echo 'Continue'; + + garbage_collection(); + exit_handler(); + } } echo 'Finished'; + +garbage_collection(); +exit_handler(); From 28cd253d19f49a6450bce90a5b81df939d0be2c9 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 9 Jan 2013 17:22:05 -0600 Subject: [PATCH 35/90] [feature/migrations] Comment PHPBB3-9737 --- phpBB/test.php | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/test.php b/phpBB/test.php index ed4c1928ee..7a2dafb7ef 100644 --- a/phpBB/test.php +++ b/phpBB/test.php @@ -101,6 +101,7 @@ if (!$db_tools->sql_table_exists(MIGRATIONS_TABLE)) $migrator = $phpbb_container->get('migrator'); $migrator->load_migrations($phpbb_root_path . 'includes/db/migration/data/'); +// What is a safe limit of execution time? Half the max execution time should be safe. $safe_time_limit = (ini_get('max_execution_time') / 2); while (!$migrator->finished()) From 3d4c00619f1c96df7a4c6f8bc1c03eb21abf49d7 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 9 Jan 2013 18:24:32 -0600 Subject: [PATCH 36/90] [feature/migrations] Reverse data functionality If data step fails, attempt to roll back any previous calls from the migration that failed. Fix some failing tests PHPBB3-9737 --- phpBB/includes/db/migration/tool/config.php | 42 ++++++++++++++ .../includes/db/migration/tool/interface.php | 10 ++++ phpBB/includes/db/migration/tool/module.php | 31 +++++++++++ .../includes/db/migration/tool/permission.php | 55 +++++++++++++++++++ phpBB/includes/db/migrator.php | 37 +++++++++---- tests/dbal/migrator_tool_config_test.php | 27 +++++++++ tests/dbal/migrator_tool_module.php | 28 +++++++++- tests/dbal/migrator_tool_permission.php | 25 ++++++++- 8 files changed, 240 insertions(+), 15 deletions(-) diff --git a/phpBB/includes/db/migration/tool/config.php b/phpBB/includes/db/migration/tool/config.php index e7239436d2..6ae419d5e7 100644 --- a/phpBB/includes/db/migration/tool/config.php +++ b/phpBB/includes/db/migration/tool/config.php @@ -103,4 +103,46 @@ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interfac $this->config->delete($config_name); } + + /** + * Reverse an original install action + * + * First argument is the original call to the class (e.g. add, remove) + * After the first argument, send the original arguments to the function in the original call + * + * @return null + */ + public function reverse() + { + $arguments = func_get_args(); + $original_call = array_shift($arguments); + + $call = false; + switch ($original_call) + { + case 'add': + $call = 'remove'; + break; + + case 'remove': + $call = 'add'; + break; + + case 'update_if_equals': + $call = 'update_if_equals'; + + // Set to the original value if the current value is what we compared to originally + $arguments = array( + $arguments[2], + $arguments[1], + $arguments[0], + ); + break; + } + + if ($call) + { + return call_user_func_array(array(&$this, $call), $arguments); + } + } } diff --git a/phpBB/includes/db/migration/tool/interface.php b/phpBB/includes/db/migration/tool/interface.php index 5d10246ba1..ced53b2023 100644 --- a/phpBB/includes/db/migration/tool/interface.php +++ b/phpBB/includes/db/migration/tool/interface.php @@ -20,4 +20,14 @@ interface phpbb_db_migration_tool_interface * @return string short name */ public function get_name(); + + /** + * Reverse an original install action + * + * First argument is the original call to the class (e.g. add, remove) + * After the first argument, send the original arguments to the function in the original call + * + * @return null + */ + public function reverse(); } diff --git a/phpBB/includes/db/migration/tool/module.php b/phpBB/includes/db/migration/tool/module.php index 70a246849a..561faac552 100644 --- a/phpBB/includes/db/migration/tool/module.php +++ b/phpBB/includes/db/migration/tool/module.php @@ -471,4 +471,35 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac $this->cache->destroy("_modules_$class"); } } + + /** + * Reverse an original install action + * + * First argument is the original call to the class (e.g. add, remove) + * After the first argument, send the original arguments to the function in the original call + * + * @return null + */ + public function reverse() + { + $arguments = func_get_args(); + $original_call = array_shift($arguments); + + $call = false; + switch ($original_call) + { + case 'add': + $call = 'remove'; + break; + + case 'remove': + $call = 'add'; + break; + } + + if ($call) + { + return call_user_func_array(array(&$this, $call), $arguments); + } + } } diff --git a/phpBB/includes/db/migration/tool/permission.php b/phpBB/includes/db/migration/tool/permission.php index 7b45b24361..a25fdb345e 100644 --- a/phpBB/includes/db/migration/tool/permission.php +++ b/phpBB/includes/db/migration/tool/permission.php @@ -563,4 +563,59 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte $this->auth->acl_clear_prefetch(); } + + /** + * Reverse an original install action + * + * First argument is the original call to the class (e.g. add, remove) + * After the first argument, send the original arguments to the function in the original call + * + * @return null + */ + public function reverse() + { + $arguments = func_get_args(); + $original_call = array_shift($arguments); + + $call = false; + switch ($original_call) + { + case 'add': + $call = 'remove'; + break; + + case 'remove': + $call = 'add'; + break; + + case 'permission_set': + $call = 'permission_unset'; + break; + + case 'permission_unset': + $call = 'permission_set'; + break; + + case 'role_add': + $call = 'role_remove'; + break; + + case 'role_remove': + $call = 'role_add'; + break; + + case 'role_update': + // Set to the original value if the current value is what we compared to originally + $arguments = array( + $arguments[1], + $arguments[0], + ); + break; + } + + if ($call) + { + return call_user_func_array(array(&$this, $call), $arguments); + } + } } diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 359c34bf5d..dc2c746559 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -347,6 +347,17 @@ class phpbb_db_migrator catch (phpbb_db_migration_exception $e) { // We should try rolling back here + foreach ($steps as $reverse_step) + { + // Reverse the step that was run + $result = $this->run_step($step, false, true); + + // If we've reached the current step we can break because we reversed everything that was run + if ($reverse_step === $step) + { + break; + } + } var_dump($step); echo $e; @@ -364,11 +375,12 @@ class phpbb_db_migrator * * @param mixed $step Data step from migration * @param mixed $last_result Result to pass to the callable (only for 'custom' method) + * @param bool $reverse False to install, True to attempt uninstallation by reversing the call * @return null */ - protected function run_step($step, $last_result = false) + protected function run_step($step, $last_result = false, $reverse = false) { - $callable_and_parameters = $this->get_callable_from_step($step, $last_result); + $callable_and_parameters = $this->get_callable_from_step($step, $last_result, $reverse); if ($callable_and_parameters === false) { @@ -386,9 +398,10 @@ class phpbb_db_migrator * * @param mixed $step Data step from migration * @param mixed $last_result Result to pass to the callable (only for 'custom' method) + * @param bool $reverse False to install, True to attempt uninstallation by reversing the call * @return array Array with parameters for call_user_func_array(), 0 is the callable, 1 is parameters */ - protected function get_callable_from_step($step, $last_result = false) + protected function get_callable_from_step($step, $last_result = false, $reverse = false) { $type = $step[0]; $parameters = $step[1]; @@ -425,14 +438,7 @@ class phpbb_db_migrator $step = $parameters[1]; - $callable_and_parameters = $this->get_callable_from_step($step); - $callable = $callable_and_parameters[0]; - $sub_parameters = $callable_and_parameters[1]; - - return array( - $callable, - $sub_parameters, - ); + return $this->get_callable_from_step($step); break; case 'custom': if (!is_callable($parameters[0])) @@ -462,6 +468,15 @@ class phpbb_db_migrator throw new phpbb_db_migration_exception('MIGRATION_INVALID_DATA_UNDEFINED_METHOD', $step); } + // Attempt to reverse operations + if ($reverse) + { + return array( + array($this->tools[$class], 'reverse'), + array_unshift($parameters, $method), + ); + } + return array( array($this->tools[$class], $method), $parameters, diff --git a/tests/dbal/migrator_tool_config_test.php b/tests/dbal/migrator_tool_config_test.php index 27511519ca..7d582f230b 100644 --- a/tests/dbal/migrator_tool_config_test.php +++ b/tests/dbal/migrator_tool_config_test.php @@ -94,4 +94,31 @@ class phpbb_dbal_migrator_tool_config_test extends phpbb_test_case } $this->assertFalse(isset($this->config['foo'])); } + + public function test_reverse() + { + $this->config->set('foo', 'bar'); + + try + { + $this->tool->reverse('add', 'foo'); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertFalse(isset($this->config['foo'])); + + $this->config->set('foo', 'bar'); + + try + { + $this->tool->reverse('update_if_equals', 'test', 'foo', 'bar'); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals('test', $this->config['foo']); + } } diff --git a/tests/dbal/migrator_tool_module.php b/tests/dbal/migrator_tool_module.php index 0b57cbfbcb..6937b6f8c5 100644 --- a/tests/dbal/migrator_tool_module.php +++ b/tests/dbal/migrator_tool_module.php @@ -29,10 +29,10 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case $skip_add_log = true; $db = $this->db = $this->new_dbal(); - $this->cache = new phpbb_cache_service(new phpbb_cache_driver_null()); + $this->cache = new phpbb_cache_service(new phpbb_cache_driver_null(), new phpbb_config(array()), $this->db, $phpbb_root_path, $phpEx); $user = $this->user = new phpbb_user(); - $this->tool = new phpbb_db_migration_tool_module($this->db, $this->cache, $this->user, $phpbb_root_path, $phpEx); + $this->tool = new phpbb_db_migration_tool_module($this->db, $this->cache, $this->user, $phpbb_root_path, $phpEx, 'phpbb_modules'); } public function exists_data() @@ -99,7 +99,7 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case try { - $this->tool->add('acp', ACP_NEW_CAT, array( + $this->tool->add('acp', 'ACP_NEW_CAT', array( 'module_basename' => 'acp_new_module', 'module_langname' => 'ACP_NEW_MODULE', 'module_mode' => 'test', @@ -125,4 +125,26 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case } $this->assertEquals(false, $this->tool->exists('acp', 'ACP_CAT', 'ACP_MODULE')); } + + public function test_reverse() + { + try + { + $this->tool->add('acp', 0, 'ACP_NEW_CAT'); + } + catch (Exception $e) + { + $this->fail($e); + } + + try + { + $this->tool->reverse('add', 'acp', 0, 'ACP_NEW_CAT'); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertFalse($this->tool->exists('acp', 0, 'ACP_NEW_CAT')); + } } diff --git a/tests/dbal/migrator_tool_permission.php b/tests/dbal/migrator_tool_permission.php index 2229576cd9..438ab2b28e 100644 --- a/tests/dbal/migrator_tool_permission.php +++ b/tests/dbal/migrator_tool_permission.php @@ -26,7 +26,7 @@ class phpbb_dbal_migrator_tool_permission_test extends phpbb_database_test_case parent::setup(); $db = $this->db = $this->new_dbal(); - $cache = $this->cache = new phpbb_cache_service(new phpbb_cache_driver_null()); + $cache = $this->cache = new phpbb_cache_service(new phpbb_cache_driver_null(), new phpbb_config(array()), $this->db, $phpbb_root_path, $phpEx); $this->auth = new phpbb_auth(); $this->tool = new phpbb_db_migration_tool_permission($this->db, $this->cache, $this->auth, $phpbb_root_path, $phpEx); @@ -133,4 +133,27 @@ class phpbb_dbal_migrator_tool_permission_test extends phpbb_database_test_case } catch (Exception $e) {} } + + public function test_reverse() + { + try + { + $this->tool->reverse('remove', 'global_test', true); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertTrue($this->tool->exists('global_test', true)); + + try + { + $this->tool->reverse('add', 'global_test', true); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertFalse($this->tool->exists('global_test', true)); + } } From 595246f9bf17f1bef69c285ba8e78534cd91054a Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 9 Jan 2013 18:55:55 -0600 Subject: [PATCH 37/90] [feature/migrations] Some comments in db_tools PHPBB3-9737 --- phpBB/includes/db/db_tools.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index 1d6823d37a..b13d4fe978 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -685,6 +685,8 @@ class phpbb_db_tools * Handle passed database update array. * Expected structure... * Key being one of the following + * drop_tables: Drop tables + * add_tables: Add tables * change_columns: Column changes (only type, not name) * add_columns: Add columns to a table * drop_keys: Dropping keys From 44c10f661ee548ae08fe81ba76f47f1c8134b96f Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 9 Jan 2013 18:59:15 -0600 Subject: [PATCH 38/90] [feature/migrations] Creating revert method to attempt reverting a migration This code is in progress PHPBB3-9737 --- phpBB/includes/db/migration/migration.php | 23 +++++ phpBB/includes/db/migrator.php | 100 ++++++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/phpBB/includes/db/migration/migration.php b/phpBB/includes/db/migration/migration.php index 5f1f0443db..61fbf04320 100644 --- a/phpBB/includes/db/migration/migration.php +++ b/phpBB/includes/db/migration/migration.php @@ -93,6 +93,16 @@ abstract class phpbb_db_migration return array(); } + /** + * Reverts the database schema by providing a set of change instructions + * + * @return array Array of schema changes (compatible with db_tools->perform_schema_changes()) + */ + public function revert_schema() + { + return array(); + } + /** * Updates data by returning a list of instructions to be executed * @@ -103,6 +113,19 @@ abstract class phpbb_db_migration return array(); } + /** + * Reverts data by returning a list of instructions to be executed + * + * @return array Array of data instructions that will be performed on revert + * NOTE: calls to tools (such as config.add) are automatically reverted when + * possible, so you should not attempt to revert those, this is mostly for + * otherwise unrevertable calls (custom functions for example) + */ + public function revert_data() + { + return array(); + } + /** * Wrapper for running queries to generate user feedback on updates * diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index dc2c746559..e8d3735974 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -289,6 +289,91 @@ class phpbb_db_migrator return true; } + /** + * Runs a single revert step from the last migration installed + * + * The revert step can either be a schema or a (partial) data revert. To + * check if revert() needs to be called again use the migration_installed() method. + * + * @param string $migration String migration name to revert (including any that depend on this migration) + * @return null + */ + public function revert($migration) + { + if (!isset($this->migration_state[$name])) + { + // Not installed + return; + } + + // Iterate through all installed migrations and make sure any dependencies are removed first + foreach ($this->migration_state as $name => $state) + { + $migration_class = $this->get_migration($name); + + if (in_array($migration, $migration_class->depends_on())) + { + $this->revert($name); + } + } + + $this->try_revert($migration); + } + + /** + * Attempts to apply a step of the given migration or one of its dependencies + * + * @param string The class name of the migration + * @return bool Whether any update step was successfully run + */ + protected function try_revert($name) + { + if (!class_exists($name)) + { + return false; + } + + $migration = $this->get_migration($name); + + $state = $this->migration_state[$name]; + + $this->last_run_migration = array( + 'name' => $name, + 'class' => $migration, + ); + + // Left off here + + if (!isset($this->migration_state[$name])) + { + $state['migration_start_time'] = time(); + $this->insert_migration($name, $state); + } + + if (!$state['migration_schema_done']) + { + $this->apply_schema_changes($migration->update_schema()); + $state['migration_schema_done'] = true; + } + else + { + $result = $this->process_data_step($migration, $state['migration_data_state']); + + $state['migration_data_state'] = ($result === true) ? '' : $result; + $state['migration_data_done'] = ($result === true); + $state['migration_end_time'] = ($result === true) ? time() : 0; + } + + $sql = 'UPDATE ' . $this->migrations_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $state) . " + WHERE migration_name = '" . $this->db->sql_escape($name) . "'"; + $this->db->sql_query($sql); + + $this->migration_state[$name] = $state; + + return true; + } + /** * Apply schema changes from a migration * @@ -359,6 +444,7 @@ class phpbb_db_migrator } } + /** TODO Revert Schema **/ var_dump($step); echo $e; die(); @@ -567,6 +653,20 @@ class phpbb_db_migrator return true; } + /** + * Checks whether a migration is installed + * + * @param string $migration String migration name to check if it is installed + * @return bool Whether the migrations have been applied + */ + public function migration_installed($migration) + { + if (isset($this->migration_state[$migration])) + { + return true; + } + } + /** * Helper to get a migration * From ddb1eaab6868cfac70b7b202468cab29315b794d Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 12:49:13 -0600 Subject: [PATCH 39/90] [feature/migrations] Test for calling a step multiple times This is used when a long-running process is needed during an update. For example, iterating over all posts and applying some transformation. This allows the process to be broken apart into multiple shorter steps to prevent hitting the time limit. PHPBB3-9737 --- tests/dbal/migration/recall.php | 43 +++++++++++++++++++++++++++++++++ tests/dbal/migrator_test.php | 23 ++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 tests/dbal/migration/recall.php diff --git a/tests/dbal/migration/recall.php b/tests/dbal/migration/recall.php new file mode 100644 index 0000000000..18d8b4a6d2 --- /dev/null +++ b/tests/dbal/migration/recall.php @@ -0,0 +1,43 @@ +fail('False test failed'); } } + + public function test_recall() + { + $this->migrator->set_migrations(array('phpbb_dbal_migration_recall')); + + global $migrator_test_call_input; + + // Run the schema first + $this->migrator->update(); + + $i = 0; + while (!$this->migrator->finished()) + { + $this->migrator->update(); + + $this->assertSame($i, $migrator_test_call_input); + + $i++; + } + + $this->assertSame(10, $migrator_test_call_input); + } } From 00385aa742da17678f7d147b6d71fa759fcd7e78 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 13:52:11 -0600 Subject: [PATCH 40/90] [feature/migrations] Basic reverting test PHPBB3-9737 --- tests/dbal/migration/revert.php | 45 ++++++++++++++++ .../dbal/migration/revert_with_dependency.php | 16 ++++++ tests/dbal/migrator_test.php | 54 +++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 tests/dbal/migration/revert.php create mode 100644 tests/dbal/migration/revert_with_dependency.php diff --git a/tests/dbal/migration/revert.php b/tests/dbal/migration/revert.php new file mode 100644 index 0000000000..2bb23e31c2 --- /dev/null +++ b/tests/dbal/migration/revert.php @@ -0,0 +1,45 @@ + array( + 'phpbb_config' => array( + 'bar_column' => array('UINT', 1), + ), + ), + ); + } + + function revert_schema() + { + return array( + 'drop_columns' => array( + 'phpbb_config' => array( + 'bar_column', + ), + ), + ); + } + + function update_data() + { + return array( + array('config.add', array('foobartest', 0)), + ); + } +} diff --git a/tests/dbal/migration/revert_with_dependency.php b/tests/dbal/migration/revert_with_dependency.php new file mode 100644 index 0000000000..f6820dbf3f --- /dev/null +++ b/tests/dbal/migration/revert_with_dependency.php @@ -0,0 +1,16 @@ +db_tools->sql_column_remove('phpbb_config', 'extra_column'); } public function test_if() @@ -150,4 +154,54 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->assertSame(10, $migrator_test_call_input); } + + public function test_revert() + { + // Make sure there are no other migrations in the db, this could cause issues + $this->db->sql_query("DELETE FROM phpbb_migrations"); + $this->migrator->load_migration_state(); + + $this->migrator->set_migrations(array('phpbb_dbal_migration_revert', 'phpbb_dbal_migration_revert_with_dependency')); + + $this->assertFalse($this->migrator->migration_installed('phpbb_dbal_migration_revert')); + $this->assertFalse($this->migrator->migration_installed('phpbb_dbal_migration_revert_with_dependency')); + + // Install the migration first + while (!$this->migrator->finished()) + { + $this->migrator->update(); + } + + $this->assertTrue($this->migrator->migration_installed('phpbb_dbal_migration_revert')); + $this->assertTrue($this->migrator->migration_installed('phpbb_dbal_migration_revert_with_dependency')); + + $this->assertSqlResultEquals( + array(array('bar_column' => '1')), + "SELECT bar_column FROM phpbb_config WHERE config_name = 'foo'", + 'Installing revert migration failed to create bar_column.' + ); + + $this->assertTrue(isset($this->config['foobartest'])); + + while ($this->migrator->migration_installed('phpbb_dbal_migration_revert')) + { + $this->migrator->revert('phpbb_dbal_migration_revert'); + } + + $this->assertFalse($this->migrator->migration_installed('phpbb_dbal_migration_revert')); + $this->assertFalse($this->migrator->migration_installed('phpbb_dbal_migration_revert_with_dependency')); + + $this->assertFalse(isset($this->config['foobartest'])); + + try + { + // Should cause an error + $this->assertSqlResultEquals( + false, + "SELECT bar_column FROM phpbb_config WHERE config_name = 'foo'", + 'Revert did not remove bar_column.' + ); + } + catch (Exception $e) {} + } } From dbe71bb170dc684311174bb025696c81f1d50883 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 13:53:09 -0600 Subject: [PATCH 41/90] [feature/migrations] Revert method completed PHPBB3-9737 --- phpBB/includes/db/migrator.php | 74 +++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index e8d3735974..13114e7df1 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -272,7 +272,7 @@ class phpbb_db_migrator } else { - $result = $this->process_data_step($migration, $state['migration_data_state']); + $result = $this->process_data_step($migration->update_data(), $state['migration_data_state']); $state['migration_data_state'] = ($result === true) ? '' : $result; $state['migration_data_done'] = ($result === true); @@ -300,7 +300,7 @@ class phpbb_db_migrator */ public function revert($migration) { - if (!isset($this->migration_state[$name])) + if (!isset($this->migration_state[$migration])) { // Not installed return; @@ -342,35 +342,40 @@ class phpbb_db_migrator 'class' => $migration, ); - // Left off here - - if (!isset($this->migration_state[$name])) + if ($state['migration_data_done']) { - $state['migration_start_time'] = time(); - $this->insert_migration($name, $state); - } + if ($state['migration_data_state'] !== 'revert_data') + { + $result = $this->process_data_step($migration->update_data(), $state['migration_data_state'], true); - if (!$state['migration_schema_done']) - { - $this->apply_schema_changes($migration->update_schema()); - $state['migration_schema_done'] = true; + $state['migration_data_state'] = ($result === true) ? 'revert_data' : $result; + } + else + { + $result = $this->process_data_step($migration->revert_data(), $state['migration_data_state'], false); + + $state['migration_data_state'] = ($result === true) ? '' : $result; + $state['migration_data_done'] = ($result === true) ? false : true; + } + + $sql = 'UPDATE ' . $this->migrations_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $state) . " + WHERE migration_name = '" . $this->db->sql_escape($name) . "'"; + $this->db->sql_query($sql); + + $this->migration_state[$name] = $state; } else { - $result = $this->process_data_step($migration, $state['migration_data_state']); + $this->apply_schema_changes($migration->revert_schema()); - $state['migration_data_state'] = ($result === true) ? '' : $result; - $state['migration_data_done'] = ($result === true); - $state['migration_end_time'] = ($result === true) ? time() : 0; + $sql = 'DELETE FROM ' . $this->migrations_table . " + WHERE migration_name = '" . $this->db->sql_escape($name) . "'"; + $this->db->sql_query($sql); + + unset($this->migration_state[$name]); } - $sql = 'UPDATE ' . $this->migrations_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $state) . " - WHERE migration_name = '" . $this->db->sql_escape($name) . "'"; - $this->db->sql_query($sql); - - $this->migration_state[$name] = $state; - return true; } @@ -389,23 +394,22 @@ class phpbb_db_migrator /** * Process the data step of the migration * - * @param phpbb_db_migration $migration + * @param array $steps The steps to run * @param bool|string $state Current state of the migration + * @param bool $revert true to revert a data step * @return bool|string migration state. True if completed, serialized array if not finished */ - protected function process_data_step($migration, $state) + protected function process_data_step($steps, $state, $revert = false) { $state = ($state) ? unserialize($state) : false; - $steps = $migration->update_data(); - - foreach ($steps as $step) + foreach ($steps as $step_identifier => $step) { $last_result = false; if ($state) { // Continue until we reach the step that matches the last step called - if ($state['step'] != $step) + if ($state['step'] != $step_identifier) { continue; } @@ -420,12 +424,12 @@ class phpbb_db_migrator try { // Result will be null or true if everything completed correctly - $result = $this->run_step($step, $last_result); + $result = $this->run_step($step, $last_result, $revert); if ($result !== null && $result !== true) { return serialize(array( 'result' => $result, - 'step' => $step, + 'step' => $step_identifier, )); } } @@ -435,7 +439,7 @@ class phpbb_db_migrator foreach ($steps as $reverse_step) { // Reverse the step that was run - $result = $this->run_step($step, false, true); + $result = $this->run_step($step, false, !$revert); // If we've reached the current step we can break because we reversed everything that was run if ($reverse_step === $step) @@ -557,9 +561,11 @@ class phpbb_db_migrator // Attempt to reverse operations if ($reverse) { + array_unshift($parameters, $method); + return array( array($this->tools[$class], 'reverse'), - array_unshift($parameters, $method), + $parameters, ); } @@ -665,6 +671,8 @@ class phpbb_db_migrator { return true; } + + return false; } /** From d50500860fe44a78c8f29e0f2382b96da17c0b62 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 15:09:51 -0600 Subject: [PATCH 42/90] [feature/migrations] Store depends on in the database (serialized) This is required so that when migrations are reverted we can check through all installed migrations and make sure that all dependencies are handled properly and so that we are only required to load the migrations files that could be dependent on the ones installed. I believe in normal proper use the old way might have worked, but in case something happens and an unrelated migration file is installed, but cannot be loaded, this makes sure we do not stop everything unless we absolutely must (one of those files is dependent on something we want to revert). PHPBB3-9737 --- phpBB/develop/create_schema_files.php | 1 + phpBB/includes/db/migrator.php | 79 +++++++++++++---------- phpBB/install/schemas/firebird_schema.sql | 1 + phpBB/install/schemas/mssql_schema.sql | 1 + phpBB/install/schemas/mysql_40_schema.sql | 1 + phpBB/install/schemas/mysql_41_schema.sql | 1 + phpBB/install/schemas/oracle_schema.sql | 1 + phpBB/install/schemas/postgres_schema.sql | 1 + phpBB/install/schemas/sqlite_schema.sql | 1 + phpBB/test.php | 13 +++- tests/dbal/fixtures/migrator.xml | 2 + tests/dbal/migration/fail.php | 46 +++++++++++++ tests/dbal/migrator_test.php | 57 ++++++++++++---- 13 files changed, 157 insertions(+), 48 deletions(-) create mode 100644 tests/dbal/migration/fail.php diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index b37dcc246f..d0864b975d 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1276,6 +1276,7 @@ function get_schema_struct() $schema_data['phpbb_migrations'] = array( 'COLUMNS' => array( 'migration_name' => array('VCHAR', ''), + 'migration_depends_on' => array('TEXT', ''), 'migration_schema_done' => array('BOOL', 0), 'migration_data_done' => array('BOOL', 0), 'migration_data_state' => array('TEXT', ''), diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 13114e7df1..2ec44a5a45 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -106,6 +106,8 @@ class phpbb_db_migrator while ($migration = $this->db->sql_fetchrow($result)) { $this->migration_state[$migration['migration_name']] = $migration; + + $this->migration_state[$migration['migration_name']]['migration_depends_on'] = unserialize($migration['migration_depends_on']); } $this->db->sql_freeresult($result); @@ -235,16 +237,15 @@ class phpbb_db_migrator $state = (isset($this->migration_state[$name])) ? $this->migration_state[$name] : array( + 'migration_depends_on' => $migration->depends_on(), 'migration_schema_done' => false, - 'migration_data_done' => false, - 'migration_data_state' => '', - 'migration_start_time' => 0, - 'migration_end_time' => 0, + 'migration_data_done' => false, + 'migration_data_state' => '', + 'migration_start_time' => 0, + 'migration_end_time' => 0, ); - $depends = $migration->depends_on(); - - foreach ($depends as $depend) + foreach ($state['migration_depends_on'] as $depend) { if (!isset($this->migration_state[$depend]) || !$this->migration_state[$depend]['migration_schema_done'] || @@ -272,15 +273,28 @@ class phpbb_db_migrator } else { - $result = $this->process_data_step($migration->update_data(), $state['migration_data_state']); + try + { + $result = $this->process_data_step($migration->update_data(), $state['migration_data_state']); - $state['migration_data_state'] = ($result === true) ? '' : $result; - $state['migration_data_done'] = ($result === true); - $state['migration_end_time'] = ($result === true) ? time() : 0; + $state['migration_data_state'] = ($result === true) ? '' : $result; + $state['migration_data_done'] = ($result === true); + $state['migration_end_time'] = ($result === true) ? time() : 0; + } + catch (phpbb_db_migration_exception $e) + { + // Revert the schema changes + $this->revert($name); + + // Rethrow exception + throw $e; + } } + $insert = $state; + $insert['migration_depends_on'] = serialize($state['migration_depends_on']); $sql = 'UPDATE ' . $this->migrations_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $state) . " + SET ' . $this->db->sql_build_array('UPDATE', $insert) . " WHERE migration_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); @@ -292,8 +306,9 @@ class phpbb_db_migrator /** * Runs a single revert step from the last migration installed * + * YOU MUST ADD/SET ALL MIGRATIONS THAT COULD BE DEPENDENT ON THE MIGRATION TO REVERT TO BEFORE CALLING THIS METHOD! * The revert step can either be a schema or a (partial) data revert. To - * check if revert() needs to be called again use the migration_installed() method. + * check if revert() needs to be called again use the migration_state() method. * * @param string $migration String migration name to revert (including any that depend on this migration) * @return null @@ -306,12 +321,9 @@ class phpbb_db_migrator return; } - // Iterate through all installed migrations and make sure any dependencies are removed first foreach ($this->migration_state as $name => $state) { - $migration_class = $this->get_migration($name); - - if (in_array($migration, $migration_class->depends_on())) + if (!empty($state['migration_depends_on']) && in_array($migration, $state['migration_depends_on'])) { $this->revert($name); } @@ -358,8 +370,10 @@ class phpbb_db_migrator $state['migration_data_done'] = ($result === true) ? false : true; } + $insert = $state; + $insert['migration_depends_on'] = serialize($state['migration_depends_on']); $sql = 'UPDATE ' . $this->migrations_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $state) . " + SET ' . $this->db->sql_build_array('UPDATE', $insert) . " WHERE migration_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); @@ -436,22 +450,20 @@ class phpbb_db_migrator catch (phpbb_db_migration_exception $e) { // We should try rolling back here - foreach ($steps as $reverse_step) + foreach ($steps as $reverse_step_identifier => $reverse_step) { - // Reverse the step that was run - $result = $this->run_step($step, false, !$revert); - // If we've reached the current step we can break because we reversed everything that was run - if ($reverse_step === $step) + if ($reverse_step_identifier == $step_identifier) { break; } + + // Reverse the step that was run + $result = $this->run_step($reverse_step, false, !$revert); } - /** TODO Revert Schema **/ - var_dump($step); - echo $e; - die(); + // rethrow the exception + throw $e; } } @@ -588,6 +600,7 @@ class phpbb_db_migrator { $migration_row = $state; $migration_row['migration_name'] = $name; + $migration_row['migration_depends_on'] = serialize($state['migration_depends_on']); $sql = 'INSERT INTO ' . $this->migrations_table . ' ' . $this->db->sql_build_array('INSERT', $migration_row); @@ -660,19 +673,19 @@ class phpbb_db_migrator } /** - * Checks whether a migration is installed + * Gets a migration state (whether it is installed and to what extent) * * @param string $migration String migration name to check if it is installed - * @return bool Whether the migrations have been applied + * @return bool|array False if the migration has not at all been installed, array */ - public function migration_installed($migration) + public function migration_state($migration) { - if (isset($this->migration_state[$migration])) + if (!isset($this->migration_state[$migration])) { - return true; + return false; } - return false; + return $this->migration_state[$migration]; } /** diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 535cbb0df4..45024c4049 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -589,6 +589,7 @@ CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache(forum_id);; # Table: 'phpbb_migrations' CREATE TABLE phpbb_migrations ( migration_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + migration_depends_on BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, migration_schema_done INTEGER DEFAULT 0 NOT NULL, migration_data_done INTEGER DEFAULT 0 NOT NULL, migration_data_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 43b8f3e556..e261e73d73 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -721,6 +721,7 @@ GO */ CREATE TABLE [phpbb_migrations] ( [migration_name] [varchar] (255) DEFAULT ('') NOT NULL , + [migration_depends_on] [varchar] (8000) DEFAULT ('') NOT NULL , [migration_schema_done] [int] DEFAULT (0) NOT NULL , [migration_data_done] [int] DEFAULT (0) NOT NULL , [migration_data_state] [varchar] (8000) DEFAULT ('') NOT NULL , diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index c46230744a..0f184d4d05 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -413,6 +413,7 @@ CREATE TABLE phpbb_moderator_cache ( # Table: 'phpbb_migrations' CREATE TABLE phpbb_migrations ( migration_name varbinary(255) DEFAULT '' NOT NULL, + migration_depends_on blob NOT NULL, migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, migration_data_state blob NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index fa94598e9c..b7564ceb7c 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -413,6 +413,7 @@ CREATE TABLE phpbb_moderator_cache ( # Table: 'phpbb_migrations' CREATE TABLE phpbb_migrations ( migration_name varchar(255) DEFAULT '' NOT NULL, + migration_depends_on text NOT NULL, migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, migration_data_state text NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index f8a9d5e1a6..7796c3a729 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -803,6 +803,7 @@ CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id) */ CREATE TABLE phpbb_migrations ( migration_name varchar2(255) DEFAULT '' , + migration_depends_on clob DEFAULT '' , migration_schema_done number(1) DEFAULT '0' NOT NULL, migration_data_done number(1) DEFAULT '0' NOT NULL, migration_data_state clob DEFAULT '' , diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index c976659f05..9fd81ec06a 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -577,6 +577,7 @@ CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id); */ CREATE TABLE phpbb_migrations ( migration_name varchar(255) DEFAULT '' NOT NULL, + migration_depends_on varchar(8000) DEFAULT '' NOT NULL, migration_schema_done INT2 DEFAULT '0' NOT NULL CHECK (migration_schema_done >= 0), migration_data_done INT2 DEFAULT '0' NOT NULL CHECK (migration_data_done >= 0), migration_data_state varchar(8000) DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 31a6f715a0..9d6d648c00 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -401,6 +401,7 @@ CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id); # Table: 'phpbb_migrations' CREATE TABLE phpbb_migrations ( migration_name varchar(255) NOT NULL DEFAULT '', + migration_depends_on text(65535) NOT NULL DEFAULT '', migration_schema_done INTEGER UNSIGNED NOT NULL DEFAULT '0', migration_data_done INTEGER UNSIGNED NOT NULL DEFAULT '0', migration_data_state text(65535) NOT NULL DEFAULT '', diff --git a/phpBB/test.php b/phpBB/test.php index 7a2dafb7ef..6602aa8dcc 100644 --- a/phpBB/test.php +++ b/phpBB/test.php @@ -88,6 +88,7 @@ if (!$db_tools->sql_table_exists(MIGRATIONS_TABLE)) $db_tools->sql_create_table(MIGRATIONS_TABLE, array( 'COLUMNS' => array( 'migration_name' => array('VCHAR', ''), + 'migration_depends_on' => array('TEXT', ''), 'migration_schema_done' => array('BOOL', 0), 'migration_data_done' => array('BOOL', 0), 'migration_data_state' => array('TEXT', ''), @@ -106,7 +107,17 @@ $safe_time_limit = (ini_get('max_execution_time') / 2); while (!$migrator->finished()) { - $migrator->update(); + try + { + $migrator->update(); + } + catch (phpbb_db_migration_exception $e) + { + echo $e; + + garbage_collection(); + exit_handler(); + } echo $migrator->last_run_migration['name'] . '
'; diff --git a/tests/dbal/fixtures/migrator.xml b/tests/dbal/fixtures/migrator.xml index 1f9079c811..25be4d4129 100644 --- a/tests/dbal/fixtures/migrator.xml +++ b/tests/dbal/fixtures/migrator.xml @@ -2,6 +2,7 @@ migration_name + migration_depends_onmigration_schema_donemigration_data_donemigration_data_state @@ -9,6 +10,7 @@ migration_end_time installed_migration + 1 1 diff --git a/tests/dbal/migration/fail.php b/tests/dbal/migration/fail.php new file mode 100644 index 0000000000..8b5c521e09 --- /dev/null +++ b/tests/dbal/migration/fail.php @@ -0,0 +1,46 @@ + array( + $this->table_prefix . 'config' => array( + 'test_column' => array('BOOL', 1), + ), + ), + ); + } + + function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'config' => array( + 'test_column', + ), + ), + ); + } + + function update_data() + { + return array( + array('config.add', array('foobar3', true)), + array('config.update', array('does_not_exist', true)), + ); + } +} diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index 84bcb109b2..69db7ca047 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -18,6 +18,7 @@ require_once dirname(__FILE__) . '/migration/if.php'; require_once dirname(__FILE__) . '/migration/recall.php'; require_once dirname(__FILE__) . '/migration/revert.php'; require_once dirname(__FILE__) . '/migration/revert_with_dependency.php'; +require_once dirname(__FILE__) . '/migration/fail.php'; class phpbb_dbal_migrator_test extends phpbb_database_test_case { @@ -163,8 +164,8 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->migrator->set_migrations(array('phpbb_dbal_migration_revert', 'phpbb_dbal_migration_revert_with_dependency')); - $this->assertFalse($this->migrator->migration_installed('phpbb_dbal_migration_revert')); - $this->assertFalse($this->migrator->migration_installed('phpbb_dbal_migration_revert_with_dependency')); + $this->assertFalse($this->migrator->migration_state('phpbb_dbal_migration_revert')); + $this->assertFalse($this->migrator->migration_state('phpbb_dbal_migration_revert_with_dependency')); // Install the migration first while (!$this->migrator->finished()) @@ -172,8 +173,8 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->migrator->update(); } - $this->assertTrue($this->migrator->migration_installed('phpbb_dbal_migration_revert')); - $this->assertTrue($this->migrator->migration_installed('phpbb_dbal_migration_revert_with_dependency')); + $this->assertTrue($this->migrator->migration_state('phpbb_dbal_migration_revert') !== false); + $this->assertTrue($this->migrator->migration_state('phpbb_dbal_migration_revert_with_dependency') !== false); $this->assertSqlResultEquals( array(array('bar_column' => '1')), @@ -183,25 +184,53 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->assertTrue(isset($this->config['foobartest'])); - while ($this->migrator->migration_installed('phpbb_dbal_migration_revert')) + while ($this->migrator->migration_state('phpbb_dbal_migration_revert') !== false) { $this->migrator->revert('phpbb_dbal_migration_revert'); } - $this->assertFalse($this->migrator->migration_installed('phpbb_dbal_migration_revert')); - $this->assertFalse($this->migrator->migration_installed('phpbb_dbal_migration_revert_with_dependency')); + $this->assertFalse($this->migrator->migration_state('phpbb_dbal_migration_revert')); + $this->assertFalse($this->migrator->migration_state('phpbb_dbal_migration_revert_with_dependency')); $this->assertFalse(isset($this->config['foobartest'])); + $sql = 'SELECT * FROM phpbb_config'; + $result = $this->db->sql_query_limit($sql, 1); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (isset($row['bar_column'])) + { + $this->fail('Revert did not remove test_column.'); + } + } + + public function test_fail() + { + $this->migrator->set_migrations(array('phpbb_dbal_migration_fail')); + + $this->assertFalse(isset($this->config['foobar3'])); + try { - // Should cause an error - $this->assertSqlResultEquals( - false, - "SELECT bar_column FROM phpbb_config WHERE config_name = 'foo'", - 'Revert did not remove bar_column.' - ); + while (!$this->migrator->finished()) + { + $this->migrator->update(); + } + } + catch (phpbb_db_migration_exception $e) {} + + // Failure should have caused an automatic roll-back, so this should not exist. + $this->assertFalse(isset($this->config['foobar3'])); + + $sql = 'SELECT * FROM phpbb_config'; + $result = $this->db->sql_query_limit($sql, 1); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (isset($row['test_column'])) + { + $this->fail('Revert did not remove test_column.'); } - catch (Exception $e) {} } } From 63780bda8d6e6e968b934b200853de2776e53596 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 15:14:16 -0600 Subject: [PATCH 43/90] [feature/migrations] Move test.php -> install/database_update_migrations.php This should be used as a basis for the database updater using migrations. PHPBB3-9737 --- phpBB/{test.php => install/database_update_migrations.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename phpBB/{test.php => install/database_update_migrations.php} (99%) diff --git a/phpBB/test.php b/phpBB/install/database_update_migrations.php similarity index 99% rename from phpBB/test.php rename to phpBB/install/database_update_migrations.php index 6602aa8dcc..52682dc489 100644 --- a/phpBB/test.php +++ b/phpBB/install/database_update_migrations.php @@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; * @ignore */ define('IN_PHPBB', true); -$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './'; +$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; $phpEx = substr(strrchr(__FILE__, '.'), 1); require($phpbb_root_path . 'includes/startup.' . $phpEx); From ebfa42455a19376a7996980301a81ad5665a1414 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 15:17:36 -0600 Subject: [PATCH 44/90] [feature/migrations] install/database_update_migrations.php Actually, this does not belong in the main PR, moving to the data PR. PHPBB3-9737 --- phpBB/install/database_update_migrations.php | 139 ------------------- 1 file changed, 139 deletions(-) delete mode 100644 phpBB/install/database_update_migrations.php diff --git a/phpBB/install/database_update_migrations.php b/phpBB/install/database_update_migrations.php deleted file mode 100644 index 52682dc489..0000000000 --- a/phpBB/install/database_update_migrations.php +++ /dev/null @@ -1,139 +0,0 @@ -register(); - -// Set up container -$container_extensions = array( - new phpbb_di_extension_config($phpbb_root_path . 'config.' . $phpEx), - new phpbb_di_extension_core($phpbb_root_path), -); -$container_passes = array( - new phpbb_di_pass_collection_pass(), - //new phpbb_di_pass_kernel_pass(), -); -$phpbb_container = phpbb_create_container($container_extensions, $phpbb_root_path, $phpEx); - -// Compile the container -foreach ($container_passes as $pass) -{ - $phpbb_container->addCompilerPass($pass); -} -$phpbb_container->compile(); - -// set up caching -$cache = $phpbb_container->get('cache'); - -// Instantiate some basic classes -$phpbb_dispatcher = $phpbb_container->get('dispatcher'); -$request = $phpbb_container->get('request'); -$user = $phpbb_container->get('user'); -$auth = $phpbb_container->get('auth'); -$db = $phpbb_container->get('dbal.conn'); - -// make sure request_var uses this request instance -request_var('', 0, false, false, $request); // "dependency injection" for a function - -// Grab global variables, re-cache if necessary -$config = $phpbb_container->get('config'); -set_config(null, null, null, $config); -set_config_count(null, null, null, $config); - -// End startup code - -$db_tools = $phpbb_container->get('dbal.tools'); -if (!$db_tools->sql_table_exists(MIGRATIONS_TABLE)) -{ - $db_tools->sql_create_table(MIGRATIONS_TABLE, array( - 'COLUMNS' => array( - 'migration_name' => array('VCHAR', ''), - 'migration_depends_on' => array('TEXT', ''), - 'migration_schema_done' => array('BOOL', 0), - 'migration_data_done' => array('BOOL', 0), - 'migration_data_state' => array('TEXT', ''), - 'migration_start_time' => array('TIMESTAMP', 0), - 'migration_end_time' => array('TIMESTAMP', 0), - ), - 'PRIMARY_KEY' => 'migration_name', - )); -} - -$migrator = $phpbb_container->get('migrator'); -$migrator->load_migrations($phpbb_root_path . 'includes/db/migration/data/'); - -// What is a safe limit of execution time? Half the max execution time should be safe. -$safe_time_limit = (ini_get('max_execution_time') / 2); - -while (!$migrator->finished()) -{ - try - { - $migrator->update(); - } - catch (phpbb_db_migration_exception $e) - { - echo $e; - - garbage_collection(); - exit_handler(); - } - - echo $migrator->last_run_migration['name'] . '
'; - - // Are we approaching the time limit? If so we want to pause the update and continue after refreshing - if ((time() - $update_start_time) >= $safe_time_limit) - { - //echo ''; - echo 'Update not yet completed.
'; - echo 'Continue'; - - garbage_collection(); - exit_handler(); - } -} - -echo 'Finished'; - -garbage_collection(); -exit_handler(); From db4fcab3bb4aefcabe93dd4acd1f12e8517cf340 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 22:29:49 -0600 Subject: [PATCH 45/90] [feature/migrations] Make depends_on static to call it without dependencies PHPBB3-11318 --- phpBB/includes/db/migration/migration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/migration/migration.php b/phpBB/includes/db/migration/migration.php index 61fbf04320..4271751362 100644 --- a/phpBB/includes/db/migration/migration.php +++ b/phpBB/includes/db/migration/migration.php @@ -78,7 +78,7 @@ abstract class phpbb_db_migration * * @return array An array of migration class names */ - public function depends_on() + static public function depends_on() { return array(); } From 9f38dc67a80b5fc2a8bb0d01825d7655915e3319 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 22:48:31 -0600 Subject: [PATCH 46/90] [feature/migrations] Make the test depends_on methods static PHPBB3-11318 --- tests/dbal/migration/dummy.php | 2 +- tests/dbal/migration/fail.php | 5 ----- tests/dbal/migration/if.php | 5 ----- tests/dbal/migration/recall.php | 5 ----- tests/dbal/migration/revert.php | 5 ----- tests/dbal/migration/revert_with_dependency.php | 2 +- tests/dbal/migration/unfulfillable.php | 2 +- 7 files changed, 3 insertions(+), 23 deletions(-) diff --git a/tests/dbal/migration/dummy.php b/tests/dbal/migration/dummy.php index e542493f9f..0ac6e733a1 100644 --- a/tests/dbal/migration/dummy.php +++ b/tests/dbal/migration/dummy.php @@ -9,7 +9,7 @@ class phpbb_dbal_migration_dummy extends phpbb_db_migration { - function depends_on() + static public function depends_on() { return array('installed_migration'); } diff --git a/tests/dbal/migration/fail.php b/tests/dbal/migration/fail.php index 8b5c521e09..f88d8169f5 100644 --- a/tests/dbal/migration/fail.php +++ b/tests/dbal/migration/fail.php @@ -9,11 +9,6 @@ class phpbb_dbal_migration_fail extends phpbb_db_migration { - function depends_on() - { - return array(); - } - function update_schema() { return array( diff --git a/tests/dbal/migration/if.php b/tests/dbal/migration/if.php index aa9a5dab87..83fe21bd21 100644 --- a/tests/dbal/migration/if.php +++ b/tests/dbal/migration/if.php @@ -9,11 +9,6 @@ class phpbb_dbal_migration_if extends phpbb_db_migration { - function depends_on() - { - return array(); - } - function update_schema() { return array(); diff --git a/tests/dbal/migration/recall.php b/tests/dbal/migration/recall.php index 18d8b4a6d2..6c2f04bf08 100644 --- a/tests/dbal/migration/recall.php +++ b/tests/dbal/migration/recall.php @@ -9,11 +9,6 @@ class phpbb_dbal_migration_recall extends phpbb_db_migration { - function depends_on() - { - return array(); - } - function update_schema() { return array(); diff --git a/tests/dbal/migration/revert.php b/tests/dbal/migration/revert.php index 2bb23e31c2..ac01987cd4 100644 --- a/tests/dbal/migration/revert.php +++ b/tests/dbal/migration/revert.php @@ -9,11 +9,6 @@ class phpbb_dbal_migration_revert extends phpbb_db_migration { - function depends_on() - { - return array(); - } - function update_schema() { return array( diff --git a/tests/dbal/migration/revert_with_dependency.php b/tests/dbal/migration/revert_with_dependency.php index f6820dbf3f..ca2c070e8c 100644 --- a/tests/dbal/migration/revert_with_dependency.php +++ b/tests/dbal/migration/revert_with_dependency.php @@ -9,7 +9,7 @@ class phpbb_dbal_migration_revert_with_dependency extends phpbb_db_migration { - function depends_on() + static public function depends_on() { return array('phpbb_dbal_migration_revert'); } diff --git a/tests/dbal/migration/unfulfillable.php b/tests/dbal/migration/unfulfillable.php index 84136ffe6d..6d375e6880 100644 --- a/tests/dbal/migration/unfulfillable.php +++ b/tests/dbal/migration/unfulfillable.php @@ -9,7 +9,7 @@ class phpbb_dbal_migration_unfulfillable extends phpbb_db_migration { - function depends_on() + static public function depends_on() { return array('installed_migration', 'phpbb_dbal_migration_dummy', 'non_existant_migration'); } From 9affd6f7e7b95442f1ef14894858d8213f3fbd2a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Jan 2013 00:41:03 +0100 Subject: [PATCH 47/90] [ticket/11201] Remove MSN/WLM fields WLM will be shutdown in March 2013. Skype is the new replacement. But as Skype uses a different login ID and service, the values in this field are useless. So we can safely remove the field and the links/functions we create. PHPBB3-11201 --- phpBB/adm/style/acp_users_profile.html | 4 - phpBB/develop/benchmark.php | 5 +- phpBB/develop/create_schema_files.php | 1 - phpBB/develop/mysql_upgrader.php | 1 - phpBB/includes/acp/acp_users.php | 4 - phpBB/includes/ucp/ucp_pm_viewmessage.php | 1 - phpBB/includes/ucp/ucp_profile.php | 4 - phpBB/install/convertors/convert_phpbb20.php | 1 - phpBB/install/schemas/firebird_schema.sql | 1 - phpBB/install/schemas/mssql_schema.sql | 1 - phpBB/install/schemas/mysql_40_schema.sql | 1 - phpBB/install/schemas/mysql_41_schema.sql | 1 - phpBB/install/schemas/oracle_schema.sql | 1 - phpBB/install/schemas/postgres_schema.sql | 1 - phpBB/install/schemas/schema_data.sql | 4 +- phpBB/install/schemas/sqlite_schema.sql | 1 - phpBB/language/en/acp/styles.php | 1 - phpBB/language/en/common.php | 3 - phpBB/language/en/memberlist.php | 4 - phpBB/language/en/ucp.php | 1 - phpBB/memberlist.php | 22 +---- .../prosilver/template/memberlist_im.html | 82 +----------------- .../prosilver/template/memberlist_search.html | 4 - .../prosilver/template/memberlist_view.html | 1 - .../template/ucp_pm_viewmessage.html | 3 +- .../template/ucp_profile_profile_info.html | 4 - .../prosilver/template/viewtopic_body.html | 3 +- phpBB/styles/prosilver/theme/bidi.css | 2 +- phpBB/styles/prosilver/theme/buttons.css | 2 - phpBB/styles/prosilver/theme/colours.css | 1 - phpBB/styles/prosilver/theme/imageset.css | 5 -- .../subsilver2/template/memberlist_im.html | 83 +------------------ .../template/memberlist_search.html | 8 +- .../subsilver2/template/memberlist_view.html | 4 - .../template/ucp_profile_profile_info.html | 4 - .../styles/subsilver2/theme/en/stylesheet.css | 5 -- phpBB/styles/subsilver2/theme/stylesheet.css | 5 -- phpBB/viewtopic.php | 4 - 38 files changed, 16 insertions(+), 267 deletions(-) diff --git a/phpBB/adm/style/acp_users_profile.html b/phpBB/adm/style/acp_users_profile.html index 3232e8d1f5..36e9f340d4 100644 --- a/phpBB/adm/style/acp_users_profile.html +++ b/phpBB/adm/style/acp_users_profile.html @@ -10,10 +10,6 @@
-
-
-
-
diff --git a/phpBB/develop/benchmark.php b/phpBB/develop/benchmark.php index c867b9262e..6517954dfe 100644 --- a/phpBB/develop/benchmark.php +++ b/phpBB/develop/benchmark.php @@ -377,7 +377,6 @@ function make_user($username) $viewemail = 0; $aim = 0; $yim = 0; - $msn = 0; $attachsig = 1; $allowsmilies = 1; $allowhtml = 1; @@ -422,8 +421,8 @@ function make_user($username) } - $sql = "INSERT INTO " . USERS_TABLE . " (user_id, username, user_regdate, user_password, user_email, user_icq, user_website, user_occ, user_from, user_interests, user_sig, user_sig_bbcode_uid, user_avatar, user_viewemail, user_aim, user_yim, user_msnm, user_attachsig, user_allowsmilies, user_allowhtml, user_allowbbcode, user_allow_viewonline, user_notify, user_notify_pm, user_timezone, user_dateformat, user_lang, user_style, user_level, user_allow_pm, user_active, user_actkey) - VALUES ($new_user_id, '$username', " . time() . ", '$password', '$email', '$icq', '$website', '$occupation', '$location', '$interests', '$signature', '$signature_bbcode_uid', '$avatar_filename', $viewemail, '$aim', '$yim', '$msn', $attachsig, $allowsmilies, $allowhtml, $allowbbcode, $allowviewonline, $notifyreply, $notifypm, $user_timezone, '$user_dateformat', '$user_lang', $user_style, 0, 1, "; + $sql = "INSERT INTO " . USERS_TABLE . " (user_id, username, user_regdate, user_password, user_email, user_icq, user_website, user_occ, user_from, user_interests, user_sig, user_sig_bbcode_uid, user_avatar, user_viewemail, user_aim, user_yim, user_attachsig, user_allowsmilies, user_allowhtml, user_allowbbcode, user_allow_viewonline, user_notify, user_notify_pm, user_timezone, user_dateformat, user_lang, user_style, user_level, user_allow_pm, user_active, user_actkey) + VALUES ($new_user_id, '$username', " . time() . ", '$password', '$email', '$icq', '$website', '$occupation', '$location', '$interests', '$signature', '$signature_bbcode_uid', '$avatar_filename', $viewemail, '$aim', '$yim', $attachsig, $allowsmilies, $allowhtml, $allowbbcode, $allowviewonline, $notifyreply, $notifypm, $user_timezone, '$user_dateformat', '$user_lang', $user_style, 0, 1, "; $sql .= "1, '')"; diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 3d3e478032..38d7a2df33 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1833,7 +1833,6 @@ function get_schema_struct() 'user_icq' => array('VCHAR:15', ''), 'user_aim' => array('VCHAR_UNI', ''), 'user_yim' => array('VCHAR_UNI', ''), - 'user_msnm' => array('VCHAR_UNI', ''), 'user_jabber' => array('VCHAR_UNI', ''), 'user_website' => array('VCHAR_UNI:200', ''), 'user_occ' => array('TEXT_UNI', ''), diff --git a/phpBB/develop/mysql_upgrader.php b/phpBB/develop/mysql_upgrader.php index 7f82ebfeab..ca738aabf6 100644 --- a/phpBB/develop/mysql_upgrader.php +++ b/phpBB/develop/mysql_upgrader.php @@ -1265,7 +1265,6 @@ function get_schema_struct() 'user_icq' => array('VCHAR:15', ''), 'user_aim' => array('VCHAR_UNI', ''), 'user_yim' => array('VCHAR_UNI', ''), - 'user_msnm' => array('VCHAR_UNI', ''), 'user_jabber' => array('VCHAR_UNI', ''), 'user_website' => array('VCHAR_UNI:200', ''), 'user_occ' => array('TEXT_UNI', ''), diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 82d8ef5cbb..2bdbf1441a 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1352,7 +1352,6 @@ class acp_users $data = array( 'icq' => request_var('icq', $user_row['user_icq']), 'aim' => request_var('aim', $user_row['user_aim']), - 'msn' => request_var('msn', $user_row['user_msnm']), 'yim' => request_var('yim', $user_row['user_yim']), 'jabber' => utf8_normalize_nfc(request_var('jabber', $user_row['user_jabber'], true)), 'website' => request_var('website', $user_row['user_website']), @@ -1382,7 +1381,6 @@ class acp_users array('string', true, 3, 15), array('match', true, '#^[0-9]+$#i')), 'aim' => array('string', true, 3, 255), - 'msn' => array('string', true, 5, 255), 'jabber' => array( array('string', true, 5, 255), array('jabber')), @@ -1416,7 +1414,6 @@ class acp_users $sql_ary = array( 'user_icq' => $data['icq'], 'user_aim' => $data['aim'], - 'user_msnm' => $data['msn'], 'user_yim' => $data['yim'], 'user_jabber' => $data['jabber'], 'user_website' => $data['website'], @@ -1469,7 +1466,6 @@ class acp_users 'ICQ' => $data['icq'], 'YIM' => $data['yim'], 'AIM' => $data['aim'], - 'MSN' => $data['msn'], 'JABBER' => $data['jabber'], 'WEBSITE' => $data['website'], 'LOCATION' => $data['location'], diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index c85b05f144..a1001cfa74 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -241,7 +241,6 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) 'U_ICQ' => ($user_info['user_icq']) ? 'http://www.icq.com/people/' . urlencode($user_info['user_icq']) . '/' : '', 'U_AIM' => ($user_info['user_aim'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=aim&u=' . $author_id) : '', 'U_YIM' => ($user_info['user_yim']) ? 'http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($user_info['user_yim']) . '&.src=pg' : '', - 'U_MSN' => ($user_info['user_msnm'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=msnm&u=' . $author_id) : '', 'U_JABBER' => ($user_info['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=jabber&u=' . $author_id) : '', 'U_DELETE' => ($auth->acl_get('u_pm_delete')) ? "$url&mode=compose&action=delete&f=$folder_id&p=" . $message_row['msg_id'] : '', diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index e7cea06a45..c1ad9955b6 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -266,7 +266,6 @@ class ucp_profile $data = array( 'icq' => request_var('icq', $user->data['user_icq']), 'aim' => request_var('aim', $user->data['user_aim']), - 'msn' => request_var('msn', $user->data['user_msnm']), 'yim' => request_var('yim', $user->data['user_yim']), 'jabber' => utf8_normalize_nfc(request_var('jabber', $user->data['user_jabber'], true)), 'website' => request_var('website', $user->data['user_website']), @@ -299,7 +298,6 @@ class ucp_profile array('string', true, 3, 15), array('match', true, '#^[0-9]+$#i')), 'aim' => array('string', true, 3, 255), - 'msn' => array('string', true, 5, 255), 'jabber' => array( array('string', true, 5, 255), array('jabber')), @@ -351,7 +349,6 @@ class ucp_profile $sql_ary = array( 'user_icq' => $data['icq'], 'user_aim' => $data['aim'], - 'user_msnm' => $data['msn'], 'user_yim' => $data['yim'], 'user_jabber' => $data['jabber'], 'user_website' => $data['website'], @@ -423,7 +420,6 @@ class ucp_profile 'ICQ' => $data['icq'], 'YIM' => $data['yim'], 'AIM' => $data['aim'], - 'MSN' => $data['msn'], 'JABBER' => $data['jabber'], 'WEBSITE' => $data['website'], 'LOCATION' => $data['location'], diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index 5f30625980..6792f4ff9c 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -896,7 +896,6 @@ if (!$get_info) array('user_occ', 'users.user_occ', array('function1' => 'phpbb_set_encoding')), array('user_website', 'users.user_website', 'validate_website'), array('user_jabber', '', ''), - array('user_msnm', 'users.user_msnm', array('function1' => 'phpbb_set_encoding')), array('user_yim', 'users.user_yim', array('function1' => 'phpbb_set_encoding')), array('user_aim', 'users.user_aim', array('function1' => 'phpbb_set_encoding')), array('user_icq', 'users.user_icq', array('function1' => 'phpbb_set_encoding')), diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index ef57df29a0..9016d8b318 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -1281,7 +1281,6 @@ CREATE TABLE phpbb_users ( user_icq VARCHAR(15) CHARACTER SET NONE DEFAULT '' NOT NULL, user_aim VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, user_yim VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_msnm VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, user_jabber VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, user_website VARCHAR(200) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, user_occ BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index a37fd2b14e..81bd0cbb0f 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -1565,7 +1565,6 @@ CREATE TABLE [phpbb_users] ( [user_icq] [varchar] (15) DEFAULT ('') NOT NULL , [user_aim] [varchar] (255) DEFAULT ('') NOT NULL , [user_yim] [varchar] (255) DEFAULT ('') NOT NULL , - [user_msnm] [varchar] (255) DEFAULT ('') NOT NULL , [user_jabber] [varchar] (255) DEFAULT ('') NOT NULL , [user_website] [varchar] (200) DEFAULT ('') NOT NULL , [user_occ] [varchar] (4000) DEFAULT ('') NOT NULL , diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 517e51d3c5..0797b6ac6b 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -929,7 +929,6 @@ CREATE TABLE phpbb_users ( user_icq varbinary(15) DEFAULT '' NOT NULL, user_aim blob NOT NULL, user_yim blob NOT NULL, - user_msnm blob NOT NULL, user_jabber blob NOT NULL, user_website blob NOT NULL, user_occ blob NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index f05322b28f..414f9f0f2a 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -929,7 +929,6 @@ CREATE TABLE phpbb_users ( user_icq varchar(15) DEFAULT '' NOT NULL, user_aim varchar(255) DEFAULT '' NOT NULL, user_yim varchar(255) DEFAULT '' NOT NULL, - user_msnm varchar(255) DEFAULT '' NOT NULL, user_jabber varchar(255) DEFAULT '' NOT NULL, user_website varchar(200) DEFAULT '' NOT NULL, user_occ text NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 993df9e82a..03c9f9fd4c 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -1677,7 +1677,6 @@ CREATE TABLE phpbb_users ( user_icq varchar2(15) DEFAULT '' , user_aim varchar2(765) DEFAULT '' , user_yim varchar2(765) DEFAULT '' , - user_msnm varchar2(765) DEFAULT '' , user_jabber varchar2(765) DEFAULT '' , user_website varchar2(600) DEFAULT '' , user_occ clob DEFAULT '' , diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index 2acdeb7f45..a6c989fe62 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -1179,7 +1179,6 @@ CREATE TABLE phpbb_users ( user_icq varchar(15) DEFAULT '' NOT NULL, user_aim varchar(255) DEFAULT '' NOT NULL, user_yim varchar(255) DEFAULT '' NOT NULL, - user_msnm varchar(255) DEFAULT '' NOT NULL, user_jabber varchar(255) DEFAULT '' NOT NULL, user_website varchar(200) DEFAULT '' NOT NULL, user_occ varchar(4000) DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 7c1a7d40f5..19c00ef9fb 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -454,10 +454,10 @@ INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts, forum_topics, forum_topics_real, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_subject, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents, forum_flags) VALUES ('{L_FORUMS_TEST_FORUM_TITLE}', '{L_FORUMS_TEST_FORUM_DESC}', 2, 3, 1, 1, 1, 1, 1, 1, 2, 'Admin', 'AA0000', '{L_TOPICS_TOPIC_TITLE}', 972086460, '', '', '', '', '', '', '', 0, 0, '', 48); # -- Users / Anonymous user -INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_from, user_icq, user_aim, user_yim, user_msnm, user_jabber, user_website, user_occ, user_interests, user_actkey, user_newpasswd, user_allow_massemail) VALUES (2, 1, 'Anonymous', 'anonymous', 0, '', '', 'en', 1, 0, '', 0, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0); +INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_from, user_icq, user_aim, user_yim, user_jabber, user_website, user_occ, user_interests, user_actkey, user_newpasswd, user_allow_massemail) VALUES (2, 1, 'Anonymous', 'anonymous', 0, '', '', 'en', 1, 0, '', 0, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', '', '', '', '', '', '', '', 0); # -- username: Admin password: admin (change this or remove it once everything is working!) -INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_from, user_icq, user_aim, user_yim, user_msnm, user_jabber, user_website, user_occ, user_interests, user_actkey, user_newpasswd) VALUES (3, 5, 'Admin', 'admin', 0, '21232f297a57a5a743894a0e4a801fc3', 'admin@yourdomain.com', 'en', 1, 1, 'AA0000', 1, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', '', '', '', '', '', '', '', ''); +INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_from, user_icq, user_aim, user_yim, user_jabber, user_website, user_occ, user_interests, user_actkey, user_newpasswd) VALUES (3, 5, 'Admin', 'admin', 0, '21232f297a57a5a743894a0e4a801fc3', 'admin@yourdomain.com', 'en', 1, 1, 'AA0000', 1, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', '', '', '', '', '', '', ''); # -- Groups INSERT INTO phpbb_groups (group_name, group_type, group_founder_manage, group_colour, group_legend, group_teampage, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('GUESTS', 3, 0, '', 0, 0, '', '', '', 5); diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 775f67c5c3..feec31d727 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -903,7 +903,6 @@ CREATE TABLE phpbb_users ( user_icq varchar(15) NOT NULL DEFAULT '', user_aim varchar(255) NOT NULL DEFAULT '', user_yim varchar(255) NOT NULL DEFAULT '', - user_msnm varchar(255) NOT NULL DEFAULT '', user_jabber varchar(255) NOT NULL DEFAULT '', user_website varchar(200) NOT NULL DEFAULT '', user_occ text(65535) NOT NULL DEFAULT '', diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php index e7954ff148..3cb2e741ca 100644 --- a/phpBB/language/en/acp/styles.php +++ b/phpBB/language/en/acp/styles.php @@ -186,7 +186,6 @@ $lang = array_merge($lang, array( 'IMG_ICON_CONTACT_EMAIL' => 'Send email', 'IMG_ICON_CONTACT_ICQ' => 'ICQ', 'IMG_ICON_CONTACT_JABBER' => 'Jabber', - 'IMG_ICON_CONTACT_MSNM' => 'WLM', 'IMG_ICON_CONTACT_PM' => 'Send message', 'IMG_ICON_CONTACT_YAHOO' => 'YIM', 'IMG_ICON_CONTACT_WWW' => 'Website', diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 6277457af7..6cad4136a2 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -368,7 +368,6 @@ $lang = array_merge($lang, array( 'MODERATORS' => 'Moderators', 'MONTH' => 'Month', 'MOVE' => 'Move', - 'MSNM' => 'WLM', 'NA' => 'N/A', 'NEWEST_USER' => 'Our newest member %s', @@ -627,7 +626,6 @@ $lang = array_merge($lang, array( 'TOO_LONG_INTERESTS' => 'The interests you entered is too long.', 'TOO_LONG_JABBER' => 'The Jabber account name you entered is too long.', 'TOO_LONG_LOCATION' => 'The location you entered is too long.', - 'TOO_LONG_MSN' => 'The WLM name you entered is too long.', 'TOO_LONG_NEW_PASSWORD' => 'The password you entered is too long.', 'TOO_LONG_OCCUPATION' => 'The occupation you entered is too long.', 'TOO_LONG_PASSWORD_CONFIRM' => 'The password confirmation you entered is too long.', @@ -648,7 +646,6 @@ $lang = array_merge($lang, array( 'TOO_SHORT_INTERESTS' => 'The interests you entered is too short.', 'TOO_SHORT_JABBER' => 'The Jabber account name you entered is too short.', 'TOO_SHORT_LOCATION' => 'The location you entered is too short.', - 'TOO_SHORT_MSN' => 'The WLM name you entered is too short.', 'TOO_SHORT_NEW_PASSWORD' => 'The password you entered is too short.', 'TOO_SHORT_OCCUPATION' => 'The occupation you entered is too short.', 'TOO_SHORT_PASSWORD_CONFIRM' => 'The password confirmation you entered is too short.', diff --git a/phpBB/language/en/memberlist.php b/phpBB/language/en/memberlist.php index ec21e8e904..bc5a0c100b 100644 --- a/phpBB/language/en/memberlist.php +++ b/phpBB/language/en/memberlist.php @@ -78,9 +78,6 @@ $lang = array_merge($lang, array( 'IM_JABBER' => 'Please note that users may have selected to not receive unsolicited instant messages.', 'IM_JABBER_SUBJECT' => 'This is an automated message please do not reply! Message from user %1$s at %2$s.', 'IM_MESSAGE' => 'Your message', - 'IM_MSNM' => 'Please note that you need Windows Live Messenger installed to use this.', - 'IM_MSNM_BROWSER' => 'Your browser does not support this.', - 'IM_MSNM_CONNECT' => 'WLM is not connected.\nYou have to connect to WLM to continue.', 'IM_NAME' => 'Your Name', 'IM_NO_DATA' => 'There is no suitable contact information for this user.', 'IM_NO_JABBER' => 'Sorry, direct messaging of Jabber users is not supported on this board. You will need a Jabber client installed on your system to contact the recipient above.', @@ -123,7 +120,6 @@ $lang = array_merge($lang, array( 'SEND_IM' => 'Instant messaging', 'SEND_JABBER_MESSAGE' => 'Send Jabber message', 'SEND_MESSAGE' => 'Message', - 'SEND_MSNM_MESSAGE' => 'Send WLM message', 'SEND_YIM_MESSAGE' => 'Send YIM message', 'SORT_EMAIL' => 'Email', 'SORT_LAST_ACTIVE' => 'Last active', diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 267ae00710..2eb34b3713 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -455,7 +455,6 @@ $lang = array_merge($lang, array( 'UCP_MAIN_FRONT' => 'Front page', 'UCP_MAIN_SUBSCRIBED' => 'Manage subscriptions', - 'UCP_MSNM' => 'Windows Live Messenger', 'UCP_NO_ATTACHMENTS' => 'You have posted no files.', 'UCP_PREFS' => 'Board preferences', diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 79be9ca432..091379061c 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -287,13 +287,6 @@ switch ($mode) $s_action = ''; break; - case 'msnm': - $lang = 'MSNM'; - $sql_field = 'user_msnm'; - $s_select = 'S_SEND_MSNM'; - $s_action = ''; - break; - case 'jabber': $lang = 'JABBER'; $sql_field = 'user_jabber'; @@ -640,7 +633,6 @@ switch ($mode) 'WWW_IMG' => $user->img('icon_contact_www', $user->lang['WWW']), 'ICQ_IMG' => $user->img('icon_contact_icq', $user->lang['ICQ']), 'AIM_IMG' => $user->img('icon_contact_aim', $user->lang['AIM']), - 'MSN_IMG' => $user->img('icon_contact_msnm', $user->lang['MSNM']), 'YIM_IMG' => $user->img('icon_contact_yahoo', $user->lang['YIM']), 'JABBER_IMG' => $user->img('icon_contact_jabber', $user->lang['JABBER']), 'SEARCH_IMG' => $user->img('icon_user_search', $user->lang['SEARCH']), @@ -984,8 +976,8 @@ switch ($mode) $template_html = 'memberlist_body.html'; // Sorting - $sort_key_text = array('a' => $user->lang['SORT_USERNAME'], 'b' => $user->lang['SORT_LOCATION'], 'c' => $user->lang['SORT_JOINED'], 'd' => $user->lang['SORT_POST_COUNT'], 'f' => $user->lang['WEBSITE'], 'g' => $user->lang['ICQ'], 'h' => $user->lang['AIM'], 'i' => $user->lang['MSNM'], 'j' => $user->lang['YIM'], 'k' => $user->lang['JABBER']); - $sort_key_sql = array('a' => 'u.username_clean', 'b' => 'u.user_from', 'c' => 'u.user_regdate', 'd' => 'u.user_posts', 'f' => 'u.user_website', 'g' => 'u.user_icq', 'h' => 'u.user_aim', 'i' => 'u.user_msnm', 'j' => 'u.user_yim', 'k' => 'u.user_jabber'); + $sort_key_text = array('a' => $user->lang['SORT_USERNAME'], 'b' => $user->lang['SORT_LOCATION'], 'c' => $user->lang['SORT_JOINED'], 'd' => $user->lang['SORT_POST_COUNT'], 'f' => $user->lang['WEBSITE'], 'g' => $user->lang['ICQ'], 'h' => $user->lang['AIM'], 'j' => $user->lang['YIM'], 'k' => $user->lang['JABBER']); + $sort_key_sql = array('a' => 'u.username_clean', 'b' => 'u.user_from', 'c' => 'u.user_regdate', 'd' => 'u.user_posts', 'f' => 'u.user_website', 'g' => 'u.user_icq', 'h' => 'u.user_aim', 'j' => 'u.user_yim', 'k' => 'u.user_jabber'); if ($auth->acl_get('a_user')) { @@ -1028,7 +1020,7 @@ switch ($mode) $select_single = request_var('select_single', false); // Search URL parameters, if any of these are in the URL we do a search - $search_params = array('username', 'email', 'icq', 'aim', 'yahoo', 'msn', 'jabber', 'search_group_id', 'joined_select', 'active_select', 'count_select', 'joined', 'active', 'count', 'ip'); + $search_params = array('username', 'email', 'icq', 'aim', 'yahoo', 'jabber', 'search_group_id', 'joined_select', 'active_select', 'count_select', 'joined', 'active', 'count', 'ip'); // We validate form and field here, only id/class allowed $form = (!preg_match('/^[a-z0-9_-]+$/i', $form)) ? '' : $form; @@ -1040,7 +1032,6 @@ switch ($mode) $icq = request_var('icq', ''); $aim = request_var('aim', ''); $yahoo = request_var('yahoo', ''); - $msn = request_var('msn', ''); $jabber = request_var('jabber', ''); $search_group_id = request_var('search_group_id', 0); @@ -1084,7 +1075,6 @@ switch ($mode) $sql_where .= ($icq) ? ' AND u.user_icq ' . $db->sql_like_expression(str_replace('*', $db->any_char, $icq)) . ' ' : ''; $sql_where .= ($aim) ? ' AND u.user_aim ' . $db->sql_like_expression(str_replace('*', $db->any_char, $aim)) . ' ' : ''; $sql_where .= ($yahoo) ? ' AND u.user_yim ' . $db->sql_like_expression(str_replace('*', $db->any_char, $yahoo)) . ' ' : ''; - $sql_where .= ($msn) ? ' AND u.user_msnm ' . $db->sql_like_expression(str_replace('*', $db->any_char, $msn)) . ' ' : ''; $sql_where .= ($jabber) ? ' AND u.user_jabber ' . $db->sql_like_expression(str_replace('*', $db->any_char, $jabber)) . ' ' : ''; $sql_where .= (is_numeric($count) && isset($find_key_match[$count_select])) ? ' AND u.user_posts ' . $find_key_match[$count_select] . ' ' . (int) $count . ' ' : ''; @@ -1317,7 +1307,6 @@ switch ($mode) 'icq' => array('icq', ''), 'aim' => array('aim', ''), 'yahoo' => array('yahoo', ''), - 'msn' => array('msn', ''), 'jabber' => array('jabber', ''), 'search_group_id' => array('search_group_id', 0), 'joined_select' => array('joined_select', 'lt'), @@ -1449,7 +1438,6 @@ switch ($mode) 'ICQ' => $icq, 'AIM' => $aim, 'YAHOO' => $yahoo, - 'MSNM' => $msn, 'JABBER' => $jabber, 'JOINED' => implode('-', $joined), 'ACTIVE' => implode('-', $active), @@ -1605,7 +1593,6 @@ switch ($mode) 'WWW_IMG' => $user->img('icon_contact_www', $user->lang['WWW']), 'ICQ_IMG' => $user->img('icon_contact_icq', $user->lang['ICQ']), 'AIM_IMG' => $user->img('icon_contact_aim', $user->lang['AIM']), - 'MSN_IMG' => $user->img('icon_contact_msnm', $user->lang['MSNM']), 'YIM_IMG' => $user->img('icon_contact_yahoo', $user->lang['YIM']), 'JABBER_IMG' => $user->img('icon_contact_jabber', $user->lang['JABBER']), 'SEARCH_IMG' => $user->img('icon_user_search', $user->lang['SEARCH']), @@ -1621,7 +1608,6 @@ switch ($mode) 'U_SORT_LOCATION' => $sort_url . '&sk=b&sd=' . (($sort_key == 'b' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_ICQ' => $sort_url . '&sk=g&sd=' . (($sort_key == 'g' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_AIM' => $sort_url . '&sk=h&sd=' . (($sort_key == 'h' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_MSN' => $sort_url . '&sk=i&sd=' . (($sort_key == 'i' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_YIM' => $sort_url . '&sk=j&sd=' . (($sort_key == 'j' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_ACTIVE' => ($auth->acl_get('u_viewonline')) ? $sort_url . '&sk=l&sd=' . (($sort_key == 'l' && $sort_dir == 'a') ? 'd' : 'a') : '', 'U_SORT_RANK' => $sort_url . '&sk=m&sd=' . (($sort_key == 'm' && $sort_dir == 'a') ? 'd' : 'a'), @@ -1748,14 +1734,12 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f 'U_ICQ' => ($data['user_icq']) ? 'http://www.icq.com/people/' . urlencode($data['user_icq']) . '/' : '', 'U_AIM' => ($data['user_aim'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=aim&u=' . $user_id) : '', 'U_YIM' => ($data['user_yim']) ? 'http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($data['user_yim']) . '&.src=pg' : '', - 'U_MSN' => ($data['user_msnm'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=msnm&u=' . $user_id) : '', 'U_JABBER' => ($data['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=jabber&u=' . $user_id) : '', 'LOCATION' => ($data['user_from']) ? $data['user_from'] : '', 'USER_ICQ' => $data['user_icq'], 'USER_AIM' => $data['user_aim'], 'USER_YIM' => $data['user_yim'], - 'USER_MSN' => $data['user_msnm'], 'USER_JABBER' => $data['user_jabber'], 'USER_JABBER_IMG' => ($data['user_jabber']) ? $user->img('icon_contact_jabber', $data['user_jabber']) : '', diff --git a/phpBB/styles/prosilver/template/memberlist_im.html b/phpBB/styles/prosilver/template/memberlist_im.html index 68aed0b3dd..61b4a1469b 100644 --- a/phpBB/styles/prosilver/template/memberlist_im.html +++ b/phpBB/styles/prosilver/template/memberlist_im.html @@ -1,6 +1,5 @@ -

{L_SEND_IM}

@@ -13,7 +12,7 @@
-
{USERNAME} [ {IM_CONTACT} ] {PRESENCE_IMG}
+
{USERNAME} [ {IM_CONTACT} ] {PRESENCE_IMG}
@@ -43,15 +42,6 @@
- -
-
 
-
-
{L_IM_ADD_CONTACT}
-
{L_IM_SEND_MESSAGE}
-
- -
@@ -85,74 +75,4 @@ {L_CLOSE_WINDOW} - - diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html index 6fed528cea..1ef8710817 100644 --- a/phpBB/styles/prosilver/template/memberlist_search.html +++ b/phpBB/styles/prosilver/template/memberlist_search.html @@ -71,10 +71,6 @@ function insert_single(user)
-
-
-
-
diff --git a/phpBB/styles/prosilver/template/memberlist_view.html b/phpBB/styles/prosilver/template/memberlist_view.html index 57cfcb86d9..7f33e70e8f 100644 --- a/phpBB/styles/prosilver/template/memberlist_view.html +++ b/phpBB/styles/prosilver/template/memberlist_view.html @@ -62,7 +62,6 @@
{L_EMAIL_ADDRESS}{L_COLON}
{L_SEND_EMAIL_USER} {USERNAME}
{L_WEBSITE}{L_COLON}
{U_WWW}
{L_PM}{L_COLON}
{L_SEND_PRIVATE_MESSAGE}
-
{L_MSNM}{L_COLON}
{L_SEND_MSNM_MESSAGE}{USER_MSN}
{L_YIM}{L_COLON}
{L_SEND_YIM_MESSAGE}{USER_YIM}
{L_AIM}{L_COLON}
{L_SEND_AIM_MESSAGE}{USER_AIM}
{L_ICQ}{L_COLON}
{L_SEND_ICQ_MESSAGE}{USER_ICQ}
diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index 22149c8b80..23665aa252 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -90,13 +90,12 @@ - +
  • {L_PRIVATE_MESSAGE}
  • {L_WEBSITE}
  • -
  • {L_MSNM}
  • {L_ICQ}
  • {L_YIM}
  • {L_AIM}
  • diff --git a/phpBB/styles/prosilver/template/ucp_profile_profile_info.html b/phpBB/styles/prosilver/template/ucp_profile_profile_info.html index 03d89e8590..e8c6715de8 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_profile_info.html +++ b/phpBB/styles/prosilver/template/ucp_profile_profile_info.html @@ -18,10 +18,6 @@
    -
    -
    -
    -
    diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 7688898f5c..9910be34b0 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -216,13 +216,12 @@ - +
    • {L_PRIVATE_MESSAGE}
    • {L_WEBSITE}
    • -
    • {L_MSNM}
    • {L_ICQ}
    • {L_YIM}
    • {L_AIM}
    • diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css index 5cff0a811b..a43323d879 100644 --- a/phpBB/styles/prosilver/theme/bidi.css +++ b/phpBB/styles/prosilver/theme/bidi.css @@ -786,7 +786,7 @@ padding-right: 11px; padding-left: 0; } -.rtl .imageset.icon_contact_aim, .rtl .imageset.icon_contact_email, .rtl .imageset.icon_contact_icq, .rtl .imageset.icon_contact_jabber, .rtl .imageset.icon_contact_msnm, .rtl .imageset.icon_contact_www, .rtl .imageset.icon_contact_yahoo, .rtl .imageset.icon_post_delete, .rtl .imageset.icon_post_info, .rtl .imageset.icon_post_report, .rtl .imageset.icon_user_warn { +.rtl .imageset.icon_contact_aim, .rtl .imageset.icon_contact_email, .rtl .imageset.icon_contact_icq, .rtl .imageset.icon_contact_jabber, .rtl .imageset.icon_contact_www, .rtl .imageset.icon_contact_yahoo, .rtl .imageset.icon_post_delete, .rtl .imageset.icon_post_info, .rtl .imageset.icon_post_report, .rtl .imageset.icon_user_warn { padding-right: 20px; padding-left: 0; } diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index e817380f8e..f74e82a123 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -122,7 +122,6 @@ ul.profile-icons li a:hover { background: none; } .aim-icon, .aim-icon a { background: none top left no-repeat; } .yahoo-icon, .yahoo-icon a { background: none top left no-repeat; } .web-icon, .web-icon a { background: none top left no-repeat; } -.msnm-icon, .msnm-icon a { background: none top left no-repeat; } .icq-icon, .icq-icon a { background: none top left no-repeat; } .jabber-icon, .jabber-icon a { background: none top left no-repeat; } .pm-icon, .pm-icon a { background: none top left no-repeat; } @@ -140,7 +139,6 @@ ul.profile-icons li.email-icon { width: 20px; height: 20px; } ul.profile-icons li.aim-icon { width: 20px; height: 20px; } ul.profile-icons li.yahoo-icon { width: 20px; height: 20px; } ul.profile-icons li.web-icon { width: 20px; height: 20px; } -ul.profile-icons li.msnm-icon { width: 20px; height: 20px; } ul.profile-icons li.icq-icon { width: 20px; height: 20px; } ul.profile-icons li.jabber-icon { width: 20px; height: 20px; } ul.profile-icons li.pm-icon { width: 28px; height: 20px; } diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index a5a18dc6a1..199d7b3059 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -686,7 +686,6 @@ a.sendemail { .aim-icon, .aim-icon a { background-image: url("./images/icon_contact_aim.gif"); } .yahoo-icon, .yahoo-icon a { background-image: url("./images/icon_contact_yahoo.gif"); } .web-icon, .web-icon a { background-image: url("./images/icon_contact_www.gif"); } -.msnm-icon, .msnm-icon a { background-image: url("./images/icon_contact_msnm.gif"); } .icq-icon, .icq-icon a { background-image: url("./images/icon_contact_icq.gif"); } .jabber-icon, .jabber-icon a { background-image: url("./images/icon_contact_jabber.gif"); } .pm-icon, .pm-icon a { background-image: url("./en/icon_contact_pm.gif"); } diff --git a/phpBB/styles/prosilver/theme/imageset.css b/phpBB/styles/prosilver/theme/imageset.css index cb99e9e715..a85e320f98 100644 --- a/phpBB/styles/prosilver/theme/imageset.css +++ b/phpBB/styles/prosilver/theme/imageset.css @@ -280,11 +280,6 @@ span.imageset { padding-left: 20px; padding-top: 20px; } -.imageset.icon_contact_msnm { - background-image: url("./images/icon_contact_msnm.gif"); - padding-left: 20px; - padding-top: 20px; -} .imageset.icon_contact_www { background-image: url("./images/icon_contact_www.gif"); padding-left: 20px; diff --git a/phpBB/styles/subsilver2/template/memberlist_im.html b/phpBB/styles/subsilver2/template/memberlist_im.html index da1ad661c3..e91a1caf11 100644 --- a/phpBB/styles/subsilver2/template/memberlist_im.html +++ b/phpBB/styles/subsilver2/template/memberlist_im.html @@ -2,8 +2,6 @@
      - -
@@ -14,7 +12,7 @@ - + @@ -26,85 +24,6 @@ - - - - - - - - - diff --git a/phpBB/styles/subsilver2/template/memberlist_search.html b/phpBB/styles/subsilver2/template/memberlist_search.html index c0434d8110..fb76cacc79 100644 --- a/phpBB/styles/subsilver2/template/memberlist_search.html +++ b/phpBB/styles/subsilver2/template/memberlist_search.html @@ -102,14 +102,14 @@ - - + + - - + + diff --git a/phpBB/styles/subsilver2/template/memberlist_view.html b/phpBB/styles/subsilver2/template/memberlist_view.html index 464369a7a8..ff22dcc0f7 100644 --- a/phpBB/styles/subsilver2/template/memberlist_view.html +++ b/phpBB/styles/subsilver2/template/memberlist_view.html @@ -116,10 +116,6 @@ - - - - diff --git a/phpBB/styles/subsilver2/template/ucp_profile_profile_info.html b/phpBB/styles/subsilver2/template/ucp_profile_profile_info.html index 19259aebc8..69da5f6172 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_profile_info.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_profile_info.html @@ -20,10 +20,6 @@ - - - - diff --git a/phpBB/styles/subsilver2/theme/en/stylesheet.css b/phpBB/styles/subsilver2/theme/en/stylesheet.css index 563492d4fc..6ddecf963b 100644 --- a/phpBB/styles/subsilver2/theme/en/stylesheet.css +++ b/phpBB/styles/subsilver2/theme/en/stylesheet.css @@ -19,11 +19,6 @@ padding-left: 72px; padding-top: 20px; } -.imageset.icon_contact_msnm { - background-image: url("./icon_contact_msnm.gif"); - padding-left: 72px; - padding-top: 20px; -} .imageset.icon_contact_pm { background-image: url("./icon_contact_pm.gif"); padding-left: 72px; diff --git a/phpBB/styles/subsilver2/theme/stylesheet.css b/phpBB/styles/subsilver2/theme/stylesheet.css index 977e5c20c6..e7e64eff32 100644 --- a/phpBB/styles/subsilver2/theme/stylesheet.css +++ b/phpBB/styles/subsilver2/theme/stylesheet.css @@ -1008,11 +1008,6 @@ a.imageset { padding-left: 72px; padding-top: 20px; } -.imageset.icon_contact_msnm { - background-image: url("./en/icon_contact_msnm.gif"); - padding-left: 72px; - padding-top: 20px; -} .imageset.icon_contact_pm { background-image: url("./en/icon_contact_pm.gif"); padding-left: 72px; diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index bd2c7bea77..fcf34a139a 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -617,7 +617,6 @@ $template->assign_vars(array( 'WWW_IMG' => $user->img('icon_contact_www', 'VISIT_WEBSITE'), 'ICQ_IMG' => $user->img('icon_contact_icq', 'ICQ'), 'AIM_IMG' => $user->img('icon_contact_aim', 'AIM'), - 'MSN_IMG' => $user->img('icon_contact_msnm', 'MSNM'), 'YIM_IMG' => $user->img('icon_contact_yahoo', 'YIM'), 'JABBER_IMG' => $user->img('icon_contact_jabber', 'JABBER') , 'REPORT_IMG' => $user->img('icon_post_report', 'REPORT_POST'), @@ -1095,7 +1094,6 @@ while ($row = $db->sql_fetchrow($result)) 'icq_status_img' => '', 'icq' => '', 'aim' => '', - 'msn' => '', 'yim' => '', 'jabber' => '', 'search' => '', @@ -1163,7 +1161,6 @@ while ($row = $db->sql_fetchrow($result)) 'profile' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=viewprofile&u=$poster_id"), 'www' => $row['user_website'], 'aim' => ($row['user_aim'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&action=aim&u=$poster_id") : '', - 'msn' => ($row['user_msnm'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&action=msnm&u=$poster_id") : '', 'yim' => ($row['user_yim']) ? 'http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($row['user_yim']) . '&.src=pg' : '', 'jabber' => ($row['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&action=jabber&u=$poster_id") : '', 'search' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id=$poster_id&sr=posts") : '', @@ -1585,7 +1582,6 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'U_WWW' => $user_cache[$poster_id]['www'], 'U_ICQ' => $user_cache[$poster_id]['icq'], 'U_AIM' => $user_cache[$poster_id]['aim'], - 'U_MSN' => $user_cache[$poster_id]['msn'], 'U_YIM' => $user_cache[$poster_id]['yim'], 'U_JABBER' => $user_cache[$poster_id]['jabber'], From 93f9ebbb258a06e34198cffda0f5fd8dfdf29597 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sat, 12 Jan 2013 18:27:33 -0600 Subject: [PATCH 48/90] [feature/migrations] Make load_migrations recursive (optionally) PHPBB3-9737 --- phpBB/includes/db/migrator.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 2ec44a5a45..6b249e3ee0 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -127,7 +127,6 @@ class phpbb_db_migrator /** * Load migration data files from a directory * - * This does not loop through sub-directories. * Migration data files loaded with this function MUST contain * ONLY ONE class in them (or an exception will be thrown). * @@ -137,9 +136,10 @@ class phpbb_db_migrator * If FALSE, we will not check. You SHOULD check at least once * to prevent errors (if including multiple directories, check * with the last call to prevent throwing errors unnecessarily). - * @return array Array of migrations with names + * @param bool $recursive Set to true to also load data files from subdirectories + * @return array Array of migration names */ - public function load_migrations($path, $check_fulfillable = true) + public function load_migrations($path, $check_fulfillable = true, $recursive = true) { if (!is_dir($path)) { @@ -149,6 +149,17 @@ class phpbb_db_migrator $handle = opendir($path); while (($file = readdir($handle)) !== false) { + if ($file == '.' || $file == '..') + { + continue; + } + + // Recursion through subdirectories + if (is_dir($path . $file) && $recursive) + { + $this->load_migrations($path . $file . '/', $check_fulfillable, $recursive); + } + if (strpos($file, '_') !== 0 && strrpos($file, '.' . $this->php_ext) === (strlen($file) - strlen($this->php_ext) - 1)) { // We try to find what class existed by comparing the classes declared before and after including the file. From 26c16559c3496f5496ad6e83e55c40f03edda5bd Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sun, 13 Jan 2013 12:39:08 -0600 Subject: [PATCH 49/90] [feature/migrations] Function effectively_installed() in migrations Allows you to check if the migration is effectively installed (entirely optionall) This function is intended to help moving to migrations from a previous database updater, where some migrations may have been installed already even though they are not yet listed in the migrations table. PHPBB3-9737 --- phpBB/includes/db/migration/migration.php | 15 ++++++++++++ phpBB/includes/db/migrator.php | 20 ++++++++++++--- tests/dbal/migration/installed.php | 30 +++++++++++++++++++++++ tests/dbal/migrator_test.php | 21 ++++++++++++++++ 4 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 tests/dbal/migration/installed.php diff --git a/phpBB/includes/db/migration/migration.php b/phpBB/includes/db/migration/migration.php index 4271751362..cf1e97b3b1 100644 --- a/phpBB/includes/db/migration/migration.php +++ b/phpBB/includes/db/migration/migration.php @@ -83,6 +83,21 @@ abstract class phpbb_db_migration return array(); } + /** + * Allows you to check if the migration is effectively installed (entirely optionall) + * + * This is checked when a migration is installed. If true is returned, the migration will be set as + * installed without performing the database changes. + * This function is intended to help moving to migrations from a previous database updater, where some + * migrations may have been installed already even though they are not yet listed in the migrations table. + * + * @return bool True if this migration is installed, False if this migration is not installed (checked on install) + */ + public function effectively_installed() + { + return false; + } + /** * Updates the database schema by providing a set of change instructions * diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 6b249e3ee0..b56da95b1a 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -271,10 +271,24 @@ class phpbb_db_migrator 'class' => $migration, ); - if (!isset($this->migration_state[$name])) + if ($migration->effectively_installed()) { - $state['migration_start_time'] = time(); - $this->insert_migration($name, $state); + $state = array( + 'migration_depends_on' => $migration->depends_on(), + 'migration_schema_done' => true, + 'migration_data_done' => true, + 'migration_data_state' => '', + 'migration_start_time' => 0, + 'migration_end_time' => 0, + ); + } + else + { + if (!isset($this->migration_state[$name])) + { + $state['migration_start_time'] = time(); + $this->insert_migration($name, $state); + } } if (!$state['migration_schema_done']) diff --git a/tests/dbal/migration/installed.php b/tests/dbal/migration/installed.php new file mode 100644 index 0000000000..01829f7a99 --- /dev/null +++ b/tests/dbal/migration/installed.php @@ -0,0 +1,30 @@ +fail('Revert did not remove test_column.'); } } + + public function test_installed() + { + $this->migrator->set_migrations(array('phpbb_dbal_migration_installed')); + + global $migrator_test_installed_failed; + $migrator_test_installed_failed = false; + + while (!$this->migrator->finished()) + { + $this->migrator->update(); + } + + $this->assertTrue($this->migrator->migration_state('phpbb_dbal_migration_installed') !== false); + + if ($migrator_test_installed_failed) + { + $this->fail('Installed test failed'); + } + } } From 000b8fefd2788c7f9f6aa6efc1d93658a00e48bd Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sun, 13 Jan 2013 13:21:01 -0600 Subject: [PATCH 50/90] [feature/migrations] Function to populate the migrations table (for install) PHPBB3-9737 --- phpBB/includes/db/migrator.php | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index b56da95b1a..69a5a4dd9c 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -124,6 +124,42 @@ class phpbb_db_migrator $this->migrations = $class_names; } + /** + * This function adds all migrations in a specified directory to the migrations table + * + * THIS SHOULD NOT GENERALLY BE USED! THIS IS FOR THE PHPBB INSTALLER. + * THIS WILL THROW ERRORS IF MIGRATIONS ALREADY EXIST IN THE TABLE, DO NOT CALL MORE THAN ONCE! + * + * @param string $path Path to migration data files + * @param bool $recursive Set to true to also load data files from subdirectories + * @return null + */ + public function populate_migrations_from_directory($path, $recursive = true) + { + $existing_migrations = $this->migrations; + + $this->migrations = array(); + $this->load_migrations($path, true, $recursive); + + foreach ($this->migrations as $name) + { + if ($this->migration_state($name) === false) + { + $state = array( + 'migration_depends_on' => $name::depends_on(), + 'migration_schema_done' => true, + 'migration_data_done' => true, + 'migration_data_state' => '', + 'migration_start_time' => time(), + 'migration_end_time' => time(), + ); + $this->insert_migration($name, $state); + } + } + + $this->migrations = $existing_migrations; + } + /** * Load migration data files from a directory * From ccd08e21f6ae97ff0ff628ff29935a70bdd7a58d Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sun, 13 Jan 2013 13:34:16 -0600 Subject: [PATCH 51/90] [feature/migrations] Make sure migration data not done before running data step PHPBB3-9737 --- phpBB/includes/db/migrator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php index 69a5a4dd9c..d95283ae01 100644 --- a/phpBB/includes/db/migrator.php +++ b/phpBB/includes/db/migrator.php @@ -332,7 +332,7 @@ class phpbb_db_migrator $this->apply_schema_changes($migration->update_schema()); $state['migration_schema_done'] = true; } - else + else if (!$state['migration_data_done']) { try { From 90235754b3919eafcb47047a8aac0fa0f075087e Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sun, 13 Jan 2013 18:28:51 -0500 Subject: [PATCH 52/90] [ticket/11323] Backport include_define test to olympus. PHPBB3-11323 --- tests/template/template_test.php | 7 +++++++ tests/template/templates/include_define.html | 2 ++ 2 files changed, 9 insertions(+) create mode 100644 tests/template/templates/include_define.html diff --git a/tests/template/template_test.php b/tests/template/template_test.php index 9b3c6ac245..83af63cdd9 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -232,6 +232,13 @@ class phpbb_template_template_test extends phpbb_test_case array(), 'value', ), + array( + 'include_define.html', + array('VARIABLE' => 'value'), + array(), + array(), + 'value', + ), array( 'loop_vars.html', array(), diff --git a/tests/template/templates/include_define.html b/tests/template/templates/include_define.html new file mode 100644 index 0000000000..2419c8cba1 --- /dev/null +++ b/tests/template/templates/include_define.html @@ -0,0 +1,2 @@ + + From 63b037b4bd1d1d3650235081b8d834a27719d2e1 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 15 Jan 2013 23:12:44 +0200 Subject: [PATCH 53/90] [ticket/10431] Adjustments for large buttons Changing CSS for large buttons to display better on Mac browsers. Fixing tabs. PHPBB3-10431 --- phpBB/styles/prosilver/theme/buttons.css | 67 ++++++++++++------------ 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index 02f973d0ff..543d9d8183 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -18,56 +18,57 @@ /* Rolloff state */ .buttons div a { - display: inline-block; - line-height: 16px; - font-size: 13px; + display: inline-block; + line-height: 17.5px; + height: 18px; + font-size: 13px; white-space: nowrap; - border: 1px solid #c7c3bf; - border-radius: 4px; + border: 1px solid #c7c3bf; + border-radius: 4px; background: #fff none 0 0 repeat-x; - background-image: -moz-linear-gradient(top, #fff, #e9e9e9); - background-image: -webkit-linear-gradient(top, #fff, #e9e9e9); - background-image: -o-linear-gradient(top, #fff, #e9e9e9); - background-image: linear-gradient(to bottom, #fff, #e9e9e9); + background-image: -moz-linear-gradient(top, #fff, #e9e9e9); + background-image: -webkit-linear-gradient(top, #fff, #e9e9e9); + background-image: -o-linear-gradient(top, #fff, #e9e9e9); + background-image: linear-gradient(to bottom, #fff, #e9e9e9); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff', EndColorStr='#e9e9e9')"; - box-shadow: 0 0 0 1px #fff inset; - -webkit-box-shadow: 0 0 0 1px #fff inset; - text-shadow: 1px 1px 0 #fff, -1px -1px 1px rgba(188, 42, 77, 0.25); - padding: 3px 22px 3px 8px; - font-family: "Futura-Medium", Verdana, Arial, Helvetica; - color: #bc2a4d !important; - position: relative; - text-decoration: none !important; - outline-style: none !important; + box-shadow: 0 0 0 1px #fff inset; + -webkit-box-shadow: 0 0 0 1px #fff inset; + padding: 2px 22px 2px 8px; + font-family: Verdana, Arial, Helvetica; + color: #bc2a4d !important; + position: relative; + text-decoration: none !important; + outline-style: none !important; + vertical-align: bottom; *padding-right: 8px; } .buttons div span { display: none; } .buttons div a:hover { - border-color: #0a8ed0; - background-image: -moz-linear-gradient(top, #e9e9e9, #fff); - background-image: -webkit-linear-gradient(top, #e9e9e9, #fff); - background-image: -o-linear-gradient(top, #e9e9e9, #fff); - background-image: linear-gradient(to bottom, #e9e9e9, #fff); + border-color: #0a8ed0; + background-image: -moz-linear-gradient(top, #e9e9e9, #fff); + background-image: -webkit-linear-gradient(top, #e9e9e9, #fff); + background-image: -o-linear-gradient(top, #e9e9e9, #fff); + background-image: linear-gradient(to bottom, #e9e9e9, #fff); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#e9e9e9', EndColorStr='#ffffff')"; - text-shadow: 1px 1px 0 #fff, -1px -1px 0 #fff, -1px -1px 0 rgba(188, 42, 77, 0.2); + text-shadow: 1px 1px 0 #fff, -1px -1px 0 #fff, -1px -1px 0 rgba(188, 42, 77, 0.2); } .buttons div a:after { - content: ''; - display: block; - position: absolute; - top: 50%; - right: 6px; - width: 12px; - height: 12px; + content: ''; + display: block; + position: absolute; + top: 50%; + right: 6px; + width: 12px; + height: 12px; margin-top: -6px; - background: url("images/buttons.png") 0px 0 no-repeat; + background: url("images/buttons.png") 0px 0 no-repeat; } .buttons div a:hover:after { - background-position: 0 -20px; + background-position: 0 -20px; } /* Big button images */ .buttons div.reply-icon a:after, .buttons div.pmreply-icon a:after { background-position: -20px 0; } From 74b09c01ffce189c73053f2d3749740254287aa7 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Wed, 16 Jan 2013 00:03:17 +0200 Subject: [PATCH 54/90] [ticket/10431] Remove reply-all custom css Remove CSS for reply-all button that is no longer used PHPBB3-10431 --- phpBB/styles/prosilver/theme/cp.css | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css index da3ec1736e..e32ff8fcb8 100644 --- a/phpBB/styles/prosilver/theme/cp.css +++ b/phpBB/styles/prosilver/theme/cp.css @@ -287,20 +287,6 @@ dl.mini dd { line-height: 2.5em; } -/* PM panel adjustments */ -.reply-all a.left { - background-position: 3px 60%; -} - -.reply-all a.left:hover { - background-position: 0px 60%; -} - -.reply-all { - font-size: 11px; - padding-top: 5px; -} - /* Defined rules list for PM options */ ol.def-rules { padding-left: 0; From 107a9016f1d4677f059cd0e10ccfdd8bd79cfce2 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Wed, 16 Jan 2013 00:09:10 +0200 Subject: [PATCH 55/90] [ticket/10431] Remove .left class from reply-all Remove .left class from .reply-all button PHPBB3-10431 --- phpBB/styles/prosilver/template/ucp_pm_message_header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/styles/prosilver/template/ucp_pm_message_header.html b/phpBB/styles/prosilver/template/ucp_pm_message_header.html index 29e6a5a46b..f03b7c2c86 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_message_header.html +++ b/phpBB/styles/prosilver/template/ucp_pm_message_header.html @@ -11,7 +11,7 @@ - + From 460470229d972b93ef5a98b0d1d97a2a970d684f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 16 Jan 2013 01:08:34 +0100 Subject: [PATCH 56/90] [ticket/11201] Remove database column on update PHPBB3-11201 --- phpBB/install/database_update.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 8950d677ae..3de9ce2717 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -1193,6 +1193,11 @@ function database_update_info() 'user_timezone' => array('VCHAR:100', ''), ), ), + 'drop_columns' => array( + USERS_TABLE => array( + 'user_msnm', + ), + ), ), ); } From de541ac13b44d1f52e1ba4bb626b9ec4e124557f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Fri, 20 Apr 2012 00:19:50 -0400 Subject: [PATCH 57/90] [ticket/10786] Javascript toggle member search panel in memberlist.php PHPBB3-10786 --- phpBB/memberlist.php | 8 ++-- phpBB/styles/prosilver/template/forum_fn.js | 37 +++++++++++++++++ .../prosilver/template/memberlist_body.html | 11 ++--- .../prosilver/template/memberlist_search.html | 3 +- .../subsilver2/template/memberlist_body.html | 8 ++-- .../template/memberlist_search.html | 41 ++++++++++++++++++- 6 files changed, 89 insertions(+), 19 deletions(-) diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 091379061c..681e51e3fd 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -1025,7 +1025,7 @@ switch ($mode) // We validate form and field here, only id/class allowed $form = (!preg_match('/^[a-z0-9_-]+$/i', $form)) ? '' : $form; $field = (!preg_match('/^[a-z0-9_-]+$/i', $field)) ? '' : $field; - if (($mode == 'searchuser' || sizeof(array_intersect($request->variable_names(phpbb_request_interface::GET), $search_params)) > 0) && ($config['load_search'] || $auth->acl_get('a_'))) + if ((in_array($mode, array('', 'searchuser')) || sizeof(array_intersect($request->variable_names(phpbb_request_interface::GET), $search_params)) > 0) && ($config['load_search'] || $auth->acl_get('a_'))) { $username = request_var('username', '', true); $email = strtolower(request_var('email', '')); @@ -1377,7 +1377,7 @@ switch ($mode) } // Some search user specific data - if ($mode == 'searchuser' && ($config['load_search'] || $auth->acl_get('a_'))) + if (in_array($mode, array('', 'searchuser')) && ($config['load_search'] || $auth->acl_get('a_'))) { $group_selected = request_var('search_group_id', 0); $s_group_select = ''; @@ -1447,7 +1447,7 @@ switch ($mode) 'S_IP_SEARCH_ALLOWED' => ($auth->acl_getf_global('m_info')) ? true : false, 'S_EMAIL_SEARCH_ALLOWED'=> ($auth->acl_get('a_user')) ? true : false, 'S_IN_SEARCH_POPUP' => ($form && $field) ? true : false, - 'S_SEARCH_USER' => true, + 'S_SEARCH_USER' => ($mode == 'searchuser' || ($mode == '' && $submit)) ? true : false, 'S_FORM_NAME' => $form, 'S_FIELD_NAME' => $field, 'S_SELECT_SINGLE' => $select_single, @@ -1598,7 +1598,7 @@ switch ($mode) 'SEARCH_IMG' => $user->img('icon_user_search', $user->lang['SEARCH']), 'U_FIND_MEMBER' => ($config['load_search'] || $auth->acl_get('a_')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser' . (($start) ? "&start=$start" : '') . (!empty($params) ? '&' . implode('&', $params) : '')) : '', - 'U_HIDE_FIND_MEMBER' => ($mode == 'searchuser') ? $u_hide_find_member : '', + 'U_HIDE_FIND_MEMBER' => ($mode == 'searchuser' || ($mode == '' && $submit)) ? $u_hide_find_member : '', 'U_SORT_USERNAME' => $sort_url . '&sk=a&sd=' . (($sort_key == 'a' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_FROM' => $sort_url . '&sk=b&sd=' . (($sort_key == 'b' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_JOINED' => $sort_url . '&sk=c&sd=' . (($sort_key == 'c' && $sort_dir == 'a') ? 'd' : 'a'), diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js index 995b4b0ab7..527a064fa9 100644 --- a/phpBB/styles/prosilver/template/forum_fn.js +++ b/phpBB/styles/prosilver/template/forum_fn.js @@ -433,6 +433,43 @@ function apply_onkeypress_event() } } +/** +* Toggle a section's visibility status +*/ +function toggle_section(link, panel_id, expand_text, collapse_text) +{ + if (jquery_present) + { + var panel = jQuery('#' + panel_id); + if (panel.is(':visible')) + { + jQuery(link).text(expand_text); + panel.slideUp('fast'); + } + else + { + jQuery(link).text(collapse_text); + panel.slideDown('fast'); + } + } + else + { + var panel = document.getElementById(panel_id); + if (panel.style.display == 'none') + { + link.innerHTML = collapse_text; + panel.style.display = ''; + } + else + { + link.innerHTML = expand_text; + panel.style.display = 'none'; + } + } + + return false; +} + /** * Detect JQuery existance. We currently do not deliver it, but some styles do, so why not benefit from it. ;) */ diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html index 4ba0c5cb2a..023c0e1e4e 100644 --- a/phpBB/styles/prosilver/template/memberlist_body.html +++ b/phpBB/styles/prosilver/template/memberlist_body.html @@ -3,13 +3,11 @@ - - - - - + @@ -32,8 +30,7 @@ + - +
{L_IM_RECIPIENT}{L_COLON} {USERNAME} [ {IM_CONTACT} ] {PRESENCE_IMG}{USERNAME} [ {IM_CONTACT} ] {PRESENCE_IMG}
- - - - {L_IM_ADD_CONTACT}
{L_IM_SEND_MESSAGE} -
 
{L_IM_MESSAGE}{L_COLON}   {L_MSNM}{L_COLON}{L_JABBER}{L_COLON}
{L_POSTS}{L_COLON} {L_JABBER}{L_COLON}  
{L_SORT_BY}{L_COLON}{PM_IMG}
{L_MSNM}{L_COLON} {MSN_IMG}{USER_MSN}
{L_YIM}{L_COLON} {YIM_IMG}{USER_YIM}{L_UCP_AIM}{L_COLON}
{L_UCP_MSNM}{L_COLON}
{L_UCP_YIM}{L_COLON} {L_FIND_USERNAME}{L_FIND_USERNAME} {L_HIDE_MEMBER_SEARCH}{L_HIDE_MEMBER_SEARCH}
diff --git a/phpBB/styles/subsilver2/template/memberlist_search.html b/phpBB/styles/subsilver2/template/memberlist_search.html index fb76cacc79..f1f96e1ecd 100644 --- a/phpBB/styles/subsilver2/template/memberlist_search.html +++ b/phpBB/styles/subsilver2/template/memberlist_search.html @@ -1,8 +1,8 @@ - - From babe07caefe8a035f711fd76c38b4dbeb0a8e804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Tue, 26 Jun 2012 00:37:48 -0400 Subject: [PATCH 58/90] [ticket/10786] Javascript toggle member search panel in memberlist.php Search functions on the memberlist.php page are now rendered by default and displayed via javascript. If javascript is disabled the page still works as it previously did. PHPBB3-10786 --- phpBB/memberlist.php | 6 +-- phpBB/styles/prosilver/template/ajax.js | 13 +++++- phpBB/styles/prosilver/template/forum_fn.js | 37 ----------------- .../prosilver/template/memberlist_body.html | 2 +- .../subsilver2/template/memberlist_body.html | 8 ++-- .../template/memberlist_search.html | 41 +------------------ 6 files changed, 22 insertions(+), 85 deletions(-) diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 681e51e3fd..ebc1757810 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -1025,7 +1025,7 @@ switch ($mode) // We validate form and field here, only id/class allowed $form = (!preg_match('/^[a-z0-9_-]+$/i', $form)) ? '' : $form; $field = (!preg_match('/^[a-z0-9_-]+$/i', $field)) ? '' : $field; - if ((in_array($mode, array('', 'searchuser')) || sizeof(array_intersect($request->variable_names(phpbb_request_interface::GET), $search_params)) > 0) && ($config['load_search'] || $auth->acl_get('a_'))) + if ((($mode == '' || $mode == 'searchuser') || sizeof(array_intersect($request->variable_names(phpbb_request_interface::GET), $search_params)) > 0) && ($config['load_search'] || $auth->acl_get('a_'))) { $username = request_var('username', '', true); $email = strtolower(request_var('email', '')); @@ -1377,7 +1377,7 @@ switch ($mode) } // Some search user specific data - if (in_array($mode, array('', 'searchuser')) && ($config['load_search'] || $auth->acl_get('a_'))) + if (($mode == '' || $mode == 'searchuser') && ($config['load_search'] || $auth->acl_get('a_'))) { $group_selected = request_var('search_group_id', 0); $s_group_select = ''; @@ -1447,7 +1447,7 @@ switch ($mode) 'S_IP_SEARCH_ALLOWED' => ($auth->acl_getf_global('m_info')) ? true : false, 'S_EMAIL_SEARCH_ALLOWED'=> ($auth->acl_get('a_user')) ? true : false, 'S_IN_SEARCH_POPUP' => ($form && $field) ? true : false, - 'S_SEARCH_USER' => ($mode == 'searchuser' || ($mode == '' && $submit)) ? true : false, + 'S_SEARCH_USER' => ($mode == 'searchuser' || ($mode == '' && $submit)), 'S_FORM_NAME' => $form, 'S_FIELD_NAME' => $field, 'S_SELECT_SINGLE' => $select_single, diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 8583fb565c..968f57bba2 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -192,6 +192,17 @@ $('#quick-mod-select').change(function () { $('#quickmodform').submit(); }); - +/** +* Toggle the member search panel in memberlist.php. +*/ +$('#member_search').click(function () { + $('#memberlist_search').slideToggle('fast'); + phpbb.ajax_callbacks['alt_text'].call(this); + //Focus on the username textbox if it's available and displayed + if ($('#username').length > 0 && $('#memberlist_search').is(':visible')) { + $('#username').focus(); + } + return false; +}); })(jQuery); // Avoid conflicts with other libraries diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js index 527a064fa9..995b4b0ab7 100644 --- a/phpBB/styles/prosilver/template/forum_fn.js +++ b/phpBB/styles/prosilver/template/forum_fn.js @@ -433,43 +433,6 @@ function apply_onkeypress_event() } } -/** -* Toggle a section's visibility status -*/ -function toggle_section(link, panel_id, expand_text, collapse_text) -{ - if (jquery_present) - { - var panel = jQuery('#' + panel_id); - if (panel.is(':visible')) - { - jQuery(link).text(expand_text); - panel.slideUp('fast'); - } - else - { - jQuery(link).text(collapse_text); - panel.slideDown('fast'); - } - } - else - { - var panel = document.getElementById(panel_id); - if (panel.style.display == 'none') - { - link.innerHTML = collapse_text; - panel.style.display = ''; - } - else - { - link.innerHTML = expand_text; - panel.style.display = 'none'; - } - } - - return false; -} - /** * Detect JQuery existance. We currently do not deliver it, but some styles do, so why not benefit from it. ;) */ diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html index 023c0e1e4e..17dc2c33c0 100644 --- a/phpBB/styles/prosilver/template/memberlist_body.html +++ b/phpBB/styles/prosilver/template/memberlist_body.html @@ -30,7 +30,7 @@