From f6e45ed24420e719a969ffd301cf019ba0aa912a Mon Sep 17 00:00:00 2001 From: hjpotter92 Date: Sun, 2 Mar 2014 21:58:10 +0530 Subject: [ticket/11875] Create new map for UNSIGNED 4-byte integer ULINT => Unsigned Large INTeger --- phpBB/phpbb/db/tools.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 3a7207e743..7f143873b1 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -44,6 +44,7 @@ class tools 'mysql_41' => array( 'INT:' => 'int(%d)', 'BINT' => 'bigint(20)', + 'ULINT' => 'INT(10) UNSIGNED', 'UINT' => 'mediumint(8) UNSIGNED', 'UINT:' => 'int(%d) UNSIGNED', 'TINT:' => 'tinyint(%d)', @@ -74,6 +75,7 @@ class tools 'mysql_40' => array( 'INT:' => 'int(%d)', 'BINT' => 'bigint(20)', + 'ULINT' => 'INT(10) UNSIGNED', 'UINT' => 'mediumint(8) UNSIGNED', 'UINT:' => 'int(%d) UNSIGNED', 'TINT:' => 'tinyint(%d)', @@ -104,6 +106,7 @@ class tools 'firebird' => array( 'INT:' => 'INTEGER', 'BINT' => 'DOUBLE PRECISION', + 'ULINT' => 'INTEGER', 'UINT' => 'INTEGER', 'UINT:' => 'INTEGER', 'TINT:' => 'INTEGER', @@ -134,6 +137,7 @@ class tools 'mssql' => array( 'INT:' => '[int]', 'BINT' => '[float]', + 'ULINT' => '[int]', 'UINT' => '[int]', 'UINT:' => '[int]', 'TINT:' => '[int]', @@ -164,6 +168,7 @@ class tools 'mssqlnative' => array( 'INT:' => '[int]', 'BINT' => '[float]', + 'ULINT' => '[int]', 'UINT' => '[int]', 'UINT:' => '[int]', 'TINT:' => '[int]', @@ -194,6 +199,7 @@ class tools 'oracle' => array( 'INT:' => 'number(%d)', 'BINT' => 'number(20)', + 'ULINT' => 'number(10)', 'UINT' => 'number(8)', 'UINT:' => 'number(%d)', 'TINT:' => 'number(%d)', @@ -224,7 +230,8 @@ class tools 'sqlite' => array( 'INT:' => 'int(%d)', 'BINT' => 'bigint(20)', - 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED', + 'ULINT' => 'INTEGER UNSIGNED', // 'int(10) UNSIGNED + 'UINT' => 'INTEGER UNSIGNED', // 'mediumint(8) UNSIGNED', 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', 'TINT:' => 'tinyint(%d)', 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED', @@ -254,6 +261,7 @@ class tools 'postgres' => array( 'INT:' => 'INT4', 'BINT' => 'INT8', + 'ULINT' => 'INT4', // unsigned 'UINT' => 'INT4', // unsigned 'UINT:' => 'INT4', // unsigned 'USINT' => 'INT2', // unsigned @@ -287,7 +295,7 @@ class tools * A list of types being unsigned for better reference in some db's * @var array */ - var $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); + var $unsigned_types = array('ULINT', 'UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); /** * A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules. -- cgit v1.2.1 From 7696f39ac3ecb803468f230129a76dac59f2972b Mon Sep 17 00:00:00 2001 From: hjpotter92 Date: Sun, 2 Mar 2014 23:23:44 +0530 Subject: [ticket/11875] Recreate schemas for install PHPBB3-11875 --- phpBB/phpbb/db/tools.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 7f143873b1..18e30d309a 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -230,12 +230,12 @@ class tools 'sqlite' => array( 'INT:' => 'int(%d)', 'BINT' => 'bigint(20)', - 'ULINT' => 'INTEGER UNSIGNED', // 'int(10) UNSIGNED + 'ULINT' => 'INTEGER UNSIGNED', // 'int(10) UNSIGNED', 'UINT' => 'INTEGER UNSIGNED', // 'mediumint(8) UNSIGNED', 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', 'TINT:' => 'tinyint(%d)', - 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED', - 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED', + 'USINT' => 'INTEGER UNSIGNED', // 'mediumint(4) UNSIGNED', + 'BOOL' => 'INTEGER UNSIGNED', // 'tinyint(1) UNSIGNED', 'VCHAR' => 'varchar(255)', 'VCHAR:' => 'varchar(%d)', 'CHAR:' => 'char(%d)', @@ -247,7 +247,7 @@ class tools 'STEXT_UNI' => 'text(65535)', 'TEXT_UNI' => 'text(65535)', 'MTEXT_UNI' => 'mediumtext(16777215)', - 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', + 'TIMESTAMP' => 'INTEGER UNSIGNED', // 'int(11) UNSIGNED', 'DECIMAL' => 'decimal(5,2)', 'DECIMAL:' => 'decimal(%d,2)', 'PDECIMAL' => 'decimal(6,3)', -- cgit v1.2.1 From 2276c1c0f246a39dee8d0e979c89e8de0ee7a5de Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 22 Jun 2014 18:08:38 +0200 Subject: [ticket/12387] Cleanup *_free_result call and remove @ on that call PHPBB3-12387 --- phpBB/phpbb/db/driver/driver.php | 8 ++--- phpBB/phpbb/db/driver/mssql.php | 44 ++++++++++++++++----------- phpBB/phpbb/db/driver/mssql_odbc.php | 30 +++++++++++------- phpBB/phpbb/db/driver/mssqlnative.php | 32 ++++++++++++-------- phpBB/phpbb/db/driver/mysql.php | 54 ++++++++++++++++++++++----------- phpBB/phpbb/db/driver/mysqli.php | 44 ++++++++++++++++----------- phpBB/phpbb/db/driver/oracle.php | 57 +++++++++++++++++++++++------------ phpBB/phpbb/db/driver/postgres.php | 43 ++++++++++++++++---------- phpBB/phpbb/db/driver/sqlite.php | 34 ++++++++++++--------- phpBB/phpbb/db/driver/sqlite3.php | 14 +++++++-- 10 files changed, 227 insertions(+), 133 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 3d4aa95606..3c23f8fa36 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -175,7 +175,7 @@ abstract class driver implements driver_interface $query_id = $this->query_result; } - if ($query_id !== false) + if ($query_id) { $result = array(); while ($row = $this->sql_fetchrow($query_id)) @@ -206,7 +206,7 @@ abstract class driver implements driver_interface return $cache->sql_rowseek($rownum, $query_id); } - if ($query_id === false) + if (!$query_id) { return false; } @@ -214,7 +214,7 @@ abstract class driver implements driver_interface $this->sql_freeresult($query_id); $query_id = $this->sql_query($this->last_query_text); - if ($query_id === false) + if (!$query_id) { return false; } @@ -243,7 +243,7 @@ abstract class driver implements driver_interface $query_id = $this->query_result; } - if ($query_id !== false) + if ($query_id) { if ($rownum !== false) { diff --git a/phpBB/phpbb/db/driver/mssql.php b/phpBB/phpbb/db/driver/mssql.php index 2e56638617..14a9fd938c 100644 --- a/phpBB/phpbb/db/driver/mssql.php +++ b/phpBB/phpbb/db/driver/mssql.php @@ -71,8 +71,8 @@ class mssql extends \phpbb\db\driver\driver $row = false; if ($result_id) { - $row = @mssql_fetch_assoc($result_id); - @mssql_free_result($result_id); + $row = mssql_fetch_assoc($result_id); + mssql_free_result($result_id); } $this->sql_server_version = ($row) ? trim(implode(' ', $row)) : 0; @@ -153,6 +153,11 @@ class mssql extends \phpbb\db\driver\driver $this->sql_report('stop', $query); } + if (!$this->query_result) + { + return false; + } + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; @@ -233,12 +238,12 @@ class mssql extends \phpbb\db\driver\driver return $cache->sql_fetchrow($query_id); } - if ($query_id === false) + if (!$query_id) { return false; } - $row = @mssql_fetch_assoc($query_id); + $row = mssql_fetch_assoc($query_id); // I hope i am able to remove this later... hopefully only a PHP or MSSQL bug if ($row) @@ -269,7 +274,7 @@ class mssql extends \phpbb\db\driver\driver return $cache->sql_rowseek($rownum, $query_id); } - return ($query_id !== false) ? @mssql_data_seek($query_id, $rownum) : false; + return ($query_id) ? @mssql_data_seek($query_id, $rownum) : false; } /** @@ -280,12 +285,12 @@ class mssql extends \phpbb\db\driver\driver $result_id = @mssql_query('SELECT SCOPE_IDENTITY()', $this->db_connect_id); if ($result_id) { - if ($row = @mssql_fetch_assoc($result_id)) + if ($row = mssql_fetch_assoc($result_id)) { - @mssql_free_result($result_id); + mssql_free_result($result_id); return $row['computed']; } - @mssql_free_result($result_id); + mssql_free_result($result_id); } return false; @@ -311,7 +316,7 @@ class mssql extends \phpbb\db\driver\driver if (isset($this->open_queries[(int) $query_id])) { unset($this->open_queries[(int) $query_id]); - return @mssql_free_result($query_id); + return mssql_free_result($query_id); } return false; @@ -359,9 +364,9 @@ class mssql extends \phpbb\db\driver\driver $result_id = @mssql_query('SELECT @@ERROR as code', $this->db_connect_id); if ($result_id) { - $row = @mssql_fetch_assoc($result_id); + $row = mssql_fetch_assoc($result_id); $error['code'] = $row['code']; - @mssql_free_result($result_id); + mssql_free_result($result_id); } // Get full error message if possible @@ -372,12 +377,12 @@ class mssql extends \phpbb\db\driver\driver if ($result_id) { - $row = @mssql_fetch_assoc($result_id); + $row = mssql_fetch_assoc($result_id); if (!empty($row['message'])) { $error['message'] .= '
' . $row['message']; } - @mssql_free_result($result_id); + mssql_free_result($result_id); } } else @@ -423,13 +428,13 @@ class mssql extends \phpbb\db\driver\driver if ($result = @mssql_query($query, $this->db_connect_id)) { @mssql_next_result($result); - while ($row = @mssql_fetch_row($result)) + while ($row = mssql_fetch_row($result)) { $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); } } @mssql_query('SET SHOWPLAN_TEXT OFF;', $this->db_connect_id); - @mssql_free_result($result); + mssql_free_result($result); if ($html_table) { @@ -442,11 +447,14 @@ class mssql extends \phpbb\db\driver\driver $endtime = $endtime[0] + $endtime[1]; $result = @mssql_query($query, $this->db_connect_id); - while ($void = @mssql_fetch_assoc($result)) + if ($result) { - // Take the time spent on parsing rows into account + while ($void = mssql_fetch_assoc($result)) + { + // Take the time spent on parsing rows into account + } + mssql_free_result($result); } - @mssql_free_result($result); $splittime = explode(' ', microtime()); $splittime = $splittime[0] + $splittime[1]; diff --git a/phpBB/phpbb/db/driver/mssql_odbc.php b/phpBB/phpbb/db/driver/mssql_odbc.php index de90d878e7..847cdeb188 100644 --- a/phpBB/phpbb/db/driver/mssql_odbc.php +++ b/phpBB/phpbb/db/driver/mssql_odbc.php @@ -98,8 +98,8 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base $row = false; if ($result_id) { - $row = @odbc_fetch_array($result_id); - @odbc_free_result($result_id); + $row = odbc_fetch_array($result_id); + odbc_free_result($result_id); } $this->sql_server_version = ($row) ? trim(implode(' ', $row)) : 0; @@ -173,6 +173,11 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base $this->sql_report('stop', $query); } + if (!$this->query_result) + { + return false; + } + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; @@ -253,7 +258,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base return $cache->sql_fetchrow($query_id); } - return ($query_id !== false) ? @odbc_fetch_array($query_id) : false; + return ($query_id) ? odbc_fetch_array($query_id) : false; } /** @@ -265,13 +270,13 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base if ($result_id) { - if (@odbc_fetch_array($result_id)) + if (odbc_fetch_array($result_id)) { - $id = @odbc_result($result_id, 1); - @odbc_free_result($result_id); + $id = odbc_result($result_id, 1); + odbc_free_result($result_id); return $id; } - @odbc_free_result($result_id); + odbc_free_result($result_id); } return false; @@ -297,7 +302,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base if (isset($this->open_queries[(int) $query_id])) { unset($this->open_queries[(int) $query_id]); - return @odbc_free_result($query_id); + return odbc_free_result($query_id); } return false; @@ -352,11 +357,14 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base $endtime = $endtime[0] + $endtime[1]; $result = @odbc_exec($this->db_connect_id, $query); - while ($void = @odbc_fetch_array($result)) + if ($result) { - // Take the time spent on parsing rows into account + while ($void = odbc_fetch_array($result)) + { + // Take the time spent on parsing rows into account + } + odbc_free_result($result); } - @odbc_free_result($result); $splittime = explode(' ', microtime()); $splittime = $splittime[0] + $splittime[1]; diff --git a/phpBB/phpbb/db/driver/mssqlnative.php b/phpBB/phpbb/db/driver/mssqlnative.php index a7f93c8feb..fbf37cbff2 100644 --- a/phpBB/phpbb/db/driver/mssqlnative.php +++ b/phpBB/phpbb/db/driver/mssqlnative.php @@ -146,6 +146,11 @@ class mssqlnative extends \phpbb\db\driver\mssql_base $this->sql_report('stop', $query); } + if (!$this->query_result) + { + return false; + } + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; @@ -234,12 +239,12 @@ class mssqlnative extends \phpbb\db\driver\mssql_base return $cache->sql_fetchrow($query_id); } - if ($query_id === false) + if (!$query_id) { return false; } - $row = @sqlsrv_fetch_array($query_id, SQLSRV_FETCH_ASSOC); + $row = sqlsrv_fetch_array($query_id, SQLSRV_FETCH_ASSOC); if ($row) { @@ -264,11 +269,11 @@ class mssqlnative extends \phpbb\db\driver\mssql_base { $result_id = @sqlsrv_query($this->db_connect_id, 'SELECT @@IDENTITY'); - if ($result_id !== false) + if ($result_id) { - $row = @sqlsrv_fetch_array($result_id); + $row = sqlsrv_fetch_array($result_id); $id = $row[0]; - @sqlsrv_free_stmt($result_id); + sqlsrv_free_stmt($result_id); return $id; } else @@ -297,7 +302,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base if (isset($this->open_queries[(int) $query_id])) { unset($this->open_queries[(int) $query_id]); - return @sqlsrv_free_stmt($query_id); + return sqlsrv_free_stmt($query_id); } return false; @@ -370,14 +375,14 @@ class mssqlnative extends \phpbb\db\driver\mssql_base @sqlsrv_query($this->db_connect_id, 'SET SHOWPLAN_TEXT ON;'); if ($result = @sqlsrv_query($this->db_connect_id, $query)) { - @sqlsrv_next_result($result); - while ($row = @sqlsrv_fetch_array($result)) + sqlsrv_next_result($result); + while ($row = sqlsrv_fetch_array($result)) { $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); } + sqlsrv_free_stmt($result); } @sqlsrv_query($this->db_connect_id, 'SET SHOWPLAN_TEXT OFF;'); - @sqlsrv_free_stmt($result); if ($html_table) { @@ -390,11 +395,14 @@ class mssqlnative extends \phpbb\db\driver\mssql_base $endtime = $endtime[0] + $endtime[1]; $result = @sqlsrv_query($this->db_connect_id, $query); - while ($void = @sqlsrv_fetch_array($result)) + if ($result) { - // Take the time spent on parsing rows into account + while ($void = sqlsrv_fetch_array($result)) + { + // Take the time spent on parsing rows into account + } + sqlsrv_free_stmt($result); } - @sqlsrv_free_stmt($result); $splittime = explode(' ', microtime()); $splittime = $splittime[0] + $splittime[1]; diff --git a/phpBB/phpbb/db/driver/mysql.php b/phpBB/phpbb/db/driver/mysql.php index 569bd4f10a..50bb8204a8 100644 --- a/phpBB/phpbb/db/driver/mysql.php +++ b/phpBB/phpbb/db/driver/mysql.php @@ -70,9 +70,16 @@ class mysql extends \phpbb\db\driver\mysql_base if (version_compare($this->sql_server_info(true), '5.0.2', '>=')) { $result = @mysql_query('SELECT @@session.sql_mode AS sql_mode', $this->db_connect_id); - $row = @mysql_fetch_assoc($result); - @mysql_free_result($result); - $modes = array_map('trim', explode(',', $row['sql_mode'])); + if ($result) + { + $row = mysql_fetch_assoc($result); + mysql_free_result($result); + $modes = array_map('trim', explode(',', $row['sql_mode'])); + } + else + { + $modes = array(); + } // TRADITIONAL includes STRICT_ALL_TABLES and STRICT_TRANS_TABLES if (!in_array('TRADITIONAL', $modes)) @@ -114,14 +121,17 @@ class mysql extends \phpbb\db\driver\mysql_base if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mysql_version')) === false) { $result = @mysql_query('SELECT VERSION() AS version', $this->db_connect_id); - $row = @mysql_fetch_assoc($result); - @mysql_free_result($result); + if ($result) + { + $row = mysql_fetch_assoc($result); + mysql_free_result($result); - $this->sql_server_version = $row['version']; + $this->sql_server_version = $row['version']; - if (!empty($cache) && $use_cache) - { - $cache->put('mysql_version', $this->sql_server_version); + if (!empty($cache) && $use_cache) + { + $cache->put('mysql_version', $this->sql_server_version); + } } } @@ -182,6 +192,11 @@ class mysql extends \phpbb\db\driver\mysql_base $this->sql_report('stop', $query); } + if (!$this->query_result) + { + return false; + } + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; @@ -249,7 +264,7 @@ class mysql extends \phpbb\db\driver\mysql_base return $cache->sql_fetchrow($query_id); } - return ($query_id !== false) ? @mysql_fetch_assoc($query_id) : false; + return ($query_id) ? mysql_fetch_assoc($query_id) : false; } /** @@ -300,7 +315,7 @@ class mysql extends \phpbb\db\driver\mysql_base if (isset($this->open_queries[(int) $query_id])) { unset($this->open_queries[(int) $query_id]); - return @mysql_free_result($query_id); + return mysql_free_result($query_id); } return false; @@ -403,12 +418,12 @@ class mysql extends \phpbb\db\driver\mysql_base if ($result = @mysql_query("EXPLAIN $explain_query", $this->db_connect_id)) { - while ($row = @mysql_fetch_assoc($result)) + while ($row = mysql_fetch_assoc($result)) { $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); } + mysql_free_result($result); } - @mysql_free_result($result); if ($html_table) { @@ -423,7 +438,7 @@ class mysql extends \phpbb\db\driver\mysql_base if ($result = @mysql_query('SHOW PROFILE ALL;', $this->db_connect_id)) { $this->html_hold .= '
'; - while ($row = @mysql_fetch_assoc($result)) + while ($row = mysql_fetch_assoc($result)) { // make HTML safe if (!empty($row['Source_function'])) @@ -441,8 +456,8 @@ class mysql extends \phpbb\db\driver\mysql_base } $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); } + mysql_free_result($result); } - @mysql_free_result($result); if ($html_table) { @@ -460,11 +475,14 @@ class mysql extends \phpbb\db\driver\mysql_base $endtime = $endtime[0] + $endtime[1]; $result = @mysql_query($query, $this->db_connect_id); - while ($void = @mysql_fetch_assoc($result)) + if ($result) { - // Take the time spent on parsing rows into account + while ($void = mysql_fetch_assoc($result)) + { + // Take the time spent on parsing rows into account + } + mysql_free_result($result); } - @mysql_free_result($result); $splittime = explode(' ', microtime()); $splittime = $splittime[0] + $splittime[1]; diff --git a/phpBB/phpbb/db/driver/mysqli.php b/phpBB/phpbb/db/driver/mysqli.php index 520bb65b67..410d84c1df 100644 --- a/phpBB/phpbb/db/driver/mysqli.php +++ b/phpBB/phpbb/db/driver/mysqli.php @@ -71,9 +71,10 @@ class mysqli extends \phpbb\db\driver\mysql_base if (version_compare($this->sql_server_info(true), '5.0.2', '>=')) { $result = @mysqli_query($this->db_connect_id, 'SELECT @@session.sql_mode AS sql_mode'); - if ($result !== null) + if ($result) { - $row = @mysqli_fetch_assoc($result); + $row = mysqli_fetch_assoc($result); + mysqli_free_result($result); $modes = array_map('trim', explode(',', $row['sql_mode'])); } @@ -81,7 +82,6 @@ class mysqli extends \phpbb\db\driver\mysql_base { $modes = array(); } - @mysqli_free_result($result); // TRADITIONAL includes STRICT_ALL_TABLES and STRICT_TRANS_TABLES if (!in_array('TRADITIONAL', $modes)) @@ -116,9 +116,10 @@ class mysqli extends \phpbb\db\driver\mysql_base if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mysqli_version')) === false) { $result = @mysqli_query($this->db_connect_id, 'SELECT VERSION() AS version'); - if ($result !== null) + if ($result) { - $row = @mysqli_fetch_assoc($result); + $row = mysqli_fetch_assoc($result); + mysqli_free_result($result); $this->sql_server_version = $row['version']; @@ -127,7 +128,6 @@ class mysqli extends \phpbb\db\driver\mysql_base $cache->put('mysqli_version', $this->sql_server_version); } } - @mysqli_free_result($result); } return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version; @@ -191,6 +191,11 @@ class mysqli extends \phpbb\db\driver\mysql_base $this->sql_report('stop', $query); } + if (!$this->query_result) + { + return false; + } + if ($cache && $cache_ttl) { $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); @@ -234,9 +239,9 @@ class mysqli extends \phpbb\db\driver\mysql_base return $cache->sql_fetchrow($query_id); } - if ($query_id !== false && $query_id !== null) + if ($query_id) { - $result = @mysqli_fetch_assoc($query_id); + $result = mysqli_fetch_assoc($query_id); return $result !== null ? $result : false; } @@ -260,7 +265,7 @@ class mysqli extends \phpbb\db\driver\mysql_base return $cache->sql_rowseek($rownum, $query_id); } - return ($query_id !== false) ? @mysqli_data_seek($query_id, $rownum) : false; + return ($query_id) ? @mysqli_data_seek($query_id, $rownum) : false; } /** @@ -288,7 +293,12 @@ class mysqli extends \phpbb\db\driver\mysql_base return $cache->sql_freeresult($query_id); } - return @mysqli_free_result($query_id); + if (!$this->query_result) + { + return false; + } + + return mysqli_free_result($query_id); } /** @@ -387,12 +397,12 @@ class mysqli extends \phpbb\db\driver\mysql_base if ($result = @mysqli_query($this->db_connect_id, "EXPLAIN $explain_query")) { - while ($row = @mysqli_fetch_assoc($result)) + while ($row = mysqli_fetch_assoc($result)) { $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); } + mysqli_free_result($result); } - @mysqli_free_result($result); if ($html_table) { @@ -407,7 +417,7 @@ class mysqli extends \phpbb\db\driver\mysql_base if ($result = @mysqli_query($this->db_connect_id, 'SHOW PROFILE ALL;')) { $this->html_hold .= '
'; - while ($row = @mysqli_fetch_assoc($result)) + while ($row = mysqli_fetch_assoc($result)) { // make HTML safe if (!empty($row['Source_function'])) @@ -425,8 +435,8 @@ class mysqli extends \phpbb\db\driver\mysql_base } $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); } + mysqli_free_result($result); } - @mysqli_free_result($result); if ($html_table) { @@ -444,14 +454,14 @@ class mysqli extends \phpbb\db\driver\mysql_base $endtime = $endtime[0] + $endtime[1]; $result = @mysqli_query($this->db_connect_id, $query); - if ($result !== null) + if ($result) { - while ($void = @mysqli_fetch_assoc($result)) + while ($void = mysqli_fetch_assoc($result)) { // Take the time spent on parsing rows into account } + mysqli_free_result($result); } - @mysqli_free_result($result); $splittime = explode(' ', microtime()); $splittime = $splittime[0] + $splittime[1]; diff --git a/phpBB/phpbb/db/driver/oracle.php b/phpBB/phpbb/db/driver/oracle.php index bfc5373e35..0dfd8484ee 100644 --- a/phpBB/phpbb/db/driver/oracle.php +++ b/phpBB/phpbb/db/driver/oracle.php @@ -431,6 +431,11 @@ class oracle extends \phpbb\db\driver\driver $this->sql_report('stop', $query); } + if (!$this->query_result) + { + return false; + } + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; @@ -491,10 +496,10 @@ class oracle extends \phpbb\db\driver\driver return $cache->sql_fetchrow($query_id); } - if ($query_id !== false) + if ($query_id) { $row = array(); - $result = @ocifetchinto($query_id, $row, OCI_ASSOC + OCI_RETURN_NULLS); + $result = ocifetchinto($query_id, $row, OCI_ASSOC + OCI_RETURN_NULLS); if (!$result || !$row) { @@ -542,7 +547,7 @@ class oracle extends \phpbb\db\driver\driver return $cache->sql_rowseek($rownum, $query_id); } - if ($query_id === false) + if (!$query_id) { return false; } @@ -575,18 +580,24 @@ class oracle extends \phpbb\db\driver\driver { $query = 'SELECT ' . $tablename[1] . '_seq.currval FROM DUAL'; $stmt = @ociparse($this->db_connect_id, $query); - @ociexecute($stmt, OCI_DEFAULT); + if ($stmt) + { + $success = @ociexecute($stmt, OCI_DEFAULT); - $temp_result = @ocifetchinto($stmt, $temp_array, OCI_ASSOC + OCI_RETURN_NULLS); - @ocifreestatement($stmt); + if ($success) + { + $temp_result = ocifetchinto($stmt, $temp_array, OCI_ASSOC + OCI_RETURN_NULLS); + ocifreestatement($stmt); - if ($temp_result) - { - return $temp_array['CURRVAL']; - } - else - { - return false; + if ($temp_result) + { + return $temp_array['CURRVAL']; + } + else + { + return false; + } + } } } } @@ -614,7 +625,7 @@ class oracle extends \phpbb\db\driver\driver if (isset($this->open_queries[(int) $query_id])) { unset($this->open_queries[(int) $query_id]); - return @ocifreestatement($query_id); + return ocifreestatement($query_id); } return false; @@ -770,14 +781,20 @@ class oracle extends \phpbb\db\driver\driver $endtime = $endtime[0] + $endtime[1]; $result = @ociparse($this->db_connect_id, $query); - $success = @ociexecute($result, OCI_DEFAULT); - $row = array(); - - while (@ocifetchinto($result, $row, OCI_ASSOC + OCI_RETURN_NULLS)) + if ($result) { - // Take the time spent on parsing rows into account + $success = @ociexecute($result, OCI_DEFAULT); + if ($success) + { + $row = array(); + + while (ocifetchinto($result, $row, OCI_ASSOC + OCI_RETURN_NULLS)) + { + // Take the time spent on parsing rows into account + } + @ocifreestatement($result); + } } - @ocifreestatement($result); $splittime = explode(' ', microtime()); $splittime = $splittime[0] + $splittime[1]; diff --git a/phpBB/phpbb/db/driver/postgres.php b/phpBB/phpbb/db/driver/postgres.php index a4aa9497ed..3fade46bdd 100644 --- a/phpBB/phpbb/db/driver/postgres.php +++ b/phpBB/phpbb/db/driver/postgres.php @@ -127,14 +127,17 @@ class postgres extends \phpbb\db\driver\driver if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('pgsql_version')) === false) { $query_id = @pg_query($this->db_connect_id, 'SELECT VERSION() AS version'); - $row = @pg_fetch_assoc($query_id, null); - @pg_free_result($query_id); + if ($query_id) + { + $row = pg_fetch_assoc($query_id, null); + pg_free_result($query_id); - $this->sql_server_version = (!empty($row['version'])) ? trim(substr($row['version'], 10)) : 0; + $this->sql_server_version = (!empty($row['version'])) ? trim(substr($row['version'], 10)) : 0; - if (!empty($cache) && $use_cache) - { - $cache->put('pgsql_version', $this->sql_server_version); + if (!empty($cache) && $use_cache) + { + $cache->put('pgsql_version', $this->sql_server_version); + } } } @@ -196,6 +199,11 @@ class postgres extends \phpbb\db\driver\driver $this->sql_report('stop', $query); } + if (!$this->query_result) + { + return false; + } + if ($cache && $cache_ttl) { $this->open_queries[(int) $this->query_result] = $this->query_result; @@ -271,7 +279,7 @@ class postgres extends \phpbb\db\driver\driver return $cache->sql_fetchrow($query_id); } - return ($query_id !== false) ? @pg_fetch_assoc($query_id, null) : false; + return ($query_id) ? pg_fetch_assoc($query_id, null) : false; } /** @@ -291,7 +299,7 @@ class postgres extends \phpbb\db\driver\driver return $cache->sql_rowseek($rownum, $query_id); } - return ($query_id !== false) ? @pg_result_seek($query_id, $rownum) : false; + return ($query_id) ? @pg_result_seek($query_id, $rownum) : false; } /** @@ -313,8 +321,8 @@ class postgres extends \phpbb\db\driver\driver return false; } - $temp_result = @pg_fetch_assoc($temp_q_id, null); - @pg_free_result($query_id); + $temp_result = pg_fetch_assoc($temp_q_id, null); + pg_free_result($query_id); return ($temp_result) ? $temp_result['last_value'] : false; } @@ -343,7 +351,7 @@ class postgres extends \phpbb\db\driver\driver if (isset($this->open_queries[(int) $query_id])) { unset($this->open_queries[(int) $query_id]); - return @pg_free_result($query_id); + return pg_free_result($query_id); } return false; @@ -440,12 +448,12 @@ class postgres extends \phpbb\db\driver\driver if ($result = @pg_query($this->db_connect_id, "EXPLAIN $explain_query")) { - while ($row = @pg_fetch_assoc($result, null)) + while ($row = pg_fetch_assoc($result, null)) { $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); } + pg_free_result($result); } - @pg_free_result($result); if ($html_table) { @@ -460,11 +468,14 @@ class postgres extends \phpbb\db\driver\driver $endtime = $endtime[0] + $endtime[1]; $result = @pg_query($this->db_connect_id, $query); - while ($void = @pg_fetch_assoc($result, null)) + if ($result) { - // Take the time spent on parsing rows into account + while ($void = pg_fetch_assoc($result, null)) + { + // Take the time spent on parsing rows into account + } + pg_free_result($result); } - @pg_free_result($result); $splittime = explode(' ', microtime()); $splittime = $splittime[0] + $splittime[1]; diff --git a/phpBB/phpbb/db/driver/sqlite.php b/phpBB/phpbb/db/driver/sqlite.php index f4c5e240fc..9130b2b292 100644 --- a/phpBB/phpbb/db/driver/sqlite.php +++ b/phpBB/phpbb/db/driver/sqlite.php @@ -70,13 +70,16 @@ class sqlite extends \phpbb\db\driver\driver if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite_version')) === false) { $result = @sqlite_query('SELECT sqlite_version() AS version', $this->db_connect_id); - $row = @sqlite_fetch_array($result, SQLITE_ASSOC); + if ($result) + { + $row = sqlite_fetch_array($result, SQLITE_ASSOC); - $this->sql_server_version = (!empty($row['version'])) ? $row['version'] : 0; + $this->sql_server_version = (!empty($row['version'])) ? $row['version'] : 0; - if (!empty($cache) && $use_cache) - { - $cache->put('sqlite_version', $this->sql_server_version); + if (!empty($cache) && $use_cache) + { + $cache->put('sqlite_version', $this->sql_server_version); + } } } @@ -137,14 +140,14 @@ class sqlite extends \phpbb\db\driver\driver $this->sql_report('stop', $query); } - if ($cache && $cache_ttl) + if (!$this->query_result) { - $this->open_queries[(int) $this->query_result] = $this->query_result; - $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); + return false; } - else if (strpos($query, 'SELECT') === 0 && $this->query_result) + + if ($cache && $cache_ttl) { - $this->open_queries[(int) $this->query_result] = $this->query_result; + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } } else if (defined('DEBUG')) @@ -203,7 +206,7 @@ class sqlite extends \phpbb\db\driver\driver return $cache->sql_fetchrow($query_id); } - return ($query_id !== false) ? @sqlite_fetch_array($query_id, SQLITE_ASSOC) : false; + return ($query_id) ? sqlite_fetch_array($query_id, SQLITE_ASSOC) : false; } /** @@ -223,7 +226,7 @@ class sqlite extends \phpbb\db\driver\driver return $cache->sql_rowseek($rownum, $query_id); } - return ($query_id !== false) ? @sqlite_seek($query_id, $rownum) : false; + return ($query_id) ? @sqlite_seek($query_id, $rownum) : false; } /** @@ -337,9 +340,12 @@ class sqlite extends \phpbb\db\driver\driver $endtime = $endtime[0] + $endtime[1]; $result = @sqlite_query($query, $this->db_connect_id); - while ($void = @sqlite_fetch_array($result, SQLITE_ASSOC)) + if ($result) { - // Take the time spent on parsing rows into account + while ($void = sqlite_fetch_array($result, SQLITE_ASSOC)) + { + // Take the time spent on parsing rows into account + } } $splittime = explode(' ', microtime()); diff --git a/phpBB/phpbb/db/driver/sqlite3.php b/phpBB/phpbb/db/driver/sqlite3.php index 2c6bf99497..4ca3d8f91d 100644 --- a/phpBB/phpbb/db/driver/sqlite3.php +++ b/phpBB/phpbb/db/driver/sqlite3.php @@ -50,7 +50,7 @@ class sqlite3 extends \phpbb\db\driver\driver $this->dbo = new \SQLite3($this->server, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE); $this->db_connect_id = true; } - catch (Exception $e) + catch (\Exception $e) { return array('message' => $e->getMessage()); } @@ -138,6 +138,11 @@ class sqlite3 extends \phpbb\db\driver\driver $this->sql_report('stop', $query); } + if (!$this->query_result) + { + return false; + } + if ($cache && $cache_ttl) { $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); @@ -362,9 +367,12 @@ class sqlite3 extends \phpbb\db\driver\driver $endtime = $endtime[0] + $endtime[1]; $result = $this->dbo->query($query); - while ($void = $result->fetchArray(SQLITE3_ASSOC)) + if ($result) { - // Take the time spent on parsing rows into account + while ($void = $result->fetchArray(SQLITE3_ASSOC)) + { + // Take the time spent on parsing rows into account + } } $splittime = explode(' ', microtime()); -- cgit v1.2.1 From adba7d471583537fb20c18dca08c571909171aeb Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 22 Jun 2014 19:34:02 +0200 Subject: [ticket/12387] mssql_query return true if a select query returns 0 row PHPBB3-12387 --- phpBB/phpbb/db/driver/mssql.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/mssql.php b/phpBB/phpbb/db/driver/mssql.php index 14a9fd938c..0809703b48 100644 --- a/phpBB/phpbb/db/driver/mssql.php +++ b/phpBB/phpbb/db/driver/mssql.php @@ -163,7 +163,7 @@ class mssql extends \phpbb\db\driver\driver $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } - else if (strpos($query, 'SELECT') === 0 && $this->query_result) + else if (strpos($query, 'SELECT') === 0 && $this->query_result !== true) { $this->open_queries[(int) $this->query_result] = $this->query_result; } @@ -238,7 +238,7 @@ class mssql extends \phpbb\db\driver\driver return $cache->sql_fetchrow($query_id); } - if (!$query_id) + if (!$query_id || $query_id === true) { return false; } @@ -269,6 +269,11 @@ class mssql extends \phpbb\db\driver\driver $query_id = $this->query_result; } + if ($query_id === true) + { + return false; + } + if ($cache && $cache->sql_exists($query_id)) { return $cache->sql_rowseek($rownum, $query_id); @@ -308,6 +313,11 @@ class mssql extends \phpbb\db\driver\driver $query_id = $this->query_result; } + if ($query_id === true) + { + return false; + } + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); -- cgit v1.2.1 From 50f4bea6101f64c513b3918ade58a712b00f3df7 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 22 Jun 2014 19:35:07 +0200 Subject: [ticket/12387] Remove unnecessary checks PHPBB3-12387 --- phpBB/phpbb/db/driver/mssql_odbc.php | 2 +- phpBB/phpbb/db/driver/mssqlnative.php | 2 +- phpBB/phpbb/db/driver/mysql.php | 2 +- phpBB/phpbb/db/driver/oracle.php | 2 +- phpBB/phpbb/db/driver/postgres.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/mssql_odbc.php b/phpBB/phpbb/db/driver/mssql_odbc.php index 847cdeb188..0a15148e1d 100644 --- a/phpBB/phpbb/db/driver/mssql_odbc.php +++ b/phpBB/phpbb/db/driver/mssql_odbc.php @@ -183,7 +183,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } - else if (strpos($query, 'SELECT') === 0 && $this->query_result) + else if (strpos($query, 'SELECT') === 0) { $this->open_queries[(int) $this->query_result] = $this->query_result; } diff --git a/phpBB/phpbb/db/driver/mssqlnative.php b/phpBB/phpbb/db/driver/mssqlnative.php index fbf37cbff2..3bc9ecda75 100644 --- a/phpBB/phpbb/db/driver/mssqlnative.php +++ b/phpBB/phpbb/db/driver/mssqlnative.php @@ -156,7 +156,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } - else if (strpos($query, 'SELECT') === 0 && $this->query_result) + else if (strpos($query, 'SELECT') === 0) { $this->open_queries[(int) $this->query_result] = $this->query_result; } diff --git a/phpBB/phpbb/db/driver/mysql.php b/phpBB/phpbb/db/driver/mysql.php index 50bb8204a8..ed8f16fa5f 100644 --- a/phpBB/phpbb/db/driver/mysql.php +++ b/phpBB/phpbb/db/driver/mysql.php @@ -202,7 +202,7 @@ class mysql extends \phpbb\db\driver\mysql_base $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } - else if (strpos($query, 'SELECT') === 0 && $this->query_result) + else if (strpos($query, 'SELECT') === 0) { $this->open_queries[(int) $this->query_result] = $this->query_result; } diff --git a/phpBB/phpbb/db/driver/oracle.php b/phpBB/phpbb/db/driver/oracle.php index 0dfd8484ee..cacee3ef41 100644 --- a/phpBB/phpbb/db/driver/oracle.php +++ b/phpBB/phpbb/db/driver/oracle.php @@ -441,7 +441,7 @@ class oracle extends \phpbb\db\driver\driver $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } - else if (strpos($query, 'SELECT') === 0 && $this->query_result) + else if (strpos($query, 'SELECT') === 0) { $this->open_queries[(int) $this->query_result] = $this->query_result; } diff --git a/phpBB/phpbb/db/driver/postgres.php b/phpBB/phpbb/db/driver/postgres.php index 3fade46bdd..78825de73c 100644 --- a/phpBB/phpbb/db/driver/postgres.php +++ b/phpBB/phpbb/db/driver/postgres.php @@ -209,7 +209,7 @@ class postgres extends \phpbb\db\driver\driver $this->open_queries[(int) $this->query_result] = $this->query_result; $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); } - else if (strpos($query, 'SELECT') === 0 && $this->query_result) + else if (strpos($query, 'SELECT') === 0) { $this->open_queries[(int) $this->query_result] = $this->query_result; } -- cgit v1.2.1 From d039f56af00fb98b2b03f54f00ce4bb1436e9932 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 22 Jun 2014 22:49:33 +0200 Subject: [ticket/12387] Use the hash as query_id for caching PHPBB3-12387 --- phpBB/phpbb/cache/driver/file.php | 8 ++++---- phpBB/phpbb/cache/driver/memory.php | 11 +++++------ 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index b32af32d25..fbd3b571f7 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -396,13 +396,13 @@ class file extends \phpbb\cache\driver\base { // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); + $query_id = md5($query); - if (($rowset = $this->_read('sql_' . md5($query))) === false) + if (($rowset = $this->_read('sql_' . $query_id)) === false) { return false; } - $query_id = sizeof($this->sql_rowset); $this->sql_rowset[$query_id] = $rowset; $this->sql_row_pointer[$query_id] = 0; @@ -417,7 +417,7 @@ class file extends \phpbb\cache\driver\base // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); - $query_id = sizeof($this->sql_rowset); + $query_id = md5($query); $this->sql_rowset[$query_id] = array(); $this->sql_row_pointer[$query_id] = 0; @@ -427,7 +427,7 @@ class file extends \phpbb\cache\driver\base } $db->sql_freeresult($query_result); - if ($this->_write('sql_' . md5($query), $this->sql_rowset[$query_id], $ttl + time(), $query)) + if ($this->_write('sql_' . $query_id, $this->sql_rowset[$query_id], $ttl + time(), $query)) { return $query_id; } diff --git a/phpBB/phpbb/cache/driver/memory.php b/phpBB/phpbb/cache/driver/memory.php index 5dee375192..cb2b6a10a7 100644 --- a/phpBB/phpbb/cache/driver/memory.php +++ b/phpBB/phpbb/cache/driver/memory.php @@ -266,9 +266,9 @@ abstract class memory extends \phpbb\cache\driver\base { // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); - $query_id = sizeof($this->sql_rowset); + $query_id = md5($query); - if (($result = $this->_read('sql_' . md5($query))) === false) + if (($result = $this->_read('sql_' . $query_id)) === false) { return false; } @@ -286,7 +286,7 @@ abstract class memory extends \phpbb\cache\driver\base { // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); - $hash = md5($query); + $query_id = md5($query); // determine which tables this query belongs to // Some queries use backticks, namely the get_database_size() query @@ -315,14 +315,13 @@ abstract class memory extends \phpbb\cache\driver\base $temp = array(); } - $temp[$hash] = true; + $temp[$query_id] = true; // This must never expire $this->_write('sql_' . $table_name, $temp, 0); } // store them in the right place - $query_id = sizeof($this->sql_rowset); $this->sql_rowset[$query_id] = array(); $this->sql_row_pointer[$query_id] = 0; @@ -332,7 +331,7 @@ abstract class memory extends \phpbb\cache\driver\base } $db->sql_freeresult($query_result); - $this->_write('sql_' . $hash, $this->sql_rowset[$query_id], $ttl); + $this->_write('sql_' . $query_id, $this->sql_rowset[$query_id], $ttl); return $query_id; } -- cgit v1.2.1 From bc3659a1861597b8edd5b9b3789260b93ac3f121 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 22 Jun 2014 23:13:10 +0200 Subject: [ticket/12387] Fix \phpbb\db\driver\mysqli::sql_freeresult PHPBB3-12387 --- phpBB/phpbb/db/driver/mysqli.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/mysqli.php b/phpBB/phpbb/db/driver/mysqli.php index 410d84c1df..4c6963673e 100644 --- a/phpBB/phpbb/db/driver/mysqli.php +++ b/phpBB/phpbb/db/driver/mysqli.php @@ -293,11 +293,16 @@ class mysqli extends \phpbb\db\driver\mysql_base return $cache->sql_freeresult($query_id); } - if (!$this->query_result) + if (!$query_id) { return false; } + if ($query_id === true) + { + return true; + } + return mysqli_free_result($query_id); } -- cgit v1.2.1 From cc32ee8a2848b902f7dc9d809499855a78cb41f4 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 23 Jun 2014 00:31:56 +0200 Subject: [ticket/12387] Fix a call to sql_freeresult in full_text_native PHPBB3-12387 --- phpBB/phpbb/search/fulltext_native.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index f7b1751a51..8d97916ec5 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -848,7 +848,7 @@ class fulltext_native extends \phpbb\search\base $sql_calc = $this->db->sql_build_query('SELECT', $sql_array_copy); unset($sql_array_copy); - $this->db->sql_query($sql_calc); + $result = $this->db->sql_query($sql_calc); $this->db->sql_freeresult($result); $sql_count = 'SELECT FOUND_ROWS() as total_results'; -- cgit v1.2.1 From 192b8e2568f499aa2ead98a24d8dd5541b1f315a Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 2 Aug 2014 19:09:42 +0200 Subject: [ticket/11649] Expose Twig through the container PHPBB3-11649 --- phpBB/phpbb/template/twig/environment.php | 30 +++++++++++++++++++++++- phpBB/phpbb/template/twig/twig.php | 39 ++++++++----------------------- 2 files changed, 39 insertions(+), 30 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 476ffd935e..df586af9e5 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -13,6 +13,9 @@ namespace phpbb\template\twig; +use Twig_Lexer; +use Twig_LexerInterface; + class environment extends \Twig_Environment { /** @var \phpbb\config\config */ @@ -21,6 +24,9 @@ class environment extends \Twig_Environment /** @var \phpbb\path_helper */ protected $phpbb_path_helper; + /** @var \Symfony\Component\DependencyInjection\ContainerInterface */ + protected $container; + /** @var \phpbb\extension\manager */ protected $extension_manager; @@ -38,23 +44,45 @@ class environment extends \Twig_Environment * * @param \phpbb\config\config $phpbb_config The phpBB configuration * @param \phpbb\path_helper $path_helper phpBB path helper + * @param \Symfony\Component\DependencyInjection\ContainerInterface $container * @param \phpbb\extension\manager $extension_manager phpBB extension manager * @param \Twig_LoaderInterface $loader Twig loader interface * @param array $options Array of options to pass to Twig */ - public function __construct($phpbb_config, \phpbb\path_helper $path_helper, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array()) + public function __construct($phpbb_config, \phpbb\path_helper $path_helper, \Symfony\Component\DependencyInjection\ContainerInterface $container, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array()) { $this->phpbb_config = $phpbb_config; $this->phpbb_path_helper = $path_helper; $this->extension_manager = $extension_manager; + $this->container = $container; $this->phpbb_root_path = $this->phpbb_path_helper->get_phpbb_root_path(); $this->web_root_path = $this->phpbb_path_helper->get_web_root_path(); + $options = array_merge(array( + 'cache' => (defined('IN_INSTALL')) ? false : $cache_path, + 'debug' => defined('DEBUG'), + 'auto_reload' => (bool) $this->phpbb_config['load_tplcompile'], + 'autoescape' => false, + ), $options); + return parent::__construct($loader, $options); } + /** + * {@inheritdoc} + */ + public function getLexer() + { + if (null === $this->lexer) { + $this->lexer = $this->container->get('template.twig.lexer'); + } + + return $this->lexer; + } + + /** * Get the list of enabled phpBB extensions * diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php index 5e2057f818..dd6117819a 100644 --- a/phpBB/phpbb/template/twig/twig.php +++ b/phpBB/phpbb/template/twig/twig.php @@ -78,9 +78,12 @@ class twig extends \phpbb\template\base * @param \phpbb\config\config $config * @param \phpbb\user $user * @param \phpbb\template\context $context template context + * @param \phpbb\template\twig\environment $twig_environment + * @param string $cache_path + * @param array|\ArrayAccess $extensions * @param \phpbb\extension\manager $extension_manager extension manager, if null then template events will not be invoked */ - public function __construct(\phpbb\path_helper $path_helper, $config, $user, \phpbb\template\context $context, \phpbb\extension\manager $extension_manager = null) + public function __construct(\phpbb\path_helper $path_helper, $config, $user, \phpbb\template\context $context, \phpbb\template\twig\environment $twig_environment, $cache_path, $extensions = array(), \phpbb\extension\manager $extension_manager = null) { $this->path_helper = $path_helper; $this->phpbb_root_path = $path_helper->get_phpbb_root_path(); @@ -89,35 +92,13 @@ class twig extends \phpbb\template\base $this->user = $user; $this->context = $context; $this->extension_manager = $extension_manager; + $this->cachepath = $cache_path; + $this->twig = $twig_environment; - $this->cachepath = $this->phpbb_root_path . 'cache/twig/'; - - // Initiate the loader, __main__ namespace paths will be setup later in set_style_names() - $loader = new \phpbb\template\twig\loader(''); - - $this->twig = new \phpbb\template\twig\environment( - $this->config, - $this->path_helper, - $this->extension_manager, - $loader, - array( - 'cache' => (defined('IN_INSTALL')) ? false : $this->cachepath, - 'debug' => defined('DEBUG'), - 'auto_reload' => (bool) $this->config['load_tplcompile'], - 'autoescape' => false, - ) - ); - - $this->twig->addExtension( - new \phpbb\template\twig\extension( - $this->context, - $this->user - ) - ); - - $lexer = new \phpbb\template\twig\lexer($this->twig); - - $this->twig->setLexer($lexer); + foreach ($extensions as $extension) + { + $this->twig->addExtension($extension); + } // Add admin namespace if ($this->path_helper->get_adm_relative_path() !== null && is_dir($this->phpbb_root_path . $this->path_helper->get_adm_relative_path() . 'style/')) -- cgit v1.2.1 From 827510a4185ae8ef6fbf0d0f2fbeb92bf63ccace Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 9 Aug 2014 16:14:58 +0200 Subject: [ticket/11649] Fix coding style PHPBB3-11649 --- phpBB/phpbb/template/twig/environment.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index df586af9e5..f6d9b73178 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -44,7 +44,8 @@ class environment extends \Twig_Environment * * @param \phpbb\config\config $phpbb_config The phpBB configuration * @param \phpbb\path_helper $path_helper phpBB path helper - * @param \Symfony\Component\DependencyInjection\ContainerInterface $container + * @param \Symfony\Component\DependencyInjection\ContainerInterface $container The dependency injection container + * @param string $cache_path The path to the cache directory * @param \phpbb\extension\manager $extension_manager phpBB extension manager * @param \Twig_LoaderInterface $loader Twig loader interface * @param array $options Array of options to pass to Twig @@ -61,11 +62,11 @@ class environment extends \Twig_Environment $this->web_root_path = $this->phpbb_path_helper->get_web_root_path(); $options = array_merge(array( - 'cache' => (defined('IN_INSTALL')) ? false : $cache_path, - 'debug' => defined('DEBUG'), - 'auto_reload' => (bool) $this->phpbb_config['load_tplcompile'], - 'autoescape' => false, - ), $options); + 'cache' => (defined('IN_INSTALL')) ? false : $cache_path, + 'debug' => defined('DEBUG'), + 'auto_reload' => (bool) $this->phpbb_config['load_tplcompile'], + 'autoescape' => false, + ), $options); return parent::__construct($loader, $options); } @@ -75,7 +76,8 @@ class environment extends \Twig_Environment */ public function getLexer() { - if (null === $this->lexer) { + if (null === $this->lexer) + { $this->lexer = $this->container->get('template.twig.lexer'); } -- cgit v1.2.1 From e7e6d45789d4084b98a9c6227a42976e4a1d8f7f Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 10 Aug 2014 02:26:16 +0200 Subject: [ticket/12957] Update the constructions of the template engine PHPBB3-12957 --- phpBB/phpbb/template/twig/environment.php | 1 + phpBB/phpbb/template/twig/lexer.php | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index f6d9b73178..b3f57b016f 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -79,6 +79,7 @@ class environment extends \Twig_Environment if (null === $this->lexer) { $this->lexer = $this->container->get('template.twig.lexer'); + $this->lexer->set_environment($this); } return $this->lexer; diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php index c5dc7273ba..a7848738bb 100644 --- a/phpBB/phpbb/template/twig/lexer.php +++ b/phpBB/phpbb/template/twig/lexer.php @@ -15,6 +15,11 @@ namespace phpbb\template\twig; class lexer extends \Twig_Lexer { + public function set_environment(\Twig_Environment $env) + { + $this->env = $env; + } + public function tokenize($code, $filename = null) { // Our phpBB tags -- cgit v1.2.1 From 143c1ba8d10bc27500812acd433ffca56110f02c Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 10 Aug 2014 04:01:47 +0200 Subject: [ticket/12957] Removed unused use PHPBB3-12957 --- phpBB/phpbb/template/twig/environment.php | 3 --- 1 file changed, 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index b3f57b016f..0ba7a265e4 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -13,9 +13,6 @@ namespace phpbb\template\twig; -use Twig_Lexer; -use Twig_LexerInterface; - class environment extends \Twig_Environment { /** @var \phpbb\config\config */ -- cgit v1.2.1 From 59780bbd091c9e162eaf5f399f9bb2440605c4f7 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sun, 10 Aug 2014 12:17:03 +0200 Subject: [ticket/12958] Remove more references of subsilver2 PHPBB3-12958 --- phpBB/phpbb/event/md_exporter.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/event/md_exporter.php b/phpBB/phpbb/event/md_exporter.php index f7021875f3..84b10e79c1 100644 --- a/phpBB/phpbb/event/md_exporter.php +++ b/phpBB/phpbb/event/md_exporter.php @@ -89,7 +89,7 @@ class md_exporter { $this->crawl_eventsmd($md_file, 'styles'); - $styles = array('prosilver', 'subsilver2'); + $styles = array('prosilver'); foreach ($styles as $style) { $file_list = $this->get_recursive_file_list( @@ -179,7 +179,7 @@ class md_exporter { $wiki_page = '= Template Events =' . "\n"; $wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n"; - $wiki_page .= '! Identifier !! Prosilver Placement (If applicable) !! Subsilver Placement (If applicable) !! Added in Release !! Explanation' . "\n"; + $wiki_page .= '! Identifier !! Prosilver Placement (If applicable) !! Added in Release !! Explanation' . "\n"; } foreach ($this->events as $event_name => $event) @@ -193,7 +193,7 @@ class md_exporter } else { - $wiki_page .= implode(', ', $event['files']['prosilver']) . ' || ' . implode(', ', $event['files']['subsilver2']); + $wiki_page .= implode(', ', $event['files']['prosilver']); } $wiki_page .= " || {$event['since']} || " . str_replace("\n", ' ', $event['description']) . "\n"; @@ -246,7 +246,6 @@ class md_exporter { $files_list = array( 'prosilver' => array(), - 'subsilver2' => array(), 'adm' => array(), ); @@ -266,10 +265,6 @@ class md_exporter { $files_list['prosilver'][] = substr($file, strlen('styles/prosilver/template/')); } - else if (($this->filter !== 'adm') && strpos($file, 'styles/subsilver2/template/') === 0) - { - $files_list['subsilver2'][] = substr($file, strlen('styles/subsilver2/template/')); - } else if (($this->filter === 'adm') && strpos($file, 'adm/style/') === 0) { $files_list['adm'][] = substr($file, strlen('adm/style/')); -- cgit v1.2.1 From 5a7caf65084369422fdbe4aaaae46e5de69cc594 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 20 Nov 2013 13:47:31 +0100 Subject: [feature/patchwork-utf8] Normalize with intl, use patchwork/utf8 as fallback --- phpBB/phpbb/search/fulltext_native.php | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 34947b176d..ea239c0b36 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -18,6 +18,13 @@ namespace phpbb\search; */ class fulltext_native extends \phpbb\search\base { + const UTF8_HANGUL_FIRST = "\xEA\xB0\x80"; + const UTF8_HANGUL_LAST = "\xED\x9E\xA3"; + const UTF8_CJK_FIRST = "\xE4\xB8\x80"; + const UTF8_CJK_LAST = "\xE9\xBE\xBB"; + const UTF8_CJK_B_FIRST = "\xF0\xA0\x80\x80"; + const UTF8_CJK_B_LAST = "\xF0\xAA\x9B\x96"; + /** * Associative array holding index stats * @var array @@ -93,7 +100,7 @@ class fulltext_native extends \phpbb\search\base protected $user; /** - * Initialises the fulltext_native search backend with min/max word length and makes sure the UTF-8 normalizer is loaded + * Initialises the fulltext_native search backend with min/max word length * * @param boolean|string &$error is passed by reference and should either be set to false on success or an error message on failure */ @@ -110,10 +117,6 @@ class fulltext_native extends \phpbb\search\base /** * Load the UTF tools */ - if (!class_exists('utf_normalizer')) - { - include($this->phpbb_root_path . 'includes/utf/utf_normalizer.' . $this->php_ext); - } if (!function_exists('utf8_decode_ncr')) { include($this->phpbb_root_path . 'includes/utf/utf_tools.' . $this->php_ext); @@ -1175,9 +1178,9 @@ class fulltext_native extends \phpbb\search\base * Note: this could be optimized. If the codepoint is lower than Hangul's range * we know that it will also be lower than CJK ranges */ - if ((strncmp($word, UTF8_HANGUL_FIRST, 3) < 0 || strncmp($word, UTF8_HANGUL_LAST, 3) > 0) - && (strncmp($word, UTF8_CJK_FIRST, 3) < 0 || strncmp($word, UTF8_CJK_LAST, 3) > 0) - && (strncmp($word, UTF8_CJK_B_FIRST, 4) < 0 || strncmp($word, UTF8_CJK_B_LAST, 4) > 0)) + if ((strncmp($word, self::UTF8_HANGUL_FIRST, 3) < 0 || strncmp($word, self::UTF8_HANGUL_LAST, 3) > 0) + && (strncmp($word, self::UTF8_CJK_FIRST, 3) < 0 || strncmp($word, self::UTF8_CJK_LAST, 3) > 0) + && (strncmp($word, self::UTF8_CJK_B_FIRST, 4) < 0 || strncmp($word, self::UTF8_CJK_B_LAST, 4) > 0)) { $word = strtok(' '); continue; @@ -1544,8 +1547,6 @@ class fulltext_native extends \phpbb\search\base * @param string $allowed_chars String of special chars to allow * @param string $encoding Text encoding * @return string Cleaned up text, only alphanumeric chars are left - * - * @todo \normalizer::cleanup being able to be used? */ protected function cleanup($text, $allowed_chars = null, $encoding = 'utf-8') { @@ -1572,12 +1573,9 @@ class fulltext_native extends \phpbb\search\base $text = htmlspecialchars_decode(utf8_decode_ncr($text), ENT_QUOTES); /** - * Load the UTF-8 normalizer - * - * If we use it more widely, an instance of that class should be held in a - * a global variable instead + * Normalize to NFC */ - \utf_normalizer::nfc($text); + $text = \Normalizer::normalize($text); /** * The first thing we do is: @@ -1670,9 +1668,9 @@ class fulltext_native extends \phpbb\search\base $utf_char = substr($text, $pos, $utf_len); $pos += $utf_len; - if (($utf_char >= UTF8_HANGUL_FIRST && $utf_char <= UTF8_HANGUL_LAST) - || ($utf_char >= UTF8_CJK_FIRST && $utf_char <= UTF8_CJK_LAST) - || ($utf_char >= UTF8_CJK_B_FIRST && $utf_char <= UTF8_CJK_B_LAST)) + if (($utf_char >= self::UTF8_HANGUL_FIRST && $utf_char <= self::UTF8_HANGUL_LAST) + || ($utf_char >= self::UTF8_CJK_FIRST && $utf_char <= self::UTF8_CJK_LAST) + || ($utf_char >= self::UTF8_CJK_B_FIRST && $utf_char <= self::UTF8_CJK_B_LAST)) { /** * All characters within these ranges are valid -- cgit v1.2.1 From a2300eb3aa428a080314caf0c0b60556f6701ffa Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 20 Nov 2013 14:04:06 +0100 Subject: [feature/patchwork-utf8] Remove utf8_str_replace --- phpBB/phpbb/db/driver/driver.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 4be315a154..8d360fc3e2 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -363,8 +363,8 @@ abstract class driver implements driver_interface */ function sql_like_expression($expression) { - $expression = utf8_str_replace(array('_', '%'), array("\_", "\%"), $expression); - $expression = utf8_str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $expression); + $expression = str_replace(array('_', '%'), array("\_", "\%"), $expression); + $expression = str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $expression); return $this->_sql_like_expression('LIKE \'' . $this->sql_escape($expression) . '\''); } @@ -374,8 +374,8 @@ abstract class driver implements driver_interface */ function sql_not_like_expression($expression) { - $expression = utf8_str_replace(array('_', '%'), array("\_", "\%"), $expression); - $expression = utf8_str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $expression); + $expression = str_replace(array('_', '%'), array("\_", "\%"), $expression); + $expression = str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $expression); return $this->_sql_not_like_expression('NOT LIKE \'' . $this->sql_escape($expression) . '\''); } -- cgit v1.2.1 From a5bfc76a73a213a388126d0f697ba64f27a4b00d Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 14 Sep 2014 21:18:20 +0200 Subject: [ticket/13063] Introduces a new \phpbb\routing\router class PHPBB3-13063 --- phpBB/phpbb/cache/driver/base.php | 1 + phpBB/phpbb/controller/helper.php | 17 +- phpBB/phpbb/controller/provider.php | 92 ------- phpBB/phpbb/event/kernel_request_subscriber.php | 82 ------- phpBB/phpbb/routing/router.php | 304 ++++++++++++++++++++++++ 5 files changed, 315 insertions(+), 181 deletions(-) delete mode 100644 phpBB/phpbb/controller/provider.php delete mode 100644 phpBB/phpbb/event/kernel_request_subscriber.php create mode 100644 phpBB/phpbb/routing/router.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/base.php b/phpBB/phpbb/cache/driver/base.php index b357431589..c83b928a12 100644 --- a/phpBB/phpbb/cache/driver/base.php +++ b/phpBB/phpbb/cache/driver/base.php @@ -50,6 +50,7 @@ abstract class base implements \phpbb\cache\driver\driver_interface } else if (strpos($filename, 'container_') === 0 || strpos($filename, 'url_matcher') === 0 || + strpos($filename, 'url_generator') === 0 || strpos($filename, 'sql_') === 0 || strpos($filename, 'data_') === 0) { diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index 52e6947c2c..f4535af711 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -14,7 +14,6 @@ namespace phpbb\controller; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Generator\UrlGenerator; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RequestContext; @@ -41,6 +40,11 @@ class helper */ protected $config; + /** + * @var \phpbb\routing\router phpBB router + */ + protected $router; + /* @var \phpbb\symfony_request */ protected $symfony_request; @@ -70,7 +74,7 @@ class helper * @param \phpbb\template\template $template Template object * @param \phpbb\user $user User object * @param \phpbb\config\config $config Config object - * @param \phpbb\controller\provider $provider Path provider + * @param \phpbb\routing\router $router phpBB router * @param \phpbb\extension\manager $manager Extension manager object * @param \phpbb\symfony_request $symfony_request Symfony Request object * @param \phpbb\request\request_interface $request phpBB request object @@ -78,18 +82,17 @@ class helper * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP file extension */ - public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\routing\router $router, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext) { $this->template = $template; $this->user = $user; $this->config = $config; + $this->router = $router; $this->symfony_request = $symfony_request; $this->request = $request; $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; - $provider->find_routing_files($manager->get_finder()); - $this->route_collection = $provider->find($phpbb_root_path)->get_routes(); } /** @@ -162,8 +165,8 @@ class helper $context->setBaseUrl($base_url); - $url_generator = new UrlGenerator($this->route_collection, $context); - $route_url = $url_generator->generate($route, $params, $reference_type); + $this->router->setContext($context); + $route_url = $this->router->generate($route, $params, $reference_type); if ($is_amp) { diff --git a/phpBB/phpbb/controller/provider.php b/phpBB/phpbb/controller/provider.php deleted file mode 100644 index 7e26848290..0000000000 --- a/phpBB/phpbb/controller/provider.php +++ /dev/null @@ -1,92 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\controller; - -use Symfony\Component\Routing\RouteCollection; -use Symfony\Component\Routing\Loader\YamlFileLoader; -use Symfony\Component\Config\FileLocator; - -/** -* Controller interface -*/ -class provider -{ - /** - * YAML file(s) containing route information - * @var array - */ - protected $routing_files; - - /** - * Collection of the routes in phpBB and all found extensions - * @var RouteCollection - */ - protected $routes; - - /** - * Construct method - * - * @param array $routing_files Array of strings containing paths - * to YAML files holding route information - */ - public function __construct($routing_files = array()) - { - $this->routing_files = $routing_files; - } - - /** - * Find the list of routing files - * - * @param \phpbb\finder $finder - * @return null - */ - public function find_routing_files(\phpbb\finder $finder) - { - // We hardcode the path to the core config directory - // because the finder cannot find it - $this->routing_files = array_merge($this->routing_files, array('config/routing.yml'), array_keys($finder - ->directory('/config') - ->suffix('routing.yml') - ->find() - )); - } - - /** - * Find a list of controllers - * - * @param string $base_path Base path to prepend to file paths - * @return provider - */ - public function find($base_path = '') - { - $this->routes = new RouteCollection; - foreach ($this->routing_files as $file_path) - { - $loader = new YamlFileLoader(new FileLocator(phpbb_realpath($base_path))); - $this->routes->addCollection($loader->load($file_path)); - } - - return $this; - } - - /** - * Get the list of routes - * - * @return RouteCollection Get the route collection - */ - public function get_routes() - { - return $this->routes; - } -} diff --git a/phpBB/phpbb/event/kernel_request_subscriber.php b/phpBB/phpbb/event/kernel_request_subscriber.php deleted file mode 100644 index ee9f29a59d..0000000000 --- a/phpBB/phpbb/event/kernel_request_subscriber.php +++ /dev/null @@ -1,82 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\event; - -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Symfony\Component\HttpKernel\EventListener\RouterListener; -use Symfony\Component\Routing\RequestContext; - -class kernel_request_subscriber implements EventSubscriberInterface -{ - /** - * Extension manager object - * @var \phpbb\extension\manager - */ - protected $manager; - - /** - * PHP file extension - * @var string - */ - protected $php_ext; - - /** - * Root path - * @var string - */ - protected $root_path; - - /** - * Construct method - * - * @param \phpbb\extension\manager $manager Extension manager object - * @param string $root_path Root path - * @param string $php_ext PHP file extension - */ - public function __construct(\phpbb\extension\manager $manager, $root_path, $php_ext) - { - $this->root_path = $root_path; - $this->php_ext = $php_ext; - $this->manager = $manager; - } - - /** - * This listener is run when the KernelEvents::REQUEST event is triggered - * - * This is responsible for setting up the routing information - * - * @param GetResponseEvent $event - * @throws \BadMethodCallException - * @return null - */ - public function on_kernel_request(GetResponseEvent $event) - { - $request = $event->getRequest(); - $context = new RequestContext(); - $context->fromRequest($request); - - $matcher = phpbb_get_url_matcher($this->manager, $context, $this->root_path, $this->php_ext); - $router_listener = new RouterListener($matcher, $context); - $router_listener->onKernelRequest($event); - } - - public static function getSubscribedEvents() - { - return array( - KernelEvents::REQUEST => 'on_kernel_request', - ); - } -} diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php new file mode 100644 index 0000000000..cebf19e702 --- /dev/null +++ b/phpBB/phpbb/routing/router.php @@ -0,0 +1,304 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\routing; + +use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; +use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper; +use Symfony\Component\Routing\Matcher\UrlMatcher; +use Symfony\Component\Routing\Generator\UrlGenerator; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RouterInterface; +use Symfony\Component\Routing\Loader\YamlFileLoader; +use Symfony\Component\Config\FileLocator; +use phpbb\extension\manager; + +/** +* Integration of all pieces of the routing system for easier use. +*/ +class router implements RouterInterface +{ + /** + * @var manager Extension manager + */ + protected $extension_manager; + + /** + * @var string phpBB root path + */ + protected $phpbb_root_path; + + /** + * @var string PHP file extensions + */ + protected $php_ext; + + /** + * @var array YAML file(s) containing route information + */ + protected $routing_files; + + /** + * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|null + */ + protected $matcher; + + /** + * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface|null + */ + protected $generator; + + /** + * @var RequestContext + */ + protected $context; + + /** + * @var RouteCollection|null + */ + protected $route_collection; + + /** + * Construct method + * + * @param manager $extension_manager The extension manager + * @param string $phpbb_root_path phpBB root path + * @param string $php_ext PHP file extension + * @param array $routing_files Array of strings containing paths + * to YAML files holding route information + */ + public function __construct(manager $extension_manager, $phpbb_root_path, $php_ext, $routing_files = array()) + { + $this->extension_manager = $extension_manager; + $this->routing_files = $routing_files; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->context = new RequestContext(); + } + + /** + * Find the list of routing files + * + * @param \phpbb\finder $finder + * @return router + */ + public function find_routing_files(\phpbb\finder $finder) + { + if ($this->routing_files === null || empty($this->routing_files)) + { + // We hardcode the path to the core config directory + // because the finder cannot find it + $this->routing_files = array_merge($this->routing_files, array('config/routing.yml'), array_keys($finder + ->directory('/config') + ->suffix('routing.yml') + ->find() + )); + } + + return $this; + } + + /** + * Find a list of controllers + * + * @param string $base_path Base path to prepend to file paths + * @return router + */ + public function find($base_path = '') + { + if ($this->route_collection === null || $this->route_collection->count() === 0) + { + $this->route_collection = new RouteCollection; + foreach ($this->routing_files as $file_path) + { + $loader = new YamlFileLoader(new FileLocator(phpbb_realpath($base_path))); + $this->route_collection->addCollection($loader->load($file_path)); + } + } + + return $this; + } + + /** + * Get the list of routes + * + * @return RouteCollection Get the route collection + */ + public function get_routes() + { + if ($this->route_collection == null || empty($this->routing_files)) + { + $this->find_routing_files($this->extension_manager->get_finder()) + ->find($this->phpbb_root_path); + } + + return $this->route_collection; + } + + /** + * {@inheritdoc} + */ + public function getRouteCollection() + { + return $this->get_routes(); + } + + /** + * {@inheritdoc} + */ + public function setContext(RequestContext $context) + { + $this->context = $context; + + if ($this->matcher !== null) + { + $this->get_matcher()->setContext($context); + } + if ($this->generator !== null) + { + $this->get_generator()->setContext($context); + } + } + + /** + * {@inheritdoc} + */ + public function getContext() + { + return $this->context; + } + + /** + * {@inheritdoc} + */ + public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) + { + return $this->get_generator()->generate($name, $parameters, $referenceType); + } + + /** + * {@inheritdoc} + */ + public function match($pathinfo) + { + return $this->get_matcher()->match($pathinfo); + } + + /** + * Gets the UrlMatcher instance associated with this Router. + * + * @return \Symfony\Component\Routing\Matcher\UrlMatcherInterface A UrlMatcherInterface instance + */ + public function get_matcher() + { + if ($this->matcher !== null) + { + return $this->matcher; + } + + if (defined('DEBUG')) + { + $this->create_new_url_matcher(); + } + else + { + $this->create_dumped_url_matcher(); + } + + return $this->matcher; + } + /** + * Creates a new dumped URL Matcher (dump it if necessary) + */ + protected function create_dumped_url_matcher() + { + if (!file_exists($this->phpbb_root_path . 'cache/url_matcher.' . $this->php_ext)) + { + $dumper = new PhpMatcherDumper($this->get_routes()); + + $options = array( + 'class' => 'phpbb_url_matcher', + ); + + $dump = $dumper->dump($options); + file_put_contents($this->phpbb_root_path . 'cache/url_matcher.' . $this->php_ext, $dump); + } + + require_once($this->phpbb_root_path . 'cache/url_matcher.' . $this->php_ext); + + $this->matcher = new phpbb_url_matcher($this->context); + } + + /** + * Creates a new URL Matcher + */ + protected function create_new_url_matcher() + { + $this->matcher = new UrlMatcher($this->get_routes(), $this->context); + } + + /** + * Gets the UrlGenerator instance associated with this Router. + * + * @return \Symfony\Component\Routing\Generator\UrlGeneratorInterface A UrlGeneratorInterface instance + */ + public function get_generator() + { + if ($this->generator !== null) + { + return $this->generator; + } + + if (defined('DEBUG')) + { + $this->create_new_url_generator(); + } + else + { + $this->create_dumped_url_generator(); + } + + return $this->generator; + } + + /** + * Creates a new dumped URL Generator (dump it if necessary) + */ + protected function create_dumped_url_generator() + { + if (!file_exists($this->phpbb_root_path . 'cache/url_generator.' . $this->php_ext)) + { + $dumper = new PhpGeneratorDumper($this->get_routes()); + + $options = array( + 'class' => 'phpbb_url_generator', + ); + + $dump = $dumper->dump($options); + file_put_contents($this->phpbb_root_path . 'cache/url_generator.' . $this->php_ext, $dump); + } + + require_once($this->phpbb_root_path . 'cache/url_generator.' . $this->php_ext); + + $this->generator = new phpbb_url_generator($this->context); + } + + /** + * Creates a new URL Generator + */ + protected function create_new_url_generator() + { + $this->generator = new UrlGenerator($this->get_routes(), $this->context); + } +} -- cgit v1.2.1 From fdcd6e81cd4ae530036fd18ad184c0d2423c6949 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 20 Nov 2014 16:37:45 +0100 Subject: [ticket/13063] Fix tests after rebase PHPBB3-13063 --- phpBB/phpbb/controller/helper.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index f4535af711..cc327882e0 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -75,14 +75,13 @@ class helper * @param \phpbb\user $user User object * @param \phpbb\config\config $config Config object * @param \phpbb\routing\router $router phpBB router - * @param \phpbb\extension\manager $manager Extension manager object * @param \phpbb\symfony_request $symfony_request Symfony Request object * @param \phpbb\request\request_interface $request phpBB request object * @param \phpbb\filesystem $filesystem The filesystem object * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP file extension */ - public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\routing\router $router, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\routing\router $router, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext) { $this->template = $template; $this->user = $user; -- cgit v1.2.1 From 2573dd18ca3327d0b5209a8d465f7911034c1302 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 20 Nov 2014 16:47:24 +0100 Subject: [ticket/13063] Fix coding style PHPBB3-13063 --- phpBB/phpbb/routing/router.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index cebf19e702..f721837bba 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -72,11 +72,10 @@ class router implements RouterInterface /** * Construct method * - * @param manager $extension_manager The extension manager - * @param string $phpbb_root_path phpBB root path - * @param string $php_ext PHP file extension - * @param array $routing_files Array of strings containing paths - * to YAML files holding route information + * @param manager $extension_manager The extension manager + * @param string $phpbb_root_path phpBB root path + * @param string $php_ext PHP file extension + * @param array $routing_files Array of strings containing paths to YAML files holding route information */ public function __construct(manager $extension_manager, $phpbb_root_path, $php_ext, $routing_files = array()) { -- cgit v1.2.1 From c22562f5cdb3db9482a7c6bc2398ebb12cbcfb8b Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 30 May 2014 14:57:19 +0200 Subject: [ticket/12620] Allow the user to define multiples environments PHPBB3-12620 --- phpBB/phpbb/di/extension/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index ca4fa5c082..d203cc7049 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -50,7 +50,7 @@ class core extends Extension public function load(array $config, ContainerBuilder $container) { $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($this->config_path))); - $loader->load('services.yml'); + $loader->load('config_' . ENVIRONMENT . '.yml'); } /** -- cgit v1.2.1 From 873260589eaa7ac2d7e520ebe321cb8bb2609ce0 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 30 May 2014 15:29:09 +0200 Subject: [ticket/12620] Display error message when the environment isn't available PHPBB3-12620 --- phpBB/phpbb/di/extension/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index d203cc7049..5fb8d9ad34 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -50,7 +50,7 @@ class core extends Extension public function load(array $config, ContainerBuilder $container) { $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($this->config_path))); - $loader->load('config_' . ENVIRONMENT . '.yml'); + $loader->load('environment_' . ENVIRONMENT . '.yml'); } /** -- cgit v1.2.1 From 8664d3229a511eb320fef3df6a852d1a20852dae Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 20 Jun 2014 18:49:19 +0200 Subject: [ticket/12620] Split the environments into differents folders PHPBB3-12620 --- phpBB/phpbb/di/extension/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 5fb8d9ad34..cff0a1e76e 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -50,7 +50,7 @@ class core extends Extension public function load(array $config, ContainerBuilder $container) { $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($this->config_path))); - $loader->load('environment_' . ENVIRONMENT . '.yml'); + $loader->load(ENVIRONMENT . '/environment.yml'); } /** -- cgit v1.2.1 From b697273aaa53d9f9f4a3d4a53cc6267e906953cd Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 4 Sep 2014 17:06:39 +0200 Subject: [ticket/12620] Use PHPBB_ENVIRONMENT PHPBB3-12620 --- phpBB/phpbb/di/extension/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index cff0a1e76e..7787602aba 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -50,7 +50,7 @@ class core extends Extension public function load(array $config, ContainerBuilder $container) { $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($this->config_path))); - $loader->load(ENVIRONMENT . '/environment.yml'); + $loader->load(PHPBB_ENVIRONMENT . '/environment.yml'); } /** -- cgit v1.2.1 From 0bf3d2d962c33ffa606d38e91d04665b78fbd8bc Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 5 Sep 2014 02:29:15 +0200 Subject: [ticket/12620] Add the support of the environments for the ext services We look for an environment.yml file in the config/PHPBB_ENVIRONMENT/ directory of the extensionss. If the directory does not exist we look for the environment.yml file in the 'default' environment and finally for the services.yml file in the config/ directory. PHPBB3-12620 --- phpBB/phpbb/di/extension/ext.php | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/extension/ext.php b/phpBB/phpbb/di/extension/ext.php index 718c992d2e..330303ca0c 100644 --- a/phpBB/phpbb/di/extension/ext.php +++ b/phpBB/phpbb/di/extension/ext.php @@ -45,10 +45,32 @@ class ext extends Extension { foreach ($this->paths as $path) { - if (file_exists($path . '/config/services.yml')) + $services_directory = false; + $services_file = false; + + if (file_exists($path . 'config/' . PHPBB_ENVIRONMENT . '/environment.yml')) + { + $services_directory = $path . 'config/' . PHPBB_ENVIRONMENT; + $services_file = 'environment.yml'; + } + else if (!is_dir($path . 'config/' . PHPBB_ENVIRONMENT)) + { + if (file_exists($path . 'config/default/environment.yml')) + { + $services_directory = $path . 'config/default'; + $services_file = 'environment.yml'; + } + else if (!is_dir($path . 'config/default') && file_exists($path . '/config/services.yml')) + { + $services_directory = $path . 'config'; + $services_file = 'services.yml'; + } + } + + if ($services_directory && $services_file) { - $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($path . '/config'))); - $loader->load('services.yml'); + $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($services_directory))); + $loader->load($services_file); } } } -- cgit v1.2.1 From aa061aa7c9187009f220e62252a53b49dad7644a Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 29 Sep 2014 16:06:56 +0200 Subject: [ticket/12620] Uses a cache directory per environment PHPBB3-12620 --- phpBB/phpbb/cache/driver/file.php | 7 +++- phpBB/phpbb/di/container_builder.php | 68 ++++++++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 15 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index adfe87b740..d3708fe9a0 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -28,7 +28,12 @@ class file extends \phpbb\cache\driver\base function __construct($cache_dir = null) { global $phpbb_root_path; - $this->cache_dir = !is_null($cache_dir) ? $cache_dir : $phpbb_root_path . 'cache/'; + $this->cache_dir = !is_null($cache_dir) ? $cache_dir : $phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT . '/'; + + if (!is_dir($this->cache_dir)) + { + @mkdir($this->cache_dir, 0777, true); + } } /** diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 638c13e86d..b264b0182f 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -13,16 +13,21 @@ namespace phpbb\di; +use Symfony\Component\Config\ConfigCache; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass; class container_builder { - /** @var string phpBB Root Path */ + /** + * @var string phpBB Root Path + */ protected $phpbb_root_path; - /** @var string php file extension */ + /** + * @var string php file extension + */ protected $php_ext; /** @@ -111,6 +116,11 @@ class container_builder */ protected $config_php_file; + /** + * @var string + */ + protected $cache_dir; + /** * Constructor * @@ -133,18 +143,16 @@ class container_builder public function get_container() { $container_filename = $this->get_container_filename(); - if (!defined('DEBUG_CONTAINER') && $this->dump_container && file_exists($container_filename)) + $config_cache = new ConfigCache($container_filename, defined('DEBUG')); + if ($this->dump_container && $config_cache->isFresh()) { require($container_filename); $this->container = new \phpbb_cache_container(); } else { - if ($this->config_path === null) - { - $this->config_path = $this->phpbb_root_path . 'config'; - } - $container_extensions = array(new \phpbb\di\extension\core($this->config_path)); + + $container_extensions = array(new \phpbb\di\extension\core($this->get_config_path())); if ($this->use_extensions) { @@ -178,9 +186,9 @@ class container_builder $this->container->compile(); } - if ($this->dump_container && !defined('DEBUG_CONTAINER')) + if ($this->dump_container) { - $this->dump_container($container_filename); + $this->dump_container($config_cache); } } @@ -266,6 +274,16 @@ class container_builder $this->config_path = $config_path; } + /** + * Returns the path to the container configuration (default: root_path/config) + * + * @return string + */ + protected function get_config_path() + { + return $this->config_path ?: $this->phpbb_root_path . 'config'; + } + /** * Set custom parameters to inject into the container. * @@ -276,12 +294,32 @@ class container_builder $this->custom_parameters = $custom_parameters; } + /** + * Set the path to the cache directory. + * + * @param string $cache_dir Path to the cache directory + */ + public function set_cache_dir($cache_dir) + { + $this->cache_dir = $cache_dir; + } + + /** + * Returns the path to the cache directory (default: root_path/cache/environment). + * + * @return string Path to the cache directory. + */ + protected function get_cache_dir() + { + return $this->cache_dir ?: $this->phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT . '/'; + } + /** * Dump the container to the disk. * - * @param string $container_filename The name of the file. + * @param ConfigCache $cache The config cache */ - protected function dump_container($container_filename) + protected function dump_container($cache) { $dumper = new PhpDumper($this->container); $cached_container_dump = $dumper->dump(array( @@ -289,7 +327,7 @@ class container_builder 'base_class' => 'Symfony\\Component\\DependencyInjection\\ContainerBuilder', )); - file_put_contents($container_filename, $cached_container_dump); + $cache->write($cached_container_dump, $this->container->getResources()); } /** @@ -386,6 +424,8 @@ class container_builder ); } + $this->custom_parameters['environment'] = PHPBB_ENVIRONMENT; + foreach ($this->custom_parameters as $key => $value) { $this->container->setParameter($key, $value); @@ -400,6 +440,6 @@ class container_builder protected function get_container_filename() { $filename = str_replace(array('/', '.'), array('slash', 'dot'), $this->phpbb_root_path); - return $this->phpbb_root_path . 'cache/container_' . $filename . '.' . $this->php_ext; + return $this->get_cache_dir() . 'container_' . $filename . '.' . $this->php_ext; } } -- cgit v1.2.1 From 6cbb60d13f75da6d9b6c6d60555ea119df79b5c0 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 4 Oct 2014 16:30:34 +0200 Subject: [ticket/12620] Adds a yaml config file PHPBB3-12620 --- phpBB/phpbb/di/container_builder.php | 63 +++++++++++++++------- .../phpbb/di/extension/container_configuration.php | 38 +++++++++++++ phpBB/phpbb/di/extension/core.php | 37 +++++++++++-- phpBB/phpbb/di/extension/ext.php | 8 +-- 4 files changed, 119 insertions(+), 27 deletions(-) create mode 100644 phpBB/phpbb/di/extension/container_configuration.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index b264b0182f..45dbaaf303 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -14,9 +14,13 @@ namespace phpbb\di; use Symfony\Component\Config\ConfigCache; +use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass; +use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; class container_builder { @@ -151,7 +155,6 @@ class container_builder } else { - $container_extensions = array(new \phpbb\di\extension\core($this->get_config_path())); if ($this->use_extensions) @@ -179,7 +182,8 @@ class container_builder } } - $this->inject_custom_parameters(); + $loader = new YamlFileLoader($this->container, new FileLocator(phpbb_realpath($this->get_config_path()))); + $loader->load(PHPBB_ENVIRONMENT . '/config.yml'); if ($this->compile_container) { @@ -400,36 +404,59 @@ class container_builder */ protected function create_container(array $extensions) { - $container = new ContainerBuilder(); + $container = new ContainerBuilder(new ParameterBag($this->get_core_parameters())); + + $extensions_alias = array(); foreach ($extensions as $extension) { $container->registerExtension($extension); - $container->loadFromExtension($extension->getAlias()); + $extensions_alias[] = $extension->getAlias(); + //$container->loadFromExtension($extension->getAlias()); } + $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions_alias)); + return $container; } /** - * Inject the customs parameters into the container - */ - protected function inject_custom_parameters() + * Returns the core parameters. + * + * @return array An array of core parameters + */ + protected function get_core_parameters() { - if ($this->custom_parameters === null) - { - $this->custom_parameters = array( - 'core.root_path' => $this->phpbb_root_path, - 'core.php_ext' => $this->php_ext, - ); - } - - $this->custom_parameters['environment'] = PHPBB_ENVIRONMENT; + return array_merge( + array( + 'core.root_path' => $this->phpbb_root_path, + 'core.php_ext' => $this->php_ext, + 'core.environment' => PHPBB_ENVIRONMENT, + 'core.debug' => DEBUG, + ), + $this->get_env_parameters() + ); + } - foreach ($this->custom_parameters as $key => $value) + /** + * Gets the environment parameters. + * + * Only the parameters starting with "PHPBB__" are considered. + * + * @return array An array of parameters + */ + protected function get_env_parameters() + { + $parameters = array(); + foreach ($_SERVER as $key => $value) { - $this->container->setParameter($key, $value); + if (0 === strpos($key, 'PHPBB__')) + { + $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value; + } } + + return $parameters; } /** diff --git a/phpBB/phpbb/di/extension/container_configuration.php b/phpBB/phpbb/di/extension/container_configuration.php new file mode 100644 index 0000000000..1f1c077472 --- /dev/null +++ b/phpBB/phpbb/di/extension/container_configuration.php @@ -0,0 +1,38 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\di\extension; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +class container_configuration implements ConfigurationInterface +{ + + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('core'); + $rootNode + ->children() + ->booleanNode('require_dev_dependencies')->defaultValue(false)->end() + ->end() + ; + return $treeBuilder; + } +} diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 7787602aba..62fcf46ad5 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -13,10 +13,11 @@ namespace phpbb\di\extension; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; -use Symfony\Component\Config\FileLocator; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** * Container core extension @@ -42,15 +43,41 @@ class core extends Extension /** * Loads a specific configuration. * - * @param array $config An array of configuration values + * @param array $configs An array of configuration values * @param ContainerBuilder $container A ContainerBuilder instance * * @throws \InvalidArgumentException When provided tag is not defined in this extension */ - public function load(array $config, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container) { $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($this->config_path))); - $loader->load(PHPBB_ENVIRONMENT . '/environment.yml'); + $loader->load(PHPBB_ENVIRONMENT . '/container/environment.yml'); + + $config = $this->getConfiguration($configs, $container); + $config = $this->processConfiguration($config, $configs); + + if ($config['require_dev_dependencies']) + { + if (!class_exists('Goutte\Client', true)) + { + trigger_error( + 'Composer development dependencies have not been set up for the ' . $container->getParameter('core.environment') . ' environment yet, run ' . + "'php ../composer.phar install --dev' from the phpBB directory to do so.", + E_USER_ERROR + ); + } + } + } + + /** + * {@inheritdoc} + */ + public function getConfiguration(array $config, ContainerBuilder $container) + { + $r = new \ReflectionClass('\phpbb\di\extension\container_configuration'); + $container->addResource(new FileResource($r->getFileName())); + + return new container_configuration(); } /** diff --git a/phpBB/phpbb/di/extension/ext.php b/phpBB/phpbb/di/extension/ext.php index 330303ca0c..021e862118 100644 --- a/phpBB/phpbb/di/extension/ext.php +++ b/phpBB/phpbb/di/extension/ext.php @@ -48,16 +48,16 @@ class ext extends Extension $services_directory = false; $services_file = false; - if (file_exists($path . 'config/' . PHPBB_ENVIRONMENT . '/environment.yml')) + if (file_exists($path . 'config/' . PHPBB_ENVIRONMENT . '/container/environment.yml')) { - $services_directory = $path . 'config/' . PHPBB_ENVIRONMENT; + $services_directory = $path . 'config/' . PHPBB_ENVIRONMENT . '/container/'; $services_file = 'environment.yml'; } else if (!is_dir($path . 'config/' . PHPBB_ENVIRONMENT)) { - if (file_exists($path . 'config/default/environment.yml')) + if (file_exists($path . 'config/default/container/environment.yml')) { - $services_directory = $path . 'config/default'; + $services_directory = $path . 'config/default/container/'; $services_file = 'environment.yml'; } else if (!is_dir($path . 'config/default') && file_exists($path . '/config/services.yml')) -- cgit v1.2.1 From 3a167aa0c3eaec6c4b9d322460480786234e0419 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 4 Oct 2014 17:30:10 +0200 Subject: [ticket/12620] Creates one di extension per phpBB extension PHPBB3-12620 --- phpBB/phpbb/di/container_builder.php | 12 ++- phpBB/phpbb/di/extension/ext.php | 89 ------------------ phpBB/phpbb/extension/di/extension_base.php | 137 ++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 90 deletions(-) delete mode 100644 phpBB/phpbb/di/extension/ext.php create mode 100644 phpBB/phpbb/extension/di/extension_base.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 45dbaaf303..5ad9336695 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -160,7 +160,17 @@ class container_builder if ($this->use_extensions) { $installed_exts = $this->get_installed_extensions(); - $container_extensions[] = new \phpbb\di\extension\ext($installed_exts); + foreach ($installed_exts as $ext_name => $path) + { + $extension_class = '\\' . str_replace('/', '\\', $ext_name) . '\\di\extension'; + + if (!class_exists($extension_class)) + { + $extension_class = '\phpbb\extension\di\extension_base'; + } + + $container_extensions[] = new $extension_class($ext_name, $path); + } } if ($this->inject_config) diff --git a/phpBB/phpbb/di/extension/ext.php b/phpBB/phpbb/di/extension/ext.php deleted file mode 100644 index 021e862118..0000000000 --- a/phpBB/phpbb/di/extension/ext.php +++ /dev/null @@ -1,89 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\di\extension; - -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\HttpKernel\DependencyInjection\Extension; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; -use Symfony\Component\Config\FileLocator; - -/** -* Container ext extension -*/ -class ext extends Extension -{ - protected $paths = array(); - - public function __construct($enabled_extensions) - { - foreach ($enabled_extensions as $ext => $path) - { - $this->paths[] = $path; - } - } - - /** - * Loads a specific configuration. - * - * @param array $config An array of configuration values - * @param ContainerBuilder $container A ContainerBuilder instance - * - * @throws \InvalidArgumentException When provided tag is not defined in this extension - */ - public function load(array $config, ContainerBuilder $container) - { - foreach ($this->paths as $path) - { - $services_directory = false; - $services_file = false; - - if (file_exists($path . 'config/' . PHPBB_ENVIRONMENT . '/container/environment.yml')) - { - $services_directory = $path . 'config/' . PHPBB_ENVIRONMENT . '/container/'; - $services_file = 'environment.yml'; - } - else if (!is_dir($path . 'config/' . PHPBB_ENVIRONMENT)) - { - if (file_exists($path . 'config/default/container/environment.yml')) - { - $services_directory = $path . 'config/default/container/'; - $services_file = 'environment.yml'; - } - else if (!is_dir($path . 'config/default') && file_exists($path . '/config/services.yml')) - { - $services_directory = $path . 'config'; - $services_file = 'services.yml'; - } - } - - if ($services_directory && $services_file) - { - $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($services_directory))); - $loader->load($services_file); - } - } - } - - /** - * Returns the recommended alias to use in XML. - * - * This alias is also the mandatory prefix to use when using YAML. - * - * @return string The alias - */ - public function getAlias() - { - return 'ext'; - } -} diff --git a/phpBB/phpbb/extension/di/extension_base.php b/phpBB/phpbb/extension/di/extension_base.php new file mode 100644 index 0000000000..74026bd53a --- /dev/null +++ b/phpBB/phpbb/extension/di/extension_base.php @@ -0,0 +1,137 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\extension\di; + +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; + +/** +* Container core extension +*/ +class extension_base extends Extension +{ + /** + * Name of the extension (vendor/name) + * + * @var string + */ + protected $extension_name; + + /** + * Path to the extension. + * + * @var string + */ + protected $ext_path; + + /** + * Constructor + * + * @param string $extension_name Name of the extension (vendor/name) + * @param string $ext_path Path to the extension + */ + public function __construct($extension_name, $ext_path) + { + $this->extension_name = $extension_name; + $this->ext_path = $ext_path; + } + + /** + * Loads a specific configuration. + * + * @param array $configs An array of configuration values + * @param ContainerBuilder $container A ContainerBuilder instance + * + * @throws \InvalidArgumentException When provided tag is not defined in this extension + */ + public function load(array $configs, ContainerBuilder $container) + { + $this->load_services($container); + } + + /** + * Loads the services.yml file. + * + * @param ContainerBuilder $container A ContainerBuilder instance + */ + protected function load_services(ContainerBuilder $container) + { + $services_directory = false; + $services_file = false; + + if (file_exists($this->ext_path . 'config/' . $container->getParameter('core.environment') . '/container/environment.yml')) + { + $services_directory = $this->ext_path . 'config/' . $container->getParameter('core.environment') . '/container/'; + $services_file = 'environment.yml'; + } + else if (!is_dir($this->ext_path . 'config/' . $container->getParameter('core.environment'))) + { + if (file_exists($this->ext_path . 'config/default/container/environment.yml')) + { + $services_directory = $this->ext_path . 'config/default/container/'; + $services_file = 'environment.yml'; + } + else if (!is_dir($this->ext_path . 'config/default') && file_exists($this->ext_path . '/config/services.yml')) + { + $services_directory = $this->ext_path . 'config'; + $services_file = 'services.yml'; + } + } + + if ($services_directory && $services_file) + { + $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($services_directory))); + $loader->load($services_file); + } + } + + /** + * {@inheritdoc} + */ + public function getConfiguration(array $config, ContainerBuilder $container) + { + $reflected = new \ReflectionClass($this); + $namespace = $reflected->getNamespaceName(); + + $class = $namespace . '\\di\configuration'; + if (class_exists($class)) + { + $r = new \ReflectionClass($class); + $container->addResource(new FileResource($r->getFileName())); + + if (!method_exists($class, '__construct')) + { + $configuration = new $class(); + + return $configuration; + } + } + + } + + /** + * Returns the recommended alias to use in XML. + * + * This alias is also the mandatory prefix to use when using YAML. + * + * @return string The alias + */ + public function getAlias() + { + return str_replace('/', '_', $this->extension_name); + } +} -- cgit v1.2.1 From 0b61e3540de353f2bf0a6904a87727e4efe9c5fa Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 4 Oct 2014 17:47:36 +0200 Subject: [ticket/12620] Fix tests PHPBB3-12620 --- phpBB/phpbb/di/container_builder.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 5ad9336695..6216dad978 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -195,6 +195,8 @@ class container_builder $loader = new YamlFileLoader($this->container, new FileLocator(phpbb_realpath($this->get_config_path()))); $loader->load(PHPBB_ENVIRONMENT . '/config.yml'); + $this->inject_custom_parameters(); + if ($this->compile_container) { $this->container->compile(); @@ -430,6 +432,20 @@ class container_builder return $container; } + /** + * Inject the customs parameters into the container + */ + protected function inject_custom_parameters() + { + if ($this->custom_parameters !== null) + { + foreach ($this->custom_parameters as $key => $value) + { + $this->container->setParameter($key, $value); + } + } + } + /** * Returns the core parameters. * -- cgit v1.2.1 From acc91a2bbf28656d4a6917b457ba3dd6b4e02e37 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Tue, 11 Nov 2014 17:59:41 +0100 Subject: [ticket/12620] Use the container to get the environment name PHPBB3-12620 --- phpBB/phpbb/cache/driver/file.php | 5 +++-- phpBB/phpbb/di/container_builder.php | 16 +++++++++++++--- phpBB/phpbb/di/extension/core.php | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index d3708fe9a0..114959c06c 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -27,8 +27,9 @@ class file extends \phpbb\cache\driver\base */ function __construct($cache_dir = null) { - global $phpbb_root_path; - $this->cache_dir = !is_null($cache_dir) ? $cache_dir : $phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT . '/'; + global $phpbb_root_path, $phpbb_container; + + $this->cache_dir = !is_null($cache_dir) ? $cache_dir : $phpbb_root_path . 'cache/' . $phpbb_container->getParameter('core.environment') . '/'; if (!is_dir($this->cache_dir)) { diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 6216dad978..c665c8444c 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -193,7 +193,7 @@ class container_builder } $loader = new YamlFileLoader($this->container, new FileLocator(phpbb_realpath($this->get_config_path()))); - $loader->load(PHPBB_ENVIRONMENT . '/config.yml'); + $loader->load($this->container->getParameter('core.environment') . '/config.yml'); $this->inject_custom_parameters(); @@ -327,7 +327,7 @@ class container_builder */ protected function get_cache_dir() { - return $this->cache_dir ?: $this->phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT . '/'; + return $this->cache_dir ?: $this->phpbb_root_path . 'cache/' . $this->get_environment() . '/'; } /** @@ -457,7 +457,7 @@ class container_builder array( 'core.root_path' => $this->phpbb_root_path, 'core.php_ext' => $this->php_ext, - 'core.environment' => PHPBB_ENVIRONMENT, + 'core.environment' => $this->get_environment(), 'core.debug' => DEBUG, ), $this->get_env_parameters() @@ -495,4 +495,14 @@ class container_builder $filename = str_replace(array('/', '.'), array('slash', 'dot'), $this->phpbb_root_path); return $this->get_cache_dir() . 'container_' . $filename . '.' . $this->php_ext; } + + /** + * Return the name of the current environment. + * + * @return string + */ + protected function get_environment() + { + return PHPBB_ENVIRONMENT; + } } diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 62fcf46ad5..ce0d4a869c 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -51,7 +51,7 @@ class core extends Extension public function load(array $configs, ContainerBuilder $container) { $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($this->config_path))); - $loader->load(PHPBB_ENVIRONMENT . '/container/environment.yml'); + $loader->load($container->getParameter('core.environment') . '/container/environment.yml'); $config = $this->getConfiguration($configs, $container); $config = $this->processConfiguration($config, $configs); -- cgit v1.2.1 From 0a1db77ea85116adf24f9d3f0b92a44f818a107f Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Tue, 11 Nov 2014 19:10:43 +0100 Subject: [ticket/12620] Add a test using a custom DI extension in an extension PHPBB3-12620 --- phpBB/phpbb/di/container_builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index c665c8444c..62bba5baf9 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -162,7 +162,7 @@ class container_builder $installed_exts = $this->get_installed_extensions(); foreach ($installed_exts as $ext_name => $path) { - $extension_class = '\\' . str_replace('/', '\\', $ext_name) . '\\di\extension'; + $extension_class = '\\' . str_replace('/', '\\', $ext_name) . '\\di\\extension'; if (!class_exists($extension_class)) { -- cgit v1.2.1 From 677b5b2cd4937ee6c777728082084c661223dee8 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 20 Nov 2014 22:40:37 +0100 Subject: [ticket/12620] Fix rebase PHPBB3-12620 --- phpBB/phpbb/controller/helper.php | 5 +- phpBB/phpbb/di/container_builder.php | 2 +- phpBB/phpbb/di/extension/core.php | 40 +++---- phpBB/phpbb/extension/di/extension_base.php | 4 +- phpBB/phpbb/routing/router.php | 180 ++++++++++++++++------------ 5 files changed, 128 insertions(+), 103 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index cc327882e0..2bc8e6b9d0 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -41,8 +41,9 @@ class helper protected $config; /** - * @var \phpbb\routing\router phpBB router - */ + * phpBB router + * @var \phpbb\routing\router + */ protected $router; /* @var \phpbb\symfony_request */ diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 62bba5baf9..125ae28e9b 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -19,7 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; -use Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass; +use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; class container_builder diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index ce0d4a869c..72d46fb05b 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -25,29 +25,29 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; class core extends Extension { /** - * Config path - * @var string - */ + * Config path + * @var string + */ protected $config_path; /** - * Constructor - * - * @param string $config_path Config path - */ + * Constructor + * + * @param string $config_path Config path + */ public function __construct($config_path) { $this->config_path = $config_path; } /** - * Loads a specific configuration. - * - * @param array $configs An array of configuration values - * @param ContainerBuilder $container A ContainerBuilder instance - * - * @throws \InvalidArgumentException When provided tag is not defined in this extension - */ + * Loads a specific configuration. + * + * @param array $configs An array of configuration values + * @param ContainerBuilder $container A ContainerBuilder instance + * + * @throws \InvalidArgumentException When provided tag is not defined in this extension + */ public function load(array $configs, ContainerBuilder $container) { $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($this->config_path))); @@ -81,12 +81,12 @@ class core extends Extension } /** - * Returns the recommended alias to use in XML. - * - * This alias is also the mandatory prefix to use when using YAML. - * - * @return string The alias - */ + * Returns the recommended alias to use in XML. + * + * This alias is also the mandatory prefix to use when using YAML. + * + * @return string The alias + */ public function getAlias() { return 'core'; diff --git a/phpBB/phpbb/extension/di/extension_base.php b/phpBB/phpbb/extension/di/extension_base.php index 74026bd53a..30cc37dbb6 100644 --- a/phpBB/phpbb/extension/di/extension_base.php +++ b/phpBB/phpbb/extension/di/extension_base.php @@ -20,8 +20,8 @@ use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** -* Container core extension -*/ + * Container core extension + */ class extension_base extends Extension { /** diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index f721837bba..0617e94c93 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -25,95 +25,119 @@ use Symfony\Component\Config\FileLocator; use phpbb\extension\manager; /** -* Integration of all pieces of the routing system for easier use. -*/ + * Integration of all pieces of the routing system for easier use. + */ class router implements RouterInterface { /** - * @var manager Extension manager - */ + * Extension manager + * + * @var manager + */ protected $extension_manager; /** - * @var string phpBB root path - */ + * phpBB root path + * + * @var string + */ protected $phpbb_root_path; /** - * @var string PHP file extensions - */ + * PHP file extensions + * + * @var string + */ protected $php_ext; /** - * @var array YAML file(s) containing route information - */ + * Name of the current environment + * + * @var string + */ + protected $environment; + + /** + * YAML file(s) containing route information + * + * @var array + */ protected $routing_files; /** - * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|null - */ + * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|null + */ protected $matcher; /** - * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface|null - */ + * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface|null + */ protected $generator; /** - * @var RequestContext - */ + * @var RequestContext + */ protected $context; /** - * @var RouteCollection|null - */ + * @var RouteCollection|null + */ protected $route_collection; /** - * Construct method - * - * @param manager $extension_manager The extension manager - * @param string $phpbb_root_path phpBB root path - * @param string $php_ext PHP file extension - * @param array $routing_files Array of strings containing paths to YAML files holding route information - */ - public function __construct(manager $extension_manager, $phpbb_root_path, $php_ext, $routing_files = array()) + * Construct method + * + * @param manager $extension_manager Extension manager + * @param string $phpbb_root_path phpBB root path + * @param string $php_ext PHP file extension + * @param string $environment Name of the current environment + * @param array $routing_files Array of strings containing paths to YAML files holding route information + */ + public function __construct(manager $extension_manager, $phpbb_root_path, $php_ext, $environment, $routing_files = array()) { $this->extension_manager = $extension_manager; $this->routing_files = $routing_files; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; + $this->environment = $environment; $this->context = new RequestContext(); } /** - * Find the list of routing files - * - * @param \phpbb\finder $finder - * @return router - */ - public function find_routing_files(\phpbb\finder $finder) + * Find the list of routing files + * + * @param array $paths Array of paths where to look for routing files. + * @return null + */ + public function find_routing_files(array $paths) { - if ($this->routing_files === null || empty($this->routing_files)) + $this->routing_files = array($this->phpbb_root_path . 'config/' . $this->environment . '/routing/environment.yml'); + foreach ($paths as $path) { - // We hardcode the path to the core config directory - // because the finder cannot find it - $this->routing_files = array_merge($this->routing_files, array('config/routing.yml'), array_keys($finder - ->directory('/config') - ->suffix('routing.yml') - ->find() - )); + if (file_exists($path . 'config/' . $this->environment . '/routing/environment.yml')) + { + $this->routing_files[] = $path . 'config/' . $this->environment . '/routing/environment.yml'; + } + else if (!is_dir($path . 'config/' . $this->environment)) + { + if (file_exists($path . 'config/default/routing/environment.yml')) + { + $this->routing_files[] = $path . 'config/default/routing/environment.yml'; + } + else if (!is_dir($path . 'config/default/routing') && file_exists($path . 'config/routing.yml')) + { + $this->routing_files[] = $path . 'config/routing.yml'; + } + } } - - return $this; } /** - * Find a list of controllers - * - * @param string $base_path Base path to prepend to file paths - * @return router - */ + * Find a list of controllers + * + * @param string $base_path Base path to prepend to file paths + * @return router + */ public function find($base_path = '') { if ($this->route_collection === null || $this->route_collection->count() === 0) @@ -130,15 +154,15 @@ class router implements RouterInterface } /** - * Get the list of routes - * - * @return RouteCollection Get the route collection - */ + * Get the list of routes + * + * @return RouteCollection Get the route collection + */ public function get_routes() { if ($this->route_collection == null || empty($this->routing_files)) { - $this->find_routing_files($this->extension_manager->get_finder()) + $this->find_routing_files($this->extension_manager->all_enabled()) ->find($this->phpbb_root_path); } @@ -146,16 +170,16 @@ class router implements RouterInterface } /** - * {@inheritdoc} - */ + * {@inheritdoc} + */ public function getRouteCollection() { return $this->get_routes(); } /** - * {@inheritdoc} - */ + * {@inheritdoc} + */ public function setContext(RequestContext $context) { $this->context = $context; @@ -171,34 +195,34 @@ class router implements RouterInterface } /** - * {@inheritdoc} - */ + * {@inheritdoc} + */ public function getContext() { return $this->context; } /** - * {@inheritdoc} - */ + * {@inheritdoc} + */ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) { return $this->get_generator()->generate($name, $parameters, $referenceType); } /** - * {@inheritdoc} - */ + * {@inheritdoc} + */ public function match($pathinfo) { return $this->get_matcher()->match($pathinfo); } /** - * Gets the UrlMatcher instance associated with this Router. - * - * @return \Symfony\Component\Routing\Matcher\UrlMatcherInterface A UrlMatcherInterface instance - */ + * Gets the UrlMatcher instance associated with this Router. + * + * @return \Symfony\Component\Routing\Matcher\UrlMatcherInterface A UrlMatcherInterface instance + */ public function get_matcher() { if ($this->matcher !== null) @@ -218,8 +242,8 @@ class router implements RouterInterface return $this->matcher; } /** - * Creates a new dumped URL Matcher (dump it if necessary) - */ + * Creates a new dumped URL Matcher (dump it if necessary) + */ protected function create_dumped_url_matcher() { if (!file_exists($this->phpbb_root_path . 'cache/url_matcher.' . $this->php_ext)) @@ -240,18 +264,18 @@ class router implements RouterInterface } /** - * Creates a new URL Matcher - */ + * Creates a new URL Matcher + */ protected function create_new_url_matcher() { $this->matcher = new UrlMatcher($this->get_routes(), $this->context); } /** - * Gets the UrlGenerator instance associated with this Router. - * - * @return \Symfony\Component\Routing\Generator\UrlGeneratorInterface A UrlGeneratorInterface instance - */ + * Gets the UrlGenerator instance associated with this Router. + * + * @return \Symfony\Component\Routing\Generator\UrlGeneratorInterface A UrlGeneratorInterface instance + */ public function get_generator() { if ($this->generator !== null) @@ -272,8 +296,8 @@ class router implements RouterInterface } /** - * Creates a new dumped URL Generator (dump it if necessary) - */ + * Creates a new dumped URL Generator (dump it if necessary) + */ protected function create_dumped_url_generator() { if (!file_exists($this->phpbb_root_path . 'cache/url_generator.' . $this->php_ext)) @@ -294,8 +318,8 @@ class router implements RouterInterface } /** - * Creates a new URL Generator - */ + * Creates a new URL Generator + */ protected function create_new_url_generator() { $this->generator = new UrlGenerator($this->get_routes(), $this->context); -- cgit v1.2.1 From f5c5f7df755dd930fef4de6f62e42d4a2a54219e Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 21 Nov 2014 08:26:19 +0100 Subject: [ticket/12620] Fix functionnal tests PHPBB3-12620 --- phpBB/phpbb/routing/router.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 0617e94c93..1003708540 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -107,7 +107,7 @@ class router implements RouterInterface * Find the list of routing files * * @param array $paths Array of paths where to look for routing files. - * @return null + * @return router */ public function find_routing_files(array $paths) { @@ -130,6 +130,8 @@ class router implements RouterInterface } } } + + return $this; } /** -- cgit v1.2.1 From 6850169095f099d8fd9f3886e60237134c77ddb4 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 22 Nov 2014 12:33:45 +0100 Subject: [ticket/13266] Enable the debug extension in the development environment PHPBB3-13266 --- phpBB/phpbb/di/extension/container_configuration.php | 8 +++++++- phpBB/phpbb/di/extension/core.php | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/extension/container_configuration.php b/phpBB/phpbb/di/extension/container_configuration.php index 1f1c077472..ee58ec2b74 100644 --- a/phpBB/phpbb/di/extension/container_configuration.php +++ b/phpBB/phpbb/di/extension/container_configuration.php @@ -30,7 +30,13 @@ class container_configuration implements ConfigurationInterface $rootNode = $treeBuilder->root('core'); $rootNode ->children() - ->booleanNode('require_dev_dependencies')->defaultValue(false)->end() + ->booleanNode('require_dev_dependencies')->defaultValue(false)->end() + ->arrayNode('twig') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('enable_debug_extension')->defaultValue(false)->end() + ->end() + ->end() ->end() ; return $treeBuilder; diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 72d46fb05b..451efc8e35 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -67,6 +67,12 @@ class core extends Extension ); } } + + if ($config['twig']['enable_debug_extension']) + { + $definition = $container->getDefinition('template.twig.extensions.debug'); + $definition->addTag('twig.extension'); + } } /** -- cgit v1.2.1 From fd94027b40184b4c9eae10c6e5c1f8bee2c2a974 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Tue, 25 Nov 2014 12:23:16 +0100 Subject: [ticket/13372] Fix Url Generator/Matcher generation PHPBB3-13372 --- phpBB/phpbb/routing/router.php | 45 ++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 1003708540..c9c50534a2 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -13,6 +13,7 @@ namespace phpbb\routing; +use Symfony\Component\Config\ConfigCache; use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper; use Symfony\Component\Routing\Matcher\UrlMatcher; @@ -232,14 +233,7 @@ class router implements RouterInterface return $this->matcher; } - if (defined('DEBUG')) - { - $this->create_new_url_matcher(); - } - else - { - $this->create_dumped_url_matcher(); - } + $this->create_dumped_url_matcher(); return $this->matcher; } @@ -248,21 +242,22 @@ class router implements RouterInterface */ protected function create_dumped_url_matcher() { - if (!file_exists($this->phpbb_root_path . 'cache/url_matcher.' . $this->php_ext)) + $cache = new ConfigCache("{$this->phpbb_root_path}cache/{$this->environment}/url_matcher.{$this->php_ext}", defined('DEBUG')); + if (!$cache->isFresh()) { $dumper = new PhpMatcherDumper($this->get_routes()); $options = array( - 'class' => 'phpbb_url_matcher', + 'class' => 'phpbb_url_matcher', + 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', ); - $dump = $dumper->dump($options); - file_put_contents($this->phpbb_root_path . 'cache/url_matcher.' . $this->php_ext, $dump); + $cache->write($dumper->dump($options), $this->get_routes()->getResources()); } - require_once($this->phpbb_root_path . 'cache/url_matcher.' . $this->php_ext); + require_once $cache; - $this->matcher = new phpbb_url_matcher($this->context); + $this->matcher = new \phpbb_url_matcher($this->context); } /** @@ -285,14 +280,7 @@ class router implements RouterInterface return $this->generator; } - if (defined('DEBUG')) - { - $this->create_new_url_generator(); - } - else - { - $this->create_dumped_url_generator(); - } + $this->create_dumped_url_generator(); return $this->generator; } @@ -302,21 +290,22 @@ class router implements RouterInterface */ protected function create_dumped_url_generator() { - if (!file_exists($this->phpbb_root_path . 'cache/url_generator.' . $this->php_ext)) + $cache = new ConfigCache("{$this->phpbb_root_path}cache/{$this->environment}/url_generator.{$this->php_ext}", defined('DEBUG')); + if (!$cache->isFresh()) { $dumper = new PhpGeneratorDumper($this->get_routes()); $options = array( - 'class' => 'phpbb_url_generator', + 'class' => 'phpbb_url_generator', + 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', ); - $dump = $dumper->dump($options); - file_put_contents($this->phpbb_root_path . 'cache/url_generator.' . $this->php_ext, $dump); + $cache->write($dumper->dump($options), $this->get_routes()->getResources()); } - require_once($this->phpbb_root_path . 'cache/url_generator.' . $this->php_ext); + require_once $cache; - $this->generator = new phpbb_url_generator($this->context); + $this->generator = new \phpbb_url_generator($this->context); } /** -- cgit v1.2.1 From f4576c969ab3c3619564e8be7b71547049846bd5 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Tue, 25 Nov 2014 12:48:48 +0100 Subject: [ticket/13372] Fix require_once CS PHPBB3-13372 --- phpBB/phpbb/routing/router.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index c9c50534a2..40a829b73f 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -255,7 +255,7 @@ class router implements RouterInterface $cache->write($dumper->dump($options), $this->get_routes()->getResources()); } - require_once $cache; + require_once($cache); $this->matcher = new \phpbb_url_matcher($this->context); } @@ -303,7 +303,7 @@ class router implements RouterInterface $cache->write($dumper->dump($options), $this->get_routes()->getResources()); } - require_once $cache; + require_once($cache); $this->generator = new \phpbb_url_generator($this->context); } -- cgit v1.2.1 From 10594779b9f0e334ea9db982ee9f980a8d8f87b7 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 22 Nov 2014 02:07:08 +0100 Subject: [ticket/13421] Add an interface for \phpbb\db\tools PHPBB3-13421 --- phpBB/phpbb/db/tools.php | 22 ++-- phpBB/phpbb/db/tools_interface.php | 202 +++++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 11 deletions(-) create mode 100644 phpBB/phpbb/db/tools_interface.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index c8d25f23a2..ee2b6e843b 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -17,7 +17,7 @@ namespace phpbb\db; * Database Tools for handling cross-db actions such as altering columns, etc. * Currently not supported is returning SQL for creating tables. */ -class tools +class tools implements tools_interface { /** * Current sql layer @@ -1081,11 +1081,11 @@ class tools /** * Gets a list of columns of a table. * - * @param string $table Table name + * @param string $table_name Table name * * @return array Array of column names (all lower case) */ - function sql_list_columns($table) + function sql_list_columns($table_name) { $columns = array(); @@ -1093,7 +1093,7 @@ class tools { case 'mysql_40': case 'mysql_41': - $sql = "SHOW COLUMNS FROM $table"; + $sql = "SHOW COLUMNS FROM $table_name"; break; // PostgreSQL has a way of doing this in a much simpler way but would @@ -1101,7 +1101,7 @@ class tools case 'postgres': $sql = "SELECT a.attname FROM pg_class c, pg_attribute a - WHERE c.relname = '{$table}' + WHERE c.relname = '{$table_name}' AND a.attnum > 0 AND a.attrelid = c.oid"; break; @@ -1113,13 +1113,13 @@ class tools $sql = "SELECT c.name FROM syscolumns c LEFT JOIN sysobjects o ON c.id = o.id - WHERE o.name = '{$table}'"; + WHERE o.name = '{$table_name}'"; break; case 'oracle': $sql = "SELECT column_name FROM user_tab_columns - WHERE LOWER(table_name) = '" . strtolower($table) . "'"; + WHERE LOWER(table_name) = '" . strtolower($table_name) . "'"; break; case 'sqlite': @@ -1127,7 +1127,7 @@ class tools $sql = "SELECT sql FROM sqlite_master WHERE type = 'table' - AND name = '{$table}'"; + AND name = '{$table_name}'"; $result = $this->db->sql_query($sql); @@ -1175,14 +1175,14 @@ class tools /** * Check whether a specified column exist in a table * - * @param string $table Table to check + * @param string $table_name Table to check * @param string $column_name Column to check * * @return bool True if column exists, false otherwise */ - function sql_column_exists($table, $column_name) + function sql_column_exists($table_name, $column_name) { - $columns = $this->sql_list_columns($table); + $columns = $this->sql_list_columns($table_name); return isset($columns[$column_name]); } diff --git a/phpBB/phpbb/db/tools_interface.php b/phpBB/phpbb/db/tools_interface.php new file mode 100644 index 0000000000..d0ecac779e --- /dev/null +++ b/phpBB/phpbb/db/tools_interface.php @@ -0,0 +1,202 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db; + +/** + * Interface for a Database Tools for handling cross-db actions such as altering columns, etc. + */ +interface tools_interface +{ + /** + * 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 + * drop_columns: Removing/Dropping columns + * add_primary_keys: adding primary keys + * add_unique_index: adding an unique index + * add_index: adding an index (can be column:index_size if you need to provide size) + * + * The values are in this format: + * {TABLE NAME} => array( + * {COLUMN NAME} => array({COLUMN TYPE}, {DEFAULT VALUE}, {OPTIONAL VARIABLES}), + * {KEY/INDEX NAME} => array({COLUMN NAMES}), + * ) + * + * + * @param array $schema_changes + * @return null + */ + public function perform_schema_changes($schema_changes); + + /** + * Gets a list of tables in the database. + * + * @return array Array of table names (all lower case) + */ + public function sql_list_tables(); + + /** + * Check if table exists + * + * @param string $table_name The table name to check for + * @return bool true if table exists, else false + */ + public function sql_table_exists($table_name); + + /** + * Create SQL Table + * + * @param string $table_name The table name to create + * @param array $table_data Array containing table data. + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_create_table($table_name, $table_data); + + /** + * Drop Table + * + * @param string $table_name The table name to drop + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_table_drop($table_name); + + /** + * Gets a list of columns of a table. + * + * @param string $table_name Table name + * @return array Array of column names (all lower case) + */ + public function sql_list_columns($table_name); + + /** + * Check whether a specified column exist in a table + * + * @param string $table_name Table to check + * @param string $column_name Column to check + * @return bool True if column exists, false otherwise + */ + public function sql_column_exists($table_name, $column_name); + + /** + * Add new column + * + * @param string $table_name Table to modify + * @param string $column_name Name of the column to add + * @param array $column_data Column data + * @param bool $inline Whether the query should actually be run, + * or return a string for adding the column + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_column_add($table_name, $column_name, $column_data, $inline = false); + + /** + * Change column type (not name!) + * + * @param string $table_name Table to modify + * @param string $column_name Name of the column to modify + * @param array $column_data Column data + * @param bool $inline Whether the query should actually be run, + * or return a string for modifying the column + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_column_change($table_name, $column_name, $column_data, $inline = false); + + /** + * Drop column + * + * @param string $table_name Table to modify + * @param string $column_name Name of the column to drop + * @param bool $inline Whether the query should actually be run, + * or return a string for deleting the column + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_column_remove($table_name, $column_name, $inline = false); + + /** + * List all of the indices that belong to a table + * + * NOTE: does not list + * - UNIQUE indices + * - PRIMARY keys + * + * @param string $table_name Table to check + * @return array Array with index names + */ + public function sql_list_index($table_name); + + /** + * Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes. + * + * @param string $table_name Table to check the index at + * @param string $index_name The index name to check + * @return bool True if index exists, else false + */ + public function sql_index_exists($table_name, $index_name); + + /** + * Add index + * + * @param string $table_name Table to modify + * @param string $index_name Name of the index to create + * @param string|array $column Either a string with a column name, or an array with columns + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_create_index($table_name, $index_name, $column); + + /** + * Drop Index + * + * @param string $table_name Table to modify + * @param string $index_name Name of the index to delete + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_index_drop($table_name, $index_name); + + /** + * Check if a specified index exists in table. + * + * NOTE: Does not return normal and PRIMARY KEY indexes + * + * @param string $table_name Table to check the index at + * @param string $index_name The index name to check + * @return bool True if index exists, else false + */ + public function sql_unique_index_exists($table_name, $index_name); + + /** + * Add unique index + * + * @param string $table_name Table to modify + * @param string $index_name Name of the unique index to create + * @param string|array $column Either a string with a column name, or an array with columns + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_create_unique_index($table_name, $index_name, $column); + + /** + * Add primary key + * + * @param string $table_name Table to modify + * @param string|array $column Either a string with a column name, or an array with columns + * @param bool $inline Whether the query should actually be run, + * or return a string for creating the key + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_create_primary_key($table_name, $column, $inline = false); +} -- cgit v1.2.1 From 536bdf036b6fc2a715f5dc3eec759fe360c2b1cf Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 22 Nov 2014 02:11:21 +0100 Subject: [ticket/13421] Inherit docs PHPBB3-13421 --- phpBB/phpbb/db/tools.php | 119 ++++++++++++++--------------------------------- 1 file changed, 34 insertions(+), 85 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index ee2b6e843b..e9d2382910 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -371,10 +371,8 @@ class tools implements tools_interface } /** - * Gets a list of tables in the database. - * - * @return array Array of table names (all lower case) - */ + * {@inheritDoc} + */ function sql_list_tables() { switch ($this->db->get_sql_layer()) @@ -431,12 +429,8 @@ class tools implements tools_interface } /** - * Check if table exists - * - * - * @param string $table_name The table name to check for - * @return bool true if table exists, else false - */ + * {@inheritDoc} + */ function sql_table_exists($table_name) { $this->db->sql_return_on_error(true); @@ -453,12 +447,8 @@ class tools implements tools_interface } /** - * Create SQL Table - * - * @param string $table_name The table name to create - * @param array $table_data Array containing table data. - * @return array Statements if $return_statements is true. - */ + * {@inheritDoc} + */ function sql_create_table($table_name, $table_data) { // holds the DDL for a column @@ -679,27 +669,8 @@ class tools implements tools_interface } /** - * 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 - * drop_columns: Removing/Dropping columns - * add_primary_keys: adding primary keys - * add_unique_index: adding an unique index - * add_index: adding an index (can be column:index_size if you need to provide size) - * - * The values are in this format: - * {TABLE NAME} => array( - * {COLUMN NAME} => array({COLUMN TYPE}, {DEFAULT VALUE}, {OPTIONAL VARIABLES}), - * {KEY/INDEX NAME} => array({COLUMN NAMES}), - * ) - * - * For more information have a look at /develop/create_schema_files.php (only available through SVN) - */ + * {@inheritDoc} + */ function perform_schema_changes($schema_changes) { if (empty($schema_changes)) @@ -1079,12 +1050,8 @@ class tools implements tools_interface } /** - * Gets a list of columns of a table. - * - * @param string $table_name Table name - * - * @return array Array of column names (all lower case) - */ + * {@inheritDoc} + */ function sql_list_columns($table_name) { $columns = array(); @@ -1173,13 +1140,8 @@ class tools implements tools_interface } /** - * Check whether a specified column exist in a table - * - * @param string $table_name Table to check - * @param string $column_name Column to check - * - * @return bool True if column exists, false otherwise - */ + * {@inheritDoc} + */ function sql_column_exists($table_name, $column_name) { $columns = $this->sql_list_columns($table_name); @@ -1188,13 +1150,8 @@ class tools implements tools_interface } /** - * Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes. - * - * @param string $table_name Table to check the index at - * @param string $index_name The index name to check - * - * @return bool True if index exists, else false - */ + * {@inheritDoc} + */ function sql_index_exists($table_name, $index_name) { if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') @@ -1285,13 +1242,8 @@ class tools implements tools_interface } /** - * Check if a specified index exists in table. Does not return PRIMARY KEY indexes. - * - * @param string $table_name Table to check the index at - * @param string $index_name The index name to check - * - * @return bool True if index exists, else false - */ + * {@inheritDoc} + */ function sql_unique_index_exists($table_name, $index_name) { if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') @@ -1684,8 +1636,8 @@ class tools implements tools_interface } /** - * Add new column - */ + * {@inheritDoc} + */ function sql_column_add($table_name, $column_name, $column_data, $inline = false) { $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); @@ -1802,8 +1754,8 @@ class tools implements tools_interface } /** - * Drop column - */ + * {@inheritDoc} + */ function sql_column_remove($table_name, $column_name, $inline = false) { $statements = array(); @@ -1931,8 +1883,8 @@ class tools implements tools_interface } /** - * Drop Index - */ + * {@inheritDoc} + */ function sql_index_drop($table_name, $index_name) { $statements = array(); @@ -1961,8 +1913,8 @@ class tools implements tools_interface } /** - * Drop Table - */ + * {@inheritDoc} + */ function sql_table_drop($table_name) { $statements = array(); @@ -2014,8 +1966,8 @@ class tools implements tools_interface } /** - * Add primary key - */ + * {@inheritDoc} + */ function sql_create_primary_key($table_name, $column, $inline = false) { $statements = array(); @@ -2098,8 +2050,8 @@ class tools implements tools_interface } /** - * Add unique index - */ + * {@inheritDoc} + */ function sql_create_unique_index($table_name, $index_name, $column) { $statements = array(); @@ -2135,8 +2087,8 @@ class tools implements tools_interface } /** - * Add index - */ + * {@inheritDoc} + */ function sql_create_index($table_name, $index_name, $column) { $statements = array(); @@ -2188,11 +2140,8 @@ class tools implements tools_interface } /** - * List all of the indices that belong to a table, - * does not count: - * * UNIQUE indices - * * PRIMARY keys - */ + * {@inheritDoc} + */ function sql_list_index($table_name) { $index_array = array(); @@ -2287,8 +2236,8 @@ class tools implements tools_interface } /** - * Change column type (not name!) - */ + * {@inheritDoc} + */ function sql_column_change($table_name, $column_name, $column_data, $inline = false) { $original_column_data = $column_data; -- cgit v1.2.1 From d78bb2865b27aa753b165fdc8aaa73ed82eaeac8 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 22 Nov 2014 02:15:06 +0100 Subject: [ticket/13421] Always require the interface when possible PHPBB3-13421 --- phpBB/phpbb/db/migration/migration.php | 6 +++--- phpBB/phpbb/db/migrator.php | 4 ++-- phpBB/phpbb/search/fulltext_sphinx.php | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/migration.php b/phpBB/phpbb/db/migration/migration.php index 5f120333e1..6cf7685350 100644 --- a/phpBB/phpbb/db/migration/migration.php +++ b/phpBB/phpbb/db/migration/migration.php @@ -28,7 +28,7 @@ abstract class migration /** @var \phpbb\db\driver\driver_interface */ protected $db; - /** @var \phpbb\db\tools */ + /** @var \phpbb\db\tools_interface */ protected $db_tools; /** @var string */ @@ -51,12 +51,12 @@ abstract class migration * * @param \phpbb\config\config $config * @param \phpbb\db\driver\driver_interface $db - * @param \phpbb\db\tools $db_tools + * @param \phpbb\db\tools_interface $db_tools * @param string $phpbb_root_path * @param string $php_ext * @param string $table_prefix */ - public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix) + public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools_interface $db_tools, $phpbb_root_path, $php_ext, $table_prefix) { $this->config = $config; $this->db = $db; diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index d03496eae3..c0d42ab6ac 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -24,7 +24,7 @@ class migrator /** @var \phpbb\db\driver\driver_interface */ protected $db; - /** @var \phpbb\db\tools */ + /** @var \phpbb\db\tools_interface */ protected $db_tools; /** @var \phpbb\db\migration\helper */ @@ -84,7 +84,7 @@ class migrator /** * Constructor of the database migrator */ - public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper) + public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools_interface $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper) { $this->config = $config; $this->db = $db; diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index eb53ca6d40..7be1b487ab 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -85,7 +85,7 @@ class fulltext_sphinx /** * Database Tools object - * @var \phpbb\db\tools + * @var \phpbb\db\tools_interface */ protected $db_tools; -- cgit v1.2.1 From ec90f2b380a598a3dbf7ada0e95878d9d1b85cbe Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 6 Dec 2014 16:34:02 +0100 Subject: [ticket/13421] Move tools to subdirectory PHPBB3-13421 --- phpBB/phpbb/captcha/plugins/qa.php | 4 +- .../db/migration/data/v30x/release_3_0_9_rc1.php | 2 +- phpBB/phpbb/db/migration/migration.php | 6 +- phpBB/phpbb/db/migration/schema_generator.php | 4 +- phpBB/phpbb/db/migrator.php | 4 +- phpBB/phpbb/db/tools.php | 2776 -------------------- phpBB/phpbb/db/tools/tools.php | 2776 ++++++++++++++++++++ phpBB/phpbb/db/tools/tools_interface.php | 202 ++ phpBB/phpbb/db/tools_interface.php | 202 -- phpBB/phpbb/search/fulltext_sphinx.php | 6 +- 10 files changed, 2991 insertions(+), 2991 deletions(-) delete mode 100644 phpBB/phpbb/db/tools.php create mode 100644 phpBB/phpbb/db/tools/tools.php create mode 100644 phpBB/phpbb/db/tools/tools_interface.php delete mode 100644 phpBB/phpbb/db/tools_interface.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/captcha/plugins/qa.php b/phpBB/phpbb/captcha/plugins/qa.php index a7ba994cc3..ca242a96dc 100644 --- a/phpBB/phpbb/captcha/plugins/qa.php +++ b/phpBB/phpbb/captcha/plugins/qa.php @@ -115,7 +115,7 @@ class qa { global $db; - $db_tool = new \phpbb\db\tools($db); + $db_tool = new \phpbb\db\tools\tools($db); return $db_tool->sql_table_exists($this->table_captcha_questions); } @@ -308,7 +308,7 @@ class qa { global $db; - $db_tool = new \phpbb\db\tools($db); + $db_tool = new \phpbb\db\tools\tools($db); $tables = array($this->table_captcha_questions, $this->table_captcha_answers, $this->table_qa_confirm); diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php index 06e46d522f..5f928df47c 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php @@ -34,7 +34,7 @@ class release_3_0_9_rc1 extends \phpbb\db\migration\migration // 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 as - // soon as the db_tools class is capable of properly + // soon as the \phpbb\db\tools\tools class is capable of properly // removing a primary key. // 'attempt_id' => array('UINT', NULL, 'auto_increment'), 'attempt_ip' => array('VCHAR:40', ''), diff --git a/phpBB/phpbb/db/migration/migration.php b/phpBB/phpbb/db/migration/migration.php index 6cf7685350..2304c8e44c 100644 --- a/phpBB/phpbb/db/migration/migration.php +++ b/phpBB/phpbb/db/migration/migration.php @@ -28,7 +28,7 @@ abstract class migration /** @var \phpbb\db\driver\driver_interface */ protected $db; - /** @var \phpbb\db\tools_interface */ + /** @var \phpbb\db\tools\tools_interface */ protected $db_tools; /** @var string */ @@ -51,12 +51,12 @@ abstract class migration * * @param \phpbb\config\config $config * @param \phpbb\db\driver\driver_interface $db - * @param \phpbb\db\tools_interface $db_tools + * @param \phpbb\db\tools\tools_interface $db_tools * @param string $phpbb_root_path * @param string $php_ext * @param string $table_prefix */ - public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools_interface $db_tools, $phpbb_root_path, $php_ext, $table_prefix) + public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools\tools_interface $db_tools, $phpbb_root_path, $php_ext, $table_prefix) { $this->config = $config; $this->db = $db; diff --git a/phpBB/phpbb/db/migration/schema_generator.php b/phpBB/phpbb/db/migration/schema_generator.php index 91d8307d91..7003844bc4 100644 --- a/phpBB/phpbb/db/migration/schema_generator.php +++ b/phpBB/phpbb/db/migration/schema_generator.php @@ -24,7 +24,7 @@ class schema_generator /** @var \phpbb\db\driver\driver_interface */ protected $db; - /** @var \phpbb\db\tools */ + /** @var \phpbb\db\tools\tools_interface */ protected $db_tools; /** @var array */ @@ -48,7 +48,7 @@ class schema_generator /** * Constructor */ - public function __construct(array $class_names, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix) + public function __construct(array $class_names, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools\tools_interface $db_tools, $phpbb_root_path, $php_ext, $table_prefix) { $this->config = $config; $this->db = $db; diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index c0d42ab6ac..bb79c0dd68 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -24,7 +24,7 @@ class migrator /** @var \phpbb\db\driver\driver_interface */ protected $db; - /** @var \phpbb\db\tools_interface */ + /** @var \phpbb\db\tools\tools_interface */ protected $db_tools; /** @var \phpbb\db\migration\helper */ @@ -84,7 +84,7 @@ class migrator /** * Constructor of the database migrator */ - public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools_interface $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper) + public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools\tools_interface $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper) { $this->config = $config; $this->db = $db; diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php deleted file mode 100644 index e9d2382910..0000000000 --- a/phpBB/phpbb/db/tools.php +++ /dev/null @@ -1,2776 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\db; - -/** -* Database Tools for handling cross-db actions such as altering columns, etc. -* Currently not supported is returning SQL for creating tables. -*/ -class tools implements tools_interface -{ - /** - * Current sql layer - */ - var $sql_layer = ''; - - /** - * @var object DB object - */ - var $db = null; - - /** - * The Column types for every database we support - * @var array - */ - var $dbms_type_map = array(); - - /** - * Is the used MS SQL Server a SQL Server 2000? - * @var bool - */ - protected $is_sql_server_2000; - - /** - * Get the column types for every database we support - * - * @return array - */ - public static function get_dbms_type_map() - { - return array( - 'mysql_41' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'mediumint(8) UNSIGNED', - 'UINT:' => 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'smallint(4) UNSIGNED', - 'BOOL' => 'tinyint(1) UNSIGNED', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'text', - 'XSTEXT_UNI'=> 'varchar(100)', - 'STEXT' => 'text', - 'STEXT_UNI' => 'varchar(255)', - 'TEXT' => 'text', - 'TEXT_UNI' => 'text', - 'MTEXT' => 'mediumtext', - 'MTEXT_UNI' => 'mediumtext', - 'TIMESTAMP' => 'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar(255)', - 'VARBINARY' => 'varbinary(255)', - ), - - 'mysql_40' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'mediumint(8) UNSIGNED', - 'UINT:' => 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'smallint(4) UNSIGNED', - 'BOOL' => 'tinyint(1) UNSIGNED', - 'VCHAR' => 'varbinary(255)', - 'VCHAR:' => 'varbinary(%d)', - 'CHAR:' => 'binary(%d)', - 'XSTEXT' => 'blob', - 'XSTEXT_UNI'=> 'blob', - 'STEXT' => 'blob', - 'STEXT_UNI' => 'blob', - 'TEXT' => 'blob', - 'TEXT_UNI' => 'blob', - 'MTEXT' => 'mediumblob', - 'MTEXT_UNI' => 'mediumblob', - 'TIMESTAMP' => 'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'blob', - 'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')), - 'VCHAR_CI' => 'blob', - 'VARBINARY' => 'varbinary(255)', - ), - - 'mssql' => array( - 'INT:' => '[int]', - 'BINT' => '[float]', - 'UINT' => '[int]', - 'UINT:' => '[int]', - 'TINT:' => '[int]', - 'USINT' => '[int]', - 'BOOL' => '[int]', - 'VCHAR' => '[varchar] (255)', - 'VCHAR:' => '[varchar] (%d)', - 'CHAR:' => '[char] (%d)', - 'XSTEXT' => '[varchar] (1000)', - 'STEXT' => '[varchar] (3000)', - 'TEXT' => '[varchar] (8000)', - 'MTEXT' => '[text]', - 'XSTEXT_UNI'=> '[varchar] (100)', - 'STEXT_UNI' => '[varchar] (255)', - 'TEXT_UNI' => '[varchar] (4000)', - 'MTEXT_UNI' => '[text]', - 'TIMESTAMP' => '[int]', - 'DECIMAL' => '[float]', - 'DECIMAL:' => '[float]', - 'PDECIMAL' => '[float]', - 'PDECIMAL:' => '[float]', - 'VCHAR_UNI' => '[varchar] (255)', - 'VCHAR_UNI:'=> '[varchar] (%d)', - 'VCHAR_CI' => '[varchar] (255)', - 'VARBINARY' => '[varchar] (255)', - ), - - 'mssqlnative' => array( - 'INT:' => '[int]', - 'BINT' => '[float]', - 'UINT' => '[int]', - 'UINT:' => '[int]', - 'TINT:' => '[int]', - 'USINT' => '[int]', - 'BOOL' => '[int]', - 'VCHAR' => '[varchar] (255)', - 'VCHAR:' => '[varchar] (%d)', - 'CHAR:' => '[char] (%d)', - 'XSTEXT' => '[varchar] (1000)', - 'STEXT' => '[varchar] (3000)', - 'TEXT' => '[varchar] (8000)', - 'MTEXT' => '[text]', - 'XSTEXT_UNI'=> '[varchar] (100)', - 'STEXT_UNI' => '[varchar] (255)', - 'TEXT_UNI' => '[varchar] (4000)', - 'MTEXT_UNI' => '[text]', - 'TIMESTAMP' => '[int]', - 'DECIMAL' => '[float]', - 'DECIMAL:' => '[float]', - 'PDECIMAL' => '[float]', - 'PDECIMAL:' => '[float]', - 'VCHAR_UNI' => '[varchar] (255)', - 'VCHAR_UNI:'=> '[varchar] (%d)', - 'VCHAR_CI' => '[varchar] (255)', - 'VARBINARY' => '[varchar] (255)', - ), - - 'oracle' => array( - 'INT:' => 'number(%d)', - 'BINT' => 'number(20)', - 'UINT' => 'number(8)', - 'UINT:' => 'number(%d)', - 'TINT:' => 'number(%d)', - 'USINT' => 'number(4)', - 'BOOL' => 'number(1)', - 'VCHAR' => 'varchar2(255)', - 'VCHAR:' => 'varchar2(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'varchar2(1000)', - 'STEXT' => 'varchar2(3000)', - 'TEXT' => 'clob', - 'MTEXT' => 'clob', - 'XSTEXT_UNI'=> 'varchar2(300)', - 'STEXT_UNI' => 'varchar2(765)', - 'TEXT_UNI' => 'clob', - 'MTEXT_UNI' => 'clob', - 'TIMESTAMP' => 'number(11)', - 'DECIMAL' => 'number(5, 2)', - 'DECIMAL:' => 'number(%d, 2)', - 'PDECIMAL' => 'number(6, 3)', - 'PDECIMAL:' => 'number(%d, 3)', - 'VCHAR_UNI' => 'varchar2(765)', - 'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')), - 'VCHAR_CI' => 'varchar2(255)', - 'VARBINARY' => 'raw(255)', - ), - - 'sqlite' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED', - 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED', - 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'text(65535)', - 'STEXT' => 'text(65535)', - 'TEXT' => 'text(65535)', - 'MTEXT' => 'mediumtext(16777215)', - 'XSTEXT_UNI'=> 'text(65535)', - 'STEXT_UNI' => 'text(65535)', - 'TEXT_UNI' => 'text(65535)', - 'MTEXT_UNI' => 'mediumtext(16777215)', - 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar(255)', - 'VARBINARY' => 'blob', - ), - - 'sqlite3' => array( - 'INT:' => 'INT(%d)', - 'BINT' => 'BIGINT(20)', - 'UINT' => 'INTEGER UNSIGNED', - 'UINT:' => 'INTEGER UNSIGNED', - 'TINT:' => 'TINYINT(%d)', - 'USINT' => 'INTEGER UNSIGNED', - 'BOOL' => 'INTEGER UNSIGNED', - 'VCHAR' => 'VARCHAR(255)', - 'VCHAR:' => 'VARCHAR(%d)', - 'CHAR:' => 'CHAR(%d)', - 'XSTEXT' => 'TEXT(65535)', - 'STEXT' => 'TEXT(65535)', - 'TEXT' => 'TEXT(65535)', - 'MTEXT' => 'MEDIUMTEXT(16777215)', - 'XSTEXT_UNI'=> 'TEXT(65535)', - 'STEXT_UNI' => 'TEXT(65535)', - 'TEXT_UNI' => 'TEXT(65535)', - 'MTEXT_UNI' => 'MEDIUMTEXT(16777215)', - 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', - 'DECIMAL' => 'DECIMAL(5,2)', - 'DECIMAL:' => 'DECIMAL(%d,2)', - 'PDECIMAL' => 'DECIMAL(6,3)', - 'PDECIMAL:' => 'DECIMAL(%d,3)', - 'VCHAR_UNI' => 'VARCHAR(255)', - 'VCHAR_UNI:'=> 'VARCHAR(%d)', - 'VCHAR_CI' => 'VARCHAR(255)', - 'VARBINARY' => 'BLOB', - ), - - 'postgres' => array( - 'INT:' => 'INT4', - 'BINT' => 'INT8', - 'UINT' => 'INT4', // unsigned - 'UINT:' => 'INT4', // unsigned - 'USINT' => 'INT2', // unsigned - 'BOOL' => 'INT2', // unsigned - 'TINT:' => 'INT2', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'varchar(1000)', - 'STEXT' => 'varchar(3000)', - 'TEXT' => 'varchar(8000)', - 'MTEXT' => 'TEXT', - 'XSTEXT_UNI'=> 'varchar(100)', - 'STEXT_UNI' => 'varchar(255)', - 'TEXT_UNI' => 'varchar(4000)', - 'MTEXT_UNI' => 'TEXT', - 'TIMESTAMP' => 'INT4', // unsigned - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar_ci', - 'VARBINARY' => 'bytea', - ), - ); - } - - /** - * A list of types being unsigned for better reference in some db's - * @var array - */ - var $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); - - /** - * A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules. - * @var array - */ - var $supported_dbms = array('mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite', 'sqlite3'); - - /** - * This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array). - * This mode has no effect on some methods (inserting of data for example). This is expressed within the methods command. - */ - var $return_statements = false; - - /** - * Constructor. Set DB Object and set {@link $return_statements return_statements}. - * - * @param \phpbb\db\driver\driver_interface $db Database connection - * @param bool $return_statements True if only statements should be returned and no SQL being executed - */ - public function __construct(\phpbb\db\driver\driver_interface $db, $return_statements = false) - { - $this->db = $db; - $this->return_statements = $return_statements; - - $this->dbms_type_map = self::get_dbms_type_map(); - - // Determine mapping database type - switch ($this->db->get_sql_layer()) - { - case 'mysql': - $this->sql_layer = 'mysql_40'; - break; - - case 'mysql4': - if (version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) - { - $this->sql_layer = 'mysql_41'; - } - else - { - $this->sql_layer = 'mysql_40'; - } - break; - - case 'mysqli': - $this->sql_layer = 'mysql_41'; - break; - - case 'mssql': - case 'mssql_odbc': - $this->sql_layer = 'mssql'; - break; - - case 'mssqlnative': - $this->sql_layer = 'mssqlnative'; - break; - - default: - $this->sql_layer = $this->db->get_sql_layer(); - break; - } - } - - /** - * 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) - { - $this->return_statements = $return_statements; - } - - /** - * {@inheritDoc} - */ - function sql_list_tables() - { - switch ($this->db->get_sql_layer()) - { - case 'mysql': - case 'mysql4': - case 'mysqli': - $sql = 'SHOW TABLES'; - break; - - case 'sqlite': - $sql = 'SELECT name - FROM sqlite_master - WHERE type = "table"'; - break; - - case 'sqlite3': - $sql = 'SELECT name - FROM sqlite_master - WHERE type = "table" - AND name <> "sqlite_sequence"'; - break; - - case 'mssql': - case 'mssql_odbc': - case 'mssqlnative': - $sql = "SELECT name - FROM sysobjects - WHERE type='U'"; - break; - - case 'postgres': - $sql = 'SELECT relname - FROM pg_stat_user_tables'; - break; - - case 'oracle': - $sql = 'SELECT table_name - FROM USER_TABLES'; - break; - } - - $result = $this->db->sql_query($sql); - - $tables = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $name = current($row); - $tables[$name] = $name; - } - $this->db->sql_freeresult($result); - - return $tables; - } - - /** - * {@inheritDoc} - */ - function sql_table_exists($table_name) - { - $this->db->sql_return_on_error(true); - $result = $this->db->sql_query_limit('SELECT * FROM ' . $table_name, 1); - $this->db->sql_return_on_error(false); - - if ($result) - { - $this->db->sql_freeresult($result); - return true; - } - - return false; - } - - /** - * {@inheritDoc} - */ - function sql_create_table($table_name, $table_data) - { - // holds the DDL for a column - $columns = $statements = array(); - - if ($this->sql_table_exists($table_name)) - { - return $this->_sql_run_sql($statements); - } - - // Begin transaction - $statements[] = 'begin'; - - // Determine if we have created a PRIMARY KEY in the earliest - $primary_key_gen = false; - - // Determine if the table requires a sequence - $create_sequence = false; - - // Begin table sql statement - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - $table_sql = 'CREATE TABLE [' . $table_name . '] (' . "\n"; - break; - - default: - $table_sql = 'CREATE TABLE ' . $table_name . ' (' . "\n"; - break; - } - - if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') - { - if (!isset($table_data['PRIMARY_KEY'])) - { - $table_data['COLUMNS']['mssqlindex'] = array('UINT', null, 'auto_increment'); - $table_data['PRIMARY_KEY'] = 'mssqlindex'; - } - } - - // Iterate through the columns to create a table - foreach ($table_data['COLUMNS'] as $column_name => $column_data) - { - // here lies an array, filled with information compiled on the column's data - $prepared_column = $this->sql_prepare_column_data($table_name, $column_name, $column_data); - - if (isset($prepared_column['auto_increment']) && $prepared_column['auto_increment'] && strlen($column_name) > 26) // "${column_name}_gen" - { - trigger_error("Index name '${column_name}_gen' on table '$table_name' is too long. The maximum auto increment column length is 26 characters.", E_USER_ERROR); - } - - // here we add the definition of the new column to the list of columns - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - $columns[] = "\t [{$column_name}] " . $prepared_column['column_type_sql_default']; - break; - - default: - $columns[] = "\t {$column_name} " . $prepared_column['column_type_sql']; - break; - } - - // see if we have found a primary key set due to a column definition if we have found it, we can stop looking - if (!$primary_key_gen) - { - $primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set']; - } - - // create sequence DDL based off of the existance of auto incrementing columns - if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment']) - { - $create_sequence = $column_name; - } - } - - // this makes up all the columns in the create table statement - $table_sql .= implode(",\n", $columns); - - // Close the table for two DBMS and add to the statements - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - $table_sql .= "\n);"; - $statements[] = $table_sql; - break; - } - - // we have yet to create a primary key for this table, - // this means that we can add the one we really wanted instead - if (!$primary_key_gen) - { - // 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 ($this->sql_layer) - { - case 'mysql_40': - case 'mysql_41': - case 'postgres': - case 'sqlite': - case 'sqlite3': - $table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; - break; - - case 'mssql': - case 'mssqlnative': - // We need the data here - $old_return_statements = $this->return_statements; - $this->return_statements = true; - - $primary_key_stmts = $this->sql_create_primary_key($table_name, $table_data['PRIMARY_KEY']); - foreach ($primary_key_stmts as $pk_stmt) - { - $statements[] = $pk_stmt; - } - - $this->return_statements = $old_return_statements; - break; - - case 'oracle': - $table_sql .= ",\n\t CONSTRAINT pk_{$table_name} PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; - break; - } - } - } - - // close the table - switch ($this->sql_layer) - { - case 'mysql_41': - // make sure the table is in UTF-8 mode - $table_sql .= "\n) CHARACTER SET `utf8` COLLATE `utf8_bin`;"; - $statements[] = $table_sql; - break; - - case 'mysql_40': - case 'sqlite': - case 'sqlite3': - $table_sql .= "\n);"; - $statements[] = $table_sql; - break; - - case 'postgres': - // do we need to add a sequence for auto incrementing columns? - if ($create_sequence) - { - $statements[] = "CREATE SEQUENCE {$table_name}_seq;"; - } - - $table_sql .= "\n);"; - $statements[] = $table_sql; - break; - - case 'oracle': - $table_sql .= "\n)"; - $statements[] = $table_sql; - - // do we need to add a sequence and a tigger for auto incrementing columns? - if ($create_sequence) - { - // create the actual sequence - $statements[] = "CREATE SEQUENCE {$table_name}_seq"; - - // the trigger is the mechanism by which we increment the counter - $trigger = "CREATE OR REPLACE TRIGGER t_{$table_name}\n"; - $trigger .= "BEFORE INSERT ON {$table_name}\n"; - $trigger .= "FOR EACH ROW WHEN (\n"; - $trigger .= "\tnew.{$create_sequence} IS NULL OR new.{$create_sequence} = 0\n"; - $trigger .= ")\n"; - $trigger .= "BEGIN\n"; - $trigger .= "\tSELECT {$table_name}_seq.nextval\n"; - $trigger .= "\tINTO :new.{$create_sequence}\n"; - $trigger .= "\tFROM dual;\n"; - $trigger .= "END;"; - - $statements[] = $trigger; - } - 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]); - } - - $old_return_statements = $this->return_statements; - $this->return_statements = true; - - $key_stmts = ($key_data[0] == 'UNIQUE') ? $this->sql_create_unique_index($table_name, $key_name, $key_data[1]) : $this->sql_create_index($table_name, $key_name, $key_data[1]); - - foreach ($key_stmts as $key_stmt) - { - $statements[] = $key_stmt; - } - - $this->return_statements = $old_return_statements; - } - } - - // Commit Transaction - $statements[] = 'commit'; - - return $this->_sql_run_sql($statements); - } - - /** - * {@inheritDoc} - */ - function perform_schema_changes($schema_changes) - { - if (empty($schema_changes)) - { - return; - } - - $statements = array(); - $sqlite = false; - - // For SQLite we need to perform the schema changes in a much more different way - if (($this->db->get_sql_layer() == 'sqlite' || $this->db->get_sql_layer() == 'sqlite3') && $this->return_statements) - { - $sqlite_data = array(); - $sqlite = true; - } - - // Drop tables? - if (!empty($schema_changes['drop_tables'])) - { - foreach ($schema_changes['drop_tables'] as $table) - { - // only drop table if it exists - if ($this->sql_table_exists($table)) - { - $result = $this->sql_table_drop($table); - if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - // Add tables? - if (!empty($schema_changes['add_tables'])) - { - foreach ($schema_changes['add_tables'] as $table => $table_data) - { - $result = $this->sql_create_table($table, $table_data); - if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - - // Change columns? - if (!empty($schema_changes['change_columns'])) - { - foreach ($schema_changes['change_columns'] as $table => $columns) - { - foreach ($columns as $column_name => $column_data) - { - // If the column exists we change it, else we add it ;) - if ($column_exists = $this->sql_column_exists($table, $column_name)) - { - $result = $this->sql_column_change($table, $column_name, $column_data, true); - } - else - { - $result = $this->sql_column_add($table, $column_name, $column_data, true); - } - - if ($sqlite) - { - if ($column_exists) - { - $sqlite_data[$table]['change_columns'][] = $result; - } - else - { - $sqlite_data[$table]['add_columns'][] = $result; - } - } - else if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - // Add columns? - if (!empty($schema_changes['add_columns'])) - { - foreach ($schema_changes['add_columns'] as $table => $columns) - { - foreach ($columns as $column_name => $column_data) - { - // Only add the column if it does not exist yet - if ($column_exists = $this->sql_column_exists($table, $column_name)) - { - continue; - // This is commented out here because it can take tremendous time on updates -// $result = $this->sql_column_change($table, $column_name, $column_data, true); - } - else - { - $result = $this->sql_column_add($table, $column_name, $column_data, true); - } - - if ($sqlite) - { - if ($column_exists) - { - continue; -// $sqlite_data[$table]['change_columns'][] = $result; - } - else - { - $sqlite_data[$table]['add_columns'][] = $result; - } - } - else if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - // Remove keys? - if (!empty($schema_changes['drop_keys'])) - { - foreach ($schema_changes['drop_keys'] as $table => $indexes) - { - foreach ($indexes as $index_name) - { - if (!$this->sql_index_exists($table, $index_name)) - { - continue; - } - - $result = $this->sql_index_drop($table, $index_name); - - if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - // Drop columns? - if (!empty($schema_changes['drop_columns'])) - { - foreach ($schema_changes['drop_columns'] as $table => $columns) - { - foreach ($columns as $column) - { - // Only remove the column if it exists... - if ($this->sql_column_exists($table, $column)) - { - $result = $this->sql_column_remove($table, $column, true); - - if ($sqlite) - { - $sqlite_data[$table]['drop_columns'][] = $result; - } - else if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - } - - // Add primary keys? - if (!empty($schema_changes['add_primary_keys'])) - { - foreach ($schema_changes['add_primary_keys'] as $table => $columns) - { - $result = $this->sql_create_primary_key($table, $columns, true); - - if ($sqlite) - { - $sqlite_data[$table]['primary_key'] = $result; - } - else if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - - // Add unique indexes? - if (!empty($schema_changes['add_unique_index'])) - { - foreach ($schema_changes['add_unique_index'] as $table => $index_array) - { - foreach ($index_array as $index_name => $column) - { - if ($this->sql_unique_index_exists($table, $index_name)) - { - continue; - } - - $result = $this->sql_create_unique_index($table, $index_name, $column); - - if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - // Add indexes? - if (!empty($schema_changes['add_index'])) - { - foreach ($schema_changes['add_index'] as $table => $index_array) - { - foreach ($index_array as $index_name => $column) - { - if ($this->sql_index_exists($table, $index_name)) - { - continue; - } - - $result = $this->sql_create_index($table, $index_name, $column); - - if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - if ($sqlite) - { - foreach ($sqlite_data as $table_name => $sql_schema_changes) - { - // Create temporary table with original data - $statements[] = 'begin'; - - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - continue; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - // Get the columns... - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $plain_table_cols = trim($matches[1]); - $new_table_cols = preg_split('/,(?![\s\w]+\))/m', $plain_table_cols); - $column_list = array(); - - foreach ($new_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - $column_list[] = $entities[0]; - } - - // note down the primary key notation because sqlite only supports adding it to the end for the new table - $primary_key = false; - $_new_cols = array(); - - foreach ($new_table_cols as $key => $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - $primary_key = $declaration; - continue; - } - $_new_cols[] = $declaration; - } - - $new_table_cols = $_new_cols; - - // First of all... change columns - if (!empty($sql_schema_changes['change_columns'])) - { - foreach ($sql_schema_changes['change_columns'] as $column_sql) - { - foreach ($new_table_cols as $key => $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if (strpos($column_sql, $entities[0] . ' ') === 0) - { - $new_table_cols[$key] = $column_sql; - } - } - } - } - - if (!empty($sql_schema_changes['add_columns'])) - { - foreach ($sql_schema_changes['add_columns'] as $column_sql) - { - $new_table_cols[] = $column_sql; - } - } - - // Now drop them... - if (!empty($sql_schema_changes['drop_columns'])) - { - foreach ($sql_schema_changes['drop_columns'] as $column_name) - { - // Remove from column list... - $new_column_list = array(); - foreach ($column_list as $key => $value) - { - if ($value === $column_name) - { - continue; - } - - $new_column_list[] = $value; - } - - $column_list = $new_column_list; - - // Remove from table... - $_new_cols = array(); - foreach ($new_table_cols as $key => $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if (strpos($column_name . ' ', $entities[0] . ' ') === 0) - { - continue; - } - $_new_cols[] = $declaration; - } - $new_table_cols = $_new_cols; - } - } - - // Primary key... - if (!empty($sql_schema_changes['primary_key'])) - { - $new_table_cols[] = 'PRIMARY KEY (' . implode(', ', $sql_schema_changes['primary_key']) . ')'; - } - // Add a new one or the old primary key - else if ($primary_key !== false) - { - $new_table_cols[] = $primary_key; - } - - $columns = implode(',', $column_list); - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $new_table_cols) . ');'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - } - } - - if ($this->return_statements) - { - return $statements; - } - } - - /** - * {@inheritDoc} - */ - function sql_list_columns($table_name) - { - $columns = array(); - - switch ($this->sql_layer) - { - case 'mysql_40': - case 'mysql_41': - $sql = "SHOW COLUMNS FROM $table_name"; - break; - - // PostgreSQL has a way of doing this in a much simpler way but would - // not allow us to support all versions of PostgreSQL - case 'postgres': - $sql = "SELECT a.attname - FROM pg_class c, pg_attribute a - WHERE c.relname = '{$table_name}' - AND a.attnum > 0 - AND a.attrelid = c.oid"; - break; - - // same deal with PostgreSQL, we must perform more complex operations than - // we technically could - case 'mssql': - case 'mssqlnative': - $sql = "SELECT c.name - FROM syscolumns c - LEFT JOIN sysobjects o ON c.id = o.id - WHERE o.name = '{$table_name}'"; - break; - - case 'oracle': - $sql = "SELECT column_name - FROM user_tab_columns - WHERE LOWER(table_name) = '" . strtolower($table_name) . "'"; - break; - - case 'sqlite': - case 'sqlite3': - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}'"; - - $result = $this->db->sql_query($sql); - - if (!$result) - { - return false; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $cols = trim($matches[1]); - $col_array = preg_split('/,(?![\s\w]+\))/m', $cols); - - foreach ($col_array as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - - $column = strtolower($entities[0]); - $columns[$column] = $column; - } - - return $columns; - break; - } - - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - $column = strtolower(current($row)); - $columns[$column] = $column; - } - $this->db->sql_freeresult($result); - - return $columns; - } - - /** - * {@inheritDoc} - */ - function sql_column_exists($table_name, $column_name) - { - $columns = $this->sql_list_columns($table_name); - - return isset($columns[$column_name]); - } - - /** - * {@inheritDoc} - */ - function sql_index_exists($table_name, $index_name) - { - if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') - { - $sql = "EXEC sp_statistics '$table_name'"; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - if ($row['TYPE'] == 3) - { - if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) - { - $this->db->sql_freeresult($result); - return true; - } - } - } - $this->db->sql_freeresult($result); - - return false; - } - - switch ($this->sql_layer) - { - case 'postgres': - $sql = "SELECT ic.relname as index_name - FROM pg_class bc, pg_class ic, pg_index i - WHERE (bc.oid = i.indrelid) - AND (ic.oid = i.indexrelid) - AND (bc.relname = '" . $table_name . "') - AND (i.indisunique != 't') - AND (i.indisprimary != 't')"; - $col = 'index_name'; - break; - - case 'mysql_40': - case 'mysql_41': - $sql = 'SHOW KEYS - FROM ' . $table_name; - $col = 'Key_name'; - break; - - case 'oracle': - $sql = "SELECT index_name - FROM user_indexes - WHERE table_name = '" . strtoupper($table_name) . "' - AND generated = 'N' - AND uniqueness = 'NONUNIQUE'"; - $col = 'index_name'; - break; - - case 'sqlite': - case 'sqlite3': - $sql = "PRAGMA index_list('" . $table_name . "');"; - $col = 'name'; - break; - } - - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) - { - continue; - } - - // These DBMS prefix index name with the table name - switch ($this->sql_layer) - { - case 'oracle': - case 'postgres': - case 'sqlite': - case 'sqlite3': - $row[$col] = substr($row[$col], strlen($table_name) + 1); - break; - } - - if (strtolower($row[$col]) == strtolower($index_name)) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - - return false; - } - - /** - * {@inheritDoc} - */ - function sql_unique_index_exists($table_name, $index_name) - { - if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') - { - $sql = "EXEC sp_statistics '$table_name'"; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - // Usually NON_UNIQUE is the column we want to check, but we allow for both - if ($row['TYPE'] == 3) - { - if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) - { - $this->db->sql_freeresult($result); - return true; - } - } - } - $this->db->sql_freeresult($result); - return false; - } - - switch ($this->sql_layer) - { - case 'postgres': - $sql = "SELECT ic.relname as index_name, i.indisunique - FROM pg_class bc, pg_class ic, pg_index i - WHERE (bc.oid = i.indrelid) - AND (ic.oid = i.indexrelid) - AND (bc.relname = '" . $table_name . "') - AND (i.indisprimary != 't')"; - $col = 'index_name'; - break; - - case 'mysql_40': - case 'mysql_41': - $sql = 'SHOW KEYS - FROM ' . $table_name; - $col = 'Key_name'; - break; - - case 'oracle': - $sql = "SELECT index_name, table_owner - FROM user_indexes - WHERE table_name = '" . strtoupper($table_name) . "' - AND generated = 'N' - AND uniqueness = 'UNIQUE'"; - $col = 'index_name'; - break; - - case 'sqlite': - case 'sqlite3': - $sql = "PRAGMA index_list('" . $table_name . "');"; - $col = 'name'; - break; - } - - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && ($row['Non_unique'] || $row[$col] == 'PRIMARY')) - { - continue; - } - - if (($this->sql_layer == 'sqlite' || $this->sql_layer == 'sqlite3') && !$row['unique']) - { - continue; - } - - if ($this->sql_layer == 'postgres' && $row['indisunique'] != 't') - { - continue; - } - - // These DBMS prefix index name with the table name - switch ($this->sql_layer) - { - case 'oracle': - // Two cases here... prefixed with U_[table_owner] and not prefixed with table_name - if (strpos($row[$col], 'U_') === 0) - { - $row[$col] = substr($row[$col], strlen('U_' . $row['table_owner']) + 1); - } - else if (strpos($row[$col], strtoupper($table_name)) === 0) - { - $row[$col] = substr($row[$col], strlen($table_name) + 1); - } - break; - - case 'postgres': - case 'sqlite': - case 'sqlite3': - $row[$col] = substr($row[$col], strlen($table_name) + 1); - break; - } - - if (strtolower($row[$col]) == strtolower($index_name)) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - - return false; - } - - /** - * Private method for performing sql statements (either execute them or return them) - * @access private - */ - function _sql_run_sql($statements) - { - if ($this->return_statements) - { - return $statements; - } - - // We could add error handling here... - foreach ($statements as $sql) - { - if ($sql === 'begin') - { - $this->db->sql_transaction('begin'); - } - else if ($sql === 'commit') - { - $this->db->sql_transaction('commit'); - } - else - { - $this->db->sql_query($sql); - } - } - - return true; - } - - /** - * Function to prepare some column information for better usage - * @access private - */ - function sql_prepare_column_data($table_name, $column_name, $column_data) - { - if (strlen($column_name) > 30) - { - trigger_error("Column name '$column_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); - } - - // Get type - list($column_type, $orig_column_type) = $this->get_column_type($column_data[0]); - - // Adjust default value if db-dependent specified - if (is_array($column_data[1])) - { - $column_data[1] = (isset($column_data[1][$this->sql_layer])) ? $column_data[1][$this->sql_layer] : $column_data[1]['default']; - } - - $sql = ''; - - $return_array = array(); - - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - $sql .= " {$column_type} "; - $sql_default = " {$column_type} "; - - // For adding columns we need the default definition - if (!is_null($column_data[1])) - { - // For hexadecimal values do not use single quotes - if (strpos($column_data[1], '0x') === 0) - { - $return_array['default'] = 'DEFAULT (' . $column_data[1] . ') '; - $sql_default .= $return_array['default']; - } - else - { - $return_array['default'] = 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; - $sql_default .= $return_array['default']; - } - } - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { -// $sql .= 'IDENTITY (1, 1) '; - $sql_default .= 'IDENTITY (1, 1) '; - } - - $return_array['textimage'] = $column_type === '[text]'; - - if (!is_null($column_data[1]) || (isset($column_data[2]) && $column_data[2] == 'auto_increment')) - { - $sql .= 'NOT NULL'; - $sql_default .= 'NOT NULL'; - } - else - { - $sql .= 'NULL'; - $sql_default .= 'NULL'; - } - - $return_array['column_type_sql_default'] = $sql_default; - - break; - - case 'mysql_40': - case 'mysql_41': - $sql .= " {$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]}' "; - } - - if (!is_null($column_data[1]) || (isset($column_data[2]) && $column_data[2] == 'auto_increment')) - { - $sql .= 'NOT NULL'; - } - else - { - $sql .= 'NULL'; - } - - if (isset($column_data[2])) - { - if ($column_data[2] == 'auto_increment') - { - $sql .= ' auto_increment'; - } - else if ($this->sql_layer === 'mysql_41' && $column_data[2] == 'true_sort') - { - $sql .= ' COLLATE utf8_unicode_ci'; - } - } - - break; - - case 'oracle': - $sql .= " {$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 - // Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields) - if (!preg_match('/number/i', $column_type)) - { - $sql .= ($column_data[1] === '' || $column_data[1] === null) ? '' : 'NOT NULL'; - } - - $return_array['auto_increment'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $return_array['auto_increment'] = true; - } - - break; - - case 'postgres': - $return_array['column_type'] = $column_type; - - $sql .= " {$column_type} "; - - $return_array['auto_increment'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $default_val = "nextval('{$table_name}_seq')"; - $return_array['auto_increment'] = true; - } - else if (!is_null($column_data[1])) - { - $default_val = "'" . $column_data[1] . "'"; - $return_array['null'] = 'NOT NULL'; - $sql .= 'NOT NULL '; - } - else - { - $default_val = "'" . $column_data[1] . "'"; - $return_array['null'] = 'NULL'; - $sql .= 'NULL '; - } - - $return_array['default'] = $default_val; - - $sql .= "DEFAULT {$default_val}"; - - // Unsigned? Then add a CHECK contraint - if (in_array($orig_column_type, $this->unsigned_types)) - { - $return_array['constraint'] = "CHECK ({$column_name} >= 0)"; - $sql .= " CHECK ({$column_name} >= 0)"; - } - - break; - - case 'sqlite': - case 'sqlite3': - $return_array['primary_key_set'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $sql .= ' INTEGER PRIMARY KEY'; - $return_array['primary_key_set'] = true; - - if ($this->sql_layer === 'sqlite3') - { - $sql .= ' AUTOINCREMENT'; - } - } - else - { - $sql .= ' ' . $column_type; - } - - if (!is_null($column_data[1])) - { - $sql .= ' NOT NULL '; - $sql .= "DEFAULT '{$column_data[1]}'"; - } - - break; - } - - $return_array['column_type_sql'] = $sql; - - return $return_array; - } - - /** - * Get the column's database type from the type map - * - * @param string $column_map_type - * @return array column type for this database - * and map type without length - */ - function get_column_type($column_map_type) - { - if (strpos($column_map_type, ':') !== false) - { - list($orig_column_type, $column_length) = explode(':', $column_map_type); - if (!is_array($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'])) - { - $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'], $column_length); - } - else - { - if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'])) - { - switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][0]) - { - case 'div': - $column_length /= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][1]; - $column_length = ceil($column_length); - $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); - break; - } - } - - if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'])) - { - switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][0]) - { - case 'mult': - $column_length *= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][1]; - if ($column_length > $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][2]) - { - $column_type = $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][3]; - } - else - { - $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); - } - break; - } - } - } - $orig_column_type .= ':'; - } - else - { - $orig_column_type = $column_map_type; - $column_type = $this->dbms_type_map[$this->sql_layer][$column_map_type]; - } - - return array($column_type, $orig_column_type); - } - - /** - * {@inheritDoc} - */ - function sql_column_add($table_name, $column_name, $column_data, $inline = false) - { - $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); - $statements = array(); - - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - // Does not support AFTER, only through temporary table - $statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default']; - break; - - case 'mysql_40': - case 'mysql_41': - $after = (!empty($column_data['after'])) ? ' AFTER ' . $column_data['after'] : ''; - $statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql'] . $after; - break; - - case 'oracle': - // Does not support AFTER, only through temporary table - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; - break; - - case 'postgres': - // Does not support AFTER, only through temporary table - if (version_compare($this->db->sql_server_info(true), '8.0', '>=')) - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; - } - else - { - // old versions cannot add columns with default and null information - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type'] . ' ' . $column_data['constraint']; - - if (isset($column_data['null'])) - { - if ($column_data['null'] == 'NOT NULL') - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET NOT NULL'; - } - } - - if (isset($column_data['default'])) - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; - } - } - - break; - - case 'sqlite': - if ($inline && $this->return_statements) - { - return $column_name . ' ' . $column_data['column_type_sql']; - } - - $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name); - if (empty($recreate_queries)) - { - break; - } - - $statements[] = 'begin'; - - $sql_create_table = array_shift($recreate_queries); - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $sql_create_table, $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - $column_list[] = $entities[0]; - } - - $columns = implode(',', $column_list); - - $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols; - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; - $statements = array_merge($statements, $recreate_queries); - - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - break; - - case 'sqlite3': - if ($inline && $this->return_statements) - { - return $column_name . ' ' . $column_data['column_type_sql']; - } - - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * {@inheritDoc} - */ - function sql_column_remove($table_name, $column_name, $inline = false) - { - $statements = array(); - - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - // We need the data here - $old_return_statements = $this->return_statements; - $this->return_statements = true; - - $indexes = $this->get_existing_indexes($table_name, $column_name); - $indexes = array_merge($indexes, $this->get_existing_indexes($table_name, $column_name, true)); - - // Drop any indexes - $recreate_indexes = array(); - if (!empty($indexes)) - { - foreach ($indexes as $index_name => $index_data) - { - $result = $this->sql_index_drop($table_name, $index_name); - $statements = array_merge($statements, $result); - if (sizeof($index_data) > 1) - { - // Remove this column from the index and recreate it - $recreate_indexes[$index_name] = array_diff($index_data, array($column_name)); - } - } - } - - // Drop default value constraint - $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); - $statements = array_merge($statements, $result); - - // Remove the column - $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']'; - - if (!empty($recreate_indexes)) - { - // Recreate indexes after we removed the column - foreach ($recreate_indexes as $index_name => $index_data) - { - $result = $this->sql_create_index($table_name, $index_name, $index_data); - $statements = array_merge($statements, $result); - } - } - - $this->return_statements = $old_return_statements; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`'; - break; - - case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name; - break; - - case 'postgres': - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"'; - break; - - case 'sqlite': - case 'sqlite3': - - if ($inline && $this->return_statements) - { - return $column_name; - } - - $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name, $column_name); - if (empty($recreate_queries)) - { - break; - } - - $statements[] = 'begin'; - - $sql_create_table = array_shift($recreate_queries); - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $sql_create_table, $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name) - { - continue; - } - $column_list[] = $entities[0]; - } - - $columns = implode(',', $column_list); - - $new_table_cols = trim(preg_replace('/' . $column_name . '\b[^,]+(?:,|$)/m', '', $new_table_cols)); - if (substr($new_table_cols, -1) === ',') - { - // Remove the comma from the last entry again - $new_table_cols = substr($new_table_cols, 0, -1); - } - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; - $statements = array_merge($statements, $recreate_queries); - - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * {@inheritDoc} - */ - function sql_index_drop($table_name, $index_name) - { - $statements = array(); - - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - $statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name; - break; - - case 'oracle': - case 'postgres': - case 'sqlite': - case 'sqlite3': - $statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * {@inheritDoc} - */ - function sql_table_drop($table_name) - { - $statements = array(); - - if (!$this->sql_table_exists($table_name)) - { - return $this->_sql_run_sql($statements); - } - - // the most basic operation, get rid of the table - $statements[] = 'DROP TABLE ' . $table_name; - - switch ($this->sql_layer) - { - case 'oracle': - $sql = 'SELECT A.REFERENCED_NAME - FROM USER_DEPENDENCIES A, USER_TRIGGERS B - WHERE A.REFERENCED_TYPE = \'SEQUENCE\' - AND A.NAME = B.TRIGGER_NAME - AND B.TABLE_NAME = \'' . strtoupper($table_name) . "'"; - $result = $this->db->sql_query($sql); - - // any sequences ref'd to this table's triggers? - while ($row = $this->db->sql_fetchrow($result)) - { - $statements[] = "DROP SEQUENCE {$row['referenced_name']}"; - } - $this->db->sql_freeresult($result); - break; - - case 'postgres': - // PGSQL does not "tightly" bind sequences and tables, we must guess... - $sql = "SELECT relname - FROM pg_class - WHERE relkind = 'S' - AND relname = '{$table_name}_seq'"; - $result = $this->db->sql_query($sql); - - // We don't even care about storing the results. We already know the answer if we get rows back. - if ($this->db->sql_fetchrow($result)) - { - $statements[] = "DROP SEQUENCE {$table_name}_seq;\n"; - } - $this->db->sql_freeresult($result); - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * {@inheritDoc} - */ - function sql_create_primary_key($table_name, $column, $inline = false) - { - $statements = array(); - - switch ($this->sql_layer) - { - case 'postgres': - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; - break; - - case 'mssql': - case 'mssqlnative': - $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD "; - $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED ("; - $sql .= '[' . implode("],\n\t\t[", $column) . ']'; - $sql .= ')'; - - $statements[] = $sql; - break; - - case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . ' add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; - break; - - case 'sqlite': - case 'sqlite3': - - if ($inline && $this->return_statements) - { - return $column; - } - - $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name); - if (empty($recreate_queries)) - { - break; - } - - $statements[] = 'begin'; - - $sql_create_table = array_shift($recreate_queries); - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $sql_create_table, $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - $column_list[] = $entities[0]; - } - - $columns = implode(',', $column_list); - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));'; - $statements = array_merge($statements, $recreate_queries); - - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * {@inheritDoc} - */ - function sql_create_unique_index($table_name, $index_name, $column) - { - $statements = array(); - - $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) - if (strlen($table_name . '_' . $index_name) - strlen($table_prefix) > 24) - { - $max_length = strlen($table_prefix) + 24; - trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); - } - - switch ($this->sql_layer) - { - case 'postgres': - case 'oracle': - case 'sqlite': - case 'sqlite3': - $statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mssql': - case 'mssqlnative': - $statements[] = 'CREATE UNIQUE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * {@inheritDoc} - */ - function sql_create_index($table_name, $index_name, $column) - { - $statements = array(); - - $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) - if (strlen($table_name . $index_name) - strlen($table_prefix) > 24) - { - $max_length = strlen($table_prefix) + 24; - trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); - } - - // remove index length unless MySQL4 - if ('mysql_40' != $this->sql_layer) - { - $column = preg_replace('#:.*$#', '', $column); - } - - switch ($this->sql_layer) - { - case 'postgres': - case 'oracle': - case 'sqlite': - case 'sqlite3': - $statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mysql_40': - // add index size to definition as required by MySQL4 - foreach ($column as $i => $col) - { - if (false !== strpos($col, ':')) - { - list($col, $index_size) = explode(':', $col); - $column[$i] = "$col($index_size)"; - } - } - // no break - case 'mysql_41': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mssql': - case 'mssqlnative': - $statements[] = 'CREATE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * {@inheritDoc} - */ - function sql_list_index($table_name) - { - $index_array = array(); - - if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') - { - $sql = "EXEC sp_statistics '$table_name'"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if ($row['TYPE'] == 3) - { - $index_array[] = $row['INDEX_NAME']; - } - } - $this->db->sql_freeresult($result); - } - else - { - switch ($this->sql_layer) - { - case 'postgres': - $sql = "SELECT ic.relname as index_name - FROM pg_class bc, pg_class ic, pg_index i - WHERE (bc.oid = i.indrelid) - AND (ic.oid = i.indexrelid) - AND (bc.relname = '" . $table_name . "') - AND (i.indisunique != 't') - AND (i.indisprimary != 't')"; - $col = 'index_name'; - break; - - case 'mysql_40': - case 'mysql_41': - $sql = 'SHOW KEYS - FROM ' . $table_name; - $col = 'Key_name'; - break; - - case 'oracle': - $sql = "SELECT index_name - FROM user_indexes - WHERE table_name = '" . strtoupper($table_name) . "' - AND generated = 'N' - AND uniqueness = 'NONUNIQUE'"; - $col = 'index_name'; - break; - - case 'sqlite': - case 'sqlite3': - $sql = "PRAGMA index_info('" . $table_name . "');"; - $col = 'name'; - break; - } - - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) - { - continue; - } - - switch ($this->sql_layer) - { - case 'oracle': - case 'postgres': - case 'sqlite': - case 'sqlite3': - $row[$col] = substr($row[$col], strlen($table_name) + 1); - break; - } - - $index_array[] = $row[$col]; - } - $this->db->sql_freeresult($result); - } - - return array_map('strtolower', $index_array); - } - - /** - * Removes table_name from the index_name if it is at the beginning - * - * @param $table_name - * @param $index_name - * @return string - */ - protected function strip_table_name_from_index_name($table_name, $index_name) - { - return (strpos(strtoupper($index_name), strtoupper($table_name)) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name; - } - - /** - * {@inheritDoc} - */ - function sql_column_change($table_name, $column_name, $column_data, $inline = false) - { - $original_column_data = $column_data; - $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); - $statements = array(); - - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - // We need the data here - $old_return_statements = $this->return_statements; - $this->return_statements = true; - - $indexes = $this->get_existing_indexes($table_name, $column_name); - $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); - - // Drop any indexes - if (!empty($indexes) || !empty($unique_indexes)) - { - $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); - foreach ($drop_indexes as $index_name) - { - $result = $this->sql_index_drop($table_name, $index_name); - $statements = array_merge($statements, $result); - } - } - - // Drop default value constraint - $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); - $statements = array_merge($statements, $result); - - // Change the column - $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; - - if (!empty($column_data['default'])) - { - // Add new default value constraint - $statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $this->db->sql_escape($column_data['default']) . ' FOR [' . $column_name . ']'; - } - - if (!empty($indexes)) - { - // Recreate indexes after we changed the column - foreach ($indexes as $index_name => $index_data) - { - $result = $this->sql_create_index($table_name, $index_name, $index_data); - $statements = array_merge($statements, $result); - } - } - - if (!empty($unique_indexes)) - { - // Recreate unique indexes after we changed the column - foreach ($unique_indexes as $index_name => $index_data) - { - $result = $this->sql_create_unique_index($table_name, $index_name, $index_data); - $statements = array_merge($statements, $result); - } - } - - $this->return_statements = $old_return_statements; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql']; - break; - - case 'oracle': - // We need the data here - $old_return_statements = $this->return_statements; - $this->return_statements = true; - - // Get list of existing indexes - $indexes = $this->get_existing_indexes($table_name, $column_name); - $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); - - // Drop any indexes - if (!empty($indexes) || !empty($unique_indexes)) - { - $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); - foreach ($drop_indexes as $index_name) - { - $result = $this->sql_index_drop($table_name, $this->strip_table_name_from_index_name($table_name, $index_name)); - $statements = array_merge($statements, $result); - } - } - - $temp_column_name = 'temp_' . substr(md5($column_name), 0, 25); - // Add a temporary table with the new type - $result = $this->sql_column_add($table_name, $temp_column_name, $original_column_data); - $statements = array_merge($statements, $result); - - // Copy the data to the new column - $statements[] = 'UPDATE ' . $table_name . ' SET ' . $temp_column_name . ' = ' . $column_name; - - // Drop the original column - $result = $this->sql_column_remove($table_name, $column_name); - $statements = array_merge($statements, $result); - - // Recreate the original column with the new type - $result = $this->sql_column_add($table_name, $column_name, $original_column_data); - $statements = array_merge($statements, $result); - - if (!empty($indexes)) - { - // Recreate indexes after we changed the column - foreach ($indexes as $index_name => $index_data) - { - $result = $this->sql_create_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data); - $statements = array_merge($statements, $result); - } - } - - if (!empty($unique_indexes)) - { - // Recreate unique indexes after we changed the column - foreach ($unique_indexes as $index_name => $index_data) - { - $result = $this->sql_create_unique_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data); - $statements = array_merge($statements, $result); - } - } - - // Copy the data to the original column - $statements[] = 'UPDATE ' . $table_name . ' SET ' . $column_name . ' = ' . $temp_column_name; - - // Drop the temporary column again - $result = $this->sql_column_remove($table_name, $temp_column_name); - $statements = array_merge($statements, $result); - - $this->return_statements = $old_return_statements; - break; - - case 'postgres': - $sql = 'ALTER TABLE ' . $table_name . ' '; - - $sql_array = array(); - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type']; - - if (isset($column_data['null'])) - { - if ($column_data['null'] == 'NOT NULL') - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL'; - } - else if ($column_data['null'] == 'NULL') - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL'; - } - } - - if (isset($column_data['default'])) - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; - } - - // we don't want to double up on constraints if we change different number data types - if (isset($column_data['constraint'])) - { - $constraint_sql = "SELECT consrc as constraint_data - FROM pg_constraint, pg_class bc - WHERE conrelid = bc.oid - AND bc.relname = '{$table_name}' - AND NOT EXISTS ( - SELECT * - FROM pg_constraint as c, pg_inherits as i - WHERE i.inhrelid = pg_constraint.conrelid - AND c.conname = pg_constraint.conname - AND c.consrc = pg_constraint.consrc - AND c.conrelid = i.inhparent - )"; - - $constraint_exists = false; - - $result = $this->db->sql_query($constraint_sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if (trim($row['constraint_data']) == trim($column_data['constraint'])) - { - $constraint_exists = true; - break; - } - } - $this->db->sql_freeresult($result); - - if (!$constraint_exists) - { - $sql_array[] = 'ADD ' . $column_data['constraint']; - } - } - - $sql .= implode(', ', $sql_array); - - $statements[] = $sql; - break; - - case 'sqlite': - case 'sqlite3': - - if ($inline && $this->return_statements) - { - return $column_name . ' ' . $column_data['column_type_sql']; - } - - $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name); - if (empty($recreate_queries)) - { - break; - } - - $statements[] = 'begin'; - - $sql_create_table = array_shift($recreate_queries); - - // Create a temp table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $sql_create_table, $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $key => $declaration) - { - $declaration = trim($declaration); - - // Check for the beginning of the constraint section and stop - if (preg_match('/[^\(]*\s*PRIMARY KEY\s+\(/', $declaration) || - preg_match('/[^\(]*\s*UNIQUE\s+\(/', $declaration) || - preg_match('/[^\(]*\s*FOREIGN KEY\s+\(/', $declaration) || - preg_match('/[^\(]*\s*CHECK\s+\(/', $declaration)) - { - break; - } - - $entities = preg_split('#\s+#', $declaration); - $column_list[] = $entities[0]; - if ($entities[0] == $column_name) - { - $old_table_cols[$key] = $column_name . ' ' . $column_data['column_type_sql']; - } - } - - $columns = implode(',', $column_list); - - // Create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');'; - $statements = array_merge($statements, $recreate_queries); - - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * Get queries to drop the default constraints of a column - * - * We need to drop the default constraints of a column, - * before being able to change their type or deleting them. - * - * @param string $table_name - * @param string $column_name - * @return array Array with SQL statements - */ - protected function mssql_get_drop_default_constraints_queries($table_name, $column_name) - { - $statements = array(); - if ($this->mssql_is_sql_server_2000()) - { - // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx - // Deprecated in SQL Server 2005 - $sql = "SELECT so.name AS def_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}')"; - } - else - { - $sql = "SELECT dobj.name AS def_name - FROM sys.columns col - LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D') - WHERE col.object_id = object_id('{$table_name}') - AND col.name = '{$column_name}' - AND dobj.name IS NOT NULL"; - } - - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']'; - } - $this->db->sql_freeresult($result); - - return $statements; - } - - /** - * Get a list with existing indexes for the column - * - * @param string $table_name - * @param string $column_name - * @param bool $unique Should we get unique indexes or normal ones - * @return array Array with Index name => columns - */ - public function get_existing_indexes($table_name, $column_name, $unique = false) - { - switch ($this->sql_layer) - { - case 'mysql_40': - case 'mysql_41': - case 'postgres': - case 'sqlite': - case 'sqlite3': - // Not supported - throw new \Exception('DBMS is not supported'); - break; - } - - $sql = ''; - $existing_indexes = array(); - - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - if ($this->mssql_is_sql_server_2000()) - { - // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx - // Deprecated in SQL Server 2005 - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name - FROM sysindexes ix - INNER JOIN sysindexkeys ixc - ON ixc.id = ix.id - AND ixc.indid = ix.indid - INNER JOIN syscolumns cols - ON cols.colid = ixc.colid - AND cols.id = ix.id - WHERE ix.id = object_id('{$table_name}') - AND cols.name = '{$column_name}' - AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique ? '1' : '0'); - } - else - { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name - FROM sys.indexes ix - INNER JOIN sys.index_columns ixc - ON ixc.object_id = ix.object_id - AND ixc.index_id = ix.index_id - INNER JOIN sys.columns cols - ON cols.column_id = ixc.column_id - AND cols.object_id = ix.object_id - WHERE ix.object_id = object_id('{$table_name}') - AND cols.name = '{$column_name}' - AND ix.is_unique = " . ($unique ? '1' : '0'); - } - break; - - case 'oracle': - $sql = "SELECT ix.index_name AS phpbb_index_name, ix.uniqueness AS is_unique - FROM all_ind_columns ixc, all_indexes ix - WHERE ix.index_name = ixc.index_name - AND ixc.table_name = '" . strtoupper($table_name) . "' - AND ixc.column_name = '" . strtoupper($column_name) . "'"; - break; - } - - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if (!isset($row['is_unique']) || ($unique && $row['is_unique'] == 'UNIQUE') || (!$unique && $row['is_unique'] == 'NONUNIQUE')) - { - $existing_indexes[$row['phpbb_index_name']] = array(); - } - } - $this->db->sql_freeresult($result); - - if (empty($existing_indexes)) - { - return array(); - } - - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - if ($this->mssql_is_sql_server_2000()) - { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name - FROM sysindexes ix - INNER JOIN sysindexkeys ixc - ON ixc.id = ix.id - AND ixc.indid = ix.indid - INNER JOIN syscolumns cols - ON cols.colid = ixc.colid - AND cols.id = ix.id - WHERE ix.id = object_id('{$table_name}') - AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); - } - else - { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name - FROM sys.indexes ix - INNER JOIN sys.index_columns ixc - ON ixc.object_id = ix.object_id - AND ixc.index_id = ix.index_id - INNER JOIN sys.columns cols - ON cols.column_id = ixc.column_id - AND cols.object_id = ix.object_id - WHERE ix.object_id = object_id('{$table_name}') - AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); - } - break; - - case 'oracle': - $sql = "SELECT index_name AS phpbb_index_name, column_name AS phpbb_column_name - FROM all_ind_columns - WHERE table_name = '" . strtoupper($table_name) . "' - AND " . $this->db->sql_in_set('index_name', array_keys($existing_indexes)); - break; - } - - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; - } - $this->db->sql_freeresult($result); - - return $existing_indexes; - } - - /** - * Is the used MS SQL Server a SQL Server 2000? - * - * @return bool - */ - protected function mssql_is_sql_server_2000() - { - if ($this->is_sql_server_2000 === null) - { - $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version"; - $result = $this->db->sql_query($sql); - $properties = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - $this->is_sql_server_2000 = $properties['mssql_version'][0] == '8'; - } - - return $this->is_sql_server_2000; - } - - /** - * Returns the Queries which are required to recreate a table including indexes - * - * @param string $table_name - * @param string $remove_column When we drop a column, we remove the column - * from all indexes. If the index has no other - * column, we drop it completly. - * @return array - */ - protected function sqlite_get_recreate_table_queries($table_name, $remove_column = '') - { - $queries = array(); - - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}'"; - $result = $this->db->sql_query($sql); - $sql_create_table = $this->db->sql_fetchfield('sql'); - $this->db->sql_freeresult($result); - - if (!$sql_create_table) - { - return array(); - } - $queries[] = $sql_create_table; - - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'index' - AND tbl_name = '{$table_name}'"; - $result = $this->db->sql_query($sql); - while ($sql_create_index = $this->db->sql_fetchfield('sql')) - { - if ($remove_column) - { - $match = array(); - preg_match('#(?:[\w ]+)\((.*)\)#', $sql_create_index, $match); - if (!isset($match[1])) - { - continue; - } - - // Find and remove $remove_column from the index - $columns = explode(', ', $match[1]); - $found_column = array_search($remove_column, $columns); - if ($found_column !== false) - { - unset($columns[$found_column]); - - // If the column list is not empty add the index to the list - if (!empty($columns)) - { - $queries[] = str_replace($match[1], implode(', ', $columns), $sql_create_index); - } - } - else - { - $queries[] = $sql_create_index; - } - } - else - { - $queries[] = $sql_create_index; - } - } - $this->db->sql_freeresult($result); - - return $queries; - } -} diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php new file mode 100644 index 0000000000..63c43c07ef --- /dev/null +++ b/phpBB/phpbb/db/tools/tools.php @@ -0,0 +1,2776 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\tools; + +/** +* Database Tools for handling cross-db actions such as altering columns, etc. +* Currently not supported is returning SQL for creating tables. +*/ +class tools implements tools_interface +{ + /** + * Current sql layer + */ + var $sql_layer = ''; + + /** + * @var object DB object + */ + var $db = null; + + /** + * The Column types for every database we support + * @var array + */ + var $dbms_type_map = array(); + + /** + * Is the used MS SQL Server a SQL Server 2000? + * @var bool + */ + protected $is_sql_server_2000; + + /** + * Get the column types for every database we support + * + * @return array + */ + public static function get_dbms_type_map() + { + return array( + 'mysql_41' => array( + 'INT:' => 'int(%d)', + 'BINT' => 'bigint(20)', + 'UINT' => 'mediumint(8) UNSIGNED', + 'UINT:' => 'int(%d) UNSIGNED', + 'TINT:' => 'tinyint(%d)', + 'USINT' => 'smallint(4) UNSIGNED', + 'BOOL' => 'tinyint(1) UNSIGNED', + 'VCHAR' => 'varchar(255)', + 'VCHAR:' => 'varchar(%d)', + 'CHAR:' => 'char(%d)', + 'XSTEXT' => 'text', + 'XSTEXT_UNI'=> 'varchar(100)', + 'STEXT' => 'text', + 'STEXT_UNI' => 'varchar(255)', + 'TEXT' => 'text', + 'TEXT_UNI' => 'text', + 'MTEXT' => 'mediumtext', + 'MTEXT_UNI' => 'mediumtext', + 'TIMESTAMP' => 'int(11) UNSIGNED', + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'varchar(255)', + 'VCHAR_UNI:'=> 'varchar(%d)', + 'VCHAR_CI' => 'varchar(255)', + 'VARBINARY' => 'varbinary(255)', + ), + + 'mysql_40' => array( + 'INT:' => 'int(%d)', + 'BINT' => 'bigint(20)', + 'UINT' => 'mediumint(8) UNSIGNED', + 'UINT:' => 'int(%d) UNSIGNED', + 'TINT:' => 'tinyint(%d)', + 'USINT' => 'smallint(4) UNSIGNED', + 'BOOL' => 'tinyint(1) UNSIGNED', + 'VCHAR' => 'varbinary(255)', + 'VCHAR:' => 'varbinary(%d)', + 'CHAR:' => 'binary(%d)', + 'XSTEXT' => 'blob', + 'XSTEXT_UNI'=> 'blob', + 'STEXT' => 'blob', + 'STEXT_UNI' => 'blob', + 'TEXT' => 'blob', + 'TEXT_UNI' => 'blob', + 'MTEXT' => 'mediumblob', + 'MTEXT_UNI' => 'mediumblob', + 'TIMESTAMP' => 'int(11) UNSIGNED', + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'blob', + 'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')), + 'VCHAR_CI' => 'blob', + 'VARBINARY' => 'varbinary(255)', + ), + + 'mssql' => array( + 'INT:' => '[int]', + 'BINT' => '[float]', + 'UINT' => '[int]', + 'UINT:' => '[int]', + 'TINT:' => '[int]', + 'USINT' => '[int]', + 'BOOL' => '[int]', + 'VCHAR' => '[varchar] (255)', + 'VCHAR:' => '[varchar] (%d)', + 'CHAR:' => '[char] (%d)', + 'XSTEXT' => '[varchar] (1000)', + 'STEXT' => '[varchar] (3000)', + 'TEXT' => '[varchar] (8000)', + 'MTEXT' => '[text]', + 'XSTEXT_UNI'=> '[varchar] (100)', + 'STEXT_UNI' => '[varchar] (255)', + 'TEXT_UNI' => '[varchar] (4000)', + 'MTEXT_UNI' => '[text]', + 'TIMESTAMP' => '[int]', + 'DECIMAL' => '[float]', + 'DECIMAL:' => '[float]', + 'PDECIMAL' => '[float]', + 'PDECIMAL:' => '[float]', + 'VCHAR_UNI' => '[varchar] (255)', + 'VCHAR_UNI:'=> '[varchar] (%d)', + 'VCHAR_CI' => '[varchar] (255)', + 'VARBINARY' => '[varchar] (255)', + ), + + 'mssqlnative' => array( + 'INT:' => '[int]', + 'BINT' => '[float]', + 'UINT' => '[int]', + 'UINT:' => '[int]', + 'TINT:' => '[int]', + 'USINT' => '[int]', + 'BOOL' => '[int]', + 'VCHAR' => '[varchar] (255)', + 'VCHAR:' => '[varchar] (%d)', + 'CHAR:' => '[char] (%d)', + 'XSTEXT' => '[varchar] (1000)', + 'STEXT' => '[varchar] (3000)', + 'TEXT' => '[varchar] (8000)', + 'MTEXT' => '[text]', + 'XSTEXT_UNI'=> '[varchar] (100)', + 'STEXT_UNI' => '[varchar] (255)', + 'TEXT_UNI' => '[varchar] (4000)', + 'MTEXT_UNI' => '[text]', + 'TIMESTAMP' => '[int]', + 'DECIMAL' => '[float]', + 'DECIMAL:' => '[float]', + 'PDECIMAL' => '[float]', + 'PDECIMAL:' => '[float]', + 'VCHAR_UNI' => '[varchar] (255)', + 'VCHAR_UNI:'=> '[varchar] (%d)', + 'VCHAR_CI' => '[varchar] (255)', + 'VARBINARY' => '[varchar] (255)', + ), + + 'oracle' => array( + 'INT:' => 'number(%d)', + 'BINT' => 'number(20)', + 'UINT' => 'number(8)', + 'UINT:' => 'number(%d)', + 'TINT:' => 'number(%d)', + 'USINT' => 'number(4)', + 'BOOL' => 'number(1)', + 'VCHAR' => 'varchar2(255)', + 'VCHAR:' => 'varchar2(%d)', + 'CHAR:' => 'char(%d)', + 'XSTEXT' => 'varchar2(1000)', + 'STEXT' => 'varchar2(3000)', + 'TEXT' => 'clob', + 'MTEXT' => 'clob', + 'XSTEXT_UNI'=> 'varchar2(300)', + 'STEXT_UNI' => 'varchar2(765)', + 'TEXT_UNI' => 'clob', + 'MTEXT_UNI' => 'clob', + 'TIMESTAMP' => 'number(11)', + 'DECIMAL' => 'number(5, 2)', + 'DECIMAL:' => 'number(%d, 2)', + 'PDECIMAL' => 'number(6, 3)', + 'PDECIMAL:' => 'number(%d, 3)', + 'VCHAR_UNI' => 'varchar2(765)', + 'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')), + 'VCHAR_CI' => 'varchar2(255)', + 'VARBINARY' => 'raw(255)', + ), + + 'sqlite' => array( + 'INT:' => 'int(%d)', + 'BINT' => 'bigint(20)', + 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED', + 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', + 'TINT:' => 'tinyint(%d)', + 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED', + 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED', + 'VCHAR' => 'varchar(255)', + 'VCHAR:' => 'varchar(%d)', + 'CHAR:' => 'char(%d)', + 'XSTEXT' => 'text(65535)', + 'STEXT' => 'text(65535)', + 'TEXT' => 'text(65535)', + 'MTEXT' => 'mediumtext(16777215)', + 'XSTEXT_UNI'=> 'text(65535)', + 'STEXT_UNI' => 'text(65535)', + 'TEXT_UNI' => 'text(65535)', + 'MTEXT_UNI' => 'mediumtext(16777215)', + 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'varchar(255)', + 'VCHAR_UNI:'=> 'varchar(%d)', + 'VCHAR_CI' => 'varchar(255)', + 'VARBINARY' => 'blob', + ), + + 'sqlite3' => array( + 'INT:' => 'INT(%d)', + 'BINT' => 'BIGINT(20)', + 'UINT' => 'INTEGER UNSIGNED', + 'UINT:' => 'INTEGER UNSIGNED', + 'TINT:' => 'TINYINT(%d)', + 'USINT' => 'INTEGER UNSIGNED', + 'BOOL' => 'INTEGER UNSIGNED', + 'VCHAR' => 'VARCHAR(255)', + 'VCHAR:' => 'VARCHAR(%d)', + 'CHAR:' => 'CHAR(%d)', + 'XSTEXT' => 'TEXT(65535)', + 'STEXT' => 'TEXT(65535)', + 'TEXT' => 'TEXT(65535)', + 'MTEXT' => 'MEDIUMTEXT(16777215)', + 'XSTEXT_UNI'=> 'TEXT(65535)', + 'STEXT_UNI' => 'TEXT(65535)', + 'TEXT_UNI' => 'TEXT(65535)', + 'MTEXT_UNI' => 'MEDIUMTEXT(16777215)', + 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', + 'DECIMAL' => 'DECIMAL(5,2)', + 'DECIMAL:' => 'DECIMAL(%d,2)', + 'PDECIMAL' => 'DECIMAL(6,3)', + 'PDECIMAL:' => 'DECIMAL(%d,3)', + 'VCHAR_UNI' => 'VARCHAR(255)', + 'VCHAR_UNI:'=> 'VARCHAR(%d)', + 'VCHAR_CI' => 'VARCHAR(255)', + 'VARBINARY' => 'BLOB', + ), + + 'postgres' => array( + 'INT:' => 'INT4', + 'BINT' => 'INT8', + 'UINT' => 'INT4', // unsigned + 'UINT:' => 'INT4', // unsigned + 'USINT' => 'INT2', // unsigned + 'BOOL' => 'INT2', // unsigned + 'TINT:' => 'INT2', + 'VCHAR' => 'varchar(255)', + 'VCHAR:' => 'varchar(%d)', + 'CHAR:' => 'char(%d)', + 'XSTEXT' => 'varchar(1000)', + 'STEXT' => 'varchar(3000)', + 'TEXT' => 'varchar(8000)', + 'MTEXT' => 'TEXT', + 'XSTEXT_UNI'=> 'varchar(100)', + 'STEXT_UNI' => 'varchar(255)', + 'TEXT_UNI' => 'varchar(4000)', + 'MTEXT_UNI' => 'TEXT', + 'TIMESTAMP' => 'INT4', // unsigned + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'varchar(255)', + 'VCHAR_UNI:'=> 'varchar(%d)', + 'VCHAR_CI' => 'varchar_ci', + 'VARBINARY' => 'bytea', + ), + ); + } + + /** + * A list of types being unsigned for better reference in some db's + * @var array + */ + var $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); + + /** + * A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules. + * @var array + */ + var $supported_dbms = array('mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite', 'sqlite3'); + + /** + * This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array). + * This mode has no effect on some methods (inserting of data for example). This is expressed within the methods command. + */ + var $return_statements = false; + + /** + * Constructor. Set DB Object and set {@link $return_statements return_statements}. + * + * @param \phpbb\db\driver\driver_interface $db Database connection + * @param bool $return_statements True if only statements should be returned and no SQL being executed + */ + public function __construct(\phpbb\db\driver\driver_interface $db, $return_statements = false) + { + $this->db = $db; + $this->return_statements = $return_statements; + + $this->dbms_type_map = self::get_dbms_type_map(); + + // Determine mapping database type + switch ($this->db->get_sql_layer()) + { + case 'mysql': + $this->sql_layer = 'mysql_40'; + break; + + case 'mysql4': + if (version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) + { + $this->sql_layer = 'mysql_41'; + } + else + { + $this->sql_layer = 'mysql_40'; + } + break; + + case 'mysqli': + $this->sql_layer = 'mysql_41'; + break; + + case 'mssql': + case 'mssql_odbc': + $this->sql_layer = 'mssql'; + break; + + case 'mssqlnative': + $this->sql_layer = 'mssqlnative'; + break; + + default: + $this->sql_layer = $this->db->get_sql_layer(); + break; + } + } + + /** + * 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) + { + $this->return_statements = $return_statements; + } + + /** + * {@inheritDoc} + */ + function sql_list_tables() + { + switch ($this->db->get_sql_layer()) + { + case 'mysql': + case 'mysql4': + case 'mysqli': + $sql = 'SHOW TABLES'; + break; + + case 'sqlite': + $sql = 'SELECT name + FROM sqlite_master + WHERE type = "table"'; + break; + + case 'sqlite3': + $sql = 'SELECT name + FROM sqlite_master + WHERE type = "table" + AND name <> "sqlite_sequence"'; + break; + + case 'mssql': + case 'mssql_odbc': + case 'mssqlnative': + $sql = "SELECT name + FROM sysobjects + WHERE type='U'"; + break; + + case 'postgres': + $sql = 'SELECT relname + FROM pg_stat_user_tables'; + break; + + case 'oracle': + $sql = 'SELECT table_name + FROM USER_TABLES'; + break; + } + + $result = $this->db->sql_query($sql); + + $tables = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $name = current($row); + $tables[$name] = $name; + } + $this->db->sql_freeresult($result); + + return $tables; + } + + /** + * {@inheritDoc} + */ + function sql_table_exists($table_name) + { + $this->db->sql_return_on_error(true); + $result = $this->db->sql_query_limit('SELECT * FROM ' . $table_name, 1); + $this->db->sql_return_on_error(false); + + if ($result) + { + $this->db->sql_freeresult($result); + return true; + } + + return false; + } + + /** + * {@inheritDoc} + */ + function sql_create_table($table_name, $table_data) + { + // holds the DDL for a column + $columns = $statements = array(); + + if ($this->sql_table_exists($table_name)) + { + return $this->_sql_run_sql($statements); + } + + // Begin transaction + $statements[] = 'begin'; + + // Determine if we have created a PRIMARY KEY in the earliest + $primary_key_gen = false; + + // Determine if the table requires a sequence + $create_sequence = false; + + // Begin table sql statement + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': + $table_sql = 'CREATE TABLE [' . $table_name . '] (' . "\n"; + break; + + default: + $table_sql = 'CREATE TABLE ' . $table_name . ' (' . "\n"; + break; + } + + if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') + { + if (!isset($table_data['PRIMARY_KEY'])) + { + $table_data['COLUMNS']['mssqlindex'] = array('UINT', null, 'auto_increment'); + $table_data['PRIMARY_KEY'] = 'mssqlindex'; + } + } + + // Iterate through the columns to create a table + foreach ($table_data['COLUMNS'] as $column_name => $column_data) + { + // here lies an array, filled with information compiled on the column's data + $prepared_column = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + + if (isset($prepared_column['auto_increment']) && $prepared_column['auto_increment'] && strlen($column_name) > 26) // "${column_name}_gen" + { + trigger_error("Index name '${column_name}_gen' on table '$table_name' is too long. The maximum auto increment column length is 26 characters.", E_USER_ERROR); + } + + // here we add the definition of the new column to the list of columns + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': + $columns[] = "\t [{$column_name}] " . $prepared_column['column_type_sql_default']; + break; + + default: + $columns[] = "\t {$column_name} " . $prepared_column['column_type_sql']; + break; + } + + // see if we have found a primary key set due to a column definition if we have found it, we can stop looking + if (!$primary_key_gen) + { + $primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set']; + } + + // create sequence DDL based off of the existance of auto incrementing columns + if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment']) + { + $create_sequence = $column_name; + } + } + + // this makes up all the columns in the create table statement + $table_sql .= implode(",\n", $columns); + + // Close the table for two DBMS and add to the statements + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': + $table_sql .= "\n);"; + $statements[] = $table_sql; + break; + } + + // we have yet to create a primary key for this table, + // this means that we can add the one we really wanted instead + if (!$primary_key_gen) + { + // 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 ($this->sql_layer) + { + case 'mysql_40': + case 'mysql_41': + case 'postgres': + case 'sqlite': + case 'sqlite3': + $table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; + break; + + case 'mssql': + case 'mssqlnative': + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $primary_key_stmts = $this->sql_create_primary_key($table_name, $table_data['PRIMARY_KEY']); + foreach ($primary_key_stmts as $pk_stmt) + { + $statements[] = $pk_stmt; + } + + $this->return_statements = $old_return_statements; + break; + + case 'oracle': + $table_sql .= ",\n\t CONSTRAINT pk_{$table_name} PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; + break; + } + } + } + + // close the table + switch ($this->sql_layer) + { + case 'mysql_41': + // make sure the table is in UTF-8 mode + $table_sql .= "\n) CHARACTER SET `utf8` COLLATE `utf8_bin`;"; + $statements[] = $table_sql; + break; + + case 'mysql_40': + case 'sqlite': + case 'sqlite3': + $table_sql .= "\n);"; + $statements[] = $table_sql; + break; + + case 'postgres': + // do we need to add a sequence for auto incrementing columns? + if ($create_sequence) + { + $statements[] = "CREATE SEQUENCE {$table_name}_seq;"; + } + + $table_sql .= "\n);"; + $statements[] = $table_sql; + break; + + case 'oracle': + $table_sql .= "\n)"; + $statements[] = $table_sql; + + // do we need to add a sequence and a tigger for auto incrementing columns? + if ($create_sequence) + { + // create the actual sequence + $statements[] = "CREATE SEQUENCE {$table_name}_seq"; + + // the trigger is the mechanism by which we increment the counter + $trigger = "CREATE OR REPLACE TRIGGER t_{$table_name}\n"; + $trigger .= "BEFORE INSERT ON {$table_name}\n"; + $trigger .= "FOR EACH ROW WHEN (\n"; + $trigger .= "\tnew.{$create_sequence} IS NULL OR new.{$create_sequence} = 0\n"; + $trigger .= ")\n"; + $trigger .= "BEGIN\n"; + $trigger .= "\tSELECT {$table_name}_seq.nextval\n"; + $trigger .= "\tINTO :new.{$create_sequence}\n"; + $trigger .= "\tFROM dual;\n"; + $trigger .= "END;"; + + $statements[] = $trigger; + } + 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]); + } + + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $key_stmts = ($key_data[0] == 'UNIQUE') ? $this->sql_create_unique_index($table_name, $key_name, $key_data[1]) : $this->sql_create_index($table_name, $key_name, $key_data[1]); + + foreach ($key_stmts as $key_stmt) + { + $statements[] = $key_stmt; + } + + $this->return_statements = $old_return_statements; + } + } + + // Commit Transaction + $statements[] = 'commit'; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function perform_schema_changes($schema_changes) + { + if (empty($schema_changes)) + { + return; + } + + $statements = array(); + $sqlite = false; + + // For SQLite we need to perform the schema changes in a much more different way + if (($this->db->get_sql_layer() == 'sqlite' || $this->db->get_sql_layer() == 'sqlite3') && $this->return_statements) + { + $sqlite_data = array(); + $sqlite = true; + } + + // Drop tables? + if (!empty($schema_changes['drop_tables'])) + { + foreach ($schema_changes['drop_tables'] as $table) + { + // only drop table if it exists + if ($this->sql_table_exists($table)) + { + $result = $this->sql_table_drop($table); + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + // Add tables? + if (!empty($schema_changes['add_tables'])) + { + foreach ($schema_changes['add_tables'] as $table => $table_data) + { + $result = $this->sql_create_table($table, $table_data); + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + + // Change columns? + if (!empty($schema_changes['change_columns'])) + { + foreach ($schema_changes['change_columns'] as $table => $columns) + { + foreach ($columns as $column_name => $column_data) + { + // If the column exists we change it, else we add it ;) + if ($column_exists = $this->sql_column_exists($table, $column_name)) + { + $result = $this->sql_column_change($table, $column_name, $column_data, true); + } + else + { + $result = $this->sql_column_add($table, $column_name, $column_data, true); + } + + if ($sqlite) + { + if ($column_exists) + { + $sqlite_data[$table]['change_columns'][] = $result; + } + else + { + $sqlite_data[$table]['add_columns'][] = $result; + } + } + else if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + // Add columns? + if (!empty($schema_changes['add_columns'])) + { + foreach ($schema_changes['add_columns'] as $table => $columns) + { + foreach ($columns as $column_name => $column_data) + { + // Only add the column if it does not exist yet + if ($column_exists = $this->sql_column_exists($table, $column_name)) + { + continue; + // This is commented out here because it can take tremendous time on updates +// $result = $this->sql_column_change($table, $column_name, $column_data, true); + } + else + { + $result = $this->sql_column_add($table, $column_name, $column_data, true); + } + + if ($sqlite) + { + if ($column_exists) + { + continue; +// $sqlite_data[$table]['change_columns'][] = $result; + } + else + { + $sqlite_data[$table]['add_columns'][] = $result; + } + } + else if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + // Remove keys? + if (!empty($schema_changes['drop_keys'])) + { + foreach ($schema_changes['drop_keys'] as $table => $indexes) + { + foreach ($indexes as $index_name) + { + if (!$this->sql_index_exists($table, $index_name)) + { + continue; + } + + $result = $this->sql_index_drop($table, $index_name); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + // Drop columns? + if (!empty($schema_changes['drop_columns'])) + { + foreach ($schema_changes['drop_columns'] as $table => $columns) + { + foreach ($columns as $column) + { + // Only remove the column if it exists... + if ($this->sql_column_exists($table, $column)) + { + $result = $this->sql_column_remove($table, $column, true); + + if ($sqlite) + { + $sqlite_data[$table]['drop_columns'][] = $result; + } + else if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + } + + // Add primary keys? + if (!empty($schema_changes['add_primary_keys'])) + { + foreach ($schema_changes['add_primary_keys'] as $table => $columns) + { + $result = $this->sql_create_primary_key($table, $columns, true); + + if ($sqlite) + { + $sqlite_data[$table]['primary_key'] = $result; + } + else if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + + // Add unique indexes? + if (!empty($schema_changes['add_unique_index'])) + { + foreach ($schema_changes['add_unique_index'] as $table => $index_array) + { + foreach ($index_array as $index_name => $column) + { + if ($this->sql_unique_index_exists($table, $index_name)) + { + continue; + } + + $result = $this->sql_create_unique_index($table, $index_name, $column); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + // Add indexes? + if (!empty($schema_changes['add_index'])) + { + foreach ($schema_changes['add_index'] as $table => $index_array) + { + foreach ($index_array as $index_name => $column) + { + if ($this->sql_index_exists($table, $index_name)) + { + continue; + } + + $result = $this->sql_create_index($table, $index_name, $column); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + if ($sqlite) + { + foreach ($sqlite_data as $table_name => $sql_schema_changes) + { + // Create temporary table with original data + $statements[] = 'begin'; + + $sql = "SELECT sql + FROM sqlite_master + WHERE type = 'table' + AND name = '{$table_name}' + ORDER BY type DESC, name;"; + $result = $this->db->sql_query($sql); + + if (!$result) + { + continue; + } + + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + // Create a backup table and populate it, destroy the existing one + $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); + $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; + $statements[] = 'DROP TABLE ' . $table_name; + + // Get the columns... + preg_match('#\((.*)\)#s', $row['sql'], $matches); + + $plain_table_cols = trim($matches[1]); + $new_table_cols = preg_split('/,(?![\s\w]+\))/m', $plain_table_cols); + $column_list = array(); + + foreach ($new_table_cols as $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if ($entities[0] == 'PRIMARY') + { + continue; + } + $column_list[] = $entities[0]; + } + + // note down the primary key notation because sqlite only supports adding it to the end for the new table + $primary_key = false; + $_new_cols = array(); + + foreach ($new_table_cols as $key => $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if ($entities[0] == 'PRIMARY') + { + $primary_key = $declaration; + continue; + } + $_new_cols[] = $declaration; + } + + $new_table_cols = $_new_cols; + + // First of all... change columns + if (!empty($sql_schema_changes['change_columns'])) + { + foreach ($sql_schema_changes['change_columns'] as $column_sql) + { + foreach ($new_table_cols as $key => $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if (strpos($column_sql, $entities[0] . ' ') === 0) + { + $new_table_cols[$key] = $column_sql; + } + } + } + } + + if (!empty($sql_schema_changes['add_columns'])) + { + foreach ($sql_schema_changes['add_columns'] as $column_sql) + { + $new_table_cols[] = $column_sql; + } + } + + // Now drop them... + if (!empty($sql_schema_changes['drop_columns'])) + { + foreach ($sql_schema_changes['drop_columns'] as $column_name) + { + // Remove from column list... + $new_column_list = array(); + foreach ($column_list as $key => $value) + { + if ($value === $column_name) + { + continue; + } + + $new_column_list[] = $value; + } + + $column_list = $new_column_list; + + // Remove from table... + $_new_cols = array(); + foreach ($new_table_cols as $key => $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if (strpos($column_name . ' ', $entities[0] . ' ') === 0) + { + continue; + } + $_new_cols[] = $declaration; + } + $new_table_cols = $_new_cols; + } + } + + // Primary key... + if (!empty($sql_schema_changes['primary_key'])) + { + $new_table_cols[] = 'PRIMARY KEY (' . implode(', ', $sql_schema_changes['primary_key']) . ')'; + } + // Add a new one or the old primary key + else if ($primary_key !== false) + { + $new_table_cols[] = $primary_key; + } + + $columns = implode(',', $column_list); + + // create a new table and fill it up. destroy the temp one + $statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $new_table_cols) . ');'; + $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; + $statements[] = 'DROP TABLE ' . $table_name . '_temp'; + + $statements[] = 'commit'; + } + } + + if ($this->return_statements) + { + return $statements; + } + } + + /** + * {@inheritDoc} + */ + function sql_list_columns($table_name) + { + $columns = array(); + + switch ($this->sql_layer) + { + case 'mysql_40': + case 'mysql_41': + $sql = "SHOW COLUMNS FROM $table_name"; + break; + + // PostgreSQL has a way of doing this in a much simpler way but would + // not allow us to support all versions of PostgreSQL + case 'postgres': + $sql = "SELECT a.attname + FROM pg_class c, pg_attribute a + WHERE c.relname = '{$table_name}' + AND a.attnum > 0 + AND a.attrelid = c.oid"; + break; + + // same deal with PostgreSQL, we must perform more complex operations than + // we technically could + case 'mssql': + case 'mssqlnative': + $sql = "SELECT c.name + FROM syscolumns c + LEFT JOIN sysobjects o ON c.id = o.id + WHERE o.name = '{$table_name}'"; + break; + + case 'oracle': + $sql = "SELECT column_name + FROM user_tab_columns + WHERE LOWER(table_name) = '" . strtolower($table_name) . "'"; + break; + + case 'sqlite': + case 'sqlite3': + $sql = "SELECT sql + FROM sqlite_master + WHERE type = 'table' + AND name = '{$table_name}'"; + + $result = $this->db->sql_query($sql); + + if (!$result) + { + return false; + } + + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + preg_match('#\((.*)\)#s', $row['sql'], $matches); + + $cols = trim($matches[1]); + $col_array = preg_split('/,(?![\s\w]+\))/m', $cols); + + foreach ($col_array as $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if ($entities[0] == 'PRIMARY') + { + continue; + } + + $column = strtolower($entities[0]); + $columns[$column] = $column; + } + + return $columns; + break; + } + + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $column = strtolower(current($row)); + $columns[$column] = $column; + } + $this->db->sql_freeresult($result); + + return $columns; + } + + /** + * {@inheritDoc} + */ + function sql_column_exists($table_name, $column_name) + { + $columns = $this->sql_list_columns($table_name); + + return isset($columns[$column_name]); + } + + /** + * {@inheritDoc} + */ + function sql_index_exists($table_name, $index_name) + { + if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') + { + $sql = "EXEC sp_statistics '$table_name'"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + if ($row['TYPE'] == 3) + { + if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + } + $this->db->sql_freeresult($result); + + return false; + } + + switch ($this->sql_layer) + { + case 'postgres': + $sql = "SELECT ic.relname as index_name + FROM pg_class bc, pg_class ic, pg_index i + WHERE (bc.oid = i.indrelid) + AND (ic.oid = i.indexrelid) + AND (bc.relname = '" . $table_name . "') + AND (i.indisunique != 't') + AND (i.indisprimary != 't')"; + $col = 'index_name'; + break; + + case 'mysql_40': + case 'mysql_41': + $sql = 'SHOW KEYS + FROM ' . $table_name; + $col = 'Key_name'; + break; + + case 'oracle': + $sql = "SELECT index_name + FROM user_indexes + WHERE table_name = '" . strtoupper($table_name) . "' + AND generated = 'N' + AND uniqueness = 'NONUNIQUE'"; + $col = 'index_name'; + break; + + case 'sqlite': + case 'sqlite3': + $sql = "PRAGMA index_list('" . $table_name . "');"; + $col = 'name'; + break; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) + { + continue; + } + + // These DBMS prefix index name with the table name + switch ($this->sql_layer) + { + case 'oracle': + case 'postgres': + case 'sqlite': + case 'sqlite3': + $row[$col] = substr($row[$col], strlen($table_name) + 1); + break; + } + + if (strtolower($row[$col]) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + $this->db->sql_freeresult($result); + + return false; + } + + /** + * {@inheritDoc} + */ + function sql_unique_index_exists($table_name, $index_name) + { + if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') + { + $sql = "EXEC sp_statistics '$table_name'"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + // Usually NON_UNIQUE is the column we want to check, but we allow for both + if ($row['TYPE'] == 3) + { + if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + } + $this->db->sql_freeresult($result); + return false; + } + + switch ($this->sql_layer) + { + case 'postgres': + $sql = "SELECT ic.relname as index_name, i.indisunique + FROM pg_class bc, pg_class ic, pg_index i + WHERE (bc.oid = i.indrelid) + AND (ic.oid = i.indexrelid) + AND (bc.relname = '" . $table_name . "') + AND (i.indisprimary != 't')"; + $col = 'index_name'; + break; + + case 'mysql_40': + case 'mysql_41': + $sql = 'SHOW KEYS + FROM ' . $table_name; + $col = 'Key_name'; + break; + + case 'oracle': + $sql = "SELECT index_name, table_owner + FROM user_indexes + WHERE table_name = '" . strtoupper($table_name) . "' + AND generated = 'N' + AND uniqueness = 'UNIQUE'"; + $col = 'index_name'; + break; + + case 'sqlite': + case 'sqlite3': + $sql = "PRAGMA index_list('" . $table_name . "');"; + $col = 'name'; + break; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && ($row['Non_unique'] || $row[$col] == 'PRIMARY')) + { + continue; + } + + if (($this->sql_layer == 'sqlite' || $this->sql_layer == 'sqlite3') && !$row['unique']) + { + continue; + } + + if ($this->sql_layer == 'postgres' && $row['indisunique'] != 't') + { + continue; + } + + // These DBMS prefix index name with the table name + switch ($this->sql_layer) + { + case 'oracle': + // Two cases here... prefixed with U_[table_owner] and not prefixed with table_name + if (strpos($row[$col], 'U_') === 0) + { + $row[$col] = substr($row[$col], strlen('U_' . $row['table_owner']) + 1); + } + else if (strpos($row[$col], strtoupper($table_name)) === 0) + { + $row[$col] = substr($row[$col], strlen($table_name) + 1); + } + break; + + case 'postgres': + case 'sqlite': + case 'sqlite3': + $row[$col] = substr($row[$col], strlen($table_name) + 1); + break; + } + + if (strtolower($row[$col]) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + $this->db->sql_freeresult($result); + + return false; + } + + /** + * Private method for performing sql statements (either execute them or return them) + * @access private + */ + function _sql_run_sql($statements) + { + if ($this->return_statements) + { + return $statements; + } + + // We could add error handling here... + foreach ($statements as $sql) + { + if ($sql === 'begin') + { + $this->db->sql_transaction('begin'); + } + else if ($sql === 'commit') + { + $this->db->sql_transaction('commit'); + } + else + { + $this->db->sql_query($sql); + } + } + + return true; + } + + /** + * Function to prepare some column information for better usage + * @access private + */ + function sql_prepare_column_data($table_name, $column_name, $column_data) + { + if (strlen($column_name) > 30) + { + trigger_error("Column name '$column_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); + } + + // Get type + list($column_type, $orig_column_type) = $this->get_column_type($column_data[0]); + + // Adjust default value if db-dependent specified + if (is_array($column_data[1])) + { + $column_data[1] = (isset($column_data[1][$this->sql_layer])) ? $column_data[1][$this->sql_layer] : $column_data[1]['default']; + } + + $sql = ''; + + $return_array = array(); + + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': + $sql .= " {$column_type} "; + $sql_default = " {$column_type} "; + + // For adding columns we need the default definition + if (!is_null($column_data[1])) + { + // For hexadecimal values do not use single quotes + if (strpos($column_data[1], '0x') === 0) + { + $return_array['default'] = 'DEFAULT (' . $column_data[1] . ') '; + $sql_default .= $return_array['default']; + } + else + { + $return_array['default'] = 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; + $sql_default .= $return_array['default']; + } + } + + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { +// $sql .= 'IDENTITY (1, 1) '; + $sql_default .= 'IDENTITY (1, 1) '; + } + + $return_array['textimage'] = $column_type === '[text]'; + + if (!is_null($column_data[1]) || (isset($column_data[2]) && $column_data[2] == 'auto_increment')) + { + $sql .= 'NOT NULL'; + $sql_default .= 'NOT NULL'; + } + else + { + $sql .= 'NULL'; + $sql_default .= 'NULL'; + } + + $return_array['column_type_sql_default'] = $sql_default; + + break; + + case 'mysql_40': + case 'mysql_41': + $sql .= " {$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]}' "; + } + + if (!is_null($column_data[1]) || (isset($column_data[2]) && $column_data[2] == 'auto_increment')) + { + $sql .= 'NOT NULL'; + } + else + { + $sql .= 'NULL'; + } + + if (isset($column_data[2])) + { + if ($column_data[2] == 'auto_increment') + { + $sql .= ' auto_increment'; + } + else if ($this->sql_layer === 'mysql_41' && $column_data[2] == 'true_sort') + { + $sql .= ' COLLATE utf8_unicode_ci'; + } + } + + break; + + case 'oracle': + $sql .= " {$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 + // Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields) + if (!preg_match('/number/i', $column_type)) + { + $sql .= ($column_data[1] === '' || $column_data[1] === null) ? '' : 'NOT NULL'; + } + + $return_array['auto_increment'] = false; + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $return_array['auto_increment'] = true; + } + + break; + + case 'postgres': + $return_array['column_type'] = $column_type; + + $sql .= " {$column_type} "; + + $return_array['auto_increment'] = false; + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $default_val = "nextval('{$table_name}_seq')"; + $return_array['auto_increment'] = true; + } + else if (!is_null($column_data[1])) + { + $default_val = "'" . $column_data[1] . "'"; + $return_array['null'] = 'NOT NULL'; + $sql .= 'NOT NULL '; + } + else + { + $default_val = "'" . $column_data[1] . "'"; + $return_array['null'] = 'NULL'; + $sql .= 'NULL '; + } + + $return_array['default'] = $default_val; + + $sql .= "DEFAULT {$default_val}"; + + // Unsigned? Then add a CHECK contraint + if (in_array($orig_column_type, $this->unsigned_types)) + { + $return_array['constraint'] = "CHECK ({$column_name} >= 0)"; + $sql .= " CHECK ({$column_name} >= 0)"; + } + + break; + + case 'sqlite': + case 'sqlite3': + $return_array['primary_key_set'] = false; + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $sql .= ' INTEGER PRIMARY KEY'; + $return_array['primary_key_set'] = true; + + if ($this->sql_layer === 'sqlite3') + { + $sql .= ' AUTOINCREMENT'; + } + } + else + { + $sql .= ' ' . $column_type; + } + + if (!is_null($column_data[1])) + { + $sql .= ' NOT NULL '; + $sql .= "DEFAULT '{$column_data[1]}'"; + } + + break; + } + + $return_array['column_type_sql'] = $sql; + + return $return_array; + } + + /** + * Get the column's database type from the type map + * + * @param string $column_map_type + * @return array column type for this database + * and map type without length + */ + function get_column_type($column_map_type) + { + if (strpos($column_map_type, ':') !== false) + { + list($orig_column_type, $column_length) = explode(':', $column_map_type); + if (!is_array($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'])) + { + $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'], $column_length); + } + else + { + if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'])) + { + switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][0]) + { + case 'div': + $column_length /= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][1]; + $column_length = ceil($column_length); + $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); + break; + } + } + + if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'])) + { + switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][0]) + { + case 'mult': + $column_length *= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][1]; + if ($column_length > $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][2]) + { + $column_type = $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][3]; + } + else + { + $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); + } + break; + } + } + } + $orig_column_type .= ':'; + } + else + { + $orig_column_type = $column_map_type; + $column_type = $this->dbms_type_map[$this->sql_layer][$column_map_type]; + } + + return array($column_type, $orig_column_type); + } + + /** + * {@inheritDoc} + */ + function sql_column_add($table_name, $column_name, $column_data, $inline = false) + { + $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + $statements = array(); + + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': + // Does not support AFTER, only through temporary table + $statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default']; + break; + + case 'mysql_40': + case 'mysql_41': + $after = (!empty($column_data['after'])) ? ' AFTER ' . $column_data['after'] : ''; + $statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql'] . $after; + break; + + case 'oracle': + // Does not support AFTER, only through temporary table + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; + break; + + case 'postgres': + // Does not support AFTER, only through temporary table + if (version_compare($this->db->sql_server_info(true), '8.0', '>=')) + { + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; + } + else + { + // old versions cannot add columns with default and null information + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type'] . ' ' . $column_data['constraint']; + + if (isset($column_data['null'])) + { + if ($column_data['null'] == 'NOT NULL') + { + $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET NOT NULL'; + } + } + + if (isset($column_data['default'])) + { + $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; + } + } + + break; + + case 'sqlite': + if ($inline && $this->return_statements) + { + return $column_name . ' ' . $column_data['column_type_sql']; + } + + $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name); + if (empty($recreate_queries)) + { + break; + } + + $statements[] = 'begin'; + + $sql_create_table = array_shift($recreate_queries); + + // Create a backup table and populate it, destroy the existing one + $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); + $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; + $statements[] = 'DROP TABLE ' . $table_name; + + preg_match('#\((.*)\)#s', $sql_create_table, $matches); + + $new_table_cols = trim($matches[1]); + $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); + $column_list = array(); + + foreach ($old_table_cols as $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if ($entities[0] == 'PRIMARY') + { + continue; + } + $column_list[] = $entities[0]; + } + + $columns = implode(',', $column_list); + + $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols; + + // create a new table and fill it up. destroy the temp one + $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; + $statements = array_merge($statements, $recreate_queries); + + $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; + $statements[] = 'DROP TABLE ' . $table_name . '_temp'; + + $statements[] = 'commit'; + break; + + case 'sqlite3': + if ($inline && $this->return_statements) + { + return $column_name . ' ' . $column_data['column_type_sql']; + } + + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; + break; + } + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_column_remove($table_name, $column_name, $inline = false) + { + $statements = array(); + + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $indexes = $this->get_existing_indexes($table_name, $column_name); + $indexes = array_merge($indexes, $this->get_existing_indexes($table_name, $column_name, true)); + + // Drop any indexes + $recreate_indexes = array(); + if (!empty($indexes)) + { + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_index_drop($table_name, $index_name); + $statements = array_merge($statements, $result); + if (sizeof($index_data) > 1) + { + // Remove this column from the index and recreate it + $recreate_indexes[$index_name] = array_diff($index_data, array($column_name)); + } + } + } + + // Drop default value constraint + $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Remove the column + $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']'; + + if (!empty($recreate_indexes)) + { + // Recreate indexes after we removed the column + foreach ($recreate_indexes as $index_name => $index_data) + { + $result = $this->sql_create_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + $this->return_statements = $old_return_statements; + break; + + case 'mysql_40': + case 'mysql_41': + $statements[] = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`'; + break; + + case 'oracle': + $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name; + break; + + case 'postgres': + $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"'; + break; + + case 'sqlite': + case 'sqlite3': + + if ($inline && $this->return_statements) + { + return $column_name; + } + + $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name, $column_name); + if (empty($recreate_queries)) + { + break; + } + + $statements[] = 'begin'; + + $sql_create_table = array_shift($recreate_queries); + + // Create a backup table and populate it, destroy the existing one + $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); + $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; + $statements[] = 'DROP TABLE ' . $table_name; + + preg_match('#\((.*)\)#s', $sql_create_table, $matches); + + $new_table_cols = trim($matches[1]); + $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); + $column_list = array(); + + foreach ($old_table_cols as $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name) + { + continue; + } + $column_list[] = $entities[0]; + } + + $columns = implode(',', $column_list); + + $new_table_cols = trim(preg_replace('/' . $column_name . '\b[^,]+(?:,|$)/m', '', $new_table_cols)); + if (substr($new_table_cols, -1) === ',') + { + // Remove the comma from the last entry again + $new_table_cols = substr($new_table_cols, 0, -1); + } + + // create a new table and fill it up. destroy the temp one + $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; + $statements = array_merge($statements, $recreate_queries); + + $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; + $statements[] = 'DROP TABLE ' . $table_name . '_temp'; + + $statements[] = 'commit'; + break; + } + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_index_drop($table_name, $index_name) + { + $statements = array(); + + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': + $statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name; + break; + + case 'mysql_40': + case 'mysql_41': + $statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name; + break; + + case 'oracle': + case 'postgres': + case 'sqlite': + case 'sqlite3': + $statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name; + break; + } + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_table_drop($table_name) + { + $statements = array(); + + if (!$this->sql_table_exists($table_name)) + { + return $this->_sql_run_sql($statements); + } + + // the most basic operation, get rid of the table + $statements[] = 'DROP TABLE ' . $table_name; + + switch ($this->sql_layer) + { + case 'oracle': + $sql = 'SELECT A.REFERENCED_NAME + FROM USER_DEPENDENCIES A, USER_TRIGGERS B + WHERE A.REFERENCED_TYPE = \'SEQUENCE\' + AND A.NAME = B.TRIGGER_NAME + AND B.TABLE_NAME = \'' . strtoupper($table_name) . "'"; + $result = $this->db->sql_query($sql); + + // any sequences ref'd to this table's triggers? + while ($row = $this->db->sql_fetchrow($result)) + { + $statements[] = "DROP SEQUENCE {$row['referenced_name']}"; + } + $this->db->sql_freeresult($result); + break; + + case 'postgres': + // PGSQL does not "tightly" bind sequences and tables, we must guess... + $sql = "SELECT relname + FROM pg_class + WHERE relkind = 'S' + AND relname = '{$table_name}_seq'"; + $result = $this->db->sql_query($sql); + + // We don't even care about storing the results. We already know the answer if we get rows back. + if ($this->db->sql_fetchrow($result)) + { + $statements[] = "DROP SEQUENCE {$table_name}_seq;\n"; + } + $this->db->sql_freeresult($result); + break; + } + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_create_primary_key($table_name, $column, $inline = false) + { + $statements = array(); + + switch ($this->sql_layer) + { + case 'postgres': + case 'mysql_40': + case 'mysql_41': + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; + break; + + case 'mssql': + case 'mssqlnative': + $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD "; + $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED ("; + $sql .= '[' . implode("],\n\t\t[", $column) . ']'; + $sql .= ')'; + + $statements[] = $sql; + break; + + case 'oracle': + $statements[] = 'ALTER TABLE ' . $table_name . ' add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; + break; + + case 'sqlite': + case 'sqlite3': + + if ($inline && $this->return_statements) + { + return $column; + } + + $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name); + if (empty($recreate_queries)) + { + break; + } + + $statements[] = 'begin'; + + $sql_create_table = array_shift($recreate_queries); + + // Create a backup table and populate it, destroy the existing one + $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); + $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; + $statements[] = 'DROP TABLE ' . $table_name; + + preg_match('#\((.*)\)#s', $sql_create_table, $matches); + + $new_table_cols = trim($matches[1]); + $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); + $column_list = array(); + + foreach ($old_table_cols as $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if ($entities[0] == 'PRIMARY') + { + continue; + } + $column_list[] = $entities[0]; + } + + $columns = implode(',', $column_list); + + // create a new table and fill it up. destroy the temp one + $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));'; + $statements = array_merge($statements, $recreate_queries); + + $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; + $statements[] = 'DROP TABLE ' . $table_name . '_temp'; + + $statements[] = 'commit'; + break; + } + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_create_unique_index($table_name, $index_name, $column) + { + $statements = array(); + + $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) + if (strlen($table_name . '_' . $index_name) - strlen($table_prefix) > 24) + { + $max_length = strlen($table_prefix) + 24; + trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); + } + + switch ($this->sql_layer) + { + case 'postgres': + case 'oracle': + case 'sqlite': + case 'sqlite3': + $statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; + break; + + case 'mysql_40': + case 'mysql_41': + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; + break; + + case 'mssql': + case 'mssqlnative': + $statements[] = 'CREATE UNIQUE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; + break; + } + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_create_index($table_name, $index_name, $column) + { + $statements = array(); + + $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) + if (strlen($table_name . $index_name) - strlen($table_prefix) > 24) + { + $max_length = strlen($table_prefix) + 24; + trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); + } + + // remove index length unless MySQL4 + if ('mysql_40' != $this->sql_layer) + { + $column = preg_replace('#:.*$#', '', $column); + } + + switch ($this->sql_layer) + { + case 'postgres': + case 'oracle': + case 'sqlite': + case 'sqlite3': + $statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; + break; + + case 'mysql_40': + // add index size to definition as required by MySQL4 + foreach ($column as $i => $col) + { + if (false !== strpos($col, ':')) + { + list($col, $index_size) = explode(':', $col); + $column[$i] = "$col($index_size)"; + } + } + // no break + case 'mysql_41': + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; + break; + + case 'mssql': + case 'mssqlnative': + $statements[] = 'CREATE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; + break; + } + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_list_index($table_name) + { + $index_array = array(); + + if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') + { + $sql = "EXEC sp_statistics '$table_name'"; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if ($row['TYPE'] == 3) + { + $index_array[] = $row['INDEX_NAME']; + } + } + $this->db->sql_freeresult($result); + } + else + { + switch ($this->sql_layer) + { + case 'postgres': + $sql = "SELECT ic.relname as index_name + FROM pg_class bc, pg_class ic, pg_index i + WHERE (bc.oid = i.indrelid) + AND (ic.oid = i.indexrelid) + AND (bc.relname = '" . $table_name . "') + AND (i.indisunique != 't') + AND (i.indisprimary != 't')"; + $col = 'index_name'; + break; + + case 'mysql_40': + case 'mysql_41': + $sql = 'SHOW KEYS + FROM ' . $table_name; + $col = 'Key_name'; + break; + + case 'oracle': + $sql = "SELECT index_name + FROM user_indexes + WHERE table_name = '" . strtoupper($table_name) . "' + AND generated = 'N' + AND uniqueness = 'NONUNIQUE'"; + $col = 'index_name'; + break; + + case 'sqlite': + case 'sqlite3': + $sql = "PRAGMA index_info('" . $table_name . "');"; + $col = 'name'; + break; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) + { + continue; + } + + switch ($this->sql_layer) + { + case 'oracle': + case 'postgres': + case 'sqlite': + case 'sqlite3': + $row[$col] = substr($row[$col], strlen($table_name) + 1); + break; + } + + $index_array[] = $row[$col]; + } + $this->db->sql_freeresult($result); + } + + return array_map('strtolower', $index_array); + } + + /** + * Removes table_name from the index_name if it is at the beginning + * + * @param $table_name + * @param $index_name + * @return string + */ + protected function strip_table_name_from_index_name($table_name, $index_name) + { + return (strpos(strtoupper($index_name), strtoupper($table_name)) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name; + } + + /** + * {@inheritDoc} + */ + function sql_column_change($table_name, $column_name, $column_data, $inline = false) + { + $original_column_data = $column_data; + $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + $statements = array(); + + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $indexes = $this->get_existing_indexes($table_name, $column_name); + $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); + + // Drop any indexes + if (!empty($indexes) || !empty($unique_indexes)) + { + $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); + foreach ($drop_indexes as $index_name) + { + $result = $this->sql_index_drop($table_name, $index_name); + $statements = array_merge($statements, $result); + } + } + + // Drop default value constraint + $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Change the column + $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; + + if (!empty($column_data['default'])) + { + // Add new default value constraint + $statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $this->db->sql_escape($column_data['default']) . ' FOR [' . $column_name . ']'; + } + + if (!empty($indexes)) + { + // Recreate indexes after we changed the column + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_create_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + if (!empty($unique_indexes)) + { + // Recreate unique indexes after we changed the column + foreach ($unique_indexes as $index_name => $index_data) + { + $result = $this->sql_create_unique_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + $this->return_statements = $old_return_statements; + break; + + case 'mysql_40': + case 'mysql_41': + $statements[] = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql']; + break; + + case 'oracle': + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + // Get list of existing indexes + $indexes = $this->get_existing_indexes($table_name, $column_name); + $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); + + // Drop any indexes + if (!empty($indexes) || !empty($unique_indexes)) + { + $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); + foreach ($drop_indexes as $index_name) + { + $result = $this->sql_index_drop($table_name, $this->strip_table_name_from_index_name($table_name, $index_name)); + $statements = array_merge($statements, $result); + } + } + + $temp_column_name = 'temp_' . substr(md5($column_name), 0, 25); + // Add a temporary table with the new type + $result = $this->sql_column_add($table_name, $temp_column_name, $original_column_data); + $statements = array_merge($statements, $result); + + // Copy the data to the new column + $statements[] = 'UPDATE ' . $table_name . ' SET ' . $temp_column_name . ' = ' . $column_name; + + // Drop the original column + $result = $this->sql_column_remove($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Recreate the original column with the new type + $result = $this->sql_column_add($table_name, $column_name, $original_column_data); + $statements = array_merge($statements, $result); + + if (!empty($indexes)) + { + // Recreate indexes after we changed the column + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_create_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data); + $statements = array_merge($statements, $result); + } + } + + if (!empty($unique_indexes)) + { + // Recreate unique indexes after we changed the column + foreach ($unique_indexes as $index_name => $index_data) + { + $result = $this->sql_create_unique_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data); + $statements = array_merge($statements, $result); + } + } + + // Copy the data to the original column + $statements[] = 'UPDATE ' . $table_name . ' SET ' . $column_name . ' = ' . $temp_column_name; + + // Drop the temporary column again + $result = $this->sql_column_remove($table_name, $temp_column_name); + $statements = array_merge($statements, $result); + + $this->return_statements = $old_return_statements; + break; + + case 'postgres': + $sql = 'ALTER TABLE ' . $table_name . ' '; + + $sql_array = array(); + $sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type']; + + if (isset($column_data['null'])) + { + if ($column_data['null'] == 'NOT NULL') + { + $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL'; + } + else if ($column_data['null'] == 'NULL') + { + $sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL'; + } + } + + if (isset($column_data['default'])) + { + $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; + } + + // we don't want to double up on constraints if we change different number data types + if (isset($column_data['constraint'])) + { + $constraint_sql = "SELECT consrc as constraint_data + FROM pg_constraint, pg_class bc + WHERE conrelid = bc.oid + AND bc.relname = '{$table_name}' + AND NOT EXISTS ( + SELECT * + FROM pg_constraint as c, pg_inherits as i + WHERE i.inhrelid = pg_constraint.conrelid + AND c.conname = pg_constraint.conname + AND c.consrc = pg_constraint.consrc + AND c.conrelid = i.inhparent + )"; + + $constraint_exists = false; + + $result = $this->db->sql_query($constraint_sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (trim($row['constraint_data']) == trim($column_data['constraint'])) + { + $constraint_exists = true; + break; + } + } + $this->db->sql_freeresult($result); + + if (!$constraint_exists) + { + $sql_array[] = 'ADD ' . $column_data['constraint']; + } + } + + $sql .= implode(', ', $sql_array); + + $statements[] = $sql; + break; + + case 'sqlite': + case 'sqlite3': + + if ($inline && $this->return_statements) + { + return $column_name . ' ' . $column_data['column_type_sql']; + } + + $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name); + if (empty($recreate_queries)) + { + break; + } + + $statements[] = 'begin'; + + $sql_create_table = array_shift($recreate_queries); + + // Create a temp table and populate it, destroy the existing one + $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); + $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; + $statements[] = 'DROP TABLE ' . $table_name; + + preg_match('#\((.*)\)#s', $sql_create_table, $matches); + + $new_table_cols = trim($matches[1]); + $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); + $column_list = array(); + + foreach ($old_table_cols as $key => $declaration) + { + $declaration = trim($declaration); + + // Check for the beginning of the constraint section and stop + if (preg_match('/[^\(]*\s*PRIMARY KEY\s+\(/', $declaration) || + preg_match('/[^\(]*\s*UNIQUE\s+\(/', $declaration) || + preg_match('/[^\(]*\s*FOREIGN KEY\s+\(/', $declaration) || + preg_match('/[^\(]*\s*CHECK\s+\(/', $declaration)) + { + break; + } + + $entities = preg_split('#\s+#', $declaration); + $column_list[] = $entities[0]; + if ($entities[0] == $column_name) + { + $old_table_cols[$key] = $column_name . ' ' . $column_data['column_type_sql']; + } + } + + $columns = implode(',', $column_list); + + // Create a new table and fill it up. destroy the temp one + $statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');'; + $statements = array_merge($statements, $recreate_queries); + + $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; + $statements[] = 'DROP TABLE ' . $table_name . '_temp'; + + $statements[] = 'commit'; + + break; + } + + return $this->_sql_run_sql($statements); + } + + /** + * Get queries to drop the default constraints of a column + * + * We need to drop the default constraints of a column, + * before being able to change their type or deleting them. + * + * @param string $table_name + * @param string $column_name + * @return array Array with SQL statements + */ + protected function mssql_get_drop_default_constraints_queries($table_name, $column_name) + { + $statements = array(); + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT so.name AS def_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}')"; + } + else + { + $sql = "SELECT dobj.name AS def_name + FROM sys.columns col + LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D') + WHERE col.object_id = object_id('{$table_name}') + AND col.name = '{$column_name}' + AND dobj.name IS NOT NULL"; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']'; + } + $this->db->sql_freeresult($result); + + return $statements; + } + + /** + * Get a list with existing indexes for the column + * + * @param string $table_name + * @param string $column_name + * @param bool $unique Should we get unique indexes or normal ones + * @return array Array with Index name => columns + */ + public function get_existing_indexes($table_name, $column_name, $unique = false) + { + switch ($this->sql_layer) + { + case 'mysql_40': + case 'mysql_41': + case 'postgres': + case 'sqlite': + case 'sqlite3': + // Not supported + throw new \Exception('DBMS is not supported'); + break; + } + + $sql = ''; + $existing_indexes = array(); + + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND cols.name = '{$column_name}' + AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique ? '1' : '0'); + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND cols.name = '{$column_name}' + AND ix.is_unique = " . ($unique ? '1' : '0'); + } + break; + + case 'oracle': + $sql = "SELECT ix.index_name AS phpbb_index_name, ix.uniqueness AS is_unique + FROM all_ind_columns ixc, all_indexes ix + WHERE ix.index_name = ixc.index_name + AND ixc.table_name = '" . strtoupper($table_name) . "' + AND ixc.column_name = '" . strtoupper($column_name) . "'"; + break; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (!isset($row['is_unique']) || ($unique && $row['is_unique'] == 'UNIQUE') || (!$unique && $row['is_unique'] == 'NONUNIQUE')) + { + $existing_indexes[$row['phpbb_index_name']] = array(); + } + } + $this->db->sql_freeresult($result); + + if (empty($existing_indexes)) + { + return array(); + } + + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': + if ($this->mssql_is_sql_server_2000()) + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + break; + + case 'oracle': + $sql = "SELECT index_name AS phpbb_index_name, column_name AS phpbb_column_name + FROM all_ind_columns + WHERE table_name = '" . strtoupper($table_name) . "' + AND " . $this->db->sql_in_set('index_name', array_keys($existing_indexes)); + break; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; + } + $this->db->sql_freeresult($result); + + return $existing_indexes; + } + + /** + * Is the used MS SQL Server a SQL Server 2000? + * + * @return bool + */ + protected function mssql_is_sql_server_2000() + { + if ($this->is_sql_server_2000 === null) + { + $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version"; + $result = $this->db->sql_query($sql); + $properties = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + $this->is_sql_server_2000 = $properties['mssql_version'][0] == '8'; + } + + return $this->is_sql_server_2000; + } + + /** + * Returns the Queries which are required to recreate a table including indexes + * + * @param string $table_name + * @param string $remove_column When we drop a column, we remove the column + * from all indexes. If the index has no other + * column, we drop it completly. + * @return array + */ + protected function sqlite_get_recreate_table_queries($table_name, $remove_column = '') + { + $queries = array(); + + $sql = "SELECT sql + FROM sqlite_master + WHERE type = 'table' + AND name = '{$table_name}'"; + $result = $this->db->sql_query($sql); + $sql_create_table = $this->db->sql_fetchfield('sql'); + $this->db->sql_freeresult($result); + + if (!$sql_create_table) + { + return array(); + } + $queries[] = $sql_create_table; + + $sql = "SELECT sql + FROM sqlite_master + WHERE type = 'index' + AND tbl_name = '{$table_name}'"; + $result = $this->db->sql_query($sql); + while ($sql_create_index = $this->db->sql_fetchfield('sql')) + { + if ($remove_column) + { + $match = array(); + preg_match('#(?:[\w ]+)\((.*)\)#', $sql_create_index, $match); + if (!isset($match[1])) + { + continue; + } + + // Find and remove $remove_column from the index + $columns = explode(', ', $match[1]); + $found_column = array_search($remove_column, $columns); + if ($found_column !== false) + { + unset($columns[$found_column]); + + // If the column list is not empty add the index to the list + if (!empty($columns)) + { + $queries[] = str_replace($match[1], implode(', ', $columns), $sql_create_index); + } + } + else + { + $queries[] = $sql_create_index; + } + } + else + { + $queries[] = $sql_create_index; + } + } + $this->db->sql_freeresult($result); + + return $queries; + } +} diff --git a/phpBB/phpbb/db/tools/tools_interface.php b/phpBB/phpbb/db/tools/tools_interface.php new file mode 100644 index 0000000000..f153f73a54 --- /dev/null +++ b/phpBB/phpbb/db/tools/tools_interface.php @@ -0,0 +1,202 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\tools; + +/** + * Interface for a Database Tools for handling cross-db actions such as altering columns, etc. + */ +interface tools_interface +{ + /** + * 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 + * drop_columns: Removing/Dropping columns + * add_primary_keys: adding primary keys + * add_unique_index: adding an unique index + * add_index: adding an index (can be column:index_size if you need to provide size) + * + * The values are in this format: + * {TABLE NAME} => array( + * {COLUMN NAME} => array({COLUMN TYPE}, {DEFAULT VALUE}, {OPTIONAL VARIABLES}), + * {KEY/INDEX NAME} => array({COLUMN NAMES}), + * ) + * + * + * @param array $schema_changes + * @return null + */ + public function perform_schema_changes($schema_changes); + + /** + * Gets a list of tables in the database. + * + * @return array Array of table names (all lower case) + */ + public function sql_list_tables(); + + /** + * Check if table exists + * + * @param string $table_name The table name to check for + * @return bool true if table exists, else false + */ + public function sql_table_exists($table_name); + + /** + * Create SQL Table + * + * @param string $table_name The table name to create + * @param array $table_data Array containing table data. + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_create_table($table_name, $table_data); + + /** + * Drop Table + * + * @param string $table_name The table name to drop + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_table_drop($table_name); + + /** + * Gets a list of columns of a table. + * + * @param string $table_name Table name + * @return array Array of column names (all lower case) + */ + public function sql_list_columns($table_name); + + /** + * Check whether a specified column exist in a table + * + * @param string $table_name Table to check + * @param string $column_name Column to check + * @return bool True if column exists, false otherwise + */ + public function sql_column_exists($table_name, $column_name); + + /** + * Add new column + * + * @param string $table_name Table to modify + * @param string $column_name Name of the column to add + * @param array $column_data Column data + * @param bool $inline Whether the query should actually be run, + * or return a string for adding the column + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_column_add($table_name, $column_name, $column_data, $inline = false); + + /** + * Change column type (not name!) + * + * @param string $table_name Table to modify + * @param string $column_name Name of the column to modify + * @param array $column_data Column data + * @param bool $inline Whether the query should actually be run, + * or return a string for modifying the column + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_column_change($table_name, $column_name, $column_data, $inline = false); + + /** + * Drop column + * + * @param string $table_name Table to modify + * @param string $column_name Name of the column to drop + * @param bool $inline Whether the query should actually be run, + * or return a string for deleting the column + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_column_remove($table_name, $column_name, $inline = false); + + /** + * List all of the indices that belong to a table + * + * NOTE: does not list + * - UNIQUE indices + * - PRIMARY keys + * + * @param string $table_name Table to check + * @return array Array with index names + */ + public function sql_list_index($table_name); + + /** + * Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes. + * + * @param string $table_name Table to check the index at + * @param string $index_name The index name to check + * @return bool True if index exists, else false + */ + public function sql_index_exists($table_name, $index_name); + + /** + * Add index + * + * @param string $table_name Table to modify + * @param string $index_name Name of the index to create + * @param string|array $column Either a string with a column name, or an array with columns + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_create_index($table_name, $index_name, $column); + + /** + * Drop Index + * + * @param string $table_name Table to modify + * @param string $index_name Name of the index to delete + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_index_drop($table_name, $index_name); + + /** + * Check if a specified index exists in table. + * + * NOTE: Does not return normal and PRIMARY KEY indexes + * + * @param string $table_name Table to check the index at + * @param string $index_name The index name to check + * @return bool True if index exists, else false + */ + public function sql_unique_index_exists($table_name, $index_name); + + /** + * Add unique index + * + * @param string $table_name Table to modify + * @param string $index_name Name of the unique index to create + * @param string|array $column Either a string with a column name, or an array with columns + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_create_unique_index($table_name, $index_name, $column); + + /** + * Add primary key + * + * @param string $table_name Table to modify + * @param string|array $column Either a string with a column name, or an array with columns + * @param bool $inline Whether the query should actually be run, + * or return a string for creating the key + * @return array|true Statements to run, or true if the statements have been executed + */ + public function sql_create_primary_key($table_name, $column, $inline = false); +} diff --git a/phpBB/phpbb/db/tools_interface.php b/phpBB/phpbb/db/tools_interface.php deleted file mode 100644 index d0ecac779e..0000000000 --- a/phpBB/phpbb/db/tools_interface.php +++ /dev/null @@ -1,202 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\db; - -/** - * Interface for a Database Tools for handling cross-db actions such as altering columns, etc. - */ -interface tools_interface -{ - /** - * 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 - * drop_columns: Removing/Dropping columns - * add_primary_keys: adding primary keys - * add_unique_index: adding an unique index - * add_index: adding an index (can be column:index_size if you need to provide size) - * - * The values are in this format: - * {TABLE NAME} => array( - * {COLUMN NAME} => array({COLUMN TYPE}, {DEFAULT VALUE}, {OPTIONAL VARIABLES}), - * {KEY/INDEX NAME} => array({COLUMN NAMES}), - * ) - * - * - * @param array $schema_changes - * @return null - */ - public function perform_schema_changes($schema_changes); - - /** - * Gets a list of tables in the database. - * - * @return array Array of table names (all lower case) - */ - public function sql_list_tables(); - - /** - * Check if table exists - * - * @param string $table_name The table name to check for - * @return bool true if table exists, else false - */ - public function sql_table_exists($table_name); - - /** - * Create SQL Table - * - * @param string $table_name The table name to create - * @param array $table_data Array containing table data. - * @return array|true Statements to run, or true if the statements have been executed - */ - public function sql_create_table($table_name, $table_data); - - /** - * Drop Table - * - * @param string $table_name The table name to drop - * @return array|true Statements to run, or true if the statements have been executed - */ - public function sql_table_drop($table_name); - - /** - * Gets a list of columns of a table. - * - * @param string $table_name Table name - * @return array Array of column names (all lower case) - */ - public function sql_list_columns($table_name); - - /** - * Check whether a specified column exist in a table - * - * @param string $table_name Table to check - * @param string $column_name Column to check - * @return bool True if column exists, false otherwise - */ - public function sql_column_exists($table_name, $column_name); - - /** - * Add new column - * - * @param string $table_name Table to modify - * @param string $column_name Name of the column to add - * @param array $column_data Column data - * @param bool $inline Whether the query should actually be run, - * or return a string for adding the column - * @return array|true Statements to run, or true if the statements have been executed - */ - public function sql_column_add($table_name, $column_name, $column_data, $inline = false); - - /** - * Change column type (not name!) - * - * @param string $table_name Table to modify - * @param string $column_name Name of the column to modify - * @param array $column_data Column data - * @param bool $inline Whether the query should actually be run, - * or return a string for modifying the column - * @return array|true Statements to run, or true if the statements have been executed - */ - public function sql_column_change($table_name, $column_name, $column_data, $inline = false); - - /** - * Drop column - * - * @param string $table_name Table to modify - * @param string $column_name Name of the column to drop - * @param bool $inline Whether the query should actually be run, - * or return a string for deleting the column - * @return array|true Statements to run, or true if the statements have been executed - */ - public function sql_column_remove($table_name, $column_name, $inline = false); - - /** - * List all of the indices that belong to a table - * - * NOTE: does not list - * - UNIQUE indices - * - PRIMARY keys - * - * @param string $table_name Table to check - * @return array Array with index names - */ - public function sql_list_index($table_name); - - /** - * Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes. - * - * @param string $table_name Table to check the index at - * @param string $index_name The index name to check - * @return bool True if index exists, else false - */ - public function sql_index_exists($table_name, $index_name); - - /** - * Add index - * - * @param string $table_name Table to modify - * @param string $index_name Name of the index to create - * @param string|array $column Either a string with a column name, or an array with columns - * @return array|true Statements to run, or true if the statements have been executed - */ - public function sql_create_index($table_name, $index_name, $column); - - /** - * Drop Index - * - * @param string $table_name Table to modify - * @param string $index_name Name of the index to delete - * @return array|true Statements to run, or true if the statements have been executed - */ - public function sql_index_drop($table_name, $index_name); - - /** - * Check if a specified index exists in table. - * - * NOTE: Does not return normal and PRIMARY KEY indexes - * - * @param string $table_name Table to check the index at - * @param string $index_name The index name to check - * @return bool True if index exists, else false - */ - public function sql_unique_index_exists($table_name, $index_name); - - /** - * Add unique index - * - * @param string $table_name Table to modify - * @param string $index_name Name of the unique index to create - * @param string|array $column Either a string with a column name, or an array with columns - * @return array|true Statements to run, or true if the statements have been executed - */ - public function sql_create_unique_index($table_name, $index_name, $column); - - /** - * Add primary key - * - * @param string $table_name Table to modify - * @param string|array $column Either a string with a column name, or an array with columns - * @param bool $inline Whether the query should actually be run, - * or return a string for creating the key - * @return array|true Statements to run, or true if the statements have been executed - */ - public function sql_create_primary_key($table_name, $column, $inline = false); -} diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index 7be1b487ab..2765d05b94 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -85,7 +85,7 @@ class fulltext_sphinx /** * Database Tools object - * @var \phpbb\db\tools_interface + * @var \phpbb\db\tools\tools_interface */ protected $db_tools; @@ -135,8 +135,8 @@ class fulltext_sphinx $this->db = $db; $this->auth = $auth; - // Initialize \phpbb\db\tools object - $this->db_tools = new \phpbb\db\tools($this->db); + // Initialize \phpbb\db\tools\tools object + $this->db_tools = new \phpbb\db\tools\tools($this->db); if(!$this->config['fulltext_sphinx_id']) { -- cgit v1.2.1 From 11b6bc5722a6a4aed1cd45ce65f2d9cf16ae7dd5 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 10 Jan 2015 15:43:18 +0100 Subject: [ticket/13487] Add factory for db tool class This allows us to split up the large file one by one easily. PHPBB3-13487 --- phpBB/phpbb/db/tools/factory.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 phpBB/phpbb/db/tools/factory.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/factory.php b/phpBB/phpbb/db/tools/factory.php new file mode 100644 index 0000000000..60db2ade03 --- /dev/null +++ b/phpBB/phpbb/db/tools/factory.php @@ -0,0 +1,35 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\tools; + +/** + * A factory which serves the suitable tools instance for the given dbal + */ +class factory +{ + /** + * @param mixed $db_driver + * @param bool $return_statements + * @return \phpbb\db\tools\tools_interface + */ + public function get($db_driver, $return_statements = false) + { + if ($db_driver instanceof \phpbb\db\driver\driver_interface) + { + return new \phpbb\db\tools\tools($db_driver, $return_statements); + } + + throw new \InvalidArgumentException('Invalid database driver given'); + } +} -- cgit v1.2.1 From 35d37fdff44365ccb01e1599759d2a5c02084184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gae=CC=88tan=20Muller?= Date: Sun, 11 Jan 2015 21:09:21 +0100 Subject: [ticket/13498] Update calls to `get_user_avatar()` PHPBB3-13498 --- phpBB/phpbb/user_loader.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/user_loader.php b/phpBB/phpbb/user_loader.php index 24e663b150..0b192e4452 100644 --- a/phpBB/phpbb/user_loader.php +++ b/phpBB/phpbb/user_loader.php @@ -175,7 +175,7 @@ class user_loader /** * Get avatar * - * @param int $user_id User ID of the user you want to retreive the avatar for + * @param int $user_id User ID of the user you want to retrieve the avatar for * @param bool $query Should we query the database if this user has not yet been loaded? * Typically this should be left as false and you should make sure * you load users ahead of time with load_users() @@ -188,12 +188,14 @@ class user_loader return ''; } - if (!function_exists('get_user_avatar')) - { - include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext); - } + $row = array( + 'avatar' => $user['user_avatar'], + 'avatar_type' => $user['user_avatar_type'], + 'avatar_width' => $user['user_avatar_width'], + 'avatar_height' => $user['user_avatar_height'], + ); - return get_user_avatar($user['user_avatar'], $user['user_avatar_type'], $user['user_avatar_width'], $user['user_avatar_height']); + return phpbb_get_avatar($row, 'USER_AVATAR'); } /** -- cgit v1.2.1 From b5544b2f471ce4c93b08d19919ab062725545ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gae=CC=88tan=20Muller?= Date: Sat, 3 Jan 2015 11:39:29 +0100 Subject: [ticket/13450] Type-hint return value of $phpbb_container->get() PHPBB3-13450 --- phpBB/phpbb/auth/auth.php | 1 + phpBB/phpbb/auth/provider/db.php | 1 + phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php | 1 + phpBB/phpbb/db/migration/profilefield_base_migration.php | 2 ++ phpBB/phpbb/session.php | 4 ++++ 5 files changed, 9 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php index b59f0e60ec..92c19fd5f7 100644 --- a/phpBB/phpbb/auth/auth.php +++ b/phpBB/phpbb/auth/auth.php @@ -929,6 +929,7 @@ class auth { global $db, $user, $phpbb_root_path, $phpEx, $phpbb_container; + /* @var $provider_collection \phpbb\auth\provider_collection */ $provider_collection = $phpbb_container->get('auth.provider_collection'); $provider = $provider_collection->get_provider(); diff --git a/phpBB/phpbb/auth/provider/db.php b/phpBB/phpbb/auth/provider/db.php index d8c5fb72de..1adf85ee05 100644 --- a/phpBB/phpbb/auth/provider/db.php +++ b/phpBB/phpbb/auth/provider/db.php @@ -155,6 +155,7 @@ class db extends \phpbb\auth\provider\base // Every auth module is able to define what to do by itself... if ($show_captcha) { + /* @var $captcha_factory \phpbb\captcha\factory */ $captcha_factory = $this->phpbb_container->get('captcha.factory'); $captcha = $captcha_factory->get_instance($this->config['captcha_plugin']); $captcha->init(CONFIRM_LOGIN); diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php index 2cc7786046..20543463ab 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php @@ -57,6 +57,7 @@ class release_3_0_5_rc1 extends \phpbb\db\migration\migration { global $phpbb_container; + /* @var $passwords_manager \phpbb\passwords\manager */ $passwords_manager = $phpbb_container->get('passwords.manager'); $sql = 'SELECT user_id, user_password FROM ' . $this->table_prefix . 'users diff --git a/phpBB/phpbb/db/migration/profilefield_base_migration.php b/phpBB/phpbb/db/migration/profilefield_base_migration.php index 9000949a7d..bc3d2e9ee5 100644 --- a/phpBB/phpbb/db/migration/profilefield_base_migration.php +++ b/phpBB/phpbb/db/migration/profilefield_base_migration.php @@ -238,6 +238,8 @@ abstract class profilefield_base_migration extends \phpbb\db\migration\migration if ($profile_row === null) { global $phpbb_container; + + /* @var $manager \phpbb\profilefields\manager */ $manager = $phpbb_container->get('profilefields.manager'); $profile_row = $manager->build_insert_sql_array(array()); } diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 0a6a18ffbe..5b9fb6d835 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -409,6 +409,7 @@ class session $session_expired = false; // Check whether the session is still valid if we have one + /* @var $provider_collection \phpbb\auth\provider_collection */ $provider_collection = $phpbb_container->get('auth.provider_collection'); $provider = $provider_collection->get_provider(); @@ -578,6 +579,7 @@ class session } } + /* @var $provider_collection \phpbb\auth\provider_collection */ $provider_collection = $phpbb_container->get('auth.provider_collection'); $provider = $provider_collection->get_provider(); $this->data = $provider->autologin(); @@ -910,6 +912,7 @@ class session $db->sql_query($sql); // Allow connecting logout with external auth method logout + /* @var $provider_collection \phpbb\auth\provider_collection */ $provider_collection = $phpbb_container->get('auth.provider_collection'); $provider = $provider_collection->get_provider(); $provider->logout($this->data, $new_session); @@ -1036,6 +1039,7 @@ class session } // only called from CRON; should be a safe workaround until the infrastructure gets going + /* @var $captcha_factory \phpbb\captcha\factory */ $captcha_factory = $phpbb_container->get('captcha.factory'); $captcha_factory->garbage_collect($config['captcha_plugin']); -- cgit v1.2.1 From 6842831d6baa59425ec83cc2ebbae377942824ce Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 17 Jan 2015 11:05:18 +0100 Subject: [ticket/13513] Use paths relative to the phpBB root in the router PHPBB3-13513 --- phpBB/phpbb/extension/manager.php | 17 +++++++++++------ phpBB/phpbb/routing/router.php | 14 +++++++------- 2 files changed, 18 insertions(+), 13 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 76f0e3558e..880973d5fb 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -464,15 +464,17 @@ class manager * All enabled and disabled extensions are considered configured. A purged * extension that is no longer in the database is not configured. * + * @param bool $phpbb_relative Whether the path should be relative to phpbb root + * * @return array An array with extension names as keys and and the * database stored extension information as values */ - public function all_configured() + public function all_configured($phpbb_relative = true) { $configured = array(); foreach ($this->extensions as $name => $data) { - $data['ext_path'] = $this->phpbb_root_path . $data['ext_path']; + $data['ext_path'] = ($phpbb_relative ? $this->phpbb_root_path : '') . $data['ext_path']; $configured[$name] = $data; } return $configured; @@ -480,18 +482,19 @@ class manager /** * Retrieves all enabled extensions. + * @param bool $phpbb_relative Whether the path should be relative to phpbb root * * @return array An array with extension names as keys and and the * database stored extension information as values */ - public function all_enabled() + public function all_enabled($phpbb_relative = true) { $enabled = array(); foreach ($this->extensions as $name => $data) { if ($data['ext_active']) { - $enabled[$name] = $this->phpbb_root_path . $data['ext_path']; + $enabled[$name] = ($phpbb_relative ? $this->phpbb_root_path : '') . $data['ext_path']; } } return $enabled; @@ -500,17 +503,19 @@ class manager /** * Retrieves all disabled extensions. * + * @param bool $phpbb_relative Whether the path should be relative to phpbb root + * * @return array An array with extension names as keys and and the * database stored extension information as values */ - public function all_disabled() + public function all_disabled($phpbb_relative = true) { $disabled = array(); foreach ($this->extensions as $name => $data) { if (!$data['ext_active']) { - $disabled[$name] = $this->phpbb_root_path . $data['ext_path']; + $disabled[$name] = ($phpbb_relative ? $this->phpbb_root_path : '') . $data['ext_path']; } } return $disabled; diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 1003708540..601d774129 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -106,25 +106,25 @@ class router implements RouterInterface /** * Find the list of routing files * - * @param array $paths Array of paths where to look for routing files. + * @param array $paths Array of paths where to look for routing files (they must be relative to the phpBB root path). * @return router */ public function find_routing_files(array $paths) { - $this->routing_files = array($this->phpbb_root_path . 'config/' . $this->environment . '/routing/environment.yml'); + $this->routing_files = array('config/' . $this->environment . '/routing/environment.yml'); foreach ($paths as $path) { - if (file_exists($path . 'config/' . $this->environment . '/routing/environment.yml')) + if (file_exists($this->phpbb_root_path . $path . 'config/' . $this->environment . '/routing/environment.yml')) { $this->routing_files[] = $path . 'config/' . $this->environment . '/routing/environment.yml'; } - else if (!is_dir($path . 'config/' . $this->environment)) + else if (!is_dir($this->phpbb_root_path . $path . 'config/' . $this->environment)) { - if (file_exists($path . 'config/default/routing/environment.yml')) + if (file_exists($this->phpbb_root_path . $path . 'config/default/routing/environment.yml')) { $this->routing_files[] = $path . 'config/default/routing/environment.yml'; } - else if (!is_dir($path . 'config/default/routing') && file_exists($path . 'config/routing.yml')) + else if (!is_dir($this->phpbb_root_path . $path . 'config/default/routing') && file_exists($this->phpbb_root_path . $path . 'config/routing.yml')) { $this->routing_files[] = $path . 'config/routing.yml'; } @@ -164,7 +164,7 @@ class router implements RouterInterface { if ($this->route_collection == null || empty($this->routing_files)) { - $this->find_routing_files($this->extension_manager->all_enabled()) + $this->find_routing_files($this->extension_manager->all_enabled(false)) ->find($this->phpbb_root_path); } -- cgit v1.2.1 From 7fc586080bf5e7b6e90dcf44526200d7c9356d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gae=CC=88tan=20Muller?= Date: Mon, 5 Jan 2015 22:21:31 +0100 Subject: [ticket/13468] Update calls to `add_log()` PHPBB3-13468 --- phpBB/phpbb/captcha/plugins/gd.php | 4 ++-- phpBB/phpbb/captcha/plugins/qa.php | 4 ++-- phpBB/phpbb/captcha/plugins/recaptcha.php | 4 ++-- phpBB/phpbb/cron/task/core/tidy_plupload.php | 8 ++++---- phpBB/phpbb/db/migration/tool/module.php | 4 +++- phpBB/phpbb/log/log.php | 8 ++++---- phpBB/phpbb/log/log_interface.php | 16 ++++++++-------- phpBB/phpbb/search/fulltext_sphinx.php | 4 +++- phpBB/phpbb/session.php | 13 ++++++++++--- 9 files changed, 38 insertions(+), 27 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/captcha/plugins/gd.php b/phpBB/phpbb/captcha/plugins/gd.php index f6200b5b2f..129fc0c907 100644 --- a/phpBB/phpbb/captcha/plugins/gd.php +++ b/phpBB/phpbb/captcha/plugins/gd.php @@ -53,7 +53,7 @@ class gd extends captcha_abstract function acp_page($id, &$module) { - global $db, $user, $auth, $template; + global $db, $user, $auth, $template, $phpbb_log; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/board'); @@ -84,7 +84,7 @@ class gd extends captcha_abstract } } - add_log('admin', 'LOG_CONFIG_VISUAL'); + $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_VISUAL'); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action)); } else if ($submit) diff --git a/phpBB/phpbb/captcha/plugins/qa.php b/phpBB/phpbb/captcha/plugins/qa.php index ca242a96dc..a545cccbac 100644 --- a/phpBB/phpbb/captcha/plugins/qa.php +++ b/phpBB/phpbb/captcha/plugins/qa.php @@ -611,7 +611,7 @@ class qa */ function acp_page($id, &$module) { - global $db, $user, $auth, $template; + global $db, $user, $auth, $template, $phpbb_log; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/board'); @@ -742,7 +742,7 @@ class qa $this->acp_add_question($data); } - add_log('admin', 'LOG_CONFIG_VISUAL'); + $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_VISUAL'); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($list_url)); } } diff --git a/phpBB/phpbb/captcha/plugins/recaptcha.php b/phpBB/phpbb/captcha/plugins/recaptcha.php index 584f3afec1..a335dedfce 100644 --- a/phpBB/phpbb/captcha/plugins/recaptcha.php +++ b/phpBB/phpbb/captcha/plugins/recaptcha.php @@ -75,7 +75,7 @@ class recaptcha extends captcha_abstract function acp_page($id, &$module) { - global $config, $db, $template, $user; + global $config, $db, $template, $user, $phpbb_log; $captcha_vars = array( 'recaptcha_pubkey' => 'RECAPTCHA_PUBKEY', @@ -101,7 +101,7 @@ class recaptcha extends captcha_abstract } } - add_log('admin', 'LOG_CONFIG_VISUAL'); + $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_VISUAL'); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action)); } else if ($submit) diff --git a/phpBB/phpbb/cron/task/core/tidy_plupload.php b/phpBB/phpbb/cron/task/core/tidy_plupload.php index b6aeecf4b4..d7364374af 100644 --- a/phpBB/phpbb/cron/task/core/tidy_plupload.php +++ b/phpBB/phpbb/cron/task/core/tidy_plupload.php @@ -67,6 +67,8 @@ class tidy_plupload extends \phpbb\cron\task\base */ public function run() { + global $user, $phpbb_log; + // Remove old temporary file (perhaps failed uploads?) $last_valid_timestamp = time() - $this->max_file_age; try @@ -88,13 +90,11 @@ class tidy_plupload extends \phpbb\cron\task\base } catch (\UnexpectedValueException $e) { - add_log( - 'critical', - 'LOG_PLUPLOAD_TIDY_FAILED', + $phpbb_log->add('critical', $user->data['user_id'], $user->ip, 'LOG_PLUPLOAD_TIDY_FAILED', false, array( $this->plupload_upload_path, $e->getMessage(), $e->getTraceAsString() - ); + )); } $this->config->set('plupload_last_gc', time(), true); diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 035625b095..b6f0372181 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -171,6 +171,8 @@ class module implements \phpbb\db\migration\tool\tool_interface */ public function add($class, $parent = 0, $data = array()) { + global $user, $phpbb_log; + // Allows '' to be sent as 0 $parent = $parent ?: 0; @@ -266,7 +268,7 @@ class module implements \phpbb\db\migration\tool\tool_interface { // Success $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); + $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_ADD', false, array($module_log_name)); // Move the module if requested above/below an existing one if (isset($data['before']) && $data['before']) diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php index 0c5205530b..4bb2e7a75a 100644 --- a/phpBB/phpbb/log/log.php +++ b/phpBB/phpbb/log/log.php @@ -27,7 +27,7 @@ class log implements \phpbb\log\log_interface /** * An array with the disabled log types. Logs of such types will not be - * added when add_log() is called. + * added when add() is called. * @var array */ protected $disabled_types; @@ -223,14 +223,14 @@ class log implements \phpbb\log\log_interface return false; } - if ($log_time == false) + if ($log_time === false) { $log_time = time(); } $sql_ary = array( - 'user_id' => $user_id, - 'log_ip' => $log_ip, + 'user_id' => $user_id ? (int) $user_id : ANONYMOUS, + 'log_ip' => empty($log_ip) ? '' : $log_ip, 'log_time' => $log_time, 'log_operation' => $log_operation, ); diff --git a/phpBB/phpbb/log/log_interface.php b/phpBB/phpbb/log/log_interface.php index 5932f722aa..86286e6f88 100644 --- a/phpBB/phpbb/log/log_interface.php +++ b/phpBB/phpbb/log/log_interface.php @@ -32,8 +32,8 @@ interface log_interface * Disable log * * This function allows disabling the log system or parts of it, for this - * page call. When add_log is called and the type is disabled, - * the log will not be added to the database. + * page call. When add() is called and the type is disabled, the log will + * not be added to the database. * * @param mixed $type The log type we want to disable. Empty to * disable all logs. Can also be an array of types. @@ -57,12 +57,12 @@ interface log_interface /** * Adds a log entry to the database * - * @param string $mode The mode defines which log_type is used and from which log the entry is retrieved - * @param int $user_id User ID of the user - * @param string $log_ip IP address of the user - * @param string $log_operation Name of the operation - * @param int $log_time Timestamp when the log entry was added, if empty time() will be used - * @param array $additional_data More arguments can be added, depending on the log_type + * @param string $mode The mode defines which log_type is used and from which log the entry is retrieved + * @param int $user_id User ID of the user + * @param string $log_ip IP address of the user + * @param string $log_operation Name of the operation + * @param int|bool $log_time Timestamp when the log entry was added. If false, time() will be used + * @param array $additional_data More arguments can be added, depending on the log_type * * @return int|bool Returns the log_id, if the entry was added to the database, false otherwise. */ diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index 2765d05b94..c62bacf470 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -454,6 +454,8 @@ class fulltext_sphinx */ public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { + global $user, $phpbb_log; + // No keywords? No posts. if (!strlen($this->search_query) && !sizeof($author_ary)) { @@ -601,7 +603,7 @@ class fulltext_sphinx if ($this->sphinx->GetLastError()) { - add_log('critical', 'LOG_SPHINX_ERROR', $this->sphinx->GetLastError()); + $phpbb_log->add('critical', $user->data['user_id'], $user->ip, 'LOG_SPHINX_ERROR', false, array($this->sphinx->GetLastError())); if ($this->auth->acl_get('a_')) { trigger_error($this->user->lang('SPHINX_SEARCH_FAILED', $this->sphinx->GetLastError())); diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 5b9fb6d835..114912b2aa 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -215,7 +215,7 @@ class session function session_begin($update_session_page = true) { global $phpEx, $SID, $_SID, $_EXTRA_URL, $db, $config, $phpbb_root_path; - global $request, $phpbb_container; + global $request, $phpbb_container, $user, $phpbb_log; // Give us some basic information $this->time_now = time(); @@ -490,11 +490,18 @@ class session { if ($referer_valid) { - add_log('critical', 'LOG_IP_BROWSER_FORWARDED_CHECK', $u_ip, $s_ip, $u_browser, $s_browser, htmlspecialchars($u_forwarded_for), htmlspecialchars($s_forwarded_for)); + $phpbb_log->add('critical', $user->data['user_id'], $user->ip, 'LOG_IP_BROWSER_FORWARDED_CHECK', false, array( + $u_ip, + $s_ip, + $u_browser, + $s_browser, + htmlspecialchars($u_forwarded_for), + htmlspecialchars($s_forwarded_for) + )); } else { - add_log('critical', 'LOG_REFERER_INVALID', $this->referer); + $phpbb_log->add('critical', $user->data['user_id'], $user->ip, 'LOG_REFERER_INVALID', false, array($this->referer)); } } } -- cgit v1.2.1 From a62adfc1157d6b071f013f9a5f34ccc86ea39220 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 29 Jan 2015 01:41:28 -0800 Subject: [ticket/10388] Use TWIG escape JS filter instead of addslashes PHPBB3-10388 --- phpBB/phpbb/template/twig/extension.php | 4 ++-- phpBB/phpbb/template/twig/lexer.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index 3a983491b9..2eb5370b59 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -71,7 +71,7 @@ class extension extends \Twig_Extension { return array( new \Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), - new \Twig_SimpleFilter('addslashes', 'addslashes'), + new \Twig_SimpleFilter('addslashes', 'addslashes'), // Deprecate addslashes in phpBB 3.1.4 ); } @@ -177,7 +177,7 @@ class extension extends \Twig_Extension return $context_vars['L_' . $key]; } - // LA_ is transformed into lang(\'$1\')|addslashes, so we should not + // LA_ is transformed into lang(\'$1\')|escape('js'), so we should not // need to check for it return call_user_func_array(array($this->user, 'lang'), $args); diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php index a7848738bb..f1542109a4 100644 --- a/phpBB/phpbb/template/twig/lexer.php +++ b/phpBB/phpbb/template/twig/lexer.php @@ -117,9 +117,9 @@ class lexer extends \Twig_Lexer // Appends any filters after lang() $code = preg_replace('#{L_([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ lang(\'$1\')$2 }}', $code); - // Replace all of our escaped language variables, {LA_VARNAME}, with Twig style, {{ lang('NAME')|addslashes }} - // Appends any filters after lang(), but before addslashes - $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ lang(\'$1\')$2|addslashes }}', $code); + // Replace all of our escaped language variables, {LA_VARNAME}, with Twig style, {{ lang('NAME')|escape('js') }} + // Appends any filters after lang(), but before escape('js') + $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ lang(\'$1\')$2|escape(\'js\') }}', $code); // Replace all of our variables, {VARNAME}, with Twig style, {{ VARNAME }} // Appends any filters -- cgit v1.2.1 From 5b7d1f1b437a166b893413e1196a2a3da3b334fb Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 29 Jan 2015 01:44:45 -0800 Subject: [ticket/10388] Update deprecation date for addslashes PHPBB3-10388 --- phpBB/phpbb/template/twig/extension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index 2eb5370b59..c8c8be5142 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -71,7 +71,7 @@ class extension extends \Twig_Extension { return array( new \Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), - new \Twig_SimpleFilter('addslashes', 'addslashes'), // Deprecate addslashes in phpBB 3.1.4 + new \Twig_SimpleFilter('addslashes', 'addslashes'), // Deprecated 3.2.0 ); } -- cgit v1.2.1 From 9f4c2effe9a9b8a497a3f00dc8a6d71e745c7ea9 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sat, 31 Jan 2015 01:11:28 -0800 Subject: [ticket/10388] Update deprecation comment PHPBB3-10388 --- phpBB/phpbb/template/twig/extension.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index c8c8be5142..14d1258c09 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -71,7 +71,8 @@ class extension extends \Twig_Extension { return array( new \Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), - new \Twig_SimpleFilter('addslashes', 'addslashes'), // Deprecated 3.2.0 + // @deprecated 3.2.0 Uses twig's JS escape method instead of addslashes + new \Twig_SimpleFilter('addslashes', 'addslashes'), ); } -- cgit v1.2.1 From 79d4ff553844fa80be4da9286239f62a45489072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gae=CC=88tan=20Muller?= Date: Sun, 11 Jan 2015 17:32:31 +0100 Subject: [ticket/13494] Update calls to `set_config()` PHPBB3-13494 --- phpBB/phpbb/cache/driver/eaccelerator.php | 4 +++- phpBB/phpbb/cache/driver/file.php | 4 ++-- phpBB/phpbb/cache/driver/memory.php | 5 +++-- phpBB/phpbb/cache/driver/null.php | 4 +++- phpBB/phpbb/captcha/plugins/gd.php | 2 +- phpBB/phpbb/captcha/plugins/recaptcha.php | 2 +- phpBB/phpbb/db/migration/data/v310/style_update_p1.php | 4 +++- phpBB/phpbb/search/fulltext_mysql.php | 6 +++--- phpBB/phpbb/search/fulltext_native.php | 6 +++--- phpBB/phpbb/search/fulltext_postgres.php | 2 +- phpBB/phpbb/search/fulltext_sphinx.php | 6 +++--- phpBB/phpbb/session.php | 6 +++--- 12 files changed, 29 insertions(+), 22 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/eaccelerator.php b/phpBB/phpbb/cache/driver/eaccelerator.php index 1697758acc..740855144f 100644 --- a/phpBB/phpbb/cache/driver/eaccelerator.php +++ b/phpBB/phpbb/cache/driver/eaccelerator.php @@ -44,9 +44,11 @@ class eaccelerator extends \phpbb\cache\driver\memory */ function tidy() { + global $config; + eaccelerator_gc(); - set_config('cache_last_gc', time(), true); + $config->set('cache_last_gc', time(), false); } /** diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index 114959c06c..9c63d0010c 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -95,7 +95,7 @@ class file extends \phpbb\cache\driver\base */ function tidy() { - global $phpEx; + global $config, $phpEx; $dir = @opendir($this->cache_dir); @@ -149,7 +149,7 @@ class file extends \phpbb\cache\driver\base } } - set_config('cache_last_gc', time(), true); + $config->set('cache_last_gc', time(), false); } /** diff --git a/phpBB/phpbb/cache/driver/memory.php b/phpBB/phpbb/cache/driver/memory.php index 0cef9c3483..baae22d809 100644 --- a/phpBB/phpbb/cache/driver/memory.php +++ b/phpBB/phpbb/cache/driver/memory.php @@ -81,9 +81,10 @@ abstract class memory extends \phpbb\cache\driver\base */ function tidy() { - // cache has auto GC, no need to have any code here :) + global $config; - set_config('cache_last_gc', time(), true); + // cache has auto GC, no need to have any code here :) + $config->set('cache_last_gc', time(), false); } /** diff --git a/phpBB/phpbb/cache/driver/null.php b/phpBB/phpbb/cache/driver/null.php index a45cf97862..298731ea54 100644 --- a/phpBB/phpbb/cache/driver/null.php +++ b/phpBB/phpbb/cache/driver/null.php @@ -52,8 +52,10 @@ class null extends \phpbb\cache\driver\base */ function tidy() { + global $config; + // This cache always has a tidy room. - set_config('cache_last_gc', time(), true); + $config->set('cache_last_gc', time(), false); } /** diff --git a/phpBB/phpbb/captcha/plugins/gd.php b/phpBB/phpbb/captcha/plugins/gd.php index 129fc0c907..5fe94af9df 100644 --- a/phpBB/phpbb/captcha/plugins/gd.php +++ b/phpBB/phpbb/captcha/plugins/gd.php @@ -80,7 +80,7 @@ class gd extends captcha_abstract $value = request_var($captcha_var, 0); if ($value >= 0) { - set_config($captcha_var, $value); + $config->set($captcha_var, $value); } } diff --git a/phpBB/phpbb/captcha/plugins/recaptcha.php b/phpBB/phpbb/captcha/plugins/recaptcha.php index a335dedfce..369c84e7df 100644 --- a/phpBB/phpbb/captcha/plugins/recaptcha.php +++ b/phpBB/phpbb/captcha/plugins/recaptcha.php @@ -97,7 +97,7 @@ class recaptcha extends captcha_abstract $value = request_var($captcha_var, ''); if ($value) { - set_config($captcha_var, $value); + $config->set($captcha_var, $value); } } diff --git a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php index e8d3a3af64..918a565e06 100644 --- a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php +++ b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php @@ -62,6 +62,8 @@ class style_update_p1 extends \phpbb\db\migration\migration public function styles_update() { + global $config; + // Get list of valid 3.1 styles $available_styles = array('prosilver'); @@ -163,7 +165,7 @@ class style_update_p1 extends \phpbb\db\migration\migration $default_style = $this->db->sql_fetchfield($result); $this->db->sql_freeresult($result); - set_config('default_style', $default_style); + $config->set('default_style', $default_style); $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = 0'; $this->sql_query($sql); diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index 1a0aba096f..da9de56009 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -188,8 +188,8 @@ class fulltext_mysql extends \phpbb\search\base } $this->db->sql_freeresult($result); - set_config('fulltext_mysql_max_word_len', $mysql_info['ft_max_word_len']); - set_config('fulltext_mysql_min_word_len', $mysql_info['ft_min_word_len']); + $this->config->set('fulltext_mysql_max_word_len', $mysql_info['ft_max_word_len']); + $this->config->set('fulltext_mysql_min_word_len', $mysql_info['ft_min_word_len']); return false; } @@ -745,7 +745,7 @@ class fulltext_mysql extends \phpbb\search\base // destroy too old cached search results $this->destroy_cache(array()); - set_config('search_last_gc', time(), true); + $this->config->set('search_last_gc', time(), false); } /** diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index cb681ec270..b18015ba1a 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -1425,7 +1425,7 @@ class fulltext_native extends \phpbb\search\base // carry on ... it's okay ... I know when I'm not wanted boo hoo if (!$this->config['fulltext_native_load_upd']) { - set_config('search_last_gc', time(), true); + $this->config->set('search_last_gc', time(), false); return; } @@ -1460,7 +1460,7 @@ class fulltext_native extends \phpbb\search\base // by setting search_last_gc to the new time here we make sure that if a user reloads because the // following query takes too long, he won't run into it again - set_config('search_last_gc', time(), true); + $this->config->set('search_last_gc', time(), false); // Delete the matches $sql = 'DELETE FROM ' . SEARCH_WORDMATCH_TABLE . ' @@ -1476,7 +1476,7 @@ class fulltext_native extends \phpbb\search\base $this->destroy_cache(array_unique($destroy_cache_words)); } - set_config('search_last_gc', time(), true); + $this->config->set('search_last_gc', time(), false); } /** diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php index b6af371d13..5a68f0cbfb 100644 --- a/phpBB/phpbb/search/fulltext_postgres.php +++ b/phpBB/phpbb/search/fulltext_postgres.php @@ -746,7 +746,7 @@ class fulltext_postgres extends \phpbb\search\base // destroy too old cached search results $this->destroy_cache(array()); - set_config('search_last_gc', time(), true); + $this->config->set('search_last_gc', time(), false); } /** diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index c62bacf470..0be646ff06 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -140,7 +140,7 @@ class fulltext_sphinx if(!$this->config['fulltext_sphinx_id']) { - set_config('fulltext_sphinx_id', unique_id()); + $this->config->set('fulltext_sphinx_id', unique_id()); } $this->id = $this->config['fulltext_sphinx_id']; $this->indexes = 'index_phpbb_' . $this->id . '_delta;index_phpbb_' . $this->id . '_main'; @@ -211,7 +211,7 @@ class fulltext_sphinx } // Move delta to main index each hour - set_config('search_gc', 3600); + $this->config->set('search_gc', 3600); return false; } @@ -757,7 +757,7 @@ class fulltext_sphinx */ public function tidy($create = false) { - set_config('search_last_gc', time(), true); + $this->config->set('search_last_gc', time(), false); } /** diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 114912b2aa..6f68dbf203 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -345,8 +345,8 @@ class session } else { - set_config('limit_load', '0'); - set_config('limit_search_load', '0'); + $config->set('limit_load', '0'); + $config->set('limit_search_load', '0'); } } @@ -1036,7 +1036,7 @@ class session { // Less than 10 users, update gc timer ... else we want gc // called again to delete other sessions - set_config('session_last_gc', $this->time_now, true); + $config->set('session_last_gc', $this->time_now, false); if ($config['max_autologin_time']) { -- cgit v1.2.1 From f4b42c961f5729b0bbadca8a897410f890228364 Mon Sep 17 00:00:00 2001 From: Nicofuma Date: Tue, 3 Feb 2015 12:41:31 +0100 Subject: [ticket/13139] Fix tests PHPBB3-13139 --- phpBB/phpbb/template/asset.php | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php index 67dbd7b357..4729685459 100644 --- a/phpBB/phpbb/template/asset.php +++ b/phpBB/phpbb/template/asset.php @@ -152,6 +152,12 @@ class asset */ public function set_path($path, $urlencode = false) { + // Since 1.7.0 Twig returns the real path of the file. We need it to be relative to the working directory. + $real_root_path = realpath('.') . DIRECTORY_SEPARATOR; + if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) { + $path = str_replace('\\', '/', substr($path, strlen($real_root_path))); + } + if ($urlencode) { $paths = explode('/', $path); @@ -161,6 +167,7 @@ class asset } $path = implode('/', $paths); } + $this->components['path'] = $path; } -- cgit v1.2.1 From f6e06da4c68917dafb057bf7fe19f884a3e148c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gae=CC=88tan=20Muller?= Date: Sun, 4 Jan 2015 20:41:04 +0100 Subject: [ticket/13455] Update calls to `request_var()` PHPBB3-13455 --- phpBB/phpbb/captcha/plugins/captcha_abstract.php | 14 +++++---- phpBB/phpbb/captcha/plugins/gd.php | 12 +++---- phpBB/phpbb/captcha/plugins/qa.php | 40 +++++++++++++----------- phpBB/phpbb/captcha/plugins/recaptcha.php | 14 ++++----- phpBB/phpbb/profilefields/type/type_date.php | 2 +- phpBB/phpbb/session.php | 12 +++---- 6 files changed, 50 insertions(+), 44 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/captcha/plugins/captcha_abstract.php b/phpBB/phpbb/captcha/plugins/captcha_abstract.php index 24ed7f939d..2c0b95411e 100644 --- a/phpBB/phpbb/captcha/plugins/captcha_abstract.php +++ b/phpBB/phpbb/captcha/plugins/captcha_abstract.php @@ -34,12 +34,12 @@ abstract class captcha_abstract function init($type) { - global $config, $db, $user; + global $config, $db, $user, $request; // read input - $this->confirm_id = request_var('confirm_id', ''); - $this->confirm_code = request_var('confirm_code', ''); - $refresh = request_var('refresh_vc', false) && $config['confirm_refresh']; + $this->confirm_id = $request->variable('confirm_id', ''); + $this->confirm_code = $request->variable('confirm_code', ''); + $refresh = $request->variable('refresh_vc', false) && $config['confirm_refresh']; $this->type = (int) $type; @@ -125,7 +125,7 @@ abstract class captcha_abstract { foreach ($this->captcha_vars as $captcha_var => $template_var) { - $variables .= '&' . rawurlencode($captcha_var) . '=' . request_var($captcha_var, (int) $config[$captcha_var]); + $variables .= '&' . rawurlencode($captcha_var) . '=' . $request->variable($captcha_var, (int) $config[$captcha_var]); } } @@ -350,7 +350,9 @@ abstract class captcha_abstract function is_solved() { - if (request_var('confirm_code', false) && $this->solved === 0) + global $request; + + if ($request->variable('confirm_code', false) && $this->solved === 0) { $this->validate(); } diff --git a/phpBB/phpbb/captcha/plugins/gd.php b/phpBB/phpbb/captcha/plugins/gd.php index 5fe94af9df..1727dcc1bb 100644 --- a/phpBB/phpbb/captcha/plugins/gd.php +++ b/phpBB/phpbb/captcha/plugins/gd.php @@ -53,7 +53,7 @@ class gd extends captcha_abstract function acp_page($id, &$module) { - global $db, $user, $auth, $template, $phpbb_log; + global $db, $user, $auth, $template, $phpbb_log, $request; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/board'); @@ -70,14 +70,14 @@ class gd extends captcha_abstract $form_key = 'acp_captcha'; add_form_key($form_key); - $submit = request_var('submit', ''); + $submit = $request->variable('submit', ''); if ($submit && check_form_key($form_key)) { $captcha_vars = array_keys($this->captcha_vars); foreach ($captcha_vars as $captcha_var) { - $value = request_var($captcha_var, 0); + $value = $request->variable($captcha_var, 0); if ($value >= 0) { $config->set($captcha_var, $value); @@ -95,7 +95,7 @@ class gd extends captcha_abstract { foreach ($this->captcha_vars as $captcha_var => $template_var) { - $var = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, 0) : $config[$captcha_var]; + $var = (isset($_REQUEST[$captcha_var])) ? $request->variable($captcha_var, 0) : $config[$captcha_var]; $template->assign_var($template_var, $var); } @@ -109,7 +109,7 @@ class gd extends captcha_abstract function execute_demo() { - global $config; + global $config, $request; $config_old = $config; @@ -121,7 +121,7 @@ class gd extends captcha_abstract foreach ($this->captcha_vars as $captcha_var => $template_var) { - $config->set($captcha_var, request_var($captcha_var, (int) $config[$captcha_var])); + $config->set($captcha_var, $request->variable($captcha_var, (int) $config[$captcha_var])); } parent::execute_demo(); $config = $config_old; diff --git a/phpBB/phpbb/captcha/plugins/qa.php b/phpBB/phpbb/captcha/plugins/qa.php index a545cccbac..657cfe9217 100644 --- a/phpBB/phpbb/captcha/plugins/qa.php +++ b/phpBB/phpbb/captcha/plugins/qa.php @@ -58,14 +58,14 @@ class qa */ function init($type) { - global $config, $db, $user; + global $config, $db, $user, $request; // load our language file $user->add_lang('captcha_qa'); // read input - $this->confirm_id = request_var('qa_confirm_id', ''); - $this->answer = utf8_normalize_nfc(request_var('qa_answer', '', true)); + $this->confirm_id = $request->variable('qa_confirm_id', ''); + $this->answer = utf8_normalize_nfc($request->variable('qa_answer', '', true)); $this->type = (int) $type; $this->question_lang = $user->lang_name; @@ -544,9 +544,9 @@ class qa */ function check_answer() { - global $db; + global $db, $request; - $answer = ($this->question_strict) ? utf8_normalize_nfc(request_var('qa_answer', '', true)) : utf8_clean_string(utf8_normalize_nfc(request_var('qa_answer', '', true))); + $answer = ($this->question_strict) ? utf8_normalize_nfc($request->variable('qa_answer', '', true)) : utf8_clean_string(utf8_normalize_nfc($request->variable('qa_answer', '', true))); $sql = 'SELECT answer_text FROM ' . $this->table_captcha_answers . ' @@ -598,7 +598,9 @@ class qa */ function is_solved() { - if (request_var('qa_answer', false) && $this->solved === 0) + global $request; + + if ($request->variable('qa_answer', false) && $this->solved === 0) { $this->validate(); } @@ -611,7 +613,7 @@ class qa */ function acp_page($id, &$module) { - global $db, $user, $auth, $template, $phpbb_log; + global $db, $user, $auth, $template, $phpbb_log, $request; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/board'); @@ -627,9 +629,9 @@ class qa $form_key = 'acp_captcha'; add_form_key($form_key); - $submit = request_var('submit', false); - $question_id = request_var('question_id', 0); - $action = request_var('action', ''); + $submit = $request->variable('submit', false); + $question_id = $request->variable('question_id', 0); + $action = $request->variable('action', ''); // we have two pages, so users might want to navigate from one to the other $list_url = $module->u_action . "&configure=1&select_captcha=" . $this->get_service_name(); @@ -675,10 +677,10 @@ class qa { // okay, show the editor $error = false; - $input_question = request_var('question_text', '', true); - $input_answers = request_var('answers', '', true); - $input_lang = request_var('lang_iso', '', true); - $input_strict = request_var('strict', false); + $input_question = $request->variable('question_text', '', true); + $input_answers = $request->variable('answers', '', true); + $input_lang = $request->variable('lang_iso', '', true); + $input_strict = $request->variable('strict', false); $langs = $this->get_languages(); foreach ($langs as $lang => $entry) @@ -826,11 +828,13 @@ class qa */ function acp_get_question_input() { - $answers = utf8_normalize_nfc(request_var('answers', '', true)); + global $request; + + $answers = utf8_normalize_nfc($request->variable('answers', '', true)); $question = array( - 'question_text' => request_var('question_text', '', true), - 'strict' => request_var('strict', false), - 'lang_iso' => request_var('lang_iso', ''), + 'question_text' => $request->variable('question_text', '', true), + 'strict' => $request->variable('strict', false), + 'lang_iso' => $request->variable('lang_iso', ''), 'answers' => (strlen($answers)) ? explode("\n", $answers) : '', ); diff --git a/phpBB/phpbb/captcha/plugins/recaptcha.php b/phpBB/phpbb/captcha/plugins/recaptcha.php index 369c84e7df..98132ab47d 100644 --- a/phpBB/phpbb/captcha/plugins/recaptcha.php +++ b/phpBB/phpbb/captcha/plugins/recaptcha.php @@ -37,12 +37,12 @@ class recaptcha extends captcha_abstract function init($type) { - global $config, $db, $user; + global $config, $db, $user, $request; $user->add_lang('captcha_recaptcha'); parent::init($type); - $this->challenge = request_var('recaptcha_challenge_field', ''); - $this->response = request_var('recaptcha_response_field', ''); + $this->challenge = $request->variable('recaptcha_challenge_field', ''); + $this->response = $request->variable('recaptcha_response_field', ''); } public function is_available() @@ -75,7 +75,7 @@ class recaptcha extends captcha_abstract function acp_page($id, &$module) { - global $config, $db, $template, $user, $phpbb_log; + global $config, $db, $template, $user, $phpbb_log, $request; $captcha_vars = array( 'recaptcha_pubkey' => 'RECAPTCHA_PUBKEY', @@ -87,14 +87,14 @@ class recaptcha extends captcha_abstract $form_key = 'acp_captcha'; add_form_key($form_key); - $submit = request_var('submit', ''); + $submit = $request->variable('submit', ''); if ($submit && check_form_key($form_key)) { $captcha_vars = array_keys($captcha_vars); foreach ($captcha_vars as $captcha_var) { - $value = request_var($captcha_var, ''); + $value = $request->variable($captcha_var, ''); if ($value) { $config->set($captcha_var, $value); @@ -112,7 +112,7 @@ class recaptcha extends captcha_abstract { foreach ($captcha_vars as $captcha_var => $template_var) { - $var = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, '') : ((isset($config[$captcha_var])) ? $config[$captcha_var] : ''); + $var = (isset($_REQUEST[$captcha_var])) ? $request->variable($captcha_var, '') : ((isset($config[$captcha_var])) ? $config[$captcha_var] : ''); $template->assign_var($template_var, $var); } diff --git a/phpBB/phpbb/profilefields/type/type_date.php b/phpBB/phpbb/profilefields/type/type_date.php index 90ac9a6703..414484920b 100644 --- a/phpBB/phpbb/profilefields/type/type_date.php +++ b/phpBB/phpbb/profilefields/type/type_date.php @@ -72,7 +72,7 @@ class type_date extends type_base 'lang_options' => $field_data['lang_options'], ); - $always_now = request_var('always_now', -1); + $always_now = $request->variable('always_now', -1); if ($always_now == -1) { $s_checked = ($field_data['field_default_value'] == 'now') ? true : false; diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 6f68dbf203..6aeb8a91de 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -139,7 +139,7 @@ class session 'root_script_path' => str_replace(' ', '%20', htmlspecialchars($root_script_path)), 'page' => $page, - 'forum' => request_var('f', 0), + 'forum' => $request->variable('f', 0), ); return $page_array; @@ -253,23 +253,23 @@ class session if ($request->is_set($config['cookie_name'] . '_sid', \phpbb\request\request_interface::COOKIE) || $request->is_set($config['cookie_name'] . '_u', \phpbb\request\request_interface::COOKIE)) { - $this->cookie_data['u'] = request_var($config['cookie_name'] . '_u', 0, false, true); - $this->cookie_data['k'] = request_var($config['cookie_name'] . '_k', '', false, true); - $this->session_id = request_var($config['cookie_name'] . '_sid', '', false, true); + $this->cookie_data['u'] = $request->variable($config['cookie_name'] . '_u', 0, false, \phpbb\request\request_interface::COOKIE); + $this->cookie_data['k'] = $request->variable($config['cookie_name'] . '_k', '', false, \phpbb\request\request_interface::COOKIE); + $this->session_id = $request->variable($config['cookie_name'] . '_sid', '', false, \phpbb\request\request_interface::COOKIE); $SID = (defined('NEED_SID')) ? '?sid=' . $this->session_id : '?sid='; $_SID = (defined('NEED_SID')) ? $this->session_id : ''; if (empty($this->session_id)) { - $this->session_id = $_SID = request_var('sid', ''); + $this->session_id = $_SID = $request->variable('sid', ''); $SID = '?sid=' . $this->session_id; $this->cookie_data = array('u' => 0, 'k' => ''); } } else { - $this->session_id = $_SID = request_var('sid', ''); + $this->session_id = $_SID = $request->variable('sid', ''); $SID = '?sid=' . $this->session_id; } -- cgit v1.2.1 From abcb2680eec86dc8016c489ebc7362e29be9e4df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gae=CC=88tan=20Muller?= Date: Mon, 2 Feb 2015 21:35:46 +0100 Subject: [ticket/13455] Remove unnecessary calls to `utf8_normalize_nfc()` PHPBB3-13455 --- phpBB/phpbb/captcha/plugins/qa.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/captcha/plugins/qa.php b/phpBB/phpbb/captcha/plugins/qa.php index 657cfe9217..b4586f1234 100644 --- a/phpBB/phpbb/captcha/plugins/qa.php +++ b/phpBB/phpbb/captcha/plugins/qa.php @@ -65,7 +65,7 @@ class qa // read input $this->confirm_id = $request->variable('qa_confirm_id', ''); - $this->answer = utf8_normalize_nfc($request->variable('qa_answer', '', true)); + $this->answer = $request->variable('qa_answer', '', true); $this->type = (int) $type; $this->question_lang = $user->lang_name; @@ -546,7 +546,7 @@ class qa { global $db, $request; - $answer = ($this->question_strict) ? utf8_normalize_nfc($request->variable('qa_answer', '', true)) : utf8_clean_string(utf8_normalize_nfc($request->variable('qa_answer', '', true))); + $answer = ($this->question_strict) ? $request->variable('qa_answer', '', true) : utf8_clean_string($request->variable('qa_answer', '', true)); $sql = 'SELECT answer_text FROM ' . $this->table_captcha_answers . ' @@ -830,7 +830,7 @@ class qa { global $request; - $answers = utf8_normalize_nfc($request->variable('answers', '', true)); + $answers = $request->variable('answers', '', true); $question = array( 'question_text' => $request->variable('question_text', '', true), 'strict' => $request->variable('strict', false), -- cgit v1.2.1 From 52446c8327426c59da74257885fd09591c9e1fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gae=CC=88tan=20Muller?= Date: Tue, 3 Feb 2015 20:56:48 +0100 Subject: [ticket/13455] Remove `request_var()` references from comments PHPBB3-13455 --- phpBB/phpbb/cron/task/core/prune_forum.php | 2 +- phpBB/phpbb/cron/task/core/prune_shadow_topics.php | 2 +- phpBB/phpbb/request/deactivated_super_global.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cron/task/core/prune_forum.php b/phpBB/phpbb/cron/task/core/prune_forum.php index ba68565197..abf91aee19 100644 --- a/phpBB/phpbb/cron/task/core/prune_forum.php +++ b/phpBB/phpbb/cron/task/core/prune_forum.php @@ -31,7 +31,7 @@ class prune_forum extends \phpbb\cron\task\base implements \phpbb\cron\task\para * If $forum_data is given, it is assumed to contain necessary information * about a single forum that is to be pruned. * - * If $forum_data is not given, forum id will be retrieved via request_var + * If $forum_data is not given, forum id will be retrieved via $request->variable() * and a database query will be performed to load the necessary information * about the forum. */ diff --git a/phpBB/phpbb/cron/task/core/prune_shadow_topics.php b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php index 97a4b0ea86..0ab59f9ed5 100644 --- a/phpBB/phpbb/cron/task/core/prune_shadow_topics.php +++ b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php @@ -33,7 +33,7 @@ class prune_shadow_topics extends \phpbb\cron\task\base implements \phpbb\cron\t * If $forum_data is given, it is assumed to contain necessary information * about a single forum that is to be pruned. * - * If $forum_data is not given, forum id will be retrieved via request_var + * If $forum_data is not given, forum id will be retrieved via $request->variable() * and a database query will be performed to load the necessary information * about the forum. */ diff --git a/phpBB/phpbb/request/deactivated_super_global.php b/phpBB/phpbb/request/deactivated_super_global.php index b6cad59be4..ab56240b14 100644 --- a/phpBB/phpbb/request/deactivated_super_global.php +++ b/phpBB/phpbb/request/deactivated_super_global.php @@ -56,7 +56,7 @@ class deactivated_super_global implements \ArrayAccess, \Countable, \IteratorAgg $file = ''; $line = 0; - $message = 'Illegal use of $' . $this->name . '. You must use the request class or request_var() to access input data. Found in %s on line %d. This error message was generated by deactivated_super_global.'; + $message = 'Illegal use of $' . $this->name . '. You must use the request class to access input data. Found in %s on line %d. This error message was generated by deactivated_super_global.'; $backtrace = debug_backtrace(); if (isset($backtrace[1])) -- cgit v1.2.1 From b8939da2425eb96dff26dbf51d6ead01fbb4901a Mon Sep 17 00:00:00 2001 From: Nicofuma Date: Tue, 3 Feb 2015 17:23:11 +0100 Subject: [ticket/13407] Bump minimal version to php 5.3.9 PHPBB3-13407 --- phpBB/phpbb/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/composer.json b/phpBB/phpbb/composer.json index 513d7e4559..175be4b0ab 100644 --- a/phpBB/phpbb/composer.json +++ b/phpBB/phpbb/composer.json @@ -22,6 +22,6 @@ "classmap": [""] }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" } } -- cgit v1.2.1 From 4ea90ca44d6d274f1ff6e6e3b4821f9e8cd1e9da Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 24 Jan 2015 10:51:59 +0100 Subject: [ticket/10748] Split MS SQL from the db tools file into it's own PHPBB3-10748 --- phpBB/phpbb/db/tools/factory.php | 6 +- phpBB/phpbb/db/tools/mssql.php | 791 +++++++++++++++++++++++++++++++++++++++ phpBB/phpbb/db/tools/tools.php | 636 ++++--------------------------- 3 files changed, 859 insertions(+), 574 deletions(-) create mode 100644 phpBB/phpbb/db/tools/mssql.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/factory.php b/phpBB/phpbb/db/tools/factory.php index 60db2ade03..24e2a4d875 100644 --- a/phpBB/phpbb/db/tools/factory.php +++ b/phpBB/phpbb/db/tools/factory.php @@ -25,7 +25,11 @@ class factory */ public function get($db_driver, $return_statements = false) { - if ($db_driver instanceof \phpbb\db\driver\driver_interface) + if ($db_driver instanceof \phpbb\db\driver\mssql || $db_driver instanceof \phpbb\db\driver\mssql_base) + { + return new \phpbb\db\tools\mssql($db_driver, $return_statements); + } + else if ($db_driver instanceof \phpbb\db\driver\driver_interface) { return new \phpbb\db\tools\tools($db_driver, $return_statements); } diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php new file mode 100644 index 0000000000..b4a09143eb --- /dev/null +++ b/phpBB/phpbb/db/tools/mssql.php @@ -0,0 +1,791 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\tools; + +/** +* Database Tools for handling cross-db actions such as altering columns, etc. +* Currently not supported is returning SQL for creating tables. +*/ +class mssql extends tools +{ + /** + * Is the used MS SQL Server a SQL Server 2000? + * @var bool + */ + protected $is_sql_server_2000; + + /** + * Get the column types for every database we support + * + * @return array + */ + public static function get_dbms_type_map() + { + return array( + 'mssql' => array( + 'INT:' => '[int]', + 'BINT' => '[float]', + 'UINT' => '[int]', + 'UINT:' => '[int]', + 'TINT:' => '[int]', + 'USINT' => '[int]', + 'BOOL' => '[int]', + 'VCHAR' => '[varchar] (255)', + 'VCHAR:' => '[varchar] (%d)', + 'CHAR:' => '[char] (%d)', + 'XSTEXT' => '[varchar] (1000)', + 'STEXT' => '[varchar] (3000)', + 'TEXT' => '[varchar] (8000)', + 'MTEXT' => '[text]', + 'XSTEXT_UNI'=> '[varchar] (100)', + 'STEXT_UNI' => '[varchar] (255)', + 'TEXT_UNI' => '[varchar] (4000)', + 'MTEXT_UNI' => '[text]', + 'TIMESTAMP' => '[int]', + 'DECIMAL' => '[float]', + 'DECIMAL:' => '[float]', + 'PDECIMAL' => '[float]', + 'PDECIMAL:' => '[float]', + 'VCHAR_UNI' => '[varchar] (255)', + 'VCHAR_UNI:'=> '[varchar] (%d)', + 'VCHAR_CI' => '[varchar] (255)', + 'VARBINARY' => '[varchar] (255)', + ), + + 'mssqlnative' => array( + 'INT:' => '[int]', + 'BINT' => '[float]', + 'UINT' => '[int]', + 'UINT:' => '[int]', + 'TINT:' => '[int]', + 'USINT' => '[int]', + 'BOOL' => '[int]', + 'VCHAR' => '[varchar] (255)', + 'VCHAR:' => '[varchar] (%d)', + 'CHAR:' => '[char] (%d)', + 'XSTEXT' => '[varchar] (1000)', + 'STEXT' => '[varchar] (3000)', + 'TEXT' => '[varchar] (8000)', + 'MTEXT' => '[text]', + 'XSTEXT_UNI'=> '[varchar] (100)', + 'STEXT_UNI' => '[varchar] (255)', + 'TEXT_UNI' => '[varchar] (4000)', + 'MTEXT_UNI' => '[text]', + 'TIMESTAMP' => '[int]', + 'DECIMAL' => '[float]', + 'DECIMAL:' => '[float]', + 'PDECIMAL' => '[float]', + 'PDECIMAL:' => '[float]', + 'VCHAR_UNI' => '[varchar] (255)', + 'VCHAR_UNI:'=> '[varchar] (%d)', + 'VCHAR_CI' => '[varchar] (255)', + 'VARBINARY' => '[varchar] (255)', + ), + ); + } + + /** + * Constructor. Set DB Object and set {@link $return_statements return_statements}. + * + * @param \phpbb\db\driver\driver_interface $db Database connection + * @param bool $return_statements True if only statements should be returned and no SQL being executed + */ + public function __construct(\phpbb\db\driver\driver_interface $db, $return_statements = false) + { + parent::__construct($db, $return_statements); + + // Determine mapping database type + switch ($this->db->get_sql_layer()) + { + case 'mssql': + case 'mssql_odbc': + $this->sql_layer = 'mssql'; + break; + + case 'mssqlnative': + $this->sql_layer = 'mssqlnative'; + break; + } + } + + /** + * {@inheritDoc} + */ + function sql_list_tables() + { + $sql = "SELECT name + FROM sysobjects + WHERE type='U'"; + $result = $this->db->sql_query($sql); + + $tables = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $name = current($row); + $tables[$name] = $name; + } + $this->db->sql_freeresult($result); + + return $tables; + } + + /** + * {@inheritDoc} + */ + function sql_create_table($table_name, $table_data) + { + // holds the DDL for a column + $columns = $statements = array(); + + if ($this->sql_table_exists($table_name)) + { + return $this->_sql_run_sql($statements); + } + + // Begin transaction + $statements[] = 'begin'; + + // Determine if we have created a PRIMARY KEY in the earliest + $primary_key_gen = false; + + // Determine if the table requires a sequence + $create_sequence = false; + + // Begin table sql statement + $table_sql = 'CREATE TABLE [' . $table_name . '] (' . "\n"; + + if (!isset($table_data['PRIMARY_KEY'])) + { + $table_data['COLUMNS']['mssqlindex'] = array('UINT', null, 'auto_increment'); + $table_data['PRIMARY_KEY'] = 'mssqlindex'; + } + + // Iterate through the columns to create a table + foreach ($table_data['COLUMNS'] as $column_name => $column_data) + { + // here lies an array, filled with information compiled on the column's data + $prepared_column = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + + if (isset($prepared_column['auto_increment']) && $prepared_column['auto_increment'] && strlen($column_name) > 26) // "${column_name}_gen" + { + trigger_error("Index name '${column_name}_gen' on table '$table_name' is too long. The maximum auto increment column length is 26 characters.", E_USER_ERROR); + } + + // here we add the definition of the new column to the list of columns + $columns[] = "\t [{$column_name}] " . $prepared_column['column_type_sql_default']; + + // see if we have found a primary key set due to a column definition if we have found it, we can stop looking + if (!$primary_key_gen) + { + $primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set']; + } + + // create sequence DDL based off of the existance of auto incrementing columns + if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment']) + { + $create_sequence = $column_name; + } + } + + // this makes up all the columns in the create table statement + $table_sql .= implode(",\n", $columns); + + // Close the table for two DBMS and add to the statements + $table_sql .= "\n);"; + $statements[] = $table_sql; + + // we have yet to create a primary key for this table, + // this means that we can add the one we really wanted instead + if (!$primary_key_gen) + { + // 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']); + } + + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $primary_key_stmts = $this->sql_create_primary_key($table_name, $table_data['PRIMARY_KEY']); + foreach ($primary_key_stmts as $pk_stmt) + { + $statements[] = $pk_stmt; + } + + $this->return_statements = $old_return_statements; + } + } + + // 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]); + } + + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $key_stmts = ($key_data[0] == 'UNIQUE') ? $this->sql_create_unique_index($table_name, $key_name, $key_data[1]) : $this->sql_create_index($table_name, $key_name, $key_data[1]); + + foreach ($key_stmts as $key_stmt) + { + $statements[] = $key_stmt; + } + + $this->return_statements = $old_return_statements; + } + } + + // Commit Transaction + $statements[] = 'commit'; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_list_columns($table_name) + { + $columns = array(); + + $sql = "SELECT c.name + FROM syscolumns c + LEFT JOIN sysobjects o ON c.id = o.id + WHERE o.name = '{$table_name}'"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $column = strtolower(current($row)); + $columns[$column] = $column; + } + $this->db->sql_freeresult($result); + + return $columns; + } + + /** + * {@inheritDoc} + */ + function sql_index_exists($table_name, $index_name) + { + $sql = "EXEC sp_statistics '$table_name'"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + if ($row['TYPE'] == 3) + { + if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + } + $this->db->sql_freeresult($result); + + return false; + } + + /** + * {@inheritDoc} + */ + function sql_unique_index_exists($table_name, $index_name) + { + $sql = "EXEC sp_statistics '$table_name'"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + // Usually NON_UNIQUE is the column we want to check, but we allow for both + if ($row['TYPE'] == 3) + { + if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + } + $this->db->sql_freeresult($result); + + return false; + } + + /** + * {@inheritDoc} + */ + function sql_prepare_column_data($table_name, $column_name, $column_data) + { + if (strlen($column_name) > 30) + { + trigger_error("Column name '$column_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); + } + + // Get type + list($column_type, $orig_column_type) = $this->get_column_type($column_data[0]); + + // Adjust default value if db-dependent specified + if (is_array($column_data[1])) + { + $column_data[1] = (isset($column_data[1][$this->sql_layer])) ? $column_data[1][$this->sql_layer] : $column_data[1]['default']; + } + + $sql = ''; + + $return_array = array(); + + $sql .= " {$column_type} "; + $sql_default = " {$column_type} "; + + // For adding columns we need the default definition + if (!is_null($column_data[1])) + { + // For hexadecimal values do not use single quotes + if (strpos($column_data[1], '0x') === 0) + { + $return_array['default'] = 'DEFAULT (' . $column_data[1] . ') '; + $sql_default .= $return_array['default']; + } + else + { + $return_array['default'] = 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; + $sql_default .= $return_array['default']; + } + } + + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + // $sql .= 'IDENTITY (1, 1) '; + $sql_default .= 'IDENTITY (1, 1) '; + } + + $return_array['textimage'] = $column_type === '[text]'; + + if (!is_null($column_data[1]) || (isset($column_data[2]) && $column_data[2] == 'auto_increment')) + { + $sql .= 'NOT NULL'; + $sql_default .= 'NOT NULL'; + } + else + { + $sql .= 'NULL'; + $sql_default .= 'NULL'; + } + + $return_array['column_type_sql_default'] = $sql_default; + + $return_array['column_type_sql'] = $sql; + + return $return_array; + } + + /** + * {@inheritDoc} + */ + function sql_column_add($table_name, $column_name, $column_data, $inline = false) + { + $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + $statements = array(); + + // Does not support AFTER, only through temporary table + $statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default']; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_column_remove($table_name, $column_name, $inline = false) + { + $statements = array(); + + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $indexes = $this->get_existing_indexes($table_name, $column_name); + $indexes = array_merge($indexes, $this->get_existing_indexes($table_name, $column_name, true)); + + // Drop any indexes + $recreate_indexes = array(); + if (!empty($indexes)) + { + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_index_drop($table_name, $index_name); + $statements = array_merge($statements, $result); + if (sizeof($index_data) > 1) + { + // Remove this column from the index and recreate it + $recreate_indexes[$index_name] = array_diff($index_data, array($column_name)); + } + } + } + + // Drop default value constraint + $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Remove the column + $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']'; + + if (!empty($recreate_indexes)) + { + // Recreate indexes after we removed the column + foreach ($recreate_indexes as $index_name => $index_data) + { + $result = $this->sql_create_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + $this->return_statements = $old_return_statements; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_index_drop($table_name, $index_name) + { + $statements = array(); + + $statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_table_drop($table_name) + { + $statements = array(); + + if (!$this->sql_table_exists($table_name)) + { + return $this->_sql_run_sql($statements); + } + + // the most basic operation, get rid of the table + $statements[] = 'DROP TABLE ' . $table_name; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_create_primary_key($table_name, $column, $inline = false) + { + $statements = array(); + + $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD "; + $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED ("; + $sql .= '[' . implode("],\n\t\t[", $column) . ']'; + $sql .= ')'; + + $statements[] = $sql; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_create_unique_index($table_name, $index_name, $column) + { + $statements = array(); + + $this->check_index_name_length($table_name, $index_name); + + $statements[] = 'CREATE UNIQUE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_create_index($table_name, $index_name, $column) + { + $statements = array(); + + $this->check_index_name_length($table_name, $index_name); + + // remove index length + $column = preg_replace('#:.*$#', '', $column); + + $statements[] = 'CREATE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_list_index($table_name) + { + $index_array = array(); + $sql = "EXEC sp_statistics '$table_name'"; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if ($row['TYPE'] == 3) + { + $index_array[] = strtolower($row['INDEX_NAME']); + } + } + $this->db->sql_freeresult($result); + + return $index_array; + } + + /** + * {@inheritDoc} + */ + function sql_column_change($table_name, $column_name, $column_data, $inline = false) + { + $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + $statements = array(); + + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $indexes = $this->get_existing_indexes($table_name, $column_name); + $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); + + // Drop any indexes + if (!empty($indexes) || !empty($unique_indexes)) + { + $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); + foreach ($drop_indexes as $index_name) + { + $result = $this->sql_index_drop($table_name, $index_name); + $statements = array_merge($statements, $result); + } + } + + // Drop default value constraint + $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Change the column + $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; + + if (!empty($column_data['default'])) + { + // Add new default value constraint + $statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $this->db->sql_escape($column_data['default']) . ' FOR [' . $column_name . ']'; + } + + if (!empty($indexes)) + { + // Recreate indexes after we changed the column + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_create_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + if (!empty($unique_indexes)) + { + // Recreate unique indexes after we changed the column + foreach ($unique_indexes as $index_name => $index_data) + { + $result = $this->sql_create_unique_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + $this->return_statements = $old_return_statements; + + return $this->_sql_run_sql($statements); + } + + /** + * Get queries to drop the default constraints of a column + * + * We need to drop the default constraints of a column, + * before being able to change their type or deleting them. + * + * @param string $table_name + * @param string $column_name + * @return array Array with SQL statements + */ + protected function mssql_get_drop_default_constraints_queries($table_name, $column_name) + { + $statements = array(); + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT so.name AS def_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}')"; + } + else + { + $sql = "SELECT dobj.name AS def_name + FROM sys.columns col + LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D') + WHERE col.object_id = object_id('{$table_name}') + AND col.name = '{$column_name}' + AND dobj.name IS NOT NULL"; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']'; + } + $this->db->sql_freeresult($result); + + return $statements; + } + + /** + * Get a list with existing indexes for the column + * + * @param string $table_name + * @param string $column_name + * @param bool $unique Should we get unique indexes or normal ones + * @return array Array with Index name => columns + */ + public function get_existing_indexes($table_name, $column_name, $unique = false) + { + $existing_indexes = array(); + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND cols.name = '{$column_name}' + AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique ? '1' : '0'); + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND cols.name = '{$column_name}' + AND ix.is_unique = " . ($unique ? '1' : '0'); + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (!isset($row['is_unique']) || ($unique && $row['is_unique'] == 'UNIQUE') || (!$unique && $row['is_unique'] == 'NONUNIQUE')) + { + $existing_indexes[$row['phpbb_index_name']] = array(); + } + } + $this->db->sql_freeresult($result); + + if (empty($existing_indexes)) + { + return array(); + } + + if ($this->mssql_is_sql_server_2000()) + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; + } + $this->db->sql_freeresult($result); + + return $existing_indexes; + } + + /** + * Is the used MS SQL Server a SQL Server 2000? + * + * @return bool + */ + protected function mssql_is_sql_server_2000() + { + if ($this->is_sql_server_2000 === null) + { + $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version"; + $result = $this->db->sql_query($sql); + $properties = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + $this->is_sql_server_2000 = $properties['mssql_version'][0] == '8'; + } + + return $this->is_sql_server_2000; + } + +} diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index 152ec6b00f..f05c690e5f 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -35,12 +35,6 @@ class tools implements tools_interface */ var $dbms_type_map = array(); - /** - * Is the used MS SQL Server a SQL Server 2000? - * @var bool - */ - protected $is_sql_server_2000; - /** * Get the column types for every database we support * @@ -109,66 +103,6 @@ class tools implements tools_interface 'VARBINARY' => 'varbinary(255)', ), - 'mssql' => array( - 'INT:' => '[int]', - 'BINT' => '[float]', - 'UINT' => '[int]', - 'UINT:' => '[int]', - 'TINT:' => '[int]', - 'USINT' => '[int]', - 'BOOL' => '[int]', - 'VCHAR' => '[varchar] (255)', - 'VCHAR:' => '[varchar] (%d)', - 'CHAR:' => '[char] (%d)', - 'XSTEXT' => '[varchar] (1000)', - 'STEXT' => '[varchar] (3000)', - 'TEXT' => '[varchar] (8000)', - 'MTEXT' => '[text]', - 'XSTEXT_UNI'=> '[varchar] (100)', - 'STEXT_UNI' => '[varchar] (255)', - 'TEXT_UNI' => '[varchar] (4000)', - 'MTEXT_UNI' => '[text]', - 'TIMESTAMP' => '[int]', - 'DECIMAL' => '[float]', - 'DECIMAL:' => '[float]', - 'PDECIMAL' => '[float]', - 'PDECIMAL:' => '[float]', - 'VCHAR_UNI' => '[varchar] (255)', - 'VCHAR_UNI:'=> '[varchar] (%d)', - 'VCHAR_CI' => '[varchar] (255)', - 'VARBINARY' => '[varchar] (255)', - ), - - 'mssqlnative' => array( - 'INT:' => '[int]', - 'BINT' => '[float]', - 'UINT' => '[int]', - 'UINT:' => '[int]', - 'TINT:' => '[int]', - 'USINT' => '[int]', - 'BOOL' => '[int]', - 'VCHAR' => '[varchar] (255)', - 'VCHAR:' => '[varchar] (%d)', - 'CHAR:' => '[char] (%d)', - 'XSTEXT' => '[varchar] (1000)', - 'STEXT' => '[varchar] (3000)', - 'TEXT' => '[varchar] (8000)', - 'MTEXT' => '[text]', - 'XSTEXT_UNI'=> '[varchar] (100)', - 'STEXT_UNI' => '[varchar] (255)', - 'TEXT_UNI' => '[varchar] (4000)', - 'MTEXT_UNI' => '[text]', - 'TIMESTAMP' => '[int]', - 'DECIMAL' => '[float]', - 'DECIMAL:' => '[float]', - 'PDECIMAL' => '[float]', - 'PDECIMAL:' => '[float]', - 'VCHAR_UNI' => '[varchar] (255)', - 'VCHAR_UNI:'=> '[varchar] (%d)', - 'VCHAR_CI' => '[varchar] (255)', - 'VARBINARY' => '[varchar] (255)', - ), - 'oracle' => array( 'INT:' => 'number(%d)', 'BINT' => 'number(20)', @@ -297,12 +231,6 @@ class tools implements tools_interface */ var $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); - /** - * A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules. - * @var array - */ - var $supported_dbms = array('mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite', 'sqlite3'); - /** * This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array). * This mode has no effect on some methods (inserting of data for example). This is expressed within the methods command. @@ -344,15 +272,6 @@ class tools implements tools_interface $this->sql_layer = 'mysql_41'; break; - case 'mssql': - case 'mssql_odbc': - $this->sql_layer = 'mssql'; - break; - - case 'mssqlnative': - $this->sql_layer = 'mssqlnative'; - break; - default: $this->sql_layer = $this->db->get_sql_layer(); break; @@ -396,14 +315,6 @@ class tools implements tools_interface AND name <> "sqlite_sequence"'; break; - case 'mssql': - case 'mssql_odbc': - case 'mssqlnative': - $sql = "SELECT name - FROM sysobjects - WHERE type='U'"; - break; - case 'postgres': $sql = 'SELECT relname FROM pg_stat_user_tables'; @@ -469,26 +380,7 @@ class tools implements tools_interface $create_sequence = false; // Begin table sql statement - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - $table_sql = 'CREATE TABLE [' . $table_name . '] (' . "\n"; - break; - - default: - $table_sql = 'CREATE TABLE ' . $table_name . ' (' . "\n"; - break; - } - - if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') - { - if (!isset($table_data['PRIMARY_KEY'])) - { - $table_data['COLUMNS']['mssqlindex'] = array('UINT', null, 'auto_increment'); - $table_data['PRIMARY_KEY'] = 'mssqlindex'; - } - } + $table_sql = 'CREATE TABLE ' . $table_name . ' (' . "\n"; // Iterate through the columns to create a table foreach ($table_data['COLUMNS'] as $column_name => $column_data) @@ -502,17 +394,7 @@ class tools implements tools_interface } // here we add the definition of the new column to the list of columns - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - $columns[] = "\t [{$column_name}] " . $prepared_column['column_type_sql_default']; - break; - - default: - $columns[] = "\t {$column_name} " . $prepared_column['column_type_sql']; - break; - } + $columns[] = "\t {$column_name} " . $prepared_column['column_type_sql']; // see if we have found a primary key set due to a column definition if we have found it, we can stop looking if (!$primary_key_gen) @@ -530,16 +412,6 @@ class tools implements tools_interface // this makes up all the columns in the create table statement $table_sql .= implode(",\n", $columns); - // Close the table for two DBMS and add to the statements - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - $table_sql .= "\n);"; - $statements[] = $table_sql; - break; - } - // we have yet to create a primary key for this table, // this means that we can add the one we really wanted instead if (!$primary_key_gen) @@ -562,21 +434,6 @@ class tools implements tools_interface $table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; break; - case 'mssql': - case 'mssqlnative': - // We need the data here - $old_return_statements = $this->return_statements; - $this->return_statements = true; - - $primary_key_stmts = $this->sql_create_primary_key($table_name, $table_data['PRIMARY_KEY']); - foreach ($primary_key_stmts as $pk_stmt) - { - $statements[] = $pk_stmt; - } - - $this->return_statements = $old_return_statements; - break; - case 'oracle': $table_sql .= ",\n\t CONSTRAINT pk_{$table_name} PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; break; @@ -1073,16 +930,6 @@ class tools implements tools_interface AND a.attrelid = c.oid"; break; - // same deal with PostgreSQL, we must perform more complex operations than - // we technically could - case 'mssql': - case 'mssqlnative': - $sql = "SELECT c.name - FROM syscolumns c - LEFT JOIN sysobjects o ON c.id = o.id - WHERE o.name = '{$table_name}'"; - break; - case 'oracle': $sql = "SELECT column_name FROM user_tab_columns @@ -1154,27 +1001,6 @@ class tools implements tools_interface */ function sql_index_exists($table_name, $index_name) { - if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') - { - $sql = "EXEC sp_statistics '$table_name'"; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - if ($row['TYPE'] == 3) - { - if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) - { - $this->db->sql_freeresult($result); - return true; - } - } - } - $this->db->sql_freeresult($result); - - return false; - } - switch ($this->sql_layer) { case 'postgres': @@ -1246,27 +1072,6 @@ class tools implements tools_interface */ function sql_unique_index_exists($table_name, $index_name) { - if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') - { - $sql = "EXEC sp_statistics '$table_name'"; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - // Usually NON_UNIQUE is the column we want to check, but we allow for both - if ($row['TYPE'] == 3) - { - if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) - { - $this->db->sql_freeresult($result); - return true; - } - } - } - $this->db->sql_freeresult($result); - return false; - } - switch ($this->sql_layer) { case 'postgres': @@ -1410,50 +1215,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'mssql': - case 'mssqlnative': - $sql .= " {$column_type} "; - $sql_default = " {$column_type} "; - - // For adding columns we need the default definition - if (!is_null($column_data[1])) - { - // For hexadecimal values do not use single quotes - if (strpos($column_data[1], '0x') === 0) - { - $return_array['default'] = 'DEFAULT (' . $column_data[1] . ') '; - $sql_default .= $return_array['default']; - } - else - { - $return_array['default'] = 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; - $sql_default .= $return_array['default']; - } - } - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { -// $sql .= 'IDENTITY (1, 1) '; - $sql_default .= 'IDENTITY (1, 1) '; - } - - $return_array['textimage'] = $column_type === '[text]'; - - if (!is_null($column_data[1]) || (isset($column_data[2]) && $column_data[2] == 'auto_increment')) - { - $sql .= 'NOT NULL'; - $sql_default .= 'NOT NULL'; - } - else - { - $sql .= 'NULL'; - $sql_default .= 'NULL'; - } - - $return_array['column_type_sql_default'] = $sql_default; - - break; - case 'mysql_40': case 'mysql_41': $sql .= " {$column_type} "; @@ -1653,12 +1414,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'mssql': - case 'mssqlnative': - // Does not support AFTER, only through temporary table - $statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default']; - break; - case 'mysql_40': case 'mysql_41': $after = (!empty($column_data['after'])) ? ' AFTER ' . $column_data['after'] : ''; @@ -1770,51 +1525,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'mssql': - case 'mssqlnative': - // We need the data here - $old_return_statements = $this->return_statements; - $this->return_statements = true; - - $indexes = $this->get_existing_indexes($table_name, $column_name); - $indexes = array_merge($indexes, $this->get_existing_indexes($table_name, $column_name, true)); - - // Drop any indexes - $recreate_indexes = array(); - if (!empty($indexes)) - { - foreach ($indexes as $index_name => $index_data) - { - $result = $this->sql_index_drop($table_name, $index_name); - $statements = array_merge($statements, $result); - if (sizeof($index_data) > 1) - { - // Remove this column from the index and recreate it - $recreate_indexes[$index_name] = array_diff($index_data, array($column_name)); - } - } - } - - // Drop default value constraint - $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); - $statements = array_merge($statements, $result); - - // Remove the column - $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']'; - - if (!empty($recreate_indexes)) - { - // Recreate indexes after we removed the column - foreach ($recreate_indexes as $index_name => $index_data) - { - $result = $this->sql_create_index($table_name, $index_name, $index_data); - $statements = array_merge($statements, $result); - } - } - - $this->return_statements = $old_return_statements; - break; - case 'mysql_40': case 'mysql_41': $statements[] = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`'; @@ -1899,11 +1609,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'mssql': - case 'mssqlnative': - $statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name; - break; - case 'mysql_40': case 'mysql_41': $statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name; @@ -1988,16 +1693,6 @@ class tools implements tools_interface $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; break; - case 'mssql': - case 'mssqlnative': - $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD "; - $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED ("; - $sql .= '[' . implode("],\n\t\t[", $column) . ']'; - $sql .= ')'; - - $statements[] = $sql; - break; - case 'oracle': $statements[] = 'ALTER TABLE ' . $table_name . ' add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; break; @@ -2064,12 +1759,7 @@ class tools implements tools_interface { $statements = array(); - $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) - if (strlen($table_name . '_' . $index_name) - strlen($table_prefix) > 24) - { - $max_length = strlen($table_prefix) + 24; - trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); - } + $this->check_index_name_length($table_name, $index_name); switch ($this->sql_layer) { @@ -2084,11 +1774,6 @@ class tools implements tools_interface case 'mysql_41': $statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; break; - - case 'mssql': - case 'mssqlnative': - $statements[] = 'CREATE UNIQUE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; - break; } return $this->_sql_run_sql($statements); @@ -2101,12 +1786,7 @@ class tools implements tools_interface { $statements = array(); - $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) - if (strlen($table_name . $index_name) - strlen($table_prefix) > 24) - { - $max_length = strlen($table_prefix) + 24; - trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); - } + $this->check_index_name_length($table_name, $index_name); // remove index length unless MySQL4 if ('mysql_40' != $this->sql_layer) @@ -2137,16 +1817,27 @@ class tools implements tools_interface case 'mysql_41': $statements[] = 'ALTER TABLE ' . $table_name . ' ADD INDEX ' . $index_name . ' (' . implode(', ', $column) . ')'; break; - - case 'mssql': - case 'mssqlnative': - $statements[] = 'CREATE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; - break; } return $this->_sql_run_sql($statements); } + /** + * Check whether the index name is too long + * + * @param string $table_name + * @param string $index_name + */ + protected function check_index_name_length($table_name, $index_name) + { + $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) + if (strlen($table_name . $index_name) - strlen($table_prefix) > 24) + { + $max_length = strlen($table_prefix) + 24; + trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); + } + } + /** * {@inheritDoc} */ @@ -2154,79 +1845,63 @@ class tools implements tools_interface { $index_array = array(); - if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') - { - $sql = "EXEC sp_statistics '$table_name'"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if ($row['TYPE'] == 3) - { - $index_array[] = $row['INDEX_NAME']; - } - } - $this->db->sql_freeresult($result); - } - else + switch ($this->sql_layer) { - switch ($this->sql_layer) - { - case 'postgres': - $sql = "SELECT ic.relname as index_name - FROM pg_class bc, pg_class ic, pg_index i - WHERE (bc.oid = i.indrelid) - AND (ic.oid = i.indexrelid) - AND (bc.relname = '" . $table_name . "') - AND (i.indisunique != 't') - AND (i.indisprimary != 't')"; - $col = 'index_name'; + case 'postgres': + $sql = "SELECT ic.relname as index_name + FROM pg_class bc, pg_class ic, pg_index i + WHERE (bc.oid = i.indrelid) + AND (ic.oid = i.indexrelid) + AND (bc.relname = '" . $table_name . "') + AND (i.indisunique != 't') + AND (i.indisprimary != 't')"; + $col = 'index_name'; break; - case 'mysql_40': - case 'mysql_41': - $sql = 'SHOW KEYS - FROM ' . $table_name; - $col = 'Key_name'; + case 'mysql_40': + case 'mysql_41': + $sql = 'SHOW KEYS + FROM ' . $table_name; + $col = 'Key_name'; break; - case 'oracle': - $sql = "SELECT index_name - FROM user_indexes - WHERE table_name = '" . strtoupper($table_name) . "' - AND generated = 'N' - AND uniqueness = 'NONUNIQUE'"; - $col = 'index_name'; + case 'oracle': + $sql = "SELECT index_name + FROM user_indexes + WHERE table_name = '" . strtoupper($table_name) . "' + AND generated = 'N' + AND uniqueness = 'NONUNIQUE'"; + $col = 'index_name'; break; - case 'sqlite': - case 'sqlite3': - $sql = "PRAGMA index_info('" . $table_name . "');"; - $col = 'name'; + case 'sqlite': + case 'sqlite3': + $sql = "PRAGMA index_info('" . $table_name . "');"; + $col = 'name'; break; - } + } - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) { - if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) - { - continue; - } + continue; + } - switch ($this->sql_layer) - { - case 'oracle': - case 'postgres': - case 'sqlite': - case 'sqlite3': - $row[$col] = substr($row[$col], strlen($table_name) + 1); + switch ($this->sql_layer) + { + case 'oracle': + case 'postgres': + case 'sqlite': + case 'sqlite3': + $row[$col] = substr($row[$col], strlen($table_name) + 1); break; - } - - $index_array[] = $row[$col]; } - $this->db->sql_freeresult($result); + + $index_array[] = $row[$col]; } + $this->db->sql_freeresult($result); return array_map('strtolower', $index_array); } @@ -2254,62 +1929,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'mssql': - case 'mssqlnative': - // We need the data here - $old_return_statements = $this->return_statements; - $this->return_statements = true; - - $indexes = $this->get_existing_indexes($table_name, $column_name); - $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); - - // Drop any indexes - if (!empty($indexes) || !empty($unique_indexes)) - { - $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); - foreach ($drop_indexes as $index_name) - { - $result = $this->sql_index_drop($table_name, $index_name); - $statements = array_merge($statements, $result); - } - } - - // Drop default value constraint - $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); - $statements = array_merge($statements, $result); - - // Change the column - $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; - - if (!empty($column_data['default'])) - { - // Add new default value constraint - $statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $this->db->sql_escape($column_data['default']) . ' FOR [' . $column_name . ']'; - } - - if (!empty($indexes)) - { - // Recreate indexes after we changed the column - foreach ($indexes as $index_name => $index_data) - { - $result = $this->sql_create_index($table_name, $index_name, $index_data); - $statements = array_merge($statements, $result); - } - } - - if (!empty($unique_indexes)) - { - // Recreate unique indexes after we changed the column - foreach ($unique_indexes as $index_name => $index_data) - { - $result = $this->sql_create_unique_index($table_name, $index_name, $index_data); - $statements = array_merge($statements, $result); - } - } - - $this->return_statements = $old_return_statements; - break; - case 'mysql_40': case 'mysql_41': $statements[] = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql']; @@ -2511,52 +2130,6 @@ class tools implements tools_interface return $this->_sql_run_sql($statements); } - /** - * Get queries to drop the default constraints of a column - * - * We need to drop the default constraints of a column, - * before being able to change their type or deleting them. - * - * @param string $table_name - * @param string $column_name - * @return array Array with SQL statements - */ - protected function mssql_get_drop_default_constraints_queries($table_name, $column_name) - { - $statements = array(); - if ($this->mssql_is_sql_server_2000()) - { - // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx - // Deprecated in SQL Server 2005 - $sql = "SELECT so.name AS def_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}')"; - } - else - { - $sql = "SELECT dobj.name AS def_name - FROM sys.columns col - LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D') - WHERE col.object_id = object_id('{$table_name}') - AND col.name = '{$column_name}' - AND dobj.name IS NOT NULL"; - } - - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']'; - } - $this->db->sql_freeresult($result); - - return $statements; - } - /** * Get a list with existing indexes for the column * @@ -2584,40 +2157,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'mssql': - case 'mssqlnative': - if ($this->mssql_is_sql_server_2000()) - { - // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx - // Deprecated in SQL Server 2005 - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name - FROM sysindexes ix - INNER JOIN sysindexkeys ixc - ON ixc.id = ix.id - AND ixc.indid = ix.indid - INNER JOIN syscolumns cols - ON cols.colid = ixc.colid - AND cols.id = ix.id - WHERE ix.id = object_id('{$table_name}') - AND cols.name = '{$column_name}' - AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique ? '1' : '0'); - } - else - { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name - FROM sys.indexes ix - INNER JOIN sys.index_columns ixc - ON ixc.object_id = ix.object_id - AND ixc.index_id = ix.index_id - INNER JOIN sys.columns cols - ON cols.column_id = ixc.column_id - AND cols.object_id = ix.object_id - WHERE ix.object_id = object_id('{$table_name}') - AND cols.name = '{$column_name}' - AND ix.is_unique = " . ($unique ? '1' : '0'); - } - break; - case 'oracle': $sql = "SELECT ix.index_name AS phpbb_index_name, ix.uniqueness AS is_unique FROM all_ind_columns ixc, all_indexes ix @@ -2644,36 +2183,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'mssql': - case 'mssqlnative': - if ($this->mssql_is_sql_server_2000()) - { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name - FROM sysindexes ix - INNER JOIN sysindexkeys ixc - ON ixc.id = ix.id - AND ixc.indid = ix.indid - INNER JOIN syscolumns cols - ON cols.colid = ixc.colid - AND cols.id = ix.id - WHERE ix.id = object_id('{$table_name}') - AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); - } - else - { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name - FROM sys.indexes ix - INNER JOIN sys.index_columns ixc - ON ixc.object_id = ix.object_id - AND ixc.index_id = ix.index_id - INNER JOIN sys.columns cols - ON cols.column_id = ixc.column_id - AND cols.object_id = ix.object_id - WHERE ix.object_id = object_id('{$table_name}') - AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); - } - break; - case 'oracle': $sql = "SELECT index_name AS phpbb_index_name, column_name AS phpbb_column_name FROM all_ind_columns @@ -2692,25 +2201,6 @@ class tools implements tools_interface return $existing_indexes; } - /** - * Is the used MS SQL Server a SQL Server 2000? - * - * @return bool - */ - protected function mssql_is_sql_server_2000() - { - if ($this->is_sql_server_2000 === null) - { - $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version"; - $result = $this->db->sql_query($sql); - $properties = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - $this->is_sql_server_2000 = $properties['mssql_version'][0] == '8'; - } - - return $this->is_sql_server_2000; - } - /** * Returns the Queries which are required to recreate a table including indexes * -- cgit v1.2.1 From 37ae99c75d388221489aa1069078d92eca413741 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 24 Jan 2015 12:06:45 +0100 Subject: [ticket/10748] Replace direct creations of tools(); PHPBB3-10748 --- phpBB/phpbb/captcha/plugins/qa.php | 12 +++++------- phpBB/phpbb/search/fulltext_sphinx.php | 3 ++- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/captcha/plugins/qa.php b/phpBB/phpbb/captcha/plugins/qa.php index b4586f1234..cf03f92e96 100644 --- a/phpBB/phpbb/captcha/plugins/qa.php +++ b/phpBB/phpbb/captcha/plugins/qa.php @@ -113,9 +113,9 @@ class qa */ public function is_installed() { - global $db; + global $phpbb_container; - $db_tool = new \phpbb\db\tools\tools($db); + $db_tool = $phpbb_container->get('dbal.tools'); return $db_tool->sql_table_exists($this->table_captcha_questions); } @@ -306,11 +306,9 @@ class qa */ function install() { - global $db; - - $db_tool = new \phpbb\db\tools\tools($db); + global $phpbb_container; - $tables = array($this->table_captcha_questions, $this->table_captcha_answers, $this->table_qa_confirm); + $db_tool = $phpbb_container->get('dbal.tools'); $schemas = array( $this->table_captcha_questions => array ( @@ -352,7 +350,7 @@ class qa ), ); - foreach($schemas as $table => $schema) + foreach ($schemas as $table => $schema) { if (!$db_tool->sql_table_exists($table)) { diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index 0be646ff06..a5ad96b114 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -136,7 +136,8 @@ class fulltext_sphinx $this->auth = $auth; // Initialize \phpbb\db\tools\tools object - $this->db_tools = new \phpbb\db\tools\tools($this->db); + global $phpbb_container; // TODO inject into object + $this->db_tools = $phpbb_container->get('dbal.tools'); if(!$this->config['fulltext_sphinx_id']) { -- cgit v1.2.1 From 74d1b1812f512ae232a063a2574d62d3f5491f46 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 24 Jan 2015 21:35:17 +0100 Subject: [ticket/10748] Overwrite the type map correctly PHPBB3-10748 --- phpBB/phpbb/db/tools/mssql.php | 4 +++- phpBB/phpbb/db/tools/tools.php | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index b4a09143eb..3a7ac6185d 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -117,6 +117,8 @@ class mssql extends tools $this->sql_layer = 'mssqlnative'; break; } + + $this->dbms_type_map = self::get_dbms_type_map(); } /** @@ -344,7 +346,7 @@ class mssql extends tools } // Get type - list($column_type, $orig_column_type) = $this->get_column_type($column_data[0]); + list($column_type, ) = $this->get_column_type($column_data[0]); // Adjust default value if db-dependent specified if (is_array($column_data[1])) diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index f05c690e5f..d2bad21a3a 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -1354,6 +1354,7 @@ class tools implements tools_interface */ function get_column_type($column_map_type) { + $column_type = ''; if (strpos($column_map_type, ':') !== false) { list($orig_column_type, $column_length) = explode(':', $column_map_type); -- cgit v1.2.1 From ec1fb0423dbc0ee64f06e419657e62e4475fe2e9 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 13 Feb 2015 22:46:18 +0100 Subject: [ticket/10748] Split postgres DB tools into it's own class PHPBB3-10748 --- phpBB/phpbb/db/tools/factory.php | 4 + phpBB/phpbb/db/tools/mssql.php | 40 +-- phpBB/phpbb/db/tools/postgres.php | 613 ++++++++++++++++++++++++++++++++++++++ phpBB/phpbb/db/tools/tools.php | 257 ---------------- 4 files changed, 637 insertions(+), 277 deletions(-) create mode 100644 phpBB/phpbb/db/tools/postgres.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/factory.php b/phpBB/phpbb/db/tools/factory.php index 24e2a4d875..d204451a63 100644 --- a/phpBB/phpbb/db/tools/factory.php +++ b/phpBB/phpbb/db/tools/factory.php @@ -29,6 +29,10 @@ class factory { return new \phpbb\db\tools\mssql($db_driver, $return_statements); } + else if ($db_driver instanceof \phpbb\db\driver\postgres) + { + return new \phpbb\db\tools\postgres($db_driver, $return_statements); + } else if ($db_driver instanceof \phpbb\db\driver\driver_interface) { return new \phpbb\db\tools\tools($db_driver, $return_statements); diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index 3a7ac6185d..6e58171040 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -1,35 +1,35 @@ -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ namespace phpbb\db\tools; /** -* Database Tools for handling cross-db actions such as altering columns, etc. -* Currently not supported is returning SQL for creating tables. -*/ + * Database Tools for handling cross-db actions such as altering columns, etc. + * Currently not supported is returning SQL for creating tables. + */ class mssql extends tools { /** - * Is the used MS SQL Server a SQL Server 2000? - * @var bool - */ + * Is the used MS SQL Server a SQL Server 2000? + * @var bool + */ protected $is_sql_server_2000; /** - * Get the column types for every database we support - * - * @return array - */ + * Get the column types for mssql based databases + * + * @return array + */ public static function get_dbms_type_map() { return array( diff --git a/phpBB/phpbb/db/tools/postgres.php b/phpBB/phpbb/db/tools/postgres.php new file mode 100644 index 0000000000..8b61625c3c --- /dev/null +++ b/phpBB/phpbb/db/tools/postgres.php @@ -0,0 +1,613 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\tools; + +/** + * Database Tools for handling cross-db actions such as altering columns, etc. + * Currently not supported is returning SQL for creating tables. + */ +class postgres extends tools +{ + /** + * Get the column types for postgres only + * + * @return array + */ + public static function get_dbms_type_map() + { + return array( + 'postgres' => array( + 'INT:' => 'INT4', + 'BINT' => 'INT8', + 'UINT' => 'INT4', // unsigned + 'UINT:' => 'INT4', // unsigned + 'USINT' => 'INT2', // unsigned + 'BOOL' => 'INT2', // unsigned + 'TINT:' => 'INT2', + 'VCHAR' => 'varchar(255)', + 'VCHAR:' => 'varchar(%d)', + 'CHAR:' => 'char(%d)', + 'XSTEXT' => 'varchar(1000)', + 'STEXT' => 'varchar(3000)', + 'TEXT' => 'varchar(8000)', + 'MTEXT' => 'TEXT', + 'XSTEXT_UNI'=> 'varchar(100)', + 'STEXT_UNI' => 'varchar(255)', + 'TEXT_UNI' => 'varchar(4000)', + 'MTEXT_UNI' => 'TEXT', + 'TIMESTAMP' => 'INT4', // unsigned + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'varchar(255)', + 'VCHAR_UNI:'=> 'varchar(%d)', + 'VCHAR_CI' => 'varchar_ci', + 'VARBINARY' => 'bytea', + ), + ); + } + + /** + * Constructor. Set DB Object and set {@link $return_statements return_statements}. + * + * @param \phpbb\db\driver\driver_interface $db Database connection + * @param bool $return_statements True if only statements should be returned and no SQL being executed + */ + public function __construct(\phpbb\db\driver\driver_interface $db, $return_statements = false) + { + parent::__construct($db, $return_statements); + + // Determine mapping database type + $this->sql_layer = 'postgres'; + + $this->dbms_type_map = self::get_dbms_type_map(); + } + + /** + * {@inheritDoc} + */ + function sql_list_tables() + { + $sql = 'SELECT relname + FROM pg_stat_user_tables'; + $result = $this->db->sql_query($sql); + + $tables = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $name = current($row); + $tables[$name] = $name; + } + $this->db->sql_freeresult($result); + + return $tables; + } + + /** + * {@inheritDoc} + */ + function sql_create_table($table_name, $table_data) + { + // holds the DDL for a column + $columns = $statements = array(); + + if ($this->sql_table_exists($table_name)) + { + return $this->_sql_run_sql($statements); + } + + // Begin transaction + $statements[] = 'begin'; + + // Determine if we have created a PRIMARY KEY in the earliest + $primary_key_gen = false; + + // Determine if the table requires a sequence + $create_sequence = false; + + // Begin table sql statement + $table_sql = 'CREATE TABLE ' . $table_name . ' (' . "\n"; + + // Iterate through the columns to create a table + foreach ($table_data['COLUMNS'] as $column_name => $column_data) + { + // here lies an array, filled with information compiled on the column's data + $prepared_column = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + + if (isset($prepared_column['auto_increment']) && $prepared_column['auto_increment'] && strlen($column_name) > 26) // "${column_name}_gen" + { + trigger_error("Index name '${column_name}_gen' on table '$table_name' is too long. The maximum auto increment column length is 26 characters.", E_USER_ERROR); + } + + // here we add the definition of the new column to the list of columns + $columns[] = "\t {$column_name} " . $prepared_column['column_type_sql']; + + // see if we have found a primary key set due to a column definition if we have found it, we can stop looking + if (!$primary_key_gen) + { + $primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set']; + } + + // create sequence DDL based off of the existance of auto incrementing columns + if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment']) + { + $create_sequence = $column_name; + } + } + + // this makes up all the columns in the create table statement + $table_sql .= implode(",\n", $columns); + + // we have yet to create a primary key for this table, + // this means that we can add the one we really wanted instead + if (!$primary_key_gen) + { + // 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']); + } + + $table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; + } + } + + // do we need to add a sequence for auto incrementing columns? + if ($create_sequence) + { + $statements[] = "CREATE SEQUENCE {$table_name}_seq;"; + } + + // close the table + $table_sql .= "\n);"; + $statements[] = $table_sql; + + // 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]); + } + + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $key_stmts = ($key_data[0] == 'UNIQUE') ? $this->sql_create_unique_index($table_name, $key_name, $key_data[1]) : $this->sql_create_index($table_name, $key_name, $key_data[1]); + + foreach ($key_stmts as $key_stmt) + { + $statements[] = $key_stmt; + } + + $this->return_statements = $old_return_statements; + } + } + + // Commit Transaction + $statements[] = 'commit'; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_list_columns($table_name) + { + $columns = array(); + + $sql = "SELECT a.attname + FROM pg_class c, pg_attribute a + WHERE c.relname = '{$table_name}' + AND a.attnum > 0 + AND a.attrelid = c.oid"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $column = strtolower(current($row)); + $columns[$column] = $column; + } + $this->db->sql_freeresult($result); + + return $columns; + } + + /** + * {@inheritDoc} + */ + function sql_index_exists($table_name, $index_name) + { + $sql = "SELECT ic.relname as index_name + FROM pg_class bc, pg_class ic, pg_index i + WHERE (bc.oid = i.indrelid) + AND (ic.oid = i.indexrelid) + AND (bc.relname = '" . $table_name . "') + AND (i.indisunique != 't') + AND (i.indisprimary != 't')"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + // This DBMS prefixes index names with the table name + $row['index_name'] = $this->strip_table_name_from_index_name($table_name, $row['index_name']); + + if (strtolower($row['index_name']) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + $this->db->sql_freeresult($result); + + return false; + } + + /** + * {@inheritDoc} + */ + function sql_unique_index_exists($table_name, $index_name) + { + $sql = "SELECT ic.relname as index_name, i.indisunique + FROM pg_class bc, pg_class ic, pg_index i + WHERE (bc.oid = i.indrelid) + AND (ic.oid = i.indexrelid) + AND (bc.relname = '" . $table_name . "') + AND (i.indisprimary != 't')"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + if ($row['indisunique'] != 't') + { + continue; + } + + // This DBMS prefixes index names with the table name + $row['index_name'] = $this->strip_table_name_from_index_name($table_name, $row['index_name']); + + if (strtolower($row['index_name']) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + $this->db->sql_freeresult($result); + + return false; + } + + /** + * Function to prepare some column information for better usage + * @access private + */ + function sql_prepare_column_data($table_name, $column_name, $column_data) + { + if (strlen($column_name) > 30) + { + trigger_error("Column name '$column_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); + } + + // Get type + list($column_type, $orig_column_type) = $this->get_column_type($column_data[0]); + + // Adjust default value if db-dependent specified + if (is_array($column_data[1])) + { + $column_data[1] = (isset($column_data[1][$this->sql_layer])) ? $column_data[1][$this->sql_layer] : $column_data[1]['default']; + } + + $sql = " {$column_type} "; + + $return_array = array( + 'column_type' => $column_type, + 'auto_increment' => false, + ); + + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $default_val = "nextval('{$table_name}_seq')"; + $return_array['auto_increment'] = true; + } + else if (!is_null($column_data[1])) + { + $default_val = "'" . $column_data[1] . "'"; + $return_array['null'] = 'NOT NULL'; + $sql .= 'NOT NULL '; + } + else + { + // Integers need to have 0 instead of empty string as default + if (strpos($column_type, 'INT') === 0) + { + $default_val = '0'; + } + else + { + $default_val = "'" . $column_data[1] . "'"; + } + $return_array['null'] = 'NULL'; + $sql .= 'NULL '; + } + + $return_array['default'] = $default_val; + + $sql .= "DEFAULT {$default_val}"; + + // Unsigned? Then add a CHECK contraint + if (in_array($orig_column_type, $this->unsigned_types)) + { + $return_array['constraint'] = "CHECK ({$column_name} >= 0)"; + $sql .= " CHECK ({$column_name} >= 0)"; + } + + $return_array['column_type_sql'] = $sql; + + return $return_array; + } + + /** + * {@inheritDoc} + */ + function sql_column_add($table_name, $column_name, $column_data, $inline = false) + { + $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + $statements = array(); + + // Does not support AFTER, only through temporary table + if (version_compare($this->db->sql_server_info(true), '8.0', '>=')) + { + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; + } + else + { + // old versions cannot add columns with default and null information + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type'] . ' ' . $column_data['constraint']; + + if (isset($column_data['null'])) + { + if ($column_data['null'] == 'NOT NULL') + { + $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET NOT NULL'; + } + } + + if (isset($column_data['default'])) + { + $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; + } + } + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_column_remove($table_name, $column_name, $inline = false) + { + $statements = array(); + + $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"'; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_index_drop($table_name, $index_name) + { + $statements = array(); + + $statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_table_drop($table_name) + { + $statements = array(); + + if (!$this->sql_table_exists($table_name)) + { + return $this->_sql_run_sql($statements); + } + + // the most basic operation, get rid of the table + $statements[] = 'DROP TABLE ' . $table_name; + + // PGSQL does not "tightly" bind sequences and tables, we must guess... + $sql = "SELECT relname + FROM pg_class + WHERE relkind = 'S' + AND relname = '{$table_name}_seq'"; + $result = $this->db->sql_query($sql); + + // We don't even care about storing the results. We already know the answer if we get rows back. + if ($this->db->sql_fetchrow($result)) + { + $statements[] = "DROP SEQUENCE {$table_name}_seq;\n"; + } + $this->db->sql_freeresult($result); + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_create_primary_key($table_name, $column, $inline = false) + { + $statements = array(); + + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_create_unique_index($table_name, $index_name, $column) + { + $statements = array(); + + $this->check_index_name_length($table_name, $index_name); + + $statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; + + return $this->_sql_run_sql($statements); + } + + /** + * {@inheritDoc} + */ + function sql_create_index($table_name, $index_name, $column) + { + $statements = array(); + + $this->check_index_name_length($table_name, $index_name); + + // remove index length + $column = preg_replace('#:.*$#', '', $column); + + $statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; + + return $this->_sql_run_sql($statements); + } + + + /** + * {@inheritDoc} + */ + function sql_list_index($table_name) + { + $index_array = array(); + + $sql = "SELECT ic.relname as index_name + FROM pg_class bc, pg_class ic, pg_index i + WHERE (bc.oid = i.indrelid) + AND (ic.oid = i.indexrelid) + AND (bc.relname = '" . $table_name . "') + AND (i.indisunique != 't') + AND (i.indisprimary != 't')"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $row['index_name'] = $this->strip_table_name_from_index_name($table_name, $row['index_name']); + + $index_array[] = $row['index_name']; + } + $this->db->sql_freeresult($result); + + return array_map('strtolower', $index_array); + } + + /** + * {@inheritDoc} + */ + function sql_column_change($table_name, $column_name, $column_data, $inline = false) + { + $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + $statements = array(); + + $sql = 'ALTER TABLE ' . $table_name . ' '; + + $sql_array = array(); + $sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type']; + + if (isset($column_data['null'])) + { + if ($column_data['null'] == 'NOT NULL') + { + $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL'; + } + else if ($column_data['null'] == 'NULL') + { + $sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL'; + } + } + + if (isset($column_data['default'])) + { + $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; + } + + // we don't want to double up on constraints if we change different number data types + if (isset($column_data['constraint'])) + { + $constraint_sql = "SELECT consrc as constraint_data + FROM pg_constraint, pg_class bc + WHERE conrelid = bc.oid + AND bc.relname = '{$table_name}' + AND NOT EXISTS ( + SELECT * + FROM pg_constraint as c, pg_inherits as i + WHERE i.inhrelid = pg_constraint.conrelid + AND c.conname = pg_constraint.conname + AND c.consrc = pg_constraint.consrc + AND c.conrelid = i.inhparent + )"; + + $constraint_exists = false; + + $result = $this->db->sql_query($constraint_sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (trim($row['constraint_data']) == trim($column_data['constraint'])) + { + $constraint_exists = true; + break; + } + } + $this->db->sql_freeresult($result); + + if (!$constraint_exists) + { + $sql_array[] = 'ADD ' . $column_data['constraint']; + } + } + + $sql .= implode(', ', $sql_array); + + $statements[] = $sql; + + return $this->_sql_run_sql($statements); + } + + /** + * Get a list with existing indexes for the column + * + * @param string $table_name + * @param string $column_name + * @param bool $unique Should we get unique indexes or normal ones + * @return array Array with Index name => columns + */ + public function get_existing_indexes($table_name, $column_name, $unique = false) + { + // Not supported + throw new \Exception('DBMS is not supported'); + } +} diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index d2bad21a3a..0d1eb63c47 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -192,36 +192,6 @@ class tools implements tools_interface 'VCHAR_CI' => 'VARCHAR(255)', 'VARBINARY' => 'BLOB', ), - - 'postgres' => array( - 'INT:' => 'INT4', - 'BINT' => 'INT8', - 'UINT' => 'INT4', // unsigned - 'UINT:' => 'INT4', // unsigned - 'USINT' => 'INT2', // unsigned - 'BOOL' => 'INT2', // unsigned - 'TINT:' => 'INT2', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'varchar(1000)', - 'STEXT' => 'varchar(3000)', - 'TEXT' => 'varchar(8000)', - 'MTEXT' => 'TEXT', - 'XSTEXT_UNI'=> 'varchar(100)', - 'STEXT_UNI' => 'varchar(255)', - 'TEXT_UNI' => 'varchar(4000)', - 'MTEXT_UNI' => 'TEXT', - 'TIMESTAMP' => 'INT4', // unsigned - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar_ci', - 'VARBINARY' => 'bytea', - ), ); } @@ -315,11 +285,6 @@ class tools implements tools_interface AND name <> "sqlite_sequence"'; break; - case 'postgres': - $sql = 'SELECT relname - FROM pg_stat_user_tables'; - break; - case 'oracle': $sql = 'SELECT table_name FROM USER_TABLES'; @@ -428,7 +393,6 @@ class tools implements tools_interface { case 'mysql_40': case 'mysql_41': - case 'postgres': case 'sqlite': case 'sqlite3': $table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; @@ -457,17 +421,6 @@ class tools implements tools_interface $statements[] = $table_sql; break; - case 'postgres': - // do we need to add a sequence for auto incrementing columns? - if ($create_sequence) - { - $statements[] = "CREATE SEQUENCE {$table_name}_seq;"; - } - - $table_sql .= "\n);"; - $statements[] = $table_sql; - break; - case 'oracle': $table_sql .= "\n)"; $statements[] = $table_sql; @@ -920,16 +873,6 @@ class tools implements tools_interface $sql = "SHOW COLUMNS FROM $table_name"; break; - // PostgreSQL has a way of doing this in a much simpler way but would - // not allow us to support all versions of PostgreSQL - case 'postgres': - $sql = "SELECT a.attname - FROM pg_class c, pg_attribute a - WHERE c.relname = '{$table_name}' - AND a.attnum > 0 - AND a.attrelid = c.oid"; - break; - case 'oracle': $sql = "SELECT column_name FROM user_tab_columns @@ -1003,17 +946,6 @@ class tools implements tools_interface { switch ($this->sql_layer) { - case 'postgres': - $sql = "SELECT ic.relname as index_name - FROM pg_class bc, pg_class ic, pg_index i - WHERE (bc.oid = i.indrelid) - AND (ic.oid = i.indexrelid) - AND (bc.relname = '" . $table_name . "') - AND (i.indisunique != 't') - AND (i.indisprimary != 't')"; - $col = 'index_name'; - break; - case 'mysql_40': case 'mysql_41': $sql = 'SHOW KEYS @@ -1049,7 +981,6 @@ class tools implements tools_interface switch ($this->sql_layer) { case 'oracle': - case 'postgres': case 'sqlite': case 'sqlite3': $row[$col] = substr($row[$col], strlen($table_name) + 1); @@ -1074,16 +1005,6 @@ class tools implements tools_interface { switch ($this->sql_layer) { - case 'postgres': - $sql = "SELECT ic.relname as index_name, i.indisunique - FROM pg_class bc, pg_class ic, pg_index i - WHERE (bc.oid = i.indrelid) - AND (ic.oid = i.indexrelid) - AND (bc.relname = '" . $table_name . "') - AND (i.indisprimary != 't')"; - $col = 'index_name'; - break; - case 'mysql_40': case 'mysql_41': $sql = 'SHOW KEYS @@ -1120,11 +1041,6 @@ class tools implements tools_interface continue; } - if ($this->sql_layer == 'postgres' && $row['indisunique'] != 't') - { - continue; - } - // These DBMS prefix index name with the table name switch ($this->sql_layer) { @@ -1140,7 +1056,6 @@ class tools implements tools_interface } break; - case 'postgres': case 'sqlite': case 'sqlite3': $row[$col] = substr($row[$col], strlen($table_name) + 1); @@ -1268,51 +1183,6 @@ class tools implements tools_interface break; - case 'postgres': - $return_array['column_type'] = $column_type; - - $sql .= " {$column_type} "; - - $return_array['auto_increment'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $default_val = "nextval('{$table_name}_seq')"; - $return_array['auto_increment'] = true; - } - else if (!is_null($column_data[1])) - { - $default_val = "'" . $column_data[1] . "'"; - $return_array['null'] = 'NOT NULL'; - $sql .= 'NOT NULL '; - } - else - { - // Integers need to have 0 instead of empty string as default - if (strpos($column_type, 'INT') === 0) - { - $default_val = '0'; - } - else - { - $default_val = "'" . $column_data[1] . "'"; - } - $return_array['null'] = 'NULL'; - $sql .= 'NULL '; - } - - $return_array['default'] = $default_val; - - $sql .= "DEFAULT {$default_val}"; - - // Unsigned? Then add a CHECK contraint - if (in_array($orig_column_type, $this->unsigned_types)) - { - $return_array['constraint'] = "CHECK ({$column_name} >= 0)"; - $sql .= " CHECK ({$column_name} >= 0)"; - } - - break; - case 'sqlite': case 'sqlite3': $return_array['primary_key_set'] = false; @@ -1426,33 +1296,6 @@ class tools implements tools_interface $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; break; - case 'postgres': - // Does not support AFTER, only through temporary table - if (version_compare($this->db->sql_server_info(true), '8.0', '>=')) - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; - } - else - { - // old versions cannot add columns with default and null information - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type'] . ' ' . $column_data['constraint']; - - if (isset($column_data['null'])) - { - if ($column_data['null'] == 'NOT NULL') - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET NOT NULL'; - } - } - - if (isset($column_data['default'])) - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; - } - } - - break; - case 'sqlite': if ($inline && $this->return_statements) { @@ -1535,10 +1378,6 @@ class tools implements tools_interface $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name; break; - case 'postgres': - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"'; - break; - case 'sqlite': case 'sqlite3': @@ -1616,7 +1455,6 @@ class tools implements tools_interface break; case 'oracle': - case 'postgres': case 'sqlite': case 'sqlite3': $statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name; @@ -1658,22 +1496,6 @@ class tools implements tools_interface } $this->db->sql_freeresult($result); break; - - case 'postgres': - // PGSQL does not "tightly" bind sequences and tables, we must guess... - $sql = "SELECT relname - FROM pg_class - WHERE relkind = 'S' - AND relname = '{$table_name}_seq'"; - $result = $this->db->sql_query($sql); - - // We don't even care about storing the results. We already know the answer if we get rows back. - if ($this->db->sql_fetchrow($result)) - { - $statements[] = "DROP SEQUENCE {$table_name}_seq;\n"; - } - $this->db->sql_freeresult($result); - break; } return $this->_sql_run_sql($statements); @@ -1688,7 +1510,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'postgres': case 'mysql_40': case 'mysql_41': $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; @@ -1764,7 +1585,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'postgres': case 'oracle': case 'sqlite': case 'sqlite3': @@ -1797,7 +1617,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'postgres': case 'oracle': case 'sqlite': case 'sqlite3': @@ -1848,17 +1667,6 @@ class tools implements tools_interface switch ($this->sql_layer) { - case 'postgres': - $sql = "SELECT ic.relname as index_name - FROM pg_class bc, pg_class ic, pg_index i - WHERE (bc.oid = i.indrelid) - AND (ic.oid = i.indexrelid) - AND (bc.relname = '" . $table_name . "') - AND (i.indisunique != 't') - AND (i.indisprimary != 't')"; - $col = 'index_name'; - break; - case 'mysql_40': case 'mysql_41': $sql = 'SHOW KEYS @@ -1893,7 +1701,6 @@ class tools implements tools_interface switch ($this->sql_layer) { case 'oracle': - case 'postgres': case 'sqlite': case 'sqlite3': $row[$col] = substr($row[$col], strlen($table_name) + 1); @@ -2001,69 +1808,6 @@ class tools implements tools_interface $this->return_statements = $old_return_statements; break; - case 'postgres': - $sql = 'ALTER TABLE ' . $table_name . ' '; - - $sql_array = array(); - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type']; - - if (isset($column_data['null'])) - { - if ($column_data['null'] == 'NOT NULL') - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL'; - } - else if ($column_data['null'] == 'NULL') - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL'; - } - } - - if (isset($column_data['default'])) - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; - } - - // we don't want to double up on constraints if we change different number data types - if (isset($column_data['constraint'])) - { - $constraint_sql = "SELECT consrc as constraint_data - FROM pg_constraint, pg_class bc - WHERE conrelid = bc.oid - AND bc.relname = '{$table_name}' - AND NOT EXISTS ( - SELECT * - FROM pg_constraint as c, pg_inherits as i - WHERE i.inhrelid = pg_constraint.conrelid - AND c.conname = pg_constraint.conname - AND c.consrc = pg_constraint.consrc - AND c.conrelid = i.inhparent - )"; - - $constraint_exists = false; - - $result = $this->db->sql_query($constraint_sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if (trim($row['constraint_data']) == trim($column_data['constraint'])) - { - $constraint_exists = true; - break; - } - } - $this->db->sql_freeresult($result); - - if (!$constraint_exists) - { - $sql_array[] = 'ADD ' . $column_data['constraint']; - } - } - - $sql .= implode(', ', $sql_array); - - $statements[] = $sql; - break; - case 'sqlite': case 'sqlite3': @@ -2145,7 +1889,6 @@ class tools implements tools_interface { case 'mysql_40': case 'mysql_41': - case 'postgres': case 'sqlite': case 'sqlite3': // Not supported -- cgit v1.2.1 From 0595ab959ca65a99befafc1d885e56a838819c6a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sun, 22 Feb 2015 20:17:37 +0100 Subject: [ticket/13647] Move FAQ page to a controller PHPBB3-13647 --- phpBB/phpbb/help/controller/help.php | 160 +++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 phpBB/phpbb/help/controller/help.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/help/controller/help.php b/phpBB/phpbb/help/controller/help.php new file mode 100644 index 0000000000..e9594a0563 --- /dev/null +++ b/phpBB/phpbb/help/controller/help.php @@ -0,0 +1,160 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\help\controller; + +use phpbb\exception\http_exception; + +class help +{ + /** @var \phpbb\controller\helper */ + protected $helper; + + /** @var \phpbb\event\dispatcher_interface */ + protected $dispatcher; + + /** @var \phpbb\template\template */ + protected $template; + + /** @var \phpbb\user */ + protected $user; + + /** @var string */ + protected $root_path; + + /** @var string */ + protected $php_ext; + + /** + * Constructor + * + * @param \phpbb\controller\helper $helper + * @param \phpbb\event\dispatcher_interface $dispatcher + * @param \phpbb\template\template $template + * @param \phpbb\user $user + * @param string $root_path + * @param string $php_ext + */ + public function __construct(\phpbb\controller\helper $helper, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\template\template $template, \phpbb\user $user, $root_path, $php_ext) + { + $this->helper = $helper; + $this->dispatcher = $dispatcher; + $this->template = $template; + $this->user = $user; + $this->root_path = $root_path; + $this->php_ext = $php_ext; + } + + /** + * Controller for /help/{mode} routes + * + * @param string $mode + * @return \Symfony\Component\HttpFoundation\Response A Symfony Response object + * @throws http_exception when the $mode is not known by any extension + */ + public function handle($mode) + { + switch ($mode) + { + case 'faq': + case 'bbcode': + $page_title = ($mode === 'faq') ? $this->user->lang['FAQ_EXPLAIN'] : $this->user->lang['BBCODE_GUIDE']; + $this->user->add_lang($mode, false, true); + break; + + default: + $page_title = $this->user->lang['FAQ_EXPLAIN']; + $ext_name = $lang_file = ''; + + /** + * You can use this event display a custom help page + * + * @event core.faq_mode_validation + * @var string page_title Title of the page + * @var string mode FAQ that is going to be displayed + * @var string lang_file Language file containing the help data + * @var string ext_name Vendor and extension name where the help + * language file can be loaded from + * @since 3.1.4-RC1 + */ + $vars = array( + 'page_title', + 'mode', + 'lang_file', + 'ext_name', + ); + extract($this->dispatcher->trigger_event('core.faq_mode_validation', compact($vars))); + + if ($ext_name === '' || $lang_file === '') + { + throw new http_exception(501, 'FEATURE_NOT_AVAILABLE'); + } + + $this->user->add_lang($lang_file, false, true, $ext_name); + break; + + } + + $this->template->assign_vars(array( + 'L_FAQ_TITLE' => $page_title, + 'S_IN_FAQ' => true, + )); + + $this->assign_to_template($this->user->help); + + make_jumpbox(append_sid("{$this->root_path}viewforum.{$this->php_ext}")); + return $this->helper->render('faq_body.html', $page_title); + } + + /** + * Assigns the help data to the template blocks + * + * @param array $help_data + * @return null + */ + protected function assign_to_template(array $help_data) + { + // Pull the array data from the lang pack + $switch_column = $found_switch = false; + foreach ($help_data as $help_ary) + { + if ($help_ary[0] == '--') + { + if ($help_ary[1] == '--') + { + $switch_column = true; + $found_switch = true; + continue; + } + + $this->template->assign_block_vars('faq_block', array( + 'BLOCK_TITLE' => $help_ary[1], + 'SWITCH_COLUMN' => $switch_column, + )); + + if ($switch_column) + { + $switch_column = false; + } + continue; + } + + $this->template->assign_block_vars('faq_block.faq_row', array( + 'FAQ_QUESTION' => $help_ary[0], + 'FAQ_ANSWER' => $help_ary[1], + )); + } + + $this->template->assign_var('SWITCH_COLUMN_MANUALLY', !$found_switch); + } +} -- cgit v1.2.1 From 193c5b86b4b6049a9bf5abc5251d5479493a10df Mon Sep 17 00:00:00 2001 From: MateBartus Date: Sun, 22 Feb 2015 16:22:10 +0100 Subject: [ticket/12466] Move classes from acp_database.php to their own files * Moving classes from acp_database.php to phpbb/db/extractor namespace, also into separate files * Adding DocBlocks and property visibility to classes * Removing globals from code * Passing former globals to base_extractor's constructor * Adding DB extractor as a service, also implementing the extractor interface as well as the extractor factory. PHPBB3-12466 --- phpBB/phpbb/db/extractor/base_extractor.php | 252 ++++++++++ .../extractor_not_initialized_exception.php | 24 + .../exception/invalid_format_exception.php | 22 + phpBB/phpbb/db/extractor/extractor_interface.php | 80 ++++ phpBB/phpbb/db/extractor/factory.php | 79 ++++ phpBB/phpbb/db/extractor/mssql_extractor.php | 524 +++++++++++++++++++++ phpBB/phpbb/db/extractor/mysql_extractor.php | 403 ++++++++++++++++ phpBB/phpbb/db/extractor/oracle_extractor.php | 265 +++++++++++ phpBB/phpbb/db/extractor/postgres_extractor.php | 338 +++++++++++++ phpBB/phpbb/db/extractor/sqlite3_extractor.php | 151 ++++++ phpBB/phpbb/db/extractor/sqlite_extractor.php | 149 ++++++ 11 files changed, 2287 insertions(+) create mode 100644 phpBB/phpbb/db/extractor/base_extractor.php create mode 100644 phpBB/phpbb/db/extractor/exception/extractor_not_initialized_exception.php create mode 100644 phpBB/phpbb/db/extractor/exception/invalid_format_exception.php create mode 100644 phpBB/phpbb/db/extractor/extractor_interface.php create mode 100644 phpBB/phpbb/db/extractor/factory.php create mode 100644 phpBB/phpbb/db/extractor/mssql_extractor.php create mode 100644 phpBB/phpbb/db/extractor/mysql_extractor.php create mode 100644 phpBB/phpbb/db/extractor/oracle_extractor.php create mode 100644 phpBB/phpbb/db/extractor/postgres_extractor.php create mode 100644 phpBB/phpbb/db/extractor/sqlite3_extractor.php create mode 100644 phpBB/phpbb/db/extractor/sqlite_extractor.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/extractor/base_extractor.php b/phpBB/phpbb/db/extractor/base_extractor.php new file mode 100644 index 0000000000..547c85f066 --- /dev/null +++ b/phpBB/phpbb/db/extractor/base_extractor.php @@ -0,0 +1,252 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor; + +use phpbb\db\extractor\exception\invalid_format_exception; +use phpbb\db\extractor\exception\extractor_not_initialized_exception; + +/** + * Abstract base class for database extraction + */ +abstract class base_extractor implements extractor_interface +{ + /** + * @var string phpBB root path + */ + protected $phpbb_root_path; + + /** + * @var \phpbb\request\request_interface + */ + protected $request; + + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var bool + */ + protected $download; + + /** + * @var bool + */ + protected $store; + + /** + * @var int + */ + protected $time; + + /** + * @var string + */ + protected $format; + + /** + * @var resource + */ + protected $fp; + + /** + * @var string + */ + protected $write; + + /** + * @var string + */ + protected $close; + + /** + * @var bool + */ + protected $run_comp; + + /** + * @var bool + */ + protected $is_initialized; + + /** + * Constructor + * + * @param string $phpbb_root_path + * @param \phpbb\request\request_interface $request + * @param \phpbb\db\driver\driver_interface $db + */ + public function __construct($phpbb_root_path, \phpbb\request\request_interface $request, \phpbb\db\driver\driver_interface $db) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->request = $request; + $this->db = $db; + $this->fp = null; + + $this->is_initialized = false; + } + + /** + * {@inheritdoc} + */ + public function init_extractor($format, $filename, $time, $download = false, $store = false) + { + $this->download = $download; + $this->store = $store; + $this->time = $time; + $this->format = $format; + + switch ($format) + { + case 'text': + $ext = '.sql'; + $open = 'fopen'; + $this->write = 'fwrite'; + $this->close = 'fclose'; + $mimetype = 'text/x-sql'; + break; + case 'bzip2': + $ext = '.sql.bz2'; + $open = 'bzopen'; + $this->write = 'bzwrite'; + $this->close = 'bzclose'; + $mimetype = 'application/x-bzip2'; + break; + case 'gzip': + $ext = '.sql.gz'; + $open = 'gzopen'; + $this->write = 'gzwrite'; + $this->close = 'gzclose'; + $mimetype = 'application/x-gzip'; + break; + default: + throw new invalid_format_exception(); + break; + } + + if ($download === true) + { + $name = $filename . $ext; + header('Cache-Control: private, no-cache'); + header("Content-Type: $mimetype; name=\"$name\""); + header("Content-disposition: attachment; filename=$name"); + + switch ($format) + { + case 'bzip2': + ob_start(); + break; + + case 'gzip': + if (strpos($this->request->header('Accept-Encoding'), 'gzip') !== false && strpos(strtolower($this->request->header('User-Agent')), 'msie') === false) + { + ob_start('ob_gzhandler'); + } + else + { + $this->run_comp = true; + } + break; + } + } + + if ($store === true) + { + $file = $this->phpbb_root_path . 'store/' . $filename . $ext; + + $this->fp = $open($file, 'w'); + + if (!$this->fp) + { + trigger_error('FILE_WRITE_FAIL', E_USER_ERROR); + } + } + + $this->is_initialized = true; + } + + /** + * {@inheritdoc} + */ + public function write_end() + { + static $close; + + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + if ($this->store) + { + if ($close === null) + { + $close = $this->close; + } + $close($this->fp); + } + + // bzip2 must be written all the way at the end + if ($this->download && $this->format === 'bzip2') + { + $c = ob_get_clean(); + echo bzcompress($c); + } + } + + /** + * {@inheritdoc} + */ + public function flush($data) + { + static $write; + + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + if ($this->store === true) + { + if ($write === null) + { + $write = $this->write; + } + $write($this->fp, $data); + } + + if ($this->download === true) + { + if ($this->format === 'bzip2' || $this->format === 'text' || ($this->format === 'gzip' && !$this->run_comp)) + { + echo $data; + } + + // we can write the gzip data as soon as we get it + if ($this->format === 'gzip') + { + if ($this->run_comp) + { + echo gzencode($data); + } + else + { + ob_flush(); + flush(); + } + } + } + } +} diff --git a/phpBB/phpbb/db/extractor/exception/extractor_not_initialized_exception.php b/phpBB/phpbb/db/extractor/exception/extractor_not_initialized_exception.php new file mode 100644 index 0000000000..62eb434be1 --- /dev/null +++ b/phpBB/phpbb/db/extractor/exception/extractor_not_initialized_exception.php @@ -0,0 +1,24 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor\exception; + +use phpbb\exception\runtime_exception; + +/** +* This exception is thrown when invalid format is given to the extractor +*/ +class extractor_not_initialized_exception extends runtime_exception +{ + +} diff --git a/phpBB/phpbb/db/extractor/exception/invalid_format_exception.php b/phpBB/phpbb/db/extractor/exception/invalid_format_exception.php new file mode 100644 index 0000000000..6be24cb5dc --- /dev/null +++ b/phpBB/phpbb/db/extractor/exception/invalid_format_exception.php @@ -0,0 +1,22 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor\exception; + +/** +* This exception is thrown when invalid format is given to the extractor +*/ +class invalid_format_exception extends \InvalidArgumentException +{ + +} diff --git a/phpBB/phpbb/db/extractor/extractor_interface.php b/phpBB/phpbb/db/extractor/extractor_interface.php new file mode 100644 index 0000000000..ff45df9bb7 --- /dev/null +++ b/phpBB/phpbb/db/extractor/extractor_interface.php @@ -0,0 +1,80 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor; + +/** +* Database extractor interface +*/ +interface extractor_interface +{ + /** + * Start the extraction of the database + * + * This function initialize the database extraction. It is required to call this + * function before calling any other extractor functions. + * + * @param string $format + * @param string $filename + * @param int $time + * @param bool $download + * @param bool $store + * @return null + * @throws \phpbb\db\extractor\exception\invalid_format_exception when $format is invalid + */ + public function init_extractor($format, $filename, $time, $download = false, $store = false); + + /** + * Writes header comments to the database backup + * + * @param string $table_prefix prefix of phpBB database tables + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + public function write_start($table_prefix); + + /** + * Closes file and/or dumps download data + * + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + public function write_end(); + + /** + * Extracts database table structure + * + * @param string $table_name name of the database table + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + public function write_table($table_name); + + /** + * Extracts data from database table + * + * @param string $table_name name of the database table + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + public function write_data($table_name); + + /** + * Writes data to file/download content + * + * @param string $data + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + public function flush($data); +} diff --git a/phpBB/phpbb/db/extractor/factory.php b/phpBB/phpbb/db/extractor/factory.php new file mode 100644 index 0000000000..a1ffb65595 --- /dev/null +++ b/phpBB/phpbb/db/extractor/factory.php @@ -0,0 +1,79 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor; + +/** +* A factory which serves the suitable extractor instance for the given dbal +*/ +class factory +{ + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var \Symfony\Component\DependencyInjection\ContainerInterface + */ + protected $container; + + /** + * Extractor factory constructor + * + * @param \phpbb\db\driver\driver_interface $db + * @param \Symfony\Component\DependencyInjection\ContainerInterface $container + */ + public function __construct(\phpbb\db\driver\driver_interface $db, \Symfony\Component\DependencyInjection\ContainerInterface $container) + { + $this->db = $db; + $this->container = $container; + } + + /** + * DB extractor factory getter + * + * @return \phpbb\db\extractor\extractor_interface an appropriate instance of the database extractor for the used database driver + * @throws \InvalidArgumentException when the database driver is unknown + */ + public function get() + { + // Return the appropriate DB extractor + if ($this->db instanceof \phpbb\db\driver\mssql || $this->db instanceof \phpbb\db\driver\mssql_base) + { + return $this->container->get('dbal.extractor.extractors.mssql_extractor'); + } + else if ($this->db instanceof \phpbb\db\driver\mysql_base) + { + return $this->container->get('dbal.extractor.extractors.mysql_extractor'); + } + else if ($this->db instanceof \phpbb\db\driver\oracle) + { + return $this->container->get('dbal.extractor.extractors.oracle_extractor'); + } + else if ($this->db instanceof \phpbb\db\driver\postgres) + { + return $this->container->get('dbal.extractor.extractors.postgres_extractor'); + } + else if ($this->db instanceof \phpbb\db\driver\sqlite) + { + return $this->container->get('dbal.extractor.extractors.sqlite_extractor'); + } + else if ($this->db instanceof \phpbb\db\driver\sqlite3) + { + return $this->container->get('dbal.extractor.extractors.sqlite3_extractor'); + } + + throw new \InvalidArgumentException('Invalid database driver given'); + } +} diff --git a/phpBB/phpbb/db/extractor/mssql_extractor.php b/phpBB/phpbb/db/extractor/mssql_extractor.php new file mode 100644 index 0000000000..d0aa78f1f5 --- /dev/null +++ b/phpBB/phpbb/db/extractor/mssql_extractor.php @@ -0,0 +1,524 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor; + +use phpbb\db\extractor\exception\extractor_not_initialized_exception; + +class mssql_extractor extends base_extractor +{ + /** + * Writes closing line(s) to database backup + * + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + public function write_end() + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $this->flush("COMMIT\nGO\n"); + parent::write_end(); + } + + /** + * {@inheritdoc} + */ + public function write_start($table_prefix) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = "--\n"; + $sql_data .= "-- phpBB Backup Script\n"; + $sql_data .= "-- Dump of tables for $table_prefix\n"; + $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; + $sql_data .= "--\n"; + $sql_data .= "BEGIN TRANSACTION\n"; + $sql_data .= "GO\n"; + $this->flush($sql_data); + } + + /** + * {@inheritdoc} + */ + public function write_table($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = '-- Table: ' . $table_name . "\n"; + $sql_data .= "IF OBJECT_ID(N'$table_name', N'U') IS NOT NULL\n"; + $sql_data .= "DROP TABLE $table_name;\n"; + $sql_data .= "GO\n"; + $sql_data .= "\nCREATE TABLE [$table_name] (\n"; + $rows = array(); + + $text_flag = false; + + $sql = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IS_IDENTITY + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME = '$table_name'"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $line = "\t[{$row['COLUMN_NAME']}] [{$row['DATA_TYPE']}]"; + + if ($row['DATA_TYPE'] == 'text') + { + $text_flag = true; + } + + if ($row['IS_IDENTITY']) + { + $line .= ' IDENTITY (1 , 1)'; + } + + if ($row['CHARACTER_MAXIMUM_LENGTH'] && $row['DATA_TYPE'] !== 'text') + { + $line .= ' (' . $row['CHARACTER_MAXIMUM_LENGTH'] . ')'; + } + + if ($row['IS_NULLABLE'] == 'YES') + { + $line .= ' NULL'; + } + else + { + $line .= ' NOT NULL'; + } + + if ($row['COLUMN_DEFAULT']) + { + $line .= ' DEFAULT ' . $row['COLUMN_DEFAULT']; + } + + $rows[] = $line; + } + $this->db->sql_freeresult($result); + + $sql_data .= implode(",\n", $rows); + $sql_data .= "\n) ON [PRIMARY]"; + + if ($text_flag) + { + $sql_data .= " TEXTIMAGE_ON [PRIMARY]"; + } + + $sql_data .= "\nGO\n\n"; + $rows = array(); + + $sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME + FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE + WHERE TABLE_NAME = '$table_name'"; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (!sizeof($rows)) + { + $sql_data .= "ALTER TABLE [$table_name] WITH NOCHECK ADD\n"; + $sql_data .= "\tCONSTRAINT [{$row['CONSTRAINT_NAME']}] PRIMARY KEY CLUSTERED \n\t(\n"; + } + $rows[] = "\t\t[{$row['COLUMN_NAME']}]"; + } + if (sizeof($rows)) + { + $sql_data .= implode(",\n", $rows); + $sql_data .= "\n\t) ON [PRIMARY] \nGO\n"; + } + $this->db->sql_freeresult($result); + + $index = array(); + $sql = "EXEC sp_statistics '$table_name'"; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if ($row['TYPE'] == 3) + { + $index[$row['INDEX_NAME']][] = '[' . $row['COLUMN_NAME'] . ']'; + } + } + $this->db->sql_freeresult($result); + + foreach ($index as $index_name => $column_name) + { + $index[$index_name] = implode(', ', $column_name); + } + + foreach ($index as $index_name => $columns) + { + $sql_data .= "\nCREATE INDEX [$index_name] ON [$table_name]($columns) ON [PRIMARY]\nGO\n"; + } + $this->flush($sql_data); + } + + /** + * {@inheritdoc} + */ + public function write_data($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + if ($this->db->get_sql_layer() === 'mssql') + { + $this->write_data_mssql($table_name); + } + else if($this->db->get_sql_layer() === 'mssqlnative') + { + $this->write_data_mssqlnative($table_name); + } + else + { + $this->write_data_odbc($table_name); + } + } + + /** + * Extracts data from database table (for MSSQL driver) + * + * @param string $table_name name of the database table + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + protected function write_data_mssql($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $ary_type = $ary_name = array(); + $ident_set = false; + $sql_data = ''; + + // Grab all of the data from current table. + $sql = "SELECT * + FROM $table_name"; + $result = $this->db->sql_query($sql); + + $retrieved_data = mssql_num_rows($result); + + $i_num_fields = mssql_num_fields($result); + + for ($i = 0; $i < $i_num_fields; $i++) + { + $ary_type[$i] = mssql_field_type($result, $i); + $ary_name[$i] = mssql_field_name($result, $i); + } + + if ($retrieved_data) + { + $sql = "SELECT 1 as has_identity + FROM INFORMATION_SCHEMA.COLUMNS + WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1"; + $result2 = $this->db->sql_query($sql); + $row2 = $this->db->sql_fetchrow($result2); + if (!empty($row2['has_identity'])) + { + $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n"; + $ident_set = true; + } + $this->db->sql_freeresult($result2); + } + + while ($row = $this->db->sql_fetchrow($result)) + { + $schema_vals = $schema_fields = array(); + + // Build the SQL statement to recreate the data. + for ($i = 0; $i < $i_num_fields; $i++) + { + $str_val = $row[$ary_name[$i]]; + + if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i])) + { + $str_quote = ''; + $str_empty = "''"; + $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val)); + } + else if (preg_match('#date|timestamp#i', $ary_type[$i])) + { + if (empty($str_val)) + { + $str_quote = ''; + } + else + { + $str_quote = "'"; + } + } + else + { + $str_quote = ''; + $str_empty = 'NULL'; + } + + if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val))) + { + $str_val = $str_empty; + } + + $schema_vals[$i] = $str_quote . $str_val . $str_quote; + $schema_fields[$i] = $ary_name[$i]; + } + + // Take the ordered fields and their associated data and build it + // into a valid sql statement to recreate that field in the data. + $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n"; + + $this->flush($sql_data); + $sql_data = ''; + } + $this->db->sql_freeresult($result); + + if ($retrieved_data && $ident_set) + { + $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n"; + } + $this->flush($sql_data); + } + + /** + * Extracts data from database table (for MSSQL Native driver) + * + * @param string $table_name name of the database table + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + protected function write_data_mssqlnative($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $ary_type = $ary_name = array(); + $ident_set = false; + $sql_data = ''; + + // Grab all of the data from current table. + $sql = "SELECT * FROM $table_name"; + $this->db->mssqlnative_set_query_options(array('Scrollable' => SQLSRV_CURSOR_STATIC)); + $result = $this->db->sql_query($sql); + + $retrieved_data = $this->db->mssqlnative_num_rows($result); + + if (!$retrieved_data) + { + $this->db->sql_freeresult($result); + return; + } + + $sql = "SELECT COLUMN_NAME, DATA_TYPE + FROM INFORMATION_SCHEMA.COLUMNS + WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = '" . $this->db->sql_escape($table_name) . "'"; + $result_fields = $this->db->sql_query($sql); + + $i_num_fields = 0; + while ($row = $this->db->sql_fetchrow($result_fields)) + { + $ary_type[$i_num_fields] = $row['DATA_TYPE']; + $ary_name[$i_num_fields] = $row['COLUMN_NAME']; + $i_num_fields++; + } + $this->db->sql_freeresult($result_fields); + + $sql = "SELECT 1 as has_identity + FROM INFORMATION_SCHEMA.COLUMNS + WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1"; + $result2 = $this->db->sql_query($sql); + $row2 = $this->db->sql_fetchrow($result2); + + if (!empty($row2['has_identity'])) + { + $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n"; + $ident_set = true; + } + $this->db->sql_freeresult($result2); + + while ($row = $this->db->sql_fetchrow($result)) + { + $schema_vals = $schema_fields = array(); + + // Build the SQL statement to recreate the data. + for ($i = 0; $i < $i_num_fields; $i++) + { + $str_val = $row[$ary_name[$i]]; + + // defaults to type number - better quote just to be safe, so check for is_int too + if (is_int($ary_type[$i]) || preg_match('#char|text|bool|varbinary#i', $ary_type[$i])) + { + $str_quote = ''; + $str_empty = "''"; + $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val)); + } + else if (preg_match('#date|timestamp#i', $ary_type[$i])) + { + if (empty($str_val)) + { + $str_quote = ''; + } + else + { + $str_quote = "'"; + } + } + else + { + $str_quote = ''; + $str_empty = 'NULL'; + } + + if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val))) + { + $str_val = $str_empty; + } + + $schema_vals[$i] = $str_quote . $str_val . $str_quote; + $schema_fields[$i] = $ary_name[$i]; + } + + // Take the ordered fields and their associated data and build it + // into a valid sql statement to recreate that field in the data. + $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n"; + + $this->flush($sql_data); + $sql_data = ''; + } + $this->db->sql_freeresult($result); + + if ($ident_set) + { + $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n"; + } + $this->flush($sql_data); + } + + /** + * Extracts data from database table (for ODBC driver) + * + * @param string $table_name name of the database table + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + protected function write_data_odbc($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $ary_type = $ary_name = array(); + $ident_set = false; + $sql_data = ''; + + // Grab all of the data from current table. + $sql = "SELECT * + FROM $table_name"; + $result = $this->db->sql_query($sql); + + $retrieved_data = odbc_num_rows($result); + + if ($retrieved_data) + { + $sql = "SELECT 1 as has_identity + FROM INFORMATION_SCHEMA.COLUMNS + WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1"; + $result2 = $this->db->sql_query($sql); + $row2 = $this->db->sql_fetchrow($result2); + if (!empty($row2['has_identity'])) + { + $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n"; + $ident_set = true; + } + $this->db->sql_freeresult($result2); + } + + $i_num_fields = odbc_num_fields($result); + + for ($i = 0; $i < $i_num_fields; $i++) + { + $ary_type[$i] = odbc_field_type($result, $i + 1); + $ary_name[$i] = odbc_field_name($result, $i + 1); + } + + while ($row = $this->db->sql_fetchrow($result)) + { + $schema_vals = $schema_fields = array(); + + // Build the SQL statement to recreate the data. + for ($i = 0; $i < $i_num_fields; $i++) + { + $str_val = $row[$ary_name[$i]]; + + if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i])) + { + $str_quote = ''; + $str_empty = "''"; + $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val)); + } + else if (preg_match('#date|timestamp#i', $ary_type[$i])) + { + if (empty($str_val)) + { + $str_quote = ''; + } + else + { + $str_quote = "'"; + } + } + else + { + $str_quote = ''; + $str_empty = 'NULL'; + } + + if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val))) + { + $str_val = $str_empty; + } + + $schema_vals[$i] = $str_quote . $str_val . $str_quote; + $schema_fields[$i] = $ary_name[$i]; + } + + // Take the ordered fields and their associated data and build it + // into a valid sql statement to recreate that field in the data. + $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n"; + + $this->flush($sql_data); + + $sql_data = ''; + + } + $this->db->sql_freeresult($result); + + if ($retrieved_data && $ident_set) + { + $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n"; + } + $this->flush($sql_data); + } +} diff --git a/phpBB/phpbb/db/extractor/mysql_extractor.php b/phpBB/phpbb/db/extractor/mysql_extractor.php new file mode 100644 index 0000000000..34e309c19e --- /dev/null +++ b/phpBB/phpbb/db/extractor/mysql_extractor.php @@ -0,0 +1,403 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor; + +use phpbb\db\extractor\exception\extractor_not_initialized_exception; + +class mysql_extractor extends base_extractor +{ + /** + * {@inheritdoc} + */ + public function write_start($table_prefix) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = "#\n"; + $sql_data .= "# phpBB Backup Script\n"; + $sql_data .= "# Dump of tables for $table_prefix\n"; + $sql_data .= "# DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; + $sql_data .= "#\n"; + $this->flush($sql_data); + } + + /** + * {@inheritdoc} + */ + public function write_table($table_name) + { + static $new_extract; + + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + if ($new_extract === null) + { + if ($this->db->get_sql_layer() === 'mysqli' || version_compare($this->db->sql_server_info(true), '3.23.20', '>=')) + { + $new_extract = true; + } + else + { + $new_extract = false; + } + } + + if ($new_extract) + { + $this->new_write_table($table_name); + } + else + { + $this->old_write_table($table_name); + } + } + + /** + * {@inheritdoc} + */ + public function write_data($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + if ($this->db->get_sql_layer() === 'mysqli') + { + $this->write_data_mysqli($table_name); + } + else + { + $this->write_data_mysql($table_name); + } + } + + /** + * Extracts data from database table (for MySQLi driver) + * + * @param string $table_name name of the database table + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + protected function write_data_mysqli($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql = "SELECT * + FROM $table_name"; + $result = mysqli_query($this->db->get_db_connect_id(), $sql, MYSQLI_USE_RESULT); + if ($result != false) + { + $fields_cnt = mysqli_num_fields($result); + + // Get field information + $field = mysqli_fetch_fields($result); + $field_set = array(); + + for ($j = 0; $j < $fields_cnt; $j++) + { + $field_set[] = $field[$j]->name; + } + + $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"'); + $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"'); + $fields = implode(', ', $field_set); + $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES '; + $first_set = true; + $query_len = 0; + $max_len = get_usable_memory(); + + while ($row = mysqli_fetch_row($result)) + { + $values = array(); + if ($first_set) + { + $query = $sql_data . '('; + } + else + { + $query .= ',('; + } + + for ($j = 0; $j < $fields_cnt; $j++) + { + if (!isset($row[$j]) || is_null($row[$j])) + { + $values[$j] = 'NULL'; + } + else if (($field[$j]->flags & 32768) && !($field[$j]->flags & 1024)) + { + $values[$j] = $row[$j]; + } + else + { + $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'"; + } + } + $query .= implode(', ', $values) . ')'; + + $query_len += strlen($query); + if ($query_len > $max_len) + { + $this->flush($query . ";\n\n"); + $query = ''; + $query_len = 0; + $first_set = true; + } + else + { + $first_set = false; + } + } + mysqli_free_result($result); + + // check to make sure we have nothing left to flush + if (!$first_set && $query) + { + $this->flush($query . ";\n\n"); + } + } + } + + /** + * Extracts data from database table (for MySQL driver) + * + * @param string $table_name name of the database table + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + protected function write_data_mysql($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql = "SELECT * + FROM $table_name"; + $result = mysql_unbuffered_query($sql, $this->db->get_db_connect_id()); + + if ($result != false) + { + $fields_cnt = mysql_num_fields($result); + + // Get field information + $field = array(); + for ($i = 0; $i < $fields_cnt; $i++) + { + $field[] = mysql_fetch_field($result, $i); + } + $field_set = array(); + + for ($j = 0; $j < $fields_cnt; $j++) + { + $field_set[] = $field[$j]->name; + } + + $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"'); + $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"'); + $fields = implode(', ', $field_set); + $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES '; + $first_set = true; + $query_len = 0; + $max_len = get_usable_memory(); + + while ($row = mysql_fetch_row($result)) + { + $values = array(); + if ($first_set) + { + $query = $sql_data . '('; + } + else + { + $query .= ',('; + } + + for ($j = 0; $j < $fields_cnt; $j++) + { + if (!isset($row[$j]) || is_null($row[$j])) + { + $values[$j] = 'NULL'; + } + else if ($field[$j]->numeric && ($field[$j]->type !== 'timestamp')) + { + $values[$j] = $row[$j]; + } + else + { + $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'"; + } + } + $query .= implode(', ', $values) . ')'; + + $query_len += strlen($query); + if ($query_len > $max_len) + { + $this->flush($query . ";\n\n"); + $query = ''; + $query_len = 0; + $first_set = true; + } + else + { + $first_set = false; + } + } + mysql_free_result($result); + + // check to make sure we have nothing left to flush + if (!$first_set && $query) + { + $this->flush($query . ";\n\n"); + } + } + } + + /** + * Extracts database table structure (for MySQLi or MySQL 3.23.20+) + * + * @param string $table_name name of the database table + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + protected function new_write_table($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql = 'SHOW CREATE TABLE ' . $table_name; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + + $sql_data = '# Table: ' . $table_name . "\n"; + $sql_data .= "DROP TABLE IF EXISTS $table_name;\n"; + $this->flush($sql_data . $row['Create Table'] . ";\n\n"); + + $this->db->sql_freeresult($result); + } + + /** + * Extracts database table structure (for MySQL verisons older than 3.23.20) + * + * @param string $table_name name of the database table + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + protected function old_write_table($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = '# Table: ' . $table_name . "\n"; + $sql_data .= "DROP TABLE IF EXISTS $table_name;\n"; + $sql_data .= "CREATE TABLE $table_name(\n"; + $rows = array(); + + $sql = "SHOW FIELDS + FROM $table_name"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $line = ' ' . $row['Field'] . ' ' . $row['Type']; + + if (!is_null($row['Default'])) + { + $line .= " DEFAULT '{$row['Default']}'"; + } + + if ($row['Null'] != 'YES') + { + $line .= ' NOT NULL'; + } + + if ($row['Extra'] != '') + { + $line .= ' ' . $row['Extra']; + } + + $rows[] = $line; + } + $this->db->sql_freeresult($result); + + $sql = "SHOW KEYS + FROM $table_name"; + + $result = $this->db->sql_query($sql); + + $index = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $kname = $row['Key_name']; + + if ($kname != 'PRIMARY') + { + if ($row['Non_unique'] == 0) + { + $kname = "UNIQUE|$kname"; + } + } + + if ($row['Sub_part']) + { + $row['Column_name'] .= '(' . $row['Sub_part'] . ')'; + } + $index[$kname][] = $row['Column_name']; + } + $this->db->sql_freeresult($result); + + foreach ($index as $key => $columns) + { + $line = ' '; + + if ($key == 'PRIMARY') + { + $line .= 'PRIMARY KEY (' . implode(', ', $columns) . ')'; + } + else if (strpos($key, 'UNIQUE') === 0) + { + $line .= 'UNIQUE ' . substr($key, 7) . ' (' . implode(', ', $columns) . ')'; + } + else if (strpos($key, 'FULLTEXT') === 0) + { + $line .= 'FULLTEXT ' . substr($key, 9) . ' (' . implode(', ', $columns) . ')'; + } + else + { + $line .= "KEY $key (" . implode(', ', $columns) . ')'; + } + + $rows[] = $line; + } + + $sql_data .= implode(",\n", $rows); + $sql_data .= "\n);\n\n"; + + $this->flush($sql_data); + } +} diff --git a/phpBB/phpbb/db/extractor/oracle_extractor.php b/phpBB/phpbb/db/extractor/oracle_extractor.php new file mode 100644 index 0000000000..05f7b8ac95 --- /dev/null +++ b/phpBB/phpbb/db/extractor/oracle_extractor.php @@ -0,0 +1,265 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor; + +use phpbb\db\extractor\exception\extractor_not_initialized_exception; + +class oracle_extractor extends base_extractor +{ + /** + * {@inheritdoc} + */ + public function write_table($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = '-- Table: ' . $table_name . "\n"; + $sql_data .= "DROP TABLE $table_name\n/\n"; + $sql_data .= "\nCREATE TABLE $table_name (\n"; + + $sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT + FROM ALL_TAB_COLS + WHERE table_name = '{$table_name}'"; + $result = $this->db->sql_query($sql); + + $rows = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $line = ' "' . $row['column_name'] . '" ' . $row['data_type']; + + if ($row['data_type'] !== 'CLOB') + { + if ($row['data_type'] !== 'VARCHAR2' && $row['data_type'] !== 'CHAR') + { + $line .= '(' . $row['data_precision'] . ')'; + } + else + { + $line .= '(' . $row['data_length'] . ')'; + } + } + + if (!empty($row['data_default'])) + { + $line .= ' DEFAULT ' . $row['data_default']; + } + + if ($row['nullable'] == 'N') + { + $line .= ' NOT NULL'; + } + $rows[] = $line; + } + $this->db->sql_freeresult($result); + + $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME + FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B + WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME + AND B.CONSTRAINT_TYPE = 'P' + AND A.TABLE_NAME = '{$table_name}'"; + $result = $this->db->sql_query($sql); + + $primary_key = array(); + $constraint_name = ''; + while ($row = $this->db->sql_fetchrow($result)) + { + $constraint_name = '"' . $row['constraint_name'] . '"'; + $primary_key[] = '"' . $row['column_name'] . '"'; + } + $this->db->sql_freeresult($result); + + if (sizeof($primary_key)) + { + $rows[] = " CONSTRAINT {$constraint_name} PRIMARY KEY (" . implode(', ', $primary_key) . ')'; + } + + $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME + FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B + WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME + AND B.CONSTRAINT_TYPE = 'U' + AND A.TABLE_NAME = '{$table_name}'"; + $result = $this->db->sql_query($sql); + + $unique = array(); + $constraint_name = ''; + while ($row = $this->db->sql_fetchrow($result)) + { + $constraint_name = '"' . $row['constraint_name'] . '"'; + $unique[] = '"' . $row['column_name'] . '"'; + } + $this->db->sql_freeresult($result); + + if (sizeof($unique)) + { + $rows[] = " CONSTRAINT {$constraint_name} UNIQUE (" . implode(', ', $unique) . ')'; + } + + $sql_data .= implode(",\n", $rows); + $sql_data .= "\n)\n/\n"; + + $sql = "SELECT A.REFERENCED_NAME, C.* + FROM USER_DEPENDENCIES A, USER_TRIGGERS B, USER_SEQUENCES C + WHERE A.REFERENCED_TYPE = 'SEQUENCE' + AND A.NAME = B.TRIGGER_NAME + AND B.TABLE_NAME = '{$table_name}' + AND C.SEQUENCE_NAME = A.REFERENCED_NAME"; + $result = $this->db->sql_query($sql); + + $type = $this->request->variable('type', ''); + + while ($row = $this->db->sql_fetchrow($result)) + { + $sql_data .= "\nDROP SEQUENCE \"{$row['referenced_name']}\"\n/\n"; + $sql_data .= "\nCREATE SEQUENCE \"{$row['referenced_name']}\""; + + if ($type == 'full') + { + $sql_data .= ' START WITH ' . $row['last_number']; + } + + $sql_data .= "\n/\n"; + } + $this->db->sql_freeresult($result); + + $sql = "SELECT DESCRIPTION, WHEN_CLAUSE, TRIGGER_BODY + FROM USER_TRIGGERS + WHERE TABLE_NAME = '{$table_name}'"; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\n/\n"; + } + $this->db->sql_freeresult($result); + + $sql = "SELECT A.INDEX_NAME, B.COLUMN_NAME + FROM USER_INDEXES A, USER_IND_COLUMNS B + WHERE A.UNIQUENESS = 'NONUNIQUE' + AND A.INDEX_NAME = B.INDEX_NAME + AND B.TABLE_NAME = '{$table_name}'"; + $result = $this->db->sql_query($sql); + + $index = array(); + + while ($row = $this->db->sql_fetchrow($result)) + { + $index[$row['index_name']][] = $row['column_name']; + } + + foreach ($index as $index_name => $column_names) + { + $sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n/\n"; + } + $this->db->sql_freeresult($result); + $this->flush($sql_data); + } + + /** + * {@inheritdoc} + */ + public function write_data($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $ary_type = $ary_name = array(); + + // Grab all of the data from current table. + $sql = "SELECT * + FROM $table_name"; + $result = $this->db->sql_query($sql); + + $i_num_fields = ocinumcols($result); + + for ($i = 0; $i < $i_num_fields; $i++) + { + $ary_type[$i] = ocicolumntype($result, $i + 1); + $ary_name[$i] = ocicolumnname($result, $i + 1); + } + + $sql_data = ''; + + while ($row = $this->db->sql_fetchrow($result)) + { + $schema_vals = $schema_fields = array(); + + // Build the SQL statement to recreate the data. + for ($i = 0; $i < $i_num_fields; $i++) + { + // Oracle uses uppercase - we use lowercase + $str_val = $row[strtolower($ary_name[$i])]; + + if (preg_match('#char|text|bool|raw|clob#i', $ary_type[$i])) + { + $str_quote = ''; + $str_empty = "''"; + $str_val = sanitize_data_oracle($str_val); + } + else if (preg_match('#date|timestamp#i', $ary_type[$i])) + { + if (empty($str_val)) + { + $str_quote = ''; + } + else + { + $str_quote = "'"; + } + } + else + { + $str_quote = ''; + $str_empty = 'NULL'; + } + + if (empty($str_val) && $str_val !== '0') + { + $str_val = $str_empty; + } + + $schema_vals[$i] = $str_quote . $str_val . $str_quote; + $schema_fields[$i] = '"' . $ary_name[$i] . '"'; + } + + // Take the ordered fields and their associated data and build it + // into a valid sql statement to recreate that field in the data. + $sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ")\n/\n"; + + $this->flush($sql_data); + } + $this->db->sql_freeresult($result); + } + + /** + * {@inheritdoc} + */ + public function write_start($table_prefix) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = "--\n"; + $sql_data .= "-- phpBB Backup Script\n"; + $sql_data .= "-- Dump of tables for $table_prefix\n"; + $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; + $sql_data .= "--\n"; + $this->flush($sql_data); + } +} diff --git a/phpBB/phpbb/db/extractor/postgres_extractor.php b/phpBB/phpbb/db/extractor/postgres_extractor.php new file mode 100644 index 0000000000..9eff1f568d --- /dev/null +++ b/phpBB/phpbb/db/extractor/postgres_extractor.php @@ -0,0 +1,338 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor; + +use phpbb\db\extractor\exception\extractor_not_initialized_exception; + +class postgres_extractor extends base_extractor +{ + /** + * {@inheritdoc} + */ + public function write_start($table_prefix) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = "--\n"; + $sql_data .= "-- phpBB Backup Script\n"; + $sql_data .= "-- Dump of tables for $table_prefix\n"; + $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; + $sql_data .= "--\n"; + $sql_data .= "BEGIN TRANSACTION;\n"; + $this->flush($sql_data); + } + + /** + * {@inheritdoc} + */ + public function write_table($table_name) + { + static $domains_created = array(); + + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql = "SELECT a.domain_name, a.data_type, a.character_maximum_length, a.domain_default + FROM INFORMATION_SCHEMA.domains a, INFORMATION_SCHEMA.column_domain_usage b + WHERE a.domain_name = b.domain_name + AND b.table_name = '{$table_name}'"; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (empty($domains_created[$row['domain_name']])) + { + $domains_created[$row['domain_name']] = true; + //$sql_data = "DROP DOMAIN {$row['domain_name']};\n"; + $sql_data = "CREATE DOMAIN {$row['domain_name']} as {$row['data_type']}"; + if (!empty($row['character_maximum_length'])) + { + $sql_data .= '(' . $row['character_maximum_length'] . ')'; + } + $sql_data .= ' NOT NULL'; + if (!empty($row['domain_default'])) + { + $sql_data .= ' DEFAULT ' . $row['domain_default']; + } + $this->flush($sql_data . ";\n"); + } + } + + $sql_data = '-- Table: ' . $table_name . "\n"; + $sql_data .= "DROP TABLE $table_name;\n"; + // PGSQL does not "tightly" bind sequences and tables, we must guess... + $sql = "SELECT relname + FROM pg_class + WHERE relkind = 'S' + AND relname = '{$table_name}_seq'"; + $result = $this->db->sql_query($sql); + // We don't even care about storing the results. We already know the answer if we get rows back. + if ($this->db->sql_fetchrow($result)) + { + $sql_data .= "DROP SEQUENCE {$table_name}_seq;\n"; + $sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n"; + } + $this->db->sql_freeresult($result); + + $field_query = "SELECT a.attnum, a.attname as field, t.typname as type, a.attlen as length, a.atttypmod as lengthvar, a.attnotnull as notnull + FROM pg_class c, pg_attribute a, pg_type t + WHERE c.relname = '" . $this->db->sql_escape($table_name) . "' + AND a.attnum > 0 + AND a.attrelid = c.oid + AND a.atttypid = t.oid + ORDER BY a.attnum"; + $result = $this->db->sql_query($field_query); + + $sql_data .= "CREATE TABLE $table_name(\n"; + $lines = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + // Get the data from the table + $sql_get_default = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault + FROM pg_attrdef d, pg_class c + WHERE (c.relname = '" . $this->db->sql_escape($table_name) . "') + AND (c.oid = d.adrelid) + AND d.adnum = " . $row['attnum']; + $def_res = $this->db->sql_query($sql_get_default); + $def_row = $this->db->sql_fetchrow($def_res); + $this->db->sql_freeresult($def_res); + + if (empty($def_row)) + { + unset($row['rowdefault']); + } + else + { + $row['rowdefault'] = $def_row['rowdefault']; + } + + if ($row['type'] == 'bpchar') + { + // Internally stored as bpchar, but isn't accepted in a CREATE TABLE statement. + $row['type'] = 'char'; + } + + $line = ' ' . $row['field'] . ' ' . $row['type']; + + if (strpos($row['type'], 'char') !== false) + { + if ($row['lengthvar'] > 0) + { + $line .= '(' . ($row['lengthvar'] - 4) . ')'; + } + } + + if (strpos($row['type'], 'numeric') !== false) + { + $line .= '('; + $line .= sprintf("%s,%s", (($row['lengthvar'] >> 16) & 0xffff), (($row['lengthvar'] - 4) & 0xffff)); + $line .= ')'; + } + + if (isset($row['rowdefault'])) + { + $line .= ' DEFAULT ' . $row['rowdefault']; + } + + if ($row['notnull'] == 't') + { + $line .= ' NOT NULL'; + } + + $lines[] = $line; + } + $this->db->sql_freeresult($result); + + // Get the listing of primary keys. + $sql_pri_keys = "SELECT ic.relname as index_name, bc.relname as tab_name, ta.attname as column_name, i.indisunique as unique_key, i.indisprimary as primary_key + FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia + WHERE (bc.oid = i.indrelid) + AND (ic.oid = i.indexrelid) + AND (ia.attrelid = i.indexrelid) + AND (ta.attrelid = bc.oid) + AND (bc.relname = '" . $this->db->sql_escape($table_name) . "') + AND (ta.attrelid = i.indrelid) + AND (ta.attnum = i.indkey[ia.attnum-1]) + ORDER BY index_name, tab_name, column_name"; + + $result = $this->db->sql_query($sql_pri_keys); + + $index_create = $index_rows = $primary_key = array(); + + // We do this in two steps. It makes placing the comma easier + while ($row = $this->db->sql_fetchrow($result)) + { + if ($row['primary_key'] == 't') + { + $primary_key[] = $row['column_name']; + $primary_key_name = $row['index_name']; + } + else + { + // We have to store this all this info because it is possible to have a multi-column key... + // we can loop through it again and build the statement + $index_rows[$row['index_name']]['table'] = $table_name; + $index_rows[$row['index_name']]['unique'] = ($row['unique_key'] == 't') ? true : false; + $index_rows[$row['index_name']]['column_names'][] = $row['column_name']; + } + } + $this->db->sql_freeresult($result); + + if (!empty($index_rows)) + { + foreach ($index_rows as $idx_name => $props) + { + $index_create[] = 'CREATE ' . ($props['unique'] ? 'UNIQUE ' : '') . "INDEX $idx_name ON $table_name (" . implode(', ', $props['column_names']) . ");"; + } + } + + if (!empty($primary_key)) + { + $lines[] = " CONSTRAINT $primary_key_name PRIMARY KEY (" . implode(', ', $primary_key) . ")"; + } + + // Generate constraint clauses for CHECK constraints + $sql_checks = "SELECT conname as index_name, consrc + FROM pg_constraint, pg_class bc + WHERE conrelid = bc.oid + AND bc.relname = '" . $this->db->sql_escape($table_name) . "' + AND NOT EXISTS ( + SELECT * + FROM pg_constraint as c, pg_inherits as i + WHERE i.inhrelid = pg_constraint.conrelid + AND c.conname = pg_constraint.conname + AND c.consrc = pg_constraint.consrc + AND c.conrelid = i.inhparent + )"; + $result = $this->db->sql_query($sql_checks); + + // Add the constraints to the sql file. + while ($row = $this->db->sql_fetchrow($result)) + { + if (!is_null($row['consrc'])) + { + $lines[] = ' CONSTRAINT ' . $row['index_name'] . ' CHECK ' . $row['consrc']; + } + } + $this->db->sql_freeresult($result); + + $sql_data .= implode(", \n", $lines); + $sql_data .= "\n);\n"; + + if (!empty($index_create)) + { + $sql_data .= implode("\n", $index_create) . "\n\n"; + } + $this->flush($sql_data); + } + + /** + * {@inheritdoc} + */ + public function write_data($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + // Grab all of the data from current table. + $sql = "SELECT * + FROM $table_name"; + $result = $this->db->sql_query($sql); + + $i_num_fields = pg_num_fields($result); + $seq = ''; + + for ($i = 0; $i < $i_num_fields; $i++) + { + $ary_type[] = pg_field_type($result, $i); + $ary_name[] = pg_field_name($result, $i); + + $sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault + FROM pg_attrdef d, pg_class c + WHERE (c.relname = '{$table_name}') + AND (c.oid = d.adrelid) + AND d.adnum = " . strval($i + 1); + $result2 = $this->db->sql_query($sql); + if ($row = $this->db->sql_fetchrow($result2)) + { + // Determine if we must reset the sequences + if (strpos($row['rowdefault'], "nextval('") === 0) + { + $seq .= "SELECT SETVAL('{$table_name}_seq',(select case when max({$ary_name[$i]})>0 then max({$ary_name[$i]})+1 else 1 end FROM {$table_name}));\n"; + } + } + } + + $this->flush("COPY $table_name (" . implode(', ', $ary_name) . ') FROM stdin;' . "\n"); + while ($row = $this->db->sql_fetchrow($result)) + { + $schema_vals = array(); + + // Build the SQL statement to recreate the data. + for ($i = 0; $i < $i_num_fields; $i++) + { + $str_val = $row[$ary_name[$i]]; + + if (preg_match('#char|text|bool|bytea#i', $ary_type[$i])) + { + $str_val = str_replace(array("\n", "\t", "\r", "\b", "\f", "\v"), array('\n', '\t', '\r', '\b', '\f', '\v'), addslashes($str_val)); + $str_empty = ''; + } + else + { + $str_empty = '\N'; + } + + if (empty($str_val) && $str_val !== '0') + { + $str_val = $str_empty; + } + + $schema_vals[] = $str_val; + } + + // Take the ordered fields and their associated data and build it + // into a valid sql statement to recreate that field in the data. + $this->flush(implode("\t", $schema_vals) . "\n"); + } + $this->db->sql_freeresult($result); + $this->flush("\\.\n"); + + // Write out the sequence statements + $this->flush($seq); + } + + /** + * Writes closing line(s) to database backup + * + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + public function write_end() + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $this->flush("COMMIT;\n"); + parent::write_end(); + } +} diff --git a/phpBB/phpbb/db/extractor/sqlite3_extractor.php b/phpBB/phpbb/db/extractor/sqlite3_extractor.php new file mode 100644 index 0000000000..ce8da6a652 --- /dev/null +++ b/phpBB/phpbb/db/extractor/sqlite3_extractor.php @@ -0,0 +1,151 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor; + +use phpbb\db\extractor\exception\extractor_not_initialized_exception; + +class sqlite3_extractor extends base_extractor +{ + /** + * {@inheritdoc} + */ + public function write_start($table_prefix) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = "--\n"; + $sql_data .= "-- phpBB Backup Script\n"; + $sql_data .= "-- Dump of tables for $table_prefix\n"; + $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; + $sql_data .= "--\n"; + $sql_data .= "BEGIN TRANSACTION;\n"; + $this->flush($sql_data); + } + + /** + * {@inheritdoc} + */ + public function write_table($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = '-- Table: ' . $table_name . "\n"; + $sql_data .= "DROP TABLE $table_name;\n"; + + $sql = "SELECT sql + FROM sqlite_master + WHERE type = 'table' + AND name = '" . $this->db->sql_escape($table_name) . "' + ORDER BY name ASC;"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + // Create Table + $sql_data .= $row['sql'] . ";\n"; + + $result = $this->db->sql_query("PRAGMA index_list('" . $this->db->sql_escape($table_name) . "');"); + + while ($row = $this->db->sql_fetchrow($result)) + { + if (strpos($row['name'], 'autoindex') !== false) + { + continue; + } + + $result2 = $this->db->sql_query("PRAGMA index_info('" . $this->db->sql_escape($row['name']) . "');"); + + $fields = array(); + while ($row2 = $this->db->sql_fetchrow($result2)) + { + $fields[] = $row2['name']; + } + $this->db->sql_freeresult($result2); + + $sql_data .= 'CREATE ' . ($row['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $row['name'] . ' ON ' . $table_name . ' (' . implode(', ', $fields) . ");\n"; + } + $this->db->sql_freeresult($result); + + $this->flush($sql_data . "\n"); + } + + /** + * {@inheritdoc} + */ + public function write_data($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $result = $this->db->sql_query("PRAGMA table_info('" . $this->db->sql_escape($table_name) . "');"); + + $col_types = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $col_types[$row['name']] = $row['type']; + } + $this->db->sql_freeresult($result); + + $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES ('; + + $sql = "SELECT * + FROM $table_name"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + foreach ($row as $column_name => $column_data) + { + if (is_null($column_data)) + { + $row[$column_name] = 'NULL'; + } + else if ($column_data === '') + { + $row[$column_name] = "''"; + } + else if (stripos($col_types[$column_name], 'text') !== false || stripos($col_types[$column_name], 'char') !== false || stripos($col_types[$column_name], 'blob') !== false) + { + $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data)); + } + } + $this->flush($sql_insert . implode(', ', $row) . ");\n"); + } + } + + /** + * Writes closing line(s) to database backup + * + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + public function write_end() + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $this->flush("COMMIT;\n"); + parent::write_end(); + } +} diff --git a/phpBB/phpbb/db/extractor/sqlite_extractor.php b/phpBB/phpbb/db/extractor/sqlite_extractor.php new file mode 100644 index 0000000000..2734e23235 --- /dev/null +++ b/phpBB/phpbb/db/extractor/sqlite_extractor.php @@ -0,0 +1,149 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\extractor; + +use phpbb\db\extractor\exception\extractor_not_initialized_exception; + +class sqlite_extractor extends base_extractor +{ + /** + * {@inheritdoc} + */ + public function write_start($table_prefix) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = "--\n"; + $sql_data .= "-- phpBB Backup Script\n"; + $sql_data .= "-- Dump of tables for $table_prefix\n"; + $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; + $sql_data .= "--\n"; + $sql_data .= "BEGIN TRANSACTION;\n"; + $this->flush($sql_data); + } + + /** + * {@inheritdoc} + */ + public function write_table($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $sql_data = '-- Table: ' . $table_name . "\n"; + $sql_data .= "DROP TABLE $table_name;\n"; + + $sql = "SELECT sql + FROM sqlite_master + WHERE type = 'table' + AND name = '" . $this->db->sql_escape($table_name) . "' + ORDER BY type DESC, name;"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + // Create Table + $sql_data .= $row['sql'] . ";\n"; + + $result = $this->db->sql_query("PRAGMA index_list('" . $this->db->sql_escape($table_name) . "');"); + + $ar = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $ar[] = $row; + } + $this->db->sql_freeresult($result); + + foreach ($ar as $value) + { + if (strpos($value['name'], 'autoindex') !== false) + { + continue; + } + + $result = $this->db->sql_query("PRAGMA index_info('" . $this->db->sql_escape($value['name']) . "');"); + + $fields = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $fields[] = $row['name']; + } + $this->db->sql_freeresult($result); + + $sql_data .= 'CREATE ' . ($value['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $value['name'] . ' on ' . $table_name . ' (' . implode(', ', $fields) . ");\n"; + } + + $this->flush($sql_data . "\n"); + } + + /** + * {@inheritdoc} + */ + public function write_data($table_name) + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $col_types = sqlite_fetch_column_types($this->db->get_db_connect_id(), $table_name); + + $sql = "SELECT * + FROM $table_name"; + $result = sqlite_unbuffered_query($this->db->get_db_connect_id(), $sql); + $rows = sqlite_fetch_all($result, SQLITE_ASSOC); + $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES ('; + foreach ($rows as $row) + { + foreach ($row as $column_name => $column_data) + { + if (is_null($column_data)) + { + $row[$column_name] = 'NULL'; + } + else if ($column_data == '') + { + $row[$column_name] = "''"; + } + else if (strpos($col_types[$column_name], 'text') !== false || strpos($col_types[$column_name], 'char') !== false || strpos($col_types[$column_name], 'blob') !== false) + { + $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data)); + } + } + $this->flush($sql_insert . implode(', ', $row) . ");\n"); + } + } + + /** + * Writes closing line(s) to database backup + * + * @return null + * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() + */ + public function write_end() + { + if (!$this->is_initialized) + { + throw new extractor_not_initialized_exception(); + } + + $this->flush("COMMIT;\n"); + parent::write_end(); + } +} -- cgit v1.2.1 From 7e0d54a331ccb569dafeae8b051db5a34e177b5f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 27 Feb 2015 22:58:51 +0100 Subject: [ticket/13647] Use the Symfony way for redirecting PHPBB3-13647 --- phpBB/phpbb/help/controller/help.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/help/controller/help.php b/phpBB/phpbb/help/controller/help.php index e9594a0563..9cc3b0c8b4 100644 --- a/phpBB/phpbb/help/controller/help.php +++ b/phpBB/phpbb/help/controller/help.php @@ -97,7 +97,7 @@ class help if ($ext_name === '' || $lang_file === '') { - throw new http_exception(501, 'FEATURE_NOT_AVAILABLE'); + throw new http_exception(404, 'Not Found'); } $this->user->add_lang($lang_file, false, true, $ext_name); -- cgit v1.2.1 From cf39cfc5939f9407082f8f5c1f876ea0ee607a45 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Tue, 7 Oct 2014 20:51:08 +0200 Subject: [ticket/13132] Twig: Add loops content to the root context PHPBB3-13132 --- phpBB/phpbb/template/twig/twig.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php index 605d37e954..0e4c619029 100644 --- a/phpBB/phpbb/template/twig/twig.php +++ b/phpBB/phpbb/template/twig/twig.php @@ -352,6 +352,12 @@ class twig extends \phpbb\template\base // cleanup unset($vars['loops']['.']); + // Inject in the main context the value added by assign_block_vars() to be able to use directly the Twig loops. + foreach ($vars['loops'] as $key => &$value) + { + $vars[$key] = $value; + } + return $vars; } -- cgit v1.2.1 From 5c77e4381945300ba9a1086b99fac12ae48c52a8 Mon Sep 17 00:00:00 2001 From: brunoais Date: Tue, 24 Feb 2015 23:03:11 +0000 Subject: [feature/sql-bool-builder] First working version PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 92 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 8d360fc3e2..5822adceab 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -792,6 +792,98 @@ abstract class driver implements driver_interface return $sql; } + + + protected function _process_boolean_tree_first($operations_ary) + { + if ($operations_ary[0] !== 'AND' && + $operations_ary[0] !== 'OR') + { + $operations_ary = array('AND', $operations_ary); + } + return $this->_process_boolean_tree($operations_ary) . "\n"; + } + + protected function _process_boolean_tree($operations_ary) + { + $operation = array_shift($operations_ary); + + foreach ($operations_ary AS &$condition) + { + switch ($condition[0]) + { + case 'AND': + case 'OR': + + $condition = ' ( ' . $this->_process_boolean_tree($condition) . ') '; + + break; + case 'NOT': + + $condition = ' NOT ' . $this->_process_boolean_tree($condition); + + break; + + default: + + switch (sizeof($condition)) + { + case 3: + + // Typical 3 element clause with {left hand} {operator} {right hand} + switch ($condition[1]) + { + case 'IN': + case 'NOT_IN': + + // As this is used with an IN, assume it is a set of elements for sql_in_set() + $condition = $this->sql_in_set($condition[0], $condition[2], $condition[1] === 'NOT_IN', true); + + break; + + default: + + $condition = implode(' ', $condition); + + break; + } + + break; + + case 5: + + // Subquery with {left hand} {operator} {compare kind} {SELECT Kind } {Sub Query} + + $condition = $condition[0] . ' ' . $condition[1] . ' ' . $condition[2] . ' ( '; + $condition .= $this->sql_build_query($condition[3], $condition[4]); + $condition .= ' )'; + + break; + + default: + // This is an unpredicted clause setup. Just join all elements. + $condition = implode(' ', $condition); + + break; + } + + break; + } + + } + + if($operation === 'NOT') + { + $operations_ary = implode("", $operations_ary); + } + else + { + $operations_ary = implode(" \n $operation ", $operations_ary); + } + + return $operations_ary; + } + /** * {@inheritDoc} -- cgit v1.2.1 From b54adaaabed7546254ff8317763214cce3a40237 Mon Sep 17 00:00:00 2001 From: brunoais Date: Wed, 25 Feb 2015 07:54:31 +0000 Subject: [feature/sql-bool-builder] Removed non-necessary spaces PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 58 ++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 5822adceab..cdff6bf9de 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -792,11 +792,11 @@ abstract class driver implements driver_interface return $sql; } - - + + protected function _process_boolean_tree_first($operations_ary) { - if ($operations_ary[0] !== 'AND' && + if ($operations_ary[0] !== 'AND' && $operations_ary[0] !== 'OR') { $operations_ary = array('AND', $operations_ary); @@ -807,71 +807,71 @@ abstract class driver implements driver_interface protected function _process_boolean_tree($operations_ary) { $operation = array_shift($operations_ary); - + foreach ($operations_ary AS &$condition) { switch ($condition[0]) { case 'AND': case 'OR': - + $condition = ' ( ' . $this->_process_boolean_tree($condition) . ') '; - + break; case 'NOT': - + $condition = ' NOT ' . $this->_process_boolean_tree($condition); - + break; - + default: - + switch (sizeof($condition)) { case 3: - + // Typical 3 element clause with {left hand} {operator} {right hand} switch ($condition[1]) - { + { case 'IN': case 'NOT_IN': - + // As this is used with an IN, assume it is a set of elements for sql_in_set() $condition = $this->sql_in_set($condition[0], $condition[2], $condition[1] === 'NOT_IN', true); - + break; - + default: - + $condition = implode(' ', $condition); - + break; } - + break; - + case 5: - + // Subquery with {left hand} {operator} {compare kind} {SELECT Kind } {Sub Query} - + $condition = $condition[0] . ' ' . $condition[1] . ' ' . $condition[2] . ' ( '; $condition .= $this->sql_build_query($condition[3], $condition[4]); $condition .= ' )'; - + break; - + default: // This is an unpredicted clause setup. Just join all elements. $condition = implode(' ', $condition); - + break; } - + break; } - + } - + if($operation === 'NOT') { $operations_ary = implode("", $operations_ary); @@ -880,10 +880,10 @@ abstract class driver implements driver_interface { $operations_ary = implode(" \n $operation ", $operations_ary); } - + return $operations_ary; } - + /** * {@inheritDoc} -- cgit v1.2.1 From 46de94690453e0bd6dfc589682b7c4ede34f1d59 Mon Sep 17 00:00:00 2001 From: brunoais Date: Wed, 25 Feb 2015 07:55:24 +0000 Subject: [feature/sql-bool-builder] Added code to use this feature for the WHERE clause PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index cdff6bf9de..0fbbe5ae7c 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -774,7 +774,18 @@ abstract class driver implements driver_interface if (!empty($array['WHERE'])) { - $sql .= ' WHERE ' . $this->_sql_custom_build('WHERE', $array['WHERE']); + $sql .= ' WHERE '; + + if (is_array($array['WHERE'])) + { + $sql_where = $this->_process_boolean_tree_first($array['WHERE']); + } + else + { + $sql_where = $array['WHERE']; + } + + $sql .= $this->_sql_custom_build('WHERE', $sql_where); } if (!empty($array['GROUP_BY'])) -- cgit v1.2.1 From 5c1850e10e0e31e4f72cc16c657e37bb009659df Mon Sep 17 00:00:00 2001 From: brunoais Date: Wed, 25 Feb 2015 09:09:48 +0000 Subject: [feature/sql-bool-builder] AS keyword must be lowercase; AS keyword must be lowercase; expected "as" but found "AS" PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 0fbbe5ae7c..f66f10322b 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -819,7 +819,7 @@ abstract class driver implements driver_interface { $operation = array_shift($operations_ary); - foreach ($operations_ary AS &$condition) + foreach ($operations_ary as &$condition) { switch ($condition[0]) { -- cgit v1.2.1 From 51737be6162584209b483f97daa87ce9d3c039b0 Mon Sep 17 00:00:00 2001 From: brunoais Date: Sat, 28 Feb 2015 18:14:00 +0000 Subject: [feature/sql-bool-builder] Also use parenthesis for the NOT operator Be on the safe side, also use parenthesis for the NOT operator PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index f66f10322b..d2bb5f4f7c 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -831,7 +831,7 @@ abstract class driver implements driver_interface break; case 'NOT': - $condition = ' NOT ' . $this->_process_boolean_tree($condition); + $condition = ' NOT (' . $this->_process_boolean_tree($condition) . ') '; break; -- cgit v1.2.1 From 5d70f612be113336d6a85146369232c87d1b069b Mon Sep 17 00:00:00 2001 From: brunoais Date: Sun, 1 Mar 2015 11:39:20 +0000 Subject: [feature/sql-bool-builder] Explain better the code in the first Explain what that if and check is for in the first method that is called. PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index d2bb5f4f7c..cda2f7f86d 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -807,6 +807,8 @@ abstract class driver implements driver_interface protected function _process_boolean_tree_first($operations_ary) { + // In cases where an array exists but there is no head condition, + // it should be because there's only 1 WHERE clause. This seems the best way to deal with it. if ($operations_ary[0] !== 'AND' && $operations_ary[0] !== 'OR') { -- cgit v1.2.1 From 298d86009ed77a4b75792a6237f987be271ac43c Mon Sep 17 00:00:00 2001 From: brunoais Date: Sun, 15 Mar 2015 11:40:02 +0000 Subject: [feature/sql-bool-builder] Added LIKE and NOT_LIKE to the comparations PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index cda2f7f86d..ce69ef6a52 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -854,6 +854,18 @@ abstract class driver implements driver_interface break; + case 'LIKE': + + $condition = $condition[0] . ' ' . $this->sql_like_expression($condition[2]) . ' '; + + break; + + case 'NOT_LIKE': + + $condition = $condition[0] . ' ' . $this->sql_not_like_expression($condition[2]) . ' '; + + break; + default: $condition = implode(' ', $condition); -- cgit v1.2.1 From 576eaa0cff7a5e051aa672034e596e90f65fc1a9 Mon Sep 17 00:00:00 2001 From: brunoais Date: Mon, 16 Mar 2015 11:31:51 +0000 Subject: [feature/sql-bool-builder] Adding the IS operator to predicted operators PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index ce69ef6a52..4d78c84c8a 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -866,6 +866,24 @@ abstract class driver implements driver_interface break; + case 'IS_NOT': + + $condition[1] = 'IS NOT'; + + // no break + case 'IS': + + // If the value is NULL, the string of it is the empty string ('') which is not the intended result. + // this should solve that + if ($condition[2] === null) + { + $condition[2] = 'NULL'; + } + + $condition = implode(' ', $condition); + + break; + default: $condition = implode(' ', $condition); -- cgit v1.2.1 From fd230cd9c59ee90828f48abb6681c96ef3fb8277 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 23 Mar 2015 01:51:04 +0100 Subject: [ticket/13718] Added missing global declaration PHPBB3-13718 --- phpBB/phpbb/captcha/plugins/captcha_abstract.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/captcha/plugins/captcha_abstract.php b/phpBB/phpbb/captcha/plugins/captcha_abstract.php index 2c0b95411e..799947a84e 100644 --- a/phpBB/phpbb/captcha/plugins/captcha_abstract.php +++ b/phpBB/phpbb/captcha/plugins/captcha_abstract.php @@ -117,7 +117,7 @@ abstract class captcha_abstract function get_demo_template($id) { - global $config, $user, $template, $phpbb_admin_path, $phpEx; + global $config, $user, $template, $request, $phpbb_admin_path, $phpEx; $variables = ''; -- cgit v1.2.1 From dbb538afbdce345dfc61b06ec6a84313c1141284 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Fri, 27 Mar 2015 00:02:20 -0700 Subject: [ticket/13725] Coding guidelines: static public PHPBB3-13725 --- phpBB/phpbb/db/tools/tools.php | 2 +- phpBB/phpbb/event/kernel_exception_subscriber.php | 2 +- phpBB/phpbb/event/kernel_terminate_subscriber.php | 2 +- phpBB/phpbb/notification/type/admin_activate_user.php | 6 +++--- phpBB/phpbb/notification/type/approve_post.php | 2 +- phpBB/phpbb/notification/type/approve_topic.php | 2 +- phpBB/phpbb/notification/type/base.php | 2 +- phpBB/phpbb/notification/type/bookmark.php | 2 +- phpBB/phpbb/notification/type/disapprove_post.php | 2 +- phpBB/phpbb/notification/type/disapprove_topic.php | 2 +- phpBB/phpbb/notification/type/group_request.php | 6 +++--- phpBB/phpbb/notification/type/group_request_approved.php | 4 ++-- phpBB/phpbb/notification/type/pm.php | 6 +++--- phpBB/phpbb/notification/type/post.php | 6 +++--- phpBB/phpbb/notification/type/post_in_queue.php | 2 +- phpBB/phpbb/notification/type/quote.php | 2 +- phpBB/phpbb/notification/type/report_pm.php | 4 ++-- phpBB/phpbb/notification/type/report_post.php | 2 +- phpBB/phpbb/notification/type/topic.php | 6 +++--- phpBB/phpbb/notification/type/topic_in_queue.php | 2 +- phpBB/phpbb/notification/type/type_interface.php | 4 ++-- 21 files changed, 34 insertions(+), 34 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index 0d1eb63c47..1d7b2ddfff 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -40,7 +40,7 @@ class tools implements tools_interface * * @return array */ - public static function get_dbms_type_map() + static public function get_dbms_type_map() { return array( 'mysql_41' => array( diff --git a/phpBB/phpbb/event/kernel_exception_subscriber.php b/phpBB/phpbb/event/kernel_exception_subscriber.php index eb7831ad34..0a8a0183dc 100644 --- a/phpBB/phpbb/event/kernel_exception_subscriber.php +++ b/phpBB/phpbb/event/kernel_exception_subscriber.php @@ -106,7 +106,7 @@ class kernel_exception_subscriber implements EventSubscriberInterface $event->setResponse($response); } - public static function getSubscribedEvents() + static public function getSubscribedEvents() { return array( KernelEvents::EXCEPTION => 'on_kernel_exception', diff --git a/phpBB/phpbb/event/kernel_terminate_subscriber.php b/phpBB/phpbb/event/kernel_terminate_subscriber.php index 3a709f73fd..f0d0a2f595 100644 --- a/phpBB/phpbb/event/kernel_terminate_subscriber.php +++ b/phpBB/phpbb/event/kernel_terminate_subscriber.php @@ -32,7 +32,7 @@ class kernel_terminate_subscriber implements EventSubscriberInterface exit_handler(); } - public static function getSubscribedEvents() + static public function getSubscribedEvents() { return array( KernelEvents::TERMINATE => array('on_kernel_terminate', ~PHP_INT_MAX), diff --git a/phpBB/phpbb/notification/type/admin_activate_user.php b/phpBB/phpbb/notification/type/admin_activate_user.php index dfc0157558..73ed612480 100644 --- a/phpBB/phpbb/notification/type/admin_activate_user.php +++ b/phpBB/phpbb/notification/type/admin_activate_user.php @@ -36,7 +36,7 @@ class admin_activate_user extends \phpbb\notification\type\base /** * {@inheritdoc} */ - public static $notification_option = array( + static public $notification_option = array( 'lang' => 'NOTIFICATION_TYPE_ADMIN_ACTIVATE_USER', 'group' => 'NOTIFICATION_GROUP_ADMINISTRATION', ); @@ -52,7 +52,7 @@ class admin_activate_user extends \phpbb\notification\type\base /** * {@inheritdoc} */ - public static function get_item_id($user) + static public function get_item_id($user) { return (int) $user['user_id']; } @@ -60,7 +60,7 @@ class admin_activate_user extends \phpbb\notification\type\base /** * {@inheritdoc} */ - public static function get_item_parent_id($post) + static public function get_item_parent_id($post) { return 0; } diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php index a9e635b41a..e6c38b2ede 100644 --- a/phpBB/phpbb/notification/type/approve_post.php +++ b/phpBB/phpbb/notification/type/approve_post.php @@ -50,7 +50,7 @@ class approve_post extends \phpbb\notification\type\post * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'id' => 'moderation_queue', 'lang' => 'NOTIFICATION_TYPE_MODERATION_QUEUE', 'group' => 'NOTIFICATION_GROUP_POSTING', diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php index 2f4678359c..5f5b96f335 100644 --- a/phpBB/phpbb/notification/type/approve_topic.php +++ b/phpBB/phpbb/notification/type/approve_topic.php @@ -50,7 +50,7 @@ class approve_topic extends \phpbb\notification\type\topic * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'id' => 'moderation_queue', 'lang' => 'NOTIFICATION_TYPE_MODERATION_QUEUE', 'group' => 'NOTIFICATION_GROUP_POSTING', diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index 4ead06071e..1cf0498138 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -63,7 +63,7 @@ abstract class base implements \phpbb\notification\type\type_interface * @var bool|array False if the service should use its default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = false; + static public $notification_option = false; /** * The notification_type_id, set upon creation of the class diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php index 4f2d34cb60..e6a695e875 100644 --- a/phpBB/phpbb/notification/type/bookmark.php +++ b/phpBB/phpbb/notification/type/bookmark.php @@ -43,7 +43,7 @@ class bookmark extends \phpbb\notification\type\post * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'lang' => 'NOTIFICATION_TYPE_BOOKMARK', 'group' => 'NOTIFICATION_GROUP_POSTING', ); diff --git a/phpBB/phpbb/notification/type/disapprove_post.php b/phpBB/phpbb/notification/type/disapprove_post.php index 6c7bcbcaee..7021cdc837 100644 --- a/phpBB/phpbb/notification/type/disapprove_post.php +++ b/phpBB/phpbb/notification/type/disapprove_post.php @@ -60,7 +60,7 @@ class disapprove_post extends \phpbb\notification\type\approve_post * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'id' => 'moderation_queue', 'lang' => 'NOTIFICATION_TYPE_MODERATION_QUEUE', 'group' => 'NOTIFICATION_GROUP_POSTING', diff --git a/phpBB/phpbb/notification/type/disapprove_topic.php b/phpBB/phpbb/notification/type/disapprove_topic.php index efa5eb7ecd..419cc5b2a6 100644 --- a/phpBB/phpbb/notification/type/disapprove_topic.php +++ b/phpBB/phpbb/notification/type/disapprove_topic.php @@ -60,7 +60,7 @@ class disapprove_topic extends \phpbb\notification\type\approve_topic * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'id' => 'moderation_queue', 'lang' => 'NOTIFICATION_TYPE_MODERATION_QUEUE', 'group' => 'NOTIFICATION_GROUP_POSTING', diff --git a/phpBB/phpbb/notification/type/group_request.php b/phpBB/phpbb/notification/type/group_request.php index 4baf516fed..19665624df 100644 --- a/phpBB/phpbb/notification/type/group_request.php +++ b/phpBB/phpbb/notification/type/group_request.php @@ -26,7 +26,7 @@ class group_request extends \phpbb\notification\type\base /** * {@inheritdoc} */ - public static $notification_option = array( + static public $notification_option = array( 'lang' => 'NOTIFICATION_TYPE_GROUP_REQUEST', ); @@ -50,7 +50,7 @@ class group_request extends \phpbb\notification\type\base /** * {@inheritdoc} */ - public static function get_item_id($group) + static public function get_item_id($group) { return (int) $group['user_id']; } @@ -58,7 +58,7 @@ class group_request extends \phpbb\notification\type\base /** * {@inheritdoc} */ - public static function get_item_parent_id($group) + static public function get_item_parent_id($group) { // Group id is the parent return (int) $group['group_id']; diff --git a/phpBB/phpbb/notification/type/group_request_approved.php b/phpBB/phpbb/notification/type/group_request_approved.php index d284046ffa..f282cdd158 100644 --- a/phpBB/phpbb/notification/type/group_request_approved.php +++ b/phpBB/phpbb/notification/type/group_request_approved.php @@ -34,7 +34,7 @@ class group_request_approved extends \phpbb\notification\type\base /** * {@inheritdoc} */ - public static function get_item_id($group) + static public function get_item_id($group) { return (int) $group['group_id']; } @@ -42,7 +42,7 @@ class group_request_approved extends \phpbb\notification\type\base /** * {@inheritdoc} */ - public static function get_item_parent_id($group) + static public function get_item_parent_id($group) { return 0; } diff --git a/phpBB/phpbb/notification/type/pm.php b/phpBB/phpbb/notification/type/pm.php index 330a70c85a..29b4b79216 100644 --- a/phpBB/phpbb/notification/type/pm.php +++ b/phpBB/phpbb/notification/type/pm.php @@ -36,7 +36,7 @@ class pm extends \phpbb\notification\type\base * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'lang' => 'NOTIFICATION_TYPE_PM', ); @@ -53,7 +53,7 @@ class pm extends \phpbb\notification\type\base * * @param array $pm The data from the private message */ - public static function get_item_id($pm) + static public function get_item_id($pm) { return (int) $pm['msg_id']; } @@ -63,7 +63,7 @@ class pm extends \phpbb\notification\type\base * * @param array $pm The data from the pm */ - public static function get_item_parent_id($pm) + static public function get_item_parent_id($pm) { // No parent return 0; diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index 421eff6372..d6aa8a8af9 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -50,7 +50,7 @@ class post extends \phpbb\notification\type\base * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'lang' => 'NOTIFICATION_TYPE_POST', 'group' => 'NOTIFICATION_GROUP_POSTING', ); @@ -68,7 +68,7 @@ class post extends \phpbb\notification\type\base * * @param array $post The data from the post */ - public static function get_item_id($post) + static public function get_item_id($post) { return (int) $post['post_id']; } @@ -78,7 +78,7 @@ class post extends \phpbb\notification\type\base * * @param array $post The data from the post */ - public static function get_item_parent_id($post) + static public function get_item_parent_id($post) { return (int) $post['topic_id']; } diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php index 315b8b0243..e500ad33bc 100644 --- a/phpBB/phpbb/notification/type/post_in_queue.php +++ b/phpBB/phpbb/notification/type/post_in_queue.php @@ -43,7 +43,7 @@ class post_in_queue extends \phpbb\notification\type\post * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'id' => 'notification.type.needs_approval', 'lang' => 'NOTIFICATION_TYPE_IN_MODERATION_QUEUE', 'group' => 'NOTIFICATION_GROUP_MODERATION', diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 508ca92fa0..141f90c7ae 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -50,7 +50,7 @@ class quote extends \phpbb\notification\type\post * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'lang' => 'NOTIFICATION_TYPE_QUOTE', 'group' => 'NOTIFICATION_GROUP_POSTING', ); diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php index d39143f4b7..1904680d5a 100644 --- a/phpBB/phpbb/notification/type/report_pm.php +++ b/phpBB/phpbb/notification/type/report_pm.php @@ -60,7 +60,7 @@ class report_pm extends \phpbb\notification\type\pm * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'id' => 'notification.type.report', 'lang' => 'NOTIFICATION_TYPE_REPORT', 'group' => 'NOTIFICATION_GROUP_MODERATION', @@ -71,7 +71,7 @@ class report_pm extends \phpbb\notification\type\pm * * @param array $pm The data from the pm */ - public static function get_item_parent_id($pm) + static public function get_item_parent_id($pm) { return (int) $pm['report_id']; } diff --git a/phpBB/phpbb/notification/type/report_post.php b/phpBB/phpbb/notification/type/report_post.php index 027cca716b..b64862078a 100644 --- a/phpBB/phpbb/notification/type/report_post.php +++ b/phpBB/phpbb/notification/type/report_post.php @@ -66,7 +66,7 @@ class report_post extends \phpbb\notification\type\post_in_queue * @var bool|array False if the service should use it's default data * Array of data (including keys 'id' and 'lang') */ - public static $notification_option = array( + static public $notification_option = array( 'id' => 'notification.type.report', 'lang' => 'NOTIFICATION_TYPE_REPORT', 'group' => 'NOTIFICATION_GROUP_MODERATION', diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php index 5f57087b73..a1a17535b5 100644 --- a/phpBB/phpbb/notification/type/topic.php +++ b/phpBB/phpbb/notification/type/topic.php @@ -50,7 +50,7 @@ class topic extends \phpbb\notification\type\base * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'lang' => 'NOTIFICATION_TYPE_TOPIC', 'group' => 'NOTIFICATION_GROUP_POSTING', ); @@ -68,7 +68,7 @@ class topic extends \phpbb\notification\type\base * * @param array $post The data from the post */ - public static function get_item_id($post) + static public function get_item_id($post) { return (int) $post['topic_id']; } @@ -78,7 +78,7 @@ class topic extends \phpbb\notification\type\base * * @param array $post The data from the post */ - public static function get_item_parent_id($post) + static public function get_item_parent_id($post) { return (int) $post['forum_id']; } diff --git a/phpBB/phpbb/notification/type/topic_in_queue.php b/phpBB/phpbb/notification/type/topic_in_queue.php index 4c60c6b858..cfdf748d38 100644 --- a/phpBB/phpbb/notification/type/topic_in_queue.php +++ b/phpBB/phpbb/notification/type/topic_in_queue.php @@ -43,7 +43,7 @@ class topic_in_queue extends \phpbb\notification\type\topic * @var bool|array False if the service should use it's default data * Array of data (including keys 'id', 'lang', and 'group') */ - public static $notification_option = array( + static public $notification_option = array( 'id' => 'notification.type.needs_approval', 'lang' => 'NOTIFICATION_TYPE_IN_MODERATION_QUEUE', 'group' => 'NOTIFICATION_GROUP_MODERATION', diff --git a/phpBB/phpbb/notification/type/type_interface.php b/phpBB/phpbb/notification/type/type_interface.php index 5c5a110836..8844ce1a38 100644 --- a/phpBB/phpbb/notification/type/type_interface.php +++ b/phpBB/phpbb/notification/type/type_interface.php @@ -37,14 +37,14 @@ interface type_interface * * @param array $type_data The type specific data */ - public static function get_item_id($type_data); + static public function get_item_id($type_data); /** * Get the id of the parent * * @param array $type_data The type specific data */ - public static function get_item_parent_id($type_data); + static public function get_item_parent_id($type_data); /** * Is this type available to the current user (defines whether or not it will be shown in the UCP Edit notification options) -- cgit v1.2.1 From 147a713cc066d493b50b82a9d475aa9af940e2b4 Mon Sep 17 00:00:00 2001 From: s9e Date: Sat, 22 Nov 2014 20:00:58 +0100 Subject: [ticket/11768] This commit integrates s9e\TextFormatter This commit integrates s9e\TextFormatter as outlined in http://area51.phpbb.com/phpBB/viewtopic.php?f=108&t=44467 PHPBB3-11768 --- phpBB/phpbb/textformatter/cache.php | 37 +++ phpBB/phpbb/textformatter/data_access.php | 233 ++++++++++++++ phpBB/phpbb/textformatter/parser.php | 121 +++++++ phpBB/phpbb/textformatter/renderer.php | 136 ++++++++ phpBB/phpbb/textformatter/s9e/factory.php | 493 +++++++++++++++++++++++++++++ phpBB/phpbb/textformatter/s9e/parser.php | 335 ++++++++++++++++++++ phpBB/phpbb/textformatter/s9e/renderer.php | 228 +++++++++++++ phpBB/phpbb/textformatter/s9e/utils.php | 67 ++++ phpBB/phpbb/textformatter/utils.php | 62 ++++ 9 files changed, 1712 insertions(+) create mode 100644 phpBB/phpbb/textformatter/cache.php create mode 100644 phpBB/phpbb/textformatter/data_access.php create mode 100644 phpBB/phpbb/textformatter/parser.php create mode 100644 phpBB/phpbb/textformatter/renderer.php create mode 100644 phpBB/phpbb/textformatter/s9e/factory.php create mode 100644 phpBB/phpbb/textformatter/s9e/parser.php create mode 100644 phpBB/phpbb/textformatter/s9e/renderer.php create mode 100644 phpBB/phpbb/textformatter/s9e/utils.php create mode 100644 phpBB/phpbb/textformatter/utils.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/cache.php b/phpBB/phpbb/textformatter/cache.php new file mode 100644 index 0000000000..c92683217e --- /dev/null +++ b/phpBB/phpbb/textformatter/cache.php @@ -0,0 +1,37 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter; + +/** +* text_formatter.cache service +* +* Currently only used to signal that something that could effect the rendering has changed. +* BBCodes, smilies, censored words, templates, etc... +* +* @todo functionality should be moved to data_access +* +* @package phpBB3 +*/ +interface cache +{ + /** + * Invalidate and/or regenerate this text formatter's cache(s) + */ + public function invalidate(); + + /** + * Tidy/prune this text formatter's cache(s) + */ + public function tidy(); +} diff --git a/phpBB/phpbb/textformatter/data_access.php b/phpBB/phpbb/textformatter/data_access.php new file mode 100644 index 0000000000..ec6bf9f88e --- /dev/null +++ b/phpBB/phpbb/textformatter/data_access.php @@ -0,0 +1,233 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter; + +/** +* text_formatter.data_access service +* +* Data access layer that fetchs BBCodes, smilies and censored words from the database. +* To be extended to include insert/update/delete operations. +* +* Also used to get templates. +* +* @package phpBB3 +*/ +class data_access +{ + /** + * @var string Name of the BBCodes table + */ + protected $bbcodes_table; + + /** + * @var phpbb_db_driver + */ + protected $db; + + /** + * @var string Name of the smilies table + */ + protected $smilies_table; + + /** + * @var string Name of the styles table + */ + protected $styles_table; + + /** + * @var string Path to the styles dir + */ + protected $styles_path; + + /** + * @var string Name of the words table + */ + protected $words_table; + + /** + * Constructor + * + * @param \phpbb\db\driver\driver_interface $db Database connection + * @param string $bbcodes_table Name of the BBCodes table + * @param string $smilies_table Name of the smilies table + * @param string $styles_table Name of the styles table + * @param string $words_table Name of the words table + * @param string $styles_path Path to the styles dir + * @return null + */ + public function __construct(\phpbb\db\driver\driver_interface $db, $bbcodes_table, $smilies_table, $styles_table, $words_table, $styles_path) + { + $this->db = $db; + + $this->bbcodes_table = $bbcodes_table; + $this->smilies_table = $smilies_table; + $this->styles_table = $styles_table; + $this->words_table = $words_table; + + $this->styles_path = $styles_path; + } + + /** + * Return the list of custom BBCodes + * + * @return array + */ + public function get_bbcodes() + { + $sql = 'SELECT bbcode_match, bbcode_tpl FROM ' . $this->bbcodes_table; + $result = $this->db->sql_query($sql); + $rows = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $rows; + } + + /** + * Return the list of smilies + * + * @return array + */ + public function get_smilies() + { + // NOTE: smilies that are displayed on the posting page are processed first because they're + // typically the most used smilies and it ends up producing a slightly more efficient + // renderer + $sql = 'SELECT code, emotion, smiley_url, smiley_width, smiley_height + FROM ' . $this->smilies_table . ' + ORDER BY display_on_posting DESC'; + $result = $this->db->sql_query($sql); + $rows = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $rows; + } + + /** + * Return the list of installed styles + * + * @return array + */ + protected function get_styles() + { + $sql = 'SELECT style_id, style_path, bbcode_bitfield FROM ' . $this->styles_table; + $result = $this->db->sql_query($sql); + $rows = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $rows; + } + + /** + * Return the bbcode.html template for every installed style + * + * @return array 2D array. style_id as keys, each element is an array with a "template" element that contains the style's bbcode.html and a "bbcodes" element that contains the name of each BBCode that is to be stylised + */ + public function get_styles_templates() + { + $templates = array(); + + $bbcode_ids = array( + 'quote' => 0, + 'b' => 1, + 'i' => 2, + 'url' => 3, + 'img' => 4, + 'size' => 5, + 'color' => 6, + 'u' => 7, + 'code' => 8, + 'list' => 9, + '*' => 9, + 'email' => 10, + 'flash' => 11, + 'attachment' => 12, + ); + + $styles = array(); + foreach ($this->get_styles() as $row) + { + $styles[$row['style_id']] = $row; + } + + foreach ($styles as $style_id => $style) + { + $bbcodes = array(); + + // Collect the name of the BBCodes whose bit is set in the style's bbcode_bitfield + $template_bitfield = new \bitfield($style['bbcode_bitfield']); + foreach ($bbcode_ids as $bbcode_name => $bit) + { + if ($template_bitfield->get($bit)) + { + $bbcodes[] = $bbcode_name; + } + } + + $filename = $this->resolve_style_filename($styles, $style); + if ($filename === false) + { + // Ignore this style, it will use the default templates + continue; + } + + $templates[$style_id] = array( + 'bbcodes' => $bbcodes, + 'template' => file_get_contents($filename), + ); + } + + return $templates; + } + + /** + * Resolve inheritance for given style and return the path to their bbcode.html file + * + * @param array $styles Associative array of [style_id => style] containing all styles + * @param array $style Style for which we resolve + * @return string|bool Path to this style's bbcode.html, or FALSE + */ + protected function resolve_style_filename(array $styles, array $style) + { + // Look for a bbcode.html in this style's dir + $filename = $this->styles_path . $style['style_path'] . '/template/bbcode.html'; + if (file_exists($filename)) + { + return $filename; + } + + // Resolve using this style's parent + $parent_id = $style['style_parent_id']; + if ($parent_id && !empty($styles[$parent_id])) + { + return $this->resolve_style_filename($styles, $styles[$parent_id]); + } + + return false; + } + + /** + * Return the list of censored words + * + * @return array + */ + public function get_words() + { + $sql = 'SELECT word, replacement FROM ' . $this->words_table; + $result = $this->db->sql_query($sql); + $rows = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $rows; + } +} diff --git a/phpBB/phpbb/textformatter/parser.php b/phpBB/phpbb/textformatter/parser.php new file mode 100644 index 0000000000..c595a459bd --- /dev/null +++ b/phpBB/phpbb/textformatter/parser.php @@ -0,0 +1,121 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter; + +/** +* text_formatter.parser service +* @package phpBB3 +*/ +abstract class parser +{ + /** + * Parse given text + * + * @param string $text + * @return string + */ + abstract public function parse($text); + + /** + * Disable a specific BBCode + * + * @param string $name BBCode name + * @return null + */ + abstract public function disable_bbcode($name); + + /** + * Disable BBCodes in general + */ + abstract public function disable_bbcodes(); + + /** + * Disable the censor + */ + abstract public function disable_censor(); + + /** + * Disable magic URLs + */ + abstract public function disable_magic_url(); + + /** + * Disable smilies + */ + abstract public function disable_smilies(); + + /** + * Enable a specific BBCode + * + * @param string $name BBCode name + * @return null + */ + abstract public function enable_bbcode($name); + + /** + * Enable BBCodes in general + */ + abstract public function enable_bbcodes(); + + /** + * Enable the censor + */ + abstract public function enable_censor(); + + /** + * Enable magic URLs + */ + abstract public function enable_magic_url(); + + /** + * Enable smilies + */ + abstract public function enable_smilies(); + + /** + * Get the list of errors that were generated during last parsing + * + * @return array + */ + abstract public function get_errors(); + + /** + * Set a variable to be used by the parser + * + * - max_font_size + * - max_img_height + * - max_img_width + * - max_smilies + * - max_urls + * + * @param string $name + * @param mixed $value + * @return null + */ + abstract public function set_var($name, $value); + + /** + * Set multiple variables to be used by the parser + * + * @param array Associative array of [name => value] + * @return null + */ + public function set_vars(array $vars) + { + foreach ($vars as $name => $value) + { + $this->set_var($name, $value); + } + } +} diff --git a/phpBB/phpbb/textformatter/renderer.php b/phpBB/phpbb/textformatter/renderer.php new file mode 100644 index 0000000000..fb731a5294 --- /dev/null +++ b/phpBB/phpbb/textformatter/renderer.php @@ -0,0 +1,136 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter; + +/** +* text_formatter.renderer service +* @package phpBB3 +*/ +abstract class renderer +{ + /** + * Render given text + * + * @param string $text Text, as parsed by the text_formatter.parser service + * @return string + */ + abstract public function render($text); + + /** + * Automatically set the smilies path based on config + * + * Called by the service container + * + * @param phpbb\config\config $config + * @param phpbb\path_helper $path_helper + * @return null + */ + public function configure_smilies_path(\phpbb\config\config $config, \phpbb\path_helper $path_helper) + { + /** + * @see smiley_text() + */ + $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $path_helper->get_web_root_path(); + + $this->set_smilies_path($root_path . $config['smilies_path']); + } + + /** + * Configure this renderer as per the user's settings + * + * Should set the locale as well as the viewcensor/viewflash/viewimg/viewsmilies options. + * Called by the service container + * + * @param phpbb\user $user + * @param phpbb\config\config $config + * @param phpbb\auth\auth $auth + * @return null + */ + public function configure_user(\phpbb\user $user, \phpbb\config\config $config, \phpbb\auth\auth $auth) + { + $censor = $user->optionget('viewcensors') || !$config['allow_nocensors'] || !$auth->acl_get('u_chgcensors'); + + $this->set_viewcensors($censor); + $this->set_viewflash($user->optionget('viewflash')); + $this->set_viewimg($user->optionget('viewimg')); + $this->set_viewsmilies($user->optionget('viewsmilies')); + } + + /** + * Set the smilies' path + * + * @return null + */ + abstract public function set_smilies_path($path); + + /** + * Return the value of the "viewcensors" option + * + * @return bool Option's value + */ + abstract public function get_viewcensors(); + + /** + * Return the value of the "viewflash" option + * + * @return bool Option's value + */ + abstract public function get_viewflash(); + + /** + * Return the value of the "viewimg" option + * + * @return bool Option's value + */ + abstract public function get_viewimg(); + + /** + * Return the value of the "viewsmilies" option + * + * @return bool Option's value + */ + abstract public function get_viewsmilies(); + + /** + * Set the "viewcensors" option + * + * @param bool $value Option's value + * @return null + */ + abstract public function set_viewcensors($value); + + /** + * Set the "viewflash" option + * + * @param bool $value Option's value + * @return null + */ + abstract public function set_viewflash($value); + + /** + * Set the "viewimg" option + * + * @param bool $value Option's value + * @return null + */ + abstract public function set_viewimg($value); + + /** + * Set the "viewsmilies" option + * + * @param bool $value Option's value + * @return null + */ + abstract public function set_viewsmilies($value); +} diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php new file mode 100644 index 0000000000..8d61f2caac --- /dev/null +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -0,0 +1,493 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter\s9e; + +use s9e\TextFormatter\Configurator; +use s9e\TextFormatter\Configurator\Items\AttributeFilters\Regexp as RegexpFilter; + +/** +* Creates s9e\TextFormatter objects +* @package phpBB3 +*/ +class factory implements \phpbb\textformatter\cache +{ + /** + * @var phpbb_cache_driver_interface $cache + */ + protected $cache; + + /** + * @var string Path to the cache dir + */ + protected $cache_dir; + + /** + * @var string Cache key used for the parser + */ + protected $cache_key_parser; + + /** + * @var string Cache key used for the renderer + */ + protected $cache_key_renderer; + + /** + * @var array Custom tokens used in bbcode.html and their corresponding token from the definition + */ + protected $custom_tokens = array( + 'email' => array('{DESCRIPTION}' => '{TEXT}'), + 'flash' => array('{WIDTH}' => '{NUMBER1}', '{HEIGHT}' => '{NUMBER2}'), + 'img' => array('{URL}' => '{IMAGEURL}'), + 'list' => array('{LIST_TYPE}' => '{HASHMAP}'), + 'quote' => array('{USERNAME}' => '{TEXT1}'), + 'size' => array('{SIZE}' => '{FONTSIZE}'), + 'url' => array('{DESCRIPTION}' => '{TEXT}'), + ); + + /** + * @var \phpbb\textformatter\data_access + */ + protected $dal; + + /** + * @var array Default BBCode definitions + */ + protected $default_definitions = array( + 'attachment' => '[ATTACHMENT index={NUMBER} filename={TEXT;useContent}]', + 'b' => '[B]{TEXT}[/B]', + 'code' => '[CODE]{TEXT}[/CODE]', + 'color' => '[COLOR={COLOR}]{TEXT}[/COLOR]', + 'email' => '[EMAIL={EMAIL;useContent}]{TEXT}[/EMAIL]', + 'flash' => '[FLASH={NUMBER1},{NUMBER2} width={NUMBER1;postFilter=#flashwidth} height={NUMBER2;postFilter=#flashheight} url={URL;useContent} /]', + 'i' => '[I]{TEXT}[/I]', + 'img' => '[IMG src={IMAGEURL;useContent}]', + 'list' => '[LIST type={HASHMAP=1:decimal,a:lower-alpha,A:upper-alpha,i:lower-roman,I:upper-roman;optional;postFilter=#simpletext}]{TEXT}[/LIST]', + 'li' => '[* $tagName=LI]{TEXT}[/*]', + 'quote' => '[QUOTE author={TEXT1;optional}]{TEXT2}[/QUOTE]', + 'size' => '[SIZE={FONTSIZE}]{TEXT}[/SIZE]', + 'u' => '[U]{TEXT}[/U]', + 'url' => '[URL={URL;useContent}]{TEXT}[/URL]', + ); + + /** + * @var array Default templates, taken from bbcode::bbcode_tpl() + */ + protected $default_templates = array( + 'b' => '', + 'i' => '', + 'u' => '', + 'img' => '{L_IMAGE}', + 'size' => '', + 'color' => '', + 'email' => '', + ); + + /** + * Constructor + * + * @param phpbb\textformatter\data_access $dal + * @param phpbb\cache\driver\driver_interface $cache + * @param string $cache_dir Path to the cache dir + * @param string $cache_key_parser Cache key used for the parser + * @param string $cache_key_renderer Cache key used for the renderer + * @return null + */ + public function __construct(\phpbb\textformatter\data_access $dal, \phpbb\cache\driver\driver_interface $cache, $cache_dir, $cache_key_parser, $cache_key_renderer) + { + $this->cache = $cache; + $this->cache_dir = $cache_dir; + $this->cache_key_parser = $cache_key_parser; + $this->cache_key_renderer = $cache_key_renderer; + + $this->dal = $dal; + } + + /** + * {@inheritdoc} + */ + public function invalidate() + { + $this->regenerate(); + } + + /** + * {@inheritdoc} + * + * Will remove old renderers from the cache dir but won't touch the current renderer + */ + public function tidy() + { + // Get the name of current renderer + $renderer_data = $this->cache->get($this->cache_key_renderer); + $renderer_file = ($renderer_data) ? $renderer_data['class'] . '.php' : null; + + foreach (glob($this->cache_dir . 's9e_*') as $filename) + { + // Only remove the file if it's not the current renderer + if (!$renderer_file || substr($filename, -strlen($renderer_file)) !== $renderer_file) + { + unlink($filename); + } + } + } + + /** + * Generate and return a new configured instance of s9e\TextFormatter\Configurator + * + * @return s9e\TextFormatter\Configurator + */ + public function get_configurator() + { + // Create a new Configurator + $configurator = new Configurator; + + // Convert newlines to br elements by default + $configurator->rootRules->enableAutoLineBreaks(); + + // Set the rendering engine and configure it to save to the cache dir + $configurator->rendering->engine = 'PHP'; + $configurator->rendering->engine->cacheDir = $this->cache_dir; + $configurator->rendering->engine->defaultClassPrefix = 's9e_renderer_'; + $configurator->rendering->engine->enableQuickRenderer = true; + + // Create custom filters for BBCode tokens that are supported in phpBB but not in + // s9e\TextFormatter + $filter = new RegexpFilter('#^' . get_preg_expression('relative_url') . '$#D'); + $configurator->attributeFilters->add('#local_url', $filter); + $configurator->attributeFilters->add('#relative_url', $filter); + + $regexp = (phpbb_pcre_utf8_support()) + ? '!^([\p{L}\p{N}\-+,_. ]+)$!uD' + : '!^([a-zA-Z0-9\-+,_. ]+)$!uD'; + $configurator->attributeFilters->add('#inttext', new RegexpFilter($regexp)); + + // Create custom filters for Flash restrictions, which use the same values as the image + // restrictions but have their own error message + $configurator->attributeFilters + ->add('#flashheight', __NAMESPACE__ . '\\parser::filter_flash_height') + ->addParameterByName('max_img_height') + ->addParameterByName('logger'); + + $configurator->attributeFilters + ->add('#flashwidth', __NAMESPACE__ . '\\parser::filter_flash_width') + ->addParameterByName('max_img_width') + ->addParameterByName('logger'); + + // Create a custom filter for phpBB's per-mode font size limits + $configurator->attributeFilters + ->add('#fontsize', __NAMESPACE__ . '\\parser::filter_font_size') + ->addParameterByName('max_font_size') + ->addParameterByName('logger') + ->markAsSafeInCSS(); + + // Create a custom filter for image URLs + $configurator->attributeFilters + ->add('#imageurl', __NAMESPACE__ . '\\parser::filter_img_url') + ->addParameterByName('urlConfig') + ->addParameterByName('logger') + ->addParameterByName('max_img_height') + ->addParameterByName('max_img_width') + ->markAsSafeAsURL(); + + // Add default BBCodes + foreach ($this->get_default_bbcodes($configurator) as $bbcode) + { + $configurator->BBCodes->addCustom($bbcode['usage'], $bbcode['template']); + } + + // Modify the template to disable images/flash depending on user's settings + foreach (array('FLASH', 'IMG') as $name) + { + $tag = $configurator->tags[$name]; + $tag->template = '' . $tag->template . ''; + } + + // Load custom BBCodes + foreach ($this->dal->get_bbcodes() as $row) + { + // Insert the board's URL before {LOCAL_URL} tokens + $tpl = preg_replace_callback( + '#\\{LOCAL_URL\\d*\\}#', + function ($m) + { + return generate_board_url() . '/' . $m[0]; + }, + $row['bbcode_tpl'] + ); + + try + { + $configurator->BBCodes->addCustom($row['bbcode_match'], $tpl); + } + catch (\Exception $e) + { + /** + * @todo log an error? + */ + } + } + + // Load smilies + foreach ($this->dal->get_smilies() as $row) + { + $configurator->Emoticons->add( + $row['code'], + '{.}' + ); + } + + if (isset($configurator->Emoticons)) + { + // Force emoticons to be rendered as text if $S_VIEWSMILIES is not set + $configurator->Emoticons->notIfCondition = 'not($S_VIEWSMILIES)'; + + // Only parse emoticons at the beginning of the text or if they're preceded by any + // one of: a new line, a space, a dot, or a right square bracket + $configurator->Emoticons->notAfter = '[^\\n .\\]]'; + } + + // Load the censored words + foreach ($this->dal->get_words() as $row) + { + $configurator->Censor->add($row['word'], $row['replacement']); + } + + if (isset($configurator->Censor)) + { + // Replace the template with a template that applies only when $S_VIEWCENSORS is set + $tag = $configurator->Censor->getTag(); + $tag->template = + ' + + + + + + + **** + '; + } + + // Load the magic links plugins. We do that after BBCodes so that they use the same tags + $configurator->plugins->load('Autoemail'); + $configurator->plugins->load('Autolink'); + + // Register some vars with a default value. Those should be set at runtime by whatever calls + // the parser + $configurator->registeredVars['max_font_size'] = 0; + $configurator->registeredVars['max_img_height'] = 0; + $configurator->registeredVars['max_img_width'] = 0; + + return $configurator; + } + + /** + * Regenerate and cache a new parser and renderer + * + * @return array Array with two elements: an instance of the parser, an instance of the renderer + */ + public function regenerate() + { + $configurator = $this->get_configurator(); + + // Create $parser and $renderer + extract($configurator->finalize()); + + // Cache the parser as-is + $this->cache->put($this->cache_key_parser, $parser); + + // We need to cache the name of the renderer's generated class so that we can load the class + // before the renderer is unserialized. That's why we save them together, with the renderer + // in serialized form + $renderer_data = array( + 'class' => get_class($renderer), + 'renderer' => serialize($renderer) + ); + $this->cache->put($this->cache_key_renderer, $renderer_data); + + return array($parser, $renderer); + } + + /** + * Return the default BBCodes configuration + * + * @return array 2D array. Each element has a 'usage' key, a 'template' key, and an optional 'options' key + */ + protected function get_default_bbcodes($configurator) + { + // For each BBCode, build an associative array matching style_ids to their template + $templates = array(); + foreach ($this->dal->get_styles_templates() as $style_id => $data) + { + foreach ($this->extract_templates($data['template']) as $bbcode_name => $template) + { + $templates[$bbcode_name][$style_id] = $template; + } + + // Add default templates wherever missing, or for BBCodes that were not specified in + // this template's bitfield. For instance, prosilver has a custom template for b but its + // bitfield does not enable it so the default template is used instead + foreach ($this->default_templates as $bbcode_name => $template) + { + if (!isset($templates[$bbcode_name][$style_id]) || !in_array($bbcode_name, $data['bbcodes'], true)) + { + $templates[$bbcode_name][$style_id] = $template; + } + } + } + + // Replace custom tokens and normalize templates + foreach ($templates as $bbcode_name => &$style_templates) + { + foreach ($style_templates as &$template) + { + if (isset($this->custom_tokens[$bbcode_name])) + { + $template = strtr($template, $this->custom_tokens[$bbcode_name]); + } + + $template = $configurator->templateNormalizer->normalizeTemplate($template); + } + unset($template); + } + unset($style_templates); + + $bbcodes = array(); + foreach ($this->default_definitions as $bbcode_name => $usage) + { + $bbcodes[$bbcode_name] = array( + 'usage' => $usage, + 'template' => $this->merge_templates($templates[$bbcode_name]), + ); + } + + return $bbcodes; + } + + /** + * Extract and recompose individual BBCode templates from a style's template file + * + * @param string $template Style template (bbcode.html) + * @return array Associative array matching BBCode names to their template + */ + protected function extract_templates($template) + { + // Capture the template fragments + preg_match_all('#(.*?)#s', $template, $matches, PREG_SET_ORDER); + + $fragments = array(); + foreach ($matches as $match) + { + // Normalize the whitespace + $fragment = preg_replace('#>\\n\\t*<#', '><', trim($match[2])); + + $fragments[$match[1]] = $fragment; + } + + // Automatically recompose templates split between *_open and *_close + foreach ($fragments as $fragment_name => $fragment) + { + if (preg_match('#^(\\w+)_close$#', $fragment_name, $match)) + { + $bbcode_name = $match[1]; + + if (isset($fragments[$bbcode_name . '_open'])) + { + $templates[$bbcode_name] = $fragments[$bbcode_name . '_open'] . '' . $fragment; + } + } + } + + // Manually recompose and overwrite irregular templates + $templates['list'] = + ' + + ' . $fragments['ulist_open_default'] . '' . $fragments['ulist_close'] . ' + + + ' . $fragments['olist_open'] . '' . $fragments['olist_close'] . ' + + + ' . $fragments['ulist_open'] . '' . $fragments['ulist_close'] . ' + + '; + + $templates['li'] = $fragments['listitem'] . '' . $fragments['listitem_close']; + + $templates['quote'] = + ' + + ' . $fragments['quote_username_open'] . '' . $fragments['quote_close'] . ' + + + ' . $fragments['quote_open'] . '' . $fragments['quote_close'] . ' + + '; + + // The [attachment] BBCode uses the inline_attachment template to output a comment that + // is post-processed by parse_attachments() + $templates['attachment'] = $fragments['inline_attachment_open'] . ' ia ia ' . $fragments['inline_attachment_close']; + + // Finally save fragments whose names look like the name of a BBCode, e.g. "flash" + foreach ($fragments as $fragment_name => $fragment) + { + if (preg_match('#^\\w+$#', $fragment_name)) + { + $templates[$fragment_name] = $fragment; + } + } + + return $templates; + } + + /** + * Merge the templates from any number of styles into one BBCode template + * + * @param array $style_templates Associative array matching style_ids to their template + * @return string + */ + protected function merge_templates(array $style_templates) + { + // Group identical templates together + $grouped_templates = array(); + foreach ($style_templates as $style_id => $style_template) + { + $grouped_templates[$style_template][] = $style_id; + } + + if (count($grouped_templates) === 1) + { + return $style_template; + } + + // Sort templates by frequency descending + $templates_cnt = array_map('sizeof', $grouped_templates); + array_multisort($grouped_templates, $templates_cnt); + + // Remove the most frequent template from the list; It becomes the default + reset($grouped_templates); + $default_template = key($grouped_templates); + unset($grouped_templates[$default_template]); + + // Build an xsl:choose switch + $template = ''; + foreach ($grouped_templates as $style_template => $style_ids) + { + $template .= '' . $style_template . ''; + } + $template .= '' . $default_template . ''; + + return $template; + } +} diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php new file mode 100644 index 0000000000..10e33f47e6 --- /dev/null +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -0,0 +1,335 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter\s9e; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use s9e\TextFormatter\Parser\BuiltInFilters; +use s9e\TextFormatter\Parser\Logger; + +/** +* s9e\TextFormatter\Parser adapter +* @package phpBB3 +*/ +class parser extends \phpbb\textformatter\parser +{ + /** + * @var s9e\TextFormatter\Parser + */ + protected $parser; + + /** + * @var phpbb\user User object, used for translating errors + */ + protected $user; + + /** + * Constructor + * + * @param phpbb\cache\driver_interface $cache + * @param string $key Cache key + * @param phpbb\user $user + * @param Symfony\Component\DependencyInjection\ContainerInterface $container + * @return null + */ + public function __construct(\phpbb\cache\driver\driver_interface $cache, $key, \phpbb\user $user, ContainerInterface $container) + { + $this->user = $user; + + $parser = $cache->get($key); + if (!$parser) + { + list($parser) = $container->get('text_formatter.s9e.factory')->regenerate(); + } + + $this->parser = $parser; + } + + /** + * {@inheritdoc} + */ + public function parse($text) + { + return $this->parser->parse($text); + } + + /** + * {@inheritdoc} + */ + public function disable_bbcode($name) + { + $this->parser->disableTag(strtoupper($name)); + } + + /** + * {@inheritdoc} + */ + public function disable_bbcodes() + { + $this->parser->disablePlugin('BBCodes'); + } + + /** + * {@inheritdoc} + */ + public function disable_censor() + { + $this->parser->disablePlugin('Censor'); + } + + /** + * {@inheritdoc} + */ + public function disable_magic_url() + { + $this->parser->disablePlugin('Autoemail'); + $this->parser->disablePlugin('Autolink'); + } + + /** + * {@inheritdoc} + */ + public function disable_smilies() + { + $this->parser->disablePlugin('Emoticons'); + } + + /** + * {@inheritdoc} + */ + public function enable_bbcode($name) + { + $this->parser->enableTag(strtoupper($name)); + } + + /** + * {@inheritdoc} + */ + public function enable_bbcodes() + { + $this->parser->enablePlugin('BBCodes'); + } + + /** + * {@inheritdoc} + */ + public function enable_censor() + { + $this->parser->enablePlugin('Censor'); + } + + /** + * {@inheritdoc} + */ + public function enable_magic_url() + { + $this->parser->enablePlugin('Autoemail'); + $this->parser->enablePlugin('Autolink'); + } + + /** + * {@inheritdoc} + */ + public function enable_smilies() + { + $this->parser->enablePlugin('Emoticons'); + } + + /** + * {@inheritdoc} + * + * This will translate the log entries found in s9e\TextFormatter's logger into phpBB error + * messages + */ + public function get_errors() + { + $errors = array(); + + foreach ($this->parser->getLogger()->get() as $entry) + { + list($type, $msg, $context) = $entry; + + if ($msg === 'Tag limit exceeded') + { + if ($context['tagName'] === 'E') + { + $errors[] = $this->user->lang('TOO_MANY_SMILIES', $context['tagLimit']); + } + else if ($context['tagName'] === 'URL') + { + $errors[] = $this->user->lang('TOO_MANY_URLS', $context['tagLimit']); + } + } + else if ($msg === 'MAX_FONT_SIZE_EXCEEDED') + { + $errors[] = $this->user->lang($msg, $context['max_size']); + } + else if (preg_match('/^MAX_(?:FLASH|IMG)_(HEIGHT|WIDTH)_EXCEEDED$/D', $msg, $m)) + { + $errors[] = $this->user->lang($msg, $context['max_' . strtolower($m[1])]); + } + else if ($msg === 'Tag is disabled') + { + $name = strtolower($context['tag']->getName()); + $errors[] = $this->user->lang('UNAUTHORISED_BBCODE', '[' . $name . ']'); + } + else if ($msg === 'UNABLE_GET_IMAGE_SIZE') + { + $errors[] = $this->user->lang[$msg]; + } + } + + return array_unique($errors); + } + + /** + * {@inheritdoc} + */ + public function set_var($name, $value) + { + if ($name === 'max_smilies') + { + $this->parser->setTagLimit('E', $value ?: PHP_INT_MAX); + } + else if ($name === 'max_urls') + { + $this->parser->setTagLimit('URL', $value ?: PHP_INT_MAX); + } + else + { + $this->parser->registeredVars[$name] = $value; + } + } + + /** + * Filter a flash object's height + * + * @see bbcode_firstpass::bbcode_flash() + * + * @param string $height + * @param integer $max_height + * @param s9e\TextFormatter\Parser\Logger $logger + * @return mixed Original value if valid, FALSE otherwise + */ + static public function filter_flash_height($height, $max_height, Logger $logger) + { + if ($max_height && $height > $max_height) + { + $logger->err('MAX_FLASH_HEIGHT_EXCEEDED', array('max_height' => $max_height)); + + return false; + } + + return $height; + } + + /** + * Filter a flash object's width + * + * @see bbcode_firstpass::bbcode_flash() + * + * @param string $width + * @param integer $max_width + * @param s9e\TextFormatter\Parser\Logger $logger + * @return mixed Original value if valid, FALSE otherwise + */ + static public function filter_flash_width($width, $max_width, Logger $logger) + { + if ($max_width && $width > $max_width) + { + $logger->err('MAX_FLASH_WIDTH_EXCEEDED', array('max_width' => $max_width)); + + return false; + } + + return $width; + } + + /** + * Filter the value used in a [size] BBCode + * + * @see bbcode_firstpass::bbcode_size() + * + * @param string $size Original size + * @param integer $max_size Maximum allowed size + * @param s9e\TextFormatter\Parser\Logger $logger + * @return mixed Original value if valid, FALSE otherwise + */ + static public function filter_font_size($size, $max_size, Logger $logger) + { + if ($max_size && $size > $max_size) + { + $logger->err('MAX_FONT_SIZE_EXCEEDED', array('max_size' => $max_size)); + + return false; + } + + if ($size < 1) + { + return false; + } + + return $size; + } + + /** + * Filter an image's URL to enforce restrictions on its dimensions + * + * @see bbcode_firstpass::bbcode_img() + * + * @param string $url Original URL + * @param array $url_config Config used by the URL filter + * @param s9e\TextFormatter\Parser\Logger $logger + * @param integer $max_height Maximum height allowed + * @param integer $max_width Maximum width allowed + * @return string|bool Original value if valid, FALSE otherwise + */ + static public function filter_img_url($url, array $url_config, Logger $logger, $max_height, $max_width) + { + // Validate the URL + $url = BuiltInFilters::filterUrl($url, $url_config, $logger); + + if ($url === false) + { + return false; + } + + if ($max_height || $max_width) + { + $stats = @getimagesize($url); + + if ($stats === false) + { + $logger->err('UNABLE_GET_IMAGE_SIZE'); + + return false; + } + + if ($max_height && $max_height < $stats[1]) + { + $logger->err('MAX_IMG_HEIGHT_EXCEEDED', array('max_height' => $max_height)); + + return false; + } + + if ($max_width && $max_width < $stats[0]) + { + $logger->err('MAX_IMG_WIDTH_EXCEEDED', array('max_width' => $max_width)); + + return false; + } + } + + return $url; + } +} diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php new file mode 100644 index 0000000000..2c8412f961 --- /dev/null +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -0,0 +1,228 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter\s9e; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** +* s9e\TextFormatter\Renderer adapter +* @package phpBB3 +*/ +class renderer extends \phpbb\textformatter\renderer +{ + /** + * @var s9e\TextFormatter\Renderer + */ + protected $renderer; + + /** + * @var bool Status of the viewcensors option + */ + protected $viewcensors = false; + + /** + * @var bool Status of the viewflash option + */ + protected $viewflash = false; + + /** + * @var bool Status of the viewimg option + */ + protected $viewimg = false; + + /** + * @var bool Status of the viewsmilies option + */ + protected $viewsmilies = false; + + /** + * Constructor + * + * @param phpbb\cache\driver\driver_interface $cache + * @param string $cache_dir Path to the cache dir + * @param string $key Cache key + * @param Symfony\Component\DependencyInjection\ContainerInterface $container + * @return null + */ + public function __construct(\phpbb\cache\driver\driver_interface $cache, $cache_dir, $key, ContainerInterface $container) + { + $renderer_data = $cache->get($key); + + if ($renderer_data) + { + $class = $renderer_data['class']; + + if (!class_exists($class, false)) + { + // Try to load the renderer class from its cache file + $cache_file = $cache_dir . $class . '.php'; + + if (file_exists($cache_file)) + { + include($cache_file); + } + } + + if (class_exists($class, false)) + { + $renderer = unserialize($renderer_data['renderer']); + } + } + + if (!isset($renderer)) + { + list(, $renderer) = $container->get('text_formatter.s9e.factory')->regenerate(); + } + + $this->renderer = $renderer; + } + + /** + * {@inheritdoc} + */ + public function configure_user(\phpbb\user $user, \phpbb\config\config $config, \phpbb\auth\auth $auth) + { + parent::configure_user($user, $config, $auth); + + // Set the stylesheet parameters + foreach (array_keys($this->renderer->getParameters()) as $param_name) + { + if (substr($param_name, 0, 2) === 'L_') + { + // L_FOO is set to $user->lang('FOO') + $this->renderer->setParameter($param_name, $user->lang(substr($param_name, 2))); + } + } + + // Set the style id + $this->renderer->setParameter('STYLE_ID', $user->style['style_id']); + } + + /** + * {@inheritdoc} + */ + public function get_viewcensors() + { + return $this->viewcensors; + } + + /** + * {@inheritdoc} + */ + public function get_viewflash() + { + return $this->viewflash; + } + + /** + * {@inheritdoc} + */ + public function get_viewimg() + { + return $this->viewimg; + } + + /** + * {@inheritdoc} + */ + public function get_viewsmilies() + { + return $this->viewsmilies; + } + + /** + * {@inheritdoc} + */ + public function render($text) + { + $html = $this->renderer->render($text); + + /** + * @see bbcode::bbcode_second_pass_code() + */ + $html = preg_replace_callback( + '#()(.*?)()#is', + function ($captures) + { + $code = $captures[2]; + + $code = str_replace("\t", '   ', $code); + $code = str_replace(' ', '  ', $code); + $code = str_replace(' ', '  ', $code); + $code = str_replace("\n ", "\n ", $code); + + // keep space at the beginning + if (!empty($code) && $code[0] == ' ') + { + $code = ' ' . substr($code, 1); + } + + // remove newline at the beginning + if (!empty($code) && $code[0] == "\n") + { + $code = substr($code, 1); + } + + return $captures[1] . $code . $captures[3]; + }, + $html + ); + + return $html; + } + + /** + * {@inheritdoc} + */ + public function set_smilies_path($path) + { + $this->renderer->setParameter('T_SMILIES_PATH', $path); + } + + /** + * {@inheritdoc} + */ + public function set_viewcensors($value) + { + $this->viewcensors = $value; + $this->renderer->setParameter('S_VIEWCENSORS', $value); + } + + /** + * {@inheritdoc} + */ + public function set_viewflash($value) + { + $this->viewflash = $value; + $this->renderer->setParameter('S_VIEWFLASH', $value); + } + + /** + * {@inheritdoc} + */ + public function set_viewimg($value) + { + $this->viewimg = $value; + $this->renderer->setParameter('S_VIEWIMG', $value); + } + + /** + * {@inheritdoc} + */ + public function set_viewsmilies($value) + { + $this->viewsmilies = $value; + $this->renderer->setParameter('S_VIEWSMILIES', $value); + } +} diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php new file mode 100644 index 0000000000..19cd3a11c8 --- /dev/null +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -0,0 +1,67 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter\s9e; + +/** +* Text manipulation utilities +* @package phpBB3 +*/ +class utils extends \phpbb\textformatter\utils +{ + /** + * {@inheritdoc} + */ + public function clean_formatting($text) + { + // Insert a space before and then remove formatting + $text = preg_replace('#<[es]>#', ' $0', $text); + + return \s9e\TextFormatter\Unparser::removeFormatting($text); + } + + /** + * {@inheritdoc} + */ + public function remove_bbcode($text, $bbcode_name, $depth = 0) + { + $dom = new \DOMDocument; + $dom->loadXML($text); + + $xpath = new \DOMXPath($dom); + $nodes = $xpath->query(str_repeat('//' . strtoupper($bbcode_name), 1 + $depth)); + + foreach ($nodes as $node) + { + $node->parentNode->removeChild($node); + } + + return $dom->saveXML($dom->documentElement); + } + + /** + * {@inheritdoc} + */ + public function remove_formatting($text) + { + return \s9e\TextFormatter\Unparser::removeFormatting($text); + } + + /** + * {@inheritdoc} + */ + public function unparse($text) + { + return \s9e\TextFormatter\Unparser::unparse($text); + } +} diff --git a/phpBB/phpbb/textformatter/utils.php b/phpBB/phpbb/textformatter/utils.php new file mode 100644 index 0000000000..c9bed94553 --- /dev/null +++ b/phpBB/phpbb/textformatter/utils.php @@ -0,0 +1,62 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter; + +/** +* text_formatter.utils service +* +* Used to manipulate a parsed text +* +* @package phpBB3 +*/ +abstract class utils +{ + /** + * Replace BBCodes and other formatting elements with whitespace + * + * NOTE: preserves smilies as text + * + * @param string $text + * @return string + */ + abstract public function clean_formatting($text); + + /** + * Remove given BBCode at given nesting depth + * + * @param string $text Parsed text + * @param string $bbcode_name BBCode's name + * @param integer $depth Minimum nesting depth (number of parents of the same name) + * @return string + */ + abstract public function remove_bbcode($text, $bbcode_name, $depth = 0); + + /** + * Remove BBCodes and other formatting from a parsed text + * + * NOTE: preserves smilies as text + * + * @param string $text + * @return string + */ + abstract public function remove_formatting($text); + + /** + * Return a parsed text to its original form + * + * @param string $text + * @return string + */ + abstract public function unparse($text); +} -- cgit v1.2.1 From cf39b02891d5ab021e4abc0932e1bb964cbd680c Mon Sep 17 00:00:00 2001 From: s9e Date: Thu, 8 Jan 2015 11:28:23 +0100 Subject: [ticket/11768] Updated annotations to pass sniff PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 2 +- phpBB/phpbb/textformatter/s9e/parser.php | 10 +++++----- phpBB/phpbb/textformatter/s9e/renderer.php | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 8d61f2caac..39697f6d4b 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -145,7 +145,7 @@ class factory implements \phpbb\textformatter\cache /** * Generate and return a new configured instance of s9e\TextFormatter\Configurator * - * @return s9e\TextFormatter\Configurator + * @return Configurator */ public function get_configurator() { diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 10e33f47e6..58cef8fa9e 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -39,7 +39,7 @@ class parser extends \phpbb\textformatter\parser * @param phpbb\cache\driver_interface $cache * @param string $key Cache key * @param phpbb\user $user - * @param Symfony\Component\DependencyInjection\ContainerInterface $container + * @param ContainerInterface $container * @return null */ public function __construct(\phpbb\cache\driver\driver_interface $cache, $key, \phpbb\user $user, ContainerInterface $container) @@ -218,7 +218,7 @@ class parser extends \phpbb\textformatter\parser * * @param string $height * @param integer $max_height - * @param s9e\TextFormatter\Parser\Logger $logger + * @param Logger $logger * @return mixed Original value if valid, FALSE otherwise */ static public function filter_flash_height($height, $max_height, Logger $logger) @@ -240,7 +240,7 @@ class parser extends \phpbb\textformatter\parser * * @param string $width * @param integer $max_width - * @param s9e\TextFormatter\Parser\Logger $logger + * @param Logger $logger * @return mixed Original value if valid, FALSE otherwise */ static public function filter_flash_width($width, $max_width, Logger $logger) @@ -262,7 +262,7 @@ class parser extends \phpbb\textformatter\parser * * @param string $size Original size * @param integer $max_size Maximum allowed size - * @param s9e\TextFormatter\Parser\Logger $logger + * @param Logger $logger * @return mixed Original value if valid, FALSE otherwise */ static public function filter_font_size($size, $max_size, Logger $logger) @@ -289,7 +289,7 @@ class parser extends \phpbb\textformatter\parser * * @param string $url Original URL * @param array $url_config Config used by the URL filter - * @param s9e\TextFormatter\Parser\Logger $logger + * @param Logger $logger * @param integer $max_height Maximum height allowed * @param integer $max_width Maximum width allowed * @return string|bool Original value if valid, FALSE otherwise diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 2c8412f961..c724be7cfe 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -50,9 +50,9 @@ class renderer extends \phpbb\textformatter\renderer * Constructor * * @param phpbb\cache\driver\driver_interface $cache - * @param string $cache_dir Path to the cache dir - * @param string $key Cache key - * @param Symfony\Component\DependencyInjection\ContainerInterface $container + * @param string $cache_dir Path to the cache dir + * @param string $key Cache key + * @param ContainerInterface $container * @return null */ public function __construct(\phpbb\cache\driver\driver_interface $cache, $cache_dir, $key, ContainerInterface $container) -- cgit v1.2.1 From dc303cbc993755ec446fcc3f060659668e5073f8 Mon Sep 17 00:00:00 2001 From: s9e Date: Fri, 16 Jan 2015 02:31:14 +0100 Subject: [ticket/11768] Toggled Unicode modifier in relative URL filter get_preg_expression('relative_url') returns an expression that requires it PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 39697f6d4b..06bee34767 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -163,13 +163,11 @@ class factory implements \phpbb\textformatter\cache // Create custom filters for BBCode tokens that are supported in phpBB but not in // s9e\TextFormatter - $filter = new RegexpFilter('#^' . get_preg_expression('relative_url') . '$#D'); + $filter = new RegexpFilter('#^' . get_preg_expression('relative_url') . '$#Du'); $configurator->attributeFilters->add('#local_url', $filter); $configurator->attributeFilters->add('#relative_url', $filter); - $regexp = (phpbb_pcre_utf8_support()) - ? '!^([\p{L}\p{N}\-+,_. ]+)$!uD' - : '!^([a-zA-Z0-9\-+,_. ]+)$!uD'; + $regexp = '!^([\p{L}\p{N}\-+,_. ]+)$!Du'; $configurator->attributeFilters->add('#inttext', new RegexpFilter($regexp)); // Create custom filters for Flash restrictions, which use the same values as the image -- cgit v1.2.1 From e0bb446c57d692b3e968a7a3ccd9d726f0779391 Mon Sep 17 00:00:00 2001 From: s9e Date: Fri, 16 Jan 2015 03:54:42 +0100 Subject: [ticket/11768] Reorganized code for readability No functional change intended PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 06bee34767..d000262bec 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -167,8 +167,9 @@ class factory implements \phpbb\textformatter\cache $configurator->attributeFilters->add('#local_url', $filter); $configurator->attributeFilters->add('#relative_url', $filter); - $regexp = '!^([\p{L}\p{N}\-+,_. ]+)$!Du'; - $configurator->attributeFilters->add('#inttext', new RegexpFilter($regexp)); + // INTTEXT regexp from acp_bbcodes + $filter = new RegexpFilter('!^([\p{L}\p{N}\-+,_. ]+)$!Du'); + $configurator->attributeFilters->add('#inttext', $filter); // Create custom filters for Flash restrictions, which use the same values as the image // restrictions but have their own error message -- cgit v1.2.1 From 72fb380c9fbb0d6fa51236bdc179ba7ef6126a5a Mon Sep 17 00:00:00 2001 From: s9e Date: Wed, 4 Feb 2015 23:07:58 +0100 Subject: [ticket/11768] Updated constructors with explicit dependencies The trade-off is that an instance of phpbb\textformatter\s9e\factory and phpbb\textformatter\data_access is created on any page that uses the parser or the renderer, even when neither need to be regenerated. It has no measureable impact on performance and costs ~20KB of RAM. PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/parser.php | 6 +++--- phpBB/phpbb/textformatter/s9e/renderer.php | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 58cef8fa9e..d9f693ba18 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -39,17 +39,17 @@ class parser extends \phpbb\textformatter\parser * @param phpbb\cache\driver_interface $cache * @param string $key Cache key * @param phpbb\user $user - * @param ContainerInterface $container + * @param factory $factory * @return null */ - public function __construct(\phpbb\cache\driver\driver_interface $cache, $key, \phpbb\user $user, ContainerInterface $container) + public function __construct(\phpbb\cache\driver\driver_interface $cache, $key, \phpbb\user $user, factory $factory) { $this->user = $user; $parser = $cache->get($key); if (!$parser) { - list($parser) = $container->get('text_formatter.s9e.factory')->regenerate(); + list($parser) = $factory->regenerate(); } $this->parser = $parser; diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index c724be7cfe..9fe538e35d 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -49,13 +49,13 @@ class renderer extends \phpbb\textformatter\renderer /** * Constructor * - * @param phpbb\cache\driver\driver_interface $cache - * @param string $cache_dir Path to the cache dir - * @param string $key Cache key - * @param ContainerInterface $container + * @param \phpbb\cache\driver\driver_interface $cache + * @param string $cache_dir Path to the cache dir + * @param string $key Cache key + * @param factory $factory * @return null */ - public function __construct(\phpbb\cache\driver\driver_interface $cache, $cache_dir, $key, ContainerInterface $container) + public function __construct(\phpbb\cache\driver\driver_interface $cache, $cache_dir, $key, factory $factory) { $renderer_data = $cache->get($key); @@ -82,7 +82,7 @@ class renderer extends \phpbb\textformatter\renderer if (!isset($renderer)) { - list(, $renderer) = $container->get('text_formatter.s9e.factory')->regenerate(); + list(, $renderer) = $factory->regenerate(); } $this->renderer = $renderer; -- cgit v1.2.1 From 3b115a903a5651f05ac388dea774d1b4022e2ed8 Mon Sep 17 00:00:00 2001 From: s9e Date: Thu, 5 Feb 2015 00:59:29 +0100 Subject: [ticket/11768] Removed unused use statements PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/parser.php | 1 - phpBB/phpbb/textformatter/s9e/renderer.php | 2 -- 2 files changed, 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index d9f693ba18..3b490131f2 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -13,7 +13,6 @@ namespace phpbb\textformatter\s9e; -use Symfony\Component\DependencyInjection\ContainerInterface; use s9e\TextFormatter\Parser\BuiltInFilters; use s9e\TextFormatter\Parser\Logger; diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 9fe538e35d..eea01f82af 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -13,8 +13,6 @@ namespace phpbb\textformatter\s9e; -use Symfony\Component\DependencyInjection\ContainerInterface; - /** * s9e\TextFormatter\Renderer adapter * @package phpBB3 -- cgit v1.2.1 From f6e3e41717e71fb43ea63785cfe7980e33be3fbf Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 13 Feb 2015 11:28:51 +0100 Subject: [ticket/11768] Added support for magic links that start with "www." PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index d000262bec..77b1a1c916 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -280,7 +280,7 @@ class factory implements \phpbb\textformatter\cache // Load the magic links plugins. We do that after BBCodes so that they use the same tags $configurator->plugins->load('Autoemail'); - $configurator->plugins->load('Autolink'); + $configurator->plugins->load('Autolink', array('matchWww' => true)); // Register some vars with a default value. Those should be set at runtime by whatever calls // the parser -- cgit v1.2.1 From 6bd86a8e8a7c8e2ccf90d02343132c085978cd44 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 15 Feb 2015 03:08:36 +0100 Subject: [ticket/11768] Updated phpbb\textformatter\s9e\factory::regenerate() Returns an associative array rather than a numerically-indexed array. Feels cleaner and more extensible. PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 4 ++-- phpBB/phpbb/textformatter/s9e/parser.php | 2 +- phpBB/phpbb/textformatter/s9e/renderer.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 77b1a1c916..ed99bba4a1 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -294,7 +294,7 @@ class factory implements \phpbb\textformatter\cache /** * Regenerate and cache a new parser and renderer * - * @return array Array with two elements: an instance of the parser, an instance of the renderer + * @return array Associative array with at least two elements: "parser" and "renderer" */ public function regenerate() { @@ -315,7 +315,7 @@ class factory implements \phpbb\textformatter\cache ); $this->cache->put($this->cache_key_renderer, $renderer_data); - return array($parser, $renderer); + return array('parser' => $parser, 'renderer' => $renderer); } /** diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 3b490131f2..8e78a18d40 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -48,7 +48,7 @@ class parser extends \phpbb\textformatter\parser $parser = $cache->get($key); if (!$parser) { - list($parser) = $factory->regenerate(); + extract($factory->regenerate()); } $this->parser = $parser; diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index eea01f82af..943056e6ca 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -80,7 +80,7 @@ class renderer extends \phpbb\textformatter\renderer if (!isset($renderer)) { - list(, $renderer) = $factory->regenerate(); + extract($factory->regenerate()); } $this->renderer = $renderer; -- cgit v1.2.1 From 6578e1c6ec7172016fbfa375dd2fce5cb20f3ce1 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 17 Feb 2015 09:18:31 +0100 Subject: [ticket/11768] Added limited support for [url] in [quote] author PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index ed99bba4a1..47da3e3eb7 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -74,7 +74,14 @@ class factory implements \phpbb\textformatter\cache 'img' => '[IMG src={IMAGEURL;useContent}]', 'list' => '[LIST type={HASHMAP=1:decimal,a:lower-alpha,A:upper-alpha,i:lower-roman,I:upper-roman;optional;postFilter=#simpletext}]{TEXT}[/LIST]', 'li' => '[* $tagName=LI]{TEXT}[/*]', - 'quote' => '[QUOTE author={TEXT1;optional}]{TEXT2}[/QUOTE]', + 'quote' => + "[QUOTE + author={TEXT1;optional} + url={URL;optional} + author={PARSE=/^\\[url=(?'url'.*?)](?'author'.*)\\[\\/url]$/i} + author={PARSE=/^\\[url](?'author'(?'url'.*?))\\[\\/url]$/i} + author={PARSE=/(?'url'https?:\\/\\/[^[\\]]+)/i} + ]{TEXT2}[/QUOTE]", 'size' => '[SIZE={FONTSIZE}]{TEXT}[/SIZE]', 'u' => '[U]{TEXT}[/U]', 'url' => '[URL={URL;useContent}]{TEXT}[/URL]', @@ -424,6 +431,15 @@ class factory implements \phpbb\textformatter\cache $templates['li'] = $fragments['listitem'] . '' . $fragments['listitem_close']; + $fragments['quote_username_open'] = str_replace( + '{USERNAME}', + ' + ' . str_replace('{DESCRIPTION}', '{USERNAME}', $fragments['url']) . ' + {USERNAME} + ', + $fragments['quote_username_open'] + ); + $templates['quote'] = ' @@ -438,7 +454,7 @@ class factory implements \phpbb\textformatter\cache // is post-processed by parse_attachments() $templates['attachment'] = $fragments['inline_attachment_open'] . ' ia ia ' . $fragments['inline_attachment_close']; - // Finally save fragments whose names look like the name of a BBCode, e.g. "flash" + // Add fragments as templates foreach ($fragments as $fragment_name => $fragment) { if (preg_match('#^\\w+$#', $fragment_name)) @@ -447,6 +463,9 @@ class factory implements \phpbb\textformatter\cache } } + // Keep only templates that are named after an existing BBCode + $templates = array_intersect_key($templates, $this->default_definitions); + return $templates; } -- cgit v1.2.1 From f721b85a7835c18459b310e4db74cc0f654b05ec Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 19 Feb 2015 06:05:39 +0100 Subject: [ticket/11768] Replaced the Censor plugin ...with something that is run at rendering time. PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 38 ++++++++++++++++-------------- phpBB/phpbb/textformatter/s9e/renderer.php | 21 ++++++++++++++++- 2 files changed, 40 insertions(+), 19 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 47da3e3eb7..557645b0d6 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -264,25 +264,15 @@ class factory implements \phpbb\textformatter\cache } // Load the censored words - foreach ($this->dal->get_words() as $row) + $censor = $this->dal->get_words(); + if (!empty($censor)) { - $configurator->Censor->add($row['word'], $row['replacement']); - } - - if (isset($configurator->Censor)) - { - // Replace the template with a template that applies only when $S_VIEWCENSORS is set - $tag = $configurator->Censor->getTag(); - $tag->template = - ' - - - - - - - **** - '; + // Use a namespaced tag to avoid collisions + $configurator->plugins->load('Censor', array('tagName' => 'censor:tag')); + foreach ($censor as $row) + { + $configurator->Censor->add($row['word'], $row['replacement']); + } } // Load the magic links plugins. We do that after BBCodes so that they use the same tags @@ -307,6 +297,14 @@ class factory implements \phpbb\textformatter\cache { $configurator = $this->get_configurator(); + // Get the censor helper and remove the Censor plugin if applicable + if (isset($configurator->Censor)) + { + $censor = $configurator->Censor->getHelper(); + unset($configurator->Censor); + unset($configurator->tags['censor:tag']); + } + // Create $parser and $renderer extract($configurator->finalize()); @@ -320,6 +318,10 @@ class factory implements \phpbb\textformatter\cache 'class' => get_class($renderer), 'renderer' => serialize($renderer) ); + if (isset($censor)) + { + $renderer_data['censor'] = $censor; + } $this->cache->put($this->cache_key_renderer, $renderer_data); return array('parser' => $parser, 'renderer' => $renderer); diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 943056e6ca..3ec5f38029 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -19,6 +19,11 @@ namespace phpbb\textformatter\s9e; */ class renderer extends \phpbb\textformatter\renderer { + /** + * @var s9e\TextFormatter\Plugins\Censor\Helper + */ + protected $censor; + /** * @var s9e\TextFormatter\Renderer */ @@ -56,7 +61,6 @@ class renderer extends \phpbb\textformatter\renderer public function __construct(\phpbb\cache\driver\driver_interface $cache, $cache_dir, $key, factory $factory) { $renderer_data = $cache->get($key); - if ($renderer_data) { $class = $renderer_data['class']; @@ -76,6 +80,11 @@ class renderer extends \phpbb\textformatter\renderer { $renderer = unserialize($renderer_data['renderer']); } + + if (isset($renderer_data['censor'])) + { + $censor = $renderer_data['censor']; + } } if (!isset($renderer)) @@ -83,6 +92,11 @@ class renderer extends \phpbb\textformatter\renderer extract($factory->regenerate()); } + if (isset($censor)) + { + $this->censor = $censor; + } + $this->renderer = $renderer; } @@ -146,6 +160,11 @@ class renderer extends \phpbb\textformatter\renderer { $html = $this->renderer->render($text); + if (isset($this->censor) && $this->viewcensors) + { + $html = $this->censor->censorHtml($html, true); + } + /** * @see bbcode::bbcode_second_pass_code() */ -- cgit v1.2.1 From 3e5ee87b15c70fbfc246b6d8f6d18a186d11d83a Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 20 Feb 2015 06:03:05 +0100 Subject: [ticket/11768] Allowed text in places where text is not valid HTML PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 557645b0d6..a6639976c4 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -162,6 +162,9 @@ class factory implements \phpbb\textformatter\cache // Convert newlines to br elements by default $configurator->rootRules->enableAutoLineBreaks(); + // Don't automatically ignore text in places where text is not allowed + $configurator->rulesGenerator->remove('IgnoreTextIfDisallowed'); + // Set the rendering engine and configure it to save to the cache dir $configurator->rendering->engine = 'PHP'; $configurator->rendering->engine->cacheDir = $this->cache_dir; -- cgit v1.2.1 From c1ba3a678d5a565b74d893c57eb5133623702350 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 23 Feb 2015 19:03:41 +0100 Subject: [ticket/11768] Added methods to access the library's parser/renderer PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/parser.php | 10 ++++++++++ phpBB/phpbb/textformatter/s9e/renderer.php | 10 ++++++++++ 2 files changed, 20 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 8e78a18d40..b717dea962 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -191,6 +191,16 @@ class parser extends \phpbb\textformatter\parser return array_unique($errors); } + /** + * Return the instance of s9e\TextFormatter\Parser used by this object + * + * @return s9e\TextFormatter\Parser + */ + public function get_parser() + { + return $this->parser; + } + /** * {@inheritdoc} */ diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 3ec5f38029..3ccb40cc2d 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -121,6 +121,16 @@ class renderer extends \phpbb\textformatter\renderer $this->renderer->setParameter('STYLE_ID', $user->style['style_id']); } + /** + * Return the instance of s9e\TextFormatter\Renderer used by this object + * + * @return s9e\TextFormatter\Renderer + */ + public function get_renderer() + { + return $this->renderer; + } + /** * {@inheritdoc} */ -- cgit v1.2.1 From 73ce09b73a97e351197005ac89113d3451b41da0 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 23 Feb 2015 19:34:10 +0100 Subject: [ticket/11768] Fixed censored words being escaped twice PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index a6639976c4..9af34ab90a 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -274,7 +274,8 @@ class factory implements \phpbb\textformatter\cache $configurator->plugins->load('Censor', array('tagName' => 'censor:tag')); foreach ($censor as $row) { - $configurator->Censor->add($row['word'], $row['replacement']); + // NOTE: words are stored as HTML, we need to decode them to plain text + $configurator->Censor->add(htmlspecialchars_decode($row['word']), htmlspecialchars_decode($row['replacement'])); } } -- cgit v1.2.1 From 5fe74cd3944387831fb1949198409481a1358ee5 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 23 Feb 2015 19:35:49 +0100 Subject: [ticket/11768] Updated censor to apply to XML values PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/renderer.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 3ccb40cc2d..54382d7d1e 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -168,13 +168,14 @@ class renderer extends \phpbb\textformatter\renderer */ public function render($text) { - $html = $this->renderer->render($text); - if (isset($this->censor) && $this->viewcensors) { - $html = $this->censor->censorHtml($html, true); + // NOTE: censorHtml() is XML-safe + $text = $this->censor->censorHtml($text, true); } + $html = $this->renderer->render($text); + /** * @see bbcode::bbcode_second_pass_code() */ -- cgit v1.2.1 From baadc2a6e52437d9d5912c828a337a3c2866c9eb Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 00:38:35 +0100 Subject: [ticket/11768] Removed unused annotations PHPBB3-11768 --- phpBB/phpbb/textformatter/cache.php | 6 ------ phpBB/phpbb/textformatter/data_access.php | 4 ---- phpBB/phpbb/textformatter/parser.php | 4 ---- phpBB/phpbb/textformatter/renderer.php | 4 ---- phpBB/phpbb/textformatter/s9e/factory.php | 1 - phpBB/phpbb/textformatter/s9e/parser.php | 1 - phpBB/phpbb/textformatter/s9e/renderer.php | 1 - phpBB/phpbb/textformatter/s9e/utils.php | 1 - phpBB/phpbb/textformatter/utils.php | 4 ---- 9 files changed, 26 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/cache.php b/phpBB/phpbb/textformatter/cache.php index c92683217e..a2f7ff7d7b 100644 --- a/phpBB/phpbb/textformatter/cache.php +++ b/phpBB/phpbb/textformatter/cache.php @@ -14,14 +14,8 @@ namespace phpbb\textformatter; /** -* text_formatter.cache service -* * Currently only used to signal that something that could effect the rendering has changed. * BBCodes, smilies, censored words, templates, etc... -* -* @todo functionality should be moved to data_access -* -* @package phpBB3 */ interface cache { diff --git a/phpBB/phpbb/textformatter/data_access.php b/phpBB/phpbb/textformatter/data_access.php index ec6bf9f88e..2576b734f4 100644 --- a/phpBB/phpbb/textformatter/data_access.php +++ b/phpBB/phpbb/textformatter/data_access.php @@ -14,14 +14,10 @@ namespace phpbb\textformatter; /** -* text_formatter.data_access service -* * Data access layer that fetchs BBCodes, smilies and censored words from the database. * To be extended to include insert/update/delete operations. * * Also used to get templates. -* -* @package phpBB3 */ class data_access { diff --git a/phpBB/phpbb/textformatter/parser.php b/phpBB/phpbb/textformatter/parser.php index c595a459bd..6746ccada5 100644 --- a/phpBB/phpbb/textformatter/parser.php +++ b/phpBB/phpbb/textformatter/parser.php @@ -13,10 +13,6 @@ namespace phpbb\textformatter; -/** -* text_formatter.parser service -* @package phpBB3 -*/ abstract class parser { /** diff --git a/phpBB/phpbb/textformatter/renderer.php b/phpBB/phpbb/textformatter/renderer.php index fb731a5294..808beda0a5 100644 --- a/phpBB/phpbb/textformatter/renderer.php +++ b/phpBB/phpbb/textformatter/renderer.php @@ -13,10 +13,6 @@ namespace phpbb\textformatter; -/** -* text_formatter.renderer service -* @package phpBB3 -*/ abstract class renderer { /** diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 9af34ab90a..20ed692850 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -18,7 +18,6 @@ use s9e\TextFormatter\Configurator\Items\AttributeFilters\Regexp as RegexpFilter /** * Creates s9e\TextFormatter objects -* @package phpBB3 */ class factory implements \phpbb\textformatter\cache { diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index b717dea962..977097462b 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -18,7 +18,6 @@ use s9e\TextFormatter\Parser\Logger; /** * s9e\TextFormatter\Parser adapter -* @package phpBB3 */ class parser extends \phpbb\textformatter\parser { diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 54382d7d1e..ab0b032eb4 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -15,7 +15,6 @@ namespace phpbb\textformatter\s9e; /** * s9e\TextFormatter\Renderer adapter -* @package phpBB3 */ class renderer extends \phpbb\textformatter\renderer { diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index 19cd3a11c8..57e836d2d4 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -15,7 +15,6 @@ namespace phpbb\textformatter\s9e; /** * Text manipulation utilities -* @package phpBB3 */ class utils extends \phpbb\textformatter\utils { diff --git a/phpBB/phpbb/textformatter/utils.php b/phpBB/phpbb/textformatter/utils.php index c9bed94553..13942b9248 100644 --- a/phpBB/phpbb/textformatter/utils.php +++ b/phpBB/phpbb/textformatter/utils.php @@ -14,11 +14,7 @@ namespace phpbb\textformatter; /** -* text_formatter.utils service -* * Used to manipulate a parsed text -* -* @package phpBB3 */ abstract class utils { -- cgit v1.2.1 From b12043d4b076b1e214fd85da28358ba829d47a76 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 00:43:46 +0100 Subject: [ticket/11768] Renamed get_words() to get_censored_words() PHPBB3-11768 --- phpBB/phpbb/textformatter/data_access.php | 2 +- phpBB/phpbb/textformatter/s9e/factory.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/data_access.php b/phpBB/phpbb/textformatter/data_access.php index 2576b734f4..008e1fd5c0 100644 --- a/phpBB/phpbb/textformatter/data_access.php +++ b/phpBB/phpbb/textformatter/data_access.php @@ -217,7 +217,7 @@ class data_access * * @return array */ - public function get_words() + public function get_censored_words() { $sql = 'SELECT word, replacement FROM ' . $this->words_table; $result = $this->db->sql_query($sql); diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 20ed692850..ce9d34e247 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -266,7 +266,7 @@ class factory implements \phpbb\textformatter\cache } // Load the censored words - $censor = $this->dal->get_words(); + $censor = $this->dal->get_censored_words(); if (!empty($censor)) { // Use a namespaced tag to avoid collisions -- cgit v1.2.1 From 694e515f7c812a470a9a1890aa49ba6ad59385fb Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 00:52:31 +0100 Subject: [ticket/11768] Replaced \phpbb\textformatter\parser with an interface PHPBB3-11768 --- phpBB/phpbb/textformatter/parser.php | 36 +++++++++++++------------------- phpBB/phpbb/textformatter/s9e/parser.php | 13 +++++++++++- 2 files changed, 27 insertions(+), 22 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/parser.php b/phpBB/phpbb/textformatter/parser.php index 6746ccada5..922226cf44 100644 --- a/phpBB/phpbb/textformatter/parser.php +++ b/phpBB/phpbb/textformatter/parser.php @@ -13,7 +13,7 @@ namespace phpbb\textformatter; -abstract class parser +interface parser { /** * Parse given text @@ -21,7 +21,7 @@ abstract class parser * @param string $text * @return string */ - abstract public function parse($text); + public function parse($text); /** * Disable a specific BBCode @@ -29,27 +29,27 @@ abstract class parser * @param string $name BBCode name * @return null */ - abstract public function disable_bbcode($name); + public function disable_bbcode($name); /** * Disable BBCodes in general */ - abstract public function disable_bbcodes(); + public function disable_bbcodes(); /** * Disable the censor */ - abstract public function disable_censor(); + public function disable_censor(); /** * Disable magic URLs */ - abstract public function disable_magic_url(); + public function disable_magic_url(); /** * Disable smilies */ - abstract public function disable_smilies(); + public function disable_smilies(); /** * Enable a specific BBCode @@ -57,34 +57,34 @@ abstract class parser * @param string $name BBCode name * @return null */ - abstract public function enable_bbcode($name); + public function enable_bbcode($name); /** * Enable BBCodes in general */ - abstract public function enable_bbcodes(); + public function enable_bbcodes(); /** * Enable the censor */ - abstract public function enable_censor(); + public function enable_censor(); /** * Enable magic URLs */ - abstract public function enable_magic_url(); + public function enable_magic_url(); /** * Enable smilies */ - abstract public function enable_smilies(); + public function enable_smilies(); /** * Get the list of errors that were generated during last parsing * * @return array */ - abstract public function get_errors(); + public function get_errors(); /** * Set a variable to be used by the parser @@ -99,7 +99,7 @@ abstract class parser * @param mixed $value * @return null */ - abstract public function set_var($name, $value); + public function set_var($name, $value); /** * Set multiple variables to be used by the parser @@ -107,11 +107,5 @@ abstract class parser * @param array Associative array of [name => value] * @return null */ - public function set_vars(array $vars) - { - foreach ($vars as $name => $value) - { - $this->set_var($name, $value); - } - } + public function set_vars(array $vars); } diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 977097462b..de51929994 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -19,7 +19,7 @@ use s9e\TextFormatter\Parser\Logger; /** * s9e\TextFormatter\Parser adapter */ -class parser extends \phpbb\textformatter\parser +class parser implements \phpbb\textformatter\parser { /** * @var s9e\TextFormatter\Parser @@ -219,6 +219,17 @@ class parser extends \phpbb\textformatter\parser } } + /** + * {@inheritdoc} + */ + public function set_vars(array $vars) + { + foreach ($vars as $name => $value) + { + $this->set_var($name, $value); + } + } + /** * Filter a flash object's height * -- cgit v1.2.1 From 3d9596be79cc68bc4caa2263c0bd996606ab3543 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 00:54:37 +0100 Subject: [ticket/11768] Updated renderer annotation PHPBB3-11768 --- phpBB/phpbb/textformatter/renderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/renderer.php b/phpBB/phpbb/textformatter/renderer.php index 808beda0a5..1b0a36715f 100644 --- a/phpBB/phpbb/textformatter/renderer.php +++ b/phpBB/phpbb/textformatter/renderer.php @@ -18,7 +18,7 @@ abstract class renderer /** * Render given text * - * @param string $text Text, as parsed by the text_formatter.parser service + * @param string $text Text, as parsed by something that implements \phpbb\textformatter\parser * @return string */ abstract public function render($text); -- cgit v1.2.1 From 825bc45983f961b4d84f5d869dc0cb6111902aa7 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 00:56:14 +0100 Subject: [ticket/11768] Removed comments PHPBB3-11768 --- phpBB/phpbb/textformatter/renderer.php | 3 --- 1 file changed, 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/renderer.php b/phpBB/phpbb/textformatter/renderer.php index 1b0a36715f..a2375d206b 100644 --- a/phpBB/phpbb/textformatter/renderer.php +++ b/phpBB/phpbb/textformatter/renderer.php @@ -26,8 +26,6 @@ abstract class renderer /** * Automatically set the smilies path based on config * - * Called by the service container - * * @param phpbb\config\config $config * @param phpbb\path_helper $path_helper * @return null @@ -46,7 +44,6 @@ abstract class renderer * Configure this renderer as per the user's settings * * Should set the locale as well as the viewcensor/viewflash/viewimg/viewsmilies options. - * Called by the service container * * @param phpbb\user $user * @param phpbb\config\config $config -- cgit v1.2.1 From 458cf95b1e0614b8dbecaca36c57f21e8a3a7bb7 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 00:58:38 +0100 Subject: [ticket/11768] Replaced class names in annotations with their FQN PHPBB3-11768 --- phpBB/phpbb/textformatter/renderer.php | 10 +++++----- phpBB/phpbb/textformatter/s9e/factory.php | 6 +++--- phpBB/phpbb/textformatter/s9e/parser.php | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/renderer.php b/phpBB/phpbb/textformatter/renderer.php index a2375d206b..d3594bb4ae 100644 --- a/phpBB/phpbb/textformatter/renderer.php +++ b/phpBB/phpbb/textformatter/renderer.php @@ -26,8 +26,8 @@ abstract class renderer /** * Automatically set the smilies path based on config * - * @param phpbb\config\config $config - * @param phpbb\path_helper $path_helper + * @param \phpbb\config\config $config + * @param \phpbb\path_helper $path_helper * @return null */ public function configure_smilies_path(\phpbb\config\config $config, \phpbb\path_helper $path_helper) @@ -45,9 +45,9 @@ abstract class renderer * * Should set the locale as well as the viewcensor/viewflash/viewimg/viewsmilies options. * - * @param phpbb\user $user - * @param phpbb\config\config $config - * @param phpbb\auth\auth $auth + * @param \phpbb\user $user + * @param \phpbb\config\config $config + * @param \phpbb\auth\auth $auth * @return null */ public function configure_user(\phpbb\user $user, \phpbb\config\config $config, \phpbb\auth\auth $auth) diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index ce9d34e247..ebed2521b2 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -22,7 +22,7 @@ use s9e\TextFormatter\Configurator\Items\AttributeFilters\Regexp as RegexpFilter class factory implements \phpbb\textformatter\cache { /** - * @var phpbb_cache_driver_interface $cache + * @var \phpbb\cache\driver_interface $cache */ protected $cache; @@ -102,8 +102,8 @@ class factory implements \phpbb\textformatter\cache /** * Constructor * - * @param phpbb\textformatter\data_access $dal - * @param phpbb\cache\driver\driver_interface $cache + * @param \phpbb\textformatter\data_access $dal + * @param \phpbb\cache\driver\driver_interface $cache * @param string $cache_dir Path to the cache dir * @param string $cache_key_parser Cache key used for the parser * @param string $cache_key_renderer Cache key used for the renderer diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index de51929994..4362a7870e 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -34,9 +34,9 @@ class parser implements \phpbb\textformatter\parser /** * Constructor * - * @param phpbb\cache\driver_interface $cache + * @param \phpbb\cache\driver_interface $cache * @param string $key Cache key - * @param phpbb\user $user + * @param \phpbb\user $user * @param factory $factory * @return null */ -- cgit v1.2.1 From 70b7e57497e8822dc237268c54d859125cdea4d0 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 00:59:44 +0100 Subject: [ticket/11768] Renamed property PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index ebed2521b2..a0817a9a4f 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -57,7 +57,7 @@ class factory implements \phpbb\textformatter\cache /** * @var \phpbb\textformatter\data_access */ - protected $dal; + protected $data_access; /** * @var array Default BBCode definitions @@ -102,21 +102,21 @@ class factory implements \phpbb\textformatter\cache /** * Constructor * - * @param \phpbb\textformatter\data_access $dal + * @param \phpbb\textformatter\data_access $data_access * @param \phpbb\cache\driver\driver_interface $cache * @param string $cache_dir Path to the cache dir * @param string $cache_key_parser Cache key used for the parser * @param string $cache_key_renderer Cache key used for the renderer * @return null */ - public function __construct(\phpbb\textformatter\data_access $dal, \phpbb\cache\driver\driver_interface $cache, $cache_dir, $cache_key_parser, $cache_key_renderer) + public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, $cache_dir, $cache_key_parser, $cache_key_renderer) { $this->cache = $cache; $this->cache_dir = $cache_dir; $this->cache_key_parser = $cache_key_parser; $this->cache_key_renderer = $cache_key_renderer; - $this->dal = $dal; + $this->data_access = $data_access; } /** @@ -222,7 +222,7 @@ class factory implements \phpbb\textformatter\cache } // Load custom BBCodes - foreach ($this->dal->get_bbcodes() as $row) + foreach ($this->data_access->get_bbcodes() as $row) { // Insert the board's URL before {LOCAL_URL} tokens $tpl = preg_replace_callback( @@ -247,7 +247,7 @@ class factory implements \phpbb\textformatter\cache } // Load smilies - foreach ($this->dal->get_smilies() as $row) + foreach ($this->data_access->get_smilies() as $row) { $configurator->Emoticons->add( $row['code'], @@ -266,7 +266,7 @@ class factory implements \phpbb\textformatter\cache } // Load the censored words - $censor = $this->dal->get_censored_words(); + $censor = $this->data_access->get_censored_words(); if (!empty($censor)) { // Use a namespaced tag to avoid collisions @@ -339,7 +339,7 @@ class factory implements \phpbb\textformatter\cache { // For each BBCode, build an associative array matching style_ids to their template $templates = array(); - foreach ($this->dal->get_styles_templates() as $style_id => $data) + foreach ($this->data_access->get_styles_templates() as $style_id => $data) { foreach ($this->extract_templates($data['template']) as $bbcode_name => $template) { -- cgit v1.2.1 From 6cb3fb614022fe4e56a6651ffad4f476056ae520 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 01:44:48 +0100 Subject: [ticket/11768] Replaced FQNs in annotations PHPBB3-11768 --- phpBB/phpbb/textformatter/data_access.php | 2 +- phpBB/phpbb/textformatter/s9e/parser.php | 4 ++-- phpBB/phpbb/textformatter/s9e/renderer.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/data_access.php b/phpBB/phpbb/textformatter/data_access.php index 008e1fd5c0..bc33791e15 100644 --- a/phpBB/phpbb/textformatter/data_access.php +++ b/phpBB/phpbb/textformatter/data_access.php @@ -27,7 +27,7 @@ class data_access protected $bbcodes_table; /** - * @var phpbb_db_driver + * @var \phpbb_db_driver */ protected $db; diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 4362a7870e..bf0e715ada 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -22,12 +22,12 @@ use s9e\TextFormatter\Parser\Logger; class parser implements \phpbb\textformatter\parser { /** - * @var s9e\TextFormatter\Parser + * @var \s9e\TextFormatter\Parser */ protected $parser; /** - * @var phpbb\user User object, used for translating errors + * @var \phpbb\user User object, used for translating errors */ protected $user; diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index ab0b032eb4..7b2fef5f4b 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -19,12 +19,12 @@ namespace phpbb\textformatter\s9e; class renderer extends \phpbb\textformatter\renderer { /** - * @var s9e\TextFormatter\Plugins\Censor\Helper + * @var \s9e\TextFormatter\Plugins\Censor\Helper */ protected $censor; /** - * @var s9e\TextFormatter\Renderer + * @var \s9e\TextFormatter\Renderer */ protected $renderer; -- cgit v1.2.1 From d37f2d10f02b6a7a2b12e4b21284df310f39d3e6 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 02:14:09 +0100 Subject: [ticket/11768] Removed the cached renderer We don't need to cache an instance of the renderer, we can just instantiate it every time we need one. PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 9 ++------- phpBB/phpbb/textformatter/s9e/renderer.php | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index a0817a9a4f..a7cf2d89b8 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -314,13 +314,8 @@ class factory implements \phpbb\textformatter\cache // Cache the parser as-is $this->cache->put($this->cache_key_parser, $parser); - // We need to cache the name of the renderer's generated class so that we can load the class - // before the renderer is unserialized. That's why we save them together, with the renderer - // in serialized form - $renderer_data = array( - 'class' => get_class($renderer), - 'renderer' => serialize($renderer) - ); + // We need to cache the name of the renderer's generated class + $renderer_data = array('class' => get_class($renderer)); if (isset($censor)) { $renderer_data['censor'] = $censor; diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 7b2fef5f4b..71c207e6fc 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -77,7 +77,7 @@ class renderer extends \phpbb\textformatter\renderer if (class_exists($class, false)) { - $renderer = unserialize($renderer_data['renderer']); + $renderer = new $class; } if (isset($renderer_data['censor'])) -- cgit v1.2.1 From 40340004aac7ac1752c90a1dbca1faa486e668b9 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 02:52:40 +0100 Subject: [ticket/11768] Replaced some references PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index a7cf2d89b8..66dba14ac0 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -354,20 +354,18 @@ class factory implements \phpbb\textformatter\cache } // Replace custom tokens and normalize templates - foreach ($templates as $bbcode_name => &$style_templates) + foreach ($templates as $bbcode_name => $style_templates) { - foreach ($style_templates as &$template) + foreach ($style_templates as $i => $template) { if (isset($this->custom_tokens[$bbcode_name])) { $template = strtr($template, $this->custom_tokens[$bbcode_name]); } - $template = $configurator->templateNormalizer->normalizeTemplate($template); + $templates[$bbcode_name][$i] = $configurator->templateNormalizer->normalizeTemplate($template); } - unset($template); } - unset($style_templates); $bbcodes = array(); foreach ($this->default_definitions as $bbcode_name => $usage) -- cgit v1.2.1 From dc9a28d346370b38c10def92358170a5cef23b36 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 03:07:23 +0100 Subject: [ticket/11768] Replaced extract() calls PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 5 +++-- phpBB/phpbb/textformatter/s9e/parser.php | 3 ++- phpBB/phpbb/textformatter/s9e/renderer.php | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 66dba14ac0..a5b3527822 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -308,8 +308,9 @@ class factory implements \phpbb\textformatter\cache unset($configurator->tags['censor:tag']); } - // Create $parser and $renderer - extract($configurator->finalize()); + $objects = $configurator->finalize(); + $parser = $objects['parser']; + $renderer = $objects['renderer']; // Cache the parser as-is $this->cache->put($this->cache_key_parser, $parser); diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index bf0e715ada..be717bb1c9 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -47,7 +47,8 @@ class parser implements \phpbb\textformatter\parser $parser = $cache->get($key); if (!$parser) { - extract($factory->regenerate()); + $objects = $factory->regenerate(); + $parser = $objects['parser']; } $this->parser = $parser; diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 71c207e6fc..5468af450f 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -88,7 +88,8 @@ class renderer extends \phpbb\textformatter\renderer if (!isset($renderer)) { - extract($factory->regenerate()); + $objects = $factory->regenerate(); + $renderer = $objects['renderer']; } if (isset($censor)) -- cgit v1.2.1 From 78b544920c0d3984dd814cfe59f43c46feac6f12 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 3 Mar 2015 04:18:17 +0100 Subject: [ticket/11768] Added support for creating unsafe BBCodes PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index a5b3527822..9327da4b4f 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -15,6 +15,7 @@ namespace phpbb\textformatter\s9e; use s9e\TextFormatter\Configurator; use s9e\TextFormatter\Configurator\Items\AttributeFilters\Regexp as RegexpFilter; +use s9e\TextFormatter\Configurator\Items\UnsafeTemplate; /** * Creates s9e\TextFormatter objects @@ -236,7 +237,7 @@ class factory implements \phpbb\textformatter\cache try { - $configurator->BBCodes->addCustom($row['bbcode_match'], $tpl); + $configurator->BBCodes->addCustom($row['bbcode_match'], new UnsafeTemplate($tpl)); } catch (\Exception $e) { -- cgit v1.2.1 From 8411db62576a73beb921d58953bb5b767d4ee079 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 6 Mar 2015 10:21:15 +0100 Subject: [ticket/11768] Renamed interfaces PHPBB3-11768 --- phpBB/phpbb/textformatter/cache.php | 31 ------ phpBB/phpbb/textformatter/cache_interface.php | 31 ++++++ phpBB/phpbb/textformatter/data_access.php | 2 +- phpBB/phpbb/textformatter/parser.php | 111 ------------------- phpBB/phpbb/textformatter/parser_interface.php | 111 +++++++++++++++++++ phpBB/phpbb/textformatter/renderer.php | 129 ----------------------- phpBB/phpbb/textformatter/renderer_interface.php | 92 ++++++++++++++++ phpBB/phpbb/textformatter/s9e/factory.php | 2 +- phpBB/phpbb/textformatter/s9e/parser.php | 2 +- phpBB/phpbb/textformatter/s9e/renderer.php | 35 +++++- 10 files changed, 269 insertions(+), 277 deletions(-) delete mode 100644 phpBB/phpbb/textformatter/cache.php create mode 100644 phpBB/phpbb/textformatter/cache_interface.php delete mode 100644 phpBB/phpbb/textformatter/parser.php create mode 100644 phpBB/phpbb/textformatter/parser_interface.php delete mode 100644 phpBB/phpbb/textformatter/renderer.php create mode 100644 phpBB/phpbb/textformatter/renderer_interface.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/cache.php b/phpBB/phpbb/textformatter/cache.php deleted file mode 100644 index a2f7ff7d7b..0000000000 --- a/phpBB/phpbb/textformatter/cache.php +++ /dev/null @@ -1,31 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textformatter; - -/** -* Currently only used to signal that something that could effect the rendering has changed. -* BBCodes, smilies, censored words, templates, etc... -*/ -interface cache -{ - /** - * Invalidate and/or regenerate this text formatter's cache(s) - */ - public function invalidate(); - - /** - * Tidy/prune this text formatter's cache(s) - */ - public function tidy(); -} diff --git a/phpBB/phpbb/textformatter/cache_interface.php b/phpBB/phpbb/textformatter/cache_interface.php new file mode 100644 index 0000000000..f6b5f195c7 --- /dev/null +++ b/phpBB/phpbb/textformatter/cache_interface.php @@ -0,0 +1,31 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter; + +/** +* Currently only used to signal that something that could effect the rendering has changed. +* BBCodes, smilies, censored words, templates, etc... +*/ +interface cache_interface +{ + /** + * Invalidate and/or regenerate this text formatter's cache(s) + */ + public function invalidate(); + + /** + * Tidy/prune this text formatter's cache(s) + */ + public function tidy(); +} diff --git a/phpBB/phpbb/textformatter/data_access.php b/phpBB/phpbb/textformatter/data_access.php index bc33791e15..2dfba27960 100644 --- a/phpBB/phpbb/textformatter/data_access.php +++ b/phpBB/phpbb/textformatter/data_access.php @@ -27,7 +27,7 @@ class data_access protected $bbcodes_table; /** - * @var \phpbb_db_driver + * @var \phpbb_db_driver_interface */ protected $db; diff --git a/phpBB/phpbb/textformatter/parser.php b/phpBB/phpbb/textformatter/parser.php deleted file mode 100644 index 922226cf44..0000000000 --- a/phpBB/phpbb/textformatter/parser.php +++ /dev/null @@ -1,111 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textformatter; - -interface parser -{ - /** - * Parse given text - * - * @param string $text - * @return string - */ - public function parse($text); - - /** - * Disable a specific BBCode - * - * @param string $name BBCode name - * @return null - */ - public function disable_bbcode($name); - - /** - * Disable BBCodes in general - */ - public function disable_bbcodes(); - - /** - * Disable the censor - */ - public function disable_censor(); - - /** - * Disable magic URLs - */ - public function disable_magic_url(); - - /** - * Disable smilies - */ - public function disable_smilies(); - - /** - * Enable a specific BBCode - * - * @param string $name BBCode name - * @return null - */ - public function enable_bbcode($name); - - /** - * Enable BBCodes in general - */ - public function enable_bbcodes(); - - /** - * Enable the censor - */ - public function enable_censor(); - - /** - * Enable magic URLs - */ - public function enable_magic_url(); - - /** - * Enable smilies - */ - public function enable_smilies(); - - /** - * Get the list of errors that were generated during last parsing - * - * @return array - */ - public function get_errors(); - - /** - * Set a variable to be used by the parser - * - * - max_font_size - * - max_img_height - * - max_img_width - * - max_smilies - * - max_urls - * - * @param string $name - * @param mixed $value - * @return null - */ - public function set_var($name, $value); - - /** - * Set multiple variables to be used by the parser - * - * @param array Associative array of [name => value] - * @return null - */ - public function set_vars(array $vars); -} diff --git a/phpBB/phpbb/textformatter/parser_interface.php b/phpBB/phpbb/textformatter/parser_interface.php new file mode 100644 index 0000000000..37d538470d --- /dev/null +++ b/phpBB/phpbb/textformatter/parser_interface.php @@ -0,0 +1,111 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter; + +interface parser_interface +{ + /** + * Parse given text + * + * @param string $text + * @return string + */ + public function parse($text); + + /** + * Disable a specific BBCode + * + * @param string $name BBCode name + * @return null + */ + public function disable_bbcode($name); + + /** + * Disable BBCodes in general + */ + public function disable_bbcodes(); + + /** + * Disable the censor + */ + public function disable_censor(); + + /** + * Disable magic URLs + */ + public function disable_magic_url(); + + /** + * Disable smilies + */ + public function disable_smilies(); + + /** + * Enable a specific BBCode + * + * @param string $name BBCode name + * @return null + */ + public function enable_bbcode($name); + + /** + * Enable BBCodes in general + */ + public function enable_bbcodes(); + + /** + * Enable the censor + */ + public function enable_censor(); + + /** + * Enable magic URLs + */ + public function enable_magic_url(); + + /** + * Enable smilies + */ + public function enable_smilies(); + + /** + * Get the list of errors that were generated during last parsing + * + * @return array + */ + public function get_errors(); + + /** + * Set a variable to be used by the parser + * + * - max_font_size + * - max_img_height + * - max_img_width + * - max_smilies + * - max_urls + * + * @param string $name + * @param mixed $value + * @return null + */ + public function set_var($name, $value); + + /** + * Set multiple variables to be used by the parser + * + * @param array Associative array of [name => value] + * @return null + */ + public function set_vars(array $vars); +} diff --git a/phpBB/phpbb/textformatter/renderer.php b/phpBB/phpbb/textformatter/renderer.php deleted file mode 100644 index d3594bb4ae..0000000000 --- a/phpBB/phpbb/textformatter/renderer.php +++ /dev/null @@ -1,129 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textformatter; - -abstract class renderer -{ - /** - * Render given text - * - * @param string $text Text, as parsed by something that implements \phpbb\textformatter\parser - * @return string - */ - abstract public function render($text); - - /** - * Automatically set the smilies path based on config - * - * @param \phpbb\config\config $config - * @param \phpbb\path_helper $path_helper - * @return null - */ - public function configure_smilies_path(\phpbb\config\config $config, \phpbb\path_helper $path_helper) - { - /** - * @see smiley_text() - */ - $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $path_helper->get_web_root_path(); - - $this->set_smilies_path($root_path . $config['smilies_path']); - } - - /** - * Configure this renderer as per the user's settings - * - * Should set the locale as well as the viewcensor/viewflash/viewimg/viewsmilies options. - * - * @param \phpbb\user $user - * @param \phpbb\config\config $config - * @param \phpbb\auth\auth $auth - * @return null - */ - public function configure_user(\phpbb\user $user, \phpbb\config\config $config, \phpbb\auth\auth $auth) - { - $censor = $user->optionget('viewcensors') || !$config['allow_nocensors'] || !$auth->acl_get('u_chgcensors'); - - $this->set_viewcensors($censor); - $this->set_viewflash($user->optionget('viewflash')); - $this->set_viewimg($user->optionget('viewimg')); - $this->set_viewsmilies($user->optionget('viewsmilies')); - } - - /** - * Set the smilies' path - * - * @return null - */ - abstract public function set_smilies_path($path); - - /** - * Return the value of the "viewcensors" option - * - * @return bool Option's value - */ - abstract public function get_viewcensors(); - - /** - * Return the value of the "viewflash" option - * - * @return bool Option's value - */ - abstract public function get_viewflash(); - - /** - * Return the value of the "viewimg" option - * - * @return bool Option's value - */ - abstract public function get_viewimg(); - - /** - * Return the value of the "viewsmilies" option - * - * @return bool Option's value - */ - abstract public function get_viewsmilies(); - - /** - * Set the "viewcensors" option - * - * @param bool $value Option's value - * @return null - */ - abstract public function set_viewcensors($value); - - /** - * Set the "viewflash" option - * - * @param bool $value Option's value - * @return null - */ - abstract public function set_viewflash($value); - - /** - * Set the "viewimg" option - * - * @param bool $value Option's value - * @return null - */ - abstract public function set_viewimg($value); - - /** - * Set the "viewsmilies" option - * - * @param bool $value Option's value - * @return null - */ - abstract public function set_viewsmilies($value); -} diff --git a/phpBB/phpbb/textformatter/renderer_interface.php b/phpBB/phpbb/textformatter/renderer_interface.php new file mode 100644 index 0000000000..609b0bb642 --- /dev/null +++ b/phpBB/phpbb/textformatter/renderer_interface.php @@ -0,0 +1,92 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter; + +interface renderer_interface +{ + /** + * Render given text + * + * @param string $text Text, as parsed by something that implements \phpbb\textformatter\parser + * @return string + */ + public function render($text); + + /** + * Set the smilies' path + * + * @return null + */ + public function set_smilies_path($path); + + /** + * Return the value of the "viewcensors" option + * + * @return bool Option's value + */ + public function get_viewcensors(); + + /** + * Return the value of the "viewflash" option + * + * @return bool Option's value + */ + public function get_viewflash(); + + /** + * Return the value of the "viewimg" option + * + * @return bool Option's value + */ + public function get_viewimg(); + + /** + * Return the value of the "viewsmilies" option + * + * @return bool Option's value + */ + public function get_viewsmilies(); + + /** + * Set the "viewcensors" option + * + * @param bool $value Option's value + * @return null + */ + public function set_viewcensors($value); + + /** + * Set the "viewflash" option + * + * @param bool $value Option's value + * @return null + */ + public function set_viewflash($value); + + /** + * Set the "viewimg" option + * + * @param bool $value Option's value + * @return null + */ + public function set_viewimg($value); + + /** + * Set the "viewsmilies" option + * + * @param bool $value Option's value + * @return null + */ + public function set_viewsmilies($value); +} diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 9327da4b4f..aa37beeef6 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -20,7 +20,7 @@ use s9e\TextFormatter\Configurator\Items\UnsafeTemplate; /** * Creates s9e\TextFormatter objects */ -class factory implements \phpbb\textformatter\cache +class factory implements \phpbb\textformatter\cache_interface { /** * @var \phpbb\cache\driver_interface $cache diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index be717bb1c9..4775175f73 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -19,7 +19,7 @@ use s9e\TextFormatter\Parser\Logger; /** * s9e\TextFormatter\Parser adapter */ -class parser implements \phpbb\textformatter\parser +class parser implements \phpbb\textformatter\parser_interface { /** * @var \s9e\TextFormatter\Parser diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 5468af450f..0b3c63fb91 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -16,7 +16,7 @@ namespace phpbb\textformatter\s9e; /** * s9e\TextFormatter\Renderer adapter */ -class renderer extends \phpbb\textformatter\renderer +class renderer implements \phpbb\textformatter\renderer_interface { /** * @var \s9e\TextFormatter\Plugins\Censor\Helper @@ -101,11 +101,40 @@ class renderer extends \phpbb\textformatter\renderer } /** - * {@inheritdoc} + * Automatically set the smilies path based on config + * + * @param \phpbb\config\config $config + * @param \phpbb\path_helper $path_helper + * @return null + */ + public function configure_smilies_path(\phpbb\config\config $config, \phpbb\path_helper $path_helper) + { + /** + * @see smiley_text() + */ + $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $path_helper->get_web_root_path(); + + $this->set_smilies_path($root_path . $config['smilies_path']); + } + + /** + * Configure this renderer as per the user's settings + * + * Should set the locale as well as the viewcensor/viewflash/viewimg/viewsmilies options. + * + * @param \phpbb\user $user + * @param \phpbb\config\config $config + * @param \phpbb\auth\auth $auth + * @return null */ public function configure_user(\phpbb\user $user, \phpbb\config\config $config, \phpbb\auth\auth $auth) { - parent::configure_user($user, $config, $auth); + $censor = $user->optionget('viewcensors') || !$config['allow_nocensors'] || !$auth->acl_get('u_chgcensors'); + + $this->set_viewcensors($censor); + $this->set_viewflash($user->optionget('viewflash')); + $this->set_viewimg($user->optionget('viewimg')); + $this->set_viewsmilies($user->optionget('viewsmilies')); // Set the stylesheet parameters foreach (array_keys($this->renderer->getParameters()) as $param_name) -- cgit v1.2.1 From a611366bd398c02b47aa71b0fdaa9c16765d0f6b Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 6 Mar 2015 10:24:03 +0100 Subject: [ticket/11768] Whitespace [ci skip] PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/renderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 0b3c63fb91..42567098d9 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -129,7 +129,7 @@ class renderer implements \phpbb\textformatter\renderer_interface */ public function configure_user(\phpbb\user $user, \phpbb\config\config $config, \phpbb\auth\auth $auth) { - $censor = $user->optionget('viewcensors') || !$config['allow_nocensors'] || !$auth->acl_get('u_chgcensors'); + $censor = $user->optionget('viewcensors') || !$config['allow_nocensors'] || !$auth->acl_get('u_chgcensors'); $this->set_viewcensors($censor); $this->set_viewflash($user->optionget('viewflash')); -- cgit v1.2.1 From 44fc3d64dafdadd1959ab53dd7e0d1be67c75c1b Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 6 Mar 2015 10:46:59 +0100 Subject: [ticket/11768] Made capturing code blocks a bit more flexible PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/renderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 42567098d9..c896c9f1c7 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -209,7 +209,7 @@ class renderer implements \phpbb\textformatter\renderer_interface * @see bbcode::bbcode_second_pass_code() */ $html = preg_replace_callback( - '#()(.*?)()#is', + '#(]*>)(.*?)()#is', function ($captures) { $code = $captures[2]; -- cgit v1.2.1 From 20a1646fc6336635cee89426e3a60bb22cb138de Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 6 Mar 2015 10:50:05 +0100 Subject: [ticket/11768] Renamed utils PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/utils.php | 2 +- phpBB/phpbb/textformatter/utils.php | 58 --------------------------- phpBB/phpbb/textformatter/utils_interface.php | 58 +++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 59 deletions(-) delete mode 100644 phpBB/phpbb/textformatter/utils.php create mode 100644 phpBB/phpbb/textformatter/utils_interface.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index 57e836d2d4..df4ae4b9ec 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -16,7 +16,7 @@ namespace phpbb\textformatter\s9e; /** * Text manipulation utilities */ -class utils extends \phpbb\textformatter\utils +class utils implements \phpbb\textformatter\utils_interface { /** * {@inheritdoc} diff --git a/phpBB/phpbb/textformatter/utils.php b/phpBB/phpbb/textformatter/utils.php deleted file mode 100644 index 13942b9248..0000000000 --- a/phpBB/phpbb/textformatter/utils.php +++ /dev/null @@ -1,58 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textformatter; - -/** -* Used to manipulate a parsed text -*/ -abstract class utils -{ - /** - * Replace BBCodes and other formatting elements with whitespace - * - * NOTE: preserves smilies as text - * - * @param string $text - * @return string - */ - abstract public function clean_formatting($text); - - /** - * Remove given BBCode at given nesting depth - * - * @param string $text Parsed text - * @param string $bbcode_name BBCode's name - * @param integer $depth Minimum nesting depth (number of parents of the same name) - * @return string - */ - abstract public function remove_bbcode($text, $bbcode_name, $depth = 0); - - /** - * Remove BBCodes and other formatting from a parsed text - * - * NOTE: preserves smilies as text - * - * @param string $text - * @return string - */ - abstract public function remove_formatting($text); - - /** - * Return a parsed text to its original form - * - * @param string $text - * @return string - */ - abstract public function unparse($text); -} diff --git a/phpBB/phpbb/textformatter/utils_interface.php b/phpBB/phpbb/textformatter/utils_interface.php new file mode 100644 index 0000000000..45610f7ecb --- /dev/null +++ b/phpBB/phpbb/textformatter/utils_interface.php @@ -0,0 +1,58 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter; + +/** +* Used to manipulate a parsed text +*/ +interface utils_interface +{ + /** + * Replace BBCodes and other formatting elements with whitespace + * + * NOTE: preserves smilies as text + * + * @param string $text + * @return string + */ + public function clean_formatting($text); + + /** + * Remove given BBCode at given nesting depth + * + * @param string $text Parsed text + * @param string $bbcode_name BBCode's name + * @param integer $depth Minimum nesting depth (number of parents of the same name) + * @return string + */ + public function remove_bbcode($text, $bbcode_name, $depth = 0); + + /** + * Remove BBCodes and other formatting from a parsed text + * + * NOTE: preserves smilies as text + * + * @param string $text + * @return string + */ + public function remove_formatting($text); + + /** + * Return a parsed text to its original form + * + * @param string $text + * @return string + */ + public function unparse($text); +} -- cgit v1.2.1 From 89d87a99db403d7045406b869a92258e61122f67 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 6 Mar 2015 11:11:07 +0100 Subject: [ticket/11768] Replaced array access with call to $user->lang() PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/parser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 4775175f73..f3e437b163 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -184,7 +184,7 @@ class parser implements \phpbb\textformatter\parser_interface } else if ($msg === 'UNABLE_GET_IMAGE_SIZE') { - $errors[] = $this->user->lang[$msg]; + $errors[] = $this->user->lang($msg); } } -- cgit v1.2.1 From 40c54898ccd80744ba159784d631328e0338bad2 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 6 Mar 2015 13:08:18 +0100 Subject: [ticket/11768] Updated various annotations PHPBB3-11768 --- phpBB/phpbb/textformatter/data_access.php | 15 +++++++-------- phpBB/phpbb/textformatter/parser_interface.php | 2 +- phpBB/phpbb/textformatter/s9e/factory.php | 13 ++++++------- phpBB/phpbb/textformatter/s9e/parser.php | 11 +++++------ phpBB/phpbb/textformatter/s9e/renderer.php | 11 +++++------ 5 files changed, 24 insertions(+), 28 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/data_access.php b/phpBB/phpbb/textformatter/data_access.php index 2dfba27960..8938d66935 100644 --- a/phpBB/phpbb/textformatter/data_access.php +++ b/phpBB/phpbb/textformatter/data_access.php @@ -27,7 +27,7 @@ class data_access protected $bbcodes_table; /** - * @var \phpbb_db_driver_interface + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -54,13 +54,12 @@ class data_access /** * Constructor * - * @param \phpbb\db\driver\driver_interface $db Database connection - * @param string $bbcodes_table Name of the BBCodes table - * @param string $smilies_table Name of the smilies table - * @param string $styles_table Name of the styles table - * @param string $words_table Name of the words table - * @param string $styles_path Path to the styles dir - * @return null + * @param \phpbb\db\driver\driver_interface $db Database connection + * @param string $bbcodes_table Name of the BBCodes table + * @param string $smilies_table Name of the smilies table + * @param string $styles_table Name of the styles table + * @param string $words_table Name of the words table + * @param string $styles_path Path to the styles dir */ public function __construct(\phpbb\db\driver\driver_interface $db, $bbcodes_table, $smilies_table, $styles_table, $words_table, $styles_path) { diff --git a/phpBB/phpbb/textformatter/parser_interface.php b/phpBB/phpbb/textformatter/parser_interface.php index 37d538470d..3cb9f8e977 100644 --- a/phpBB/phpbb/textformatter/parser_interface.php +++ b/phpBB/phpbb/textformatter/parser_interface.php @@ -104,7 +104,7 @@ interface parser_interface /** * Set multiple variables to be used by the parser * - * @param array Associative array of [name => value] + * @param array $vars Associative array of [name => value] * @return null */ public function set_vars(array $vars); diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index aa37beeef6..f3df2ad7a5 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -23,7 +23,7 @@ use s9e\TextFormatter\Configurator\Items\UnsafeTemplate; class factory implements \phpbb\textformatter\cache_interface { /** - * @var \phpbb\cache\driver_interface $cache + * @var \phpbb\cache\driver\driver_interface */ protected $cache; @@ -103,12 +103,11 @@ class factory implements \phpbb\textformatter\cache_interface /** * Constructor * - * @param \phpbb\textformatter\data_access $data_access - * @param \phpbb\cache\driver\driver_interface $cache - * @param string $cache_dir Path to the cache dir - * @param string $cache_key_parser Cache key used for the parser - * @param string $cache_key_renderer Cache key used for the renderer - * @return null + * @param \phpbb\textformatter\data_access $data_access + * @param \phpbb\cache\driver\driver_interface $cache + * @param string $cache_dir Path to the cache dir + * @param string $cache_key_parser Cache key used for the parser + * @param string $cache_key_renderer Cache key used for the renderer */ public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, $cache_dir, $cache_key_parser, $cache_key_renderer) { diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index f3e437b163..2f4a03d4c2 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -34,11 +34,10 @@ class parser implements \phpbb\textformatter\parser_interface /** * Constructor * - * @param \phpbb\cache\driver_interface $cache - * @param string $key Cache key - * @param \phpbb\user $user - * @param factory $factory - * @return null + * @param \phpbb\cache\driver_interface $cache + * @param string $key Cache key + * @param \phpbb\user $user + * @param factory $factory */ public function __construct(\phpbb\cache\driver\driver_interface $cache, $key, \phpbb\user $user, factory $factory) { @@ -194,7 +193,7 @@ class parser implements \phpbb\textformatter\parser_interface /** * Return the instance of s9e\TextFormatter\Parser used by this object * - * @return s9e\TextFormatter\Parser + * @return \s9e\TextFormatter\Parser */ public function get_parser() { diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index c896c9f1c7..882a19b4ac 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -51,11 +51,10 @@ class renderer implements \phpbb\textformatter\renderer_interface /** * Constructor * - * @param \phpbb\cache\driver\driver_interface $cache - * @param string $cache_dir Path to the cache dir - * @param string $key Cache key - * @param factory $factory - * @return null + * @param \phpbb\cache\driver\driver_interface $cache + * @param string $cache_dir Path to the cache dir + * @param string $key Cache key + * @param factory $factory */ public function __construct(\phpbb\cache\driver\driver_interface $cache, $cache_dir, $key, factory $factory) { @@ -153,7 +152,7 @@ class renderer implements \phpbb\textformatter\renderer_interface /** * Return the instance of s9e\TextFormatter\Renderer used by this object * - * @return s9e\TextFormatter\Renderer + * @return \s9e\TextFormatter\Renderer */ public function get_renderer() { -- cgit v1.2.1 From b46bf9f02f8d1810bdb95d64603632b6fab06960 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 9 Mar 2015 12:07:10 +0100 Subject: [ticket/11768] Updated merge_templates(). No functional change intended PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index f3df2ad7a5..b053fd6468 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -480,7 +480,7 @@ class factory implements \phpbb\textformatter\cache_interface $grouped_templates = array(); foreach ($style_templates as $style_id => $style_template) { - $grouped_templates[$style_template][] = $style_id; + $grouped_templates[$style_template][] = '$STYLE_ID=' . $style_id; } if (count($grouped_templates) === 1) @@ -499,9 +499,9 @@ class factory implements \phpbb\textformatter\cache_interface // Build an xsl:choose switch $template = ''; - foreach ($grouped_templates as $style_template => $style_ids) + foreach ($grouped_templates as $style_template => $exprs) { - $template .= '' . $style_template . ''; + $template .= '' . $style_template . ''; } $template .= '' . $default_template . ''; -- cgit v1.2.1 From 4398da234ec75cb95ddab82a0fb8f3567790a60b Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 16 Mar 2015 03:03:02 +0100 Subject: [ticket/11768] Updated merge_templates(). No functional change intended PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index b053fd6468..01209d352a 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -471,11 +471,21 @@ class factory implements \phpbb\textformatter\cache_interface /** * Merge the templates from any number of styles into one BBCode template * + * When multiple templates are available for the same BBCode (because of multiple styles) we + * merge them into a single template that uses an xsl:choose construct that determines which + * style to use at rendering time. + * * @param array $style_templates Associative array matching style_ids to their template * @return string */ protected function merge_templates(array $style_templates) { + // Return the template as-is if there's only one style or all styles share the same template + if (count(array_unique($style_templates)) === 1) + { + return end($style_templates); + } + // Group identical templates together $grouped_templates = array(); foreach ($style_templates as $style_id => $style_template) @@ -483,11 +493,6 @@ class factory implements \phpbb\textformatter\cache_interface $grouped_templates[$style_template][] = '$STYLE_ID=' . $style_id; } - if (count($grouped_templates) === 1) - { - return $style_template; - } - // Sort templates by frequency descending $templates_cnt = array_map('sizeof', $grouped_templates); array_multisort($grouped_templates, $templates_cnt); -- cgit v1.2.1 From 49b9e8e4eafff93f25a99bf263982fe79b7f0549 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 19 Mar 2015 12:45:12 +0100 Subject: [ticket/11768] Added configurator events PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 01209d352a..4504a329af 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -100,23 +100,29 @@ class factory implements \phpbb\textformatter\cache_interface 'email' => '', ); + /** + * @var \phpbb\event\dispatcher_interface + */ + protected $dispatcher; + /** * Constructor * * @param \phpbb\textformatter\data_access $data_access * @param \phpbb\cache\driver\driver_interface $cache + * @param \phpbb\event\dispatcher_interface $dispatcher * @param string $cache_dir Path to the cache dir * @param string $cache_key_parser Cache key used for the parser * @param string $cache_key_renderer Cache key used for the renderer */ - public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, $cache_dir, $cache_key_parser, $cache_key_renderer) + public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, $cache_dir, $cache_key_parser, $cache_key_renderer) { $this->cache = $cache; $this->cache_dir = $cache_dir; $this->cache_key_parser = $cache_key_parser; $this->cache_key_renderer = $cache_key_renderer; - $this->data_access = $data_access; + $this->dispatcher = $dispatcher; } /** @@ -158,6 +164,16 @@ class factory implements \phpbb\textformatter\cache_interface // Create a new Configurator $configurator = new Configurator; + /** + * Modify the s9e\TextFormatter configurator before the default settings are set + * + * @event core.text_formatter_s9e_configure_before + * @var \s9e\TextFormatter\Configurator configurator Configurator instance + * @since 3.2.0-a1 + */ + $vars = array('configurator'); + extract($this->dispatcher->trigger_event('core.text_formatter_s9e_configure_before', compact($vars))); + // Convert newlines to br elements by default $configurator->rootRules->enableAutoLineBreaks(); @@ -288,6 +304,16 @@ class factory implements \phpbb\textformatter\cache_interface $configurator->registeredVars['max_img_height'] = 0; $configurator->registeredVars['max_img_width'] = 0; + /** + * Modify the s9e\TextFormatter configurator after the default settings are set + * + * @event core.text_formatter_s9e_configure_after + * @var \s9e\TextFormatter\Configurator configurator Configurator instance + * @since 3.2.0-a1 + */ + $vars = array('configurator'); + extract($this->dispatcher->trigger_event('core.text_formatter_s9e_configure_after', compact($vars))); + return $configurator; } -- cgit v1.2.1 From 69dae16ba79a82714b3fa24955c5cbc6e372a388 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sat, 21 Mar 2015 12:32:17 +0100 Subject: [ticket/11768] Preserve comments in custom BBCodes PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 4504a329af..bad9190973 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -180,6 +180,10 @@ class factory implements \phpbb\textformatter\cache_interface // Don't automatically ignore text in places where text is not allowed $configurator->rulesGenerator->remove('IgnoreTextIfDisallowed'); + // Don't remove comments and instead convert them to xsl:comment elements + $configurator->templateNormalizer->remove('RemoveComments'); + $configurator->templateNormalizer->add('TransposeComments'); + // Set the rendering engine and configure it to save to the cache dir $configurator->rendering->engine = 'PHP'; $configurator->rendering->engine->cacheDir = $this->cache_dir; -- cgit v1.2.1 From c165eaa37ccfa817c3ba1373255efc131f7be509 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 23 Mar 2015 12:34:22 +0100 Subject: [ticket/11768] Removed superfluous whitespace [ci skip] PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/renderer.php | 3 --- 1 file changed, 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 882a19b4ac..75de54d942 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -62,7 +62,6 @@ class renderer implements \phpbb\textformatter\renderer_interface if ($renderer_data) { $class = $renderer_data['class']; - if (!class_exists($class, false)) { // Try to load the renderer class from its cache file @@ -73,12 +72,10 @@ class renderer implements \phpbb\textformatter\renderer_interface include($cache_file); } } - if (class_exists($class, false)) { $renderer = new $class; } - if (isset($renderer_data['censor'])) { $censor = $renderer_data['censor']; -- cgit v1.2.1 From 37fedc656fbdeb36b098375201042eed4c7e7229 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 23 Mar 2015 21:34:49 +0100 Subject: [ticket/11768] Updated the text_formatter.s9e.utils service Made it use s9e\TextFormatter\Utils. Refactored some tests to make them more readable. PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/utils.php | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index df4ae4b9ec..29dcfcdf58 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -26,7 +26,7 @@ class utils implements \phpbb\textformatter\utils_interface // Insert a space before and then remove formatting $text = preg_replace('#<[es]>#', ' $0', $text); - return \s9e\TextFormatter\Unparser::removeFormatting($text); + return \s9e\TextFormatter\Utils::removeFormatting($text); } /** @@ -34,18 +34,7 @@ class utils implements \phpbb\textformatter\utils_interface */ public function remove_bbcode($text, $bbcode_name, $depth = 0) { - $dom = new \DOMDocument; - $dom->loadXML($text); - - $xpath = new \DOMXPath($dom); - $nodes = $xpath->query(str_repeat('//' . strtoupper($bbcode_name), 1 + $depth)); - - foreach ($nodes as $node) - { - $node->parentNode->removeChild($node); - } - - return $dom->saveXML($dom->documentElement); + return \s9e\TextFormatter\Utils::removeTag($text, strtoupper($bbcode_name), $depth); } /** @@ -53,7 +42,7 @@ class utils implements \phpbb\textformatter\utils_interface */ public function remove_formatting($text) { - return \s9e\TextFormatter\Unparser::removeFormatting($text); + return \s9e\TextFormatter\Utils::removeFormatting($text); } /** -- cgit v1.2.1 From 2a462bb7e43b848d0277bd27e14ca4d645230eeb Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Wed, 25 Mar 2015 01:13:31 +0100 Subject: [ticket/11768] Removed get_parser() / get_renderer() accessors There's no need to access the s9e\TextFormatter objects outside of events. PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/parser.php | 10 ---------- phpBB/phpbb/textformatter/s9e/renderer.php | 10 ---------- 2 files changed, 20 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 2f4a03d4c2..6fda94d7ba 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -190,16 +190,6 @@ class parser implements \phpbb\textformatter\parser_interface return array_unique($errors); } - /** - * Return the instance of s9e\TextFormatter\Parser used by this object - * - * @return \s9e\TextFormatter\Parser - */ - public function get_parser() - { - return $this->parser; - } - /** * {@inheritdoc} */ diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 75de54d942..b68c9dd9be 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -146,16 +146,6 @@ class renderer implements \phpbb\textformatter\renderer_interface $this->renderer->setParameter('STYLE_ID', $user->style['style_id']); } - /** - * Return the instance of s9e\TextFormatter\Renderer used by this object - * - * @return \s9e\TextFormatter\Renderer - */ - public function get_renderer() - { - return $this->renderer; - } - /** * {@inheritdoc} */ -- cgit v1.2.1 From a7a53d5a30d4736f8114721c0d7019d64d24cda2 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Wed, 25 Mar 2015 01:39:19 +0100 Subject: [ticket/11768] Added core.text_formatter_s9e_parser_setup event PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/parser.php | 33 ++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 6fda94d7ba..37900d3d7c 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -21,6 +21,11 @@ use s9e\TextFormatter\Parser\Logger; */ class parser implements \phpbb\textformatter\parser_interface { + /** + * @var \phpbb\event\dispatcher_interface + */ + protected $dispatcher; + /** * @var \s9e\TextFormatter\Parser */ @@ -38,19 +43,39 @@ class parser implements \phpbb\textformatter\parser_interface * @param string $key Cache key * @param \phpbb\user $user * @param factory $factory + * @param \phpbb\event\dispatcher_interface $dispatcher */ - public function __construct(\phpbb\cache\driver\driver_interface $cache, $key, \phpbb\user $user, factory $factory) + public function __construct(\phpbb\cache\driver\driver_interface $cache, $key, \phpbb\user $user, factory $factory, \phpbb\event\dispatcher_interface $dispatcher) { - $this->user = $user; - $parser = $cache->get($key); if (!$parser) { $objects = $factory->regenerate(); $parser = $objects['parser']; } - + $self = $this; + + /** + * Configure the parser service + * + * Can be used to: + * - toggle features according to the user's preferences, + * - toggle BBCodes according to the user's permissions, + * - register variables or custom parsers in the s9e\TextFormatter + * - configure the s9e\TextFormatter parser + * + * @event core.text_formatter_s9e_parser_setup + * @var \s9e\TextFormatter\Parser parser s9e\TextFormatter parser instance + * @var \phpbb\textformatter\s9e\parser self This parser service + * @var \phpbb\user user Current user + * @since 3.2.0-a1 + */ + $vars = array('parser', 'self', 'user'); + extract($dispatcher->trigger_event('core.text_formatter_s9e_parser_setup', compact($vars))); + + $this->dispatcher = $dispatcher; $this->parser = $parser; + $this->user = $user; } /** -- cgit v1.2.1 From af4f9b860f50a562a03f55efad1da7e0854bdfda Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 26 Mar 2015 04:39:36 +0100 Subject: [ticket/11768] Added core.text_formatter_s9e_renderer_setup event PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/renderer.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index b68c9dd9be..7b8b382074 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -23,6 +23,11 @@ class renderer implements \phpbb\textformatter\renderer_interface */ protected $censor; + /** + * @var \phpbb\event\dispatcher_interface + */ + protected $dispatcher; + /** * @var \s9e\TextFormatter\Renderer */ @@ -55,8 +60,9 @@ class renderer implements \phpbb\textformatter\renderer_interface * @param string $cache_dir Path to the cache dir * @param string $key Cache key * @param factory $factory + * @param \phpbb\event\dispatcher_interface $dispatcher */ - public function __construct(\phpbb\cache\driver\driver_interface $cache, $cache_dir, $key, factory $factory) + public function __construct(\phpbb\cache\driver\driver_interface $cache, $cache_dir, $key, factory $factory, \phpbb\event\dispatcher_interface $dispatcher) { $renderer_data = $cache->get($key); if ($renderer_data) @@ -81,18 +87,29 @@ class renderer implements \phpbb\textformatter\renderer_interface $censor = $renderer_data['censor']; } } - if (!isset($renderer)) { $objects = $factory->regenerate(); $renderer = $objects['renderer']; } + $self = $this; + + /** + * Configure the renderer service + * + * @event core.text_formatter_s9e_renderer_setup + * @var \s9e\TextFormatter\Renderer renderer s9e\TextFormatter renderer instance + * @var \phpbb\textformatter\s9e\renderer self This renderer service + * @since 3.2.0-a1 + */ + $vars = array('renderer', 'self'); + extract($dispatcher->trigger_event('core.text_formatter_s9e_renderer_setup', compact($vars))); if (isset($censor)) { $this->censor = $censor; } - + $this->dispatcher = $dispatcher; $this->renderer = $renderer; } -- cgit v1.2.1 From a04fca86ee4fec3cb615f358f3dc914564d9a9b1 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 26 Mar 2015 05:10:25 +0100 Subject: [ticket/11768] Added renderer events Added core.text_formatter_s9e_render_before and core.text_formatter_s9e_render_after PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/renderer.php | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 7b8b382074..484b067d47 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -198,15 +198,28 @@ class renderer implements \phpbb\textformatter\renderer_interface /** * {@inheritdoc} */ - public function render($text) + public function render($xml) { + $self = $this; + + /** + * Modify a parsed text before it is rendered + * + * @event core.text_formatter_s9e_render_before + * @var \phpbb\textformatter\s9e\renderer self This renderer service + * @var string xml The parsed text, in its XML form + * @since 3.2.0-a1 + */ + $vars = array('self', 'xml'); + extract($this->dispatcher->trigger_event('core.text_formatter_s9e_render_before', compact($vars))); + if (isset($this->censor) && $this->viewcensors) { // NOTE: censorHtml() is XML-safe - $text = $this->censor->censorHtml($text, true); + $xml = $this->censor->censorHtml($xml, true); } - $html = $this->renderer->render($text); + $html = $this->renderer->render($xml); /** * @see bbcode::bbcode_second_pass_code() @@ -239,6 +252,17 @@ class renderer implements \phpbb\textformatter\renderer_interface $html ); + /** + * Modify a rendered text + * + * @event core.text_formatter_s9e_render_after + * @var string html The renderer text's HTML + * @var \phpbb\textformatter\s9e\renderer self This renderer service + * @since 3.2.0-a1 + */ + $vars = array('html', 'self'); + extract($this->dispatcher->trigger_event('core.text_formatter_s9e_render_after', compact($vars))); + return $html; } -- cgit v1.2.1 From f75f63b264b2005faedb699dd867bd1d9c429a09 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 26 Mar 2015 05:20:23 +0100 Subject: [ticket/11768] Added parser events Added core.text_formatter_s9e_parse_before and core.text_formatter_s9e_parse_after PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/parser.php | 28 +++++++++++++++++++++++++++- phpBB/phpbb/textformatter/s9e/renderer.php | 2 +- 2 files changed, 28 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 37900d3d7c..f220dd3e64 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -83,7 +83,33 @@ class parser implements \phpbb\textformatter\parser_interface */ public function parse($text) { - return $this->parser->parse($text); + $self = $this; + + /** + * Modify a text before it is parsed + * + * @event core.text_formatter_s9e_parse_before + * @var \phpbb\textformatter\s9e\parser self This parser service + * @var string text The original text + * @since 3.2.0-a1 + */ + $vars = array('self', 'text'); + extract($this->dispatcher->trigger_event('core.text_formatter_s9e_parse_before', compact($vars))); + + $xml = $this->parser->parse($text); + + /** + * Modify a parsed text in its XML form + * + * @event core.text_formatter_s9e_parse_after + * @var \phpbb\textformatter\s9e\parser self This parser service + * @var string xml The parsed text, in XML + * @since 3.2.0-a1 + */ + $vars = array('self', 'xml'); + extract($this->dispatcher->trigger_event('core.text_formatter_s9e_parse_after', compact($vars))); + + return $xml; } /** diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 484b067d47..272cc5e6f3 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -256,7 +256,7 @@ class renderer implements \phpbb\textformatter\renderer_interface * Modify a rendered text * * @event core.text_formatter_s9e_render_after - * @var string html The renderer text's HTML + * @var string html The rendered text's HTML * @var \phpbb\textformatter\s9e\renderer self This renderer service * @since 3.2.0-a1 */ -- cgit v1.2.1 From 55c3fc02cfe1ce151bfb65c31ec72fc75f9d7872 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 26 Mar 2015 15:28:04 +0100 Subject: [ticket/11768] Updated utils service Updated docblocks. Removed remove_formatting() because it overlaps with clean_formatting() PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/utils.php | 41 +++++++++++++++------------ phpBB/phpbb/textformatter/utils_interface.php | 22 ++++---------- 2 files changed, 29 insertions(+), 34 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index 29dcfcdf58..2018bbf519 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -19,37 +19,42 @@ namespace phpbb\textformatter\s9e; class utils implements \phpbb\textformatter\utils_interface { /** - * {@inheritdoc} + * Replace BBCodes and other formatting elements with whitespace + * + * NOTE: preserves smilies as text + * + * @param string $xml Parsed text + * @return string Plain text */ - public function clean_formatting($text) + public function clean_formatting($xml) { // Insert a space before and then remove formatting - $text = preg_replace('#<[es]>#', ' $0', $text); + $xml = preg_replace('#<[es]>#', ' $0', $xml); - return \s9e\TextFormatter\Utils::removeFormatting($text); + return \s9e\TextFormatter\Utils::removeFormatting($xml); } /** - * {@inheritdoc} + * Remove given BBCode and its content, at given nesting depth + * + * @param string $xml Parsed text + * @param string $bbcode_name BBCode's name + * @param integer $depth Minimum nesting depth (number of parents of the same name) + * @return string Parsed text */ - public function remove_bbcode($text, $bbcode_name, $depth = 0) + public function remove_bbcode($xml, $bbcode_name, $depth = 0) { - return \s9e\TextFormatter\Utils::removeTag($text, strtoupper($bbcode_name), $depth); + return \s9e\TextFormatter\Utils::removeTag($xml, strtoupper($bbcode_name), $depth); } /** - * {@inheritdoc} + * Return a parsed text to its original form + * + * @param string $xml Parsed text + * @return string Original plain text */ - public function remove_formatting($text) + public function unparse($xml) { - return \s9e\TextFormatter\Utils::removeFormatting($text); - } - - /** - * {@inheritdoc} - */ - public function unparse($text) - { - return \s9e\TextFormatter\Unparser::unparse($text); + return \s9e\TextFormatter\Unparser::unparse($xml); } } diff --git a/phpBB/phpbb/textformatter/utils_interface.php b/phpBB/phpbb/textformatter/utils_interface.php index 45610f7ecb..132dc8ece4 100644 --- a/phpBB/phpbb/textformatter/utils_interface.php +++ b/phpBB/phpbb/textformatter/utils_interface.php @@ -23,36 +23,26 @@ interface utils_interface * * NOTE: preserves smilies as text * - * @param string $text - * @return string + * @param string $text Parsed text + * @return string Plain text */ public function clean_formatting($text); /** - * Remove given BBCode at given nesting depth + * Remove given BBCode and its content, at given nesting depth * * @param string $text Parsed text * @param string $bbcode_name BBCode's name * @param integer $depth Minimum nesting depth (number of parents of the same name) - * @return string + * @return string Parsed text */ public function remove_bbcode($text, $bbcode_name, $depth = 0); - /** - * Remove BBCodes and other formatting from a parsed text - * - * NOTE: preserves smilies as text - * - * @param string $text - * @return string - */ - public function remove_formatting($text); - /** * Return a parsed text to its original form * - * @param string $text - * @return string + * @param string $text Parsed text + * @return string Original plain text */ public function unparse($text); } -- cgit v1.2.1 From c1bc05a8605ef34c12f42d0ac14e45cca6fbace3 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 26 Mar 2015 17:07:58 +0100 Subject: [ticket/11768] Updated s9e\TextFormatter PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index bad9190973..9576abe1f0 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -14,7 +14,7 @@ namespace phpbb\textformatter\s9e; use s9e\TextFormatter\Configurator; -use s9e\TextFormatter\Configurator\Items\AttributeFilters\Regexp as RegexpFilter; +use s9e\TextFormatter\Configurator\Items\AttributeFilters\RegexpFilter; use s9e\TextFormatter\Configurator\Items\UnsafeTemplate; /** -- cgit v1.2.1 From 0f30301a0cf01c609cdcd5e4d777a47872a4dcba Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 26 Mar 2015 18:32:13 +0100 Subject: [ticket/11768] Moved parser/renderer setup events Moved down the setup events to make them happen after the service is configured and ready to be used PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/parser.php | 8 ++++---- phpBB/phpbb/textformatter/s9e/renderer.php | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index f220dd3e64..ab81a0ab4f 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -53,6 +53,10 @@ class parser implements \phpbb\textformatter\parser_interface $objects = $factory->regenerate(); $parser = $objects['parser']; } + + $this->dispatcher = $dispatcher; + $this->parser = $parser; + $this->user = $user; $self = $this; /** @@ -72,10 +76,6 @@ class parser implements \phpbb\textformatter\parser_interface */ $vars = array('parser', 'self', 'user'); extract($dispatcher->trigger_event('core.text_formatter_s9e_parser_setup', compact($vars))); - - $this->dispatcher = $dispatcher; - $this->parser = $parser; - $this->user = $user; } /** diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 272cc5e6f3..28498150b3 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -92,6 +92,13 @@ class renderer implements \phpbb\textformatter\renderer_interface $objects = $factory->regenerate(); $renderer = $objects['renderer']; } + + if (isset($censor)) + { + $this->censor = $censor; + } + $this->dispatcher = $dispatcher; + $this->renderer = $renderer; $self = $this; /** @@ -104,13 +111,6 @@ class renderer implements \phpbb\textformatter\renderer_interface */ $vars = array('renderer', 'self'); extract($dispatcher->trigger_event('core.text_formatter_s9e_renderer_setup', compact($vars))); - - if (isset($censor)) - { - $this->censor = $censor; - } - $this->dispatcher = $dispatcher; - $this->renderer = $renderer; } /** -- cgit v1.2.1 From 3e04e643df4ca5463450df5d94f3caca3e5596c0 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 27 Mar 2015 01:12:57 +0100 Subject: [ticket/11768] Restored get_parser() / get_renderer() PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/parser.php | 10 ++++++++++ phpBB/phpbb/textformatter/s9e/renderer.php | 10 ++++++++++ 2 files changed, 20 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index ab81a0ab4f..fb6ef03c1c 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -241,6 +241,16 @@ class parser implements \phpbb\textformatter\parser_interface return array_unique($errors); } + /** + * Return the instance of s9e\TextFormatter\Parser used by this object + * + * @return \s9e\TextFormatter\Parser + */ + public function get_parser() + { + return $this->parser; + } + /** * {@inheritdoc} */ diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 28498150b3..02461b3849 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -163,6 +163,16 @@ class renderer implements \phpbb\textformatter\renderer_interface $this->renderer->setParameter('STYLE_ID', $user->style['style_id']); } + /** + * Return the instance of s9e\TextFormatter\Renderer used by this object + * + * @return \s9e\TextFormatter\Renderer + */ + public function get_renderer() + { + return $this->renderer; + } + /** * {@inheritdoc} */ -- cgit v1.2.1 From d8e7e11ee3a5c49e80a4ec3e0bdf2011ba5e9ce7 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 27 Mar 2015 01:29:09 +0100 Subject: [ticket/11768] Renamed service vars The name of the variable that holds the service instance is now consistent across events. PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/parser.php | 17 ++++++++--------- phpBB/phpbb/textformatter/s9e/renderer.php | 17 ++++++++--------- 2 files changed, 16 insertions(+), 18 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index fb6ef03c1c..77328ee4d9 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -57,7 +57,7 @@ class parser implements \phpbb\textformatter\parser_interface $this->dispatcher = $dispatcher; $this->parser = $parser; $this->user = $user; - $self = $this; + $parser = $this; /** * Configure the parser service @@ -69,12 +69,11 @@ class parser implements \phpbb\textformatter\parser_interface * - configure the s9e\TextFormatter parser * * @event core.text_formatter_s9e_parser_setup - * @var \s9e\TextFormatter\Parser parser s9e\TextFormatter parser instance - * @var \phpbb\textformatter\s9e\parser self This parser service + * @var \phpbb\textformatter\s9e\parser parser This parser service * @var \phpbb\user user Current user * @since 3.2.0-a1 */ - $vars = array('parser', 'self', 'user'); + $vars = array('parser', 'user'); extract($dispatcher->trigger_event('core.text_formatter_s9e_parser_setup', compact($vars))); } @@ -83,17 +82,17 @@ class parser implements \phpbb\textformatter\parser_interface */ public function parse($text) { - $self = $this; + $parser = $this; /** * Modify a text before it is parsed * * @event core.text_formatter_s9e_parse_before - * @var \phpbb\textformatter\s9e\parser self This parser service + * @var \phpbb\textformatter\s9e\parser parser This parser service * @var string text The original text * @since 3.2.0-a1 */ - $vars = array('self', 'text'); + $vars = array('parser', 'text'); extract($this->dispatcher->trigger_event('core.text_formatter_s9e_parse_before', compact($vars))); $xml = $this->parser->parse($text); @@ -102,11 +101,11 @@ class parser implements \phpbb\textformatter\parser_interface * Modify a parsed text in its XML form * * @event core.text_formatter_s9e_parse_after - * @var \phpbb\textformatter\s9e\parser self This parser service + * @var \phpbb\textformatter\s9e\parser parser This parser service * @var string xml The parsed text, in XML * @since 3.2.0-a1 */ - $vars = array('self', 'xml'); + $vars = array('parser', 'xml'); extract($this->dispatcher->trigger_event('core.text_formatter_s9e_parse_after', compact($vars))); return $xml; diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 02461b3849..168b13e692 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -99,17 +99,16 @@ class renderer implements \phpbb\textformatter\renderer_interface } $this->dispatcher = $dispatcher; $this->renderer = $renderer; - $self = $this; + $renderer = $this; /** * Configure the renderer service * * @event core.text_formatter_s9e_renderer_setup - * @var \s9e\TextFormatter\Renderer renderer s9e\TextFormatter renderer instance - * @var \phpbb\textformatter\s9e\renderer self This renderer service + * @var \phpbb\textformatter\s9e\renderer renderer This renderer service * @since 3.2.0-a1 */ - $vars = array('renderer', 'self'); + $vars = array('renderer'); extract($dispatcher->trigger_event('core.text_formatter_s9e_renderer_setup', compact($vars))); } @@ -210,17 +209,17 @@ class renderer implements \phpbb\textformatter\renderer_interface */ public function render($xml) { - $self = $this; + $renderer = $this; /** * Modify a parsed text before it is rendered * * @event core.text_formatter_s9e_render_before - * @var \phpbb\textformatter\s9e\renderer self This renderer service + * @var \phpbb\textformatter\s9e\renderer renderer This renderer service * @var string xml The parsed text, in its XML form * @since 3.2.0-a1 */ - $vars = array('self', 'xml'); + $vars = array('renderer', 'xml'); extract($this->dispatcher->trigger_event('core.text_formatter_s9e_render_before', compact($vars))); if (isset($this->censor) && $this->viewcensors) @@ -267,10 +266,10 @@ class renderer implements \phpbb\textformatter\renderer_interface * * @event core.text_formatter_s9e_render_after * @var string html The rendered text's HTML - * @var \phpbb\textformatter\s9e\renderer self This renderer service + * @var \phpbb\textformatter\s9e\renderer renderer This renderer service * @since 3.2.0-a1 */ - $vars = array('html', 'self'); + $vars = array('html', 'renderer'); extract($this->dispatcher->trigger_event('core.text_formatter_s9e_render_after', compact($vars))); return $html; -- cgit v1.2.1 From 76088d64a69ac8fdd10b8a633e72eefc1e36321b Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 27 Mar 2015 01:52:26 +0100 Subject: [ticket/11768] Moved the routine that replaces tabs with spaces ...to its own method. Also added a quick stripos() check for performance. PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/renderer.php | 44 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 168b13e692..7c58cd3d03 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -229,12 +229,37 @@ class renderer implements \phpbb\textformatter\renderer_interface } $html = $this->renderer->render($xml); + if (stripos($html, 'replace_tabs_in_code($html); + } /** - * @see bbcode::bbcode_second_pass_code() + * Modify a rendered text + * + * @event core.text_formatter_s9e_render_after + * @var string html The rendered text's HTML + * @var \phpbb\textformatter\s9e\renderer renderer This renderer service + * @since 3.2.0-a1 */ - $html = preg_replace_callback( - '#(]*>)(.*?)()#is', + $vars = array('html', 'renderer'); + extract($this->dispatcher->trigger_event('core.text_formatter_s9e_render_after', compact($vars))); + + return $html; + } + + /** + * Replace tabs in code elements + * + * @see bbcode::bbcode_second_pass_code() + * + * @param string $html Original HTML + * @return string Modified HTML + */ + protected function replace_tabs_in_code($html) + { + return preg_replace_callback( + '((]*>)(.*?)())is', function ($captures) { $code = $captures[2]; @@ -260,19 +285,6 @@ class renderer implements \phpbb\textformatter\renderer_interface }, $html ); - - /** - * Modify a rendered text - * - * @event core.text_formatter_s9e_render_after - * @var string html The rendered text's HTML - * @var \phpbb\textformatter\s9e\renderer renderer This renderer service - * @since 3.2.0-a1 - */ - $vars = array('html', 'renderer'); - extract($this->dispatcher->trigger_event('core.text_formatter_s9e_render_after', compact($vars))); - - return $html; } /** -- cgit v1.2.1 From 1d90daf96963de3349cecc54d36ae421a24e0612 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 29 Mar 2015 23:00:29 +0200 Subject: [ticket/11768] Added some default template parameters PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/renderer.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 7c58cd3d03..7c69f37371 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -158,8 +158,13 @@ class renderer implements \phpbb\textformatter\renderer_interface } } - // Set the style id - $this->renderer->setParameter('STYLE_ID', $user->style['style_id']); + // Set this user's style id and other parameters + $this->renderer->setParameters(array( + 'S_IS_BOT' => $user->data['is_bot'], + 'S_REGISTERED_USER' => $user->data['is_registered'], + 'S_USER_LOGGED_IN' => ($user->data['user_id'] != ANONYMOUS), + 'STYLE_ID' => $user->style['style_id'], + )); } /** -- cgit v1.2.1 From b24e0f4f69b6436b3a654502d44d15333b0dfdc3 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 30 Mar 2015 03:31:38 +0200 Subject: [ticket/11768] Stylistic change. No functional change intended PHPBB3-11768 --- phpBB/phpbb/textformatter/s9e/renderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 7c69f37371..8999f1d25f 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -151,7 +151,7 @@ class renderer implements \phpbb\textformatter\renderer_interface // Set the stylesheet parameters foreach (array_keys($this->renderer->getParameters()) as $param_name) { - if (substr($param_name, 0, 2) === 'L_') + if (strpos($param_name, 'L_') === 0) { // L_FOO is set to $user->lang('FOO') $this->renderer->setParameter($param_name, $user->lang(substr($param_name, 2))); -- cgit v1.2.1 From a089ff5eb0dcdab83c6c2e64cb0e7cb618aec41f Mon Sep 17 00:00:00 2001 From: MateBartus Date: Wed, 25 Feb 2015 21:13:20 +0100 Subject: [ticket/13654] Moving reporting into controller Moving report.php's content into different services and controllers to better comply with the MVC model. Also implementing: * Replacement for reasons_display() * Adding assign_meta_refresh_var() to \controller\helper * Adding separate routes for easy configuration * Updating unit tests to expect to correct results * Add BC tests PHPBB3-13654 --- phpBB/phpbb/controller/helper.php | 14 + phpBB/phpbb/report/controller/report.php | 319 +++++++++++++++++++++ .../exception/already_reported_exception.php | 19 ++ .../report/exception/empty_report_exception.php | 22 ++ .../exception/entity_not_found_exception.php | 19 ++ .../factory_invalid_argument_exception.php | 21 ++ .../report/exception/invalid_report_exception.php | 21 ++ .../exception/pm_reporting_disabled_exception.php | 22 ++ .../report_permission_denied_exception.php | 19 ++ phpBB/phpbb/report/handler_factory.php | 56 ++++ phpBB/phpbb/report/report_handler.php | 104 +++++++ phpBB/phpbb/report/report_handler_interface.php | 43 +++ phpBB/phpbb/report/report_handler_pm.php | 137 +++++++++ phpBB/phpbb/report/report_handler_post.php | 175 +++++++++++ phpBB/phpbb/report/report_reason_list_provider.php | 78 +++++ 15 files changed, 1069 insertions(+) create mode 100644 phpBB/phpbb/report/controller/report.php create mode 100644 phpBB/phpbb/report/exception/already_reported_exception.php create mode 100644 phpBB/phpbb/report/exception/empty_report_exception.php create mode 100644 phpBB/phpbb/report/exception/entity_not_found_exception.php create mode 100644 phpBB/phpbb/report/exception/factory_invalid_argument_exception.php create mode 100644 phpBB/phpbb/report/exception/invalid_report_exception.php create mode 100644 phpBB/phpbb/report/exception/pm_reporting_disabled_exception.php create mode 100644 phpBB/phpbb/report/exception/report_permission_denied_exception.php create mode 100644 phpBB/phpbb/report/handler_factory.php create mode 100644 phpBB/phpbb/report/report_handler.php create mode 100644 phpBB/phpbb/report/report_handler_interface.php create mode 100644 phpBB/phpbb/report/report_handler_pm.php create mode 100644 phpBB/phpbb/report/report_handler_post.php create mode 100644 phpBB/phpbb/report/report_reason_list_provider.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index 340b29306a..74e6cb7034 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -223,6 +223,20 @@ class helper return $this->render('message_body.html', $this->user->lang($title), $code); } + /** + * Assigns automatic refresh time meta tag in template + * + * @param int $time time in seconds, when redirection should occur + * @param string $url the URL where the user should be redirected + * @return null + */ + public function assign_meta_refresh_var($time, $url) + { + $this->template->assign_vars(array( + 'META' => '', + )); + } + /** * Return the current url * diff --git a/phpBB/phpbb/report/controller/report.php b/phpBB/phpbb/report/controller/report.php new file mode 100644 index 0000000000..f703d1cc60 --- /dev/null +++ b/phpBB/phpbb/report/controller/report.php @@ -0,0 +1,319 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report\controller; + +use phpbb\exception\http_exception; +use Symfony\Component\HttpFoundation\RedirectResponse; + +class report +{ + /** + * @var \phpbb\config\db + */ + protected $config; + + /** + * @var \phpbb\user + */ + protected $user; + + /** + * @var \phpbb\template\template + */ + protected $template; + + /** + * @var \phpbb\controller\helper + */ + protected $helper; + + /** + * @var \phpbb\request\request_interface + */ + protected $request; + + /** + * @var \phpbb\captcha\factory + */ + protected $captcha_factory; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var string + */ + protected $php_ext; + + /** + * @var \phpbb\report\report_handler_interface + */ + protected $report_handler; + + /** + * @var \phpbb\report\report_reason_list_provider + */ + protected $report_reason_provider; + + public function __construct(\phpbb\config\db $config, \phpbb\user $user, \phpbb\template\template $template, \phpbb\controller\helper $helper, \phpbb\request\request_interface $request, \phpbb\captcha\factory $captcha_factory, \phpbb\report\handler_factory $report_factory, \phpbb\report\report_reason_list_provider $ui_provider, $phpbb_root_path, $php_ext) + { + $this->config = $config; + $this->user = $user; + $this->template = $template; + $this->helper = $helper; + $this->request = $request; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->captcha_factory = $captcha_factory; + $this->report_handler = $report_factory; + + // User interface factory + $this->report_reason_provider = $ui_provider; + } + + /** + * Controller for /path_to_entities/{id}/report routes + * + * Because of how phpBB organizes routes $mode must be set in the route config. + * + * @param int $id ID of the entity to report + * @param string $mode + * @return \Symfony\Component\HttpFoundation\Response a Symfony response object + * @throws \phpbb\exception\http_exception when $mode or $id is invalid for some reason + */ + public function handle($id, $mode) + { + // Get report handler + $this->report_handler = $this->report_handler->get_instance($mode); + + $this->user->add_lang('mcp'); + + $user_notify = ($this->user->data['is_registered']) ? $this->request->variable('notify', 0) : false; + $reason_id = $this->request->variable('reason_id', 0); + $report_text = $this->request->variable('report_text', '', true); + + $submit = $this->request->variable('submit', ''); + $cancel = $this->request->variable('cancel', ''); + + $error = array(); + $s_hidden_fields = ''; + + $redirect_url = append_sid( + $this->phpbb_root_path . ( ($mode === 'pm') ? 'ucp' : 'viewtopic' ) . ".{$this->php_ext}", + ($mode == 'pm') ? "i=pm&mode=view&p=$id" : "p=$id" + ); + $redirect_url .= ($mode === 'post') ? "#p$id" : ''; + + // Set up CAPTCHA if necessary + if ($this->config['enable_post_confirm'] && !$this->user->data['is_registered']) + { + $captcha = $this->captcha_factory->get_instance($this->config['captcha_plugin']); + $captcha->init(CONFIRM_REPORT); + } + + //Has the report been cancelled? + if (!empty($cancel)) + { + return new RedirectResponse($redirect_url, 302); + } + + // Check CAPTCHA, if the form was submited + if (!empty($submit) && isset($captcha)) + { + $captcha_template_array = $this->check_captcha($captcha); + $error = $captcha_template_array['error']; + $s_hidden_fields = $captcha_template_array['hidden_fields']; + } + + // Handle request + try + { + if (!empty($submit) && sizeof($error) === 0) + { + $this->report_handler->add_report( + (int) $id, + (int) $reason_id, + (string) $report_text, + (int) $user_notify + ); + + // Send success message + switch ($mode) + { + case 'pm': + $lang_return = $this->user->lang['RETURN_PM']; + $lang_success = $this->user->lang['PM_REPORTED_SUCCESS']; + break; + case 'post': + $lang_return = $this->user->lang['RETURN_TOPIC']; + $lang_success = $this->user->lang['POST_REPORTED_SUCCESS']; + break; + } + + $this->helper->assign_meta_refresh_var(3, $redirect_url); + $message = $lang_success . '

' . sprintf($lang_return, '', ''); + return $this->helper->message($message); + } + else + { + $this->report_handler->validate_report_request($id); + } + } + catch (\phpbb\report\exception\pm_reporting_disabled_exception $exception) + { + throw new http_exception(404, 'PAGE_NOT_FOUND'); + } + catch (\phpbb\report\exception\already_reported_exception $exception) + { + switch ($mode) + { + case 'pm': + $message = $this->user->lang['ALREADY_REPORTED_PM']; + $message .= '

' . sprintf($this->user->lang['RETURN_PM'], '', ''); + break; + case 'post': + $message = $this->user->lang['ALREADY_REPORTED']; + $message .= '

' . sprintf($this->user->lang['RETURN_TOPIC'], '', ''); + break; + } + + return $this->helper->message($message); + } + catch (\phpbb\report\exception\report_permission_denied_exception $exception) + { + $message = $exception->getMessage(); + if (isset($this->user->lang[$message])) + { + $message = $this->user->lang[$message]; + } + + throw new http_exception(403, $message); + } + catch (\phpbb\report\exception\entity_not_found_exception $exception) + { + $message = $exception->getMessage(); + if (isset($this->user->lang[$message])) + { + $message = $this->user->lang[$message]; + } + + throw new http_exception(404, $message); + } + catch (\phpbb\report\exception\empty_report_exception $exception) + { + $error[] = $this->user->lang['EMPTY_REPORT']; + } + catch (\phpbb\report\exception\invalid_report_exception $exception) + { + return $this->helper->message($exception->getMessage()); + } + + // Setting up an rendering template + $page_title = ($mode === 'pm') ? $this->user->lang['REPORT_MESSAGE'] : $this->user->lang['REPORT_POST']; + $this->assign_template_data( + $mode, + $id, + $reason_id, + $report_text, + $user_notify, + $error, + $s_hidden_fields, + ( isset($captcha) ? $captcha : false ) + ); + + return $this->helper->render('report_body.html', $page_title); + } + + /** + * Assigns template variables + * + * @param int $mode + * @param int $id + * @param int $reason_id + * @param string $report_text + * @param mixed $user_notify + * @param array $error + * @param string $s_hidden_fields + * @param mixed $captcha + * @return null + */ + protected function assign_template_data($mode, $id, $reason_id, $report_text, $user_notify, $error = array(), $s_hidden_fields = '', $captcha = false) + { + if ($captcha !== false && $captcha->is_solved() === false) + { + $this->template->assign_vars(array( + 'S_CONFIRM_CODE' => true, + 'CAPTCHA_TEMPLATE' => $captcha->get_template(), + )); + } + + $this->report_reason_provider->display_reasons($reason_id); + + switch ($mode) + { + case 'pm': + $report_route = $this->helper->route('phpbb_report_pm_controller', array('id' => $id)); + break; + case 'post': + $report_route = $this->helper->route('phpbb_report_post_controller', array('id' => $id)); + break; + } + + $this->template->assign_vars(array( + 'ERROR' => (sizeof($error) > 0) ? implode('
', $error) : '', + 'S_REPORT_POST' => ($mode === 'pm') ? false : true, + 'REPORT_TEXT' => $report_text, + 'S_HIDDEN_FIELDS' => (!empty($s_hidden_fields)) ? $s_hidden_fields : null, + 'S_REPORT_ACTION' => $report_route, + + 'S_NOTIFY' => $user_notify, + 'S_CAN_NOTIFY' => ($this->user->data['is_registered']) ? true : false, + 'S_IN_REPORT' => true, + )); + } + + /** + * Check CAPTCHA + * + * @param object $captcha A phpBB CAPTCHA object + * @return array template variables which ensures that CAPTCHA's work correctly + */ + protected function check_captcha($captcha) + { + $error = array(); + $captcha_hidden_fields = ''; + + $visual_confirmation_response = $captcha->validate(); + if ($visual_confirmation_response) + { + $error[] = $visual_confirmation_response; + } + + if (sizeof($error) === 0) + { + $captcha->reset(); + } + else if ($captcha->is_solved() !== false) + { + $captcha_hidden_fields = build_hidden_fields($captcha->get_hidden_fields()); + } + + return array( + 'error' => $error, + 'hidden_fields' => $captcha_hidden_fields, + ); + } +} diff --git a/phpBB/phpbb/report/exception/already_reported_exception.php b/phpBB/phpbb/report/exception/already_reported_exception.php new file mode 100644 index 0000000000..54174044fe --- /dev/null +++ b/phpBB/phpbb/report/exception/already_reported_exception.php @@ -0,0 +1,19 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report\exception; + +class already_reported_exception extends invalid_report_exception +{ + +} diff --git a/phpBB/phpbb/report/exception/empty_report_exception.php b/phpBB/phpbb/report/exception/empty_report_exception.php new file mode 100644 index 0000000000..8c968dca80 --- /dev/null +++ b/phpBB/phpbb/report/exception/empty_report_exception.php @@ -0,0 +1,22 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report\exception; + +class empty_report_exception extends invalid_report_exception +{ + public function __construct() + { + parent::__construct('EMPTY_REPORT'); + } +} diff --git a/phpBB/phpbb/report/exception/entity_not_found_exception.php b/phpBB/phpbb/report/exception/entity_not_found_exception.php new file mode 100644 index 0000000000..732aa58a13 --- /dev/null +++ b/phpBB/phpbb/report/exception/entity_not_found_exception.php @@ -0,0 +1,19 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report\exception; + +class entity_not_found_exception extends invalid_report_exception +{ + +} diff --git a/phpBB/phpbb/report/exception/factory_invalid_argument_exception.php b/phpBB/phpbb/report/exception/factory_invalid_argument_exception.php new file mode 100644 index 0000000000..19de91eea3 --- /dev/null +++ b/phpBB/phpbb/report/exception/factory_invalid_argument_exception.php @@ -0,0 +1,21 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report\exception; + +use \phpbb\exception\runtime_exception; + +class factory_invalid_argument_exception extends runtime_exception +{ + +} diff --git a/phpBB/phpbb/report/exception/invalid_report_exception.php b/phpBB/phpbb/report/exception/invalid_report_exception.php new file mode 100644 index 0000000000..03ff0a872d --- /dev/null +++ b/phpBB/phpbb/report/exception/invalid_report_exception.php @@ -0,0 +1,21 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report\exception; + +use \phpbb\exception\runtime_exception; + +class invalid_report_exception extends runtime_exception +{ + +} diff --git a/phpBB/phpbb/report/exception/pm_reporting_disabled_exception.php b/phpBB/phpbb/report/exception/pm_reporting_disabled_exception.php new file mode 100644 index 0000000000..2c8ab8cf84 --- /dev/null +++ b/phpBB/phpbb/report/exception/pm_reporting_disabled_exception.php @@ -0,0 +1,22 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report\exception; + +class pm_reporting_disabled_exception extends invalid_report_exception +{ + public function __construct() + { + + } +} diff --git a/phpBB/phpbb/report/exception/report_permission_denied_exception.php b/phpBB/phpbb/report/exception/report_permission_denied_exception.php new file mode 100644 index 0000000000..c7069288b8 --- /dev/null +++ b/phpBB/phpbb/report/exception/report_permission_denied_exception.php @@ -0,0 +1,19 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report\exception; + +class report_permission_denied_exception extends invalid_report_exception +{ + +} diff --git a/phpBB/phpbb/report/handler_factory.php b/phpBB/phpbb/report/handler_factory.php new file mode 100644 index 0000000000..ec229aac54 --- /dev/null +++ b/phpBB/phpbb/report/handler_factory.php @@ -0,0 +1,56 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report; + +use phpbb\report\exception\factory_invalid_argument_exception; + +class handler_factory +{ + /** + * @var \Symfony\Component\DependencyInjection\ContainerInterface + */ + protected $container; + + /** + * Constructor + * + * @param \Symfony\Component\DependencyInjection\ContainerInterface $container + */ + public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container) + { + $this->container = $container; + } + + /** + * Return a new instance of an appropriate report handler + * + * @param string $type + * @return \phpbb\report\report_handler_interface + * @throws \phpbb\report\exception\factory_invalid_argument_exception if $type is not valid + */ + public function get_instance($type) + { + switch ($type) + { + case 'pm': + return $this->container->get('phpbb.report.handlers.report_handler_pm'); + break; + case 'post': + return $this->container->get('phpbb.report.handlers.report_handler_post'); + break; + } + + throw new factory_invalid_argument_exception(); + } +} diff --git a/phpBB/phpbb/report/report_handler.php b/phpBB/phpbb/report/report_handler.php new file mode 100644 index 0000000000..126a206dbf --- /dev/null +++ b/phpBB/phpbb/report/report_handler.php @@ -0,0 +1,104 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report; + +abstract class report_handler implements report_handler_interface +{ + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var \phpbb\event\dispatcher_interface + */ + protected $dispatcher; + + /** + * @var \phpbb\config\db + */ + protected $config; + + /** + * @var \phpbb\auth\auth + */ + protected $auth; + + /** + * @var \phpbb\user + */ + protected $user; + + /** + * @var \phpbb\notification\manager + */ + protected $notifications; + + /** + * @var array + */ + protected $report_data; + + /** + * Construtor + * + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\event\dispatcher_interface $dispatcher + * @param \phpbb\config\db $config + * @param \phpbb\auth\auth $auth + * @param \phpbb\user $user + * @param \phpbb\notification\manager $notification + */ + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\db $config, \phpbb\auth\auth $auth, \phpbb\user $user, \phpbb\notification\manager $notification) + { + $this->db = $db; + $this->dispatcher = $dispatcher; + $this->config = $config; + $this->auth = $auth; + $this->user = $user; + $this->notifications = $notification; + $this->report_data = array(); + } + + /** + * Creates a report entity in the database + * + * @param array $report_data + * @return int the ID of the created entity + */ + protected function create_report(array $report_data) + { + $sql_ary = array( + 'reason_id' => (int) $report_data['reason_id'], + 'post_id' => $report_data['post_id'], + 'pm_id' => $report_data['pm_id'], + 'user_id' => (int) $this->user->data['user_id'], + 'user_notify' => (int) $report_data['user_notify'], + 'report_closed' => 0, + 'report_time' => (int) time(), + 'report_text' => (string) $report_data['report_text'], + 'reported_post_text' => $report_data['reported_post_text'], + 'reported_post_uid' => $report_data['reported_post_uid'], + 'reported_post_bitfield' => $report_data['reported_post_bitfield'], + 'reported_post_enable_bbcode' => $report_data['reported_post_enable_bbcode'], + 'reported_post_enable_smilies' => $report_data['reported_post_enable_smilies'], + 'reported_post_enable_magic_url' => $report_data['reported_post_enable_magic_url'], + ); + + $sql = 'INSERT INTO ' . REPORTS_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); + $this->db->sql_query($sql); + + return $this->db->sql_nextid(); + } +} diff --git a/phpBB/phpbb/report/report_handler_interface.php b/phpBB/phpbb/report/report_handler_interface.php new file mode 100644 index 0000000000..8dafc392d0 --- /dev/null +++ b/phpBB/phpbb/report/report_handler_interface.php @@ -0,0 +1,43 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report; + +interface report_handler_interface +{ + /** + * Reports a message + * + * @param int $id + * @param int $reason_id + * @param string $report_text + * @param int $user_notify + * @return null + * @throws \phpbb\report\exception\empty_report_exception when the given report is empty + * @throws \phpbb\report\exception\already_reported_exception when the entity is already reported + * @throws \phpbb\report\exception\entity_not_found_exception when the entity does not exist or the user does not have viewing permissions for it + * @throws \phpbb\report\exception\invalid_report_exception when the entity cannot be reported for some other reason + */ + public function add_report($id, $reason_id, $report_text, $user_notify); + + /** + * Checks if the message is reportable + * + * @param int $id + * @return null + * @throws \phpbb\report\exception\already_reported_exception when the entity is already reported + * @throws \phpbb\report\exception\entity_not_found_exception when the entity does not exist or the user does not have viewing permissions for it + * @throws \phpbb\report\exception\invalid_report_exception when the entity cannot be reported for some other reason + */ + public function validate_report_request($id); +} diff --git a/phpBB/phpbb/report/report_handler_pm.php b/phpBB/phpbb/report/report_handler_pm.php new file mode 100644 index 0000000000..2f2a697efc --- /dev/null +++ b/phpBB/phpbb/report/report_handler_pm.php @@ -0,0 +1,137 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report; + +use phpbb\report\exception\empty_report_exception; +use phpbb\report\exception\already_reported_exception; +use phpbb\report\exception\pm_reporting_disabled_exception; +use phpbb\report\exception\entity_not_found_exception; + +class report_handler_pm extends report_handler +{ + /** + * {@inheritdoc} + * @throws \phpbb\report\exception\pm_reporting_disabled_exception when PM reporting is disabled on the board + */ + public function add_report($id, $reason_id, $report_text, $user_notify) + { + // Cast the input variables + $id = (int) $id; + $reason_id = (int) $reason_id; + $report_text = (string) $report_text; + $user_notify = (int) $user_notify; + + $this->validate_report_request($id); + + $sql = 'SELECT * + FROM ' . REPORTS_REASONS_TABLE . " + WHERE reason_id = $reason_id"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row || (empty($report_text) && strtolower($row['reason_title']) === 'other')) + { + throw new empty_report_exception(); + } + + $report_data = array( + 'reason_id' => $reason_id, + 'post_id' => 0, + 'pm_id' => $id, + 'user_notify' => $user_notify, + 'report_text' => $report_text, + 'reported_post_text' => $this->report_data['message_text'], + 'reported_post_uid' => $this->report_data['bbcode_bitfield'], + 'reported_post_bitfield' => $this->report_data['bbcode_uid'], + 'reported_post_enable_bbcode' => $this->report_data['enable_bbcode'], + 'reported_post_enable_smilies' => $this->report_data['enable_smilies'], + 'reported_post_enable_magic_url' => $this->report_data['enable_magic_url'], + ); + + $report_id = $this->create_report($report_data); + + $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' + SET message_reported = 1 + WHERE msg_id = ' . $id; + $this->db->sql_query($sql); + + $sql_ary = array( + 'msg_id' => $id, + 'user_id' => ANONYMOUS, + 'author_id' => (int) $this->report_data['author_id'], + 'pm_deleted' => 0, + 'pm_new' => 0, + 'pm_unread' => 0, + 'pm_replied' => 0, + 'pm_marked' => 0, + 'pm_forwarded' => 0, + 'folder_id' => PRIVMSGS_INBOX, + ); + + $sql = 'INSERT INTO ' . PRIVMSGS_TO_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); + $this->db->sql_query($sql); + + $this->notifications->add_notifications('notification.type.report_pm', array_merge($this->report_data, $row, array( + 'report_text' => $report_text, + 'from_user_id' => $this->report_data['author_id'], + 'report_id' => $report_id, + ))); + } + + /** + * {@inheritdoc} + * @throws \phpbb\report\exception\pm_reporting_disabled_exception when PM reporting is disabled on the board + */ + public function validate_report_request($id) + { + $id = (int) $id; + + // Check if reporting PMs is enabled + if (!$this->config['allow_pm_report']) + { + throw new pm_reporting_disabled_exception(); + } + else if ($id <= 0) + { + throw new entity_not_found_exception('NO_POST_SELECTED'); + } + + // Grab all relevant data + $sql = 'SELECT p.*, pt.* + FROM ' . PRIVMSGS_TABLE . ' p, ' . PRIVMSGS_TO_TABLE . " pt + WHERE p.msg_id = $id + AND p.msg_id = pt.msg_id + AND (p.author_id = " . $this->user->data['user_id'] . " + OR pt.user_id = " . $this->user->data['user_id'] . ")"; + $result = $this->db->sql_query($sql); + $report_data = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + // Check if message exists + if (!$report_data) + { + $this->user->add_lang('ucp'); + throw new entity_not_found_exception('NO_MESSAGE'); + } + + // Check if message is already reported + if ($report_data['message_reported']) + { + throw new already_reported_exception(); + } + + $this->report_data = $report_data; + } +} diff --git a/phpBB/phpbb/report/report_handler_post.php b/phpBB/phpbb/report/report_handler_post.php new file mode 100644 index 0000000000..ce4ed67d27 --- /dev/null +++ b/phpBB/phpbb/report/report_handler_post.php @@ -0,0 +1,175 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report; + +use phpbb\report\exception\invalid_report_exception; +use phpbb\report\exception\empty_report_exception; +use phpbb\report\exception\already_reported_exception; +use phpbb\report\exception\entity_not_found_exception; +use phpbb\report\exception\report_permission_denied_exception; + +class report_handler_post extends report_handler +{ + /** + * @var array + */ + protected $forum_data; + + /** + * {@inheritdoc} + * @throws \phpbb\report\exception\report_permission_denied_exception when the user does not have permission to report the post + */ + public function add_report($id, $reason_id, $report_text, $user_notify) + { + // Cast the input variables + $id = (int) $id; + $reason_id = (int) $reason_id; + $report_text = (string) $report_text; + $user_notify = (int) $user_notify; + + $this->validate_report_request($id); + + $sql = 'SELECT * + FROM ' . REPORTS_REASONS_TABLE . " + WHERE reason_id = $reason_id"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row || (empty($report_text) && strtolower($row['reason_title']) === 'other')) + { + throw new empty_report_exception(); + } + + $report_data = array( + 'reason_id' => $reason_id, + 'post_id' => $id, + 'pm_id' => 0, + 'user_notify' => $user_notify, + 'report_text' => $report_text, + 'reported_post_text' => $this->report_data['post_text'], + 'reported_post_uid' => $this->report_data['bbcode_bitfield'], + 'reported_post_bitfield' => $this->report_data['bbcode_uid'], + 'reported_post_enable_bbcode' => $this->report_data['enable_bbcode'], + 'reported_post_enable_smilies' => $this->report_data['enable_smilies'], + 'reported_post_enable_magic_url' => $this->report_data['enable_magic_url'], + ); + + $report_id = $this->create_report($report_data); + + $sql = 'UPDATE ' . POSTS_TABLE . ' + SET post_reported = 1 + WHERE post_id = ' . $id; + $this->db->sql_query($sql); + + if (!$this->report_data['topic_reported']) + { + $sql = 'UPDATE ' . TOPICS_TABLE . ' + SET topic_reported = 1 + WHERE topic_id = ' . $this->report_data['topic_id'] . ' + OR topic_moved_id = ' . $this->report_data['topic_id']; + $this->db->sql_query($sql); + } + + $this->notifications->add_notifications('notification.type.report_post', array_merge($this->report_data, $row, $this->forum_data, array( + 'report_text' => $report_text, + ))); + } + + /** + * {@inheritdoc} + * @throws \phpbb\report\exception\report_permission_denied_exception when the user does not have permission to report the post + */ + public function validate_report_request($id) + { + $id = (int) $id; + + // Check if id is valid + if ($id <= 0) + { + throw new entity_not_found_exception('NO_POST_SELECTED'); + } + + // Grab all relevant data + $sql = 'SELECT t.*, p.* + FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t + WHERE p.post_id = $id + AND p.topic_id = t.topic_id"; + $result = $this->db->sql_query($sql); + $report_data = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$report_data) + { + throw new entity_not_found_exception('POST_NOT_EXIST'); + } + + $forum_id = (int) $report_data['forum_id']; + + $sql = 'SELECT * + FROM ' . FORUMS_TABLE . ' + WHERE forum_id = ' . $forum_id; + $result = $this->db->sql_query($sql); + $forum_data = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$forum_data) + { + throw new invalid_report_exception('FORUM_NOT_EXIST'); + } + + $acl_check_ary = array( + 'f_list' => 'POST_NOT_EXIST', + 'f_read' => 'USER_CANNOT_READ', + 'f_report' => 'USER_CANNOT_REPORT' + ); + + /** + * This event allows you to do extra auth checks and verify if the user + * has the required permissions + * + * @event core.report_post_auth + * @var array forum_data All data available from the forums table on this post's forum + * @var array report_data All data available from the topics and the posts tables on this post (and its topic) + * @var array acl_check_ary An array with the ACL to be tested. The evaluation is made in the same order as the array is sorted + * The key is the ACL name and the value is the language key for the error message. + * @since 3.1.3-RC1 + */ + $vars = array( + 'forum_data', + 'report_data', + 'acl_check_ary', + ); + extract($this->dispatcher->trigger_event('core.report_post_auth', compact($vars))); + + $this->auth->acl($this->user->data); + + foreach ($acl_check_ary as $acl => $error) + { + if (!$this->auth->acl_get($acl, $forum_id)) + { + throw new report_permission_denied_exception($error); + } + } + unset($acl_check_ary); + + if ($report_data['post_reported']) + { + throw new already_reported_exception(); + } + + $this->report_data = $report_data; + $this->forum_data = $forum_data; + } +} diff --git a/phpBB/phpbb/report/report_reason_list_provider.php b/phpBB/phpbb/report/report_reason_list_provider.php new file mode 100644 index 0000000000..388a61d577 --- /dev/null +++ b/phpBB/phpbb/report/report_reason_list_provider.php @@ -0,0 +1,78 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\report; + +class report_reason_list_provider +{ + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var \phpbb\template\template + */ + protected $template; + + /** + * @var \phpbb\user + */ + protected $user; + + /** + * Constructor + * + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\template\template $template + * @param \phpbb\user $user + */ + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\template\template $template, \phpbb\user $user) + { + $this->db = $db; + $this->template = $template; + $this->user = $user; + } + + /** + * Sets template variables to render report reasons select HTML input + * + * @param int $reason_id + * @return null + */ + public function display_reasons($reason_id = 0) + { + $sql = 'SELECT * + FROM ' . REPORTS_REASONS_TABLE . ' + ORDER BY reason_order ASC'; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + // If the reason is defined within the language file, we will use the localized version, else just use the database entry... + if (isset($this->user->lang['report_reasons']['TITLE'][strtoupper($row['reason_title'])]) && isset($this->user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])])) + { + $row['reason_description'] = $this->user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])]; + $row['reason_title'] = $this->user->lang['report_reasons']['TITLE'][strtoupper($row['reason_title'])]; + } + + $this->template->assign_block_vars('reason', array( + 'ID' => $row['reason_id'], + 'TITLE' => $row['reason_title'], + 'DESCRIPTION' => $row['reason_description'], + 'S_SELECTED' => ($row['reason_id'] == $reason_id) ? true : false, + )); + } + $this->db->sql_freeresult($result); + } +} -- cgit v1.2.1 From 4bdef6fd21a5dcab455b0cd1ee2652de606929c3 Mon Sep 17 00:00:00 2001 From: MateBartus Date: Thu, 12 Mar 2015 00:25:00 +0100 Subject: [ticket/13697] Moving filesystem related functions to filesystem service * Moving filesystem service to \phpbb\filesystem namespace * Wraping Symfony's Filesystem component * Moving filesystem related functions from includes/functions.php into \phpbb\filesystem\filesystem Functions moved (and deprecated): - phpbb_chmod - phpbb_is_writable - phpbb_is_absolute - phpbb_own_realpath - phpbb_realpath * Adding interface for filesystem service PHPBB3-13697 --- phpBB/phpbb/avatar/driver/upload.php | 15 +- phpBB/phpbb/cache/driver/base.php | 8 +- phpBB/phpbb/cache/driver/file.php | 25 +- phpBB/phpbb/console/command/db/migrate.php | 8 +- phpBB/phpbb/controller/helper.php | 6 +- .../db/log_wrapper_migrator_output_handler.php | 11 +- phpBB/phpbb/di/container_builder.php | 3 +- phpBB/phpbb/di/extension/core.php | 3 +- phpBB/phpbb/extension/di/extension_base.php | 3 +- phpBB/phpbb/extension/manager.php | 4 +- phpBB/phpbb/filesystem.php | 35 +- .../filesystem/exception/filesystem_exception.php | 42 + phpBB/phpbb/filesystem/filesystem.php | 916 +++++++++++++++++++++ phpBB/phpbb/filesystem/filesystem_interface.php | 284 +++++++ phpBB/phpbb/finder.php | 4 +- phpBB/phpbb/path_helper.php | 6 +- phpBB/phpbb/routing/router.php | 11 +- phpBB/phpbb/session.php | 4 +- phpBB/phpbb/template/twig/loader.php | 22 +- phpBB/phpbb/viewonline_helper.php | 6 +- 20 files changed, 1336 insertions(+), 80 deletions(-) create mode 100644 phpBB/phpbb/filesystem/exception/filesystem_exception.php create mode 100644 phpBB/phpbb/filesystem/filesystem.php create mode 100644 phpBB/phpbb/filesystem/filesystem_interface.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index 003b23659f..2ad84c087d 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -18,6 +18,11 @@ namespace phpbb\avatar\driver; */ class upload extends \phpbb\avatar\driver\driver { + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + /** * @var \phpbb\mimetype\guesser */ @@ -29,15 +34,17 @@ class upload extends \phpbb\avatar\driver\driver * @param \phpbb\config\config $config phpBB configuration * @param string $phpbb_root_path Path to the phpBB root * @param string $php_ext PHP file extension - * @param \phpbb_path_helper $path_helper phpBB path helper + * @param \phpbb\filesystem\filesystem_interface phpBB filesystem helper + * @param \phpbb\path_helper $path_helper phpBB path helper * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser * @param \phpbb\cache\driver\driver_interface $cache Cache driver */ - public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\cache\driver\driver_interface $cache = null) { $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; + $this->filesystem = $filesystem; $this->path_helper = $path_helper; $this->mimetype_guesser = $mimetype_guesser; $this->cache = $cache; @@ -88,7 +95,7 @@ class upload extends \phpbb\avatar\driver\driver include($this->phpbb_root_path . 'includes/functions_upload.' . $this->php_ext); } - $upload = new \fileupload('AVATAR_', $this->allowed_extensions, $this->config['avatar_filesize'], $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], (isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false)); + $upload = new \fileupload($this->filesystem, 'AVATAR_', $this->allowed_extensions, $this->config['avatar_filesize'], $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], (isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false)); $url = $request->variable('avatar_upload_url', ''); $upload_file = $request->file('avatar_upload_file'); @@ -209,6 +216,6 @@ class upload extends \phpbb\avatar\driver\driver */ protected function can_upload() { - return (file_exists($this->phpbb_root_path . $this->config['avatar_path']) && phpbb_is_writable($this->phpbb_root_path . $this->config['avatar_path']) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')); + return (file_exists($this->phpbb_root_path . $this->config['avatar_path']) && $this->filesystem->is_writable($this->phpbb_root_path . $this->config['avatar_path']) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')); } } diff --git a/phpBB/phpbb/cache/driver/base.php b/phpBB/phpbb/cache/driver/base.php index c83b928a12..55cd4668de 100644 --- a/phpBB/phpbb/cache/driver/base.php +++ b/phpBB/phpbb/cache/driver/base.php @@ -177,13 +177,9 @@ abstract class base implements \phpbb\cache\driver\driver_interface */ function remove_file($filename, $check = false) { - if (!function_exists('phpbb_is_writable')) - { - global $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/functions.' . $phpEx); - } + global $phpbb_filesystem; - if ($check && !phpbb_is_writable($this->cache_dir)) + if ($check && !$phpbb_filesystem->is_writable($this->cache_dir)) { // E_USER_ERROR - not using language entry - intended. trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR); diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index 32086458ee..bb055d3acf 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -20,6 +20,11 @@ class file extends \phpbb\cache\driver\base { var $var_expires = array(); + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + /** * Set cache path * @@ -30,6 +35,7 @@ class file extends \phpbb\cache\driver\base global $phpbb_root_path, $phpbb_container; $this->cache_dir = !is_null($cache_dir) ? $cache_dir : $phpbb_root_path . 'cache/' . $phpbb_container->getParameter('core.environment') . '/'; + $this->filesystem = new \phpbb\filesystem\filesystem(); if (!is_dir($this->cache_dir)) { @@ -69,14 +75,8 @@ class file extends \phpbb\cache\driver\base if (!$this->_write('data_global')) { - if (!function_exists('phpbb_is_writable')) - { - global $phpbb_root_path; - include($phpbb_root_path . 'includes/functions.' . $phpEx); - } - // Now, this occurred how often? ... phew, just tell the user then... - if (!phpbb_is_writable($this->cache_dir)) + if (!$this->filesystem->is_writable($this->cache_dir)) { // We need to use die() here, because else we may encounter an infinite loop (the message handler calls $cache->unload()) die('Fatal: ' . $this->cache_dir . ' is NOT writable.'); @@ -574,13 +574,14 @@ class file extends \phpbb\cache\driver\base fclose($handle); - if (!function_exists('phpbb_chmod')) + try { - global $phpbb_root_path; - include($phpbb_root_path . 'includes/functions.' . $phpEx); + $this->filesystem->phpbb_chmod($file, CHMOD_READ | CHMOD_WRITE); + } + catch (\phpbb\filesystem\exception\filesystem_exception $e) + { + // Do nothing } - - phpbb_chmod($file, CHMOD_READ | CHMOD_WRITE); $return_value = true; } diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php index 87c2a057d1..2490bf1310 100644 --- a/phpBB/phpbb/console/command/db/migrate.php +++ b/phpBB/phpbb/console/command/db/migrate.php @@ -35,13 +35,17 @@ class migrate extends \phpbb\console\command\command /** @var string phpBB root path */ protected $phpbb_root_path; - function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, $phpbb_root_path) + /** @var \phpbb\filesystem\filesystem_interface */ + protected $filesystem; + + function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) { $this->migrator = $migrator; $this->extension_manager = $extension_manager; $this->config = $config; $this->cache = $cache; $this->log = $log; + $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; parent::__construct($user); $this->user->add_lang(array('common', 'install', 'migrator')); @@ -57,7 +61,7 @@ class migrate extends \phpbb\console\command\command protected function execute(InputInterface $input, OutputInterface $output) { - $this->migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($this->user, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log')); + $this->migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($this->user, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem)); $this->migrator->create_migrations_table(); diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index 2790ea4277..1e1cf5e4e8 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -53,7 +53,7 @@ class helper protected $request; /** - * @var \phpbb\filesystem The filesystem object + * @var \phpbb\filesystem\filesystem_interface The filesystem object */ protected $filesystem; @@ -78,11 +78,11 @@ class helper * @param \phpbb\routing\router $router phpBB router * @param \phpbb\symfony_request $symfony_request Symfony Request object * @param \phpbb\request\request_interface $request phpBB request object - * @param \phpbb\filesystem $filesystem The filesystem object + * @param \phpbb\filesystem\filesystem_interface $filesystem The filesystem object * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP file extension */ - public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\routing\router $router, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\routing\router $router, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path, $php_ext) { $this->template = $template; $this->user = $user; diff --git a/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php b/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php index 94c293dc45..4c85bf4d67 100644 --- a/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php +++ b/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php @@ -37,17 +37,24 @@ class log_wrapper_migrator_output_handler implements migrator_output_handler_int */ protected $file_handle = false; + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + /** * Constructor * * @param user $user User object * @param migrator_output_handler_interface $migrator Migrator output handler * @param string $log_file File to log to + * @param \phpbb\filesystem\filesystem_interface phpBB filesystem object */ - public function __construct(user $user, migrator_output_handler_interface $migrator, $log_file) + public function __construct(user $user, migrator_output_handler_interface $migrator, $log_file, \phpbb\filesystem\filesystem_interface $filesystem) { $this->user = $user; $this->migrator = $migrator; + $this->filesystem = $filesystem; $this->file_open($log_file); } @@ -58,7 +65,7 @@ class log_wrapper_migrator_output_handler implements migrator_output_handler_int */ protected function file_open($file) { - if (phpbb_is_writable(dirname($file))) + if ($this->filesystem->is_writable(dirname($file))) { $this->file_handle = fopen($file, 'w'); } diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 125ae28e9b..2a410db9bd 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -192,7 +192,8 @@ class container_builder } } - $loader = new YamlFileLoader($this->container, new FileLocator(phpbb_realpath($this->get_config_path()))); + $filesystem = new \phpbb\filesystem\filesystem(); + $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path()))); $loader->load($this->container->getParameter('core.environment') . '/config.yml'); $this->inject_custom_parameters(); diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 451efc8e35..c71dc61280 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -50,7 +50,8 @@ class core extends Extension */ public function load(array $configs, ContainerBuilder $container) { - $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($this->config_path))); + $filesystem = new \phpbb\filesystem\filesystem(); + $loader = new YamlFileLoader($container, new FileLocator($filesystem->realpath($this->config_path))); $loader->load($container->getParameter('core.environment') . '/container/environment.yml'); $config = $this->getConfiguration($configs, $container); diff --git a/phpBB/phpbb/extension/di/extension_base.php b/phpBB/phpbb/extension/di/extension_base.php index 30cc37dbb6..ba74615e70 100644 --- a/phpBB/phpbb/extension/di/extension_base.php +++ b/phpBB/phpbb/extension/di/extension_base.php @@ -94,7 +94,8 @@ class extension_base extends Extension if ($services_directory && $services_file) { - $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($services_directory))); + $filesystem = new \phpbb\filesystem\filesystem(); + $loader = new YamlFileLoader($container, new FileLocator($filesystem->realpath($services_directory))); $loader->load($services_file); } } diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 880973d5fb..40fda74065 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -39,7 +39,7 @@ class manager * @param ContainerInterface $container A container * @param \phpbb\db\driver\driver_interface $db A database connection * @param \phpbb\config\config $config Config object - * @param \phpbb\filesystem $filesystem + * @param \phpbb\filesystem\filesystem_interface $filesystem * @param \phpbb\user $user User object * @param string $extension_table The name of the table holding extensions * @param string $phpbb_root_path Path to the phpbb includes directory. @@ -47,7 +47,7 @@ class manager * @param \phpbb\cache\driver\driver_interface $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem $filesystem, \phpbb\user $user, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\user $user, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') { $this->cache = $cache; $this->cache_name = $cache_name; diff --git a/phpBB/phpbb/filesystem.php b/phpBB/phpbb/filesystem.php index 77517082e5..af56d78845 100644 --- a/phpBB/phpbb/filesystem.php +++ b/phpBB/phpbb/filesystem.php @@ -14,37 +14,8 @@ namespace phpbb; /** -* A class with various functions that are related to paths, files and the filesystem -*/ -class filesystem + * @deprecated 3.2.0-dev (To be removed 3.3.0) use \phpbb\filesystem\filesystem instead + */ +class filesystem extends \phpbb\filesystem\filesystem { - /** - * Eliminates useless . and .. components from specified path. - * - * @param string $path Path to clean - * @return string Cleaned path - */ - public function clean_path($path) - { - $exploded = explode('/', $path); - $filtered = array(); - foreach ($exploded as $part) - { - if ($part === '.' && !empty($filtered)) - { - continue; - } - - if ($part === '..' && !empty($filtered) && $filtered[sizeof($filtered) - 1] !== '.' && $filtered[sizeof($filtered) - 1] !== '..') - { - array_pop($filtered); - } - else - { - $filtered[] = $part; - } - } - $path = implode('/', $filtered); - return $path; - } } diff --git a/phpBB/phpbb/filesystem/exception/filesystem_exception.php b/phpBB/phpbb/filesystem/exception/filesystem_exception.php new file mode 100644 index 0000000000..d68fa9adf3 --- /dev/null +++ b/phpBB/phpbb/filesystem/exception/filesystem_exception.php @@ -0,0 +1,42 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\filesystem\exception; + +class filesystem_exception extends \phpbb\exception\runtime_exception +{ + /** + * Constructor + * + * @param string $message The Exception message to throw (must be a language variable). + * @param string $filename The file that caused the error. + * @param array $parameters The parameters to use with the language var. + * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining. + * @param integer $code The Exception code. + */ + public function __construct($message = "", $filename = '', $parameters = array(), \Exception $previous = null, $code = 0) + { + parent::__construct($message, array_merge(array('filename' => $filename), $parameters), $previous, $code); + } + + /** + * Returns the filename that triggered the error + * + * @return string + */ + public function get_filename() + { + $parameters = parent::get_parameters(); + return $parameters['filename']; + } +} diff --git a/phpBB/phpbb/filesystem/filesystem.php b/phpBB/phpbb/filesystem/filesystem.php new file mode 100644 index 0000000000..370dff77e5 --- /dev/null +++ b/phpBB/phpbb/filesystem/filesystem.php @@ -0,0 +1,916 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\filesystem; + +use phpbb\filesystem\exception\filesystem_exception; + +/** + * A class with various functions that are related to paths, files and the filesystem + */ +class filesystem implements filesystem_interface +{ + /** + * Store some information about file ownership for phpBB's chmod function + * + * @var array + */ + protected $chmod_info; + + /** + * Stores current working directory + * + * @var string|bool current working directory or false if it cannot be recovered + */ + protected $working_directory; + + /** + * Symfony's Filesystem component + * + * @var \Symfony\Component\Filesystem\Filesystem + */ + protected $symfony_filesystem; + + /** + * Constructor + */ + public function __construct() + { + $this->chmod_info = array(); + $this->symfony_filesystem = new \Symfony\Component\Filesystem\Filesystem(); + $this->working_directory = null; + } + + /** + * {@inheritdoc} + */ + public function chgrp($files, $group, $recursive = false) + { + try + { + $this->symfony_filesystem->chgrp($files, $group, $recursive); + } + catch (\Symfony\Component\Filesystem\Exception\IOException $e) + { + // Try to recover filename + // By the time this is written that is at the end of the message + $error = trim($e->getMessage()); + $file = substr($error, strrpos($error, ' ')); + + throw new filesystem_exception('CANNOT_CHANGE_FILE_GROUP', $file, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function chmod($files, $perms = null, $recursive = false, $force_chmod_link = false) + { + if (is_null($perms)) + { + // Default to read permission for compatibility reasons + $perms = self::CHMOD_READ; + } + + // Check if we got a permission flag + if ($perms > self::CHMOD_ALL) + { + $file_perm = $perms; + + // Extract permissions + //$owner = ($file_perm >> 6) & 7; // This will be ignored + $group = ($file_perm >> 3) & 7; + $other = ($file_perm >> 0) & 7; + + // Does any permissions provided? if so we add execute bit for directories + $group = ($group !== 0) ? ($group | self::CHMOD_EXECUTE) : $group; + $other = ($other !== 0) ? ($other | self::CHMOD_EXECUTE) : $other; + + // Compute directory permissions + $dir_perm = (self::CHMOD_ALL << 6) + ($group << 3) + ($other << 3); + } + else + { + // Add execute bit to owner if execute bit is among perms + $owner_perm = (self::CHMOD_READ | self::CHMOD_WRITE) | ($perms & self::CHMOD_EXECUTE); + $file_perm = ($owner_perm << 6) + ($perms << 3) + ($perms << 0); + + // Compute directory permissions + $perm = ($perms !== 0) ? ($perms | self::CHMOD_EXECUTE) : $perms; + $dir_perm = (($owner_perm | self::CHMOD_EXECUTE) << 6) + ($perm << 3) + ($perm << 0); + } + + // Symfony's filesystem component does not support extra execution flags on directories + // so we need to implement it again + foreach ($this->to_iterator($files) as $file) + { + if ($recursive && is_dir($file) && !is_link($file)) + { + $this->chmod(new \FilesystemIterator($file), $perms, true); + } + + // Don't chmod links as mostly those require 0777 and that cannot be changed + if (is_dir($file) || (is_link($file) && $force_chmod_link)) + { + if (true !== @chmod($file, $dir_perm)) + { + throw new filesystem_exception('CANNOT_CHANGE_FILE_PERMISSIONS', $file, array()); + } + } + else if (is_file($file)) + { + if (true !== @chmod($file, $file_perm)) + { + throw new filesystem_exception('CANNOT_CHANGE_FILE_PERMISSIONS', $file, array()); + } + } + } + } + + /** + * {@inheritdoc} + */ + public function chown($files, $user, $recursive = false) + { + try + { + $this->symfony_filesystem->chown($files, $user, $recursive); + } + catch (\Symfony\Component\Filesystem\Exception\IOException $e) + { + // Try to recover filename + // By the time this is written that is at the end of the message + $error = trim($e->getMessage()); + $file = substr($error, strrpos($error, ' ')); + + throw new filesystem_exception('CANNOT_CHANGE_FILE_GROUP', $file, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function clean_path($path) + { + $exploded = explode('/', $path); + $filtered = array(); + foreach ($exploded as $part) + { + if ($part === '.' && !empty($filtered)) + { + continue; + } + + if ($part === '..' && !empty($filtered) && $filtered[sizeof($filtered) - 1] !== '.' && $filtered[sizeof($filtered) - 1] !== '..') + { + array_pop($filtered); + } + else + { + $filtered[] = $part; + } + } + $path = implode('/', $filtered); + return $path; + } + + /** + * {@inheritdoc} + */ + public function copy($origin_file, $target_file, $override = false) + { + try + { + $this->symfony_filesystem->copy($origin_file, $target_file, $override); + } + catch (\Symfony\Component\Filesystem\Exception\IOException $e) + { + throw new filesystem_exception('CANNOT_COPY_FILES', '', array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function dump_file($filename, $content) + { + try + { + $this->symfony_filesystem->dumpFile($filename, $content); + } + catch (\Symfony\Component\Filesystem\Exception\IOException $e) + { + throw new filesystem_exception('CANNOT_DUMP_FILE', $filename, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function exists($files) + { + return $this->symfony_filesystem->exists($files); + } + + /** + * {@inheritdoc} + */ + public function is_absolute_path($path) + { + return (isset($path[0]) && $path[0] === '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false; + } + + /** + * {@inheritdoc} + */ + public function is_readable($files, $recursive = false) + { + foreach ($this->to_iterator($files) as $file) + { + if ($recursive && is_dir($file) && !is_link($file)) + { + if (!$this->is_readable(new \FilesystemIterator($file), true)) + { + return false; + } + } + + if (!is_readable($file)) + { + return false; + } + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function is_writable($files, $recursive = false) + { + if (defined('PHP_WINDOWS_VERSION_MAJOR') || !function_exists('is_writable')) + { + foreach ($this->to_iterator($files) as $file) + { + if ($recursive && is_dir($file) && !is_link($file)) + { + if (!$this->is_writable(new \FilesystemIterator($file), true)) + { + return false; + } + } + + if (!$this->phpbb_is_writable($file)) + { + return false; + } + } + } + else + { + // use built in is_writable + foreach ($this->to_iterator($files) as $file) + { + if ($recursive && is_dir($file) && !is_link($file)) + { + if (!$this->is_writable(new \FilesystemIterator($file), true)) + { + return false; + } + } + + if (!is_writable($file)) + { + return false; + } + } + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function make_path_relative($end_path, $start_path) + { + return $this->symfony_filesystem->makePathRelative($end_path, $start_path); + } + + /** + * {@inheritdoc} + */ + public function mirror($origin_dir, $target_dir, \Traversable $iterator = null, $options = array()) + { + try + { + $this->symfony_filesystem->mirror($origin_dir, $target_dir, $iterator, $options); + } + catch (\Symfony\Component\Filesystem\Exception\IOException $e) + { + $msg = $e->getMessage(); + $filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"')); + + throw new filesystem_exception('CANNOT_MIRROR_DIRECTORY', $filename, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function mkdir($dirs, $mode = 0777) + { + try + { + $this->symfony_filesystem->mkdir($dirs, $mode); + } + catch (\Symfony\Component\Filesystem\Exception\IOException $e) + { + $msg = $e->getMessage(); + $filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"')); + + throw new filesystem_exception('CANNOT_CREATE_DIRECTORY', $filename, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function phpbb_chmod($files, $perms = null, $recursive = false, $force_chmod_link = false) + { + if (is_null($perms)) + { + // Default to read permission for compatibility reasons + $perms = self::CHMOD_READ; + } + + if (empty($this->chmod_info)) + { + if (!function_exists('fileowner') || !function_exists('filegroup')) + { + $this->chmod_info['process'] = false; + } + else + { + $common_php_owner = @fileowner(__FILE__); + $common_php_group = @filegroup(__FILE__); + + // And the owner and the groups PHP is running under. + $php_uid = (function_exists('posic_getuid')) ? @posix_getuid() : false; + $php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false; + + // If we are unable to get owner/group, then do not try to set them by guessing + if (!$php_uid || empty($php_gids) || !$common_php_owner || !$common_php_group) + { + $this->chmod_info['process'] = false; + } + else + { + $this->chmod_info = array( + 'process' => true, + 'common_owner' => $common_php_owner, + 'common_group' => $common_php_group, + 'php_uid' => $php_uid, + 'php_gids' => $php_gids, + ); + } + } + } + + if ($this->chmod_info['process']) + { + try + { + foreach ($this->to_iterator($files) as $file) + { + $file_uid = @fileowner($file); + $file_gid = @filegroup($file); + + // Change owner + if ($file_uid !== $this->chmod_info['common_owner']) + { + $this->chown($file, $this->chmod_info['common_owner'], $recursive); + } + + // Change group + if ($file_gid !== $this->chmod_info['common_group']) + { + $this->chgrp($file, $this->chmod_info['common_group'], $recursive); + } + + clearstatcache(); + $file_uid = @fileowner($file); + $file_gid = @filegroup($file); + } + } + catch (filesystem_exception $e) + { + $this->chmod_info['process'] = false; + } + } + + // Still able to process? + if ($this->chmod_info['process']) + { + if ($file_uid === $this->chmod_info['php_uid']) + { + $php = 'owner'; + } + else if (in_array($file_gid, $this->chmod_info['php_gids'])) + { + $php = 'group'; + } + else + { + // Since we are setting the everyone bit anyway, no need to do expensive operations + $this->chmod_info['process'] = false; + } + } + + // We are not able to determine or change something + if (!$this->chmod_info['process']) + { + $php = 'other'; + } + + switch ($php) + { + case 'owner': + try + { + $this->chmod($files, $perms, $recursive, $force_chmod_link); + clearstatcache(); + if ($this->is_readable($files) && $this->is_writable($files)) + { + break; + } + } + catch (filesystem_exception $e) + { + // Do nothing + } + case 'group': + try + { + $this->chmod($files, $perms, $recursive, $force_chmod_link); + clearstatcache(); + if ((!($perms & self::CHMOD_READ) || $this->is_readable($files, $recursive)) && (!($perms & self::CHMOD_WRITE) || $this->is_writable($files, $recursive))) + { + break; + } + } + catch (filesystem_exception $e) + { + // Do nothing + } + case 'other': + default: + $this->chmod($files, $perms, $recursive, $force_chmod_link); + break; + } + } + + /** + * {@inheritdoc} + */ + public function realpath($path) + { + if (!function_exists('realpath')) + { + return $this->phpbb_own_realpath($path); + } + + $realpath = realpath($path); + + // Strangely there are provider not disabling realpath but returning strange values. :o + // We at least try to cope with them. + if ((!$this->is_absolute_path($path) && $realpath === $path) || $realpath === false) + { + return $this->phpbb_own_realpath($path); + } + + // Check for DIRECTORY_SEPARATOR at the end (and remove it!) + if (substr($realpath, -1) === DIRECTORY_SEPARATOR) + { + $realpath = substr($realpath, 0, -1); + } + + return $realpath; + } + + /** + * {@inheritdoc} + */ + public function remove($files) + { + try + { + $this->symfony_filesystem->remove($files); + } + catch (\Symfony\Component\Filesystem\Exception\IOException $e) + { + // Try to recover filename + // By the time this is written that is at the end of the message + $error = trim($e->getMessage()); + $file = substr($error, strrpos($error, ' ')); + + throw new filesystem_exception('CANNOT_DELETE_FILES', $file, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function rename($origin, $target, $overwrite = false) + { + try + { + $this->symfony_filesystem->rename($origin, $target, $overwrite); + } + catch (\Symfony\Component\Filesystem\Exception\IOException $e) + { + $msg = $e->getMessage(); + $filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"')); + + throw new filesystem_exception('CANNOT_RENAME_FILE', $filename, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function symlink($origin_dir, $target_dir, $copy_on_windows = false) + { + try + { + $this->symfony_filesystem->symlink($origin_dir, $target_dir, $copy_on_windows); + } + catch (\Symfony\Component\Filesystem\Exception\IOException $e) + { + throw new filesystem_exception('CANNOT_CREATE_SYMLINK', $origin_dir, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function touch($files, $time = null, $access_time = null) + { + try + { + $this->symfony_filesystem->touch($files, $time, $access_time); + } + catch (\Symfony\Component\Filesystem\Exception\IOException $e) + { + // Try to recover filename + // By the time this is written that is at the end of the message + $error = trim($e->getMessage()); + $file = substr($error, strrpos($error, ' ')); + + throw new filesystem_exception('CANNOT_TOUCH_FILES', $file, array(), $e); + } + } + + /** + * phpBB's implementation of is_writable + * + * @todo Investigate if is_writable is still buggy + * + * @param string $file file/directory to check if writable + * + * @return bool true if the given path is writable + */ + protected function phpbb_is_writable($file) + { + if (file_exists($file)) + { + // Canonicalise path to absolute path + $file = $this->realpath($file); + + if (is_dir($file)) + { + // Test directory by creating a file inside the directory + $result = @tempnam($file, 'i_w'); + + if (is_string($result) && file_exists($result)) + { + unlink($result); + + // Ensure the file is actually in the directory (returned realpathed) + return (strpos($result, $file) === 0) ? true : false; + } + } + else + { + $handle = @fopen($file, 'w'); + + if (is_resource($handle)) + { + fclose($handle); + return true; + } + } + } + else + { + // file does not exist test if we can write to the directory + $dir = dirname($file); + + if (file_exists($dir) && is_dir($dir) && $this->phpbb_is_writable($dir)) + { + return true; + } + } + + return false; + } + + /** + * Try to resolve real path when PHP's realpath failes to do so + * + * @param string $path + * @return bool|string + */ + protected function phpbb_own_realpath($path) + { + // Replace all directory separators with '/' + $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); + + $is_absolute_path = false; + $path_prefix = ''; + + if ($this->is_absolute_path($path)) + { + $is_absolute_path = true; + } + else + { + // Resolve working directory and store it + if (is_null($this->working_directory)) + { + if (function_exists('getcwd')) + { + $this->working_directory = str_replace(DIRECTORY_SEPARATOR, '/', getcwd()); + } + + // + // From this point on we really just guessing + // If chdir were called we screwed + // + else if (function_exists('debug_backtrace')) + { + $call_stack = debug_backtrace(0); + $this->working_directory = str_replace(DIRECTORY_SEPARATOR, '/', dirname($call_stack[sizeof($call_stack) - 1]['file'])); + } + else + { + // + // Assuming that the working directory is phpBB root + // we could use this as a fallback, when phpBB will use controllers + // everywhere this will be a safe assumption + // + //$dir_parts = explode(DIRECTORY_SEPARATOR, __DIR__); + //$namespace_parts = explode('\\', trim(__NAMESPACE__, '\\')); + + //$namespace_part_count = sizeof($namespace_parts); + + // Check if we still loading from root + //if (array_slice($dir_parts, -$namespace_part_count) === $namespace_parts) + //{ + // $this->working_directory = implode('/', array_slice($dir_parts, 0, -$namespace_part_count)); + //} + //else + //{ + // $this->working_directory = false; + //} + + $this->working_directory = false; + } + } + + if ($this->working_directory !== false) + { + $is_absolute_path = true; + $path = $this->working_directory . '/' . $path; + } + } + + if ($is_absolute_path) + { + if (defined('PHP_WINDOWS_VERSION_MAJOR')) + { + $path_prefix = $path[0] . ':'; + $path = substr($path, 2); + } + else + { + $path_prefix = ''; + } + } + + $resolved_path = $this->resolve_path($path, $path_prefix, $is_absolute_path); + if ($resolved_path === false) + { + return false; + } + + if (!@file_exists($resolved_path) || (!@is_dir($resolved_path . '/') && !is_file($resolved_path))) + { + return false; + } + + // Return OS specific directory separators + $resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved_path); + + // Check for DIRECTORY_SEPARATOR at the end (and remove it!) + if (substr($resolved, -1) === DIRECTORY_SEPARATOR) + { + return substr($resolved, 0, -1); + } + + return $resolved; + } + + /** + * Convert file(s) to \Traversable object + * + * This is the same function as Symfony's toIterator, but that is private + * so we cannot use it. + * + * @param string|array|\Traversable $files filename/list of filenames + * @return \Traversable + */ + protected function to_iterator($files) + { + if (!$files instanceof \Traversable) + { + $files = new \ArrayObject(is_array($files) ? $files : array($files)); + } + + return $files; + } + + /** + * Try to resolve symlinks in path + * + * @param string $path The path to resolve + * @param string $prefix The path prefix (on windows the drive letter) + * @param bool $absolute Whether or not the path is absolute + * @param bool $return_array Whether or not to return path parts + * + * @return string|array|bool returns the resolved path or an array of parts of the path if $return_array is true + * or false if path cannot be resolved + */ + protected function resolve_path($path, $prefix = '', $absolute = false, $return_array = false) + { + if ($return_array) + { + $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); + } + + trim ($path, '/'); + $path_parts = explode('/', $path); + $resolved = array(); + $resolved_path = $prefix; + $file_found = false; + + foreach ($path_parts as $path_part) + { + if ($file_found) + { + return false; + } + + if (empty($path_part) || ($path_part === '.' && ($absolute || !empty($resolved)))) + { + continue; + } + else if ($absolute && $path_part === '..') + { + if (empty($resolved)) + { + // No directories above root + return false; + } + + array_pop($resolved); + $resolved_path = false; + } + else if ($path_part === '..' && !empty($resolved) && !in_array($resolved[sizeof($resolved) - 1], array('.', '..'))) + { + array_pop($resolved); + $resolved_path = false; + } + else + { + if ($resolved_path === false) + { + if (empty($resolved)) + { + $resolved_path = ($absolute) ? $prefix . '/' . $path_part : $path_part; + } + else + { + $tmp_array = $resolved; + if ($absolute) + { + array_unshift($tmp_array, $prefix); + } + + $resolved_path = implode('/', $tmp_array); + } + } + + $current_path = $resolved_path . '/' . $path_part; + + // Resolve symlinks + if (is_link($current_path)) + { + if (!function_exists('readlink')) + { + return false; + } + + $link = readlink($current_path); + + // Is link has an absolute path in it? + if ($this->is_absolute_path($link)) + { + if (defined('PHP_WINDOWS_VERSION_MAJOR')) + { + $prefix = $link[0] . ':'; + $link = substr($link, 2); + } + else + { + $prefix = ''; + } + + $resolved = $this->resolve_path($link, $prefix, true, true); + $absolute = true; + } + else + { + $resolved = $this->resolve_path($resolved_path . '/' . $link, $prefix, $absolute, true); + } + + if (!$resolved) + { + return false; + } + + $resolved_path = false; + } + else if (is_dir($current_path . '/')) + { + $resolved[] = $path_part; + $resolved_path = $current_path; + } + else if (is_file($current_path)) + { + $resolved[] = $path_part; + $resolved_path = $current_path; + $file_found = true; + } + else + { + return false; + } + } + } + + // If at the end of the path there were a .. or . + // we need to build the path again. + // Only doing this when a string is expected in return + if ($resolved_path === false && $return_array === false) + { + if (empty($resolved)) + { + $resolved_path = ($absolute) ? $prefix . '/' : './'; + } + else + { + $tmp_array = $resolved; + if ($absolute) + { + array_unshift($tmp_array, $prefix); + } + + $resolved_path = implode('/', $tmp_array); + } + } + + return ($return_array) ? $resolved : $resolved_path; + } +} diff --git a/phpBB/phpbb/filesystem/filesystem_interface.php b/phpBB/phpbb/filesystem/filesystem_interface.php new file mode 100644 index 0000000000..21ad8252f8 --- /dev/null +++ b/phpBB/phpbb/filesystem/filesystem_interface.php @@ -0,0 +1,284 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\filesystem; + +/** + * Interface for phpBB's filesystem service + */ +interface filesystem_interface +{ + /** + * chmod all permissions flag + * + * @var int + */ + const CHMOD_ALL = 7; + + /** + * chmod read permissions flag + * + * @var int + */ + const CHMOD_READ = 4; + + /** + * chmod write permissions flag + * + * @var int + */ + const CHMOD_WRITE = 2; + + /** + * chmod execute permissions flag + * + * @var int + */ + const CHMOD_EXECUTE = 1; + + /** + * Change owner group of files/directories + * + * @param string|array|\Traversable $files The file(s)/directorie(s) to change group + * @param string $group The group that should own the files/directories + * @param bool $recursive If the group should be changed recursively + * @throws \phpbb\filesystem\exception\filesystem_exception the filename which triggered the error can be + * retrieved by filesystem_exception::get_filename() + */ + public function chgrp($files, $group, $recursive = false); + + /** + * Global function for chmodding directories and files for internal use + * + * The function accepts filesystem_interface::CHMOD_ flags in the permission argument + * or the user can specify octal values (or any integer if it makes sense). All directories will have + * an execution bit appended, if the user group (owner, group or other) has any bit specified. + * + * @param string|array|\Traversable $file The file/directory to be chmodded + * @param int $perms Permissions to set + * @param bool $recursive If the permissions should be changed recursively + * @param bool $force_chmod_link Try to apply permissions to symlinks as well + * + * @throws \phpbb\filesystem\exception\filesystem_exception the filename which triggered the error can be + * retrieved by filesystem_exception::get_filename() + */ + public function chmod($files, $perms = null, $recursive = false, $force_chmod_link = false); + + /** + * Change owner group of files/directories + * + * @param string|array|\Traversable $files The file(s)/directorie(s) to change group + * @param string $user The owner user name + * @param bool $recursive Whether change the owner recursively or not + * + * @throws \phpbb\filesystem\exception\filesystem_exception the filename which triggered the error can be + * retrieved by filesystem_exception::get_filename() + */ + public function chown($files, $user, $recursive = false); + + /** + * Eliminates useless . and .. components from specified path. + * + * @param string $path Path to clean + * + * @return string Cleaned path + */ + public function clean_path($path); + + /** + * Copies a file. + * + * This method only copies the file if the origin file is newer than the target file. + * + * By default, if the target already exists, it is not overridden. + * + * @param string $origin_file The original filename + * @param string $target_file The target filename + * @param bool $override Whether to override an existing file or not + * + * @throws \phpbb\filesystem\exception\filesystem_exception When the file cannot be copied + */ + public function copy($origin_file, $target_file, $override = false); + + /** + * Atomically dumps content into a file. + * + * @param string $filename The file to be written to. + * @param string $content The data to write into the file. + * + * @throws \phpbb\filesystem\exception\filesystem_exception When the file cannot be written + */ + public function dump_file($filename, $content); + + /** + * Checks the existence of files or directories. + * + * @param string|array|\Traversable $files files/directories to check + * + * @return bool Returns true if all files/directories exist, false otherwise + */ + public function exists($files); + + /** + * Checks if a path is absolute or not + * + * @param string $path Path to check + * + * @return bool true if the path is absolute, false otherwise + */ + public function is_absolute_path($path); + + /** + * Checks if files/directories are readable + * + * @param string|array|\Traversable $files files/directories to check + * @param bool $recursive Whether or not directories should be checked recursively + * + * @return bool True when the files/directories are readable, otherwise false. + */ + public function is_readable($files, $recursive = false); + + /** + * Test if a file/directory is writable + * + * @param string|array|\Traversable $files files/directories to perform write test on + * @param bool $recursive Whether or not directories should be checked recursively + * + * @return bool True when the files/directories are writable, otherwise false. + */ + public function is_writable($files, $recursive = false); + + /** + * Given an existing path, convert it to a path relative to a given starting path + * + * @param string $end_path Absolute path of target + * @param string $start_path Absolute path where traversal begins + * + * @return string Path of target relative to starting path + */ + public function make_path_relative($end_path, $start_path); + + /** + * Mirrors a directory to another. + * + * @param string $origin_dir The origin directory + * @param string $target_dir The target directory + * @param \Traversable $iterator A Traversable instance + * @param array $options An array of boolean options + * Valid options are: + * - $options['override'] Whether to override an existing file on copy or not (see copy()) + * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink()) + * - $options['delete'] Whether to delete files that are not in the source directory (defaults to false) + * + * @throws \phpbb\filesystem\exception\filesystem_exception When the file cannot be copied. + * The filename which triggered the error can be + * retrieved by filesystem_exception::get_filename() + */ + public function mirror($origin_dir, $target_dir, \Traversable $iterator = null, $options = array()); + + /** + * Creates a directory recursively. + * + * @param string|array|\Traversable $dirs The directory path + * @param int $mode The directory mode + * + * @throws \phpbb\filesystem\exception\filesystem_exception On any directory creation failure + * The filename which triggered the error can be + * retrieved by filesystem_exception::get_filename() + */ + public function mkdir($dirs, $mode = 0777); + + /** + * Global function for chmodding directories and files for internal use + * + * This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions. + * The function determines owner and group from common.php file and sets the same to the provided file. + * The function uses bit fields to build the permissions. + * The function sets the appropiate execute bit on directories. + * + * Supported constants representing bit fields are: + * + * filesystem_interface::CHMOD_ALL - all permissions (7) + * filesystem_interface::CHMOD_READ - read permission (4) + * filesystem_interface::CHMOD_WRITE - write permission (2) + * filesystem_interface::CHMOD_EXECUTE - execute permission (1) + * + * NOTE: The function uses POSIX extension and fileowner()/filegroup() functions. If any of them is disabled, this function tries to build proper permissions, by calling is_readable() and is_writable() functions. + * + * @param string|array|\Traversable $file The file/directory to be chmodded + * @param int $perms Permissions to set + * @param bool $recursive If the permissions should be changed recursively + * @param bool $force_chmod_link Try to apply permissions to symlinks as well + * + * @throws \phpbb\filesystem\exception\filesystem_exception the filename which triggered the error can be + * retrieved by filesystem_exception::get_filename() + */ + public function phpbb_chmod($file, $perms = null, $recursive = false, $force_chmod_link = false); + + /** + * A wrapper for PHP's realpath + * + * Try to resolve realpath when PHP's realpath is not available, or + * known to be buggy. + * + * @param string $path Path to resolve + * + * @return string Resolved path + */ + public function realpath($path); + + /** + * Removes files or directories. + * + * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to remove + * + * @throws \phpbb\filesystem\exception\filesystem_exception When removal fails. + * The filename which triggered the error can be + * retrieved by filesystem_exception::get_filename() + */ + public function remove($files); + + /** + * Renames a file or a directory. + * + * @param string $origin The origin filename or directory + * @param string $target The new filename or directory + * @param bool $overwrite Whether to overwrite the target if it already exists + * + * @throws \phpbb\filesystem\exception\filesystem_exception When target file or directory already exists, + * or origin cannot be renamed. + */ + public function rename($origin, $target, $overwrite = false); + + /** + * Creates a symbolic link or copy a directory. + * + * @param string $origin_dir The origin directory path + * @param string $target_dir The symbolic link name + * @param bool $copy_on_windows Whether to copy files if on Windows + * + * @throws \phpbb\filesystem\exception\filesystem_exception When symlink fails + */ + public function symlink($origin_dir, $target_dir, $copy_on_windows = false); + + /** + * Sets access and modification time of file. + * + * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to create + * @param int $time The touch time as a Unix timestamp + * @param int $access_time The access time as a Unix timestamp + * + * @throws \phpbb\filesystem\exception\filesystem_exception When touch fails + */ + public function touch($files, $time = null, $access_time = null); +} diff --git a/phpBB/phpbb/finder.php b/phpBB/phpbb/finder.php index 28f28825ba..58bc27084e 100644 --- a/phpBB/phpbb/finder.php +++ b/phpBB/phpbb/finder.php @@ -48,14 +48,14 @@ class finder /** * Creates a new finder instance with its dependencies * - * @param \phpbb\filesystem $filesystem Filesystem instance + * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem instance * @param string $phpbb_root_path Path to the phpbb root directory * @param \phpbb\cache\driver\driver_interface $cache A cache instance or null * @param string $php_ext php file extension * @param string $cache_name The name of the cache variable, defaults to * _ext_finder */ - public function __construct(\phpbb\filesystem $filesystem, $phpbb_root_path = '', \phpbb\cache\driver\driver_interface $cache = null, $php_ext = 'php', $cache_name = '_ext_finder') + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path = '', \phpbb\cache\driver\driver_interface $cache = null, $php_ext = 'php', $cache_name = '_ext_finder') { $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php index 5400c1c5a6..7b0d6f0fba 100644 --- a/phpBB/phpbb/path_helper.php +++ b/phpBB/phpbb/path_helper.php @@ -21,7 +21,7 @@ class path_helper /** @var \phpbb\symfony_request */ protected $symfony_request; - /** @var \phpbb\filesystem */ + /** @var \phpbb\filesystem\filesystem_interface */ protected $filesystem; /** @var \phpbb\request\request_interface */ @@ -43,13 +43,13 @@ class path_helper * Constructor * * @param \phpbb\symfony_request $symfony_request - * @param \phpbb\filesystem $filesystem + * @param \phpbb\filesystem\filesystem_interface $filesystem * @param \phpbb\request\request_interface $request * @param string $phpbb_root_path Relative path to phpBB root * @param string $php_ext PHP file extension * @param mixed $adm_relative_path Relative path admin path to adm/ root */ - public function __construct(\phpbb\symfony_request $symfony_request, \phpbb\filesystem $filesystem, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext, $adm_relative_path = null) + public function __construct(\phpbb\symfony_request $symfony_request, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext, $adm_relative_path = null) { $this->symfony_request = $symfony_request; $this->filesystem = $filesystem; diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 4ccd3cf5e3..5313106b0a 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -85,17 +85,24 @@ class router implements RouterInterface */ protected $route_collection; + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + /** * Construct method * + * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem helper * @param manager $extension_manager Extension manager * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP file extension * @param string $environment Name of the current environment * @param array $routing_files Array of strings containing paths to YAML files holding route information */ - public function __construct(manager $extension_manager, $phpbb_root_path, $php_ext, $environment, $routing_files = array()) + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, manager $extension_manager, $phpbb_root_path, $php_ext, $environment, $routing_files = array()) { + $this->filesystem = $filesystem; $this->extension_manager = $extension_manager; $this->routing_files = $routing_files; $this->phpbb_root_path = $phpbb_root_path; @@ -148,7 +155,7 @@ class router implements RouterInterface $this->route_collection = new RouteCollection; foreach ($this->routing_files as $file_path) { - $loader = new YamlFileLoader(new FileLocator(phpbb_realpath($base_path))); + $loader = new YamlFileLoader(new FileLocator($this->filesystem->realpath($base_path))); $this->route_collection->addCollection($loader->load($file_path)); } } diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index d49f88b676..6154f384f3 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -92,8 +92,8 @@ class session } // current directory within the phpBB root (for example: adm) - $root_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($root_path))); - $page_dirs = explode('/', str_replace('\\', '/', phpbb_realpath('./'))); + $root_dirs = explode('/', str_replace('\\', '/', $phpbb_filesystem->realpath($root_path))); + $page_dirs = explode('/', str_replace('\\', '/', $phpbb_filesystem->realpath('./'))); $intersection = array_intersect_assoc($root_dirs, $page_dirs); $root_dirs = array_diff_assoc($root_dirs, $intersection); diff --git a/phpBB/phpbb/template/twig/loader.php b/phpBB/phpbb/template/twig/loader.php index 2f8ffaa776..df8183c019 100644 --- a/phpBB/phpbb/template/twig/loader.php +++ b/phpBB/phpbb/template/twig/loader.php @@ -20,6 +20,24 @@ class loader extends \Twig_Loader_Filesystem { protected $safe_directories = array(); + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + /** + * Constructor + * + * @param \phpbb\filesystem\filesystem_interface $filesystem + * @param string|array $paths + */ + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $paths = array()) + { + $this->filesystem = $filesystem; + + parent::__construct($paths); + } + /** * Set safe directories * @@ -49,7 +67,7 @@ class loader extends \Twig_Loader_Filesystem */ public function addSafeDirectory($directory) { - $directory = phpbb_realpath($directory); + $directory = $this->filesystem->realpath($directory); if ($directory !== false) { @@ -118,7 +136,7 @@ class loader extends \Twig_Loader_Filesystem // can now check if we're within a "safe" directory // Find the real path of the directory the file is in - $directory = phpbb_realpath(dirname($file)); + $directory = $this->filesystem->realpath(dirname($file)); if ($directory === false) { diff --git a/phpBB/phpbb/viewonline_helper.php b/phpBB/phpbb/viewonline_helper.php index b722f9d911..89915f2228 100644 --- a/phpBB/phpbb/viewonline_helper.php +++ b/phpBB/phpbb/viewonline_helper.php @@ -18,13 +18,13 @@ namespace phpbb; */ class viewonline_helper { - /** @var \phpbb\filesystem */ + /** @var \phpbb\filesystem\filesystem_interface */ protected $filesystem; /** - * @param \phpbb\filesystem $filesystem + * @param \phpbb\filesystem\filesystem_interface $filesystem phpBB's filesystem service */ - public function __construct(\phpbb\filesystem $filesystem) + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem) { $this->filesystem = $filesystem; } -- cgit v1.2.1 From f23fe9e69d5a49d983af1a06297c162bb2b97f05 Mon Sep 17 00:00:00 2001 From: MateBartus Date: Thu, 16 Apr 2015 23:28:52 +0200 Subject: [ticket/13766] Add style_parent_id in textformater's data_access::get_styles() PHPBB3-13766 --- phpBB/phpbb/textformatter/data_access.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/data_access.php b/phpBB/phpbb/textformatter/data_access.php index 8938d66935..2103bf8e60 100644 --- a/phpBB/phpbb/textformatter/data_access.php +++ b/phpBB/phpbb/textformatter/data_access.php @@ -115,7 +115,7 @@ class data_access */ protected function get_styles() { - $sql = 'SELECT style_id, style_path, bbcode_bitfield FROM ' . $this->styles_table; + $sql = 'SELECT style_id, style_path, style_parent_id, bbcode_bitfield FROM ' . $this->styles_table; $result = $this->db->sql_query($sql); $rows = $this->db->sql_fetchrowset($result); $this->db->sql_freeresult($result); -- cgit v1.2.1 From de5a5c41f8e8e47d0740fa97d3d83d57168b18b4 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 19 Apr 2015 17:41:29 +0200 Subject: [ticket/13768] Fix deprecations PHPBB3-13768 --- phpBB/phpbb/di/container_builder.php | 2 +- phpBB/phpbb/routing/router.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 2a410db9bd..99576f9020 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -150,7 +150,7 @@ class container_builder $config_cache = new ConfigCache($container_filename, defined('DEBUG')); if ($this->dump_container && $config_cache->isFresh()) { - require($container_filename); + require($config_cache->getPath()); $this->container = new \phpbb_cache_container(); } else diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 5313106b0a..7444f06253 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -262,7 +262,7 @@ class router implements RouterInterface $cache->write($dumper->dump($options), $this->get_routes()->getResources()); } - require_once($cache); + require_once($cache->getPath()); $this->matcher = new \phpbb_url_matcher($this->context); } @@ -310,7 +310,7 @@ class router implements RouterInterface $cache->write($dumper->dump($options), $this->get_routes()->getResources()); } - require_once($cache); + require_once($cache->getPath()); $this->generator = new \phpbb_url_generator($this->context); } -- cgit v1.2.1 From 2fa99602c6f6431e99468ca13f4a58344a401c24 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 8 Feb 2015 20:46:14 +0100 Subject: [ticket/8672] Add class for retrieving imagesize without download getimagesize() always downloads the complete file before checking the actual image dimensions. This class will be able to do the same without having to download possibly large files. PHPBB3-8672 --- phpBB/phpbb/avatar/driver/driver.php | 7 +- phpBB/phpbb/avatar/driver/gravatar.php | 12 +- phpBB/phpbb/avatar/driver/local.php | 8 +- phpBB/phpbb/avatar/driver/remote.php | 33 +- phpBB/phpbb/upload/imagesize.php | 549 +++++++++++++++++++++++++++++++++ 5 files changed, 581 insertions(+), 28 deletions(-) create mode 100644 phpBB/phpbb/upload/imagesize.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/driver.php b/phpBB/phpbb/avatar/driver/driver.php index b3ced7edf7..aa92ba2012 100644 --- a/phpBB/phpbb/avatar/driver/driver.php +++ b/phpBB/phpbb/avatar/driver/driver.php @@ -30,6 +30,9 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface */ protected $config; + /** @var \phpbb\upload\imagesize */ + protected $imagesize; + /** * Current $phpbb_root_path * @var string @@ -73,14 +76,16 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface * Construct a driver object * * @param \phpbb\config\config $config phpBB configuration + * @param \phpbb\upload\imagesize $imagesize phpBB imagesize class * @param string $phpbb_root_path Path to the phpBB root * @param string $php_ext PHP file extension * @param \phpbb\path_helper $path_helper phpBB path helper * @param \phpbb\cache\driver\driver_interface $cache Cache driver */ - public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, \phpbb\upload\imagesize $imagesize, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface $cache = null) { $this->config = $config; + $this->imagesize = $imagesize; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; $this->path_helper = $path_helper; diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php index 2082e0fd02..73effadc18 100644 --- a/phpBB/phpbb/avatar/driver/gravatar.php +++ b/phpBB/phpbb/avatar/driver/gravatar.php @@ -98,8 +98,8 @@ class gravatar extends \phpbb\avatar\driver\driver return false; } - // Make sure getimagesize works... - if (function_exists('getimagesize') && ($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0)) + // Get image dimensions if they are not set + if ($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0) { /** * default to the minimum of the maximum allowed avatar size if the size @@ -108,20 +108,20 @@ class gravatar extends \phpbb\avatar\driver\driver $row['avatar_width'] = $row['avatar_height'] = min($this->config['avatar_max_width'], $this->config['avatar_max_height']); $url = $this->get_gravatar_url($row); - if (($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0) && (($image_data = getimagesize($url)) === false)) + if (($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0) && (($image_data = $this->imagesize->get_imagesize($url)) === false)) { $error[] = 'UNABLE_GET_IMAGE_SIZE'; return false; } - if (!empty($image_data) && ($image_data[0] <= 0 || $image_data[1] <= 0)) + if (!empty($image_data) && ($image_data['width'] <= 0 || $image_data['width'] <= 0)) { $error[] = 'AVATAR_NO_SIZE'; return false; } - $row['avatar_width'] = ($row['avatar_width'] && $row['avatar_height']) ? $row['avatar_width'] : $image_data[0]; - $row['avatar_height'] = ($row['avatar_width'] && $row['avatar_height']) ? $row['avatar_height'] : $image_data[1]; + $row['avatar_width'] = ($row['avatar_width'] && $row['avatar_height']) ? $row['avatar_width'] : $image_data['width']; + $row['avatar_height'] = ($row['avatar_width'] && $row['avatar_height']) ? $row['avatar_height'] : $image_data['height']; } if ($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0) diff --git a/phpBB/phpbb/avatar/driver/local.php b/phpBB/phpbb/avatar/driver/local.php index 36087f8ba0..abb07469de 100644 --- a/phpBB/phpbb/avatar/driver/local.php +++ b/phpBB/phpbb/avatar/driver/local.php @@ -172,13 +172,15 @@ class local extends \phpbb\avatar\driver\driver // Match all images in the gallery folder if (preg_match('#^[^&\'"<>]+\.(?:' . implode('|', $this->allowed_extensions) . ')$#i', $image) && is_file($file_path . '/' . $image)) { - if (function_exists('getimagesize')) + $dims = $this->imagesize->get_imagesize($file_path . '/' . $image); + + if ($dims === false) { - $dims = getimagesize($file_path . '/' . $image); + $dims = array(0, 0); } else { - $dims = array(0, 0); + $dims = array($dims['width'], $dims['height']); } $cat = ($path == $file_path) ? $user->lang['NO_AVATAR_CATEGORY'] : str_replace("$path/", '', $file_path); $avatar_list[$cat][$image] = array( diff --git a/phpBB/phpbb/avatar/driver/remote.php b/phpBB/phpbb/avatar/driver/remote.php index 4b0ee3f06f..d04f95905d 100644 --- a/phpBB/phpbb/avatar/driver/remote.php +++ b/phpBB/phpbb/avatar/driver/remote.php @@ -92,25 +92,22 @@ class remote extends \phpbb\avatar\driver\driver return false; } - // Make sure getimagesize works... - if (function_exists('getimagesize')) + // Get image dimensions + if (($width <= 0 || $height <= 0) && (($image_data = $this->imagesize->get_imagesize($url)) === false)) { - if (($width <= 0 || $height <= 0) && (($image_data = @getimagesize($url)) === false)) - { - $error[] = 'UNABLE_GET_IMAGE_SIZE'; - return false; - } - - if (!empty($image_data) && ($image_data[0] <= 0 || $image_data[1] <= 0)) - { - $error[] = 'AVATAR_NO_SIZE'; - return false; - } + $error[] = 'UNABLE_GET_IMAGE_SIZE'; + return false; + } - $width = ($width && $height) ? $width : $image_data[0]; - $height = ($width && $height) ? $height : $image_data[1]; + if (!empty($image_data) && ($image_data['width'] <= 0 || $image_data['height'] <= 0)) + { + $error[] = 'AVATAR_NO_SIZE'; + return false; } + $width = ($width && $height) ? $width : $image_data['width']; + $height = ($width && $height) ? $height : $image_data['height']; + if ($width <= 0 || $height <= 0) { $error[] = 'AVATAR_NO_SIZE'; @@ -172,15 +169,15 @@ class remote extends \phpbb\avatar\driver\driver return false; } - if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]]))) + if (!empty($image_data) && (!isset($types[$image_data['type']]) || !in_array($extension, $types[$image_data['type']]))) { - if (!isset($types[$image_data[2]])) + if (!isset($types[$image_data['type']])) { $error[] = 'UNABLE_GET_IMAGE_SIZE'; } else { - $error[] = array('IMAGE_FILETYPE_MISMATCH', $types[$image_data[2]][0], $extension); + $error[] = array('IMAGE_FILETYPE_MISMATCH', $types[$image_data['type']][0], $extension); } return false; diff --git a/phpBB/phpbb/upload/imagesize.php b/phpBB/phpbb/upload/imagesize.php new file mode 100644 index 0000000000..3ef258f0a2 --- /dev/null +++ b/phpBB/phpbb/upload/imagesize.php @@ -0,0 +1,549 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\upload; + +/** + * This class handles the retrieval of image dimensions + */ +class imagesize +{ + /** @var int 4-byte long size */ + const LONG_SIZE = 4; + + /** @var int 2-byte short size */ + const SHORT_SIZE = 2; + + /** @var string PNG header */ + const PNG_HEADER = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"; + + /** @var int PNG IHDR offset */ + const PNG_IHDR_OFFSET = 12; + + /** @var string GIF87a header */ + const GIF87A_HEADER = "\x47\x49\x46\x38\x37\x61"; + + /** @var string GIF89a header */ + const GIF89A_HEADER = "\x47\x49\x46\x38\x39\x61"; + + /** @var int GIF header size */ + const GIF_HEADER_SIZE = 6; + + /** @var int JPG max header size. Headers can be bigger, but we'll abort + * going throught he header after this */ + const JPG_MAX_HEADER_SIZE = 24576; + + /** @var string PSD signature */ + const PSD_SIGNATURE = "8BPS"; + + /** @var int PSD header size */ + const PSD_HEADER_SIZE = 22; + + /** @var int PSD dimensions info offset */ + const PSD_DIMENSIONS_OFFSET = 14; + + /** @var int BMP header size needed for retrieving dimensions */ + const BMP_HEADER_SIZE = 26; + + /** @var string BMP signature */ + const BMP_SIGNATURE = "\x42\x4D"; + + /** qvar int BMP dimensions offset */ + const BMP_DIMENSIONS_OFFSET = 18; + + /** @var int TIF header size. The header might be larger but the dimensions + * should be in the first 512 bytes */ + const TIF_HEADER_SIZE = 512; + + /** @var int TIF tag for image height */ + const TIF_TAG_IMAGE_HEIGHT = 257; + + /** @var int TIF tag for image width */ + const TIF_TAG_IMAGE_WIDTH = 256; + + /** @var int TIF tag type for short */ + const TIF_TAG_TYPE_SHORT = 3; + + /** @var int TIF IFD entry size */ + const TIF_IFD_ENTRY_SIZE = 12; + + /** @var int IFF header size. Grab more than what should be needed to make + * sure we have the necessary data */ + const IFF_HEADER_SIZE = 32; + + /** @var string JPEG 2000 signature */ + const JPEG_2000_SIGNATURE = "\x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A"; + + /** @var array Size info that is returned */ + protected $size = array(); + + /** @var string Data retrieved from remote */ + protected $data = ''; + + /** + * Get image dimensions of supplied image + * + * @param string $file Path to image that should be checked + * @param string $type Mimetype of image + * @return array|bool Array with image dimensions if successful, false if not + */ + public function get_imagesize($file, $type = '') + { + // Reset values + $this->reset_values(); + + // Treat image type as unknown if extension or mime type is unknown + if (!preg_match('/\.([a-z0-9]+)$/i', $file, $match) && empty($type)) + { + $this->get_imagesize_unknown_type($file); + } + else + { + $extension = (isset($match[1])) ? $match[1] : preg_replace('/.+\/([a-z0-9-.]+)$/i', '$1', $type); + + // Reset size info + $this->size = array(); + + switch ($extension) + { + case 'png': + $this->get_png_size($file); + break; + + case 'gif': + $this->get_gif_size($file); + break; + + case 'jpeg': + case 'jpg': + case 'jpe': + case 'jif': + case 'jfif': + case 'jfi': + $this->get_jpeg_size($file); + break; + + case 'jp2': + case 'j2k': + case 'jpf': + case 'jpg2': + case 'jpx': + case 'jpm': + $this->get_jp2_size($file); + break; + + case 'psd': + case 'photoshop': + $this->get_psd_size($file); + break; + + case 'bmp': + $this->get_bmp_size($file); + break; + + case 'tif': + case 'tiff': + // get_tif_size() sets mime type + $this->get_tif_size($file); + break; + + case 'wbm': + case 'wbmp': + case 'vnd.wap.wbmp': + $this->get_wbmp_size($file); + break; + + case 'iff': + case 'x-iff': + $this->get_iff_size($file); + break; + + default: + return false; + } + } + + return sizeof($this->size) > 1 ? $this->size : false; + } + + /** + * Get dimensions of image if type is unknown + * + * @param string $filename Path to file + */ + protected function get_imagesize_unknown_type($filename) + { + // Grab the maximum amount of bytes we might need + $data = $this->get_image($filename, 0, self::JPG_MAX_HEADER_SIZE, false); + + if ($data !== false) + { + $class_methods = preg_grep('/get_([a-z0-9]+)_size/i', get_class_methods($this)); + + foreach ($class_methods as $method) + { + call_user_func_array(array($this, $method), array($filename)); + + if (sizeof($this->size) > 1) + { + break; + } + } + } + } + + /** + * Reset values to default + */ + protected function reset_values() + { + $this->size = array(); + $this->data = ''; + } + + /** + * Set mime type based on supplied image + * + * @param int $type Type of image + */ + protected function set_image_type($type) + { + $this->size['type'] = $type; + } + + /** + * Get image from specified path/source + * + * @param string $filename Path to image + * @param int $offset Offset at which reading of the image should start + * @param int $length Maximum length that should be read + * @param bool $force_length True if the length needs to be the specified + * length, false if not. Default: true + * + * @return bool|string Image data or false if result was empty + */ + protected function get_image($filename, $offset, $length, $force_length = true) + { + if (empty($this->data)) + { + $this->data = @file_get_contents($filename, null, null, $offset, $length); + } + + // Force length to expected one. Return false if data length + // is smaller than expected length + if ($force_length === true) + { + return (strlen($this->data) < $length) ? false : substr($this->data, $offset, $length) ; + } + + return empty($this->data) ? false : $this->data; + } + + /** + * Get dimensions of PNG image + * + * @param string $filename Filename of image + * + * @return array|bool Array with image dimensions if successful, false if not + */ + protected function get_png_size($filename) + { + // Retrieve image data including the header, the IHDR tag, and the + // following 2 chunks for the image width and height + $data = $this->get_image($filename, 0, self::PNG_IHDR_OFFSET + 3 * self::LONG_SIZE); + + // Check if header fits expected format specified by RFC 2083 + if (substr($data, 0, self::PNG_IHDR_OFFSET - self::LONG_SIZE) !== self::PNG_HEADER || substr($data, self::PNG_IHDR_OFFSET, self::LONG_SIZE) !== 'IHDR') + { + return; + } + + $this->size = unpack('Nwidth/Nheight', substr($data, self::PNG_IHDR_OFFSET + self::LONG_SIZE, self::LONG_SIZE * 2)); + + $this->set_image_type(IMAGETYPE_PNG); + } + + /** + * Get dimensions of GIF image + * + * @param string $filename Filename of image + * + * @return array|bool Array with image dimensions if successful, false if not + */ + protected function get_gif_size($filename) + { + // Get data needed for reading image dimensions as outlined by GIF87a + // and GIF89a specifications + $data = $this->get_image($filename, 0, self::GIF_HEADER_SIZE + self::SHORT_SIZE * 2); + + $type = substr($data, 0, self::GIF_HEADER_SIZE); + if ($type !== self::GIF87A_HEADER && $type !== self::GIF89A_HEADER) + { + return; + } + + $this->size = unpack('vwidth/vheight', substr($data, self::GIF_HEADER_SIZE, self::SHORT_SIZE * 2)); + + $this->set_image_type(IMAGETYPE_GIF); + } + + /** + * Get dimensions of JPG image + * + * @param string $filename Filename of image + * + * @return array|bool Array with image dimensions if successful, false if not + */ + protected function get_jpeg_size($filename) + { + // Do not force the data length + $data = $this->get_image($filename, 0, self::JPG_MAX_HEADER_SIZE, false); + + // Check if file is jpeg + if ($data[0] !== "\xFF" || $data[1] !== "\xD8") + { + return; + } + + // Look through file for SOF marker + for ($i = 2 * self::SHORT_SIZE; $i < strlen($data); $i++) + { + if ($data[$i] === "\xFF" && in_array($data[$i+1], array("\xC0", "\xC1", "\xC2", "\xC3", "\xC5", "\xC6", "\xC7", "\xC8", "\xC9", "\xCA", "\xCB", "\xCD", "\xCE", "\xCF"))) + { + // Extract size info from SOF marker + list(, $unpacked) = unpack("H*", substr($data, $i + self::SHORT_SIZE, 7)); + + // Get width and height from unpacked size info + $this->size = array( + 'width' => hexdec(substr($unpacked, 10, 4)), + 'height' => hexdec(substr($unpacked, 6, 4)), + ); + + break; + } + } + + $this->set_image_type(IMAGETYPE_JPEG); + } + + /** + * Get dimensions of PSD image + * + * @param string $filename Filename of image + * + * @return array|bool Array with image dimensions if successful, false if not + */ + protected function get_psd_size($filename) + { + $data = $this->get_image($filename, 0, self::PSD_HEADER_SIZE); + + if ($data === false) + { + return; + } + + // Offset for version info is length of header but version is only a + // 16-bit unsigned value + $version = unpack('n', substr($data, self::LONG_SIZE, 2)); + + // Check if supplied file is a PSD file + if (substr($data, 0, self::LONG_SIZE) !== self::PSD_SIGNATURE || $version[1] !== 1) + { + return; + } + + $this->size = unpack('Nheight/Nwidth', substr($data, self::PSD_DIMENSIONS_OFFSET, 2 * self::LONG_SIZE)); + + $this->set_image_type(IMAGETYPE_PSD); + } + + /** + * Get dimensions of BMP image + * + * @param string $filename Filename of image + * + * @return array|bool Array with image dimensions if successful, false if not + */ + protected function get_bmp_size($filename) + { + $data = $this->get_image($filename, 0, self::BMP_HEADER_SIZE); + + // Check if supplied file is a BMP file + if (substr($data, 0, 2) !== self::BMP_SIGNATURE) + { + return; + } + + $this->size = unpack('lwidth/lheight', substr($data, self::BMP_DIMENSIONS_OFFSET, 2 * self::LONG_SIZE)); + + $this->set_image_type(IMAGETYPE_BMP); + } + + /** + * Get dimensions of TIF/TIFF image + * + * @param string $filename Filename of image + * + * @return array|bool Array with image dimensions if successful, false if not + */ + protected function get_tif_size($filename) + { + // Do not force length of header + $data = $this->get_image($filename, 0, self::TIF_HEADER_SIZE, false); + + $signature = substr($data, 0, self::SHORT_SIZE); + + if ($signature !== "II" && $signature !== "MM") + { + return; + } + + if ($signature === "II") + { + $type_long = 'V'; + $type_short = 'v'; + $this->set_image_type(IMAGETYPE_TIFF_II); + } + else + { + $type_long = 'N'; + $type_short = 'n'; + $this->set_image_type(IMAGETYPE_TIFF_MM); + } + + // Get offset of IFD + list(, $offset) = unpack($type_long, substr($data, self::LONG_SIZE, self::LONG_SIZE)); + + // Get size of IFD + list(, $size_ifd) = unpack($type_short, substr($data, $offset, self::SHORT_SIZE)); + + // Skip 2 bytes that define the IFD size + $offset += self::SHORT_SIZE; + + // Filter through IFD + for ($i = 0; $i < $size_ifd; $i++) + { + // Get IFD tag + $type = unpack($type_short, substr($data, $offset, self::SHORT_SIZE)); + + // Get field type of tag + $field_type = unpack($type_short . 'type', substr($data, $offset + self::SHORT_SIZE, self::SHORT_SIZE)); + + // Get IFD entry + $ifd_value = substr($data, $offset + 2 * self::LONG_SIZE, self::LONG_SIZE); + + // Get actual dimensions from IFD + if ($type[1] === self::TIF_TAG_IMAGE_HEIGHT) + { + $this->size = array_merge($this->size, ($field_type['type'] === self::TIF_TAG_TYPE_SHORT) ? unpack($type_short . 'height', $ifd_value) : unpack($type_long . 'height', $ifd_value)); + } + else if ($type[1] === self::TIF_TAG_IMAGE_WIDTH) + { + $this->size = array_merge($this->size, ($field_type['type'] === self::TIF_TAG_TYPE_SHORT) ? unpack($type_short .'width', $ifd_value) : unpack($type_long . 'width', $ifd_value)); + } + + $offset += self::TIF_IFD_ENTRY_SIZE; + } + } + + /** + * Get dimensions of WBMP image + * + * @param string $filename Filename of image + * + * @return array|bool Array with image dimensions if successful, false if not + */ + protected function get_wbmp_size($filename) + { + $data = $this->get_image($filename, 0, self::LONG_SIZE); + + // Check if image is WBMP + if (ord($data[0]) !== 0 || ord($data[1]) !== 0 || $data === substr(self::JPEG_2000_SIGNATURE, 0, 4)) + { + return; + } + + $this->size = unpack('Cwidth/Cheight', substr($data, self::SHORT_SIZE, self::SHORT_SIZE)); + + $this->set_image_type(IMAGETYPE_WBMP); + } + + /** + * Get dimensions of IFF image + * + * @param string $filename Filename of image + * + * @return array|bool Array with image dimensions if successful, false if not + */ + protected function get_iff_size($filename) + { + $data = $this->get_image($filename, 0, self::IFF_HEADER_SIZE); + + $signature = substr($data, 0, self::LONG_SIZE ); + + // Check if image is IFF + if ($signature !== 'FORM' && $signature !== 'FOR4') + { + return; + } + + // Amiga version of IFF + if ($signature === 'FORM') + { + $btmhd_position = strpos($data, 'BMHD'); + $this->size = unpack('nwidth/nheight', substr($data, $btmhd_position + 2 * self::LONG_SIZE, self::LONG_SIZE)); + } + // Maya version + else + { + $btmhd_position = strpos($data, 'BHD'); + $this->size = unpack('Nwidth/Nheight', substr($data, $btmhd_position + 2 * self::LONG_SIZE - 1, self::LONG_SIZE * 2)); + } + + $this->set_image_type(IMAGETYPE_IFF); + } + + /** + * Get dimensions of JPEG 2000 image + * + * @param string $filename Filename of image + * + * @return array|bool Array with image dimensions if successful, false if not + */ + protected function get_jp2_size($filename) + { + $data = $this->get_image($filename, 0, self::JPG_MAX_HEADER_SIZE, false); + + // Check if file is jpeg 2000 + if (substr($data, 0, strlen(self::JPEG_2000_SIGNATURE)) !== self::JPEG_2000_SIGNATURE) + { + return; + } + + // Get SOC position before starting to search for SIZ + $soc_position = strpos($data, "\xFF\x4F"); + + // Make sure we do not get SIZ before SOC + $data = substr($data, $soc_position); + + $siz_position = strpos($data, "\xFF\x51"); + + // Remove SIZ and everything before + $data = substr($data, $siz_position + self::SHORT_SIZE); + + // Acquire size info from data + $this->size = unpack('Nwidth/Nheight', substr($data, self::LONG_SIZE, self::LONG_SIZE * 2)); + + $this->set_image_type(IMAGETYPE_JPEG2000); + } +} -- cgit v1.2.1 From 245d042e43374e6467f447507783a68fae186ef1 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 6 Apr 2015 21:32:22 +0200 Subject: [ticket/8672] Updated the text_formatter.s9e service PHPBB3-8672 --- phpBB/phpbb/textformatter/s9e/parser.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 77328ee4d9..0582f235e0 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -367,7 +367,6 @@ class parser implements \phpbb\textformatter\parser_interface { // Validate the URL $url = BuiltInFilters::filterUrl($url, $url_config, $logger); - if ($url === false) { return false; @@ -375,26 +374,23 @@ class parser implements \phpbb\textformatter\parser_interface if ($max_height || $max_width) { - $stats = @getimagesize($url); - - if ($stats === false) + $imagesize = new \phpbb\upload\imagesize(); + $size_info = $imagesize->get_imagesize($url); + if ($size_info === false) { $logger->err('UNABLE_GET_IMAGE_SIZE'); - return false; } - if ($max_height && $max_height < $stats[1]) + if ($max_height && $max_height < $size_info['height']) { $logger->err('MAX_IMG_HEIGHT_EXCEEDED', array('max_height' => $max_height)); - return false; } - if ($max_width && $max_width < $stats[0]) + if ($max_width && $max_width < $size_info['width']) { $logger->err('MAX_IMG_WIDTH_EXCEEDED', array('max_width' => $max_width)); - return false; } } -- cgit v1.2.1 From 39d6180c6814996dde84cfcd8c0150bba37354ac Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 7 Apr 2015 16:19:36 +0200 Subject: [ticket/8672] Use fastImageSize in classes PHPBB3-8672 --- phpBB/phpbb/avatar/driver/driver.php | 6 +++--- phpBB/phpbb/avatar/driver/gravatar.php | 2 +- phpBB/phpbb/avatar/driver/local.php | 2 +- phpBB/phpbb/avatar/driver/remote.php | 2 +- phpBB/phpbb/textformatter/s9e/parser.php | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/driver.php b/phpBB/phpbb/avatar/driver/driver.php index aa92ba2012..b6fd380bda 100644 --- a/phpBB/phpbb/avatar/driver/driver.php +++ b/phpBB/phpbb/avatar/driver/driver.php @@ -30,7 +30,7 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface */ protected $config; - /** @var \phpbb\upload\imagesize */ + /** @var \fastImageSize\fastImageSize */ protected $imagesize; /** @@ -76,13 +76,13 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface * Construct a driver object * * @param \phpbb\config\config $config phpBB configuration - * @param \phpbb\upload\imagesize $imagesize phpBB imagesize class + * @param \fastImageSize\fastImageSize $imagesize fastImageSize class * @param string $phpbb_root_path Path to the phpBB root * @param string $php_ext PHP file extension * @param \phpbb\path_helper $path_helper phpBB path helper * @param \phpbb\cache\driver\driver_interface $cache Cache driver */ - public function __construct(\phpbb\config\config $config, \phpbb\upload\imagesize $imagesize, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, \fastImageSize\fastImageSize $imagesize, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface $cache = null) { $this->config = $config; $this->imagesize = $imagesize; diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php index 73effadc18..badbd9421d 100644 --- a/phpBB/phpbb/avatar/driver/gravatar.php +++ b/phpBB/phpbb/avatar/driver/gravatar.php @@ -108,7 +108,7 @@ class gravatar extends \phpbb\avatar\driver\driver $row['avatar_width'] = $row['avatar_height'] = min($this->config['avatar_max_width'], $this->config['avatar_max_height']); $url = $this->get_gravatar_url($row); - if (($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0) && (($image_data = $this->imagesize->get_imagesize($url)) === false)) + if (($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0) && (($image_data = $this->imagesize->getImageSize($url)) === false)) { $error[] = 'UNABLE_GET_IMAGE_SIZE'; return false; diff --git a/phpBB/phpbb/avatar/driver/local.php b/phpBB/phpbb/avatar/driver/local.php index abb07469de..88a139f81e 100644 --- a/phpBB/phpbb/avatar/driver/local.php +++ b/phpBB/phpbb/avatar/driver/local.php @@ -172,7 +172,7 @@ class local extends \phpbb\avatar\driver\driver // Match all images in the gallery folder if (preg_match('#^[^&\'"<>]+\.(?:' . implode('|', $this->allowed_extensions) . ')$#i', $image) && is_file($file_path . '/' . $image)) { - $dims = $this->imagesize->get_imagesize($file_path . '/' . $image); + $dims = $this->imagesize->getImageSize($file_path . '/' . $image); if ($dims === false) { diff --git a/phpBB/phpbb/avatar/driver/remote.php b/phpBB/phpbb/avatar/driver/remote.php index d04f95905d..90443c9b4e 100644 --- a/phpBB/phpbb/avatar/driver/remote.php +++ b/phpBB/phpbb/avatar/driver/remote.php @@ -93,7 +93,7 @@ class remote extends \phpbb\avatar\driver\driver } // Get image dimensions - if (($width <= 0 || $height <= 0) && (($image_data = $this->imagesize->get_imagesize($url)) === false)) + if (($width <= 0 || $height <= 0) && (($image_data = $this->imagesize->getImageSize($url)) === false)) { $error[] = 'UNABLE_GET_IMAGE_SIZE'; return false; diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 0582f235e0..e46a0578d2 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -374,8 +374,8 @@ class parser implements \phpbb\textformatter\parser_interface if ($max_height || $max_width) { - $imagesize = new \phpbb\upload\imagesize(); - $size_info = $imagesize->get_imagesize($url); + $imagesize = new \fastImageSize\fastImageSize(); + $size_info = $imagesize->getImageSize($url); if ($size_info === false) { $logger->err('UNABLE_GET_IMAGE_SIZE'); -- cgit v1.2.1 From f92d8944704161668e3fa2a868711730fbcc777d Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 7 Apr 2015 16:47:10 +0200 Subject: [ticket/8672] Remove outdated imagesize class PHPBB3-8672 --- phpBB/phpbb/upload/imagesize.php | 549 --------------------------------------- 1 file changed, 549 deletions(-) delete mode 100644 phpBB/phpbb/upload/imagesize.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/upload/imagesize.php b/phpBB/phpbb/upload/imagesize.php deleted file mode 100644 index 3ef258f0a2..0000000000 --- a/phpBB/phpbb/upload/imagesize.php +++ /dev/null @@ -1,549 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -namespace phpbb\upload; - -/** - * This class handles the retrieval of image dimensions - */ -class imagesize -{ - /** @var int 4-byte long size */ - const LONG_SIZE = 4; - - /** @var int 2-byte short size */ - const SHORT_SIZE = 2; - - /** @var string PNG header */ - const PNG_HEADER = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"; - - /** @var int PNG IHDR offset */ - const PNG_IHDR_OFFSET = 12; - - /** @var string GIF87a header */ - const GIF87A_HEADER = "\x47\x49\x46\x38\x37\x61"; - - /** @var string GIF89a header */ - const GIF89A_HEADER = "\x47\x49\x46\x38\x39\x61"; - - /** @var int GIF header size */ - const GIF_HEADER_SIZE = 6; - - /** @var int JPG max header size. Headers can be bigger, but we'll abort - * going throught he header after this */ - const JPG_MAX_HEADER_SIZE = 24576; - - /** @var string PSD signature */ - const PSD_SIGNATURE = "8BPS"; - - /** @var int PSD header size */ - const PSD_HEADER_SIZE = 22; - - /** @var int PSD dimensions info offset */ - const PSD_DIMENSIONS_OFFSET = 14; - - /** @var int BMP header size needed for retrieving dimensions */ - const BMP_HEADER_SIZE = 26; - - /** @var string BMP signature */ - const BMP_SIGNATURE = "\x42\x4D"; - - /** qvar int BMP dimensions offset */ - const BMP_DIMENSIONS_OFFSET = 18; - - /** @var int TIF header size. The header might be larger but the dimensions - * should be in the first 512 bytes */ - const TIF_HEADER_SIZE = 512; - - /** @var int TIF tag for image height */ - const TIF_TAG_IMAGE_HEIGHT = 257; - - /** @var int TIF tag for image width */ - const TIF_TAG_IMAGE_WIDTH = 256; - - /** @var int TIF tag type for short */ - const TIF_TAG_TYPE_SHORT = 3; - - /** @var int TIF IFD entry size */ - const TIF_IFD_ENTRY_SIZE = 12; - - /** @var int IFF header size. Grab more than what should be needed to make - * sure we have the necessary data */ - const IFF_HEADER_SIZE = 32; - - /** @var string JPEG 2000 signature */ - const JPEG_2000_SIGNATURE = "\x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A"; - - /** @var array Size info that is returned */ - protected $size = array(); - - /** @var string Data retrieved from remote */ - protected $data = ''; - - /** - * Get image dimensions of supplied image - * - * @param string $file Path to image that should be checked - * @param string $type Mimetype of image - * @return array|bool Array with image dimensions if successful, false if not - */ - public function get_imagesize($file, $type = '') - { - // Reset values - $this->reset_values(); - - // Treat image type as unknown if extension or mime type is unknown - if (!preg_match('/\.([a-z0-9]+)$/i', $file, $match) && empty($type)) - { - $this->get_imagesize_unknown_type($file); - } - else - { - $extension = (isset($match[1])) ? $match[1] : preg_replace('/.+\/([a-z0-9-.]+)$/i', '$1', $type); - - // Reset size info - $this->size = array(); - - switch ($extension) - { - case 'png': - $this->get_png_size($file); - break; - - case 'gif': - $this->get_gif_size($file); - break; - - case 'jpeg': - case 'jpg': - case 'jpe': - case 'jif': - case 'jfif': - case 'jfi': - $this->get_jpeg_size($file); - break; - - case 'jp2': - case 'j2k': - case 'jpf': - case 'jpg2': - case 'jpx': - case 'jpm': - $this->get_jp2_size($file); - break; - - case 'psd': - case 'photoshop': - $this->get_psd_size($file); - break; - - case 'bmp': - $this->get_bmp_size($file); - break; - - case 'tif': - case 'tiff': - // get_tif_size() sets mime type - $this->get_tif_size($file); - break; - - case 'wbm': - case 'wbmp': - case 'vnd.wap.wbmp': - $this->get_wbmp_size($file); - break; - - case 'iff': - case 'x-iff': - $this->get_iff_size($file); - break; - - default: - return false; - } - } - - return sizeof($this->size) > 1 ? $this->size : false; - } - - /** - * Get dimensions of image if type is unknown - * - * @param string $filename Path to file - */ - protected function get_imagesize_unknown_type($filename) - { - // Grab the maximum amount of bytes we might need - $data = $this->get_image($filename, 0, self::JPG_MAX_HEADER_SIZE, false); - - if ($data !== false) - { - $class_methods = preg_grep('/get_([a-z0-9]+)_size/i', get_class_methods($this)); - - foreach ($class_methods as $method) - { - call_user_func_array(array($this, $method), array($filename)); - - if (sizeof($this->size) > 1) - { - break; - } - } - } - } - - /** - * Reset values to default - */ - protected function reset_values() - { - $this->size = array(); - $this->data = ''; - } - - /** - * Set mime type based on supplied image - * - * @param int $type Type of image - */ - protected function set_image_type($type) - { - $this->size['type'] = $type; - } - - /** - * Get image from specified path/source - * - * @param string $filename Path to image - * @param int $offset Offset at which reading of the image should start - * @param int $length Maximum length that should be read - * @param bool $force_length True if the length needs to be the specified - * length, false if not. Default: true - * - * @return bool|string Image data or false if result was empty - */ - protected function get_image($filename, $offset, $length, $force_length = true) - { - if (empty($this->data)) - { - $this->data = @file_get_contents($filename, null, null, $offset, $length); - } - - // Force length to expected one. Return false if data length - // is smaller than expected length - if ($force_length === true) - { - return (strlen($this->data) < $length) ? false : substr($this->data, $offset, $length) ; - } - - return empty($this->data) ? false : $this->data; - } - - /** - * Get dimensions of PNG image - * - * @param string $filename Filename of image - * - * @return array|bool Array with image dimensions if successful, false if not - */ - protected function get_png_size($filename) - { - // Retrieve image data including the header, the IHDR tag, and the - // following 2 chunks for the image width and height - $data = $this->get_image($filename, 0, self::PNG_IHDR_OFFSET + 3 * self::LONG_SIZE); - - // Check if header fits expected format specified by RFC 2083 - if (substr($data, 0, self::PNG_IHDR_OFFSET - self::LONG_SIZE) !== self::PNG_HEADER || substr($data, self::PNG_IHDR_OFFSET, self::LONG_SIZE) !== 'IHDR') - { - return; - } - - $this->size = unpack('Nwidth/Nheight', substr($data, self::PNG_IHDR_OFFSET + self::LONG_SIZE, self::LONG_SIZE * 2)); - - $this->set_image_type(IMAGETYPE_PNG); - } - - /** - * Get dimensions of GIF image - * - * @param string $filename Filename of image - * - * @return array|bool Array with image dimensions if successful, false if not - */ - protected function get_gif_size($filename) - { - // Get data needed for reading image dimensions as outlined by GIF87a - // and GIF89a specifications - $data = $this->get_image($filename, 0, self::GIF_HEADER_SIZE + self::SHORT_SIZE * 2); - - $type = substr($data, 0, self::GIF_HEADER_SIZE); - if ($type !== self::GIF87A_HEADER && $type !== self::GIF89A_HEADER) - { - return; - } - - $this->size = unpack('vwidth/vheight', substr($data, self::GIF_HEADER_SIZE, self::SHORT_SIZE * 2)); - - $this->set_image_type(IMAGETYPE_GIF); - } - - /** - * Get dimensions of JPG image - * - * @param string $filename Filename of image - * - * @return array|bool Array with image dimensions if successful, false if not - */ - protected function get_jpeg_size($filename) - { - // Do not force the data length - $data = $this->get_image($filename, 0, self::JPG_MAX_HEADER_SIZE, false); - - // Check if file is jpeg - if ($data[0] !== "\xFF" || $data[1] !== "\xD8") - { - return; - } - - // Look through file for SOF marker - for ($i = 2 * self::SHORT_SIZE; $i < strlen($data); $i++) - { - if ($data[$i] === "\xFF" && in_array($data[$i+1], array("\xC0", "\xC1", "\xC2", "\xC3", "\xC5", "\xC6", "\xC7", "\xC8", "\xC9", "\xCA", "\xCB", "\xCD", "\xCE", "\xCF"))) - { - // Extract size info from SOF marker - list(, $unpacked) = unpack("H*", substr($data, $i + self::SHORT_SIZE, 7)); - - // Get width and height from unpacked size info - $this->size = array( - 'width' => hexdec(substr($unpacked, 10, 4)), - 'height' => hexdec(substr($unpacked, 6, 4)), - ); - - break; - } - } - - $this->set_image_type(IMAGETYPE_JPEG); - } - - /** - * Get dimensions of PSD image - * - * @param string $filename Filename of image - * - * @return array|bool Array with image dimensions if successful, false if not - */ - protected function get_psd_size($filename) - { - $data = $this->get_image($filename, 0, self::PSD_HEADER_SIZE); - - if ($data === false) - { - return; - } - - // Offset for version info is length of header but version is only a - // 16-bit unsigned value - $version = unpack('n', substr($data, self::LONG_SIZE, 2)); - - // Check if supplied file is a PSD file - if (substr($data, 0, self::LONG_SIZE) !== self::PSD_SIGNATURE || $version[1] !== 1) - { - return; - } - - $this->size = unpack('Nheight/Nwidth', substr($data, self::PSD_DIMENSIONS_OFFSET, 2 * self::LONG_SIZE)); - - $this->set_image_type(IMAGETYPE_PSD); - } - - /** - * Get dimensions of BMP image - * - * @param string $filename Filename of image - * - * @return array|bool Array with image dimensions if successful, false if not - */ - protected function get_bmp_size($filename) - { - $data = $this->get_image($filename, 0, self::BMP_HEADER_SIZE); - - // Check if supplied file is a BMP file - if (substr($data, 0, 2) !== self::BMP_SIGNATURE) - { - return; - } - - $this->size = unpack('lwidth/lheight', substr($data, self::BMP_DIMENSIONS_OFFSET, 2 * self::LONG_SIZE)); - - $this->set_image_type(IMAGETYPE_BMP); - } - - /** - * Get dimensions of TIF/TIFF image - * - * @param string $filename Filename of image - * - * @return array|bool Array with image dimensions if successful, false if not - */ - protected function get_tif_size($filename) - { - // Do not force length of header - $data = $this->get_image($filename, 0, self::TIF_HEADER_SIZE, false); - - $signature = substr($data, 0, self::SHORT_SIZE); - - if ($signature !== "II" && $signature !== "MM") - { - return; - } - - if ($signature === "II") - { - $type_long = 'V'; - $type_short = 'v'; - $this->set_image_type(IMAGETYPE_TIFF_II); - } - else - { - $type_long = 'N'; - $type_short = 'n'; - $this->set_image_type(IMAGETYPE_TIFF_MM); - } - - // Get offset of IFD - list(, $offset) = unpack($type_long, substr($data, self::LONG_SIZE, self::LONG_SIZE)); - - // Get size of IFD - list(, $size_ifd) = unpack($type_short, substr($data, $offset, self::SHORT_SIZE)); - - // Skip 2 bytes that define the IFD size - $offset += self::SHORT_SIZE; - - // Filter through IFD - for ($i = 0; $i < $size_ifd; $i++) - { - // Get IFD tag - $type = unpack($type_short, substr($data, $offset, self::SHORT_SIZE)); - - // Get field type of tag - $field_type = unpack($type_short . 'type', substr($data, $offset + self::SHORT_SIZE, self::SHORT_SIZE)); - - // Get IFD entry - $ifd_value = substr($data, $offset + 2 * self::LONG_SIZE, self::LONG_SIZE); - - // Get actual dimensions from IFD - if ($type[1] === self::TIF_TAG_IMAGE_HEIGHT) - { - $this->size = array_merge($this->size, ($field_type['type'] === self::TIF_TAG_TYPE_SHORT) ? unpack($type_short . 'height', $ifd_value) : unpack($type_long . 'height', $ifd_value)); - } - else if ($type[1] === self::TIF_TAG_IMAGE_WIDTH) - { - $this->size = array_merge($this->size, ($field_type['type'] === self::TIF_TAG_TYPE_SHORT) ? unpack($type_short .'width', $ifd_value) : unpack($type_long . 'width', $ifd_value)); - } - - $offset += self::TIF_IFD_ENTRY_SIZE; - } - } - - /** - * Get dimensions of WBMP image - * - * @param string $filename Filename of image - * - * @return array|bool Array with image dimensions if successful, false if not - */ - protected function get_wbmp_size($filename) - { - $data = $this->get_image($filename, 0, self::LONG_SIZE); - - // Check if image is WBMP - if (ord($data[0]) !== 0 || ord($data[1]) !== 0 || $data === substr(self::JPEG_2000_SIGNATURE, 0, 4)) - { - return; - } - - $this->size = unpack('Cwidth/Cheight', substr($data, self::SHORT_SIZE, self::SHORT_SIZE)); - - $this->set_image_type(IMAGETYPE_WBMP); - } - - /** - * Get dimensions of IFF image - * - * @param string $filename Filename of image - * - * @return array|bool Array with image dimensions if successful, false if not - */ - protected function get_iff_size($filename) - { - $data = $this->get_image($filename, 0, self::IFF_HEADER_SIZE); - - $signature = substr($data, 0, self::LONG_SIZE ); - - // Check if image is IFF - if ($signature !== 'FORM' && $signature !== 'FOR4') - { - return; - } - - // Amiga version of IFF - if ($signature === 'FORM') - { - $btmhd_position = strpos($data, 'BMHD'); - $this->size = unpack('nwidth/nheight', substr($data, $btmhd_position + 2 * self::LONG_SIZE, self::LONG_SIZE)); - } - // Maya version - else - { - $btmhd_position = strpos($data, 'BHD'); - $this->size = unpack('Nwidth/Nheight', substr($data, $btmhd_position + 2 * self::LONG_SIZE - 1, self::LONG_SIZE * 2)); - } - - $this->set_image_type(IMAGETYPE_IFF); - } - - /** - * Get dimensions of JPEG 2000 image - * - * @param string $filename Filename of image - * - * @return array|bool Array with image dimensions if successful, false if not - */ - protected function get_jp2_size($filename) - { - $data = $this->get_image($filename, 0, self::JPG_MAX_HEADER_SIZE, false); - - // Check if file is jpeg 2000 - if (substr($data, 0, strlen(self::JPEG_2000_SIGNATURE)) !== self::JPEG_2000_SIGNATURE) - { - return; - } - - // Get SOC position before starting to search for SIZ - $soc_position = strpos($data, "\xFF\x4F"); - - // Make sure we do not get SIZ before SOC - $data = substr($data, $soc_position); - - $siz_position = strpos($data, "\xFF\x51"); - - // Remove SIZ and everything before - $data = substr($data, $siz_position + self::SHORT_SIZE); - - // Acquire size info from data - $this->size = unpack('Nwidth/Nheight', substr($data, self::LONG_SIZE, self::LONG_SIZE * 2)); - - $this->set_image_type(IMAGETYPE_JPEG2000); - } -} -- cgit v1.2.1 From 102b6c2df377759de8b17f3fe6fa7366fb7385dd Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 28 Apr 2015 02:40:33 +0200 Subject: [ticket/10922] Added support for body and subject in email BBCode PHPBB3-10922 --- phpBB/phpbb/textformatter/s9e/factory.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 9576abe1f0..a1bd43e40e 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -68,7 +68,7 @@ class factory implements \phpbb\textformatter\cache_interface 'b' => '[B]{TEXT}[/B]', 'code' => '[CODE]{TEXT}[/CODE]', 'color' => '[COLOR={COLOR}]{TEXT}[/COLOR]', - 'email' => '[EMAIL={EMAIL;useContent}]{TEXT}[/EMAIL]', + 'email' => '[EMAIL={EMAIL;useContent} subject={TEXT;optional;postFilter=urlencode} body={TEXT;optional;postFilter=urlencode}]{TEXT}[/EMAIL]', 'flash' => '[FLASH={NUMBER1},{NUMBER2} width={NUMBER1;postFilter=#flashwidth} height={NUMBER2;postFilter=#flashheight} url={URL;useContent} /]', 'i' => '[I]{TEXT}[/I]', 'img' => '[IMG src={IMAGEURL;useContent}]', @@ -97,7 +97,18 @@ class factory implements \phpbb\textformatter\cache_interface 'img' => '{L_IMAGE}', 'size' => '', 'color' => '', - 'email' => '', + 'email' => ' + + mailto: + + + ? + subject= + &body= + + + + ', ); /** -- cgit v1.2.1 From 3f54fd49b5bf421852ceb2a54395d5ed353d2f29 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 28 Apr 2015 02:53:40 +0200 Subject: [ticket/10922] Replaced urlencode() with rawurlencode() RFC-6068 asks for percent-encoding so that seems more correct. Not sure about that one. PHPBB3-10922 --- phpBB/phpbb/textformatter/s9e/factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index a1bd43e40e..e07a1b52ca 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -68,7 +68,7 @@ class factory implements \phpbb\textformatter\cache_interface 'b' => '[B]{TEXT}[/B]', 'code' => '[CODE]{TEXT}[/CODE]', 'color' => '[COLOR={COLOR}]{TEXT}[/COLOR]', - 'email' => '[EMAIL={EMAIL;useContent} subject={TEXT;optional;postFilter=urlencode} body={TEXT;optional;postFilter=urlencode}]{TEXT}[/EMAIL]', + 'email' => '[EMAIL={EMAIL;useContent} subject={TEXT;optional;postFilter=rawurlencode} body={TEXT;optional;postFilter=rawurlencode}]{TEXT}[/EMAIL]', 'flash' => '[FLASH={NUMBER1},{NUMBER2} width={NUMBER1;postFilter=#flashwidth} height={NUMBER2;postFilter=#flashheight} url={URL;useContent} /]', 'i' => '[I]{TEXT}[/I]', 'img' => '[IMG src={IMAGEURL;useContent}]', -- cgit v1.2.1 From 57072a1e28061ff51148c7d6a0c47664f0060639 Mon Sep 17 00:00:00 2001 From: MateBartus Date: Wed, 29 Apr 2015 00:13:29 +0200 Subject: [ticket/13793] Remove translation on throwing exceptions PHPBB3-13793 --- phpBB/phpbb/controller/exception.php | 2 +- phpBB/phpbb/controller/resolver.php | 18 +++++------------- phpBB/phpbb/extension/exception.php | 6 +----- phpBB/phpbb/extension/manager.php | 7 ++----- phpBB/phpbb/extension/metadata_manager.php | 26 +++++++++----------------- phpBB/phpbb/notification/exception.php | 6 +----- phpBB/phpbb/notification/manager.php | 2 +- 7 files changed, 20 insertions(+), 47 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/controller/exception.php b/phpBB/phpbb/controller/exception.php index 437558b06a..e227c7c37b 100644 --- a/phpBB/phpbb/controller/exception.php +++ b/phpBB/phpbb/controller/exception.php @@ -16,6 +16,6 @@ namespace phpbb\controller; /** * Controller exception class */ -class exception extends \RuntimeException +class exception extends \phpbb\exception\runtime_exception { } diff --git a/phpBB/phpbb/controller/resolver.php b/phpBB/phpbb/controller/resolver.php index 948a6a218c..4f432c3323 100644 --- a/phpBB/phpbb/controller/resolver.php +++ b/phpBB/phpbb/controller/resolver.php @@ -22,12 +22,6 @@ use Symfony\Component\HttpFoundation\Request; */ class resolver implements ControllerResolverInterface { - /** - * User object - * @var \phpbb\user - */ - protected $user; - /** * ContainerInterface object * @var ContainerInterface @@ -55,14 +49,12 @@ class resolver implements ControllerResolverInterface /** * Construct method * - * @param \phpbb\user $user User Object * @param ContainerInterface $container ContainerInterface object * @param string $phpbb_root_path Relative path to phpBB root * @param \phpbb\template\template $template */ - public function __construct(\phpbb\user $user, ContainerInterface $container, $phpbb_root_path, \phpbb\template\template $template = null) + public function __construct(ContainerInterface $container, $phpbb_root_path, \phpbb\template\template $template = null) { - $this->user = $user; $this->container = $container; $this->template = $template; $this->type_cast_helper = new \phpbb\request\type_cast_helper(); @@ -82,20 +74,20 @@ class resolver implements ControllerResolverInterface if (!$controller) { - throw new \phpbb\controller\exception($this->user->lang['CONTROLLER_NOT_SPECIFIED']); + throw new \phpbb\controller\exception('CONTROLLER_NOT_SPECIFIED'); } // Require a method name along with the service name if (stripos($controller, ':') === false) { - throw new \phpbb\controller\exception($this->user->lang['CONTROLLER_METHOD_NOT_SPECIFIED']); + throw new \phpbb\controller\exception('CONTROLLER_METHOD_NOT_SPECIFIED'); } list($service, $method) = explode(':', $controller); if (!$this->container->has($service)) { - throw new \phpbb\controller\exception($this->user->lang('CONTROLLER_SERVICE_UNDEFINED', $service)); + throw new \phpbb\controller\exception('CONTROLLER_SERVICE_UNDEFINED', array($service)); } $controller_object = $this->container->get($service); @@ -166,7 +158,7 @@ class resolver implements ControllerResolverInterface } else { - throw new \phpbb\controller\exception($this->user->lang('CONTROLLER_ARGUMENT_VALUE_MISSING', $param->getPosition() + 1, get_class($object) . ':' . $method, $param->name)); + throw new \phpbb\controller\exception('CONTROLLER_ARGUMENT_VALUE_MISSING', array($param->getPosition() + 1, get_class($object) . ':' . $method, $param->name)); } } diff --git a/phpBB/phpbb/extension/exception.php b/phpBB/phpbb/extension/exception.php index 3f7d251a4e..9050449bf1 100644 --- a/phpBB/phpbb/extension/exception.php +++ b/phpBB/phpbb/extension/exception.php @@ -16,10 +16,6 @@ namespace phpbb\extension; /** * Exception class for metadata */ -class exception extends \UnexpectedValueException +class exception extends \phpbb\exception\runtime_exception { - public function __toString() - { - return $this->getMessage(); - } } diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 40fda74065..98d2d27278 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -26,7 +26,6 @@ class manager protected $db; protected $config; protected $cache; - protected $user; protected $php_ext; protected $extensions; protected $extension_table; @@ -40,14 +39,13 @@ class manager * @param \phpbb\db\driver\driver_interface $db A database connection * @param \phpbb\config\config $config Config object * @param \phpbb\filesystem\filesystem_interface $filesystem - * @param \phpbb\user $user User object * @param string $extension_table The name of the table holding extensions * @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $php_ext php file extension, defaults to php * @param \phpbb\cache\driver\driver_interface $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\user $user, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') { $this->cache = $cache; $this->cache_name = $cache_name; @@ -58,7 +56,6 @@ class manager $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; - $this->user = $user; $this->extensions = ($this->cache) ? $this->cache->get($this->cache_name) : false; @@ -154,7 +151,7 @@ class manager */ public function create_extension_metadata_manager($name, \phpbb\template\template $template) { - return new \phpbb\extension\metadata_manager($name, $this->config, $this, $template, $this->user, $this->phpbb_root_path); + return new \phpbb\extension\metadata_manager($name, $this->config, $this, $template, $this->phpbb_root_path); } /** diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index a64d88fe39..4f080647c8 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -36,12 +36,6 @@ class metadata_manager */ protected $template; - /** - * phpBB User instance - * @var \phpbb\user - */ - protected $user; - /** * phpBB root path * @var string @@ -73,15 +67,13 @@ class metadata_manager * @param \phpbb\config\config $config phpBB Config instance * @param \phpbb\extension\manager $extension_manager An instance of the phpBB extension manager * @param \phpbb\template\template $template phpBB Template instance - * @param \phpbb\user $user User instance * @param string $phpbb_root_path Path to the phpbb includes directory. */ - public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, \phpbb\user $user, $phpbb_root_path) + public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, $phpbb_root_path) { $this->config = $config; $this->extension_manager = $extension_manager; $this->template = $template; - $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; $this->ext_name = $ext_name; @@ -149,7 +141,7 @@ class metadata_manager if (!file_exists($this->metadata_file)) { - throw new \phpbb\extension\exception($this->user->lang('FILE_NOT_FOUND', $this->metadata_file)); + throw new \phpbb\extension\exception('FILE_NOT_FOUND', array($this->metadata_file)); } } @@ -163,18 +155,18 @@ class metadata_manager { if (!file_exists($this->metadata_file)) { - throw new \phpbb\extension\exception($this->user->lang('FILE_NOT_FOUND', $this->metadata_file)); + throw new \phpbb\extension\exception('FILE_NOT_FOUND', array($this->metadata_file)); } else { if (!($file_contents = file_get_contents($this->metadata_file))) { - throw new \phpbb\extension\exception($this->user->lang('FILE_CONTENT_ERR', $this->metadata_file)); + throw new \phpbb\extension\exception('FILE_CONTENT_ERR', array($this->metadata_file)); } if (($metadata = json_decode($file_contents, true)) === null) { - throw new \phpbb\extension\exception($this->user->lang('FILE_JSON_DECODE_ERR', $this->metadata_file)); + throw new \phpbb\extension\exception('FILE_JSON_DECODE_ERR', array($this->metadata_file)); } array_walk_recursive($metadata, array($this, 'sanitize_json')); @@ -246,12 +238,12 @@ class metadata_manager { if (!isset($this->metadata[$name])) { - throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', $name)); + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array($name)); } if (!preg_match($fields[$name], $this->metadata[$name])) { - throw new \phpbb\extension\exception($this->user->lang('META_FIELD_INVALID', $name)); + throw new \phpbb\extension\exception('META_FIELD_INVALID', array($name)); } } break; @@ -270,14 +262,14 @@ class metadata_manager { if (empty($this->metadata['authors'])) { - throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'authors')); + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('authors')); } foreach ($this->metadata['authors'] as $author) { if (!isset($author['name'])) { - throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'author name')); + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('author name')); } } diff --git a/phpBB/phpbb/notification/exception.php b/phpBB/phpbb/notification/exception.php index 83c4526df7..e416438061 100644 --- a/phpBB/phpbb/notification/exception.php +++ b/phpBB/phpbb/notification/exception.php @@ -17,10 +17,6 @@ namespace phpbb\notification; * Notifications exception */ -class exception extends \Exception +class exception extends \phpbb\exception\runtime_exception { - public function __toString() - { - return $this->getMessage(); - } } diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index db92170dd8..38d7a13165 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -943,7 +943,7 @@ class manager { if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name])) { - throw new \phpbb\notification\exception($this->user->lang('NOTIFICATION_TYPE_NOT_EXIST', $notification_type_name)); + throw new \phpbb\notification\exception('NOTIFICATION_TYPE_NOT_EXIST', array($notification_type_name)); } $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array( -- cgit v1.2.1 From 179a4700221aa49071b07d638c44b9326c7a14a8 Mon Sep 17 00:00:00 2001 From: MateBartus Date: Tue, 14 Apr 2015 02:31:23 +0200 Subject: [ticket/13762] Moving language related functionality into a separate class PHPBB3-13762 --- phpBB/phpbb/captcha/plugins/captcha_abstract.php | 2 +- .../exception/invalid_plural_rule_exception.php | 22 + .../language/exception/language_exception.php | 22 + .../language/exception/language_file_not_found.php | 22 + phpBB/phpbb/language/language.php | 562 +++++++++++++++++++++ phpBB/phpbb/language/language_file_helper.php | 71 +++ phpBB/phpbb/language/language_file_loader.php | 212 ++++++++ phpBB/phpbb/user.php | 336 ++++-------- 8 files changed, 1015 insertions(+), 234 deletions(-) create mode 100644 phpBB/phpbb/language/exception/invalid_plural_rule_exception.php create mode 100644 phpBB/phpbb/language/exception/language_exception.php create mode 100644 phpBB/phpbb/language/exception/language_file_not_found.php create mode 100644 phpBB/phpbb/language/language.php create mode 100644 phpBB/phpbb/language/language_file_helper.php create mode 100644 phpBB/phpbb/language/language_file_loader.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/captcha/plugins/captcha_abstract.php b/phpBB/phpbb/captcha/plugins/captcha_abstract.php index 799947a84e..b29f144f97 100644 --- a/phpBB/phpbb/captcha/plugins/captcha_abstract.php +++ b/phpBB/phpbb/captcha/plugins/captcha_abstract.php @@ -195,7 +195,7 @@ abstract class captcha_abstract { global $config, $db, $user; - if (empty($user->lang)) + if (!$user->is_setup()) { $user->setup(); } diff --git a/phpBB/phpbb/language/exception/invalid_plural_rule_exception.php b/phpBB/phpbb/language/exception/invalid_plural_rule_exception.php new file mode 100644 index 0000000000..94e3466208 --- /dev/null +++ b/phpBB/phpbb/language/exception/invalid_plural_rule_exception.php @@ -0,0 +1,22 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\language\exception; + +/** + * Thrown when nonexistent plural rule is specified + */ +class invalid_plural_rule_exception extends language_exception +{ + +} diff --git a/phpBB/phpbb/language/exception/language_exception.php b/phpBB/phpbb/language/exception/language_exception.php new file mode 100644 index 0000000000..b1258414aa --- /dev/null +++ b/phpBB/phpbb/language/exception/language_exception.php @@ -0,0 +1,22 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\language\exception; + +/** + * Base exception class for language exceptions + */ +class language_exception extends \phpbb\exception\runtime_exception +{ + +} diff --git a/phpBB/phpbb/language/exception/language_file_not_found.php b/phpBB/phpbb/language/exception/language_file_not_found.php new file mode 100644 index 0000000000..89364267eb --- /dev/null +++ b/phpBB/phpbb/language/exception/language_file_not_found.php @@ -0,0 +1,22 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\language\exception; + +/** + * This exception is thrown when the language file is not found + */ +class language_file_not_found extends language_exception +{ + +} diff --git a/phpBB/phpbb/language/language.php b/phpBB/phpbb/language/language.php new file mode 100644 index 0000000000..9c9a3b8df1 --- /dev/null +++ b/phpBB/phpbb/language/language.php @@ -0,0 +1,562 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\language; + +use phpbb\language\exception\invalid_plural_rule_exception; + +/** + * Wrapper class for loading translations + */ +class language +{ + /** + * Global fallback language + * + * ISO code of the language to fallback to when the specified language entries + * cannot be found. + * + * @var string + */ + const FALLBACK_LANGUAGE = 'en'; + + /** + * @var array List of common language files + */ + protected $common_language_files; + + /** + * @var bool + */ + protected $common_language_files_loaded; + + /** + * @var string ISO code of the default board language + */ + protected $default_language; + + /** + * @var string ISO code of the User's language + */ + protected $user_language; + + /** + * @var array Language fallback array (the order is important) + */ + protected $language_fallback; + + /** + * @var array Array of language variables + */ + protected $lang; + + /** + * @var array Loaded language sets + */ + protected $loaded_language_sets; + + /** + * @var \phpbb\language\language_file_loader Language file loader + */ + protected $loader; + + /** + * Constructor + * + * @param \phpbb\language\language_file_loader $loader Language file loader + */ + public function __construct(language_file_loader $loader) + { + $this->loader = $loader; + + // Set up default information + $this->user_language = false; + $this->default_language = false; + $this->lang = array( + // For BC with user::help array + '__help' => array(), + ); + $this->loaded_language_sets = array( + 'core' => array(), + 'ext' => array(), + ); + + // Common language files + $this->common_language_files = array( + 'common', + ); + $this->common_language_files_loaded = false; + + $this->language_fallback = array(self::FALLBACK_LANGUAGE); + } + + /** + * Function to set user's language to display. + * + * @param string $user_lang_iso ISO code of the User's language + */ + public function set_user_language($user_lang_iso) + { + $this->user_language = $user_lang_iso; + + $this->set_fallback_array(); + } + + /** + * Function to set the board's default language to display. + * + * @param string $default_lang_iso ISO code of the board's default language + */ + public function set_default_language($default_lang_iso) + { + $this->default_language = $default_lang_iso; + + $this->set_fallback_array(); + } + + /** + * Returns language array + * + * Note: This function is needed for the BC purposes, until \phpbb\user::lang[] is + * not removed. + * + * @return array Array of loaded language strings + */ + public function get_lang_array() + { + // Load common language files if they not loaded yet + if (!$this->common_language_files_loaded) + { + $this->load_common_language_files(); + } + + return $this->lang; + } + + /** + * Add Language Items + * + * Note: $use_help is assigned where needed (only use them to force inclusion). + * + * Examples: + * + * $component = array('posting'); + * $component = array('posting', 'viewtopic') + * $component = 'posting' + * + * + * @param string|array $component The name of the language component to load + * @param string|null $extension_name Name of the extension to load component from, or null for core file + */ + public function add_lang($component, $extension_name = null) + { + // Load common language files if they not loaded yet + // This needs to be here to correctly merge language arrays + if (!$this->common_language_files_loaded) + { + $this->load_common_language_files(); + } + + if (!is_array($component)) + { + if (!is_null($extension_name)) + { + $this->load_extension($extension_name, $component); + } + else + { + $this->load_core_file($component); + } + } + else + { + foreach ($component as $lang_file) + { + $this->add_lang($lang_file, $extension_name); + } + } + } + + /** + * Advanced language substitution + * + * Function to mimic sprintf() with the possibility of using phpBB's language system to substitute nullar/singular/plural forms. + * Params are the language key and the parameters to be substituted. + * This function/functionality is inspired by SHS` and Ashe. + * + * Example call: $user->lang('NUM_POSTS_IN_QUEUE', 1); + * + * If the first parameter is an array, the elements are used as keys and subkeys to get the language entry: + * Example: $user->lang(array('datetime', 'AGO'), 1) uses $user->lang['datetime']['AGO'] as language entry. + * + * @return string Return localized string or the language key if the translation is not available + */ + public function lang() + { + // Load common language files if they not loaded yet + if (!$this->common_language_files_loaded) + { + $this->load_common_language_files(); + } + + $args = func_get_args(); + $key = $args[0]; + + if (is_array($key)) + { + $lang = &$this->lang[array_shift($key)]; + + foreach ($key as $_key) + { + $lang = &$lang[$_key]; + } + } + else + { + $lang = &$this->lang[$key]; + } + + // Return if language string does not exist + if (!isset($lang) || (!is_string($lang) && !is_array($lang))) + { + return $key; + } + + // If the language entry is a string, we simply mimic sprintf() behaviour + if (is_string($lang)) + { + if (sizeof($args) == 1) + { + return $lang; + } + + // Replace key with language entry and simply pass along... + $args[0] = $lang; + return call_user_func_array('sprintf', $args); + } + else if (sizeof($lang) == 0) + { + // If the language entry is an empty array, we just return the language key + return $args[0]; + } + + // It is an array... now handle different nullar/singular/plural forms + $key_found = false; + + // We now get the first number passed and will select the key based upon this number + for ($i = 1, $num_args = sizeof($args); $i < $num_args; $i++) + { + if (is_int($args[$i]) || is_float($args[$i])) + { + if ($args[$i] == 0 && isset($lang[0])) + { + // We allow each translation using plural forms to specify a version for the case of 0 things, + // so that "0 users" may be displayed as "No users". + $key_found = 0; + break; + } + else + { + $use_plural_form = $this->get_plural_form($args[$i]); + if (isset($lang[$use_plural_form])) + { + // The key we should use exists, so we use it. + $key_found = $use_plural_form; + } + else + { + // If the key we need to use does not exist, we fall back to the previous one. + $numbers = array_keys($lang); + + foreach ($numbers as $num) + { + if ($num > $use_plural_form) + { + break; + } + + $key_found = $num; + } + } + break; + } + } + } + + // Ok, let's check if the key was found, else use the last entry (because it is mostly the plural form) + if ($key_found === false) + { + $numbers = array_keys($lang); + $key_found = end($numbers); + } + + // Use the language string we determined and pass it to sprintf() + $args[0] = $lang[$key_found]; + return call_user_func_array('sprintf', $args); + } + + /** + * Loads common language files + */ + protected function load_common_language_files() + { + if (!$this->common_language_files_loaded) + { + foreach ($this->common_language_files as $lang_file) + { + $this->load_core_file($lang_file); + } + + $this->common_language_files_loaded = true; + } + } + + /** + * Determine which plural form we should use. + * + * For some languages this is not as simple as for English. + * + * @param int|float $number The number we want to get the plural case for. Float numbers are floored. + * @param int|bool $force_rule False to use the plural rule of the language package + * or an integer to force a certain plural rule + * + * @return int The plural-case we need to use for the number plural-rule combination + * + * @throws \phpbb\language\exception\invalid_plural_rule_exception When $force_rule has an invalid value + */ + public function get_plural_form($number, $force_rule = false) + { + $number = (int) $number; + $plural_rule = ($force_rule !== false) ? $force_rule : ((isset($this->lang['PLURAL_RULE'])) ? $this->lang['PLURAL_RULE'] : 1); + + if ($plural_rule > 15 || $plural_rule < 0) + { + throw new invalid_plural_rule_exception('INVALID_PLURAL_RULE', array( + 'plural_rule' => $plural_rule, + )); + } + + /** + * The following plural rules are based on a list published by the Mozilla Developer Network + * https://developer.mozilla.org/en/Localization_and_Plurals + */ + switch ($plural_rule) + { + case 0: + /** + * Families: Asian (Chinese, Japanese, Korean, Vietnamese), Persian, Turkic/Altaic (Turkish), Thai, Lao + * 1 - everything: 0, 1, 2, ... + */ + return 1; + + case 1: + /** + * Families: Germanic (Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish), Finno-Ugric (Estonian, Finnish, Hungarian), Language isolate (Basque), Latin/Greek (Greek), Semitic (Hebrew), Romanic (Italian, Portuguese, Spanish, Catalan) + * 1 - 1 + * 2 - everything else: 0, 2, 3, ... + */ + return ($number === 1) ? 1 : 2; + + case 2: + /** + * Families: Romanic (French, Brazilian Portuguese) + * 1 - 0, 1 + * 2 - everything else: 2, 3, ... + */ + return (($number === 0) || ($number === 1)) ? 1 : 2; + + case 3: + /** + * Families: Baltic (Latvian) + * 1 - 0 + * 2 - ends in 1, not 11: 1, 21, ... 101, 121, ... + * 3 - everything else: 2, 3, ... 10, 11, 12, ... 20, 22, ... + */ + return ($number === 0) ? 1 : ((($number % 10 === 1) && ($number % 100 != 11)) ? 2 : 3); + + case 4: + /** + * Families: Celtic (Scottish Gaelic) + * 1 - is 1 or 11: 1, 11 + * 2 - is 2 or 12: 2, 12 + * 3 - others between 3 and 19: 3, 4, ... 10, 13, ... 18, 19 + * 4 - everything else: 0, 20, 21, ... + */ + return ($number === 1 || $number === 11) ? 1 : (($number === 2 || $number === 12) ? 2 : (($number >= 3 && $number <= 19) ? 3 : 4)); + + case 5: + /** + * Families: Romanic (Romanian) + * 1 - 1 + * 2 - is 0 or ends in 01-19: 0, 2, 3, ... 19, 101, 102, ... 119, 201, ... + * 3 - everything else: 20, 21, ... + */ + return ($number === 1) ? 1 : ((($number === 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 2 : 3); + + case 6: + /** + * Families: Baltic (Lithuanian) + * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, ... + * 2 - ends in 0 or ends in 10-20: 0, 10, 11, 12, ... 19, 20, 30, 40, ... + * 3 - everything else: 2, 3, ... 8, 9, 22, 23, ... 29, 32, 33, ... + */ + return (($number % 10 === 1) && ($number % 100 != 11)) ? 1 : ((($number % 10 < 2) || (($number % 100 >= 10) && ($number % 100 < 20))) ? 2 : 3); + + case 7: + /** + * Families: Slavic (Croatian, Serbian, Russian, Ukrainian) + * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, ... + * 2 - ends in 2-4, not 12-14: 2, 3, 4, 22, 23, 24, 32, ... + * 3 - everything else: 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 26, ... + */ + return (($number % 10 === 1) && ($number % 100 != 11)) ? 1 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 2 : 3); + + case 8: + /** + * Families: Slavic (Slovak, Czech) + * 1 - 1 + * 2 - 2, 3, 4 + * 3 - everything else: 0, 5, 6, 7, ... + */ + return ($number === 1) ? 1 : ((($number >= 2) && ($number <= 4)) ? 2 : 3); + + case 9: + /** + * Families: Slavic (Polish) + * 1 - 1 + * 2 - ends in 2-4, not 12-14: 2, 3, 4, 22, 23, 24, 32, ... 104, 122, ... + * 3 - everything else: 0, 5, 6, ... 11, 12, 13, 14, 15, ... 20, 21, 25, ... + */ + return ($number === 1) ? 1 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 2 : 3); + + case 10: + /** + * Families: Slavic (Slovenian, Sorbian) + * 1 - ends in 01: 1, 101, 201, ... + * 2 - ends in 02: 2, 102, 202, ... + * 3 - ends in 03-04: 3, 4, 103, 104, 203, 204, ... + * 4 - everything else: 0, 5, 6, 7, 8, 9, 10, 11, ... + */ + return ($number % 100 === 1) ? 1 : (($number % 100 === 2) ? 2 : ((($number % 100 === 3) || ($number % 100 === 4)) ? 3 : 4)); + + case 11: + /** + * Families: Celtic (Irish Gaeilge) + * 1 - 1 + * 2 - 2 + * 3 - is 3-6: 3, 4, 5, 6 + * 4 - is 7-10: 7, 8, 9, 10 + * 5 - everything else: 0, 11, 12, ... + */ + return ($number === 1) ? 1 : (($number === 2) ? 2 : (($number >= 3 && $number <= 6) ? 3 : (($number >= 7 && $number <= 10) ? 4 : 5))); + + case 12: + /** + * Families: Semitic (Arabic) + * 1 - 1 + * 2 - 2 + * 3 - ends in 03-10: 3, 4, ... 10, 103, 104, ... 110, 203, 204, ... + * 4 - ends in 11-99: 11, ... 99, 111, 112, ... + * 5 - everything else: 100, 101, 102, 200, 201, 202, ... + * 6 - 0 + */ + return ($number === 1) ? 1 : (($number === 2) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : (($number != 0) ? 5 : 6)))); + + case 13: + /** + * Families: Semitic (Maltese) + * 1 - 1 + * 2 - is 0 or ends in 01-10: 0, 2, 3, ... 9, 10, 101, 102, ... + * 3 - ends in 11-19: 11, 12, ... 18, 19, 111, 112, ... + * 4 - everything else: 20, 21, ... + */ + return ($number === 1) ? 1 : ((($number === 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 2 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 3 : 4)); + + case 14: + /** + * Families: Slavic (Macedonian) + * 1 - ends in 1: 1, 11, 21, ... + * 2 - ends in 2: 2, 12, 22, ... + * 3 - everything else: 0, 3, 4, ... 10, 13, 14, ... 20, 23, ... + */ + return ($number % 10 === 1) ? 1 : (($number % 10 === 2) ? 2 : 3); + + case 15: + /** + * Families: Icelandic + * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, 131, ... + * 2 - everything else: 0, 2, 3, ... 10, 11, 12, ... 20, 22, ... + */ + return (($number % 10 === 1) && ($number % 100 != 11)) ? 1 : 2; + } + } + + /** + * Returns language fallback data + * + * @return array + */ + protected function set_fallback_array() + { + $fallback_array = array(); + + if ($this->user_language !== false) + { + $fallback_array[] = $this->user_language; + } + + if ($this->default_language !== false) + { + $fallback_array[] = $this->default_language; + } + + $fallback_array[] = self::FALLBACK_LANGUAGE; + + $this->language_fallback = $fallback_array; + } + + /** + * Load core language file + * + * @param string $component Name of the component to load + */ + protected function load_core_file($component) + { + // Check if the component is already loaded + if (isset($this->loaded_language_sets['core'][$component])) + { + return; + } + + $this->loader->load($component, $this->language_fallback, $this->lang); + $this->loaded_language_sets['core'][$component] = true; + } + + /** + * Load extension language file + * + * @param string $extension_name Name of the extension to load language from + * @param string $component Name of the component to load + */ + protected function load_extension($extension_name, $component) + { + // Check if the component is already loaded + if (isset($this->loaded_language_sets['ext'][$extension_name][$component])) + { + return; + } + + $this->loader->load_extension($extension_name, $component, $this->language_fallback, $this->lang); + $this->loaded_language_sets['ext'][$extension_name][$component] = true; + } +} diff --git a/phpBB/phpbb/language/language_file_helper.php b/phpBB/phpbb/language/language_file_helper.php new file mode 100644 index 0000000000..18d7b62e21 --- /dev/null +++ b/phpBB/phpbb/language/language_file_helper.php @@ -0,0 +1,71 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\language; + +use Symfony\Component\Finder\Finder; + +/** + * Helper class for language file related functions + */ +class language_file_helper +{ + /** + * @var string Path to phpBB's root + */ + protected $phpbb_root_path; + + /** + * Constructor + * + * @param string $phpbb_root_path Path to phpBB's root + */ + public function __construct($phpbb_root_path) + { + $this->phpbb_root_path = $phpbb_root_path; + } + + /** + * Returns available languages + * + * @return array + */ + public function get_available_languages() + { + // Find available language packages + $finder = new Finder(); + $finder->files() + ->name('iso.txt') + ->depth('== 1') + ->in($this->phpbb_root_path . 'language'); + + $available_languages = array(); + foreach ($finder as $file) + { + $path = $file->getRelativePath(); + $info = explode("\n", $file->getContents()); + + $available_languages[] = array( + // Get the name of the directory containing iso.txt + 'iso' => $path, + + // Recover data from file + 'name' => trim($info[0]), + 'local_name' => trim($info[1]), + 'author' => trim($info[2]) + ); + } + + return $available_languages; + } +} diff --git a/phpBB/phpbb/language/language_file_loader.php b/phpBB/phpbb/language/language_file_loader.php new file mode 100644 index 0000000000..510a29279a --- /dev/null +++ b/phpBB/phpbb/language/language_file_loader.php @@ -0,0 +1,212 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\language; + +use \phpbb\language\exception\language_file_not_found; + +/** + * Language file loader + */ +class language_file_loader +{ + /** + * @var string Path to phpBB's root + */ + protected $phpbb_root_path; + + /** + * @var string Extension of PHP files + */ + protected $php_ext; + + /** + * @var \phpbb\extension\manager Extension manager + */ + protected $extension_manager; + + /** + * Constructor + * + * @param string $phpbb_root_path Path to phpBB's root + * @param string $php_ext Extension of PHP files + */ + public function __construct($phpbb_root_path, $php_ext) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + $this->extension_manager = null; + } + + /** + * Extension manager setter + * + * @param \phpbb\extension\manager $extension_manager Extension manager + */ + public function set_extension_manager(\phpbb\extension\manager $extension_manager) + { + $this->extension_manager = $extension_manager; + } + + /** + * Loads language array for the given component + * + * @param string $component Name of the language component + * @param string|array $locale ISO code of the language to load, or array of ISO codes if you want to + * specify additional language fallback steps + * @param array $lang Array reference containing language strings + */ + public function load($component, $locale, &$lang) + { + $locale = (array) $locale; + + // Determine path to language directory + $path = $this->phpbb_root_path . 'language/'; + + $this->load_file($path, $component, $locale, $lang); + } + + /** + * Loads language array for the given extension component + * + * @param string $extension Name of the extension + * @param string $component Name of the language component + * @param string|array $locale ISO code of the language to load, or array of ISO codes if you want to + * specify additional language fallback steps + * @param array $lang Array reference containing language strings + */ + public function load_extension($extension, $component, $locale, &$lang) + { + // Check if extension manager was loaded + if ($this->extension_manager === null) + { + // If not, let's return + return; + } + + $locale = (array) $locale; + + // Determine path to language directory + $path = $this->extension_manager->get_extension_path($extension, true) . 'language/'; + + $this->load_file($path, $component, $locale, $lang); + } + + /** + * Prepares language file loading + * + * @param string $path Path to search for file in + * @param string $component Name of the language component + * @param array $locale Array containing language fallback options + * @param array $lang Array reference of language strings + */ + protected function load_file($path, $component, $locale, &$lang) + { + // This is BC stuff and not the best idea as it makes language fallback + // implementation quite hard like below. + if (strpos($this->phpbb_root_path . $component, $path) === 0) + { + // Filter out the path + $path_diff = str_replace($path, '', dirname($this->phpbb_root_path . $component)); + $language_file = basename($component, '.' . $this->php_ext); + $component = ''; + + // This step is needed to resolve language/en/subdir style $component + // $path already points to the language base directory so we need to eliminate + // the first directory from the path (that should be the language directory) + $path_diff_parts = explode('/', $path_diff); + + if (sizeof($path_diff_parts) > 1) + { + array_shift($path_diff_parts); + $component = implode('/', $path_diff_parts) . '/'; + } + + $component .= $language_file; + } + + // Determine filename + $filename = $component . '.' . $this->php_ext; + + // Determine path to file + $file_path = $this->get_language_file_path($path, $filename, $locale); + + // Load language array + $this->load_language_file($file_path, $lang); + } + + /** + * This function implements language fallback logic + * + * @param string $path Path to language directory + * @param string $filename Filename to load language strings from + * + * @return string Relative path to language file + * + * @throws \phpbb\language\exception\language_file_not_exists When the path to the file cannot be resolved + */ + protected function get_language_file_path($path, $filename, $locales) + { + // Language fallback logic + foreach ($locales as $locale) + { + $language_file_path = $path . $locale . '/' . $filename; + + // If we are in install, try to use the updated version, when available + if (defined('IN_INSTALL')) + { + $install_language_path = str_replace('language/', 'install/update/new/language/', $language_file_path); + if (file_exists($install_language_path)) + { + return $install_language_path; + } + } + + if (file_exists($language_file_path)) + { + return $language_file_path; + } + } + + // The language file is not exist + throw new language_file_not_found('Language file ' . $language_file_path . ' couldn\'t be opened.'); + } + + /** + * Loads language file + * + * @param string $path Path to language file to load + * @param array $lang Reference of the array of language strings + */ + protected function load_language_file($path, &$lang) + { + // BC code for language files with help + $help = array(); + + // Do not suppress error if in DEBUG mode + if (defined('DEBUG')) + { + include $path; + } + else + { + @include $path; + } + + if (!empty($help)) + { + $lang['__help'] = array_merge($lang['__help'], $help); + } + } +} diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index 882e9cef26..c33070d6f4 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -21,8 +21,11 @@ namespace phpbb; */ class user extends \phpbb\session { - var $lang = array(); - var $help = array(); + /** + * @var \phpbb\language\language + */ + protected $language; + var $style = array(); var $date_format; @@ -42,35 +45,63 @@ class user extends \phpbb\session var $img_lang; var $img_array = array(); + /** @var bool */ + protected $is_setup_flag; + // Able to add new options (up to id 31) var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'sig_bbcode' => 15, 'sig_smilies' => 16, 'sig_links' => 17); /** * Constructor to set the lang path + * * @param string $datetime_class Class name of datetime class + * @param \phpbb\language\language $lang phpBB's Language loader */ - function __construct($datetime_class) + function __construct(\phpbb\language\language $lang, $datetime_class) { global $phpbb_root_path; $this->lang_path = $phpbb_root_path . 'language/'; + $this->language = $lang; $this->datetime = $datetime_class; + + $this->is_setup_flag = false; } /** - * Function to set custom language path (able to use directory outside of phpBB) - * - * @param string $lang_path New language path used. - * @access public - */ - function set_custom_lang_path($lang_path) + * Returns whether user::setup was called + * + * @return bool + */ + public function is_setup() { - $this->lang_path = $lang_path; + return $this->is_setup_flag; + } - if (substr($this->lang_path, -1) != '/') + /** + * Magic getter for BC compatibility + * + * Implement array access for user::lang. + * + * @param string $param_name Name of the BC component the user want to access + * + * @return array The appropriate array + * + * @deprecated 3.2.0-dev (To be removed: 4.0.0) + */ + public function __get($param_name) + { + if ($param_name === 'lang') + { + return $this->language->get_lang_array(); + } + else if ($param_name === 'help') { - $this->lang_path .= '/'; + $help_array = $this->language->get_lang_array(); + return $help_array['__help']; } + + return array(); } /** @@ -81,6 +112,8 @@ class user extends \phpbb\session global $db, $request, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache; global $phpbb_dispatcher; + $this->language->set_default_language($config['default_lang']); + if ($this->data['user_id'] != ANONYMOUS) { $user_lang_name = (file_exists($this->lang_path . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']); @@ -98,6 +131,7 @@ class user extends \phpbb\session { $lang_override = $request->variable($config['cookie_name'] . '_lang', '', true, \phpbb\request\request_interface::COOKIE); } + if ($lang_override) { $use_lang = basename($lang_override); @@ -108,6 +142,7 @@ class user extends \phpbb\session { $user_lang_name = basename($config['default_lang']); } + $user_date_format = $config['default_dateformat']; $user_timezone = $config['board_timezone']; @@ -187,6 +222,8 @@ class user extends \phpbb\session $this->lang_name = $user_lang_name; $this->date_format = $user_date_format; + $this->language->set_user_language($user_lang_name); + try { $this->timezone = new \DateTimeZone($user_timezone); @@ -197,17 +234,6 @@ class user extends \phpbb\session $this->timezone = new \DateTimeZone('UTC'); } - // We include common language file here to not load it every time a custom language file is included - $lang = &$this->lang; - - // Do not suppress error if in DEBUG mode - $include_result = (defined('DEBUG')) ? (include $this->lang_path . $this->lang_name . "/common.$phpEx") : (@include $this->lang_path . $this->lang_name . "/common.$phpEx"); - - if ($include_result === false) - { - die('Language file ' . $this->lang_path . $this->lang_name . "/common.$phpEx" . " couldn't be opened."); - } - $this->add_lang($lang_set); unset($lang_set); @@ -393,6 +419,8 @@ class user extends \phpbb\session } } + $this->is_setup_flag = true; + return; } @@ -406,103 +434,13 @@ class user extends \phpbb\session * * If the first parameter is an array, the elements are used as keys and subkeys to get the language entry: * Example: $user->lang(array('datetime', 'AGO'), 1) uses $user->lang['datetime']['AGO'] as language entry. + * + * @deprecated 3.2.0-dev (To be removed 4.0.0) */ function lang() { $args = func_get_args(); - $key = $args[0]; - - if (is_array($key)) - { - $lang = &$this->lang[array_shift($key)]; - - foreach ($key as $_key) - { - $lang = &$lang[$_key]; - } - } - else - { - $lang = &$this->lang[$key]; - } - - // Return if language string does not exist - if (!isset($lang) || (!is_string($lang) && !is_array($lang))) - { - return $key; - } - - // If the language entry is a string, we simply mimic sprintf() behaviour - if (is_string($lang)) - { - if (sizeof($args) == 1) - { - return $lang; - } - - // Replace key with language entry and simply pass along... - $args[0] = $lang; - return call_user_func_array('sprintf', $args); - } - else if (sizeof($lang) == 0) - { - // If the language entry is an empty array, we just return the language key - return $args[0]; - } - - // It is an array... now handle different nullar/singular/plural forms - $key_found = false; - - // We now get the first number passed and will select the key based upon this number - for ($i = 1, $num_args = sizeof($args); $i < $num_args; $i++) - { - if (is_int($args[$i]) || is_float($args[$i])) - { - if ($args[$i] == 0 && isset($lang[0])) - { - // We allow each translation using plural forms to specify a version for the case of 0 things, - // so that "0 users" may be displayed as "No users". - $key_found = 0; - break; - } - else - { - $use_plural_form = $this->get_plural_form($args[$i]); - if (isset($lang[$use_plural_form])) - { - // The key we should use exists, so we use it. - $key_found = $use_plural_form; - } - else - { - // If the key we need to use does not exist, we fall back to the previous one. - $numbers = array_keys($lang); - - foreach ($numbers as $num) - { - if ($num > $use_plural_form) - { - break; - } - - $key_found = $num; - } - } - break; - } - } - } - - // Ok, let's check if the key was found, else use the last entry (because it is mostly the plural form) - if ($key_found === false) - { - $numbers = array_keys($lang); - $key_found = end($numbers); - } - - // Use the language string we determined and pass it to sprintf() - $args[0] = $lang[$key_found]; - return call_user_func_array('sprintf', $args); + return call_user_func_array(array($this->language, 'lang'), $args); } /** @@ -512,24 +450,22 @@ class user extends \phpbb\session * @param $number int|float The number we want to get the plural case for. Float numbers are floored. * @param $force_rule mixed False to use the plural rule of the language package * or an integer to force a certain plural rule - * @return int The plural-case we need to use for the number plural-rule combination + * @return int|bool The plural-case we need to use for the number plural-rule combination, false if $force_rule + * was invalid. + * + * @deprecated: 3.2.0-dev (To be removed: 3.3.0) */ function get_plural_form($number, $force_rule = false) { - $number = (int) $number; - - // Default to English system - $plural_rule = ($force_rule !== false) ? $force_rule : ((isset($this->lang['PLURAL_RULE'])) ? $this->lang['PLURAL_RULE'] : 1); - - return phpbb_get_plural_form($plural_rule, $number); + return $this->language->get_plural_form($number, $force_rule); } /** * Add Language Items - use_db and use_help are assigned where needed (only use them to force inclusion) * * @param mixed $lang_set specifies the language entries to include - * @param bool $use_db internal variable for recursion, do not use - * @param bool $use_help internal variable for recursion, do not use + * @param bool $use_db internal variable for recursion, do not use @deprecated 3.2.0-dev (To be removed: 3.3.0) + * @param bool $use_help internal variable for recursion, do not use @deprecated 3.2.0-dev (To be removed: 3.3.0) * @param string $ext_name The extension to load language from, or empty for core files * * Examples: @@ -540,11 +476,14 @@ class user extends \phpbb\session * $lang_set = 'posting' * $lang_set = array('help' => 'faq', 'db' => array('help:faq', 'posting')) * + * + * Note: $use_db and $use_help should be removed. The old function was kept for BC purposes, + * so the BC logic is handled here. + * + * @deprecated: 3.2.0-dev (To be removed: 3.3.0) */ function add_lang($lang_set, $use_db = false, $use_help = false, $ext_name = '') { - global $phpEx; - if (is_array($lang_set)) { foreach ($lang_set as $key => $lang_file) @@ -555,6 +494,7 @@ class user extends \phpbb\session if ($key == 'db') { + // This is never used $this->add_lang($lang_file, true, $use_help, $ext_name); } else if ($key == 'help') @@ -563,7 +503,7 @@ class user extends \phpbb\session } else if (!is_array($lang_file)) { - $this->set_lang($this->lang, $this->help, $lang_file, $use_db, $use_help, $ext_name); + $this->set_lang($lang_file, $use_help, $ext_name); } else { @@ -574,8 +514,37 @@ class user extends \phpbb\session } else if ($lang_set) { - $this->set_lang($this->lang, $this->help, $lang_set, $use_db, $use_help, $ext_name); + $this->set_lang($lang_set, $use_help, $ext_name); + } + } + + /** + * BC function for loading language files + * + * @deprecated 3.2.0-dev (To be removed: 3.3.0) + */ + private function set_lang($lang_set, $use_help, $ext_name) + { + if (empty($ext_name)) + { + $ext_name = null; + } + + if ($use_help && strpos($lang_set, '/') !== false) + { + $component = dirname($lang_set) . '/help_' . basename($lang_set); + + if ($component[0] === '/') + { + $component = substr($component, 1); + } + } + else + { + $component = (($use_help) ? 'help_' : '') . $lang_set; } + + $this->language->add_lang($component, $ext_name); } /** @@ -585,6 +554,10 @@ class user extends \phpbb\session * @param mixed $lang_set specifies the language entries to include * @param bool $use_db internal variable for recursion, do not use * @param bool $use_help internal variable for recursion, do not use + * + * Note: $use_db and $use_help should be removed. Kept for BC purposes. + * + * @deprecated: 3.2.0-dev (To be removed: 3.3.0) */ function add_lang_ext($ext_name, $lang_set, $use_db = false, $use_help = false) { @@ -596,109 +569,6 @@ class user extends \phpbb\session $this->add_lang($lang_set, $use_db, $use_help, $ext_name); } - /** - * Set language entry (called by add_lang) - * @access private - */ - function set_lang(&$lang, &$help, $lang_file, $use_db = false, $use_help = false, $ext_name = '') - { - global $phpbb_root_path, $phpEx; - - // Make sure the language name is set (if the user setup did not happen it is not set) - if (!$this->lang_name) - { - global $config; - $this->lang_name = basename($config['default_lang']); - } - - // $lang == $this->lang - // $help == $this->help - // - add appropriate variables here, name them as they are used within the language file... - if (!$use_db) - { - if ($use_help && strpos($lang_file, '/') !== false) - { - $filename = dirname($lang_file) . '/help_' . basename($lang_file); - } - else - { - $filename = (($use_help) ? 'help_' : '') . $lang_file; - } - - if ($ext_name) - { - global $phpbb_extension_manager; - $ext_path = $phpbb_extension_manager->get_extension_path($ext_name, true); - - $lang_path = $ext_path . 'language/'; - } - else - { - $lang_path = $this->lang_path; - } - - if (strpos($phpbb_root_path . $filename, $lang_path . $this->lang_name . '/') === 0) - { - $language_filename = $phpbb_root_path . $filename; - } - else - { - $language_filename = $lang_path . $this->lang_name . '/' . $filename . '.' . $phpEx; - } - - // If we are in install, try to use the updated version, when available - $install_language_filename = str_replace('language/', 'install/update/new/language/', $language_filename); - if (defined('IN_INSTALL') && file_exists($install_language_filename)) - { - $language_filename = $install_language_filename; - } - - if (!file_exists($language_filename)) - { - global $config; - - if ($this->lang_name == 'en') - { - // The user's selected language is missing the file, the board default's language is missing the file, and the file doesn't exist in /en. - $language_filename = str_replace($lang_path . 'en', $lang_path . $this->data['user_lang'], $language_filename); - trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR); - } - else if ($this->lang_name == basename($config['default_lang'])) - { - // Fall back to the English Language - $reset_lang_name = $this->lang_name; - $this->lang_name = 'en'; - $this->set_lang($lang, $help, $lang_file, $use_db, $use_help, $ext_name); - $this->lang_name = $reset_lang_name; - } - else if ($this->lang_name == $this->data['user_lang']) - { - // Fall back to the board default language - $reset_lang_name = $this->lang_name; - $this->lang_name = basename($config['default_lang']); - $this->set_lang($lang, $help, $lang_file, $use_db, $use_help, $ext_name); - $this->lang_name = $reset_lang_name; - } - - return; - } - - // Do not suppress error if in DEBUG mode - $include_result = (defined('DEBUG')) ? (include $language_filename) : (@include $language_filename); - - if ($include_result === false) - { - trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR); - } - } - else if ($use_db) - { - // Get Database Language Strings - // Put them into $lang if nothing is prefixed, put them into $help if help: is prefixed - // For example: help:faq, posting - } - } - /** * Format user date * @@ -808,7 +678,7 @@ class user extends \phpbb\session if ($alt) { - $alt = $this->lang($alt); + $alt = $this->language->lang($alt); $title = ' title="' . $alt . '"'; } return '' . $alt . ''; -- cgit v1.2.1 From 9f1f6f96ceaf0870dabd0cf68c40292682c04aa2 Mon Sep 17 00:00:00 2001 From: MateBartus Date: Tue, 28 Apr 2015 22:52:43 +0200 Subject: [ticket/13762] Optional DI injectable default language module array PHPBB3-13762 --- phpBB/phpbb/language/language.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/language/language.php b/phpBB/phpbb/language/language.php index 9c9a3b8df1..3298908365 100644 --- a/phpBB/phpbb/language/language.php +++ b/phpBB/phpbb/language/language.php @@ -73,9 +73,10 @@ class language /** * Constructor * - * @param \phpbb\language\language_file_loader $loader Language file loader + * @param \phpbb\language\language_file_loader $loader Language file loader + * @param array|null $common_modules Array of common language modules to load (optional) */ - public function __construct(language_file_loader $loader) + public function __construct(language_file_loader $loader, $common_modules = null) { $this->loader = $loader; @@ -92,9 +93,17 @@ class language ); // Common language files - $this->common_language_files = array( - 'common', - ); + if (is_array($common_modules)) + { + $this->common_language_files = $common_modules; + } + else + { + $this->common_language_files = array( + 'common', + ); + } + $this->common_language_files_loaded = false; $this->language_fallback = array(self::FALLBACK_LANGUAGE); -- cgit v1.2.1 From 9a99c9e4b10eba614517e335527c332761b473a4 Mon Sep 17 00:00:00 2001 From: MateBartus Date: Wed, 29 Apr 2015 01:00:13 +0200 Subject: [ticket/13762] Replace user service with lang in twig extension PHPBB3-13762 --- phpBB/phpbb/template/twig/extension.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index 14d1258c09..92f87a0331 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -18,20 +18,20 @@ class extension extends \Twig_Extension /** @var \phpbb\template\context */ protected $context; - /** @var \phpbb\user */ - protected $user; + /** @var \phpbb\language\language */ + protected $language; /** * Constructor * * @param \phpbb\template\context $context - * @param \phpbb\user $user + * @param \phpbb\language\language $language * @return \phpbb\template\twig\extension */ - public function __construct(\phpbb\template\context $context, $user) + public function __construct(\phpbb\template\context $context, $language) { $this->context = $context; - $this->user = $user; + $this->language = $language; } /** @@ -181,6 +181,6 @@ class extension extends \Twig_Extension // LA_ is transformed into lang(\'$1\')|escape('js'), so we should not // need to check for it - return call_user_func_array(array($this->user, 'lang'), $args); + return call_user_func_array(array($this->language, 'lang'), $args); } } -- cgit v1.2.1 From 74dbaac0394f45955553ff46515404fe5b06bfba Mon Sep 17 00:00:00 2001 From: MateBartus Date: Thu, 30 Apr 2015 22:40:17 +0200 Subject: [ticket/13800] Make router's extension manager dependency optional PHPBB3-13800 --- phpBB/phpbb/routing/router.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 7444f06253..dd5bffe22b 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -94,13 +94,14 @@ class router implements RouterInterface * Construct method * * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem helper - * @param manager $extension_manager Extension manager - * @param string $phpbb_root_path phpBB root path - * @param string $php_ext PHP file extension - * @param string $environment Name of the current environment - * @param array $routing_files Array of strings containing paths to YAML files holding route information + * @param string $phpbb_root_path phpBB root path + * @param string $php_ext PHP file extension + * @param string $environment Name of the current environment + * @param manager|null $extension_manager Extension manager + * @param array $routing_files Array of strings containing paths to YAML files + * holding route information */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, manager $extension_manager, $phpbb_root_path, $php_ext, $environment, $routing_files = array()) + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path, $php_ext, $environment, manager $extension_manager = null, $routing_files = array()) { $this->filesystem = $filesystem; $this->extension_manager = $extension_manager; @@ -172,7 +173,9 @@ class router implements RouterInterface { if ($this->route_collection == null || empty($this->routing_files)) { - $this->find_routing_files($this->extension_manager->all_enabled(false)) + $this->find_routing_files( + ($this->extension_manager !== null) ? $this->extension_manager->all_enabled(false) : array() + ) ->find($this->phpbb_root_path); } -- cgit v1.2.1 From b3cc20a575da12e7b66f3883dcc7f0eb6ca82ad8 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 4 May 2015 10:09:37 +0200 Subject: [ticket/13782] Rename null driver to dummy for PHP7 compatibility PHPBB3-13782 --- phpBB/phpbb/cache/driver/dummy.php | 153 +++++++++++++++++++++++++++++++++++++ phpBB/phpbb/cache/driver/null.php | 153 ------------------------------------- 2 files changed, 153 insertions(+), 153 deletions(-) create mode 100644 phpBB/phpbb/cache/driver/dummy.php delete mode 100644 phpBB/phpbb/cache/driver/null.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/dummy.php b/phpBB/phpbb/cache/driver/dummy.php new file mode 100644 index 0000000000..1f74f6dd77 --- /dev/null +++ b/phpBB/phpbb/cache/driver/dummy.php @@ -0,0 +1,153 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\cache\driver; + +/** +* ACM dummy Caching +*/ +class dummy extends \phpbb\cache\driver\base +{ + /** + * Set cache path + */ + function __construct() + { + } + + /** + * {@inheritDoc} + */ + function load() + { + return true; + } + + /** + * {@inheritDoc} + */ + function unload() + { + } + + /** + * {@inheritDoc} + */ + function save() + { + } + + /** + * {@inheritDoc} + */ + function tidy() + { + global $config; + + // This cache always has a tidy room. + $config->set('cache_last_gc', time(), false); + } + + /** + * {@inheritDoc} + */ + function get($var_name) + { + return false; + } + + /** + * {@inheritDoc} + */ + function put($var_name, $var, $ttl = 0) + { + } + + /** + * {@inheritDoc} + */ + function purge() + { + } + + /** + * {@inheritDoc} + */ + function destroy($var_name, $table = '') + { + } + + /** + * {@inheritDoc} + */ + function _exists($var_name) + { + return false; + } + + /** + * {@inheritDoc} + */ + function sql_load($query) + { + return false; + } + + /** + * {@inheritDoc} + */ + function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) + { + return $query_result; + } + + /** + * {@inheritDoc} + */ + function sql_exists($query_id) + { + return false; + } + + /** + * {@inheritDoc} + */ + function sql_fetchrow($query_id) + { + return false; + } + + /** + * {@inheritDoc} + */ + function sql_fetchfield($query_id, $field) + { + return false; + } + + /** + * {@inheritDoc} + */ + function sql_rowseek($rownum, $query_id) + { + return false; + } + + /** + * {@inheritDoc} + */ + function sql_freeresult($query_id) + { + return false; + } +} diff --git a/phpBB/phpbb/cache/driver/null.php b/phpBB/phpbb/cache/driver/null.php deleted file mode 100644 index 298731ea54..0000000000 --- a/phpBB/phpbb/cache/driver/null.php +++ /dev/null @@ -1,153 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\cache\driver; - -/** -* ACM Null Caching -*/ -class null extends \phpbb\cache\driver\base -{ - /** - * Set cache path - */ - function __construct() - { - } - - /** - * {@inheritDoc} - */ - function load() - { - return true; - } - - /** - * {@inheritDoc} - */ - function unload() - { - } - - /** - * {@inheritDoc} - */ - function save() - { - } - - /** - * {@inheritDoc} - */ - function tidy() - { - global $config; - - // This cache always has a tidy room. - $config->set('cache_last_gc', time(), false); - } - - /** - * {@inheritDoc} - */ - function get($var_name) - { - return false; - } - - /** - * {@inheritDoc} - */ - function put($var_name, $var, $ttl = 0) - { - } - - /** - * {@inheritDoc} - */ - function purge() - { - } - - /** - * {@inheritDoc} - */ - function destroy($var_name, $table = '') - { - } - - /** - * {@inheritDoc} - */ - function _exists($var_name) - { - return false; - } - - /** - * {@inheritDoc} - */ - function sql_load($query) - { - return false; - } - - /** - * {@inheritDoc} - */ - function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) - { - return $query_result; - } - - /** - * {@inheritDoc} - */ - function sql_exists($query_id) - { - return false; - } - - /** - * {@inheritDoc} - */ - function sql_fetchrow($query_id) - { - return false; - } - - /** - * {@inheritDoc} - */ - function sql_fetchfield($query_id, $field) - { - return false; - } - - /** - * {@inheritDoc} - */ - function sql_rowseek($rownum, $query_id) - { - return false; - } - - /** - * {@inheritDoc} - */ - function sql_freeresult($query_id) - { - return false; - } -} -- cgit v1.2.1 From 232f71dae43df9794184961431aca81d0e4652da Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 4 May 2015 10:11:28 +0200 Subject: [ticket/13782] Rename null log to dummy for PHP7 compatibility PHPBB3-13782 --- phpBB/phpbb/log/dummy.php | 81 +++++++++++++++++++++++++++++++++++++++++++++++ phpBB/phpbb/log/null.php | 81 ----------------------------------------------- 2 files changed, 81 insertions(+), 81 deletions(-) create mode 100644 phpBB/phpbb/log/dummy.php delete mode 100644 phpBB/phpbb/log/null.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/log/dummy.php b/phpBB/phpbb/log/dummy.php new file mode 100644 index 0000000000..5c2d145e15 --- /dev/null +++ b/phpBB/phpbb/log/dummy.php @@ -0,0 +1,81 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\log; + +/** +* Dummy logger +*/ +class dummy implements log_interface +{ + /** + * {@inheritdoc} + */ + public function is_enabled($type = '') + { + return false; + } + + /** + * {@inheritdoc} + */ + public function disable($type = '') + { + } + + /** + * {@inheritdoc} + */ + public function enable($type = '') + { + } + + /** + * {@inheritdoc} + */ + public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array()) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function delete($mode, $conditions = array()) + { + } + + /** + * {@inheritdoc} + */ + public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '') + { + return array(); + } + + /** + * {@inheritdoc} + */ + public function get_log_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_valid_offset() + { + return 0; + } +} diff --git a/phpBB/phpbb/log/null.php b/phpBB/phpbb/log/null.php deleted file mode 100644 index baa78895ea..0000000000 --- a/phpBB/phpbb/log/null.php +++ /dev/null @@ -1,81 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\log; - -/** -* Null logger -*/ -class null implements log_interface -{ - /** - * {@inheritdoc} - */ - public function is_enabled($type = '') - { - return false; - } - - /** - * {@inheritdoc} - */ - public function disable($type = '') - { - } - - /** - * {@inheritdoc} - */ - public function enable($type = '') - { - } - - /** - * {@inheritdoc} - */ - public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array()) - { - return false; - } - - /** - * {@inheritdoc} - */ - public function delete($mode, $conditions = array()) - { - } - - /** - * {@inheritdoc} - */ - public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '') - { - return array(); - } - - /** - * {@inheritdoc} - */ - public function get_log_count() - { - return 0; - } - - /** - * {@inheritdoc} - */ - public function get_valid_offset() - { - return 0; - } -} -- cgit v1.2.1 From 0d2c8b5961d461913557795e8d99c0fa0be87448 Mon Sep 17 00:00:00 2001 From: rxu Date: Mon, 4 May 2015 16:51:09 +0700 Subject: [ticket/13814] Prevent phpbb_is_writable() method from truncating files phpbb_is_writable() of filesystem class uses 'w' mode to fopen files which causes checked files to be truncated. Use the 'c' mode instead. PHPBB3-13814 --- phpBB/phpbb/filesystem/filesystem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/filesystem/filesystem.php b/phpBB/phpbb/filesystem/filesystem.php index 370dff77e5..2112882d1d 100644 --- a/phpBB/phpbb/filesystem/filesystem.php +++ b/phpBB/phpbb/filesystem/filesystem.php @@ -613,7 +613,7 @@ class filesystem implements filesystem_interface } else { - $handle = @fopen($file, 'w'); + $handle = @fopen($file, 'c'); if (is_resource($handle)) { -- cgit v1.2.1 From f821130c3a4a22efd491aaad962cc84a82dde56a Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Tue, 25 Nov 2014 17:04:15 +0100 Subject: [ticket/12632] Add twig.debug and twig.auto_reload in config.yml PHPBB3-13206 PHPBB3-12632 --- phpBB/phpbb/di/extension/container_configuration.php | 2 ++ phpBB/phpbb/di/extension/core.php | 14 ++++++++++++++ phpBB/phpbb/template/twig/environment.php | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/extension/container_configuration.php b/phpBB/phpbb/di/extension/container_configuration.php index ee58ec2b74..4cc7c7c0d1 100644 --- a/phpBB/phpbb/di/extension/container_configuration.php +++ b/phpBB/phpbb/di/extension/container_configuration.php @@ -34,6 +34,8 @@ class container_configuration implements ConfigurationInterface ->arrayNode('twig') ->addDefaultsIfNotSet() ->children() + ->booleanNode('debug')->defaultValue(null)->end() + ->booleanNode('auto_reload')->defaultValue(null)->end() ->booleanNode('enable_debug_extension')->defaultValue(false)->end() ->end() ->end() diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index c71dc61280..c9e2d4dc5b 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -69,6 +69,20 @@ class core extends Extension } } + // Set the Twig options if defined in the environment + $definition = $container->getDefinition('template.twig.environment'); + $twig_environment_options = $definition->getArgument(6); + if ($config['twig']['debug']) + { + $twig_environment_options['debug'] = true; + } + if ($config['twig']['auto_reload']) + { + $twig_environment_options['auto_reload'] = true; + } + // Replace the 6th argument, the options passed to the environment + $definition->replaceArgument(6, $twig_environment_options); + if ($config['twig']['enable_debug_extension']) { $definition = $container->getDefinition('template.twig.extensions.debug'); diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 0ba7a265e4..fcd0566b6e 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -60,7 +60,7 @@ class environment extends \Twig_Environment $options = array_merge(array( 'cache' => (defined('IN_INSTALL')) ? false : $cache_path, - 'debug' => defined('DEBUG'), + 'debug' => false, 'auto_reload' => (bool) $this->phpbb_config['load_tplcompile'], 'autoescape' => false, ), $options); -- cgit v1.2.1 From 3b631cb40d1641dce8789fabd79e3cbc5598747d Mon Sep 17 00:00:00 2001 From: Nicofuma Date: Sun, 22 Feb 2015 16:56:57 +0100 Subject: [ticket/13638] Prepend the assets path phpbb root PHPBB3-13638 --- phpBB/phpbb/template/asset.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php index 4729685459..d9ed861034 100644 --- a/phpBB/phpbb/template/asset.php +++ b/phpBB/phpbb/template/asset.php @@ -153,9 +153,9 @@ class asset public function set_path($path, $urlencode = false) { // Since 1.7.0 Twig returns the real path of the file. We need it to be relative to the working directory. - $real_root_path = realpath('.') . DIRECTORY_SEPARATOR; + $real_root_path = realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR; if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) { - $path = str_replace('\\', '/', substr($path, strlen($real_root_path))); + $path = $this->path_helper->get_phpbb_root_path() . str_replace('\\', '/', substr($path, strlen($real_root_path))); } if ($urlencode) -- cgit v1.2.1 From f097f84f16f32e8d9c0148907f0ae5743f09619f Mon Sep 17 00:00:00 2001 From: Nicofuma Date: Sun, 22 Feb 2015 18:38:30 +0100 Subject: [ticket/13638] Handle assets outside of phpbb_root_path PHPBB3-13638 --- phpBB/phpbb/template/asset.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php index d9ed861034..aa1689d71a 100644 --- a/phpBB/phpbb/template/asset.php +++ b/phpBB/phpbb/template/asset.php @@ -152,11 +152,23 @@ class asset */ public function set_path($path, $urlencode = false) { - // Since 1.7.0 Twig returns the real path of the file. We need it to be relative to the working directory. - $real_root_path = realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR; - if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) { + // Since 1.7.0 Twig returns the real path of the file. We need it to be relative. + $real_root_path = phpbb_realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR; + + // If the asset is under the phpBB root path we need to remove its path and then prepend $phpbb_root_path + if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) + { $path = $this->path_helper->get_phpbb_root_path() . str_replace('\\', '/', substr($path, strlen($real_root_path))); } + else + { + // Else we make the path relative to the current working directory + $real_root_path = phpbb_realpath('.') . DIRECTORY_SEPARATOR; + if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) + { + $path = str_replace('\\', '/', substr($path, strlen($real_root_path))); + } + } if ($urlencode) { -- cgit v1.2.1 From 51376a43919cba7a5037edb7cc31f18b5950437b Mon Sep 17 00:00:00 2001 From: Nicofuma Date: Mon, 4 May 2015 23:50:16 +0200 Subject: [ticket/13638] Inject $filesystem in \phpbb\template\asset PHPBB3-13638 --- phpBB/phpbb/template/asset.php | 11 ++++++++--- phpBB/phpbb/template/twig/environment.php | 25 ++++++++++++++++++++----- phpBB/phpbb/template/twig/node/includeasset.php | 2 +- 3 files changed, 29 insertions(+), 9 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php index aa1689d71a..cb00f16549 100644 --- a/phpBB/phpbb/template/asset.php +++ b/phpBB/phpbb/template/asset.php @@ -20,15 +20,20 @@ class asset /** @var \phpbb\path_helper **/ protected $path_helper; + /** @var \phpbb\filesystem\filesystem */ + protected $filesystem; + /** * Constructor * * @param string $url URL * @param \phpbb\path_helper $path_helper Path helper object + * @param \phpbb\filesystem\filesystem $filesystem */ - public function __construct($url, \phpbb\path_helper $path_helper) + public function __construct($url, \phpbb\path_helper $path_helper, \phpbb\filesystem\filesystem $filesystem) { $this->path_helper = $path_helper; + $this->filesystem = $filesystem; $this->set_url($url); } @@ -153,7 +158,7 @@ class asset public function set_path($path, $urlencode = false) { // Since 1.7.0 Twig returns the real path of the file. We need it to be relative. - $real_root_path = phpbb_realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR; + $real_root_path = $this->filesystem->realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR; // If the asset is under the phpBB root path we need to remove its path and then prepend $phpbb_root_path if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) @@ -163,7 +168,7 @@ class asset else { // Else we make the path relative to the current working directory - $real_root_path = phpbb_realpath('.') . DIRECTORY_SEPARATOR; + $real_root_path = $this->filesystem->realpath('.') . DIRECTORY_SEPARATOR; if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) { $path = str_replace('\\', '/', substr($path, strlen($real_root_path))); diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 0ba7a265e4..e7b8aeab89 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -18,6 +18,9 @@ class environment extends \Twig_Environment /** @var \phpbb\config\config */ protected $phpbb_config; + /** @var \phpbb\filesystem\filesystem */ + protected $filesystem; + /** @var \phpbb\path_helper */ protected $phpbb_path_helper; @@ -40,6 +43,7 @@ class environment extends \Twig_Environment * Constructor * * @param \phpbb\config\config $phpbb_config The phpBB configuration + * @param \phpbb\filesystem\filesystem $filesystem * @param \phpbb\path_helper $path_helper phpBB path helper * @param \Symfony\Component\DependencyInjection\ContainerInterface $container The dependency injection container * @param string $cache_path The path to the cache directory @@ -47,10 +51,11 @@ class environment extends \Twig_Environment * @param \Twig_LoaderInterface $loader Twig loader interface * @param array $options Array of options to pass to Twig */ - public function __construct($phpbb_config, \phpbb\path_helper $path_helper, \Symfony\Component\DependencyInjection\ContainerInterface $container, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array()) + public function __construct(\phpbb\config\config $phpbb_config, \phpbb\filesystem\filesystem $filesystem, \phpbb\path_helper $path_helper, \Symfony\Component\DependencyInjection\ContainerInterface $container, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array()) { $this->phpbb_config = $phpbb_config; + $this->filesystem = $filesystem; $this->phpbb_path_helper = $path_helper; $this->extension_manager = $extension_manager; $this->container = $container; @@ -106,15 +111,25 @@ class environment extends \Twig_Environment } /** - * Get the phpBB root path - * - * @return string - */ + * Get the phpBB root path + * + * @return string + */ public function get_phpbb_root_path() { return $this->phpbb_root_path; } + /** + * Get the filesystem object + * + * @return \phpbb\filesystem\filesystem + */ + public function get_filesystem() + { + return $this->filesystem; + } + /** * Get the web root path * diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php index 15195a226b..324823b8d7 100644 --- a/phpBB/phpbb/template/twig/node/includeasset.php +++ b/phpBB/phpbb/template/twig/node/includeasset.php @@ -39,7 +39,7 @@ abstract class includeasset extends \Twig_Node ->write("\$asset_file = ") ->subcompile($this->getNode('expr')) ->raw(";\n") - ->write("\$asset = new \phpbb\\template\\asset(\$asset_file, \$this->getEnvironment()->get_path_helper());\n") + ->write("\$asset = new \phpbb\\template\\asset(\$asset_file, \$this->getEnvironment()->get_path_helper(), \$this->getEnvironment()->get_filesystem());\n") ->write("if (substr(\$asset_file, 0, 2) !== './' && \$asset->is_relative()) {\n") ->indent() ->write("\$asset_path = \$asset->get_path();") -- cgit v1.2.1 From 7b301e22f32e9209bb4e3ea17a5637a84a4ef908 Mon Sep 17 00:00:00 2001 From: MateBartus Date: Fri, 1 May 2015 19:04:21 +0200 Subject: [ticket/13804] Make template's user dependency optional PHPBB3-13804 --- .../exception/user_object_not_available.php | 22 ++++++++++++++++++++ phpBB/phpbb/template/twig/twig.php | 24 +++++++++++++++++++--- 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 phpBB/phpbb/template/exception/user_object_not_available.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/exception/user_object_not_available.php b/phpBB/phpbb/template/exception/user_object_not_available.php new file mode 100644 index 0000000000..62fd2743c1 --- /dev/null +++ b/phpBB/phpbb/template/exception/user_object_not_available.php @@ -0,0 +1,22 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\template\exception; + +/** + * This exception is thrown when the user object was not set but it is required by the called method + */ +class user_object_not_available extends \phpbb\exception\runtime_exception +{ + +} diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php index 0e4c619029..ab349cc740 100644 --- a/phpBB/phpbb/template/twig/twig.php +++ b/phpBB/phpbb/template/twig/twig.php @@ -13,6 +13,8 @@ namespace phpbb\template\twig; +use phpbb\template\exception\user_object_not_available; + /** * Twig Template class. */ @@ -76,14 +78,14 @@ class twig extends \phpbb\template\base * * @param \phpbb\path_helper $path_helper * @param \phpbb\config\config $config - * @param \phpbb\user $user * @param \phpbb\template\context $context template context * @param \phpbb\template\twig\environment $twig_environment * @param string $cache_path + * @param \phpbb\user|null $user * @param array|\ArrayAccess $extensions * @param \phpbb\extension\manager $extension_manager extension manager, if null then template events will not be invoked */ - public function __construct(\phpbb\path_helper $path_helper, $config, $user, \phpbb\template\context $context, \phpbb\template\twig\environment $twig_environment, $cache_path, $extensions = array(), \phpbb\extension\manager $extension_manager = null) + public function __construct(\phpbb\path_helper $path_helper, $config, \phpbb\template\context $context, \phpbb\template\twig\environment $twig_environment, $cache_path, \phpbb\user $user = null, $extensions = array(), \phpbb\extension\manager $extension_manager = null) { $this->path_helper = $path_helper; $this->phpbb_root_path = $path_helper->get_phpbb_root_path(); @@ -126,9 +128,16 @@ class twig extends \phpbb\template\base * Get the style tree of the style preferred by the current user * * @return array Style tree, most specific first + * + * @throws \phpbb\template\exception\user_object_not_available When user service was not set */ public function get_user_style() { + if ($this->user === null) + { + throw new user_object_not_available(); + } + $style_list = array( $this->user->style['style_path'], ); @@ -344,11 +353,20 @@ class twig extends \phpbb\template\base $context_vars['.'][0], // To get normal vars array( 'definition' => new \phpbb\template\twig\definition(), - 'user' => $this->user, 'loops' => $context_vars, // To get loops ) ); + if ($this->user instanceof \phpbb\user) + { + $vars = array_merge( + $vars, + array( + 'user' => $this->user, + ) + ); + } + // cleanup unset($vars['loops']['.']); -- cgit v1.2.1 From 281f2ef2dacc7d635646edb3897fba8ff6f66d25 Mon Sep 17 00:00:00 2001 From: MateBartus Date: Mon, 11 May 2015 16:59:26 +0200 Subject: [ticket/13804] Remove unnecessary array_merge PHPBB3-13804 --- phpBB/phpbb/template/twig/twig.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php index ab349cc740..6b3cf32bc8 100644 --- a/phpBB/phpbb/template/twig/twig.php +++ b/phpBB/phpbb/template/twig/twig.php @@ -359,12 +359,7 @@ class twig extends \phpbb\template\base if ($this->user instanceof \phpbb\user) { - $vars = array_merge( - $vars, - array( - 'user' => $this->user, - ) - ); + $vars['user'] = $this->user; } // cleanup -- cgit v1.2.1 From d48e95bb3a17f111e9d4d8111630be44ef9019e4 Mon Sep 17 00:00:00 2001 From: Nicofuma Date: Sun, 10 May 2015 19:18:10 +0200 Subject: [ticket/13829] Don't fail if the cache isn't writeable PHPBB3-13829 --- phpBB/phpbb/routing/router.php | 59 ++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 22 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 7444f06253..f74760fa13 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -14,6 +14,7 @@ namespace phpbb\routing; use Symfony\Component\Config\ConfigCache; +use Symfony\Component\Filesystem\Exception\IOException; use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper; use Symfony\Component\Routing\Matcher\UrlMatcher; @@ -249,22 +250,29 @@ class router implements RouterInterface */ protected function create_dumped_url_matcher() { - $cache = new ConfigCache("{$this->phpbb_root_path}cache/{$this->environment}/url_matcher.{$this->php_ext}", defined('DEBUG')); - if (!$cache->isFresh()) + try { - $dumper = new PhpMatcherDumper($this->get_routes()); + $cache = new ConfigCache("{$this->phpbb_root_path}cache/{$this->environment}/url_matcher.{$this->php_ext}", defined('DEBUG')); + if (!$cache->isFresh()) + { + $dumper = new PhpMatcherDumper($this->get_routes()); - $options = array( - 'class' => 'phpbb_url_matcher', - 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', - ); + $options = array( + 'class' => 'phpbb_url_matcher', + 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', + ); - $cache->write($dumper->dump($options), $this->get_routes()->getResources()); - } + $cache->write($dumper->dump($options), $this->get_routes()->getResources()); + } - require_once($cache->getPath()); + require_once($cache->getPath()); - $this->matcher = new \phpbb_url_matcher($this->context); + $this->matcher = new \phpbb_url_matcher($this->context); + } + catch (IOException $e) + { + $this->create_new_url_matcher(); + } } /** @@ -297,22 +305,29 @@ class router implements RouterInterface */ protected function create_dumped_url_generator() { - $cache = new ConfigCache("{$this->phpbb_root_path}cache/{$this->environment}/url_generator.{$this->php_ext}", defined('DEBUG')); - if (!$cache->isFresh()) + try { - $dumper = new PhpGeneratorDumper($this->get_routes()); + $cache = new ConfigCache("{$this->phpbb_root_path}cache/{$this->environment}/url_generator.{$this->php_ext}", defined('DEBUG')); + if (!$cache->isFresh()) + { + $dumper = new PhpGeneratorDumper($this->get_routes()); - $options = array( - 'class' => 'phpbb_url_generator', - 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', - ); + $options = array( + 'class' => 'phpbb_url_generator', + 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', + ); - $cache->write($dumper->dump($options), $this->get_routes()->getResources()); - } + $cache->write($dumper->dump($options), $this->get_routes()->getResources()); + } - require_once($cache->getPath()); + require_once($cache->getPath()); - $this->generator = new \phpbb_url_generator($this->context); + $this->generator = new \phpbb_url_generator($this->context); + } + catch (IOException $e) + { + $this->create_new_url_generator(); + } } /** -- cgit v1.2.1 From c96e7ef1711932c2236620903bc256b346514dfc Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 26 Apr 2015 19:41:07 +0200 Subject: [ticket/13770] Wither interface for container_builder PHPBB3-13770 --- phpBB/phpbb/di/container_builder.php | 504 +++++++++++++++++------------------ 1 file changed, 247 insertions(+), 257 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 99576f9020..33eb4e59a8 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -13,6 +13,7 @@ namespace phpbb\di; +use phpbb\filesystem\filesystem; use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -24,6 +25,11 @@ use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfiguration class container_builder { + /** + * @var string The environment to use. + */ + protected $environment; + /** * @var string phpBB Root Path */ @@ -35,89 +41,58 @@ class container_builder protected $php_ext; /** - * The container under construction - * - * @var ContainerBuilder - */ + * The container under construction + * + * @var ContainerBuilder + */ protected $container; /** - * @var \phpbb\db\driver\driver_interface - */ - protected $dbal_connection = null; - - /** - * @var array the installed extensions - */ - protected $installed_exts = null; - - /** - * Indicates whether the php config file should be injected into the container (default to true). - * - * @var bool - */ - protected $inject_config = true; - - /** - * Indicates whether extensions should be used (default to true). - * - * @var bool - */ + * Indicates whether extensions should be used (default to true). + * + * @var bool + */ protected $use_extensions = true; /** - * Defines a custom path to find the configuration of the container (default to $this->phpbb_root_path . 'config') - * - * @var string - */ + * Defines a custom path to find the configuration of the container (default to $this->phpbb_root_path . 'config') + * + * @var string + */ protected $config_path = null; /** - * Indicates whether the phpBB compile pass should be used (default to true). - * - * @var bool - */ - protected $use_custom_pass = true; - - /** - * Indicates whether the kernel compile pass should be used (default to true). - * - * @var bool - */ - protected $use_kernel_pass = true; - - /** - * Indicates whether the container should be dumped to the filesystem (default to true). - * - * If DEBUG_CONTAINER is set this option is ignored and a new container is build. - * - * @var bool - */ - protected $dump_container = true; + * Indicates whether the container should be dumped to the filesystem (default to true). + * + * If DEBUG_CONTAINER is set this option is ignored and a new container is build. + * + * @var bool + */ + protected $use_cache = true; /** - * Indicates if the container should be compiled automatically (default to true). - * - * @var bool - */ + * Indicates if the container should be compiled automatically (default to true). + * + * @var bool + */ protected $compile_container = true; /** - * Custom parameters to inject into the container. - * - * Default to true: - * array( - * 'core.root_path', $this->phpbb_root_path, - * 'core.php_ext', $this->php_ext, - * ); - * - * @var array - */ + * Custom parameters to inject into the container. + * + * Default to: + * array( + * 'core.root_path', $this->phpbb_root_path, + * 'core.php_ext', $this->php_ext, + * ); + * + * @var array + */ protected $custom_parameters = null; /** - * @var \phpbb\config_php_file - */ + * @var \phpbb\config_php_file + */ protected $config_php_file; /** @@ -126,295 +101,311 @@ class container_builder protected $cache_dir; /** - * Constructor - * - * @param \phpbb\config_php_file $config_php_file - * @param string $phpbb_root_path Path to the phpbb includes directory. - * @param string $php_ext php file extension - */ - function __construct(\phpbb\config_php_file $config_php_file, $phpbb_root_path, $php_ext) + * @var array + */ + private $container_extensions; + + /** + * Constructor + * + * @param string $phpbb_root_path Path to the phpbb includes directory. + * @param string $php_ext php file extension + */ + function __construct($phpbb_root_path, $php_ext) { - $this->config_php_file = $config_php_file; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; } /** - * Build and return a new Container respecting the current configuration - * - * @return \phpbb_cache_container|ContainerBuilder - */ + * Build and return a new Container respecting the current configuration + * + * @return \phpbb_cache_container|ContainerBuilder + */ public function get_container() { $container_filename = $this->get_container_filename(); $config_cache = new ConfigCache($container_filename, defined('DEBUG')); - if ($this->dump_container && $config_cache->isFresh()) + if ($this->use_cache && $config_cache->isFresh()) { require($config_cache->getPath()); $this->container = new \phpbb_cache_container(); + + return $this->container; } - else - { - $container_extensions = array(new \phpbb\di\extension\core($this->get_config_path())); - if ($this->use_extensions) - { - $installed_exts = $this->get_installed_extensions(); - foreach ($installed_exts as $ext_name => $path) - { - $extension_class = '\\' . str_replace('/', '\\', $ext_name) . '\\di\\extension'; + $this->container_extensions = array(new extension\core($this->get_config_path())); - if (!class_exists($extension_class)) - { - $extension_class = '\phpbb\extension\di\extension_base'; - } + if ($this->use_extensions) + { + $this->load_extensions(); + } - $container_extensions[] = new $extension_class($ext_name, $path); - } - } + // Inject the config + $this->container_extensions[] = new extension\config($this->config_php_file); - if ($this->inject_config) - { - $container_extensions[] = new \phpbb\di\extension\config($this->config_php_file); - } + $this->container = $this->create_container($this->container_extensions); - $this->container = $this->create_container($container_extensions); + // Easy collections through tags + $this->container->addCompilerPass(new pass\collection_pass()); - if ($this->use_custom_pass) - { - // Symfony Kernel Listeners - $this->container->addCompilerPass(new \phpbb\di\pass\collection_pass()); - $this->container->addCompilerPass(new RegisterListenersPass('dispatcher', 'event.listener_listener', 'event.listener')); + // Event listeners "phpBB style" + $this->container->addCompilerPass(new RegisterListenersPass('dispatcher', 'event.listener_listener', 'event.listener')); - if ($this->use_kernel_pass) - { - $this->container->addCompilerPass(new RegisterListenersPass('dispatcher')); - } - } + // Event listeners "Symfony style" + $this->container->addCompilerPass(new RegisterListenersPass('dispatcher')); - $filesystem = new \phpbb\filesystem\filesystem(); - $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path()))); - $loader->load($this->container->getParameter('core.environment') . '/config.yml'); + $filesystem = new filesystem(); + $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path()))); + $loader->load($this->container->getParameter('core.environment') . '/config.yml'); - $this->inject_custom_parameters(); + $this->inject_custom_parameters(); - if ($this->compile_container) - { - $this->container->compile(); - } + if ($this->compile_container) + { + $this->container->compile(); - if ($this->dump_container) + if ($this->use_cache) { $this->dump_container($config_cache); } } - $this->container->set('config.php', $this->config_php_file); - - if ($this->compile_container) - { - $this->inject_dbal(); - } - return $this->container; } /** - * Set if the extensions should be used. - * - * @param bool $use_extensions - */ - public function set_use_extensions($use_extensions) + * Enable the extensions. + * + * @param string $environment The environment to use + * @return $this + */ + public function with_environment($environment) { - $this->use_extensions = $use_extensions; - } + $this->environment = $environment; - /** - * Set if the phpBB compile pass have to be used. - * - * @param bool $use_custom_pass - */ - public function set_use_custom_pass($use_custom_pass) - { - $this->use_custom_pass = $use_custom_pass; + return $this; } /** - * Set if the kernel compile pass have to be used. - * - * @param bool $use_kernel_pass - */ - public function set_use_kernel_pass($use_kernel_pass) + * Enable the extensions. + * + * @return $this + */ + public function with_extensions() { - $this->use_kernel_pass = $use_kernel_pass; + $this->use_extensions = true; + + return $this; } /** - * Set if the php config file should be injecting into the container. - * - * @param bool $inject_config - */ - public function set_inject_config($inject_config) + * Disable the extensions. + * + * @return $this + */ + public function without_extensions() { - $this->inject_config = $inject_config; + $this->use_extensions = false; + + return $this; } /** - * Set if a dump container should be used. - * - * If DEBUG_CONTAINER is set this option is ignored and a new container is build. - * - * @var bool $dump_container - */ - public function set_dump_container($dump_container) + * Enable the caching of the container. + * + * If DEBUG_CONTAINER is set this option is ignored and a new container is build. + * + * @return $this + */ + public function with_cache() { - $this->dump_container = $dump_container; + $this->use_cache = true; + + return $this; } /** - * Set if the container should be compiled automatically (default to true). - * - * @var bool $dump_container - */ - public function set_compile_container($compile_container) + * Disable the caching of the container. + * + * @return $this + */ + public function without_cache() { - $this->compile_container = $compile_container; + $this->use_cache = false; + + return $this; } /** - * Set a custom path to find the configuration of the container - * - * @param string $config_path - */ - public function set_config_path($config_path) + * Set the cache directory. + * + * @param string $cache_dir The cache directory. + * @return $this + */ + public function with_cache_dir($cache_dir) { - $this->config_path = $config_path; + $this->cache_dir = $cache_dir; + + return $this; } /** - * Returns the path to the container configuration (default: root_path/config) + * Enable the compilation of the container. * - * @return string + * @return $this */ - protected function get_config_path() + public function with_compiled_container() { - return $this->config_path ?: $this->phpbb_root_path . 'config'; + $this->compile_container = true; + + return $this; } /** - * Set custom parameters to inject into the container. - * - * @param array $custom_parameters - */ - public function set_custom_parameters($custom_parameters) + * Disable the compilation of the container. + * + * @return $this + */ + public function without_compiled_container() { - $this->custom_parameters = $custom_parameters; + $this->compile_container = false; + + return $this; } /** - * Set the path to the cache directory. + * Set a custom path to find the configuration of the container. * - * @param string $cache_dir Path to the cache directory + * @param string $config_path + * @return $this */ - public function set_cache_dir($cache_dir) + public function with_config_path($config_path) { - $this->cache_dir = $cache_dir; + $this->config_path = $config_path; + + return $this; } /** - * Returns the path to the cache directory (default: root_path/cache/environment). + * Set custom parameters to inject into the container. * - * @return string Path to the cache directory. + * @param array $custom_parameters + * @return $this */ - protected function get_cache_dir() + public function with_custom_parameters($custom_parameters) { - return $this->cache_dir ?: $this->phpbb_root_path . 'cache/' . $this->get_environment() . '/'; + $this->custom_parameters = $custom_parameters; + + return $this; } /** - * Dump the container to the disk. - * - * @param ConfigCache $cache The config cache - */ - protected function dump_container($cache) + * Set custom parameters to inject into the container. + * + * @param \phpbb\config_php_file $config_php_file + * @return $this + */ + public function with_config(\phpbb\config_php_file $config_php_file) { - $dumper = new PhpDumper($this->container); - $cached_container_dump = $dumper->dump(array( - 'class' => 'phpbb_cache_container', - 'base_class' => 'Symfony\\Component\\DependencyInjection\\ContainerBuilder', - )); + $this->config_php_file = $config_php_file; - $cache->write($cached_container_dump, $this->container->getResources()); + return $this; } /** - * Inject the connection into the container if one was opened. - */ - protected function inject_dbal() + * Returns the path to the container configuration (default: root_path/config) + * + * @return string + */ + protected function get_config_path() { - if ($this->dbal_connection !== null) - { - $this->container->get('dbal.conn')->set_driver($this->dbal_connection); - } + return $this->config_path ?: $this->phpbb_root_path . 'config'; } /** - * Get DB connection. - * - * @return \phpbb\db\driver\driver_interface - */ - protected function get_dbal_connection() + * Returns the path to the cache directory (default: root_path/cache/environment). + * + * @return string Path to the cache directory. + */ + protected function get_cache_dir() { - if ($this->dbal_connection === null) - { - $dbal_driver_class = $this->config_php_file->convert_30_dbms_to_31($this->config_php_file->get('dbms')); - $this->dbal_connection = new $dbal_driver_class(); - $this->dbal_connection->sql_connect( - $this->config_php_file->get('dbhost'), - $this->config_php_file->get('dbuser'), - $this->config_php_file->get('dbpasswd'), - $this->config_php_file->get('dbname'), - $this->config_php_file->get('dbport'), - defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK - ); - } - - return $this->dbal_connection; + return $this->cache_dir ?: $this->phpbb_root_path . 'cache/' . $this->get_environment() . '/'; } /** - * Get enabled extensions. - * - * @return array enabled extensions - */ - protected function get_installed_extensions() + * Load the enabled extensions. + */ + protected function load_extensions() { - $db = $this->get_dbal_connection(); - $extension_table = $this->config_php_file->get('table_prefix') . 'ext'; + if ($this->config_php_file !== null) + { + // Build an intermediate container to load the ext list from the database + $container_builder = new container_builder($this->phpbb_root_path, $this->php_ext); + $ext_container = $container_builder + ->without_cache() + ->without_extensions() + ->with_config($this->config_php_file) + ->with_environment('production') + ->without_compiled_container() + ->get_container() + ; + + $ext_container->register('cache.driver', '\\phpbb\\cache\\driver\\null'); + $ext_container->compile(); + + $extensions = $ext_container->get('ext.manager')->all_enabled(); + + // Load each extension found + foreach ($extensions as $ext_name => $path) + { + $extension_class = '\\' . str_replace('/', '\\', $ext_name) . '\\di\\extension'; - $sql = 'SELECT * - FROM ' . $extension_table . ' - WHERE ext_active = 1'; + if (!class_exists($extension_class)) + { + $extension_class = '\\phpbb\\extension\\di\\extension_base'; + } - $result = $db->sql_query($sql); - $rows = $db->sql_fetchrowset($result); - $db->sql_freeresult($result); + $this->container_extensions[] = new $extension_class($ext_name, $path); - $exts = array(); - foreach ($rows as $row) + // Load extension autoloader + $filename = $path . 'vendor/autoload.php'; + if (file_exists($filename)) + { + require $filename; + } + } + } + else { - $exts[$row['ext_name']] = $this->phpbb_root_path . 'ext/' . $row['ext_name'] . '/'; + // To load the extensions we need the database credentials. + // Automatically disable the extensions if we don't have them. + $this->use_extensions = false; } + } - return $exts; + /** + * Dump the container to the disk. + * + * @param ConfigCache $cache The config cache + */ + protected function dump_container($cache) + { + $dumper = new PhpDumper($this->container); + $cached_container_dump = $dumper->dump(array( + 'class' => 'phpbb_cache_container', + 'base_class' => 'Symfony\\Component\\DependencyInjection\\ContainerBuilder', + )); + + $cache->write($cached_container_dump, $this->container->getResources()); } /** - * Create the ContainerBuilder object - * - * @param array $extensions Array of Container extension objects - * @return ContainerBuilder object - */ + * Create the ContainerBuilder object + * + * @param array $extensions Array of Container extension objects + * @return ContainerBuilder object + */ protected function create_container(array $extensions) { $container = new ContainerBuilder(new ParameterBag($this->get_core_parameters())); @@ -425,7 +416,6 @@ class container_builder { $container->registerExtension($extension); $extensions_alias[] = $extension->getAlias(); - //$container->loadFromExtension($extension->getAlias()); } $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions_alias)); @@ -487,10 +477,10 @@ class container_builder } /** - * Get the filename under which the dumped container will be stored. - * - * @return string Path for dumped container - */ + * Get the filename under which the dumped container will be stored. + * + * @return string Path for dumped container + */ protected function get_container_filename() { $filename = str_replace(array('/', '.'), array('slash', 'dot'), $this->phpbb_root_path); @@ -504,6 +494,6 @@ class container_builder */ protected function get_environment() { - return PHPBB_ENVIRONMENT; + return $this->environment ?: PHPBB_ENVIRONMENT; } } -- cgit v1.2.1 From 549fe66d90eed1d6a4fee6f5f706c73455d73596 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 26 Apr 2015 21:30:50 +0200 Subject: [ticket/13770] Update tests PHPBB3-13770 --- phpBB/phpbb/di/container_builder.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 33eb4e59a8..3886bfdd5d 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -142,7 +142,10 @@ class container_builder } // Inject the config - $this->container_extensions[] = new extension\config($this->config_php_file); + if ($this->config_php_file) + { + $this->container_extensions[] = new extension\config($this->config_php_file); + } $this->container = $this->create_container($this->container_extensions); -- cgit v1.2.1 From 02af9385a13543f3f6bd9cb1500fd8508bcd35ac Mon Sep 17 00:00:00 2001 From: Nicofuma Date: Sun, 10 May 2015 23:54:49 +0200 Subject: [ticket/13770] Fix tests PHPBB3-13770 --- phpBB/phpbb/di/container_builder.php | 83 +++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 35 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 3886bfdd5d..9f2e860932 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -21,6 +21,7 @@ use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; +use Symfony\Component\Filesystem\Exception\IOException; use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; class container_builder @@ -130,50 +131,55 @@ class container_builder { require($config_cache->getPath()); $this->container = new \phpbb_cache_container(); - - return $this->container; } - - $this->container_extensions = array(new extension\core($this->get_config_path())); - - if ($this->use_extensions) + else { - $this->load_extensions(); - } + $this->container_extensions = array(new extension\core($this->get_config_path())); - // Inject the config - if ($this->config_php_file) - { - $this->container_extensions[] = new extension\config($this->config_php_file); - } + if ($this->use_extensions) + { + $this->load_extensions(); + } - $this->container = $this->create_container($this->container_extensions); + // Inject the config + if ($this->config_php_file) + { + $this->container_extensions[] = new extension\config($this->config_php_file); + } - // Easy collections through tags - $this->container->addCompilerPass(new pass\collection_pass()); + $this->container = $this->create_container($this->container_extensions); - // Event listeners "phpBB style" - $this->container->addCompilerPass(new RegisterListenersPass('dispatcher', 'event.listener_listener', 'event.listener')); + // Easy collections through tags + $this->container->addCompilerPass(new pass\collection_pass()); - // Event listeners "Symfony style" - $this->container->addCompilerPass(new RegisterListenersPass('dispatcher')); + // Event listeners "phpBB style" + $this->container->addCompilerPass(new RegisterListenersPass('dispatcher', 'event.listener_listener', 'event.listener')); - $filesystem = new filesystem(); - $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path()))); - $loader->load($this->container->getParameter('core.environment') . '/config.yml'); + // Event listeners "Symfony style" + $this->container->addCompilerPass(new RegisterListenersPass('dispatcher')); - $this->inject_custom_parameters(); + $filesystem = new filesystem(); + $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path()))); + $loader->load($this->container->getParameter('core.environment') . '/config.yml'); - if ($this->compile_container) - { - $this->container->compile(); + $this->inject_custom_parameters(); - if ($this->use_cache) + if ($this->compile_container) { - $this->dump_container($config_cache); + $this->container->compile(); + + if ($this->use_cache) + { + $this->dump_container($config_cache); + } } } + if ($this->compile_container && $this->config_php_file) + { + $this->container->set('config.php', $this->config_php_file); + } + return $this->container; } @@ -394,13 +400,20 @@ class container_builder */ protected function dump_container($cache) { - $dumper = new PhpDumper($this->container); - $cached_container_dump = $dumper->dump(array( - 'class' => 'phpbb_cache_container', - 'base_class' => 'Symfony\\Component\\DependencyInjection\\ContainerBuilder', - )); + try + { + $dumper = new PhpDumper($this->container); + $cached_container_dump = $dumper->dump(array( + 'class' => 'phpbb_cache_container', + 'base_class' => 'Symfony\\Component\\DependencyInjection\\ContainerBuilder', + )); - $cache->write($cached_container_dump, $this->container->getResources()); + $cache->write($cached_container_dump, $this->container->getResources()); + } + catch (IOException $e) + { + // Don't fail if the cache isn't writeable + } } /** -- cgit v1.2.1 From 2b25c5bd35a1a5e668d0f4e644cfabf995e1a537 Mon Sep 17 00:00:00 2001 From: Nicofuma Date: Mon, 11 May 2015 00:19:50 +0200 Subject: [ticket/13770] Use dummy cache driver PHPBB3-13770 --- phpBB/phpbb/di/container_builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 9f2e860932..4a31339b9a 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -360,7 +360,7 @@ class container_builder ->get_container() ; - $ext_container->register('cache.driver', '\\phpbb\\cache\\driver\\null'); + $ext_container->register('cache.driver', '\\phpbb\\cache\\driver\\dummy'); $ext_container->compile(); $extensions = $ext_container->get('ext.manager')->all_enabled(); -- cgit v1.2.1 From f5ce9f273829ba470a1348b4314cddb58f552da0 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 3 May 2015 16:06:42 +0200 Subject: [ticket/13680] Updated quote notifications Added get_quote_authors() to text_formatter.utils service to retrieve the names used in first-level quotes PHPBB3-13680 --- phpBB/phpbb/notification/type/quote.php | 31 ++++++++++++++++----------- phpBB/phpbb/textformatter/s9e/utils.php | 25 +++++++++++++++++++++ phpBB/phpbb/textformatter/utils_interface.php | 8 +++++++ 3 files changed, 52 insertions(+), 12 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 141f90c7ae..1b8efe4c8e 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -20,6 +20,11 @@ namespace phpbb\notification\type; class quote extends \phpbb\notification\type\post { + /** + * @var \phpbb\textformatter\utils_interface + */ + protected $utils; + /** * Get notification type name * @@ -30,13 +35,6 @@ class quote extends \phpbb\notification\type\post return 'notification.type.quote'; } - /** - * regular expression to match to find usernames - * - * @var string - */ - protected static $regular_expression_match = '#\[quote="(.+?)"#'; - /** * Language key used to output the text * @@ -77,17 +75,16 @@ class quote extends \phpbb\notification\type\post 'ignore_users' => array(), ), $options); - $usernames = false; - preg_match_all(self::$regular_expression_match, $post['post_text'], $usernames); + $usernames = $this->utils->get_quote_authors($post['post_text']); - if (empty($usernames[1])) + if (empty($usernames)) { return array(); } - $usernames[1] = array_unique($usernames[1]); + $usernames = array_unique($usernames); - $usernames = array_map('utf8_clean_string', $usernames[1]); + $usernames = array_map('utf8_clean_string', $usernames); $users = array(); @@ -187,4 +184,14 @@ class quote extends \phpbb\notification\type\post 'AUTHOR_NAME' => htmlspecialchars_decode($user_data['username']), )); } + + /** + * Set the utils service used to retrieve quote authors + * + * @param \phpbb\textformatter\utils_interface $utils + */ + public function set_utils(\phpbb\textformatter\utils_interface $utils) + { + $this->utils = $utils; + } } diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index 2018bbf519..576ab9481c 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -34,6 +34,31 @@ class utils implements \phpbb\textformatter\utils_interface return \s9e\TextFormatter\Utils::removeFormatting($xml); } + /** + * Get a list of quote authors, limited to the first level of quotes + * + * @param string $xml Parsed text + * @return string[] List of authors + */ + public function get_quote_authors($xml) + { + $authors = array(); + if (strpos($xml, 'loadXML($xml); + $xpath = new \DOMXPath($dom); + foreach ($xpath->query('//QUOTE[not(ancestor::QUOTE)]/@author') as $author) + { + $authors[] = $author->textContent; + } + + return $authors; + } + /** * Remove given BBCode and its content, at given nesting depth * diff --git a/phpBB/phpbb/textformatter/utils_interface.php b/phpBB/phpbb/textformatter/utils_interface.php index 132dc8ece4..183c426161 100644 --- a/phpBB/phpbb/textformatter/utils_interface.php +++ b/phpBB/phpbb/textformatter/utils_interface.php @@ -28,6 +28,14 @@ interface utils_interface */ public function clean_formatting($text); + /** + * Get a list of quote authors, limited to the first level of quotes + * + * @param string $text Parsed text + * @return string[] List of authors + */ + public function get_quote_authors($text); + /** * Remove given BBCode and its content, at given nesting depth * -- cgit v1.2.1 From f7ad2c2b32b309edba006a8d4b58727b50642ea2 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 15 May 2015 02:12:52 +0200 Subject: [ticket/13680] Renamed get_quote_authors to get_outermost_quote_authors PHPBB3-13680 --- phpBB/phpbb/notification/type/quote.php | 2 +- phpBB/phpbb/textformatter/s9e/utils.php | 4 ++-- phpBB/phpbb/textformatter/utils_interface.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 1b8efe4c8e..51edfec6f7 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -75,7 +75,7 @@ class quote extends \phpbb\notification\type\post 'ignore_users' => array(), ), $options); - $usernames = $this->utils->get_quote_authors($post['post_text']); + $usernames = $this->utils->get_outermost_quote_authors($post['post_text']); if (empty($usernames)) { diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index 576ab9481c..e21dedecc4 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -35,12 +35,12 @@ class utils implements \phpbb\textformatter\utils_interface } /** - * Get a list of quote authors, limited to the first level of quotes + * Get a list of quote authors, limited to the outermost quotes * * @param string $xml Parsed text * @return string[] List of authors */ - public function get_quote_authors($xml) + public function get_outermost_quote_authors($xml) { $authors = array(); if (strpos($xml, ' Date: Sat, 16 May 2015 18:49:32 +0200 Subject: [ticket/13844] Refactor bbcode help to the new system PHPBB3-13844 --- phpBB/phpbb/help/controller/bbcode.php | 85 ++++++++++++++++++++++++++++++ phpBB/phpbb/help/controller/controller.php | 81 ++++++++++++++++++++++++++++ phpBB/phpbb/help/manager.php | 85 ++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 phpBB/phpbb/help/controller/bbcode.php create mode 100644 phpBB/phpbb/help/controller/controller.php create mode 100644 phpBB/phpbb/help/manager.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/help/controller/bbcode.php b/phpBB/phpbb/help/controller/bbcode.php new file mode 100644 index 0000000000..e16f99023d --- /dev/null +++ b/phpBB/phpbb/help/controller/bbcode.php @@ -0,0 +1,85 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\help\controller; + +/** + * BBCode help page + */ +class bbcode extends controller +{ + /** + * @return string The title of the page + */ + public function display() + { + $this->language->add_lang('help/bbcode'); + + $this->manager->add_block( + 'HELP_BBCODE_BLOCK_INTRO', + false, + array( + 'HELP_BBCODE_INTRO_BBCODE_QUESTION' => 'HELP_BBCODE_INTRO_BBCODE_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_BBCODE_BLOCK_TEXT', + false, + array( + 'HELP_BBCODE_TEXT_BASIC_QUESTION' => 'HELP_BBCODE_TEXT_BASIC_ANSWER', + 'HELP_BBCODE_TEXT_COLOR_QUESTION' => 'HELP_BBCODE_TEXT_COLOR_ANSWER', + 'HELP_BBCODE_TEXT_COMBINE_QUESTION' => 'HELP_BBCODE_TEXT_COMBINE_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_BBCODE_BLOCK_QUOTES', + false, + array( + 'HELP_BBCODE_QUOTES_TEXT_QUESTION' => 'HELP_BBCODE_QUOTES_TEXT_ANSWER', + 'HELP_BBCODE_QUOTES_CODE_QUESTION' => 'HELP_BBCODE_QUOTES_CODE_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_BBCODE_BLOCK_LISTS', + false, + array( + 'HELP_BBCODE_LISTS_UNORDERER_QUESTION' => 'HELP_BBCODE_LISTS_UNORDERER_ANSWER', + 'HELP_BBCODE_LISTS_ORDERER_QUESTION' => 'HELP_BBCODE_LISTS_ORDERER_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_BBCODE_BLOCK_LINKS', + true, + array( + 'HELP_BBCODE_LINKS_BASIC_QUESTION' => 'HELP_BBCODE_LINKS_BASIC_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_BBCODE_BLOCK_IMAGES', + false, + array( + 'HELP_BBCODE_IMAGES_BASIC_QUESTION' => 'HELP_BBCODE_IMAGES_BASIC_ANSWER', + 'HELP_BBCODE_IMAGES_ATTACHMENT_QUESTION' => 'HELP_BBCODE_IMAGES_ATTACHMENT_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_BBCODE_BLOCK_OTHERS', + false, + array( + 'HELP_BBCODE_OTHERS_CUSTOM_QUESTION' => 'HELP_BBCODE_OTHERS_CUSTOM_ANSWER', + ) + ); + + return $this->language->lang('BBCODE_GUIDE'); + } +} diff --git a/phpBB/phpbb/help/controller/controller.php b/phpBB/phpbb/help/controller/controller.php new file mode 100644 index 0000000000..743a9c7fde --- /dev/null +++ b/phpBB/phpbb/help/controller/controller.php @@ -0,0 +1,81 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\help\controller; + +/** + * BBCode help page + */ +abstract class controller +{ + /** @var \phpbb\controller\helper */ + protected $helper; + + /** @var \phpbb\event\dispatcher_interface */ + protected $dispatcher; + + /** @var \phpbb\help\manager */ + protected $manager; + + /** @var \phpbb\template\template */ + protected $template; + + /** @var \phpbb\language\language */ + protected $language; + + /** @var string */ + protected $root_path; + + /** @var string */ + protected $php_ext; + + /** + * Constructor + * + * @param \phpbb\controller\helper $helper + * @param \phpbb\event\dispatcher_interface $dispatcher + * @param \phpbb\help\manager $manager + * @param \phpbb\template\template $template + * @param \phpbb\language\language $language + * @param string $root_path + * @param string $php_ext + */ + public function __construct(\phpbb\controller\helper $helper, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\help\manager $manager, \phpbb\template\template $template, \phpbb\language\language $language, $root_path, $php_ext) + { + $this->helper = $helper; + $this->dispatcher = $dispatcher; + $this->manager = $manager; + $this->template = $template; + $this->language = $language; + $this->root_path = $root_path; + $this->php_ext = $php_ext; + } + + /** + * @return string + */ + abstract protected function display(); + + public function handle() + { + $title = $this->display(); + + $this->template->assign_vars(array( + 'L_FAQ_TITLE' => $title, + 'S_IN_FAQ' => true, + )); + + make_jumpbox(append_sid("{$this->root_path}viewforum.{$this->php_ext}")); + return $this->helper->render('faq_body.html', $title); + } +} diff --git a/phpBB/phpbb/help/manager.php b/phpBB/phpbb/help/manager.php new file mode 100644 index 0000000000..a7320563a8 --- /dev/null +++ b/phpBB/phpbb/help/manager.php @@ -0,0 +1,85 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\help; + +/** + * Class help page manager + */ +class manager +{ + /** @var \phpbb\template\template */ + protected $template; + + /** @var \phpbb\language\language */ + protected $language; + + /** @var bool */ + protected $switched_column; + + /** + * Constructor + * + * @param \phpbb\template\template $template + * @param \phpbb\language\language $language + */ + public function __construct(\phpbb\template\template $template, \phpbb\language\language $language) + { + $this->template = $template; + $this->language = $language; + } + + /** + * Add a new faq block + * + * @param string $block_name Name or language key with the name of the block + * @param bool $switch_column Switch the column of the menu + */ + public function add_block($block_name, $switch_column = false, $questions = array()) + { + $this->template->assign_block_vars('faq_block', array( + 'BLOCK_TITLE' => $this->language->lang($block_name), + 'SWITCH_COLUMN' => !$this->switched_column && $switch_column, + )); + + foreach ($questions as $question => $answer) + { + $this->add_question($question, $answer); + } + + $this->switched_column = $this->switched_column || $switch_column; + } + + /** + * Add a new faq question + * + * @param string $question Question or language key with the question of the block + * @param string $answer Answer or language key with the answer of the block + */ + public function add_question($question, $answer) + { + $this->template->assign_block_vars('faq_block.faq_row', array( + 'FAQ_QUESTION' => $this->language->lang($question), + 'FAQ_ANSWER' => $this->language->lang($answer), + )); + } + + /** + * Returns whether the block titles switched side + * @return bool + */ + public function switched_column() + { + return $this->switched_column; + } +} -- cgit v1.2.1 From 07231e7943e9ffdba08393be56510e682ab7a7e5 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 16 May 2015 22:06:37 +0200 Subject: [ticket/13844] FAQ in new controller format PHPBB3-13844 --- phpBB/phpbb/help/controller/faq.php | 165 ++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 phpBB/phpbb/help/controller/faq.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/help/controller/faq.php b/phpBB/phpbb/help/controller/faq.php new file mode 100644 index 0000000000..5e45cfe667 --- /dev/null +++ b/phpBB/phpbb/help/controller/faq.php @@ -0,0 +1,165 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\help\controller; + +/** + * FAQ help page + */ +class faq extends controller +{ + /** + * @return string The title of the page + */ + public function display() + { + $this->language->add_lang('help/faq'); + + $this->manager->add_block( + 'HELP_FAQ_BLOCK_LOGIN', + false, + array( + 'HELP_FAQ_LOGIN_REGISTER_QUESTION' => 'HELP_FAQ_LOGIN_REGISTER_ANSWER', + 'HELP_FAQ_LOGIN_COPPA_QUESTION' => 'HELP_FAQ_LOGIN_COPPA_ANSWER', + 'HELP_FAQ_LOGIN_CANNOT_REGISTER_QUESTION' => 'HELP_FAQ_LOGIN_CANNOT_REGISTER_ANSWER', + 'HELP_FAQ_LOGIN_REGISTER_CONFIRM_QUESTION' => 'HELP_FAQ_LOGIN_REGISTER_CONFIRM_ANSWER', + 'HELP_FAQ_LOGIN_CANNOT_LOGIN_QUESTION' => 'HELP_FAQ_LOGIN_CANNOT_LOGIN_ANSWER', + 'HELP_FAQ_LOGIN_CANNOT_LOGIN_ANYMORE_QUESTION' => 'HELP_FAQ_LOGIN_CANNOT_LOGIN_ANYMORE_ANSWER', + 'HELP_FAQ_LOGIN_LOST_PASSWORD_QUESTION' => 'HELP_FAQ_LOGIN_LOST_PASSWORD_ANSWER', + 'HELP_FAQ_LOGIN_AUTO_LOGOUT_QUESTION' => 'HELP_FAQ_LOGIN_AUTO_LOGOUT_ANSWER', + 'HELP_FAQ_LOGIN_DELETE_COOKIES_QUESTION' => 'HELP_FAQ_LOGIN_DELETE_COOKIES_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_FAQ_BLOCK_USERSETTINGS', + false, + array( + 'HELP_FAQ_USERSETTINGS_CHANGE_SETTINGS_QUESTION' => 'HELP_FAQ_USERSETTINGS_CHANGE_SETTINGS_ANSWER', + 'HELP_FAQ_USERSETTINGS_HIDE_ONLINE_QUESTION' => 'HELP_FAQ_USERSETTINGS_HIDE_ONLINE_ANSWER', + 'HELP_FAQ_USERSETTINGS_TIMEZONE_QUESTION' => 'HELP_FAQ_USERSETTINGS_TIMEZONE_ANSWER', + 'HELP_FAQ_USERSETTINGS_SERVERTIME_QUESTION' => 'HELP_FAQ_USERSETTINGS_SERVERTIME_ANSWER', + 'HELP_FAQ_USERSETTINGS_LANGUAGE_QUESTION' => 'HELP_FAQ_USERSETTINGS_LANGUAGE_ANSWER', + 'HELP_FAQ_USERSETTINGS_AVATAR_QUESTION' => 'HELP_FAQ_USERSETTINGS_AVATAR_ANSWER', + 'HELP_FAQ_USERSETTINGS_AVATAR_DISPLAY_QUESTION' => 'HELP_FAQ_USERSETTINGS_AVATAR_DISPLAY_ANSWER', + 'HELP_FAQ_USERSETTINGS_RANK_QUESTION' => 'HELP_FAQ_USERSETTINGS_RANK_ANSWER', + 'HELP_FAQ_USERSETTINGS_EMAIL_LOGIN_QUESTION' => 'HELP_FAQ_USERSETTINGS_EMAIL_LOGIN_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_FAQ_BLOCK_POSTING', + false, + array( + 'HELP_FAQ_POSTING_CREATE_QUESTION' => 'HELP_FAQ_POSTING_CREATE_ANSWER', + 'HELP_FAQ_POSTING_EDIT_DELETE_QUESTION' => 'HELP_FAQ_POSTING_EDIT_DELETE_ANSWER', + 'HELP_FAQ_POSTING_SIGNATURE_QUESTION' => 'HELP_FAQ_POSTING_SIGNATURE_ANSWER', + 'HELP_FAQ_POSTING_POLL_CREATE_QUESTION' => 'HELP_FAQ_POSTING_POLL_CREATE_ANSWER', + 'HELP_FAQ_POSTING_POLL_ADD_QUESTION' => 'HELP_FAQ_POSTING_POLL_ADD_ANSWER', + 'HELP_FAQ_POSTING_POLL_EDIT_QUESTION' => 'HELP_FAQ_POSTING_POLL_EDIT_ANSWER', + 'HELP_FAQ_POSTING_FORUM_RESTRICTED_QUESTION' => 'HELP_FAQ_POSTING_FORUM_RESTRICTED_ANSWER', + 'HELP_FAQ_POSTING_NO_ATTACHMENTS_QUESTION' => 'HELP_FAQ_POSTING_NO_ATTACHMENTS_ANSWER', + 'HELP_FAQ_POSTING_WARNING_QUESTION' => 'HELP_FAQ_POSTING_WARNING_ANSWER', + 'HELP_FAQ_POSTING_REPORT_QUESTION' => 'HELP_FAQ_POSTING_REPORT_ANSWER', + 'HELP_FAQ_POSTING_DRAFT_QUESTION' => 'HELP_FAQ_POSTING_DRAFT_ANSWER', + 'HELP_FAQ_POSTING_QUEUE_QUESTION' => 'HELP_FAQ_POSTING_QUEUE_ANSWER', + 'HELP_FAQ_POSTING_BUMP_QUESTION' => 'HELP_FAQ_POSTING_BUMP_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_FAQ_BLOCK_FORMATTING', + false, + array( + 'HELP_FAQ_FORMATTING_BBOCDE_QUESTION' => 'HELP_FAQ_FORMATTING_BBOCDE_ANSWER', + 'HELP_FAQ_FORMATTING_HTML_QUESTION' => 'HELP_FAQ_FORMATTING_HTML_ANSWER', + 'HELP_FAQ_FORMATTING_SMILIES_QUESTION' => 'HELP_FAQ_FORMATTING_SMILIES_ANSWER', + 'HELP_FAQ_FORMATTING_IMAGES_QUESTION' => 'HELP_FAQ_FORMATTING_IMAGES_ANSWER', + 'HELP_FAQ_FORMATTING_GLOBAL_ANNOUNCE_QUESTION' => 'HELP_FAQ_FORMATTING_GLOBAL_ANNOUNCE_ANSWER', + 'HELP_FAQ_FORMATTING_ANNOUNCEMENT_QUESTION' => 'HELP_FAQ_FORMATTING_ANNOUNCEMENT_ANSWER', + 'HELP_FAQ_FORMATTING_STICKIES_QUESTION' => 'HELP_FAQ_FORMATTING_STICKIES_ANSWER', + 'HELP_FAQ_FORMATTING_LOCKED_QUESTION' => 'HELP_FAQ_FORMATTING_LOCKED_ANSWER', + 'HELP_FAQ_FORMATTING_ICONS_QUESTION' => 'HELP_FAQ_FORMATTING_ICONS_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_FAQ_BLOCK_GROUPS', + true, + array( + 'HELP_FAQ_GROUPS_ADMINISTRATORS_QUESTION' => 'HELP_FAQ_GROUPS_ADMINISTRATORS_ANSWER', + 'HELP_FAQ_GROUPS_MODERATORS_QUESTION' => 'HELP_FAQ_GROUPS_MODERATORS_ANSWER', + 'HELP_FAQ_GROUPS_USERGROUPS_QUESTION' => 'HELP_FAQ_GROUPS_USERGROUPS_ANSWER', + 'HELP_FAQ_GROUPS_USERGROUPS_JOIN_QUESTION' => 'HELP_FAQ_GROUPS_USERGROUPS_JOIN_ANSWER', + 'HELP_FAQ_GROUPS_USERGROUPS_LEAD_QUESTION' => 'HELP_FAQ_GROUPS_USERGROUPS_LEAD_ANSWER', + 'HELP_FAQ_GROUPS_COLORS_QUESTION' => 'HELP_FAQ_GROUPS_COLORS_ANSWER', + 'HELP_FAQ_GROUPS_DEFAULT_QUESTION' => 'HELP_FAQ_GROUPS_DEFAULT_ANSWER', + 'HELP_FAQ_GROUPS_TEAM_QUESTION' => 'HELP_FAQ_GROUPS_TEAM_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_FAQ_BLOCK_PMS', + false, + array( + 'HELP_FAQ_PMS_CANNOT_SEND_QUESTION' => 'HELP_FAQ_PMS_CANNOT_SEND_ANSWER', + 'HELP_FAQ_PMS_UNWANTED_QUESTION' => 'HELP_FAQ_PMS_UNWANTED_ANSWER', + 'HELP_FAQ_PMS_SPAM_QUESTION' => 'HELP_FAQ_PMS_SPAM_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_FAQ_BLOCK_FRIENDS', + false, + array( + 'HELP_FAQ_FRIENDS_BASIC_QUESTION' => 'HELP_FAQ_FRIENDS_BASIC_ANSWER', + 'HELP_FAQ_FRIENDS_MANAGE_QUESTION' => 'HELP_FAQ_FRIENDS_MANAGE_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_FAQ_BLOCK_SEARCH', + false, + array( + 'HELP_FAQ_SEARCH_FORUM_QUESTION' => 'HELP_FAQ_SEARCH_FORUM_ANSWER', + 'HELP_FAQ_SEARCH_NO_RESULT_QUESTION' => 'HELP_FAQ_SEARCH_NO_RESULT_ANSWER', + 'HELP_FAQ_SEARCH_BLANK_QUESTION' => 'HELP_FAQ_SEARCH_BLANK_ANSWER', + 'HELP_FAQ_SEARCH_MEMBERS_QUESTION' => 'HELP_FAQ_SEARCH_MEMBERS_ANSWER', + 'HELP_FAQ_SEARCH_OWN_QUESTION' => 'HELP_FAQ_SEARCH_OWN_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_FAQ_BLOCK_BOOKMARKS', + false, + array( + 'HELP_FAQ_BOOKMARKS_DIFFERENCE_QUESTION' => 'HELP_FAQ_BOOKMARKS_DIFFERENCE_ANSWER', + 'HELP_FAQ_BOOKMARKS_TOPIC_QUESTION' => 'HELP_FAQ_BOOKMARKS_TOPIC_ANSWER', + 'HELP_FAQ_BOOKMARKS_FORUM_QUESTION' => 'HELP_FAQ_BOOKMARKS_FORUM_ANSWER', + 'HELP_FAQ_BOOKMARKS_REMOVE_QUESTION' => 'HELP_FAQ_BOOKMARKS_REMOVE_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_FAQ_BLOCK_ATTACHMENTS', + false, + array( + 'HELP_FAQ_ATTACHMENTS_ALLOWED_QUESTION' => 'HELP_FAQ_ATTACHMENTS_ALLOWED_ANSWER', + 'HELP_FAQ_ATTACHMENTS_OWN_QUESTION' => 'HELP_FAQ_ATTACHMENTS_OWN_ANSWER', + ) + ); + $this->manager->add_block( + 'HELP_FAQ_BLOCK_ISSUES', + false, + array( + 'HELP_FAQ_ISSUES_WHOIS_PHPBB_QUESTION' => 'HELP_FAQ_ISSUES_WHOIS_PHPBB_ANSWER', + 'HELP_FAQ_ISSUES_FEATURE_QUESTION' => 'HELP_FAQ_ISSUES_FEATURE_ANSWER', + 'HELP_FAQ_ISSUES_LEGAL_QUESTION' => 'HELP_FAQ_ISSUES_LEGAL_ANSWER', + 'HELP_FAQ_ISSUES_ADMIN_QUESTION' => 'HELP_FAQ_ISSUES_ADMIN_ANSWER', + ) + ); + + return $this->language->lang('FAQ_EXPLAIN'); + } +} -- cgit v1.2.1 From 8ce0a64a16aa9d1b8edcef684c528cf44bc39cc6 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sun, 17 May 2015 21:18:17 +0200 Subject: [ticket/13844] Remove hacky code for the help array PHPBB3-13844 --- phpBB/phpbb/language/language.php | 7 +------ phpBB/phpbb/language/language_file_loader.php | 12 +++--------- 2 files changed, 4 insertions(+), 15 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/language/language.php b/phpBB/phpbb/language/language.php index 3298908365..b2b9f5ce12 100644 --- a/phpBB/phpbb/language/language.php +++ b/phpBB/phpbb/language/language.php @@ -83,10 +83,7 @@ class language // Set up default information $this->user_language = false; $this->default_language = false; - $this->lang = array( - // For BC with user::help array - '__help' => array(), - ); + $this->lang = array(); $this->loaded_language_sets = array( 'core' => array(), 'ext' => array(), @@ -155,8 +152,6 @@ class language /** * Add Language Items * - * Note: $use_help is assigned where needed (only use them to force inclusion). - * * Examples: * * $component = array('posting'); diff --git a/phpBB/phpbb/language/language_file_loader.php b/phpBB/phpbb/language/language_file_loader.php index 510a29279a..9862cfc3aa 100644 --- a/phpBB/phpbb/language/language_file_loader.php +++ b/phpBB/phpbb/language/language_file_loader.php @@ -154,10 +154,12 @@ class language_file_loader * * @return string Relative path to language file * - * @throws \phpbb\language\exception\language_file_not_exists When the path to the file cannot be resolved + * @throws \phpbb\language\exception\language_file_not_found When the path to the file cannot be resolved */ protected function get_language_file_path($path, $filename, $locales) { + $language_file_path = $filename; + // Language fallback logic foreach ($locales as $locale) { @@ -191,9 +193,6 @@ class language_file_loader */ protected function load_language_file($path, &$lang) { - // BC code for language files with help - $help = array(); - // Do not suppress error if in DEBUG mode if (defined('DEBUG')) { @@ -203,10 +202,5 @@ class language_file_loader { @include $path; } - - if (!empty($help)) - { - $lang['__help'] = array_merge($lang['__help'], $help); - } } } -- cgit v1.2.1 From deadc0665298f18a937fc959da449e9098873c0b Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 30 Apr 2015 23:01:28 +0200 Subject: [ticket/13801] Removed user dependency from text_formatter.s9e.parser PHPBB3-13801 --- phpBB/phpbb/textformatter/s9e/parser.php | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index e46a0578d2..178669d84f 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -31,21 +31,15 @@ class parser implements \phpbb\textformatter\parser_interface */ protected $parser; - /** - * @var \phpbb\user User object, used for translating errors - */ - protected $user; - /** * Constructor * * @param \phpbb\cache\driver_interface $cache * @param string $key Cache key - * @param \phpbb\user $user * @param factory $factory * @param \phpbb\event\dispatcher_interface $dispatcher */ - public function __construct(\phpbb\cache\driver\driver_interface $cache, $key, \phpbb\user $user, factory $factory, \phpbb\event\dispatcher_interface $dispatcher) + public function __construct(\phpbb\cache\driver\driver_interface $cache, $key, factory $factory, \phpbb\event\dispatcher_interface $dispatcher) { $parser = $cache->get($key); if (!$parser) @@ -56,24 +50,20 @@ class parser implements \phpbb\textformatter\parser_interface $this->dispatcher = $dispatcher; $this->parser = $parser; - $this->user = $user; $parser = $this; /** * Configure the parser service * * Can be used to: - * - toggle features according to the user's preferences, - * - toggle BBCodes according to the user's permissions, * - register variables or custom parsers in the s9e\TextFormatter * - configure the s9e\TextFormatter parser * * @event core.text_formatter_s9e_parser_setup * @var \phpbb\textformatter\s9e\parser parser This parser service - * @var \phpbb\user user Current user * @since 3.2.0-a1 */ - $vars = array('parser', 'user'); + $vars = array('parser'); extract($dispatcher->trigger_event('core.text_formatter_s9e_parser_setup', compact($vars))); } @@ -202,7 +192,6 @@ class parser implements \phpbb\textformatter\parser_interface public function get_errors() { $errors = array(); - foreach ($this->parser->getLogger()->get() as $entry) { list($type, $msg, $context) = $entry; @@ -211,29 +200,29 @@ class parser implements \phpbb\textformatter\parser_interface { if ($context['tagName'] === 'E') { - $errors[] = $this->user->lang('TOO_MANY_SMILIES', $context['tagLimit']); + $errors[] = array('TOO_MANY_SMILIES', $context['tagLimit']); } else if ($context['tagName'] === 'URL') { - $errors[] = $this->user->lang('TOO_MANY_URLS', $context['tagLimit']); + $errors[] = array('TOO_MANY_URLS', $context['tagLimit']); } } else if ($msg === 'MAX_FONT_SIZE_EXCEEDED') { - $errors[] = $this->user->lang($msg, $context['max_size']); + $errors[] = array($msg, $context['max_size']); } else if (preg_match('/^MAX_(?:FLASH|IMG)_(HEIGHT|WIDTH)_EXCEEDED$/D', $msg, $m)) { - $errors[] = $this->user->lang($msg, $context['max_' . strtolower($m[1])]); + $errors[] = array($msg, $context['max_' . strtolower($m[1])]); } else if ($msg === 'Tag is disabled') { $name = strtolower($context['tag']->getName()); - $errors[] = $this->user->lang('UNAUTHORISED_BBCODE', '[' . $name . ']'); + $errors[] = array('UNAUTHORISED_BBCODE', '[' . $name . ']'); } else if ($msg === 'UNABLE_GET_IMAGE_SIZE') { - $errors[] = $this->user->lang($msg); + $errors[] = array($msg); } } -- cgit v1.2.1 From 7b552152b416d9f0c2e873f6f70c4d3cec575ea6 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 8 May 2015 14:51:46 +0200 Subject: [ticket/13801] Updated comments for clarity PHPBB3-13801 --- phpBB/phpbb/textformatter/parser_interface.php | 3 ++- phpBB/phpbb/textformatter/s9e/parser.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/parser_interface.php b/phpBB/phpbb/textformatter/parser_interface.php index 3cb9f8e977..ad611fb5b4 100644 --- a/phpBB/phpbb/textformatter/parser_interface.php +++ b/phpBB/phpbb/textformatter/parser_interface.php @@ -82,7 +82,8 @@ interface parser_interface /** * Get the list of errors that were generated during last parsing * - * @return array + * @return array[] Array of arrays. Each array contains a lang string at index 0 plus any number + * of optional parameters */ public function get_errors(); diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 178669d84f..ee033f6d21 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -186,7 +186,7 @@ class parser implements \phpbb\textformatter\parser_interface /** * {@inheritdoc} * - * This will translate the log entries found in s9e\TextFormatter's logger into phpBB error + * This will convert the log entries found in s9e\TextFormatter's logger into phpBB error * messages */ public function get_errors() -- cgit v1.2.1 From 5772e06b1aace1d5fbef263217e71ad10347364d Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 17 May 2015 14:09:02 +0200 Subject: [ticket/13801] Updated event description [ci skip] PHPBB3-13801 --- phpBB/phpbb/textformatter/s9e/parser.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index ee033f6d21..b7d0b2b90b 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -56,8 +56,9 @@ class parser implements \phpbb\textformatter\parser_interface * Configure the parser service * * Can be used to: - * - register variables or custom parsers in the s9e\TextFormatter - * - configure the s9e\TextFormatter parser + * - toggle features or BBCodes + * - register variables or custom parsers in the s9e\TextFormatter parser + * - configure the s9e\TextFormatter parser's runtime settings * * @event core.text_formatter_s9e_parser_setup * @var \phpbb\textformatter\s9e\parser parser This parser service -- cgit v1.2.1 From 7a65b0cc4ea172446064d4f83b74438a9dacef09 Mon Sep 17 00:00:00 2001 From: Nicofuma Date: Tue, 19 May 2015 21:59:41 +0200 Subject: [ticket/13849] Fix development environment PHPBB3-13849 --- phpBB/phpbb/di/extension/core.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index c9e2d4dc5b..91b321a684 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -71,7 +71,7 @@ class core extends Extension // Set the Twig options if defined in the environment $definition = $container->getDefinition('template.twig.environment'); - $twig_environment_options = $definition->getArgument(6); + $twig_environment_options = $definition->getArgument(7); if ($config['twig']['debug']) { $twig_environment_options['debug'] = true; @@ -80,8 +80,8 @@ class core extends Extension { $twig_environment_options['auto_reload'] = true; } - // Replace the 6th argument, the options passed to the environment - $definition->replaceArgument(6, $twig_environment_options); + // Replace the 8th argument, the options passed to the environment + $definition->replaceArgument(7, $twig_environment_options); if ($config['twig']['enable_debug_extension']) { -- cgit v1.2.1 From 077051fef56f0d9b504a2593dc84a3d05ef02e18 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 May 2015 00:23:42 +0200 Subject: [ticket/13844] Add events PHPBB3-13844 --- phpBB/phpbb/help/controller/controller.php | 7 +--- phpBB/phpbb/help/manager.php | 61 +++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/help/controller/controller.php b/phpBB/phpbb/help/controller/controller.php index 743a9c7fde..29494205a9 100644 --- a/phpBB/phpbb/help/controller/controller.php +++ b/phpBB/phpbb/help/controller/controller.php @@ -21,9 +21,6 @@ abstract class controller /** @var \phpbb\controller\helper */ protected $helper; - /** @var \phpbb\event\dispatcher_interface */ - protected $dispatcher; - /** @var \phpbb\help\manager */ protected $manager; @@ -43,17 +40,15 @@ abstract class controller * Constructor * * @param \phpbb\controller\helper $helper - * @param \phpbb\event\dispatcher_interface $dispatcher * @param \phpbb\help\manager $manager * @param \phpbb\template\template $template * @param \phpbb\language\language $language * @param string $root_path * @param string $php_ext */ - public function __construct(\phpbb\controller\helper $helper, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\help\manager $manager, \phpbb\template\template $template, \phpbb\language\language $language, $root_path, $php_ext) + public function __construct(\phpbb\controller\helper $helper, \phpbb\help\manager $manager, \phpbb\template\template $template, \phpbb\language\language $language, $root_path, $php_ext) { $this->helper = $helper; - $this->dispatcher = $dispatcher; $this->manager = $manager; $this->template = $template; $this->language = $language; diff --git a/phpBB/phpbb/help/manager.php b/phpBB/phpbb/help/manager.php index a7320563a8..d6991c0733 100644 --- a/phpBB/phpbb/help/manager.php +++ b/phpBB/phpbb/help/manager.php @@ -18,25 +18,30 @@ namespace phpbb\help; */ class manager { - /** @var \phpbb\template\template */ - protected $template; + /** @var \phpbb\event\dispatcher */ + protected $dispatcher; /** @var \phpbb\language\language */ protected $language; + /** @var \phpbb\template\template */ + protected $template; + /** @var bool */ protected $switched_column; /** * Constructor * - * @param \phpbb\template\template $template + * @param \phpbb\event\dispatcher $dispatcher * @param \phpbb\language\language $language + * @param \phpbb\template\template $template */ - public function __construct(\phpbb\template\template $template, \phpbb\language\language $language) + public function __construct(\phpbb\event\dispatcher $dispatcher, \phpbb\language\language $language, \phpbb\template\template $template) { - $this->template = $template; + $this->dispatcher = $dispatcher; $this->language = $language; + $this->template = $template; } /** @@ -47,6 +52,18 @@ class manager */ public function add_block($block_name, $switch_column = false, $questions = array()) { + /** + * You can use this event to add a block before the current one. + * + * @event core.help_manager_add_block_before + * @var string block_name Language key of the block headline + * @var bool switch_column Should we switch the menu column before this headline + * @var array questions Array with questions + * @since 3.2.0-a1 + */ + $vars = array('block_name', 'switch_column', 'questions'); + extract($this->dispatcher->trigger_event('core.help_manager_add_block_before', compact($vars))); + $this->template->assign_block_vars('faq_block', array( 'BLOCK_TITLE' => $this->language->lang($block_name), 'SWITCH_COLUMN' => !$this->switched_column && $switch_column, @@ -58,6 +75,18 @@ class manager } $this->switched_column = $this->switched_column || $switch_column; + + /** + * You can use this event to add a block after the current one. + * + * @event core.help_manager_add_block_after + * @var string block_name Language key of the block headline + * @var bool switch_column Should we switch the menu column before this headline + * @var array questions Array with questions + * @since 3.2.0-a1 + */ + $vars = array('block_name', 'switch_column', 'questions'); + extract($this->dispatcher->trigger_event('core.help_manager_add_block_after', compact($vars))); } /** @@ -68,10 +97,32 @@ class manager */ public function add_question($question, $answer) { + /** + * You can use this event to add a question before the current one. + * + * @event core.help_manager_add_question_before + * @var string question Language key of the question + * @var string answer Language key of the answer + * @since 3.2.0-a1 + */ + $vars = array('question', 'answer'); + extract($this->dispatcher->trigger_event('core.help_manager_add_question_before', compact($vars))); + $this->template->assign_block_vars('faq_block.faq_row', array( 'FAQ_QUESTION' => $this->language->lang($question), 'FAQ_ANSWER' => $this->language->lang($answer), )); + + /** + * You can use this event to add a question after the current one. + * + * @event core.help_manager_add_question_after + * @var string question Language key of the question + * @var string answer Language key of the answer + * @since 3.2.0-a1 + */ + $vars = array('question', 'answer'); + extract($this->dispatcher->trigger_event('core.help_manager_add_question_after', compact($vars))); } /** -- cgit v1.2.1 From 92078dce3393ea705361e1c3c0a332db778ccb0a Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Wed, 29 Apr 2015 23:22:30 +0200 Subject: [ticket/11742] Removed tabs-to-space conversion in [code] PHPBB3-11742 --- phpBB/phpbb/textformatter/s9e/renderer.php | 43 ------------------------------ 1 file changed, 43 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 8999f1d25f..51bc44f339 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -234,10 +234,6 @@ class renderer implements \phpbb\textformatter\renderer_interface } $html = $this->renderer->render($xml); - if (stripos($html, 'replace_tabs_in_code($html); - } /** * Modify a rendered text @@ -253,45 +249,6 @@ class renderer implements \phpbb\textformatter\renderer_interface return $html; } - /** - * Replace tabs in code elements - * - * @see bbcode::bbcode_second_pass_code() - * - * @param string $html Original HTML - * @return string Modified HTML - */ - protected function replace_tabs_in_code($html) - { - return preg_replace_callback( - '((]*>)(.*?)())is', - function ($captures) - { - $code = $captures[2]; - - $code = str_replace("\t", '   ', $code); - $code = str_replace(' ', '  ', $code); - $code = str_replace(' ', '  ', $code); - $code = str_replace("\n ", "\n ", $code); - - // keep space at the beginning - if (!empty($code) && $code[0] == ' ') - { - $code = ' ' . substr($code, 1); - } - - // remove newline at the beginning - if (!empty($code) && $code[0] == "\n") - { - $code = substr($code, 1); - } - - return $captures[1] . $code . $captures[3]; - }, - $html - ); - } - /** * {@inheritdoc} */ -- cgit v1.2.1 From 715d365a5e776207e1dddac7e5ccc50aad5621f1 Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 23 May 2015 17:06:25 -0400 Subject: [ticket/13733] Only use migration classes that extension the base migration class. PHPBB3-13733 --- phpBB/phpbb/extension/base.php | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index 5bb530bad4..4bf19b37ed 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -137,6 +137,14 @@ class base implements \phpbb\extension\extension_interface $migrations = $this->extension_finder->get_classes_from_files($migrations); + foreach ($migrations as $key => $migration) + { + $reflector = new \ReflectionClass($migration); + if (!$reflector->isSubclassOf('\phpbb\db\migration\migration')) { + unset($migrations[$key]); + } + } + return $migrations; } } -- cgit v1.2.1 From 9e6f9c8a64d89f48d531c5b24d535025dd04f956 Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 23 May 2015 19:57:32 -0400 Subject: [ticket/13733] Handle nonexistent classes as well PHPBB3-13733 --- phpBB/phpbb/extension/base.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index 4bf19b37ed..8b4d747eaf 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -139,8 +139,9 @@ class base implements \phpbb\extension\extension_interface foreach ($migrations as $key => $migration) { - $reflector = new \ReflectionClass($migration); - if (!$reflector->isSubclassOf('\phpbb\db\migration\migration')) { + // If the class doesn't exist OR the class does not extend the migration class + // we need to skip it. + if (!class_exists($migration) || ($reflector = new \ReflectionClass($migration) && !$reflector->isSubclassOf('\phpbb\db\migration\migration'))) { unset($migrations[$key]); } } -- cgit v1.2.1 From 4ecc13af83718e26e02afc9b8516a506ca5a26e1 Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 23 May 2015 20:13:23 -0400 Subject: [ticket/13733] Properly handle nonexistent classes as well PHPBB3-13733 --- phpBB/phpbb/extension/base.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index 8b4d747eaf..8e717e1beb 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -139,11 +139,21 @@ class base implements \phpbb\extension\extension_interface foreach ($migrations as $key => $migration) { - // If the class doesn't exist OR the class does not extend the migration class - // we need to skip it. - if (!class_exists($migration) || ($reflector = new \ReflectionClass($migration) && !$reflector->isSubclassOf('\phpbb\db\migration\migration'))) { - unset($migrations[$key]); + // If the class exists and is a subclass of the + // \phpbb\db\migration\migration abstract class + // we skip it. + + // Otherwise, i.e. if it doesn't exist or it is + // not an extend the abstract class, we unset it + if (class_exists($migration)) { + $reflector = new \ReflectionClass($migration); + if ($reflector->isSubclassOf('\phpbb\db\migration\migration')) { + continue; + } + } + + unset($migrations[$key]); } return $migrations; -- cgit v1.2.1 From 65316cffafead1b0529dca50f4c110489615438a Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 23 May 2015 21:13:30 -0400 Subject: [ticket/13733] Allow tests the skip class validation PHPBB3-13733 --- phpBB/phpbb/extension/base.php | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index 8e717e1beb..ed190f6aa5 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -121,9 +121,11 @@ class base implements \phpbb\extension\extension_interface /** * Get the list of migration files from this extension * + * @var bool $validate_classes Whether or not to check that the migration + * class exists and extends the base migration class. * @return array */ - protected function get_migration_file_list() + protected function get_migration_file_list($validate_classes = true) { if ($this->migrations !== false) { @@ -137,23 +139,26 @@ class base implements \phpbb\extension\extension_interface $migrations = $this->extension_finder->get_classes_from_files($migrations); - foreach ($migrations as $key => $migration) + if ($validate_classes) { - // If the class exists and is a subclass of the - // \phpbb\db\migration\migration abstract class - // we skip it. - - // Otherwise, i.e. if it doesn't exist or it is - // not an extend the abstract class, we unset it - if (class_exists($migration)) { - $reflector = new \ReflectionClass($migration); - if ($reflector->isSubclassOf('\phpbb\db\migration\migration')) { - continue; + foreach ($migrations as $key => $migration) + { + // If the class exists and is a subclass of the + // \phpbb\db\migration\migration abstract class + // we skip it. + + // Otherwise, i.e. if it doesn't exist or it is + // not an extend the abstract class, we unset it + if (class_exists($migration)) { + $reflector = new \ReflectionClass($migration); + if ($reflector->isSubclassOf('\phpbb\db\migration\migration')) { + continue; + } + } + unset($migrations[$key]); } - - unset($migrations[$key]); } return $migrations; -- cgit v1.2.1 From c485540f537b61a1e95f72a35dbca40f0f9b1c24 Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 23 May 2015 21:38:59 -0400 Subject: [ticket/13733] Braces on their own lines PHPBB3-13733 --- phpBB/phpbb/extension/base.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index ed190f6aa5..5ce6983edf 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -149,9 +149,11 @@ class base implements \phpbb\extension\extension_interface // Otherwise, i.e. if it doesn't exist or it is // not an extend the abstract class, we unset it - if (class_exists($migration)) { + if (class_exists($migration)) + { $reflector = new \ReflectionClass($migration); - if ($reflector->isSubclassOf('\phpbb\db\migration\migration')) { + if ($reflector->isSubclassOf('\phpbb\db\migration\migration')) + { continue; } -- cgit v1.2.1 From 9dc1729e379691c97b319a12912dc48ad779a286 Mon Sep 17 00:00:00 2001 From: David King Date: Sun, 24 May 2015 01:32:01 -0400 Subject: [ticket/13733] Add isInstantiable() check. PHPBB3-13733 --- phpBB/phpbb/extension/base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index 5ce6983edf..40bd349c4d 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -152,7 +152,7 @@ class base implements \phpbb\extension\extension_interface if (class_exists($migration)) { $reflector = new \ReflectionClass($migration); - if ($reflector->isSubclassOf('\phpbb\db\migration\migration')) + if ($reflector->isSubclassOf('\phpbb\db\migration\migration') && $reflector->isInstantiable()) { continue; } -- cgit v1.2.1 From 8a077e0e943d87ee1d26b0501f0b9bcc472ab904 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 17 May 2015 20:15:06 +0200 Subject: [ticket/13847] Move quote generation to text_formatter.utils PHPBB3-13847 --- phpBB/phpbb/textformatter/s9e/utils.php | 37 +++++++++++++++++++++++++++ phpBB/phpbb/textformatter/utils_interface.php | 12 +++++++++ 2 files changed, 49 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index e21dedecc4..fe33c04da3 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -34,6 +34,43 @@ class utils implements \phpbb\textformatter\utils_interface return \s9e\TextFormatter\Utils::removeFormatting($xml); } + /** + * Return given string between quotes + * + * Will use either single- or double- quotes depending on whichever requires to be escaped. + * Quotes and backslashes are escaped with backslashes where necessary + * + * @param string $str Original string + * @return string Escaped string within quotes + */ + protected function enquote($str) + { + $quote = (strpos($str, '"') === false || strpos($str, "'") !== false) ? '"' : "'"; + + return $quote . addcslashes($str, '\\' . $quote) . $quote; + } + + /** + * {@inheritdoc} + */ + public function generate_quote($text, array $attributes = array()) + { + $quote = '[quote'; + if (isset($attributes['author'])) + { + // Add the author as the BBCode's default attribute + $quote .= '=' . $this->enquote($attributes['author']); + unset($attributes['author']); + } + foreach ($attributes as $name => $value) + { + $quote .= ' ' . $name . '=' . $this->enquote($value); + } + $quote .= ']' . $text . '[/quote]'; + + return $quote; + } + /** * Get a list of quote authors, limited to the outermost quotes * diff --git a/phpBB/phpbb/textformatter/utils_interface.php b/phpBB/phpbb/textformatter/utils_interface.php index 6d3fd13021..41a6ba2345 100644 --- a/phpBB/phpbb/textformatter/utils_interface.php +++ b/phpBB/phpbb/textformatter/utils_interface.php @@ -28,6 +28,18 @@ interface utils_interface */ public function clean_formatting($text); + /** + * Create a quote block for given text + * + * Possible attributes: + * - author + * + * @param string $text Quote's text + * @param array $attributes Quote's attributes + * @return string Quote block to be used in a new post/text + */ + public function generate_quote($text, array $attributes = array()); + /** * Get a list of quote authors, limited to the outermost quotes * -- cgit v1.2.1 From e50d9186ce15367e8f6e2aab5c04481ca0046ec6 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 19 May 2015 23:10:35 +0200 Subject: [ticket/13847] Changed enquote() logic to use whichever is the shortest Will enclose attribute values in single- or double- quotes depending on whichever requires the least escaping. Characters that need to be escaped are always escaped regardless. PHPBB3-13847 --- phpBB/phpbb/textformatter/s9e/utils.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index fe33c04da3..04df589930 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -37,7 +37,7 @@ class utils implements \phpbb\textformatter\utils_interface /** * Return given string between quotes * - * Will use either single- or double- quotes depending on whichever requires to be escaped. + * Will use either single- or double- quotes depending on whichever requires less escaping. * Quotes and backslashes are escaped with backslashes where necessary * * @param string $str Original string @@ -45,9 +45,10 @@ class utils implements \phpbb\textformatter\utils_interface */ protected function enquote($str) { - $quote = (strpos($str, '"') === false || strpos($str, "'") !== false) ? '"' : "'"; + $singleQuoted = "'" . addcslashes($str, "\\'") . "'"; + $doubleQuoted = '"' . addcslashes($str, '\\"') . '"'; - return $quote . addcslashes($str, '\\' . $quote) . $quote; + return (strlen($singleQuoted) < strlen($doubleQuoted)) ? $singleQuoted : $doubleQuoted; } /** -- cgit v1.2.1 From e0f7c225bc8f6cf8e62dcfc146bdd630e15b6e22 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 28 May 2015 12:23:45 +0200 Subject: [ticket/13860] Fixed array-to-string conversion PHPBB3-13860 --- phpBB/phpbb/textformatter/s9e/parser.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index b7d0b2b90b..838c211e56 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -227,7 +227,13 @@ class parser implements \phpbb\textformatter\parser_interface } } - return array_unique($errors); + // Deduplicate error messages. array_unique() only works on strings so we have to serialize + if (!empty($errors)) + { + $errors = array_map('unserialize', array_unique(array_map('serialize', $errors))); + } + + return $errors; } /** -- cgit v1.2.1 From 66c0e0c6a83fbf091aa078ab06dd6467c8c6aa11 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 4 May 2015 15:10:33 +0200 Subject: [ticket/13388] Integrate routing and di parameters resolution PHPBB3-13388 --- phpBB/phpbb/routing/router.php | 130 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 123 insertions(+), 7 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 2f89d4e884..ca9799ba3e 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -15,6 +15,9 @@ namespace phpbb\routing; use Symfony\Component\Config\ConfigCache; use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper; use Symfony\Component\Routing\Matcher\UrlMatcher; @@ -91,18 +94,23 @@ class router implements RouterInterface */ protected $filesystem; + /** + * @var ContainerInterface + */ + protected $container; + /** * Construct method * + * @param ContainerInterface $container DI container * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem helper - * @param string $phpbb_root_path phpBB root path - * @param string $php_ext PHP file extension - * @param string $environment Name of the current environment - * @param manager|null $extension_manager Extension manager - * @param array $routing_files Array of strings containing paths to YAML files - * holding route information + * @param string $phpbb_root_path phpBB root path + * @param string $php_ext PHP file extension + * @param string $environment Name of the current environment + * @param manager $extension_manager Extension manager + * @param array $routing_files Array of strings containing paths to YAML files holding route information */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path, $php_ext, $environment, manager $extension_manager = null, $routing_files = array()) + public function __construct(ContainerInterface $container, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path, $php_ext, $environment, manager $extension_manager = null, $routing_files = array()) { $this->filesystem = $filesystem; $this->extension_manager = $extension_manager; @@ -162,9 +170,117 @@ class router implements RouterInterface } } + $this->resolveParameters($this->route_collection); + return $this; } + /** + * Replaces placeholders with service container parameter values in: + * - the route defaults, + * - the route requirements, + * - the route path, + * - the route host, + * - the route schemes, + * - the route methods. + * + * @param RouteCollection $collection + */ + private function resolveParameters(RouteCollection $collection) + { + foreach ($collection as $route) + { + foreach ($route->getDefaults() as $name => $value) + { + $route->setDefault($name, $this->resolve($value)); + } + + foreach ($route->getRequirements() as $name => $value) + { + if ($name === '_scheme' || $name === '_method') + { + continue; // ignore deprecated requirements to not trigger deprecation warnings + } + + $route->setRequirement($name, $this->resolve($value)); + } + + $route->setPath($this->resolve($route->getPath())); + $route->setHost($this->resolve($route->getHost())); + + $schemes = array(); + foreach ($route->getSchemes() as $scheme) + { + $schemes = array_merge($schemes, explode('|', $this->resolve($scheme))); + } + + $route->setSchemes($schemes); + $methods = array(); + foreach ($route->getMethods() as $method) + { + $methods = array_merge($methods, explode('|', $this->resolve($method))); + } + + $route->setMethods($methods); + $route->setCondition($this->resolve($route->getCondition())); + } + } + /** + * Recursively replaces placeholders with the service container parameters. + * + * @param mixed $value The source which might contain "%placeholders%" + * + * @return mixed The source with the placeholders replaced by the container + * parameters. Arrays are resolved recursively. + * + * @throws ParameterNotFoundException When a placeholder does not exist as a container parameter + * @throws RuntimeException When a container value is not a string or a numeric value + */ + private function resolve($value) + { + if (is_array($value)) + { + foreach ($value as $key => $val) + { + $value[$key] = $this->resolve($val); + } + + return $value; + } + + if (!is_string($value)) + { + return $value; + } + + $container = $this->container; + $escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($container, $value) + { + // skip %% + if (!isset($match[1])) + { + return '%%'; + } + + $resolved = $container->getParameter($match[1]); + if (is_string($resolved) || is_numeric($resolved)) + { + return (string) $resolved; + } + + throw new RuntimeException(sprintf( + 'The container parameter "%s", used in the route configuration value "%s", '. + 'must be a string or numeric, but it is of type %s.', + $match[1], + $value, + gettype($resolved) + ) + ); + }, $value); + + return str_replace('%%', '%', $escapedValue); + } + /** * Get the list of routes * -- cgit v1.2.1 From 6656567424843d7118aba1eeb5fc0f4eb61a2e5a Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 29 May 2015 16:37:58 +0200 Subject: [ticket/13388] Address comments PHPBB3-13388 --- phpBB/phpbb/routing/router.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index ca9799ba3e..270b54c4ba 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -195,13 +195,12 @@ class router implements RouterInterface $route->setDefault($name, $this->resolve($value)); } + $requirements = $route->getRequirements(); + unset($requirements['_scheme']); + unset($requirements['_method']); + foreach ($route->getRequirements() as $name => $value) { - if ($name === '_scheme' || $name === '_method') - { - continue; // ignore deprecated requirements to not trigger deprecation warnings - } - $route->setRequirement($name, $this->resolve($value)); } -- cgit v1.2.1 From 80375c98f0f39a957b3348c9384fdc52ba27ea36 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 29 May 2015 16:52:21 +0200 Subject: [ticket/13388] Fix rebase PHPBB3-13388 --- phpBB/phpbb/routing/router.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 270b54c4ba..1c27e95e4d 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -112,6 +112,7 @@ class router implements RouterInterface */ public function __construct(ContainerInterface $container, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path, $php_ext, $environment, manager $extension_manager = null, $routing_files = array()) { + $this->container = $container; $this->filesystem = $filesystem; $this->extension_manager = $extension_manager; $this->routing_files = $routing_files; -- cgit v1.2.1 From d129ee6c947c6bf494166c47b2d04c7d66e41ab4 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 29 May 2015 16:53:54 +0200 Subject: [ticket/13388] Fix deprecations PHPBB3-13388 --- phpBB/phpbb/routing/router.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 1c27e95e4d..75726011c4 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -200,7 +200,7 @@ class router implements RouterInterface unset($requirements['_scheme']); unset($requirements['_method']); - foreach ($route->getRequirements() as $name => $value) + foreach ($requirements as $name => $value) { $route->setRequirement($name, $this->resolve($value)); } -- cgit v1.2.1 From 41efc55be99a3a56ed8e1af7ab1bcb0f9d9d88ea Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 30 May 2015 12:27:31 +0200 Subject: [ticket/13896] Fix coding style PHPBB3-13896 --- phpBB/phpbb/language/language_file_loader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/language/language_file_loader.php b/phpBB/phpbb/language/language_file_loader.php index 9862cfc3aa..359202fd63 100644 --- a/phpBB/phpbb/language/language_file_loader.php +++ b/phpBB/phpbb/language/language_file_loader.php @@ -154,7 +154,7 @@ class language_file_loader * * @return string Relative path to language file * - * @throws \phpbb\language\exception\language_file_not_found When the path to the file cannot be resolved + * @throws language_file_not_found When the path to the file cannot be resolved */ protected function get_language_file_path($path, $filename, $locales) { -- cgit v1.2.1 From ea7114e78528f95fae077568573f2b3363f9aab1 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 30 May 2015 13:14:27 +0200 Subject: [ticket/13388] Fix coding style PHPBB3-13388 --- phpBB/phpbb/routing/router.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 75726011c4..5af005769f 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -225,6 +225,7 @@ class router implements RouterInterface $route->setCondition($this->resolve($route->getCondition())); } } + /** * Recursively replaces placeholders with the service container parameters. * -- cgit v1.2.1 From de52580a78bcab47a2311f3993fd9952f963d563 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 1 May 2015 05:15:56 +0200 Subject: [ticket/13803] WIP implementation PHPBB3-13803 --- phpBB/phpbb/textreparser/base.php | 97 +++++++++++++++++++++++++ phpBB/phpbb/textreparser/forumdescription.php | 63 ++++++++++++++++ phpBB/phpbb/textreparser/forumrules.php | 63 ++++++++++++++++ phpBB/phpbb/textreparser/groupdescription.php | 63 ++++++++++++++++ phpBB/phpbb/textreparser/pmtext.php | 56 ++++++++++++++ phpBB/phpbb/textreparser/posttext.php | 56 ++++++++++++++ phpBB/phpbb/textreparser/reparser_interface.php | 32 ++++++++ 7 files changed, 430 insertions(+) create mode 100644 phpBB/phpbb/textreparser/base.php create mode 100644 phpBB/phpbb/textreparser/forumdescription.php create mode 100644 phpBB/phpbb/textreparser/forumrules.php create mode 100644 phpBB/phpbb/textreparser/groupdescription.php create mode 100644 phpBB/phpbb/textreparser/pmtext.php create mode 100644 phpBB/phpbb/textreparser/posttext.php create mode 100644 phpBB/phpbb/textreparser/reparser_interface.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php new file mode 100644 index 0000000000..6aa20d0015 --- /dev/null +++ b/phpBB/phpbb/textreparser/base.php @@ -0,0 +1,97 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +abstract class base implements reparser_interface +{ + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * Constructor + * + * @param \phpbb\db\driver\driver_interface $db Database connection + */ + public function __construct(\phpbb\db\driver\driver_interface $db) + { + $this->db = $db; + } + + /** + * {@inheritdoc} + */ + abstract public function get_max_id(); + + /** + * Return all records in given range + * + * @param integer $min_id Lower bound + * @param integer $max_id Upper bound + * @return array Array of record + */ + abstract protected function get_records($min_id, $max_id); + + /** + * {@inheritdoc} + */ + public function reparse_range($min_id, $max_id) + { + foreach ($this->get_records($min_id, $max_id) as $record) + { + $this->reparse_record($record); + } + } + + /** + * Reparse given record + * + * @param array $record Associative array containing the record's data + */ + protected function reparse_record(array $record) + { + $unparsed = array_merge( + $record, + generate_text_for_edit( + $record['text'], + $record['bbcode_uid'], + OPTION_FLAG_BBCODE | OPTION_FLAG_SMILIES | OPTION_FLAG_LINKS + ) + ); + $bitfield = $flags = null; + $parsed_text = $unparsed['text']; + generate_text_for_storage( + $parsed_text, + $unparsed['bbcode_uid'], + $bitfield, + $flags, + $unparsed['enable_bbcode'], + $unparsed['enable_smilies'], + $unparsed['enable_magic_url'] + ); + + // Save the new text if it has changed + if ($parsed_text !== $record['text']) + { + $record['text'] = $parsed_text; + $this->save_record($record); + } + } + + /** + * {@inheritdoc} + */ + abstract protected function save_record(array $record); +} diff --git a/phpBB/phpbb/textreparser/forumdescription.php b/phpBB/phpbb/textreparser/forumdescription.php new file mode 100644 index 0000000000..b715abd825 --- /dev/null +++ b/phpBB/phpbb/textreparser/forumdescription.php @@ -0,0 +1,63 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +class forumdescription extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(forum_id) AS max_id FROM ' . FORUMS_TABLE; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $sql = 'SELECT forum_id AS id, forum_desc AS text, forum_desc_uid AS bbcode_uid + FROM ' . FORUMS_TABLE . ' + WHERE forum_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Those fields are not saved to the database, we need to guess their original value + $row['enable_bbcode'] = !empty($row['bbcode_uid']); + $row['enable_smilies'] = (strpos($row['text'], '') !== false); + } + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . FORUMS_TABLE . " + SET forum_desc = '" . $this->db->sql_escape($record['text']) . "' + WHERE forum_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/forumrules.php b/phpBB/phpbb/textreparser/forumrules.php new file mode 100644 index 0000000000..c0538f6cce --- /dev/null +++ b/phpBB/phpbb/textreparser/forumrules.php @@ -0,0 +1,63 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +class forumrules extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(forum_id) AS max_id FROM ' . FORUMS_TABLE; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $sql = 'SELECT forum_id AS id, forum_rules AS text, forum_rules_uid AS bbcode_uid + FROM ' . FORUMS_TABLE . ' + WHERE forum_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Those fields are not saved to the database, we need to guess their original value + $row['enable_bbcode'] = !empty($row['bbcode_uid']); + $row['enable_smilies'] = (strpos($row['text'], '') !== false); + } + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . FORUMS_TABLE . " + SET forum_rules = '" . $this->db->sql_escape($record['text']) . "' + WHERE forum_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/groupdescription.php b/phpBB/phpbb/textreparser/groupdescription.php new file mode 100644 index 0000000000..608cc806b6 --- /dev/null +++ b/phpBB/phpbb/textreparser/groupdescription.php @@ -0,0 +1,63 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +class groupdescription extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(group_id) AS max_id FROM ' . GROUPS_TABLE; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $sql = 'SELECT group_id AS id, group_desc AS text, group_desc_uid AS bbcode_uid + FROM ' . GROUPS_TABLE . ' + WHERE group_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Those fields are not saved to the database, we need to guess their original value + $row['enable_bbcode'] = !empty($row['bbcode_uid']); + $row['enable_smilies'] = (strpos($row['text'], '') !== false); + } + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . GROUPS_TABLE . " + SET group_desc = '" . $this->db->sql_escape($record['text']) . "' + WHERE group_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/pmtext.php b/phpBB/phpbb/textreparser/pmtext.php new file mode 100644 index 0000000000..e1b27e60fe --- /dev/null +++ b/phpBB/phpbb/textreparser/pmtext.php @@ -0,0 +1,56 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +class pmtext extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(msg_id) AS max_id FROM ' . PRIVMSGS_TABLE; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $sql = 'SELECT msg_id AS id, enable_bbcode, enable_smilies, enable_magic_url, message_text AS text, bbcode_uid + FROM ' . PRIVMSGS_TABLE . ' + WHERE msg_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . PRIVMSGS_TABLE . " + SET message_text = '" . $this->db->sql_escape($record['text']) . "' + WHERE msg_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/posttext.php b/phpBB/phpbb/textreparser/posttext.php new file mode 100644 index 0000000000..916fc94bfa --- /dev/null +++ b/phpBB/phpbb/textreparser/posttext.php @@ -0,0 +1,56 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +class posttext extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(post_id) AS max_id FROM ' . POSTS_TABLE; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $sql = 'SELECT post_id AS id, enable_bbcode, enable_smilies, enable_magic_url, post_text AS text, bbcode_uid + FROM ' . POSTS_TABLE . ' + WHERE post_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . POSTS_TABLE . " + SET post_text = '" . $this->db->sql_escape($record['text']) . "' + WHERE post_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/reparser_interface.php b/phpBB/phpbb/textreparser/reparser_interface.php new file mode 100644 index 0000000000..20f8d92b1a --- /dev/null +++ b/phpBB/phpbb/textreparser/reparser_interface.php @@ -0,0 +1,32 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +interface reparser_interface +{ + /** + * Return the highest ID for all existing records + * + * @return integer + */ + public function get_max_id(); + + /** + * Reparse all records in given range + * + * @param integer $min_id Lower bound + * @param integer $max_id Upper bound + */ + public function reparse_range($min_id, $max_id); +} -- cgit v1.2.1 From e11ae7e9cd5573658b763b1ef72cb889f547f2dd Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 1 May 2015 05:32:48 +0200 Subject: [ticket/13803] Hyphenated class names PHPBB3-13803 --- phpBB/phpbb/textreparser/forum_description.php | 63 ++++++++++++++++++++++++++ phpBB/phpbb/textreparser/forum_rules.php | 63 ++++++++++++++++++++++++++ phpBB/phpbb/textreparser/forumdescription.php | 63 -------------------------- phpBB/phpbb/textreparser/forumrules.php | 63 -------------------------- phpBB/phpbb/textreparser/group_description.php | 63 ++++++++++++++++++++++++++ phpBB/phpbb/textreparser/groupdescription.php | 63 -------------------------- phpBB/phpbb/textreparser/pm_text.php | 56 +++++++++++++++++++++++ phpBB/phpbb/textreparser/pmtext.php | 56 ----------------------- phpBB/phpbb/textreparser/post_text.php | 56 +++++++++++++++++++++++ phpBB/phpbb/textreparser/posttext.php | 56 ----------------------- 10 files changed, 301 insertions(+), 301 deletions(-) create mode 100644 phpBB/phpbb/textreparser/forum_description.php create mode 100644 phpBB/phpbb/textreparser/forum_rules.php delete mode 100644 phpBB/phpbb/textreparser/forumdescription.php delete mode 100644 phpBB/phpbb/textreparser/forumrules.php create mode 100644 phpBB/phpbb/textreparser/group_description.php delete mode 100644 phpBB/phpbb/textreparser/groupdescription.php create mode 100644 phpBB/phpbb/textreparser/pm_text.php delete mode 100644 phpBB/phpbb/textreparser/pmtext.php create mode 100644 phpBB/phpbb/textreparser/post_text.php delete mode 100644 phpBB/phpbb/textreparser/posttext.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/forum_description.php b/phpBB/phpbb/textreparser/forum_description.php new file mode 100644 index 0000000000..493f8d6c94 --- /dev/null +++ b/phpBB/phpbb/textreparser/forum_description.php @@ -0,0 +1,63 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +class forum_description extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(forum_id) AS max_id FROM ' . FORUMS_TABLE; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $sql = 'SELECT forum_id AS id, forum_desc AS text, forum_desc_uid AS bbcode_uid + FROM ' . FORUMS_TABLE . ' + WHERE forum_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Those fields are not saved to the database, we need to guess their original value + $row['enable_bbcode'] = !empty($row['bbcode_uid']); + $row['enable_smilies'] = (strpos($row['text'], '') !== false); + } + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . FORUMS_TABLE . " + SET forum_desc = '" . $this->db->sql_escape($record['text']) . "' + WHERE forum_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/forum_rules.php b/phpBB/phpbb/textreparser/forum_rules.php new file mode 100644 index 0000000000..5a3cc7b405 --- /dev/null +++ b/phpBB/phpbb/textreparser/forum_rules.php @@ -0,0 +1,63 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +class forum_rules extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(forum_id) AS max_id FROM ' . FORUMS_TABLE; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $sql = 'SELECT forum_id AS id, forum_rules AS text, forum_rules_uid AS bbcode_uid + FROM ' . FORUMS_TABLE . ' + WHERE forum_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Those fields are not saved to the database, we need to guess their original value + $row['enable_bbcode'] = !empty($row['bbcode_uid']); + $row['enable_smilies'] = (strpos($row['text'], '') !== false); + } + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . FORUMS_TABLE . " + SET forum_rules = '" . $this->db->sql_escape($record['text']) . "' + WHERE forum_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/forumdescription.php b/phpBB/phpbb/textreparser/forumdescription.php deleted file mode 100644 index b715abd825..0000000000 --- a/phpBB/phpbb/textreparser/forumdescription.php +++ /dev/null @@ -1,63 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textreparser; - -class forumdescription extends base -{ - /** - * {@inheritdoc} - */ - public function get_max_id() - { - $sql = 'SELECT MAX(forum_id) AS max_id FROM ' . FORUMS_TABLE; - $result = $this->db->sql_query($sql); - $max_id = (int) $this->db->sql_fetchfield('max_id'); - $this->db->sql_freeresult($result); - - return $max_id; - } - - /** - * {@inheritdoc} - */ - protected function get_records($min_id, $max_id) - { - $sql = 'SELECT forum_id AS id, forum_desc AS text, forum_desc_uid AS bbcode_uid - FROM ' . FORUMS_TABLE . ' - WHERE forum_id BETWEEN ' . $min_id . ' AND ' . $max_id; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // Those fields are not saved to the database, we need to guess their original value - $row['enable_bbcode'] = !empty($row['bbcode_uid']); - $row['enable_smilies'] = (strpos($row['text'], '') !== false); - } - $records = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - - return $records; - } - - /** - * {@inheritdoc} - */ - protected function save_record(array $record) - { - $sql = 'UPDATE ' . FORUMS_TABLE . " - SET forum_desc = '" . $this->db->sql_escape($record['text']) . "' - WHERE forum_id = " . $record['id']; - $this->db->sql_query($sql); - } -} diff --git a/phpBB/phpbb/textreparser/forumrules.php b/phpBB/phpbb/textreparser/forumrules.php deleted file mode 100644 index c0538f6cce..0000000000 --- a/phpBB/phpbb/textreparser/forumrules.php +++ /dev/null @@ -1,63 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textreparser; - -class forumrules extends base -{ - /** - * {@inheritdoc} - */ - public function get_max_id() - { - $sql = 'SELECT MAX(forum_id) AS max_id FROM ' . FORUMS_TABLE; - $result = $this->db->sql_query($sql); - $max_id = (int) $this->db->sql_fetchfield('max_id'); - $this->db->sql_freeresult($result); - - return $max_id; - } - - /** - * {@inheritdoc} - */ - protected function get_records($min_id, $max_id) - { - $sql = 'SELECT forum_id AS id, forum_rules AS text, forum_rules_uid AS bbcode_uid - FROM ' . FORUMS_TABLE . ' - WHERE forum_id BETWEEN ' . $min_id . ' AND ' . $max_id; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // Those fields are not saved to the database, we need to guess their original value - $row['enable_bbcode'] = !empty($row['bbcode_uid']); - $row['enable_smilies'] = (strpos($row['text'], '') !== false); - } - $records = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - - return $records; - } - - /** - * {@inheritdoc} - */ - protected function save_record(array $record) - { - $sql = 'UPDATE ' . FORUMS_TABLE . " - SET forum_rules = '" . $this->db->sql_escape($record['text']) . "' - WHERE forum_id = " . $record['id']; - $this->db->sql_query($sql); - } -} diff --git a/phpBB/phpbb/textreparser/group_description.php b/phpBB/phpbb/textreparser/group_description.php new file mode 100644 index 0000000000..61354c832b --- /dev/null +++ b/phpBB/phpbb/textreparser/group_description.php @@ -0,0 +1,63 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +class group_description extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(group_id) AS max_id FROM ' . GROUPS_TABLE; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $sql = 'SELECT group_id AS id, group_desc AS text, group_desc_uid AS bbcode_uid + FROM ' . GROUPS_TABLE . ' + WHERE group_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Those fields are not saved to the database, we need to guess their original value + $row['enable_bbcode'] = !empty($row['bbcode_uid']); + $row['enable_smilies'] = (strpos($row['text'], '') !== false); + } + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . GROUPS_TABLE . " + SET group_desc = '" . $this->db->sql_escape($record['text']) . "' + WHERE group_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/groupdescription.php b/phpBB/phpbb/textreparser/groupdescription.php deleted file mode 100644 index 608cc806b6..0000000000 --- a/phpBB/phpbb/textreparser/groupdescription.php +++ /dev/null @@ -1,63 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textreparser; - -class groupdescription extends base -{ - /** - * {@inheritdoc} - */ - public function get_max_id() - { - $sql = 'SELECT MAX(group_id) AS max_id FROM ' . GROUPS_TABLE; - $result = $this->db->sql_query($sql); - $max_id = (int) $this->db->sql_fetchfield('max_id'); - $this->db->sql_freeresult($result); - - return $max_id; - } - - /** - * {@inheritdoc} - */ - protected function get_records($min_id, $max_id) - { - $sql = 'SELECT group_id AS id, group_desc AS text, group_desc_uid AS bbcode_uid - FROM ' . GROUPS_TABLE . ' - WHERE group_id BETWEEN ' . $min_id . ' AND ' . $max_id; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // Those fields are not saved to the database, we need to guess their original value - $row['enable_bbcode'] = !empty($row['bbcode_uid']); - $row['enable_smilies'] = (strpos($row['text'], '') !== false); - } - $records = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - - return $records; - } - - /** - * {@inheritdoc} - */ - protected function save_record(array $record) - { - $sql = 'UPDATE ' . GROUPS_TABLE . " - SET group_desc = '" . $this->db->sql_escape($record['text']) . "' - WHERE group_id = " . $record['id']; - $this->db->sql_query($sql); - } -} diff --git a/phpBB/phpbb/textreparser/pm_text.php b/phpBB/phpbb/textreparser/pm_text.php new file mode 100644 index 0000000000..b02cb0083f --- /dev/null +++ b/phpBB/phpbb/textreparser/pm_text.php @@ -0,0 +1,56 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +class pm_text extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(msg_id) AS max_id FROM ' . PRIVMSGS_TABLE; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $sql = 'SELECT msg_id AS id, enable_bbcode, enable_smilies, enable_magic_url, message_text AS text, bbcode_uid + FROM ' . PRIVMSGS_TABLE . ' + WHERE msg_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . PRIVMSGS_TABLE . " + SET message_text = '" . $this->db->sql_escape($record['text']) . "' + WHERE msg_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/pmtext.php b/phpBB/phpbb/textreparser/pmtext.php deleted file mode 100644 index e1b27e60fe..0000000000 --- a/phpBB/phpbb/textreparser/pmtext.php +++ /dev/null @@ -1,56 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textreparser; - -class pmtext extends base -{ - /** - * {@inheritdoc} - */ - public function get_max_id() - { - $sql = 'SELECT MAX(msg_id) AS max_id FROM ' . PRIVMSGS_TABLE; - $result = $this->db->sql_query($sql); - $max_id = (int) $this->db->sql_fetchfield('max_id'); - $this->db->sql_freeresult($result); - - return $max_id; - } - - /** - * {@inheritdoc} - */ - protected function get_records($min_id, $max_id) - { - $sql = 'SELECT msg_id AS id, enable_bbcode, enable_smilies, enable_magic_url, message_text AS text, bbcode_uid - FROM ' . PRIVMSGS_TABLE . ' - WHERE msg_id BETWEEN ' . $min_id . ' AND ' . $max_id; - $result = $this->db->sql_query($sql); - $records = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - - return $records; - } - - /** - * {@inheritdoc} - */ - protected function save_record(array $record) - { - $sql = 'UPDATE ' . PRIVMSGS_TABLE . " - SET message_text = '" . $this->db->sql_escape($record['text']) . "' - WHERE msg_id = " . $record['id']; - $this->db->sql_query($sql); - } -} diff --git a/phpBB/phpbb/textreparser/post_text.php b/phpBB/phpbb/textreparser/post_text.php new file mode 100644 index 0000000000..288bb0966b --- /dev/null +++ b/phpBB/phpbb/textreparser/post_text.php @@ -0,0 +1,56 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +class post_text extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(post_id) AS max_id FROM ' . POSTS_TABLE; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $sql = 'SELECT post_id AS id, enable_bbcode, enable_smilies, enable_magic_url, post_text AS text, bbcode_uid + FROM ' . POSTS_TABLE . ' + WHERE post_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . POSTS_TABLE . " + SET post_text = '" . $this->db->sql_escape($record['text']) . "' + WHERE post_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/posttext.php b/phpBB/phpbb/textreparser/posttext.php deleted file mode 100644 index 916fc94bfa..0000000000 --- a/phpBB/phpbb/textreparser/posttext.php +++ /dev/null @@ -1,56 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textreparser; - -class posttext extends base -{ - /** - * {@inheritdoc} - */ - public function get_max_id() - { - $sql = 'SELECT MAX(post_id) AS max_id FROM ' . POSTS_TABLE; - $result = $this->db->sql_query($sql); - $max_id = (int) $this->db->sql_fetchfield('max_id'); - $this->db->sql_freeresult($result); - - return $max_id; - } - - /** - * {@inheritdoc} - */ - protected function get_records($min_id, $max_id) - { - $sql = 'SELECT post_id AS id, enable_bbcode, enable_smilies, enable_magic_url, post_text AS text, bbcode_uid - FROM ' . POSTS_TABLE . ' - WHERE post_id BETWEEN ' . $min_id . ' AND ' . $max_id; - $result = $this->db->sql_query($sql); - $records = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - - return $records; - } - - /** - * {@inheritdoc} - */ - protected function save_record(array $record) - { - $sql = 'UPDATE ' . POSTS_TABLE . " - SET post_text = '" . $this->db->sql_escape($record['text']) . "' - WHERE post_id = " . $record['id']; - $this->db->sql_query($sql); - } -} -- cgit v1.2.1 From 986af43f37342953bff548630aa33904c21234f4 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 1 May 2015 08:47:01 +0200 Subject: [ticket/13803] Added plugins PHPBB3-13803 --- phpBB/phpbb/textreparser/base.php | 15 --- phpBB/phpbb/textreparser/forum_description.php | 63 ---------- phpBB/phpbb/textreparser/forum_rules.php | 63 ---------- phpBB/phpbb/textreparser/group_description.php | 63 ---------- .../textreparser/plugins/admin_contact_info.php | 69 +++++++++++ .../textreparser/plugins/forum_description.php | 37 ++++++ phpBB/phpbb/textreparser/plugins/forum_rules.php | 37 ++++++ .../textreparser/plugins/group_description.php | 37 ++++++ phpBB/phpbb/textreparser/plugins/pm_text.php | 40 +++++++ phpBB/phpbb/textreparser/plugins/poll_option.php | 50 ++++++++ phpBB/phpbb/textreparser/plugins/poll_title.php | 50 ++++++++ phpBB/phpbb/textreparser/plugins/post_text.php | 40 +++++++ .../phpbb/textreparser/plugins/user_signature.php | 37 ++++++ phpBB/phpbb/textreparser/pm_text.php | 56 --------- phpBB/phpbb/textreparser/post_text.php | 56 --------- phpBB/phpbb/textreparser/row_based_plugin.php | 128 +++++++++++++++++++++ 16 files changed, 525 insertions(+), 316 deletions(-) delete mode 100644 phpBB/phpbb/textreparser/forum_description.php delete mode 100644 phpBB/phpbb/textreparser/forum_rules.php delete mode 100644 phpBB/phpbb/textreparser/group_description.php create mode 100644 phpBB/phpbb/textreparser/plugins/admin_contact_info.php create mode 100644 phpBB/phpbb/textreparser/plugins/forum_description.php create mode 100644 phpBB/phpbb/textreparser/plugins/forum_rules.php create mode 100644 phpBB/phpbb/textreparser/plugins/group_description.php create mode 100644 phpBB/phpbb/textreparser/plugins/pm_text.php create mode 100644 phpBB/phpbb/textreparser/plugins/poll_option.php create mode 100644 phpBB/phpbb/textreparser/plugins/poll_title.php create mode 100644 phpBB/phpbb/textreparser/plugins/post_text.php create mode 100644 phpBB/phpbb/textreparser/plugins/user_signature.php delete mode 100644 phpBB/phpbb/textreparser/pm_text.php delete mode 100644 phpBB/phpbb/textreparser/post_text.php create mode 100644 phpBB/phpbb/textreparser/row_based_plugin.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php index 6aa20d0015..7d1e12c52d 100644 --- a/phpBB/phpbb/textreparser/base.php +++ b/phpBB/phpbb/textreparser/base.php @@ -15,21 +15,6 @@ namespace phpbb\textreparser; abstract class base implements reparser_interface { - /** - * @var \phpbb\db\driver\driver_interface - */ - protected $db; - - /** - * Constructor - * - * @param \phpbb\db\driver\driver_interface $db Database connection - */ - public function __construct(\phpbb\db\driver\driver_interface $db) - { - $this->db = $db; - } - /** * {@inheritdoc} */ diff --git a/phpBB/phpbb/textreparser/forum_description.php b/phpBB/phpbb/textreparser/forum_description.php deleted file mode 100644 index 493f8d6c94..0000000000 --- a/phpBB/phpbb/textreparser/forum_description.php +++ /dev/null @@ -1,63 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textreparser; - -class forum_description extends base -{ - /** - * {@inheritdoc} - */ - public function get_max_id() - { - $sql = 'SELECT MAX(forum_id) AS max_id FROM ' . FORUMS_TABLE; - $result = $this->db->sql_query($sql); - $max_id = (int) $this->db->sql_fetchfield('max_id'); - $this->db->sql_freeresult($result); - - return $max_id; - } - - /** - * {@inheritdoc} - */ - protected function get_records($min_id, $max_id) - { - $sql = 'SELECT forum_id AS id, forum_desc AS text, forum_desc_uid AS bbcode_uid - FROM ' . FORUMS_TABLE . ' - WHERE forum_id BETWEEN ' . $min_id . ' AND ' . $max_id; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // Those fields are not saved to the database, we need to guess their original value - $row['enable_bbcode'] = !empty($row['bbcode_uid']); - $row['enable_smilies'] = (strpos($row['text'], '') !== false); - } - $records = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - - return $records; - } - - /** - * {@inheritdoc} - */ - protected function save_record(array $record) - { - $sql = 'UPDATE ' . FORUMS_TABLE . " - SET forum_desc = '" . $this->db->sql_escape($record['text']) . "' - WHERE forum_id = " . $record['id']; - $this->db->sql_query($sql); - } -} diff --git a/phpBB/phpbb/textreparser/forum_rules.php b/phpBB/phpbb/textreparser/forum_rules.php deleted file mode 100644 index 5a3cc7b405..0000000000 --- a/phpBB/phpbb/textreparser/forum_rules.php +++ /dev/null @@ -1,63 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textreparser; - -class forum_rules extends base -{ - /** - * {@inheritdoc} - */ - public function get_max_id() - { - $sql = 'SELECT MAX(forum_id) AS max_id FROM ' . FORUMS_TABLE; - $result = $this->db->sql_query($sql); - $max_id = (int) $this->db->sql_fetchfield('max_id'); - $this->db->sql_freeresult($result); - - return $max_id; - } - - /** - * {@inheritdoc} - */ - protected function get_records($min_id, $max_id) - { - $sql = 'SELECT forum_id AS id, forum_rules AS text, forum_rules_uid AS bbcode_uid - FROM ' . FORUMS_TABLE . ' - WHERE forum_id BETWEEN ' . $min_id . ' AND ' . $max_id; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // Those fields are not saved to the database, we need to guess their original value - $row['enable_bbcode'] = !empty($row['bbcode_uid']); - $row['enable_smilies'] = (strpos($row['text'], '') !== false); - } - $records = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - - return $records; - } - - /** - * {@inheritdoc} - */ - protected function save_record(array $record) - { - $sql = 'UPDATE ' . FORUMS_TABLE . " - SET forum_rules = '" . $this->db->sql_escape($record['text']) . "' - WHERE forum_id = " . $record['id']; - $this->db->sql_query($sql); - } -} diff --git a/phpBB/phpbb/textreparser/group_description.php b/phpBB/phpbb/textreparser/group_description.php deleted file mode 100644 index 61354c832b..0000000000 --- a/phpBB/phpbb/textreparser/group_description.php +++ /dev/null @@ -1,63 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textreparser; - -class group_description extends base -{ - /** - * {@inheritdoc} - */ - public function get_max_id() - { - $sql = 'SELECT MAX(group_id) AS max_id FROM ' . GROUPS_TABLE; - $result = $this->db->sql_query($sql); - $max_id = (int) $this->db->sql_fetchfield('max_id'); - $this->db->sql_freeresult($result); - - return $max_id; - } - - /** - * {@inheritdoc} - */ - protected function get_records($min_id, $max_id) - { - $sql = 'SELECT group_id AS id, group_desc AS text, group_desc_uid AS bbcode_uid - FROM ' . GROUPS_TABLE . ' - WHERE group_id BETWEEN ' . $min_id . ' AND ' . $max_id; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // Those fields are not saved to the database, we need to guess their original value - $row['enable_bbcode'] = !empty($row['bbcode_uid']); - $row['enable_smilies'] = (strpos($row['text'], '') !== false); - } - $records = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - - return $records; - } - - /** - * {@inheritdoc} - */ - protected function save_record(array $record) - { - $sql = 'UPDATE ' . GROUPS_TABLE . " - SET group_desc = '" . $this->db->sql_escape($record['text']) . "' - WHERE group_id = " . $record['id']; - $this->db->sql_query($sql); - } -} diff --git a/phpBB/phpbb/textreparser/plugins/admin_contact_info.php b/phpBB/phpbb/textreparser/plugins/admin_contact_info.php new file mode 100644 index 0000000000..e432ddea81 --- /dev/null +++ b/phpBB/phpbb/textreparser/plugins/admin_contact_info.php @@ -0,0 +1,69 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser\plugins; + +class admin_contact_info extends \phpbb\textreparser\base +{ + /** + * @var \phpbb\config\db_text + */ + protected $config_text; + + /** + * Constructor + * + * @param \phpbb\config\db_text $config_text + */ + public function __construct(\phpbb\config\db_text $config_text) + { + $this->config_text = $config_text; + } + + /** + * {@inheritdoc} + */ + public function get_max_id() + { + return 1; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $values = $this->config_text->get_array(array( + 'contact_admin_info', + 'contact_admin_info_uid', + 'contact_admin_info_flags', + )); + + return array(array( + 'id' => 1, + 'text' => $values['contact_admin_info'], + 'bbcode_uid' => $values['contact_admin_info_uid'], + 'enable_bbcode' => $values['contact_admin_info_flags'] & OPTION_FLAG_BBCODE, + 'enable_magic_url' => $values['contact_admin_info_flags'] & OPTION_FLAG_LINKS, + 'enable_smilies' => $values['contact_admin_info_flags'] & OPTION_FLAG_SMILIES, + )); + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $this->config_text->set('admin_contact_info', $record['text']); + } +} diff --git a/phpBB/phpbb/textreparser/plugins/forum_description.php b/phpBB/phpbb/textreparser/plugins/forum_description.php new file mode 100644 index 0000000000..d6e95c9638 --- /dev/null +++ b/phpBB/phpbb/textreparser/plugins/forum_description.php @@ -0,0 +1,37 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser\plugins; + +class forum_description extends \phpbb\textreparser\row_based_plugin +{ + /** + * {@inheritdoc} + */ + protected function get_columns() + { + return array( + 'id' => 'forum_id', + 'text' => 'forum_desc', + 'bbcode_uid' => 'forum_desc_uid', + ); + } + + /** + * {@inheritdoc} + */ + protected function get_table_name() + { + return FORUMS_TABLE; + } +} diff --git a/phpBB/phpbb/textreparser/plugins/forum_rules.php b/phpBB/phpbb/textreparser/plugins/forum_rules.php new file mode 100644 index 0000000000..36bb595cb9 --- /dev/null +++ b/phpBB/phpbb/textreparser/plugins/forum_rules.php @@ -0,0 +1,37 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser\plugins; + +class forum_rules extends \phpbb\textreparser\row_based_plugin +{ + /** + * {@inheritdoc} + */ + protected function get_columns() + { + return array( + 'id' => 'forum_id', + 'text' => 'forum_rules', + 'bbcode_uid' => 'forum_rules_uid', + ); + } + + /** + * {@inheritdoc} + */ + protected function get_table_name() + { + return FORUMS_TABLE; + } +} diff --git a/phpBB/phpbb/textreparser/plugins/group_description.php b/phpBB/phpbb/textreparser/plugins/group_description.php new file mode 100644 index 0000000000..c83079827c --- /dev/null +++ b/phpBB/phpbb/textreparser/plugins/group_description.php @@ -0,0 +1,37 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser\plugins; + +class group_description extends \phpbb\textreparser\row_based_plugin +{ + /** + * {@inheritdoc} + */ + protected function get_columns() + { + return array( + 'id' => 'group_id', + 'text' => 'group_desc', + 'bbcode_uid' => 'group_desc_uid', + ); + } + + /** + * {@inheritdoc} + */ + protected function get_table_name() + { + return GROUPS_TABLE; + } +} diff --git a/phpBB/phpbb/textreparser/plugins/pm_text.php b/phpBB/phpbb/textreparser/plugins/pm_text.php new file mode 100644 index 0000000000..f4d87525df --- /dev/null +++ b/phpBB/phpbb/textreparser/plugins/pm_text.php @@ -0,0 +1,40 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser\plugins; + +class pm_text extends \phpbb\textreparser\row_based_plugin +{ + /** + * {@inheritdoc} + */ + protected function get_columns() + { + return array( + 'id' => 'msg_id', + 'enable_bbcode' => 'enable_bbcode', + 'enable_smilies' => 'enable_smilies', + 'enable_magic_url' => 'enable_magic_url', + 'text' => 'message_text', + 'bbcode_uid' => 'bbcode_uid', + ); + } + + /** + * {@inheritdoc} + */ + protected function get_table_name() + { + return PRIVMSGS_TABLE; + } +} diff --git a/phpBB/phpbb/textreparser/plugins/poll_option.php b/phpBB/phpbb/textreparser/plugins/poll_option.php new file mode 100644 index 0000000000..f074f1866d --- /dev/null +++ b/phpBB/phpbb/textreparser/plugins/poll_option.php @@ -0,0 +1,50 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser\plugins; + +class poll_option extends \phpbb\textreparser\row_based_plugin +{ + /** + * {@inheritdoc} + */ + protected function get_columns() + { + return array( + 'id' => 'poll_option_id', + 'text' => 'poll_option_text', + ); + } + + /** + * {@inheritdoc} + */ + protected function get_records_query($min_id, $max_id) + { + $sql = 'SELECT o.poll_option_id AS id, o.poll_option_text AS text, p.bbcode_uid + FROM ' . POLL_OPTIONS_TABLE . ' o, ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p + WHERE o.poll_option_id BETWEEN ' . $min_id . ' AND ' . $max_id .' + AND t.topic_id = o.topic_id + AND p.post_id = t.topic_first_post_id'; + + return $sql; + } + + /** + * {@inheritdoc} + */ + protected function get_table_name() + { + return POLL_OPTIONS_TABLE; + } +} diff --git a/phpBB/phpbb/textreparser/plugins/poll_title.php b/phpBB/phpbb/textreparser/plugins/poll_title.php new file mode 100644 index 0000000000..e794780eba --- /dev/null +++ b/phpBB/phpbb/textreparser/plugins/poll_title.php @@ -0,0 +1,50 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser\plugins; + +class poll_title extends \phpbb\textreparser\row_based_plugin +{ + /** + * {@inheritdoc} + */ + protected function get_columns() + { + return array( + 'id' => 'topic_id', + 'text' => 'poll_title', + ); + } + + /** + * {@inheritdoc} + */ + protected function get_records_query($min_id, $max_id) + { + $sql = 'SELECT t.topic_id AS id, t.poll_title AS text, p.bbcode_uid + FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p + WHERE t.topic_id BETWEEN ' . $min_id . ' AND ' . $max_id .' + AND t.poll_max_options > 0 + AND p.post_id = t.topic_first_post_id'; + + return $sql; + } + + /** + * {@inheritdoc} + */ + protected function get_table_name() + { + return TOPICS_TABLE; + } +} diff --git a/phpBB/phpbb/textreparser/plugins/post_text.php b/phpBB/phpbb/textreparser/plugins/post_text.php new file mode 100644 index 0000000000..2b16518b03 --- /dev/null +++ b/phpBB/phpbb/textreparser/plugins/post_text.php @@ -0,0 +1,40 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser\plugins; + +class post_text extends \phpbb\textreparser\row_based_plugin +{ + /** + * {@inheritdoc} + */ + protected function get_columns() + { + return array( + 'id' => 'post_id', + 'enable_bbcode' => 'enable_bbcode', + 'enable_smilies' => 'enable_smilies', + 'enable_magic_url' => 'enable_magic_url', + 'text' => 'post_text', + 'bbcode_uid' => 'bbcode_uid', + ); + } + + /** + * {@inheritdoc} + */ + protected function get_table_name() + { + return POSTS_TABLE; + } +} diff --git a/phpBB/phpbb/textreparser/plugins/user_signature.php b/phpBB/phpbb/textreparser/plugins/user_signature.php new file mode 100644 index 0000000000..2beaaf98e5 --- /dev/null +++ b/phpBB/phpbb/textreparser/plugins/user_signature.php @@ -0,0 +1,37 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser\plugins; + +class user_signature extends \phpbb\textreparser\row_based_plugin +{ + /** + * {@inheritdoc} + */ + protected function get_columns() + { + return array( + 'id' => 'user_id', + 'text' => 'user_sig', + 'bbcode_uid' => 'user_sig_bbcode_uid', + ); + } + + /** + * {@inheritdoc} + */ + protected function get_table_name() + { + return USERS_TABLE; + } +} diff --git a/phpBB/phpbb/textreparser/pm_text.php b/phpBB/phpbb/textreparser/pm_text.php deleted file mode 100644 index b02cb0083f..0000000000 --- a/phpBB/phpbb/textreparser/pm_text.php +++ /dev/null @@ -1,56 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textreparser; - -class pm_text extends base -{ - /** - * {@inheritdoc} - */ - public function get_max_id() - { - $sql = 'SELECT MAX(msg_id) AS max_id FROM ' . PRIVMSGS_TABLE; - $result = $this->db->sql_query($sql); - $max_id = (int) $this->db->sql_fetchfield('max_id'); - $this->db->sql_freeresult($result); - - return $max_id; - } - - /** - * {@inheritdoc} - */ - protected function get_records($min_id, $max_id) - { - $sql = 'SELECT msg_id AS id, enable_bbcode, enable_smilies, enable_magic_url, message_text AS text, bbcode_uid - FROM ' . PRIVMSGS_TABLE . ' - WHERE msg_id BETWEEN ' . $min_id . ' AND ' . $max_id; - $result = $this->db->sql_query($sql); - $records = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - - return $records; - } - - /** - * {@inheritdoc} - */ - protected function save_record(array $record) - { - $sql = 'UPDATE ' . PRIVMSGS_TABLE . " - SET message_text = '" . $this->db->sql_escape($record['text']) . "' - WHERE msg_id = " . $record['id']; - $this->db->sql_query($sql); - } -} diff --git a/phpBB/phpbb/textreparser/post_text.php b/phpBB/phpbb/textreparser/post_text.php deleted file mode 100644 index 288bb0966b..0000000000 --- a/phpBB/phpbb/textreparser/post_text.php +++ /dev/null @@ -1,56 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textreparser; - -class post_text extends base -{ - /** - * {@inheritdoc} - */ - public function get_max_id() - { - $sql = 'SELECT MAX(post_id) AS max_id FROM ' . POSTS_TABLE; - $result = $this->db->sql_query($sql); - $max_id = (int) $this->db->sql_fetchfield('max_id'); - $this->db->sql_freeresult($result); - - return $max_id; - } - - /** - * {@inheritdoc} - */ - protected function get_records($min_id, $max_id) - { - $sql = 'SELECT post_id AS id, enable_bbcode, enable_smilies, enable_magic_url, post_text AS text, bbcode_uid - FROM ' . POSTS_TABLE . ' - WHERE post_id BETWEEN ' . $min_id . ' AND ' . $max_id; - $result = $this->db->sql_query($sql); - $records = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - - return $records; - } - - /** - * {@inheritdoc} - */ - protected function save_record(array $record) - { - $sql = 'UPDATE ' . POSTS_TABLE . " - SET post_text = '" . $this->db->sql_escape($record['text']) . "' - WHERE post_id = " . $record['id']; - $this->db->sql_query($sql); - } -} diff --git a/phpBB/phpbb/textreparser/row_based_plugin.php b/phpBB/phpbb/textreparser/row_based_plugin.php new file mode 100644 index 0000000000..2317c79e4f --- /dev/null +++ b/phpBB/phpbb/textreparser/row_based_plugin.php @@ -0,0 +1,128 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textreparser; + +abstract class row_based_plugin extends base +{ + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * Constructor + * + * @param \phpbb\db\driver\driver_interface $db Database connection + */ + public function __construct(\phpbb\db\driver\driver_interface $db) + { + $this->db = $db; + } + + /** + * Return the name of the column that correspond to each field + * + * @return array + */ + abstract protected function get_columns(); + + /** + * Return the name of the table used by this plugin + * + * @return string + */ + abstract protected function get_table_name(); + + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $columns = $this->get_columns(); + + $sql = 'SELECT MAX(' . $columns['id'] . ' AS max_id FROM ' . $this->get_table_name(); + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_id'); + $this->db->sql_freeresult($result); + + return $max_id; + } + + /** + * {@inheritdoc} + */ + protected function get_records($min_id, $max_id) + { + $result = $this->db->sql_query($this->get_records_query($min_id, $max_id)); + while ($row = $this->db->sql_fetchrow($result)) + { + if (!isset($row['enable_bbcode'], $row['enable_smilies'], $row['enable_magic_url'])) + { + // Those fields are not saved to the database, we need to guess their original value + $row += array( + 'enable_bbcode' => !empty($row['bbcode_uid']), + 'enable_smilies' => (strpos($row['text'], '') !== false) + ); + } + $records[] = $row; + } + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * Generate the query that retrieves all records for given range + * + * @param integer $min_id Lower bound + * @param integer $max_id Upper bound + * @return string SQL query + */ + protected function get_records_query($min_id, $max_id) + { + $columns = $this->get_columns(); + $fields = array(); + foreach ($columns as $field_name => $column_name) + { + if ($column_name === $field_name) + { + $fields[] = $column_name; + } + else + { + $fields[] = $column_name . ' AS ' . $field_name; + } + } + + $sql = 'SELECT ' . implode(', ', $fields) . ' + FROM ' . $this->get_table_name() . ' + WHERE ' . $columns['id'] . ' BETWEEN ' . $min_id . ' AND ' . $max_id; + + return $sql; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $columns = $this->get_columns(); + + $sql = 'UPDATE ' . $this->get_table_name() . ' + SET ' . $columns['text'] . " = '" . $this->db->sql_escape($record['text']) . "' + WHERE " . $columns['id'] . ' = ' . $record['id']; + $this->db->sql_query($sql); + } +} -- cgit v1.2.1 From b5911281ae175340817345e63ddbfaf43abb3cec Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 1 May 2015 19:21:01 +0200 Subject: [ticket/13803] Added tests, fixed param order in generate_text_for_storage() PHPBB3-13803 --- phpBB/phpbb/textreparser/base.php | 4 +-- .../phpbb/textreparser/plugins/user_signature.php | 39 ++++++++++++++++++++-- phpBB/phpbb/textreparser/row_based_plugin.php | 34 +++++++++++++------ 3 files changed, 62 insertions(+), 15 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php index 7d1e12c52d..f65745f6ab 100644 --- a/phpBB/phpbb/textreparser/base.php +++ b/phpBB/phpbb/textreparser/base.php @@ -63,8 +63,8 @@ abstract class base implements reparser_interface $bitfield, $flags, $unparsed['enable_bbcode'], - $unparsed['enable_smilies'], - $unparsed['enable_magic_url'] + $unparsed['enable_magic_url'], + $unparsed['enable_smilies'] ); // Save the new text if it has changed diff --git a/phpBB/phpbb/textreparser/plugins/user_signature.php b/phpBB/phpbb/textreparser/plugins/user_signature.php index 2beaaf98e5..7a66f39ab6 100644 --- a/phpBB/phpbb/textreparser/plugins/user_signature.php +++ b/phpBB/phpbb/textreparser/plugins/user_signature.php @@ -15,15 +15,48 @@ namespace phpbb\textreparser\plugins; class user_signature extends \phpbb\textreparser\row_based_plugin { + /** + * @var array Bit numbers used for user options + * @see \phpbb\user + */ + protected $keyoptions; + + /** + * Constructor + * + * Retrieves and saves the bit numbers used for user options + */ + public function __construct() + { + $class_vars = get_class_vars('phpbb\\user'); + $this->keyoptions = $class_vars['keyoptions']; + } + + /** + * {@inheritdoc} + */ + protected function add_missing_fields(array $row) + { + $options = $row['user_options']; + $row += array( + 'enable_bbcode' => phpbb_optionget($this->keyoptions['sig_bbcode'], $options), + 'enable_smilies' => phpbb_optionget($this->keyoptions['sig_smilies'], $options), + 'enable_magic_url' => phpbb_optionget($this->keyoptions['sig_links'], $options), + ); + + return $row; + } + /** * {@inheritdoc} */ protected function get_columns() { return array( - 'id' => 'user_id', - 'text' => 'user_sig', - 'bbcode_uid' => 'user_sig_bbcode_uid', + 'id' => 'user_id', + 'text' => 'user_sig', + 'bbcode_uid' => 'user_sig_bbcode_uid', + 'user_options' => 'user_options', ); } diff --git a/phpBB/phpbb/textreparser/row_based_plugin.php b/phpBB/phpbb/textreparser/row_based_plugin.php index 2317c79e4f..b946d6532b 100644 --- a/phpBB/phpbb/textreparser/row_based_plugin.php +++ b/phpBB/phpbb/textreparser/row_based_plugin.php @@ -44,6 +44,29 @@ abstract class row_based_plugin extends base */ abstract protected function get_table_name(); + /** + * Add fields to given row, if applicable + * + * The enable_* fields are not always saved to the database. Sometimes we need to guess their + * original value based on the text content or possibly other fields + * + * @param array $row Original row + * @return array Complete row + */ + protected function add_missing_fields(array $row) + { + if (!isset($row['enable_bbcode'], $row['enable_smilies'], $row['enable_magic_url'])) + { + $row += array( + 'enable_bbcode' => !empty($row['bbcode_uid']), + 'enable_smilies' => (strpos($row['text'], '') !== false), + ); + } + + return $row; + } + /** * {@inheritdoc} */ @@ -67,16 +90,7 @@ abstract class row_based_plugin extends base $result = $this->db->sql_query($this->get_records_query($min_id, $max_id)); while ($row = $this->db->sql_fetchrow($result)) { - if (!isset($row['enable_bbcode'], $row['enable_smilies'], $row['enable_magic_url'])) - { - // Those fields are not saved to the database, we need to guess their original value - $row += array( - 'enable_bbcode' => !empty($row['bbcode_uid']), - 'enable_smilies' => (strpos($row['text'], '') !== false) - ); - } - $records[] = $row; + $records[] = $this->add_missing_fields($row); } $this->db->sql_freeresult($result); -- cgit v1.2.1 From 459f1d4c1f26658c70d29ac7c4e3f3389a973a59 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 1 May 2015 20:05:15 +0200 Subject: [ticket/13803] Refactored test PHPBB3-13803 --- phpBB/phpbb/textreparser/plugins/forum_description.php | 4 ++-- phpBB/phpbb/textreparser/plugins/forum_rules.php | 4 ++-- phpBB/phpbb/textreparser/plugins/group_description.php | 4 ++-- phpBB/phpbb/textreparser/plugins/pm_text.php | 4 ++-- phpBB/phpbb/textreparser/plugins/poll_option.php | 4 ++-- phpBB/phpbb/textreparser/plugins/poll_title.php | 4 ++-- phpBB/phpbb/textreparser/plugins/post_text.php | 4 ++-- phpBB/phpbb/textreparser/plugins/user_signature.php | 4 ++-- phpBB/phpbb/textreparser/row_based_plugin.php | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/plugins/forum_description.php b/phpBB/phpbb/textreparser/plugins/forum_description.php index d6e95c9638..7798e4b20b 100644 --- a/phpBB/phpbb/textreparser/plugins/forum_description.php +++ b/phpBB/phpbb/textreparser/plugins/forum_description.php @@ -18,7 +18,7 @@ class forum_description extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_columns() + public function get_columns() { return array( 'id' => 'forum_id', @@ -30,7 +30,7 @@ class forum_description extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_table_name() + public function get_table_name() { return FORUMS_TABLE; } diff --git a/phpBB/phpbb/textreparser/plugins/forum_rules.php b/phpBB/phpbb/textreparser/plugins/forum_rules.php index 36bb595cb9..57c666a556 100644 --- a/phpBB/phpbb/textreparser/plugins/forum_rules.php +++ b/phpBB/phpbb/textreparser/plugins/forum_rules.php @@ -18,7 +18,7 @@ class forum_rules extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_columns() + public function get_columns() { return array( 'id' => 'forum_id', @@ -30,7 +30,7 @@ class forum_rules extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_table_name() + public function get_table_name() { return FORUMS_TABLE; } diff --git a/phpBB/phpbb/textreparser/plugins/group_description.php b/phpBB/phpbb/textreparser/plugins/group_description.php index c83079827c..ddd0e1d1c5 100644 --- a/phpBB/phpbb/textreparser/plugins/group_description.php +++ b/phpBB/phpbb/textreparser/plugins/group_description.php @@ -18,7 +18,7 @@ class group_description extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_columns() + public function get_columns() { return array( 'id' => 'group_id', @@ -30,7 +30,7 @@ class group_description extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_table_name() + public function get_table_name() { return GROUPS_TABLE; } diff --git a/phpBB/phpbb/textreparser/plugins/pm_text.php b/phpBB/phpbb/textreparser/plugins/pm_text.php index f4d87525df..4d06a2878b 100644 --- a/phpBB/phpbb/textreparser/plugins/pm_text.php +++ b/phpBB/phpbb/textreparser/plugins/pm_text.php @@ -18,7 +18,7 @@ class pm_text extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_columns() + public function get_columns() { return array( 'id' => 'msg_id', @@ -33,7 +33,7 @@ class pm_text extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_table_name() + public function get_table_name() { return PRIVMSGS_TABLE; } diff --git a/phpBB/phpbb/textreparser/plugins/poll_option.php b/phpBB/phpbb/textreparser/plugins/poll_option.php index f074f1866d..cc28599737 100644 --- a/phpBB/phpbb/textreparser/plugins/poll_option.php +++ b/phpBB/phpbb/textreparser/plugins/poll_option.php @@ -18,7 +18,7 @@ class poll_option extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_columns() + public function get_columns() { return array( 'id' => 'poll_option_id', @@ -43,7 +43,7 @@ class poll_option extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_table_name() + public function get_table_name() { return POLL_OPTIONS_TABLE; } diff --git a/phpBB/phpbb/textreparser/plugins/poll_title.php b/phpBB/phpbb/textreparser/plugins/poll_title.php index e794780eba..6665d68847 100644 --- a/phpBB/phpbb/textreparser/plugins/poll_title.php +++ b/phpBB/phpbb/textreparser/plugins/poll_title.php @@ -18,7 +18,7 @@ class poll_title extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_columns() + public function get_columns() { return array( 'id' => 'topic_id', @@ -43,7 +43,7 @@ class poll_title extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_table_name() + public function get_table_name() { return TOPICS_TABLE; } diff --git a/phpBB/phpbb/textreparser/plugins/post_text.php b/phpBB/phpbb/textreparser/plugins/post_text.php index 2b16518b03..4a07c98cea 100644 --- a/phpBB/phpbb/textreparser/plugins/post_text.php +++ b/phpBB/phpbb/textreparser/plugins/post_text.php @@ -18,7 +18,7 @@ class post_text extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_columns() + public function get_columns() { return array( 'id' => 'post_id', @@ -33,7 +33,7 @@ class post_text extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_table_name() + public function get_table_name() { return POSTS_TABLE; } diff --git a/phpBB/phpbb/textreparser/plugins/user_signature.php b/phpBB/phpbb/textreparser/plugins/user_signature.php index 7a66f39ab6..db82d4089b 100644 --- a/phpBB/phpbb/textreparser/plugins/user_signature.php +++ b/phpBB/phpbb/textreparser/plugins/user_signature.php @@ -50,7 +50,7 @@ class user_signature extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_columns() + public function get_columns() { return array( 'id' => 'user_id', @@ -63,7 +63,7 @@ class user_signature extends \phpbb\textreparser\row_based_plugin /** * {@inheritdoc} */ - protected function get_table_name() + public function get_table_name() { return USERS_TABLE; } diff --git a/phpBB/phpbb/textreparser/row_based_plugin.php b/phpBB/phpbb/textreparser/row_based_plugin.php index b946d6532b..2be0b68411 100644 --- a/phpBB/phpbb/textreparser/row_based_plugin.php +++ b/phpBB/phpbb/textreparser/row_based_plugin.php @@ -35,14 +35,14 @@ abstract class row_based_plugin extends base * * @return array */ - abstract protected function get_columns(); + abstract public function get_columns(); /** * Return the name of the table used by this plugin * * @return string */ - abstract protected function get_table_name(); + abstract public function get_table_name(); /** * Add fields to given row, if applicable -- cgit v1.2.1 From ea445ffa4776b7ce0b1d13485f113c7e1ec28af0 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sat, 2 May 2015 01:08:32 +0200 Subject: [ticket/13803] Added methods to detect whether a given feature is in use They test whether a given BBCode was enabled and has been used in a text, or smilies, or magic URLs. PHPBB3-13803 --- phpBB/phpbb/textreparser/base.php | 56 +++++++++++++++++++++++++++ phpBB/phpbb/textreparser/row_based_plugin.php | 13 ++++++- 2 files changed, 67 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php index f65745f6ab..f3f31ca320 100644 --- a/phpBB/phpbb/textreparser/base.php +++ b/phpBB/phpbb/textreparser/base.php @@ -29,6 +29,62 @@ abstract class base implements reparser_interface */ abstract protected function get_records($min_id, $max_id); + /** + * Guess whether given BBCode is in use in given record + * + * @param array $record + * @param string $bbcode + * @return bool + */ + protected function guess_bbcode(array $record, $bbcode) + { + if (!empty($record['bbcode_uid'])) + { + // Look for the closing tag, e.g. [/url] + $match = '[/' . $bbcode . ':' . $record['bbcode_uid']; + if (stripos($record['text'], $match) !== false) + { + return true; + } + } + + if (substr($record['text'], 0, 2) == '[/url]
+ $match = '[/' . $bbcode . ']'; + if (stripos($record['text'], $match) !== false) + { + return true; + } + } + + return false; + } + + /** + * Guess whether magic URLs are in use in given record + * + * @param array $record + * @return bool + */ + protected function guess_magic_url(array $record) + { + // Look for or for a URL tag that's not immediately followed by + return (strpos($record['text'], '') !== false || preg_match('(]++>(?!))', strpos($row['text']))); + } + + /** + * Guess whether smilies are in use in given record + * + * @param array $record + * @return bool + */ + protected function guess_smilies(array $record) + { + return (strpos($row['text'], '') !== false), + 'enable_smilies' => $this->guess_smilies($row), + 'enable_magic_url' => $this->guess_magic_url($row), ); } + // Those BBCodes are disabled based on context and user permissions and that value is never + // stored in the database. Here we test whether they were used in the original text. + $bbcodes = array('flash', 'img', 'quote', 'url'); + foreach ($bbcodes as $bbcode) + { + $field_name = 'enable_' . $bbcode; + $row[$field_name] = $this->guess_bbcode($row, $bbcode); + } + return $row; } -- cgit v1.2.1 From 9bf0f794b5876b10491c91548f1a92bc0dff7400 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sat, 2 May 2015 02:55:45 +0200 Subject: [ticket/13803] Added pm_text tests PHPBB3-13803 --- phpBB/phpbb/textreparser/base.php | 38 ++++++++++++++++++++++++++- phpBB/phpbb/textreparser/row_based_plugin.php | 32 ---------------------- 2 files changed, 37 insertions(+), 33 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php index f3f31ca320..2d4a4171af 100644 --- a/phpBB/phpbb/textreparser/base.php +++ b/phpBB/phpbb/textreparser/base.php @@ -29,6 +29,38 @@ abstract class base implements reparser_interface */ abstract protected function get_records($min_id, $max_id); + /** + * Add fields to given record, if applicable + * + * The enable_* fields are not always saved to the database. Sometimes we need to guess their + * original value based on the text content or possibly other fields + * + * @param array $record Original record + * @return array Complete record + */ + protected function add_missing_fields(array $record) + { + if (!isset($record['enable_bbcode'], $record['enable_smilies'], $record['enable_magic_url'])) + { + $record += array( + 'enable_bbcode' => !empty($record['bbcode_uid']), + 'enable_smilies' => $this->guess_smilies($record), + 'enable_magic_url' => $this->guess_magic_url($record), + ); + } + + // Those BBCodes are disabled based on context and user permissions and that value is never + // stored in the database. Here we test whether they were used in the original text. + $bbcodes = array('flash', 'img', 'quote', 'url'); + foreach ($bbcodes as $bbcode) + { + $field_name = 'enable_' . $bbcode . '_bbcode'; + $record[$field_name] = $this->guess_bbcode($record, $bbcode); + } + + return $record; + } + /** * Guess whether given BBCode is in use in given record * @@ -120,7 +152,11 @@ abstract class base implements reparser_interface $flags, $unparsed['enable_bbcode'], $unparsed['enable_magic_url'], - $unparsed['enable_smilies'] + $unparsed['enable_smilies'], + $unparsed['enable_img_bbcode'], + $unparsed['enable_flash_bbcode'], + $unparsed['enable_quote_bbcode'], + $unparsed['enable_url_bbcode'] ); // Save the new text if it has changed diff --git a/phpBB/phpbb/textreparser/row_based_plugin.php b/phpBB/phpbb/textreparser/row_based_plugin.php index 80525a404e..e39ec4d5d3 100644 --- a/phpBB/phpbb/textreparser/row_based_plugin.php +++ b/phpBB/phpbb/textreparser/row_based_plugin.php @@ -44,38 +44,6 @@ abstract class row_based_plugin extends base */ abstract public function get_table_name(); - /** - * Add fields to given row, if applicable - * - * The enable_* fields are not always saved to the database. Sometimes we need to guess their - * original value based on the text content or possibly other fields - * - * @param array $row Original row - * @return array Complete row - */ - protected function add_missing_fields(array $row) - { - if (!isset($row['enable_bbcode'], $row['enable_smilies'], $row['enable_magic_url'])) - { - $row += array( - 'enable_bbcode' => !empty($row['bbcode_uid']), - 'enable_smilies' => $this->guess_smilies($row), - 'enable_magic_url' => $this->guess_magic_url($row), - ); - } - - // Those BBCodes are disabled based on context and user permissions and that value is never - // stored in the database. Here we test whether they were used in the original text. - $bbcodes = array('flash', 'img', 'quote', 'url'); - foreach ($bbcodes as $bbcode) - { - $field_name = 'enable_' . $bbcode; - $row[$field_name] = $this->guess_bbcode($row, $bbcode); - } - - return $row; - } - /** * {@inheritdoc} */ -- cgit v1.2.1 From 70cd911281056ecb4eefc23e678126e1747debc8 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sat, 2 May 2015 08:51:56 +0200 Subject: [ticket/13803] Added tests PHPBB3-13803 --- phpBB/phpbb/textreparser/base.php | 50 +++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 7 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php index 2d4a4171af..865b0662f9 100644 --- a/phpBB/phpbb/textreparser/base.php +++ b/phpBB/phpbb/textreparser/base.php @@ -43,7 +43,7 @@ abstract class base implements reparser_interface if (!isset($record['enable_bbcode'], $record['enable_smilies'], $record['enable_magic_url'])) { $record += array( - 'enable_bbcode' => !empty($record['bbcode_uid']), + 'enable_bbcode' => $this->guess_bbcodes($record), 'enable_smilies' => $this->guess_smilies($record), 'enable_magic_url' => $this->guess_magic_url($record), ); @@ -58,6 +58,13 @@ abstract class base implements reparser_interface $record[$field_name] = $this->guess_bbcode($record, $bbcode); } + // Magic URLs are tied to the URL BBCode, that's why if magic URLs are enabled we make sure + // that the URL BBCode is also enabled + if ($record['enable_magic_url']) + { + $record['enable_url_bbcode'] = true; + } + return $record; } @@ -74,7 +81,7 @@ abstract class base implements reparser_interface { // Look for the closing tag, e.g. [/url] $match = '[/' . $bbcode . ':' . $record['bbcode_uid']; - if (stripos($record['text'], $match) !== false) + if (strpos($record['text'], $match) !== false) { return true; } @@ -84,8 +91,8 @@ abstract class base implements reparser_interface { // Look for the closing tag inside of a e element, in an element of the same name, e.g. // [/url] - $match = '[/' . $bbcode . ']'; - if (stripos($record['text'], $match) !== false) + $match = '[/' . $bbcode . ']'; + if (strpos($record['text'], $match) !== false) { return true; } @@ -94,6 +101,33 @@ abstract class base implements reparser_interface return false; } + /** + * Guess whether any BBCode is in use in given record + * + * @param array $record + * @return bool + */ + protected function guess_bbcodes(array $record) + { + if (!empty($record['bbcode_uid'])) + { + // Test whether the bbcode_uid is in use + $match = ':' . $record['bbcode_uid']; + if (strpos($record['text'], $match) !== false) + { + return true; + } + } + + if (substr($record['text'], 0, 2) == '\\[/\\w+\\]
)', $match); + } + + return false; + } + /** * Guess whether magic URLs are in use in given record * @@ -103,7 +137,7 @@ abstract class base implements reparser_interface protected function guess_magic_url(array $record) { // Look for or for a URL tag that's not immediately followed by - return (strpos($record['text'], '') !== false || preg_match('(]++>(?!))', strpos($row['text']))); + return (strpos($record['text'], '') !== false || preg_match('(]++>(?!))', $record['text'])); } /** @@ -114,7 +148,7 @@ abstract class base implements reparser_interface */ protected function guess_smilies(array $record) { - return (strpos($row['text'], '([^[]+)<\!--#si', '', $content); diff --git a/phpBB/phpbb/feed/news.php b/phpBB/phpbb/feed/news.php index a02c199d85..fb6fa09278 100644 --- a/phpBB/phpbb/feed/news.php +++ b/phpBB/phpbb/feed/news.php @@ -1,27 +1,31 @@ -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ namespace phpbb\feed; /** -* News feed -* -* This will give you {$this->num_items} first posts -* of all topics in the selected news forums. -*/ -class news extends \phpbb\feed\topic_base + * News feed + * + * This will give you {$this->num_items} first posts + * of all topics in the selected news forums. + */ +class news extends topic_base { - function get_news_forums() + /** + * Returns the ids of the 'news forums' + * @return int[] + */ + private function get_news_forums() { static $forum_ids; @@ -48,7 +52,10 @@ class news extends \phpbb\feed\topic_base return $forum_ids; } - function get_sql() + /** + * {@inheritdoc} + */ + protected function get_sql() { // Determine forum ids $in_fid_ary = array_intersect($this->get_news_forums(), $this->get_readable_forums()); diff --git a/phpBB/phpbb/feed/overall.php b/phpBB/phpbb/feed/overall.php index ab452f5386..40cf94ace0 100644 --- a/phpBB/phpbb/feed/overall.php +++ b/phpBB/phpbb/feed/overall.php @@ -1,27 +1,30 @@ -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ namespace phpbb\feed; /** -* Board wide feed (aka overall feed) -* -* This will give you the newest {$this->num_items} posts -* from the whole board. -*/ -class overall extends \phpbb\feed\post_base + * Board wide feed (aka overall feed) + * + * This will give you the newest {$this->num_items} posts + * from the whole board. + */ +class overall extends post_base { - function get_sql() + /** + * {@inheritdoc} + */ + protected function get_sql() { $forum_ids = array_diff($this->get_readable_forums(), $this->get_excluded_forums(), $this->get_passworded_forums()); if (empty($forum_ids)) @@ -55,8 +58,8 @@ class overall extends \phpbb\feed\post_base // Get the actual data $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, ' . - 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' . - 'u.username, u.user_id', + 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' . + 'u.username, u.user_id', 'FROM' => array( USERS_TABLE => 'u', POSTS_TABLE => 'p', @@ -77,7 +80,10 @@ class overall extends \phpbb\feed\post_base return true; } - function adjust_item(&$item_row, &$row) + /** + * {@inheritdoc} + */ + public function adjust_item(&$item_row, &$row) { parent::adjust_item($item_row, $row); diff --git a/phpBB/phpbb/feed/post_base.php b/phpBB/phpbb/feed/post_base.php index 011775b6af..f6dc39cbec 100644 --- a/phpBB/phpbb/feed/post_base.php +++ b/phpBB/phpbb/feed/post_base.php @@ -1,27 +1,29 @@ -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ namespace phpbb\feed; /** -* Abstract class for post based feeds -*/ -abstract class post_base extends \phpbb\feed\attachments_base + * Abstract class for post based feeds + */ +abstract class post_base extends attachments_base { - var $num_items = 'feed_limit_post'; - var $attachments = array(); + protected $num_items = 'feed_limit_post'; - function set_keys() + /** + * {@inheritdoc} + */ + public function set_keys() { $this->set('title', 'post_subject'); $this->set('title2', 'topic_title'); @@ -40,7 +42,10 @@ abstract class post_base extends \phpbb\feed\attachments_base $this->set('enable_magic_url', 'enable_magic_url'); } - function adjust_item(&$item_row, &$row) + /** + * {@inheritdoc} + */ + public function adjust_item(&$item_row, &$row) { $item_row['link'] = $this->helper->append_sid('viewtopic.' . $this->phpEx, "t={$row['topic_id']}&p={$row['post_id']}#p{$row['post_id']}"); diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php index c916d3bccc..f029c2b00e 100644 --- a/phpBB/phpbb/feed/topic.php +++ b/phpBB/phpbb/feed/topic.php @@ -1,15 +1,15 @@ -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ namespace phpbb\feed; @@ -19,22 +19,22 @@ use phpbb\feed\exception\unauthorized_forum_exception; use phpbb\feed\exception\unauthorized_topic_exception; /** -* Topic feed for a specific topic -* -* This will give you the last {$this->num_items} posts made within this topic. -*/ -class topic extends \phpbb\feed\post_base + * Topic feed for a specific topic + * + * This will give you the last {$this->num_items} posts made within this topic. + */ +class topic extends post_base { - var $topic_id = 0; - var $forum_id = 0; - var $topic_data = array(); + protected $topic_id = 0; + protected $forum_id = 0; + protected $topic_data = array(); /** - * Set the Topic ID - * - * @param int $topic_id Topic ID - * @return \phpbb\feed\topic - */ + * Set the Topic ID + * + * @param int $topic_id Topic ID + * @return \phpbb\feed\topic + */ public function set_topic_id($topic_id) { $this->topic_id = (int) $topic_id; @@ -42,7 +42,10 @@ class topic extends \phpbb\feed\post_base return $this; } - function open() + /** + * {@inheritdoc} + */ + public function open() { $sql = 'SELECT f.forum_options, f.forum_password, t.topic_id, t.forum_id, t.topic_visibility, t.topic_title, t.topic_time, t.topic_views, t.topic_posts_approved, t.topic_type FROM ' . TOPICS_TABLE . ' t @@ -94,11 +97,14 @@ class topic extends \phpbb\feed\post_base parent::open(); } - function get_sql() + /** + * {@inheritdoc} + */ + protected function get_sql() { $this->sql = array( 'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' . - 'u.username, u.user_id', + 'u.username, u.user_id', 'FROM' => array( POSTS_TABLE => 'p', USERS_TABLE => 'u', @@ -112,14 +118,20 @@ class topic extends \phpbb\feed\post_base return true; } - function adjust_item(&$item_row, &$row) + /** + * {@inheritdoc} + */ + public function adjust_item(&$item_row, &$row) { parent::adjust_item($item_row, $row); $item_row['forum_id'] = $this->forum_id; } - function get_item() + /** + * {@inheritdoc} + */ + public function get_item() { return ($row = parent::get_item()) ? array_merge($this->topic_data, $row) : $row; } diff --git a/phpBB/phpbb/feed/topic_base.php b/phpBB/phpbb/feed/topic_base.php index f9ff368cba..0f1a9ccb70 100644 --- a/phpBB/phpbb/feed/topic_base.php +++ b/phpBB/phpbb/feed/topic_base.php @@ -1,26 +1,29 @@ -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ namespace phpbb\feed; /** -* Abstract class for topic based feeds -*/ -abstract class topic_base extends \phpbb\feed\attachments_base + * Abstract class for topic based feeds + */ +abstract class topic_base extends attachments_base { - var $num_items = 'feed_limit_topic'; + protected $num_items = 'feed_limit_topic'; - function set_keys() + /** + * {@inheritdoc} + */ + public function set_keys() { $this->set('title', 'topic_title'); $this->set('title2', 'forum_name'); @@ -39,7 +42,10 @@ abstract class topic_base extends \phpbb\feed\attachments_base $this->set('enable_magic_url', 'enable_magic_url'); } - function adjust_item(&$item_row, &$row) + /** + * {@inheritdoc} + */ + public function adjust_item(&$item_row, &$row) { $item_row['link'] = $this->helper->append_sid('viewtopic.' . $this->phpEx, 't=' . $row['topic_id'] . '&p=' . $row['post_id'] . '#p' . $row['post_id']); diff --git a/phpBB/phpbb/feed/topics.php b/phpBB/phpbb/feed/topics.php index 2b9cb3501a..cf4a2e579e 100644 --- a/phpBB/phpbb/feed/topics.php +++ b/phpBB/phpbb/feed/topics.php @@ -1,27 +1,30 @@ -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ namespace phpbb\feed; /** -* New Topics feed -* -* This will give you the last {$this->num_items} created topics -* including the first post. -*/ -class topics extends \phpbb\feed\topic_base + * New Topics feed + * + * This will give you the last {$this->num_items} created topics + * including the first post. + */ +class topics extends topic_base { - function get_sql() + /** + * {@inheritdoc} + */ + protected function get_sql() { $forum_ids_read = $this->get_readable_forums(); if (empty($forum_ids_read)) @@ -77,7 +80,10 @@ class topics extends \phpbb\feed\topic_base return true; } - function adjust_item(&$item_row, &$row) + /** + * {@inheritdoc} + */ + public function adjust_item(&$item_row, &$row) { parent::adjust_item($item_row, $row); diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php index 6d5eddfc16..52340dc2d5 100644 --- a/phpBB/phpbb/feed/topics_active.php +++ b/phpBB/phpbb/feed/topics_active.php @@ -1,30 +1,33 @@ -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ namespace phpbb\feed; /** -* Active Topics feed -* -* This will give you the last {$this->num_items} topics -* with replies made withing the last {$this->sort_days} days -* including the last post. -*/ -class topics_active extends \phpbb\feed\topic_base + * Active Topics feed + * + * This will give you the last {$this->num_items} topics + * with replies made withing the last {$this->sort_days} days + * including the last post. + */ +class topics_active extends topic_base { - var $sort_days = 7; + protected $sort_days = 7; - function set_keys() + /** + * {@inheritdoc} + */ + public function set_keys() { parent::set_keys(); @@ -32,7 +35,10 @@ class topics_active extends \phpbb\feed\topic_base $this->set('creator', 'topic_last_poster_name'); } - function get_sql() + /** + * {@inheritdoc} + */ + protected function get_sql() { $forum_ids_read = $this->get_readable_forums(); if (empty($forum_ids_read)) @@ -94,7 +100,12 @@ class topics_active extends \phpbb\feed\topic_base return true; } - function get_forum_ids() + /** + * Returns the ids of the forums not excluded from the active list + * + * @return int[] + */ + private function get_forum_ids() { static $forum_ids; @@ -122,7 +133,10 @@ class topics_active extends \phpbb\feed\topic_base return $forum_ids; } - function adjust_item(&$item_row, &$row) + /** + * {@inheritdoc} + */ + public function adjust_item(&$item_row, &$row) { parent::adjust_item($item_row, $row); -- cgit v1.2.1 From 1f16704d347277ca1923bd2e532bc25bafacf51c Mon Sep 17 00:00:00 2001 From: n-aleha Date: Sat, 18 Jul 2015 02:12:12 +0300 Subject: [ticket/12505] Add migration PHPBB3-12505 --- .../migration/data/v320/remove_outdated_media.php | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php b/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php new file mode 100644 index 0000000000..b2a0a79187 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php @@ -0,0 +1,83 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class remove_outdated_media extends \phpbb\db\migration\migration +{ + protected $cat_id = array( + ATTACHMENT_CATEGORY_WM, + ATTACHMENT_CATEGORY_RM, + ATTACHMENT_CATEGORY_QUICKTIME, + ); + + public function update_data() + { + return array( + array('custom', array(array($this, 'change_extension_group'))), + ); + } + + public function change_extension_group() + { + // select group ids of outdated media + $sql = 'SELECT group_id + FROM ' . EXTENSION_GROUPS_TABLE . ' + WHERE ' . $this->db->sql_in_set('cat_id', $cat_id); + $result = $this->db->sql_query($sql); + + $group_ids = array(); + while ($group_id = (int) $this->db->sql_fetchfield('group_id')) + { + $group_ids[] = $group_id; + } + $this->db->sql_freeresult($result); + + // nothing to do, admin has removed all the outdated media extension groups + if (empty($group_ids)) + { + return true; + } + + // get the group id of downloadable files + $sql = 'SELECT group_id + FROM ' . EXTENSION_GROUPS_TABLE . " + WHERE group_name = 'DOWNLOADABLE_FILES'"; + $result = $this->db->sql_query($sql); + $download_id = (int) $this->db->sql_fetchfield('group_id'); + $this->db->sql_freeresult($result); + + if (empty($download_id)) + { + $sql = 'UPDATE ' . EXTENSIONS_TABLE . ' + SET group_id = 0 + WHERE ' . $this->db->sql_in_set('group_id', $group_ids); + } + else + { + // move outdated media extensions to downloadable files + $sql = 'UPDATE ' . EXTENSIONS_TABLE . " + SET group_id = $download_id" . ' + WHERE ' . $this->db->sql_in_set('group_id', $group_ids); + } + + $result = $this->db->sql_query($sql); + $this->db->sql_freeresult($result); + + // delete the now empty, outdated media extension groups + $sql = 'DELETE FROM ' . EXTENSION_GROUPS_TABLE . ' + WHERE ' . $this->db->sql_in_set('group_id', $group_ids); + $result = $this->db->sql_query($sql); + $this->db->sql_freeresult($result); + } +} -- cgit v1.2.1 From afccb9cb49ce8e96079d3f0b1ea1f9084194a316 Mon Sep 17 00:00:00 2001 From: n-aleha Date: Tue, 21 Jul 2015 00:42:34 +0300 Subject: [ticket/12505] Fix variable usage in migration file PHPBB3-12505 --- phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php b/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php index b2a0a79187..59208be4dc 100644 --- a/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php +++ b/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php @@ -33,7 +33,7 @@ class remove_outdated_media extends \phpbb\db\migration\migration // select group ids of outdated media $sql = 'SELECT group_id FROM ' . EXTENSION_GROUPS_TABLE . ' - WHERE ' . $this->db->sql_in_set('cat_id', $cat_id); + WHERE ' . $this->db->sql_in_set('cat_id', $this->cat_id); $result = $this->db->sql_query($sql); $group_ids = array(); -- cgit v1.2.1 From c9ec16f6149f104c016980375c8fd04a31e57616 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 10 Aug 2015 09:38:26 +0200 Subject: [ticket/13645] Fix docblocks PHPBB3-13645 --- phpBB/phpbb/feed/controller/feed.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/feed/controller/feed.php b/phpBB/phpbb/feed/controller/feed.php index 1cc960b1cb..31476b7317 100644 --- a/phpBB/phpbb/feed/controller/feed.php +++ b/phpBB/phpbb/feed/controller/feed.php @@ -83,7 +83,8 @@ class feed /** * Constructor * - * @param symfony_request $request; + * @param \Twig_Environment $twig + * @param symfony_request $request * @param controller_helper $controller_helper * @param config $config * @param driver_interface $db @@ -91,6 +92,7 @@ class feed * @param feed_helper $feed_helper * @param user $user * @param auth $auth + * @param string $php_ext */ public function __construct(\Twig_Environment $twig, symfony_request $request, controller_helper $controller_helper, config $config, driver_interface $db, ContainerInterface $container, feed_helper $feed_helper, user $user, auth $auth, $php_ext) { -- cgit v1.2.1 From c868582e4412d482853e7975b1cff1965f51ce25 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 24 Aug 2015 17:45:24 +0200 Subject: [ticket/14125] Add --env option to all CLI commands PHPBB3-14125 --- phpBB/phpbb/console/application.php | 57 +++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 12 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/application.php b/phpBB/phpbb/console/application.php index 2c69a3cc73..dc9b8016b2 100644 --- a/phpBB/phpbb/console/application.php +++ b/phpBB/phpbb/console/application.php @@ -13,6 +13,7 @@ namespace phpbb\console; +use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Shell; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -49,12 +50,7 @@ class application extends \Symfony\Component\Console\Application { $input_definition = parent::getDefaultInputDefinition(); - $input_definition->addOption(new InputOption( - 'safe-mode', - null, - InputOption::VALUE_NONE, - $this->language->lang('CLI_DESCRIPTION_OPTION_SAFE_MODE') - )); + $this->register_global_options($input_definition); return $input_definition; } @@ -76,12 +72,20 @@ class application extends \Symfony\Component\Console\Application return parent::getHelp(); } - $this->getDefinition()->addOption(new InputOption( - '--shell', - '-s', - InputOption::VALUE_NONE, - $this->language->lang('CLI_DESCRIPTION_OPTION_SHELL') - )); + try + { + $definition = $this->getDefinition(); + $definition->addOption(new InputOption( + '--shell', + '-s', + InputOption::VALUE_NONE, + $this->language->lang('CLI_DESCRIPTION_OPTION_SHELL') + )); + } + catch (\LogicException $e) + { + // Do nothing + } return parent::getHelp(); } @@ -117,4 +121,33 @@ class application extends \Symfony\Component\Console\Application return parent::doRun($input, $output); } + + /** + * Register global options + * + * @param InputDefinition $definition An InputDefinition instance + */ + protected function register_global_options(InputDefinition $definition) + { + try + { + $definition->addOption(new InputOption( + 'safe-mode', + null, + InputOption::VALUE_NONE, + $this->language->lang('CLI_DESCRIPTION_OPTION_SAFE_MODE') + )); + + $definition->addOption(new InputOption( + 'env', + 'e', + InputOption::VALUE_REQUIRED, + $this->language->lang('CLI_DESCRIPTION_OPTION_ENV') + )); + } + catch (\LogicException $e) + { + // Do nothing + } + } } -- cgit v1.2.1 From 17e7a89a60f700efc8a0b082b7a82005e6288e80 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 24 Aug 2015 12:04:22 +0200 Subject: [ticket/14124] Automatically translate exceptions in CLI PHPBB3-14124 --- phpBB/phpbb/console/application.php | 1 + phpBB/phpbb/console/exception_subscriber.php | 74 ++++++++++++++++++++++ .../phpbb/di/extension/container_configuration.php | 6 ++ phpBB/phpbb/di/extension/core.php | 7 ++ 4 files changed, 88 insertions(+) create mode 100644 phpBB/phpbb/console/exception_subscriber.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/application.php b/phpBB/phpbb/console/application.php index 2c69a3cc73..f9f2213da6 100644 --- a/phpBB/phpbb/console/application.php +++ b/phpBB/phpbb/console/application.php @@ -13,6 +13,7 @@ namespace phpbb\console; +use phpbb\exception\exception_interface; use Symfony\Component\Console\Shell; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; diff --git a/phpBB/phpbb/console/exception_subscriber.php b/phpBB/phpbb/console/exception_subscriber.php new file mode 100644 index 0000000000..b920d4abae --- /dev/null +++ b/phpBB/phpbb/console/exception_subscriber.php @@ -0,0 +1,74 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\console; + +use phpbb\exception\exception_interface; +use Symfony\Component\Console\ConsoleEvents; +use Symfony\Component\Console\Event\ConsoleExceptionEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class exception_subscriber implements EventSubscriberInterface +{ + /** + * @var \phpbb\language\language + */ + protected $language; + + /** + * Construct method + * + * @param \phpbb\language\language $language Language object + * @param bool $debug Debug mode + */ + public function __construct(\phpbb\language\language $language, $debug = false) + { + $this->language = $language; + $this->debug = $debug; + } + + /** + * This listener is run when the ConsoleEvents::EXCEPTION event is triggered. + * It translate the exception message. If din debug mode the original exception is embedded. + * + * @param ConsoleExceptionEvent $event + */ + public function on_exception(ConsoleExceptionEvent $event) + { + $original_exception = $event->getException(); + + if ($original_exception instanceof exception_interface) + { + $parameters = array_merge(array($original_exception->getMessage()), $original_exception->get_parameters()); + $message = call_user_func_array(array($this->language, 'lang'), $parameters); + + if ($this->debug) + { + $exception = new \RuntimeException($message , $original_exception->getCode(), $original_exception); + } + else + { + $exception = new \RuntimeException($message , $original_exception->getCode()); + } + + $event->setException($exception); + } + } + + static public function getSubscribedEvents() + { + return array( + ConsoleEvents::EXCEPTION => 'on_exception', + ); + } +} diff --git a/phpBB/phpbb/di/extension/container_configuration.php b/phpBB/phpbb/di/extension/container_configuration.php index 4cc7c7c0d1..4585d6509e 100644 --- a/phpBB/phpbb/di/extension/container_configuration.php +++ b/phpBB/phpbb/di/extension/container_configuration.php @@ -31,6 +31,12 @@ class container_configuration implements ConfigurationInterface $rootNode ->children() ->booleanNode('require_dev_dependencies')->defaultValue(false)->end() + ->arrayNode('debug') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('exceptions')->defaultValue(false)->end() + ->end() + ->end() ->arrayNode('twig') ->addDefaultsIfNotSet() ->children() diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 91b321a684..c48a80a558 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -80,6 +80,7 @@ class core extends Extension { $twig_environment_options['auto_reload'] = true; } + // Replace the 8th argument, the options passed to the environment $definition->replaceArgument(7, $twig_environment_options); @@ -88,6 +89,12 @@ class core extends Extension $definition = $container->getDefinition('template.twig.extensions.debug'); $definition->addTag('twig.extension'); } + + // Set the debug options + foreach ($config['debug'] as $name => $value) + { + $container->setParameter('debug.' . $name, $value); + } } /** -- cgit v1.2.1 From 2a07de70c2decb9669990286391cef1d427244bc Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Tue, 25 Aug 2015 22:24:37 +0200 Subject: [ticket/14124] Migrate cron:run exceptions PHPBB3-14124 --- phpBB/phpbb/console/command/cron/run.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/cron/run.php b/phpBB/phpbb/console/command/cron/run.php index 72ad1205ef..da185b81b3 100644 --- a/phpBB/phpbb/console/command/cron/run.php +++ b/phpBB/phpbb/console/command/cron/run.php @@ -13,6 +13,7 @@ namespace phpbb\console\command\cron; +use phpbb\exception\runtime_exception; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Output\OutputInterface; @@ -92,8 +93,7 @@ class run extends \phpbb\console\command\command } else { - $output->writeln('' . $this->user->lang('CRON_LOCK_ERROR') . ''); - return 1; + throw new runtime_exception('CRON_LOCK_ERROR', array(), null, 1); } } @@ -164,8 +164,7 @@ class run extends \phpbb\console\command\command } else { - $output->writeln('' . $this->user->lang('CRON_NO_SUCH_TASK', $task_name) . ''); - return 2; + throw new runtime_exception('CRON_NO_SUCH_TASK', array( $task_name), null, 2); } } } -- cgit v1.2.1 From d13d66fc01688e0e9f49bae5cf368dc16220aa40 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 26 Aug 2015 14:09:42 +0200 Subject: [ticket/14124] CS PHPBB3-14124 --- phpBB/phpbb/console/application.php | 1 - 1 file changed, 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/application.php b/phpBB/phpbb/console/application.php index f9f2213da6..2c69a3cc73 100644 --- a/phpBB/phpbb/console/application.php +++ b/phpBB/phpbb/console/application.php @@ -13,7 +13,6 @@ namespace phpbb\console; -use phpbb\exception\exception_interface; use Symfony\Component\Console\Shell; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; -- cgit v1.2.1 From e19d446881ba98d8a1082732585da3f6d4bd262f Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 26 Aug 2015 10:05:14 -0700 Subject: [ticket/14128] Fix img bbcode regression, lost postimage class PHPBB3-14128 --- phpBB/phpbb/textformatter/s9e/factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 4a04b34cd8..63b23d2fd0 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -104,7 +104,7 @@ class factory implements \phpbb\textformatter\cache_interface 'b' => '', 'i' => '', 'u' => '', - 'img' => '{L_IMAGE}', + 'img' => '{L_IMAGE}', 'size' => '', 'color' => '', 'email' => ' -- cgit v1.2.1 From 306fbf23a8113e6d9d7160e02889bd10ea24b495 Mon Sep 17 00:00:00 2001 From: Zoddo Date: Sun, 30 Aug 2015 16:22:26 +0200 Subject: [ticket/9485] Add a "View post" link in the moderation logs PHPBB3-9485 --- phpBB/phpbb/db/migration/data/v320/log_post_id.php | 44 ++++++++++++++++++++++ phpBB/phpbb/log/log.php | 7 +++- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 phpBB/phpbb/db/migration/data/v320/log_post_id.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/log_post_id.php b/phpBB/phpbb/db/migration/data/v320/log_post_id.php new file mode 100644 index 0000000000..0f155d543c --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/log_post_id.php @@ -0,0 +1,44 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class log_post_id extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\dev'); + } + + public function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'log' => array( + 'post_id' => array('UINT', 0, 'after' => 'topic_id'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'log' => array( + 'post_id', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php index 1b02d98b82..f0ba120625 100644 --- a/phpBB/phpbb/log/log.php +++ b/phpBB/phpbb/log/log.php @@ -249,10 +249,13 @@ class log implements \phpbb\log\log_interface unset($additional_data['forum_id']); $topic_id = isset($additional_data['topic_id']) ? (int) $additional_data['topic_id'] : 0; unset($additional_data['topic_id']); + $post_id = isset($additional_data['post_id']) ? (int) $additional_data['post_id'] : 0; + unset($additional_data['post_id']); $sql_ary += array( 'log_type' => LOG_MOD, 'forum_id' => $forum_id, 'topic_id' => $topic_id, + 'post_id' => $post_id, 'log_data' => (!empty($additional_data)) ? serialize($additional_data) : '', ); break; @@ -417,7 +420,7 @@ class log implements \phpbb\log\log_interface $this->entry_count = 0; $this->last_page_offset = $offset; - $topic_id_list = $reportee_id_list = array(); + $post_id_list = $topic_id_list = $reportee_id_list = array(); $profile_url = ($this->get_is_admin() && $this->phpbb_admin_path) ? append_sid("{$this->phpbb_admin_path}index.{$this->php_ext}", 'i=users&mode=overview') : append_sid("{$this->phpbb_root_path}memberlist.{$this->php_ext}", 'mode=viewprofile'); @@ -643,6 +646,7 @@ class log implements \phpbb\log\log_interface 'time' => (int) $row['log_time'], 'forum_id' => (int) $row['forum_id'], 'topic_id' => (int) $row['topic_id'], + 'post_id' => (int) $row['post_id'], 'viewforum' => ($row['forum_id'] && $this->auth->acl_get('f_read', $row['forum_id'])) ? append_sid("{$this->phpbb_root_path}viewforum.{$this->php_ext}", 'f=' . $row['forum_id']) : false, 'action' => (isset($this->user->lang[$row['log_operation']])) ? $row['log_operation'] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}', @@ -743,6 +747,7 @@ class log implements \phpbb\log\log_interface foreach ($log as $key => $row) { $log[$key]['viewtopic'] = (isset($topic_auth['f_read'][$row['topic_id']])) ? append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 'f=' . $topic_auth['f_read'][$row['topic_id']] . '&t=' . $row['topic_id']) : false; + $log[$key]['viewpost'] = (isset($topic_auth['f_read'][$row['topic_id']]) && $row['post_id']) ? append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 'f=' . $topic_auth['f_read'][$row['topic_id']] . '&t=' . $row['topic_id'] . '&p=' . $row['post_id']) : false; $log[$key]['viewlogs'] = (isset($topic_auth['m_'][$row['topic_id']])) ? append_sid("{$this->phpbb_root_path}mcp.{$this->php_ext}", 'i=logs&mode=topic_logs&t=' . $row['topic_id'], true, $this->user->session_id) : false; } } -- cgit v1.2.1 From 58286171f1035495c8c2a6fdffce9f3842601e66 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 8 Sep 2015 12:59:55 +0200 Subject: [ticket/14150] Update fast-image-size to newest version PHPBB3-14150 --- phpBB/phpbb/avatar/driver/driver.php | 6 +++--- phpBB/phpbb/textformatter/s9e/parser.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/driver.php b/phpBB/phpbb/avatar/driver/driver.php index b6fd380bda..c849533166 100644 --- a/phpBB/phpbb/avatar/driver/driver.php +++ b/phpBB/phpbb/avatar/driver/driver.php @@ -30,7 +30,7 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface */ protected $config; - /** @var \fastImageSize\fastImageSize */ + /** @var \FastImageSize\FastImageSize */ protected $imagesize; /** @@ -76,13 +76,13 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface * Construct a driver object * * @param \phpbb\config\config $config phpBB configuration - * @param \fastImageSize\fastImageSize $imagesize fastImageSize class + * @param \FastImageSize\FastImageSize $imagesize FastImageSize class * @param string $phpbb_root_path Path to the phpBB root * @param string $php_ext PHP file extension * @param \phpbb\path_helper $path_helper phpBB path helper * @param \phpbb\cache\driver\driver_interface $cache Cache driver */ - public function __construct(\phpbb\config\config $config, \fastImageSize\fastImageSize $imagesize, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, \FastImageSize\FastImageSize $imagesize, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface $cache = null) { $this->config = $config; $this->imagesize = $imagesize; diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 838c211e56..ffaffbc63c 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -370,7 +370,7 @@ class parser implements \phpbb\textformatter\parser_interface if ($max_height || $max_width) { - $imagesize = new \fastImageSize\fastImageSize(); + $imagesize = new \FastImageSize\FastImageSize(); $size_info = $imagesize->getImageSize($url); if ($size_info === false) { -- cgit v1.2.1 From b971f20a5d9f6f163731b533fdb1242ebd27ff8f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 31 May 2015 13:29:49 +0200 Subject: [ticket/13904] Add initial factory for handling file classes PHPBB3-13904 --- phpBB/phpbb/files/factory.php | 79 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 phpBB/phpbb/files/factory.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/factory.php b/phpBB/phpbb/files/factory.php new file mode 100644 index 0000000000..9385ad678e --- /dev/null +++ b/phpBB/phpbb/files/factory.php @@ -0,0 +1,79 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files; + +class factory +{ + /** + * @var \Symfony\Component\DependencyInjection\ContainerInterface + */ + private $container; + + /** + * Constructor + * + * @param \Symfony\Component\DependencyInjection\ContainerInterface $container + */ + public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container) + { + $this->container = $container; + } + + /** + * Get files service + * + * @param string $name Service name + * + * @return object|false Requested service or false if service could not be + * found by the container + */ + public function get($name) + { + $service = false; + + try + { + $service = $this->container->get($name); + } + catch (\Exception $e) + { + // do nothing + } + + return $service; + } + + /** + * Magic function for handling get calls, e.g. get_fileupload() or + * get_filespec() and turning them into call for files. services like + * files.fileupload. + * + * @param string $name Name of called function + * @param mixed $arguments Possible supplied arguments + * + * @return object|false Requested service or false if service could not be + * found by the container + */ + public function __call($name, $arguments) + { + if (substr($name, 0, 4) === 'get_') + { + return $this->get('files.' . substr($name, 4)); + } + else + { + return false; + } + } +} -- cgit v1.2.1 From 557f1a89d512e6c4f4c96033091ab5b429825e6d Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 14 Aug 2015 09:01:29 +0200 Subject: [ticket/13904] Add filespec class to files classes PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 480 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 480 insertions(+) create mode 100644 phpBB/phpbb/files/filespec.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php new file mode 100644 index 0000000000..f74e91b0d5 --- /dev/null +++ b/phpBB/phpbb/files/filespec.php @@ -0,0 +1,480 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files; + +/** + * Responsible for holding all file relevant information, as well as doing file-specific operations. + * The {@link fileupload fileupload class} can be used to upload several files, each of them being this object to operate further on. + */ +class filespec +{ + var $filename = ''; + var $realname = ''; + var $uploadname = ''; + var $mimetype = ''; + var $extension = ''; + var $filesize = 0; + var $width = 0; + var $height = 0; + var $image_info = array(); + + var $destination_file = ''; + var $destination_path = ''; + + var $file_moved = false; + var $init_error = false; + var $local = false; + + var $error = array(); + + var $upload = ''; + + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + /** + * The plupload object + * @var \phpbb\plupload\plupload + */ + protected $plupload; + + /** + * phpBB Mimetype guesser + * @var \phpbb\mimetype\guesser + */ + protected $mimetype_guesser; + + /** + * File Class + * @access private + */ + function filespec($upload_ary, $upload_namespace, \phpbb\filesystem\filesystem_interface $phpbb_filesystem, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + { + if (!isset($upload_ary)) + { + $this->init_error = true; + return; + } + + $this->filename = $upload_ary['tmp_name']; + $this->filesize = $upload_ary['size']; + $name = (STRIP) ? stripslashes($upload_ary['name']) : $upload_ary['name']; + $name = trim(utf8_basename($name)); + $this->realname = $this->uploadname = $name; + $this->mimetype = $upload_ary['type']; + + // Opera adds the name to the mime type + $this->mimetype = (strpos($this->mimetype, '; name') !== false) ? str_replace(strstr($this->mimetype, '; name'), '', $this->mimetype) : $this->mimetype; + + if (!$this->mimetype) + { + $this->mimetype = 'application/octet-stream'; + } + + $this->extension = strtolower(self::get_extension($this->realname)); + + // Try to get real filesize from temporary folder (not always working) ;) + $this->filesize = (@filesize($this->filename)) ? @filesize($this->filename) : $this->filesize; + + $this->width = $this->height = 0; + $this->file_moved = false; + + $this->local = (isset($upload_ary['local_mode'])) ? true : false; + $this->upload = $upload_namespace; + $this->plupload = $plupload; + $this->mimetype_guesser = $mimetype_guesser; + $this->filesystem = $phpbb_filesystem; + } + + /** + * Cleans destination filename + * + * @param real|unique|unique_ext $mode real creates a realname, filtering some characters, lowering every character. Unique creates an unique filename + * @param string $prefix Prefix applied to filename + * @param string $user_id The user_id is only needed for when cleaning a user's avatar + * @access public + */ + function clean_filename($mode = 'unique', $prefix = '', $user_id = '') + { + if ($this->init_error) + { + return; + } + + switch ($mode) + { + case 'real': + // Remove every extension from filename (to not let the mime bug being exposed) + if (strpos($this->realname, '.') !== false) + { + $this->realname = substr($this->realname, 0, strpos($this->realname, '.')); + } + + // Replace any chars which may cause us problems with _ + $bad_chars = array("'", "\\", ' ', '/', ':', '*', '?', '"', '<', '>', '|'); + + $this->realname = rawurlencode(str_replace($bad_chars, '_', strtolower($this->realname))); + $this->realname = preg_replace("/%(\w{2})/", '_', $this->realname); + + $this->realname = $prefix . $this->realname . '.' . $this->extension; + break; + + case 'unique': + $this->realname = $prefix . md5(unique_id()); + break; + + case 'avatar': + $this->extension = strtolower($this->extension); + $this->realname = $prefix . $user_id . '.' . $this->extension; + + break; + + case 'unique_ext': + default: + $this->realname = $prefix . md5(unique_id()) . '.' . $this->extension; + break; + } + } + + /** + * Get property from file object + */ + function get($property) + { + if ($this->init_error || !isset($this->$property)) + { + return false; + } + + return $this->$property; + } + + /** + * Check if file is an image (mimetype) + * + * @return true if it is an image, false if not + */ + function is_image() + { + return (strpos($this->mimetype, 'image/') === 0); + } + + /** + * Check if the file got correctly uploaded + * + * @return true if it is a valid upload, false if not + */ + function is_uploaded() + { + $is_plupload = $this->plupload && $this->plupload->is_active(); + + if (!$this->local && !$is_plupload && !is_uploaded_file($this->filename)) + { + return false; + } + + if (($this->local || $is_plupload) && !file_exists($this->filename)) + { + return false; + } + + return true; + } + + /** + * Remove file + */ + function remove() + { + if ($this->file_moved) + { + @unlink($this->destination_file); + } + } + + /** + * Get file extension + * + * @param string Filename that needs to be checked + * @return string Extension of the supplied filename + */ + static public function get_extension($filename) + { + $filename = utf8_basename($filename); + + if (strpos($filename, '.') === false) + { + return ''; + } + + $filename = explode('.', $filename); + return array_pop($filename); + } + + /** + * Get mimetype + * + * @param string $filename Filename that needs to be checked + * @return string Mimetype of supplied filename + */ + function get_mimetype($filename) + { + if ($this->mimetype_guesser !== null) + { + $mimetype = $this->mimetype_guesser->guess($filename, $this->uploadname); + + if ($mimetype !== 'application/octet-stream') + { + $this->mimetype = $mimetype; + } + } + + return $this->mimetype; + } + + /** + * Get filesize + */ + function get_filesize($filename) + { + return @filesize($filename); + } + + + /** + * Check the first 256 bytes for forbidden content + */ + function check_content($disallowed_content) + { + if (empty($disallowed_content)) + { + return true; + } + + $fp = @fopen($this->filename, 'rb'); + + if ($fp !== false) + { + $ie_mime_relevant = fread($fp, 256); + fclose($fp); + foreach ($disallowed_content as $forbidden) + { + if (stripos($ie_mime_relevant, '<' . $forbidden) !== false) + { + return false; + } + } + } + return true; + } + + /** + * Move file to destination folder + * The phpbb_root_path variable will be applied to the destination path + * + * @param string $destination Destination path, for example $config['avatar_path'] + * @param bool $overwrite If set to true, an already existing file will be overwritten + * @param bool $skip_image_check If set to true, the check for the file to be a valid image is skipped + * @param string $chmod Permission mask for chmodding the file after a successful move. The mode entered here reflects the mode defined by {@link phpbb_chmod()} + * + * @access public + */ + function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false) + { + global $user, $phpbb_root_path; + + if (sizeof($this->error)) + { + return false; + } + + $chmod = ($chmod === false) ? CHMOD_READ | CHMOD_WRITE : $chmod; + + // We need to trust the admin in specifying valid upload directories and an attacker not being able to overwrite it... + $this->destination_path = $phpbb_root_path . $destination; + + // Check if the destination path exist... + if (!file_exists($this->destination_path)) + { + @unlink($this->filename); + return false; + } + + $upload_mode = (@ini_get('open_basedir') || @ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'on') ? 'move' : 'copy'; + $upload_mode = ($this->local) ? 'local' : $upload_mode; + $this->destination_file = $this->destination_path . '/' . utf8_basename($this->realname); + + // Check if the file already exist, else there is something wrong... + if (file_exists($this->destination_file) && !$overwrite) + { + @unlink($this->filename); + $this->error[] = $user->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file); + $this->file_moved = false; + return false; + } + else + { + if (file_exists($this->destination_file)) + { + @unlink($this->destination_file); + } + + switch ($upload_mode) + { + case 'copy': + + if (!@copy($this->filename, $this->destination_file)) + { + if (!@move_uploaded_file($this->filename, $this->destination_file)) + { + $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); + } + } + + break; + + case 'move': + + if (!@move_uploaded_file($this->filename, $this->destination_file)) + { + if (!@copy($this->filename, $this->destination_file)) + { + $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); + } + } + + break; + + case 'local': + + if (!@copy($this->filename, $this->destination_file)) + { + $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); + } + + break; + } + + // Remove temporary filename + @unlink($this->filename); + + if (sizeof($this->error)) + { + return false; + } + + try + { + $this->filesystem->phpbb_chmod($this->destination_file, $chmod); + } + catch (\phpbb\filesystem\exception\filesystem_exception $e) + { + // Do nothing + } + } + + // Try to get real filesize from destination folder + $this->filesize = (@filesize($this->destination_file)) ? @filesize($this->destination_file) : $this->filesize; + + // Get mimetype of supplied file + $this->mimetype = $this->get_mimetype($this->destination_file); + + if ($this->is_image() && !$skip_image_check) + { + $this->width = $this->height = 0; + + // Get imagesize class + $imagesize = new \fastImageSize\fastImageSize(); + + $this->image_info = $imagesize->getImageSize($this->destination_file, $this->mimetype); + + if ($this->image_info !== false) + { + $this->width = $this->image_info['width']; + $this->height = $this->image_info['height']; + + // Check image type + $types = fileupload::image_types(); + + if (!isset($types[$this->image_info['type']]) || !in_array($this->extension, $types[$this->image_info['type']])) + { + if (!isset($types[$this->image_info['type']])) + { + $this->error[] = $user->lang('IMAGE_FILETYPE_INVALID', $this->image_info['type'], $this->mimetype); + } + else + { + $this->error[] = $user->lang('IMAGE_FILETYPE_MISMATCH', $types[$this->image_info['type']][0], $this->extension); + } + } + + // Make sure the dimensions match a valid image + if (empty($this->width) || empty($this->height)) + { + $this->error[] = $user->lang['ATTACHED_IMAGE_NOT_IMAGE']; + } + } + else + { + $this->error[] = $user->lang['UNABLE_GET_IMAGE_SIZE']; + } + } + + $this->file_moved = true; + $this->additional_checks(); + unset($this->upload); + + return true; + } + + /** + * Performing additional checks + */ + function additional_checks() + { + global $user; + + if (!$this->file_moved) + { + return false; + } + + // Filesize is too big or it's 0 if it was larger than the maxsize in the upload form + if ($this->upload->max_filesize && ($this->get('filesize') > $this->upload->max_filesize || $this->filesize == 0)) + { + $max_filesize = get_formatted_filesize($this->upload->max_filesize, false); + + $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']); + + return false; + } + + if (!$this->upload->valid_dimensions($this)) + { + $this->error[] = $user->lang($this->upload->error_prefix . 'WRONG_SIZE', + $user->lang('PIXELS', (int) $this->upload->min_width), + $user->lang('PIXELS', (int) $this->upload->min_height), + $user->lang('PIXELS', (int) $this->upload->max_width), + $user->lang('PIXELS', (int) $this->upload->max_height), + $user->lang('PIXELS', (int) $this->width), + $user->lang('PIXELS', (int) $this->height)); + + return false; + } + + return true; + } +} -- cgit v1.2.1 From c72d6a71bb71b5abeae05b4a6494ffb166624179 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 31 May 2015 14:02:02 +0200 Subject: [ticket/13904] Modify constructor to be instantiatable by container PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index f74e91b0d5..4e52d13d01 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -33,7 +33,6 @@ class filespec var $destination_path = ''; var $file_moved = false; - var $init_error = false; var $local = false; var $error = array(); @@ -61,14 +60,19 @@ class filespec * File Class * @access private */ - function filespec($upload_ary, $upload_namespace, \phpbb\filesystem\filesystem_interface $phpbb_filesystem, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + function filespec(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { - if (!isset($upload_ary)) - { - $this->init_error = true; - return; - } + // @todo call this via files + //$this->set_upload_ary($upload_ary); + //$this->set_upload_namespace($upload_namespace); + $this->plupload = $plupload; + $this->mimetype_guesser = $mimetype_guesser; + $this->filesystem = $phpbb_filesystem; + } + + public function set_upload_ary($upload_ary) + { $this->filename = $upload_ary['tmp_name']; $this->filesize = $upload_ary['size']; $name = (STRIP) ? stripslashes($upload_ary['name']) : $upload_ary['name']; @@ -93,10 +97,21 @@ class filespec $this->file_moved = false; $this->local = (isset($upload_ary['local_mode'])) ? true : false; - $this->upload = $upload_namespace; - $this->plupload = $plupload; - $this->mimetype_guesser = $mimetype_guesser; - $this->filesystem = $phpbb_filesystem; + } + + public function set_upload_namespace($namespace) + { + $this->upload = $namespace; + } + + /** + * Check if class members were not properly initalised yet + * + * @return bool True if there was an init error, false if not + */ + protected function init_error() + { + return !isset($upload_ary); } /** @@ -109,7 +124,7 @@ class filespec */ function clean_filename($mode = 'unique', $prefix = '', $user_id = '') { - if ($this->init_error) + if ($this->init_error()) { return; } @@ -154,7 +169,7 @@ class filespec */ function get($property) { - if ($this->init_error || !isset($this->$property)) + if ($this->init_error() || !isset($this->$property)) { return false; } -- cgit v1.2.1 From 0cbb713cc2a6249cb12507db7d0fa78ce8663ae6 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 31 May 2015 14:47:57 +0200 Subject: [ticket/13904] Fix uploading for use with new filespec class PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 4e52d13d01..8501b217f7 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -60,7 +60,7 @@ class filespec * File Class * @access private */ - function filespec(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { // @todo call this via files //$this->set_upload_ary($upload_ary); @@ -109,9 +109,9 @@ class filespec * * @return bool True if there was an init error, false if not */ - protected function init_error() + public function init_error() { - return !isset($upload_ary); + return !isset($this->filename); } /** @@ -422,7 +422,7 @@ class filespec $this->height = $this->image_info['height']; // Check image type - $types = fileupload::image_types(); + $types = \fileupload::image_types(); if (!isset($types[$this->image_info['type']]) || !in_array($this->extension, $types[$this->image_info['type']])) { -- cgit v1.2.1 From 92e49cd0acef56b78fda3bcffebb7a0958891b82 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 1 Jun 2015 13:27:29 +0200 Subject: [ticket/13904] Turn filespec into prototype and improve init methods PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 8501b217f7..3f50488e7c 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -97,11 +97,15 @@ class filespec $this->file_moved = false; $this->local = (isset($upload_ary['local_mode'])) ? true : false; + + return $this; } public function set_upload_namespace($namespace) { $this->upload = $namespace; + + return $this; } /** -- cgit v1.2.1 From d2be8e1503db3686c62b23973511c61dea7a6616 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 1 Jun 2015 13:30:17 +0200 Subject: [ticket/13904] Add fileupload class to files classes PHPBB3-13904 --- phpBB/phpbb/files/upload.php | 655 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 655 insertions(+) create mode 100644 phpBB/phpbb/files/upload.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php new file mode 100644 index 0000000000..7501247e06 --- /dev/null +++ b/phpBB/phpbb/files/upload.php @@ -0,0 +1,655 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files; + +/** + * File upload class + * Init class (all parameters optional and able to be set/overwritten separately) - scope is global and valid for all uploads + */ +class upload +{ + var $allowed_extensions = array(); + var $disallowed_content = array('body', 'head', 'html', 'img', 'plaintext', 'a href', 'pre', 'script', 'table', 'title'); + var $max_filesize = 0; + var $min_width = 0; + var $min_height = 0; + var $max_width = 0; + var $max_height = 0; + var $error_prefix = ''; + + /** @var int Timeout for remote upload */ + var $upload_timeout = 6; + + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + /** + * Init file upload class. + * + * @param \phpbb\filesystem\filesystem_interface $filesystem + * @param string $error_prefix Used error messages will get prefixed by this string + * @param array $allowed_extensions Array of allowed extensions, for example array('jpg', 'jpeg', 'gif', 'png') + * @param int $max_filesize Maximum filesize + * @param int $min_width Minimum image width (only checked for images) + * @param int $min_height Minimum image height (only checked for images) + * @param int $max_width Maximum image width (only checked for images) + * @param int $max_height Maximum image height (only checked for images) + * @param bool|array $disallowed_content If enabled, the first 256 bytes of the file must not + * contain any of its values. Defaults to false. + * + */ + function fileupload(\phpbb\filesystem\filesystem_interface $filesystem, $error_prefix = '', $allowed_extensions = false, $max_filesize = false, $min_width = false, $min_height = false, $max_width = false, $max_height = false, $disallowed_content = false) + { + $this->set_allowed_extensions($allowed_extensions); + $this->set_max_filesize($max_filesize); + $this->set_allowed_dimensions($min_width, $min_height, $max_width, $max_height); + $this->set_error_prefix($error_prefix); + $this->set_disallowed_content($disallowed_content); + $this->filesystem = $filesystem; + } + + /** + * Reset vars + */ + function reset_vars() + { + $this->max_filesize = 0; + $this->min_width = $this->min_height = $this->max_width = $this->max_height = 0; + $this->error_prefix = ''; + $this->allowed_extensions = array(); + $this->disallowed_content = array(); + } + + /** + * Set allowed extensions + */ + function set_allowed_extensions($allowed_extensions) + { + if ($allowed_extensions !== false && is_array($allowed_extensions)) + { + $this->allowed_extensions = $allowed_extensions; + } + } + + /** + * Set allowed dimensions + */ + function set_allowed_dimensions($min_width, $min_height, $max_width, $max_height) + { + $this->min_width = (int) $min_width; + $this->min_height = (int) $min_height; + $this->max_width = (int) $max_width; + $this->max_height = (int) $max_height; + } + + /** + * Set maximum allowed filesize + */ + function set_max_filesize($max_filesize) + { + if ($max_filesize !== false && (int) $max_filesize) + { + $this->max_filesize = (int) $max_filesize; + } + } + + /** + * Set disallowed strings + */ + function set_disallowed_content($disallowed_content) + { + if ($disallowed_content !== false && is_array($disallowed_content)) + { + $this->disallowed_content = array_diff($disallowed_content, array('')); + } + } + + /** + * Set error prefix + */ + function set_error_prefix($error_prefix) + { + $this->error_prefix = $error_prefix; + } + + /** + * Form upload method + * Upload file from users harddisk + * + * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) + * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser + * @param \phpbb\plupload\plupload $plupload The plupload object + * + * @return object $file Object "filespec" is returned, all further operations can be done with this object + * @access public + */ + function form_upload($form_name, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + { + global $user, $request, $phpbb_container; + + $upload = $request->file($form_name); + unset($upload['local_mode']); + + if ($plupload) + { + $result = $plupload->handle_upload($form_name); + if (is_array($result)) + { + $upload = array_merge($upload, $result); + } + } + + /** @var \phpbb\files\filespec $file */ + $file = $phpbb_container->get('files.filespec') + ->set_upload_ary($upload) + ->set_upload_namespace($this); + + if ($file->init_error()) + { + $file->error[] = ''; + return $file; + } + + // Error array filled? + if (isset($upload['error'])) + { + $error = $this->assign_internal_error($upload['error']); + + if ($error !== false) + { + $file->error[] = $error; + return $file; + } + } + + // Check if empty file got uploaded (not catched by is_uploaded_file) + if (isset($upload['size']) && $upload['size'] == 0) + { + $file->error[] = $user->lang[$this->error_prefix . 'EMPTY_FILEUPLOAD']; + return $file; + } + + // PHP Upload filesize exceeded + if ($file->get('filename') == 'none') + { + $max_filesize = @ini_get('upload_max_filesize'); + $unit = 'MB'; + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $max_filesize = (int) $max_filesize; + + $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); + } + + $file->error[] = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); + return $file; + } + + // Not correctly uploaded + if (!$file->is_uploaded()) + { + $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED']; + return $file; + } + + $this->common_checks($file); + + return $file; + } + + /** + * Move file from another location to phpBB + */ + function local_upload($source_file, $filedata = false, \phpbb\mimetype\guesser $mimetype_guesser = null) + { + global $user, $request, $phpbb_container; + + $upload = array(); + + $upload['local_mode'] = true; + $upload['tmp_name'] = $source_file; + + if ($filedata === false) + { + $upload['name'] = utf8_basename($source_file); + $upload['size'] = 0; + } + else + { + $upload['name'] = $filedata['realname']; + $upload['size'] = $filedata['size']; + $upload['type'] = $filedata['type']; + } + + /** @var \phpbb\files\filespec $file */ + $file = $phpbb_container->get('files.filespec') + ->set_upload_ary($upload) + ->set_upload_namespace($this); + + if ($file->init_error()) + { + $file->error[] = ''; + return $file; + } + + if (isset($upload['error'])) + { + $error = $this->assign_internal_error($upload['error']); + + if ($error !== false) + { + $file->error[] = $error; + return $file; + } + } + + // PHP Upload filesize exceeded + if ($file->get('filename') == 'none') + { + $max_filesize = @ini_get('upload_max_filesize'); + $unit = 'MB'; + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $max_filesize = (int) $max_filesize; + + $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); + } + + $file->error[] = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); + return $file; + } + + // Not correctly uploaded + if (!$file->is_uploaded()) + { + $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED']; + return $file; + } + + $this->common_checks($file); + $request->overwrite('local', $upload, \phpbb\request\request_interface::FILES); + + return $file; + } + + /** + * Remote upload method + * Uploads file from given url + * + * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif + * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser + * @return object $file Object "filespec" is returned, all further operations can be done with this object + * @access public + */ + function remote_upload($upload_url, \phpbb\mimetype\guesser $mimetype_guesser = null) + { + global $user, $phpbb_root_path, $phpbb_container; + + $upload_ary = array(); + $upload_ary['local_mode'] = true; + + if (!preg_match('#^(https?://).*?\.(' . implode('|', $this->allowed_extensions) . ')$#i', $upload_url, $match)) + { + $file = new fileerror($user->lang[$this->error_prefix . 'URL_INVALID']); + return $file; + } + + if (empty($match[2])) + { + $file = new fileerror($user->lang[$this->error_prefix . 'URL_INVALID']); + return $file; + } + + $url = parse_url($upload_url); + + $host = $url['host']; + $path = $url['path']; + $port = (!empty($url['port'])) ? (int) $url['port'] : 80; + + $upload_ary['type'] = 'application/octet-stream'; + + $url['path'] = explode('.', $url['path']); + $ext = array_pop($url['path']); + + $url['path'] = implode('', $url['path']); + $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : ''); + $filename = $url['path']; + $filesize = 0; + + $remote_max_filesize = $this->max_filesize; + if (!$remote_max_filesize) + { + $max_filesize = @ini_get('upload_max_filesize'); + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $remote_max_filesize = (int) $max_filesize; + + switch ($unit) + { + case 'g': + $remote_max_filesize *= 1024; + // no break + case 'm': + $remote_max_filesize *= 1024; + // no break + case 'k': + $remote_max_filesize *= 1024; + // no break + } + } + } + + $errno = 0; + $errstr = ''; + + if (!($fsock = @fsockopen($host, $port, $errno, $errstr))) + { + $file = new fileerror($user->lang[$this->error_prefix . 'NOT_UPLOADED']); + return $file; + } + + // Make sure $path not beginning with / + if (strpos($path, '/') === 0) + { + $path = substr($path, 1); + } + + fputs($fsock, 'GET /' . $path . " HTTP/1.1\r\n"); + fputs($fsock, "HOST: " . $host . "\r\n"); + fputs($fsock, "Connection: close\r\n\r\n"); + + // Set a proper timeout for the socket + socket_set_timeout($fsock, $this->upload_timeout); + + $get_info = false; + $data = ''; + $length = false; + $timer_stop = time() + $this->upload_timeout; + + while ((!$length || $filesize < $length) && !@feof($fsock)) + { + if ($get_info) + { + if ($length) + { + // Don't attempt to read past end of file if server indicated length + $block = @fread($fsock, min($length - $filesize, 1024)); + } + else + { + $block = @fread($fsock, 1024); + } + + $filesize += strlen($block); + + if ($remote_max_filesize && $filesize > $remote_max_filesize) + { + $max_filesize = get_formatted_filesize($remote_max_filesize, false); + + $file = new fileerror(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); + return $file; + } + + $data .= $block; + } + else + { + $line = @fgets($fsock, 1024); + + if ($line == "\r\n") + { + $get_info = true; + } + else + { + if (stripos($line, 'content-type: ') !== false) + { + $upload_ary['type'] = rtrim(str_replace('content-type: ', '', strtolower($line))); + } + else if ($this->max_filesize && stripos($line, 'content-length: ') !== false) + { + $length = (int) str_replace('content-length: ', '', strtolower($line)); + + if ($remote_max_filesize && $length && $length > $remote_max_filesize) + { + $max_filesize = get_formatted_filesize($remote_max_filesize, false); + + $file = new fileerror(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); + return $file; + } + } + else if (stripos($line, '404 not found') !== false) + { + $file = new fileerror($user->lang[$this->error_prefix . 'URL_NOT_FOUND']); + return $file; + } + } + } + + $stream_meta_data = stream_get_meta_data($fsock); + + // Cancel upload if we exceed timeout + if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) + { + $file = new fileerror($user->lang[$this->error_prefix . 'REMOTE_UPLOAD_TIMEOUT']); + return $file; + } + } + @fclose($fsock); + + if (empty($data)) + { + $file = new fileerror($user->lang[$this->error_prefix . 'EMPTY_REMOTE_DATA']); + return $file; + } + + $tmp_path = (!@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'off') ? false : $phpbb_root_path . 'cache'; + $filename = tempnam($tmp_path, unique_id() . '-'); + + if (!($fp = @fopen($filename, 'wb'))) + { + $file = new fileerror($user->lang[$this->error_prefix . 'NOT_UPLOADED']); + return $file; + } + + $upload_ary['size'] = fwrite($fp, $data); + fclose($fp); + unset($data); + + $upload_ary['tmp_name'] = $filename; + + /** @var \phpbb\files\filespec $file */ + $file = $phpbb_container->get('files.filespec') + ->set_upload_ary($upload_ary) + ->set_upload_namespace($this); + $this->common_checks($file); + + return $file; + } + + /** + * Assign internal error + * @access private + */ + function assign_internal_error($errorcode) + { + global $user; + + switch ($errorcode) + { + case 1: + $max_filesize = @ini_get('upload_max_filesize'); + $unit = 'MB'; + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $max_filesize = (int) $max_filesize; + + $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); + } + + $error = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); + break; + + case 2: + $max_filesize = get_formatted_filesize($this->max_filesize, false); + + $error = sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']); + break; + + case 3: + $error = $user->lang[$this->error_prefix . 'PARTIAL_UPLOAD']; + break; + + case 4: + $error = $user->lang[$this->error_prefix . 'NOT_UPLOADED']; + break; + + case 6: + $error = 'Temporary folder could not be found. Please check your PHP installation.'; + break; + + default: + $error = false; + break; + } + + return $error; + } + + /** + * Perform common checks + */ + function common_checks(&$file) + { + global $user; + + // Filesize is too big or it's 0 if it was larger than the maxsize in the upload form + if ($this->max_filesize && ($file->get('filesize') > $this->max_filesize || $file->get('filesize') == 0)) + { + $max_filesize = get_formatted_filesize($this->max_filesize, false); + + $file->error[] = sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']); + } + + // check Filename + if (preg_match("#[\\/:*?\"<>|]#i", $file->get('realname'))) + { + $file->error[] = sprintf($user->lang[$this->error_prefix . 'INVALID_FILENAME'], $file->get('realname')); + } + + // Invalid Extension + if (!$this->valid_extension($file)) + { + $file->error[] = sprintf($user->lang[$this->error_prefix . 'DISALLOWED_EXTENSION'], $file->get('extension')); + } + + // MIME Sniffing + if (!$this->valid_content($file)) + { + $file->error[] = sprintf($user->lang[$this->error_prefix . 'DISALLOWED_CONTENT']); + } + } + + /** + * Check for allowed extension + */ + function valid_extension(&$file) + { + return (in_array($file->get('extension'), $this->allowed_extensions)) ? true : false; + } + + /** + * Check for allowed dimension + */ + function valid_dimensions(&$file) + { + if (!$this->max_width && !$this->max_height && !$this->min_width && !$this->min_height) + { + return true; + } + + if (($file->get('width') > $this->max_width && $this->max_width) || + ($file->get('height') > $this->max_height && $this->max_height) || + ($file->get('width') < $this->min_width && $this->min_width) || + ($file->get('height') < $this->min_height && $this->min_height)) + { + return false; + } + + return true; + } + + /** + * Check if form upload is valid + */ + function is_valid($form_name) + { + global $request; + $upload = $request->file($form_name); + + return (!empty($upload) && $upload['name'] !== 'none'); + } + + + /** + * Check for bad content (IE mime-sniffing) + */ + function valid_content(&$file) + { + return ($file->check_content($this->disallowed_content)); + } + + /** + * Get image type/extension mapping + * + * @return array Array containing the image types and their extensions + */ + static public function image_types() + { + $result = array( + IMAGETYPE_GIF => array('gif'), + IMAGETYPE_JPEG => array('jpg', 'jpeg'), + IMAGETYPE_PNG => array('png'), + IMAGETYPE_SWF => array('swf'), + IMAGETYPE_PSD => array('psd'), + IMAGETYPE_BMP => array('bmp'), + IMAGETYPE_TIFF_II => array('tif', 'tiff'), + IMAGETYPE_TIFF_MM => array('tif', 'tiff'), + IMAGETYPE_JPC => array('jpg', 'jpeg'), + IMAGETYPE_JP2 => array('jpg', 'jpeg'), + IMAGETYPE_JPX => array('jpg', 'jpeg'), + IMAGETYPE_JB2 => array('jpg', 'jpeg'), + IMAGETYPE_IFF => array('iff'), + IMAGETYPE_WBMP => array('wbmp'), + IMAGETYPE_XBM => array('xbm'), + ); + + if (defined('IMAGETYPE_SWC')) + { + $result[IMAGETYPE_SWC] = array('swc'); + } + + return $result; + } +} -- cgit v1.2.1 From 1af6f052d80e693d289258d490c1187a064093b9 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 14 Aug 2015 09:03:55 +0200 Subject: [ticket/13904] Load upload class using factory PHPBB3-13904 --- phpBB/phpbb/avatar/driver/remote.php | 9 ++------- phpBB/phpbb/avatar/driver/upload.php | 26 +++++++++++++++++++------- phpBB/phpbb/files/upload.php | 31 ++++++++++++++++--------------- phpBB/phpbb/plupload/plupload.php | 2 +- 4 files changed, 38 insertions(+), 30 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/remote.php b/phpBB/phpbb/avatar/driver/remote.php index 90443c9b4e..0526b9184e 100644 --- a/phpBB/phpbb/avatar/driver/remote.php +++ b/phpBB/phpbb/avatar/driver/remote.php @@ -114,13 +114,8 @@ class remote extends \phpbb\avatar\driver\driver return false; } - if (!class_exists('fileupload')) - { - include($this->phpbb_root_path . 'includes/functions_upload.' . $this->php_ext); - } - - $types = \fileupload::image_types(); - $extension = strtolower(\filespec::get_extension($url)); + $types = \phpbb\files\upload::image_types(); + $extension = strtolower(\phpbb\files\filespec::get_extension($url)); // Check if this is actually an image if ($file_stream = @fopen($url, 'r')) diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index b31609b982..4cdb65ce84 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -33,6 +33,11 @@ class upload extends \phpbb\avatar\driver\driver */ protected $dispatcher; + /** + * @var \phpbb\files\factory + */ + protected $files_factory; + /** * Construct a driver object * @@ -43,9 +48,10 @@ class upload extends \phpbb\avatar\driver\driver * @param \phpbb\path_helper $path_helper phpBB path helper * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser * @param \phpbb\event\dispatcher_interface $dispatcher phpBB Event dispatcher object + * @param \phpbb\files\factory $files_factory File classes factory * @param \phpbb\cache\driver\driver_interface $cache Cache driver */ - public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\files\factory $files_factory, \phpbb\cache\driver\driver_interface $cache = null) { $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; @@ -54,6 +60,7 @@ class upload extends \phpbb\avatar\driver\driver $this->path_helper = $path_helper; $this->mimetype_guesser = $mimetype_guesser; $this->dispatcher = $dispatcher; + $this->files_factory = $files_factory; $this->cache = $cache; } @@ -99,12 +106,17 @@ class upload extends \phpbb\avatar\driver\driver return false; } - if (!class_exists('fileupload')) - { - include($this->phpbb_root_path . 'includes/functions_upload.' . $this->php_ext); - } - - $upload = new \fileupload($this->filesystem, 'AVATAR_', $this->allowed_extensions, $this->config['avatar_filesize'], $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], (isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false)); + /** @var \phpbb\files\upload $upload */ + $upload = $this->files_factory->get('upload') + ->set_error_prefix('AVATAR_') + ->set_allowed_extensions($this->allowed_extensions) + ->set_max_filesize($this->config['avatar_filesize']) + ->set_allowed_dimensions( + $this->config['avatar_min_width'], + $this->config['avatar_min_height'], + $this->config['avatar_max_width'], + $this->config['avatar_max_height']) + ->set_disallowed_content((isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false)); $url = $request->variable('avatar_upload_url', ''); $upload_file = $request->file('avatar_upload_file'); diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 7501247e06..8666b857a5 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -40,24 +40,15 @@ class upload * Init file upload class. * * @param \phpbb\filesystem\filesystem_interface $filesystem - * @param string $error_prefix Used error messages will get prefixed by this string - * @param array $allowed_extensions Array of allowed extensions, for example array('jpg', 'jpeg', 'gif', 'png') - * @param int $max_filesize Maximum filesize - * @param int $min_width Minimum image width (only checked for images) - * @param int $min_height Minimum image height (only checked for images) - * @param int $max_width Maximum image width (only checked for images) - * @param int $max_height Maximum image height (only checked for images) - * @param bool|array $disallowed_content If enabled, the first 256 bytes of the file must not - * contain any of its values. Defaults to false. * */ - function fileupload(\phpbb\filesystem\filesystem_interface $filesystem, $error_prefix = '', $allowed_extensions = false, $max_filesize = false, $min_width = false, $min_height = false, $max_width = false, $max_height = false, $disallowed_content = false) + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem) { - $this->set_allowed_extensions($allowed_extensions); - $this->set_max_filesize($max_filesize); - $this->set_allowed_dimensions($min_width, $min_height, $max_width, $max_height); - $this->set_error_prefix($error_prefix); - $this->set_disallowed_content($disallowed_content); +// $this->set_allowed_extensions($allowed_extensions); +// $this->set_max_filesize($max_filesize); +// $this->set_allowed_dimensions($min_width, $min_height, $max_width, $max_height); +// $this->set_error_prefix($error_prefix); +// $this->set_disallowed_content($disallowed_content); $this->filesystem = $filesystem; } @@ -82,6 +73,8 @@ class upload { $this->allowed_extensions = $allowed_extensions; } + + return $this; } /** @@ -93,6 +86,8 @@ class upload $this->min_height = (int) $min_height; $this->max_width = (int) $max_width; $this->max_height = (int) $max_height; + + return $this; } /** @@ -104,6 +99,8 @@ class upload { $this->max_filesize = (int) $max_filesize; } + + return $this; } /** @@ -115,6 +112,8 @@ class upload { $this->disallowed_content = array_diff($disallowed_content, array('')); } + + return $this; } /** @@ -123,6 +122,8 @@ class upload function set_error_prefix($error_prefix) { $this->error_prefix = $error_prefix; + + return $this; } /** diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index ca78167ec0..35f3a0071e 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -303,7 +303,7 @@ class plupload $this->temporary_directory, $this->config['plupload_salt'], md5($file_name), - \filespec::get_extension($file_name) + \phpbb\files\filespec::get_extension($file_name) ); } -- cgit v1.2.1 From 8c2cbc0599b9d62fde730b2891c73c9c053682e7 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 1 Jun 2015 13:51:05 +0200 Subject: [ticket/13904] Remove magic method from factory and allow short names PHPBB3-13904 --- phpBB/phpbb/files/factory.php | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/factory.php b/phpBB/phpbb/files/factory.php index 9385ad678e..508c50c6ce 100644 --- a/phpBB/phpbb/files/factory.php +++ b/phpBB/phpbb/files/factory.php @@ -35,13 +35,15 @@ class factory * * @param string $name Service name * - * @return object|false Requested service or false if service could not be + * @return object|bool Requested service or false if service could not be * found by the container */ public function get($name) { $service = false; + $name = (strpos($name, 'files.') === false) ? 'files.' . $name : $name; + try { $service = $this->container->get($name); @@ -53,27 +55,4 @@ class factory return $service; } - - /** - * Magic function for handling get calls, e.g. get_fileupload() or - * get_filespec() and turning them into call for files. services like - * files.fileupload. - * - * @param string $name Name of called function - * @param mixed $arguments Possible supplied arguments - * - * @return object|false Requested service or false if service could not be - * found by the container - */ - public function __call($name, $arguments) - { - if (substr($name, 0, 4) === 'get_') - { - return $this->get('files.' . substr($name, 4)); - } - else - { - return false; - } - } } -- cgit v1.2.1 From 186b4495b625a40459618f01784b814a29f98ae0 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 1 Jun 2015 13:52:01 +0200 Subject: [ticket/13904] Allow using factory for none files. classes PHPBB3-13904 --- phpBB/phpbb/files/factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/factory.php b/phpBB/phpbb/files/factory.php index 508c50c6ce..b28a7ab659 100644 --- a/phpBB/phpbb/files/factory.php +++ b/phpBB/phpbb/files/factory.php @@ -42,7 +42,7 @@ class factory { $service = false; - $name = (strpos($name, 'files.') === false) ? 'files.' . $name : $name; + $name = (strpos($name, 'files.') === false && strpos($name, '.') === false) ? 'files.' . $name : $name; try { -- cgit v1.2.1 From a96e7a8ec6efa483b47dca3395ee2de608cfc675 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 1 Jun 2015 13:57:17 +0200 Subject: [ticket/13904] Get rid of useless parameters and variables PHPBB3-13904 --- phpBB/phpbb/avatar/driver/upload.php | 4 ++-- phpBB/phpbb/files/upload.php | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index 4cdb65ce84..d330eadd18 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -123,7 +123,7 @@ class upload extends \phpbb\avatar\driver\driver if (!empty($upload_file['name'])) { - $file = $upload->form_upload('avatar_upload_file', $this->mimetype_guesser); + $file = $upload->form_upload('avatar_upload_file'); } else if (!empty($this->config['allow_avatar_remote_upload']) && !empty($url)) { @@ -153,7 +153,7 @@ class upload extends \phpbb\avatar\driver\driver return false; } - $file = $upload->remote_upload($url, $this->mimetype_guesser); + $file = $upload->remote_upload($url); } else { diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 8666b857a5..1892d22adf 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -131,13 +131,12 @@ class upload * Upload file from users harddisk * * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) - * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser * @param \phpbb\plupload\plupload $plupload The plupload object * * @return object $file Object "filespec" is returned, all further operations can be done with this object * @access public */ - function form_upload($form_name, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + function form_upload($form_name, \phpbb\plupload\plupload $plupload = null) { global $user, $request, $phpbb_container; @@ -216,7 +215,7 @@ class upload /** * Move file from another location to phpBB */ - function local_upload($source_file, $filedata = false, \phpbb\mimetype\guesser $mimetype_guesser = null) + function local_upload($source_file, $filedata = false) { global $user, $request, $phpbb_container; @@ -295,11 +294,10 @@ class upload * Uploads file from given url * * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif - * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser * @return object $file Object "filespec" is returned, all further operations can be done with this object * @access public */ - function remote_upload($upload_url, \phpbb\mimetype\guesser $mimetype_guesser = null) + function remote_upload($upload_url) { global $user, $phpbb_root_path, $phpbb_container; -- cgit v1.2.1 From 57de89628622a80fcb386c0d95724fe4c6148929 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 14 Aug 2015 09:10:05 +0200 Subject: [ticket/13904] Remove unneeded parameters from avatars and fix tests PHPBB3-13904 --- phpBB/phpbb/avatar/driver/upload.php | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index d330eadd18..e848f9d2e7 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -18,22 +18,12 @@ namespace phpbb\avatar\driver; */ class upload extends \phpbb\avatar\driver\driver { - /** - * @var \phpbb\filesystem\filesystem_interface - */ - protected $filesystem; - - /** - * @var \phpbb\mimetype\guesser - */ - protected $mimetype_guesser; - /** * @var \phpbb\event\dispatcher_interface */ protected $dispatcher; - /** + /**sts * @var \phpbb\files\factory */ protected $files_factory; @@ -44,21 +34,17 @@ class upload extends \phpbb\avatar\driver\driver * @param \phpbb\config\config $config phpBB configuration * @param string $phpbb_root_path Path to the phpBB root * @param string $php_ext PHP file extension - * @param \phpbb\filesystem\filesystem_interface phpBB filesystem helper * @param \phpbb\path_helper $path_helper phpBB path helper - * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser * @param \phpbb\event\dispatcher_interface $dispatcher phpBB Event dispatcher object * @param \phpbb\files\factory $files_factory File classes factory * @param \phpbb\cache\driver\driver_interface $cache Cache driver */ - public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\files\factory $files_factory, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\files\factory $files_factory, \phpbb\cache\driver\driver_interface $cache = null) { $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; - $this->filesystem = $filesystem; $this->path_helper = $path_helper; - $this->mimetype_guesser = $mimetype_guesser; $this->dispatcher = $dispatcher; $this->files_factory = $files_factory; $this->cache = $cache; -- cgit v1.2.1 From 2915647a546b4c0733a0e1a0cdc924272e41615b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 2 Jun 2015 00:29:03 +0200 Subject: [ticket/13904] Fix filespec tests PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 3f50488e7c..2fdba2d793 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -426,7 +426,7 @@ class filespec $this->height = $this->image_info['height']; // Check image type - $types = \fileupload::image_types(); + $types = upload::image_types(); if (!isset($types[$this->image_info['type']]) || !in_array($this->extension, $types[$this->image_info['type']])) { -- cgit v1.2.1 From f32a94ae5d5df156cc33e34a98d9a2e92385c393 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 14 Aug 2015 09:12:43 +0200 Subject: [ticket/13904] Pass filesystem to upload avatar again PHPBB3-13904 --- phpBB/phpbb/avatar/driver/upload.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index e848f9d2e7..c1ce18cb12 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -18,12 +18,17 @@ namespace phpbb\avatar\driver; */ class upload extends \phpbb\avatar\driver\driver { + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + /** * @var \phpbb\event\dispatcher_interface */ protected $dispatcher; - /**sts + /** * @var \phpbb\files\factory */ protected $files_factory; @@ -34,16 +39,18 @@ class upload extends \phpbb\avatar\driver\driver * @param \phpbb\config\config $config phpBB configuration * @param string $phpbb_root_path Path to the phpBB root * @param string $php_ext PHP file extension + * @param \phpbb\filesystem\filesystem_interface $filesystem phpBB filesystem helper * @param \phpbb\path_helper $path_helper phpBB path helper * @param \phpbb\event\dispatcher_interface $dispatcher phpBB Event dispatcher object * @param \phpbb\files\factory $files_factory File classes factory * @param \phpbb\cache\driver\driver_interface $cache Cache driver */ - public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\files\factory $files_factory, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\path_helper $path_helper, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\files\factory $files_factory, \phpbb\cache\driver\driver_interface $cache = null) { $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; + $this->filesystem = $filesystem; $this->path_helper = $path_helper; $this->dispatcher = $dispatcher; $this->files_factory = $files_factory; -- cgit v1.2.1 From eb11973ea8af41623a9e6e6c320cb1fb0df7a222 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 14 Aug 2015 09:13:27 +0200 Subject: [ticket/13904] Use factory instead of container and add factory to services PHPBB3-13904 --- phpBB/phpbb/files/upload.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 1892d22adf..7ca29efe1a 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -36,20 +36,20 @@ class upload */ protected $filesystem; + /** @var \phpbb\files\factory Files factory */ + protected $factory; + /** * Init file upload class. * * @param \phpbb\filesystem\filesystem_interface $filesystem + * @param \phpbb\files\factory $factory Files factory * */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem) + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, factory $factory) { -// $this->set_allowed_extensions($allowed_extensions); -// $this->set_max_filesize($max_filesize); -// $this->set_allowed_dimensions($min_width, $min_height, $max_width, $max_height); -// $this->set_error_prefix($error_prefix); -// $this->set_disallowed_content($disallowed_content); $this->filesystem = $filesystem; + $this->factory = $factory; } /** @@ -138,7 +138,7 @@ class upload */ function form_upload($form_name, \phpbb\plupload\plupload $plupload = null) { - global $user, $request, $phpbb_container; + global $user, $request; $upload = $request->file($form_name); unset($upload['local_mode']); @@ -153,7 +153,7 @@ class upload } /** @var \phpbb\files\filespec $file */ - $file = $phpbb_container->get('files.filespec') + $file = $this->factory->get('filespec') ->set_upload_ary($upload) ->set_upload_namespace($this); @@ -217,7 +217,7 @@ class upload */ function local_upload($source_file, $filedata = false) { - global $user, $request, $phpbb_container; + global $user, $request; $upload = array(); @@ -237,7 +237,7 @@ class upload } /** @var \phpbb\files\filespec $file */ - $file = $phpbb_container->get('files.filespec') + $file = $this->factory->get('filespec') ->set_upload_ary($upload) ->set_upload_namespace($this); @@ -299,7 +299,7 @@ class upload */ function remote_upload($upload_url) { - global $user, $phpbb_root_path, $phpbb_container; + global $user, $phpbb_root_path; $upload_ary = array(); $upload_ary['local_mode'] = true; @@ -477,7 +477,7 @@ class upload $upload_ary['tmp_name'] = $filename; /** @var \phpbb\files\filespec $file */ - $file = $phpbb_container->get('files.filespec') + $file = $this->factory->get('filespec') ->set_upload_ary($upload_ary) ->set_upload_namespace($this); $this->common_checks($file); -- cgit v1.2.1 From a53825ad760cc8437d8c26eb1f947622c0fcf229 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 2 Jun 2015 11:48:55 +0200 Subject: [ticket/13904] No longer use fileerror class for extending filespec class PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 14 ++++++++++++++ phpBB/phpbb/files/upload.php | 27 +++++++++------------------ 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 2fdba2d793..d14c9a226d 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -118,6 +118,20 @@ class filespec return !isset($this->filename); } + /** + * Set error in error array + * + * @param mixed $error Content for error array + * + * @return \phpbb\files\filespec This instance of the filespec class + */ + public function set_error($error) + { + $this->error[] = $error; + + return $this; + } + /** * Cleans destination filename * diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 7ca29efe1a..291cdb266c 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -306,14 +306,12 @@ class upload if (!preg_match('#^(https?://).*?\.(' . implode('|', $this->allowed_extensions) . ')$#i', $upload_url, $match)) { - $file = new fileerror($user->lang[$this->error_prefix . 'URL_INVALID']); - return $file; + return $this->factory->get('filespec')->set_error($user->lang[$this->error_prefix . 'URL_INVALID']); } if (empty($match[2])) { - $file = new fileerror($user->lang[$this->error_prefix . 'URL_INVALID']); - return $file; + return $this->factory->get('filespec')->set_error($user->lang[$this->error_prefix . 'URL_INVALID']);e; } $url = parse_url($upload_url); @@ -362,8 +360,7 @@ class upload if (!($fsock = @fsockopen($host, $port, $errno, $errstr))) { - $file = new fileerror($user->lang[$this->error_prefix . 'NOT_UPLOADED']); - return $file; + return $this->factory->get('filespec')->set_error($user->lang[$this->error_prefix . 'NOT_UPLOADED']); } // Make sure $path not beginning with / @@ -404,8 +401,7 @@ class upload { $max_filesize = get_formatted_filesize($remote_max_filesize, false); - $file = new fileerror(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); - return $file; + return $this->factory->get('filespec')->set_error(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); } $data .= $block; @@ -432,14 +428,12 @@ class upload { $max_filesize = get_formatted_filesize($remote_max_filesize, false); - $file = new fileerror(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); - return $file; + return $this->factory->get('filespec')->set_error(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); } } else if (stripos($line, '404 not found') !== false) { - $file = new fileerror($user->lang[$this->error_prefix . 'URL_NOT_FOUND']); - return $file; + return $this->factory->get('filespec')->set_error($this->error_prefix . 'URL_NOT_FOUND'); } } } @@ -449,16 +443,14 @@ class upload // Cancel upload if we exceed timeout if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) { - $file = new fileerror($user->lang[$this->error_prefix . 'REMOTE_UPLOAD_TIMEOUT']); - return $file; + return $this->factory->get('filespec')->set_error($this->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); } } @fclose($fsock); if (empty($data)) { - $file = new fileerror($user->lang[$this->error_prefix . 'EMPTY_REMOTE_DATA']); - return $file; + return $this->factory->get('filespec')->set_error($this->error_prefix . 'EMPTY_REMOTE_DATA'); } $tmp_path = (!@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'off') ? false : $phpbb_root_path . 'cache'; @@ -466,8 +458,7 @@ class upload if (!($fp = @fopen($filename, 'wb'))) { - $file = new fileerror($user->lang[$this->error_prefix . 'NOT_UPLOADED']); - return $file; + return $this->factory->get('filespec')->set_error($this->error_prefix . 'NOT_UPLOADED'); } $upload_ary['size'] = fwrite($fp, $data); -- cgit v1.2.1 From e4546ad03c0c0130e60d164f3741cc57c33b8980 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 2 Jun 2015 13:23:51 +0200 Subject: [ticket/13904] Improve doc blocks in upload class PHPBB3-13904 --- phpBB/phpbb/files/upload.php | 85 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 291cdb266c..f253fc762d 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -19,21 +19,34 @@ namespace phpbb\files; */ class upload { + /** @var array Allowed file extensions */ var $allowed_extensions = array(); + + /** @var array Disallowed content */ var $disallowed_content = array('body', 'head', 'html', 'img', 'plaintext', 'a href', 'pre', 'script', 'table', 'title'); + + /** @var int Maximum filesize */ var $max_filesize = 0; + + /** @var int Minimum width of images */ var $min_width = 0; + + /** @var int Minimum height of images */ var $min_height = 0; + + /** @var int Maximum width of images */ var $max_width = 0; + + /** @var int Maximum height of images */ var $max_height = 0; + + /** @var string Prefix for language variables of errors */ var $error_prefix = ''; /** @var int Timeout for remote upload */ var $upload_timeout = 6; - /** - * @var \phpbb\filesystem\filesystem_interface - */ + /** @var \phpbb\filesystem\filesystem_interface */ protected $filesystem; /** @var \phpbb\files\factory Files factory */ @@ -44,7 +57,6 @@ class upload * * @param \phpbb\filesystem\filesystem_interface $filesystem * @param \phpbb\files\factory $factory Files factory - * */ public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, factory $factory) { @@ -66,6 +78,10 @@ class upload /** * Set allowed extensions + * + * @param array $allowed_extensions Allowed file extensions + * + * @return \phpbb\files\upload This instance of upload */ function set_allowed_extensions($allowed_extensions) { @@ -79,6 +95,13 @@ class upload /** * Set allowed dimensions + * + * @param int $min_width Minimum image width + * @param int $min_height Minimum image height + * @param int $max_width Maximum image width + * @param int $max_height Maximum image height + * + * @return \phpbb\files\upload This instance of upload */ function set_allowed_dimensions($min_width, $min_height, $max_width, $max_height) { @@ -91,7 +114,11 @@ class upload } /** - * Set maximum allowed filesize + * Set maximum allowed file size + * + * @param int $max_filesize Maximum file size + * + * @return \phpbb\files\upload This instance of upload */ function set_max_filesize($max_filesize) { @@ -105,6 +132,10 @@ class upload /** * Set disallowed strings + * + * @param array $disallowed_content Disallowed content + * + * @return \phpbb\files\upload This instance of upload */ function set_disallowed_content($disallowed_content) { @@ -118,6 +149,10 @@ class upload /** * Set error prefix + * + * @param string $error_prefix Prefix for language variables of errors + * + * @return \phpbb\files\upload This instance of upload */ function set_error_prefix($error_prefix) { @@ -133,7 +168,7 @@ class upload * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) * @param \phpbb\plupload\plupload $plupload The plupload object * - * @return object $file Object "filespec" is returned, all further operations can be done with this object + * @return filespec $file Object "filespec" is returned, all further operations can be done with this object * @access public */ function form_upload($form_name, \phpbb\plupload\plupload $plupload = null) @@ -152,7 +187,7 @@ class upload } } - /** @var \phpbb\files\filespec $file */ + /** @var filespec $file */ $file = $this->factory->get('filespec') ->set_upload_ary($upload) ->set_upload_namespace($this); @@ -214,6 +249,11 @@ class upload /** * Move file from another location to phpBB + * + * @param string $source_file Filename of source file + * @param array|bool $filedata Array with filedata or false + * + * @return filespec Object "filespec" is returned, all further operations can be done with this object */ function local_upload($source_file, $filedata = false) { @@ -236,7 +276,7 @@ class upload $upload['type'] = $filedata['type']; } - /** @var \phpbb\files\filespec $file */ + /** @var filespec $file */ $file = $this->factory->get('filespec') ->set_upload_ary($upload) ->set_upload_namespace($this); @@ -294,7 +334,7 @@ class upload * Uploads file from given url * * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif - * @return object $file Object "filespec" is returned, all further operations can be done with this object + * @return filespec $file Object "filespec" is returned, all further operations can be done with this object * @access public */ function remote_upload($upload_url) @@ -467,7 +507,7 @@ class upload $upload_ary['tmp_name'] = $filename; - /** @var \phpbb\files\filespec $file */ + /** @var filespec $file */ $file = $this->factory->get('filespec') ->set_upload_ary($upload_ary) ->set_upload_namespace($this); @@ -478,6 +518,10 @@ class upload /** * Assign internal error + * + * @param string $errorcode Error code to assign + * + * @return string Error string * @access private */ function assign_internal_error($errorcode) @@ -528,7 +572,9 @@ class upload } /** - * Perform common checks + * Perform common file checks + * + * @param filespec $file Instance of filespec class */ function common_checks(&$file) { @@ -563,6 +609,10 @@ class upload /** * Check for allowed extension + * + * @param filespec $file Instance of filespec class + * + * @return bool True if extension is allowed, false if not */ function valid_extension(&$file) { @@ -571,6 +621,11 @@ class upload /** * Check for allowed dimension + * + * @param filespec $file Instance of filespec class + * + * @return bool True if dimensions are valid or no constraints set, false + * if not */ function valid_dimensions(&$file) { @@ -592,6 +647,10 @@ class upload /** * Check if form upload is valid + * + * @param string $form_name Name of form + * + * @return bool True if form upload is valid, false if not */ function is_valid($form_name) { @@ -604,6 +663,10 @@ class upload /** * Check for bad content (IE mime-sniffing) + * + * @param filespec $file Instance of filespec class + * + * @return bool True if content is valid, false if not */ function valid_content(&$file) { -- cgit v1.2.1 From 0121e60cd73963043047e1b29b8d94ea9aa684e3 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 2 Jun 2015 13:33:10 +0200 Subject: [ticket/13904] Use language class instead of user global in upload PHPBB3-13904 --- phpBB/phpbb/files/upload.php | 55 +++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 26 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index f253fc762d..e37f90e820 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -13,6 +13,8 @@ namespace phpbb\files; +use \phpbb\language\language; + /** * File upload class * Init class (all parameters optional and able to be set/overwritten separately) - scope is global and valid for all uploads @@ -52,16 +54,21 @@ class upload /** @var \phpbb\files\factory Files factory */ protected $factory; + /** @var \phpbb\language\language Language class */ + protected $language; + /** * Init file upload class. * * @param \phpbb\filesystem\filesystem_interface $filesystem * @param \phpbb\files\factory $factory Files factory + * @param \phpbb\language\language $language Language class */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, factory $factory) + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, factory $factory, language $language) { $this->filesystem = $filesystem; $this->factory = $factory; + $this->language = $language; } /** @@ -173,7 +180,7 @@ class upload */ function form_upload($form_name, \phpbb\plupload\plupload $plupload = null) { - global $user, $request; + global $request; $upload = $request->file($form_name); unset($upload['local_mode']); @@ -213,7 +220,7 @@ class upload // Check if empty file got uploaded (not catched by is_uploaded_file) if (isset($upload['size']) && $upload['size'] == 0) { - $file->error[] = $user->lang[$this->error_prefix . 'EMPTY_FILEUPLOAD']; + $file->error[] = $this->language->lang($this->error_prefix . 'EMPTY_FILEUPLOAD'); return $file; } @@ -231,14 +238,14 @@ class upload $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); } - $file->error[] = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); + $file->error[] = (empty($max_filesize)) ? $this->language->lang($this->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); return $file; } // Not correctly uploaded if (!$file->is_uploaded()) { - $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED']; + $file->error[] = $this->language->lang($this->error_prefix . 'NOT_UPLOADED'); return $file; } @@ -257,7 +264,7 @@ class upload */ function local_upload($source_file, $filedata = false) { - global $user, $request; + global $request; $upload = array(); @@ -312,14 +319,14 @@ class upload $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); } - $file->error[] = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); + $file->error[] = (empty($max_filesize)) ?$this->language->lang($this->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); return $file; } // Not correctly uploaded if (!$file->is_uploaded()) { - $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED']; + $file->error[] = $this->language->lang($this->error_prefix . 'NOT_UPLOADED'); return $file; } @@ -339,19 +346,19 @@ class upload */ function remote_upload($upload_url) { - global $user, $phpbb_root_path; + global $phpbb_root_path; $upload_ary = array(); $upload_ary['local_mode'] = true; if (!preg_match('#^(https?://).*?\.(' . implode('|', $this->allowed_extensions) . ')$#i', $upload_url, $match)) { - return $this->factory->get('filespec')->set_error($user->lang[$this->error_prefix . 'URL_INVALID']); + return $this->factory->get('filespec')->set_error($this->language->lang($this->error_prefix . 'URL_INVALID')); } if (empty($match[2])) { - return $this->factory->get('filespec')->set_error($user->lang[$this->error_prefix . 'URL_INVALID']);e; + return $this->factory->get('filespec')->set_error($this->language->lang($this->error_prefix . 'URL_INVALID')); } $url = parse_url($upload_url); @@ -400,7 +407,7 @@ class upload if (!($fsock = @fsockopen($host, $port, $errno, $errstr))) { - return $this->factory->get('filespec')->set_error($user->lang[$this->error_prefix . 'NOT_UPLOADED']); + return $this->factory->get('filespec')->set_error($this->language->lang($this->error_prefix . 'NOT_UPLOADED')); } // Make sure $path not beginning with / @@ -441,7 +448,7 @@ class upload { $max_filesize = get_formatted_filesize($remote_max_filesize, false); - return $this->factory->get('filespec')->set_error(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); + return $this->factory->get('filespec')->set_error($this->language->lang($this->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); } $data .= $block; @@ -468,7 +475,7 @@ class upload { $max_filesize = get_formatted_filesize($remote_max_filesize, false); - return $this->factory->get('filespec')->set_error(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); + return $this->factory->get('filespec')->set_error($this->language->lang($this->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); } } else if (stripos($line, '404 not found') !== false) @@ -526,8 +533,6 @@ class upload */ function assign_internal_error($errorcode) { - global $user; - switch ($errorcode) { case 1: @@ -542,21 +547,21 @@ class upload $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); } - $error = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); + $error = (empty($max_filesize)) ? $this->language->lang($this->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); break; case 2: $max_filesize = get_formatted_filesize($this->max_filesize, false); - $error = sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']); + $error = $this->language->lang($this->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit']); break; case 3: - $error = $user->lang[$this->error_prefix . 'PARTIAL_UPLOAD']; + $error = $this->language->lang($this->error_prefix . 'PARTIAL_UPLOAD'); break; case 4: - $error = $user->lang[$this->error_prefix . 'NOT_UPLOADED']; + $error = $this->language->lang($this->error_prefix . 'NOT_UPLOADED'); break; case 6: @@ -578,32 +583,30 @@ class upload */ function common_checks(&$file) { - global $user; - // Filesize is too big or it's 0 if it was larger than the maxsize in the upload form if ($this->max_filesize && ($file->get('filesize') > $this->max_filesize || $file->get('filesize') == 0)) { $max_filesize = get_formatted_filesize($this->max_filesize, false); - $file->error[] = sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']); + $file->error[] = $this->language->lang($this->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit']); } // check Filename if (preg_match("#[\\/:*?\"<>|]#i", $file->get('realname'))) { - $file->error[] = sprintf($user->lang[$this->error_prefix . 'INVALID_FILENAME'], $file->get('realname')); + $file->error[] = $this->language->lang($this->error_prefix . 'INVALID_FILENAME', $file->get('realname')); } // Invalid Extension if (!$this->valid_extension($file)) { - $file->error[] = sprintf($user->lang[$this->error_prefix . 'DISALLOWED_EXTENSION'], $file->get('extension')); + $file->error[] = $this->language->lang($this->error_prefix . 'DISALLOWED_EXTENSION', $file->get('extension')); } // MIME Sniffing if (!$this->valid_content($file)) { - $file->error[] = sprintf($user->lang[$this->error_prefix . 'DISALLOWED_CONTENT']); + $file->error[] = $this->language->lang($this->error_prefix . 'DISALLOWED_CONTENT'); } } -- cgit v1.2.1 From 6541e4cb17d3014151d469b870eac5637ed23071 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 2 Jun 2015 14:52:09 +0200 Subject: [ticket/13904] Improve doc blocks in filespec class PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 94 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 18 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index d14c9a226d..d091e975d5 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -19,25 +19,50 @@ namespace phpbb\files; */ class filespec { + /** @var string File name */ var $filename = ''; + + /** @var string Real name of file */ var $realname = ''; + + /** @var string Upload name of file */ var $uploadname = ''; + + /** @var string Mimetype of file */ var $mimetype = ''; + + /** @var string File extension */ var $extension = ''; + + /** @var int File size */ var $filesize = 0; + + /** @var int Width of file */ var $width = 0; + + /** @var int Height of file */ var $height = 0; + + /** @var array Image info including type and size */ var $image_info = array(); + /** @var string Destination file name */ var $destination_file = ''; + + /** @var string Destination file path */ var $destination_path = ''; + /** @var bool Whether file was moved */ var $file_moved = false; + + /** @var bool Whether file is local */ var $local = false; + /** @var array Error array */ var $error = array(); - var $upload = ''; + /** @var upload Instance of upload class */ + var $upload; /** * @var \phpbb\filesystem\filesystem_interface @@ -57,20 +82,26 @@ class filespec protected $mimetype_guesser; /** - * File Class - * @access private + * File upload class + * + * @param \phpbb\filesystem\filesystem_interface $phpbb_filesystem + * @param \phpbb\mimetype\guesser $mimetype_guesser + * @param \phpbb\plupload\plupload $plupload */ function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { - // @todo call this via files - //$this->set_upload_ary($upload_ary); - //$this->set_upload_namespace($upload_namespace); - $this->plupload = $plupload; $this->mimetype_guesser = $mimetype_guesser; $this->filesystem = $phpbb_filesystem; } + /** + * Set upload ary + * + * @param array $upload_ary Upload ary + * + * @return filespec This instance of the filespec class + */ public function set_upload_ary($upload_ary) { $this->filename = $upload_ary['tmp_name']; @@ -101,6 +132,13 @@ class filespec return $this; } + /** + * Set the upload namespace + * + * @param upload $namespace Instance of upload class + * + * @return filespec This instance of the filespec class + */ public function set_upload_namespace($namespace) { $this->upload = $namespace; @@ -109,7 +147,7 @@ class filespec } /** - * Check if class members were not properly initalised yet + * Check if class members were not properly initialised yet * * @return bool True if there was an init error, false if not */ @@ -135,10 +173,13 @@ class filespec /** * Cleans destination filename * - * @param real|unique|unique_ext $mode real creates a realname, filtering some characters, lowering every character. Unique creates an unique filename + * @param string $mode Either real, unique, or unique_ext. Real creates a + * realname, filtering some characters, lowering every + * character. Unique creates a unique filename. * @param string $prefix Prefix applied to filename * @param string $user_id The user_id is only needed for when cleaning a user's avatar - * @access public + * + *@access public */ function clean_filename($mode = 'unique', $prefix = '', $user_id = '') { @@ -184,6 +225,10 @@ class filespec /** * Get property from file object + * + * @param string $property Name of property + * + * @return mixed Content of property */ function get($property) { @@ -196,9 +241,9 @@ class filespec } /** - * Check if file is an image (mimetype) + * Check if file is an image (mime type) * - * @return true if it is an image, false if not + * @return bool true if it is an image, false if not */ function is_image() { @@ -208,7 +253,7 @@ class filespec /** * Check if the file got correctly uploaded * - * @return true if it is a valid upload, false if not + * @return bool true if it is a valid upload, false if not */ function is_uploaded() { @@ -241,7 +286,8 @@ class filespec /** * Get file extension * - * @param string Filename that needs to be checked + * @param string $filename Filename that needs to be checked + * * @return string Extension of the supplied filename */ static public function get_extension($filename) @@ -258,10 +304,10 @@ class filespec } /** - * Get mimetype + * Get mime type * * @param string $filename Filename that needs to be checked - * @return string Mimetype of supplied filename + * @return string Mime type of supplied filename */ function get_mimetype($filename) { @@ -279,7 +325,11 @@ class filespec } /** - * Get filesize + * Get file size + * + * @param string $filename File name of file to check + * + * @return int File size */ function get_filesize($filename) { @@ -289,6 +339,10 @@ class filespec /** * Check the first 256 bytes for forbidden content + * + * @param array $disallowed_content Array containg disallowed content + * + * @return bool False if disallowed content found, true if not */ function check_content($disallowed_content) { @@ -321,8 +375,10 @@ class filespec * @param string $destination Destination path, for example $config['avatar_path'] * @param bool $overwrite If set to true, an already existing file will be overwritten * @param bool $skip_image_check If set to true, the check for the file to be a valid image is skipped - * @param string $chmod Permission mask for chmodding the file after a successful move. The mode entered here reflects the mode defined by {@link phpbb_chmod()} + * @param string|bool $chmod Permission mask for chmodding the file after a successful move. + * The mode entered here reflects the mode defined by {@link phpbb_chmod()} * + * @return bool True if file was moved, false if not * @access public */ function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false) @@ -475,6 +531,8 @@ class filespec /** * Performing additional checks + * + * @return bool False if issue was found, true if not */ function additional_checks() { -- cgit v1.2.1 From 697ac5f4aa151b06ed65f8352652443bf297682a Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 2 Jun 2015 15:06:24 +0200 Subject: [ticket/13904] Use language class instead of global user in filespec PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 45 +++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 20 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index d091e975d5..5e685615d7 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -13,6 +13,8 @@ namespace phpbb\files; +use \phpbb\language\language; + /** * Responsible for holding all file relevant information, as well as doing file-specific operations. * The {@link fileupload fileupload class} can be used to upload several files, each of them being this object to operate further on. @@ -81,18 +83,23 @@ class filespec */ protected $mimetype_guesser; + /** @var \phpbb\language\language Language class */ + protected $language; + /** * File upload class * * @param \phpbb\filesystem\filesystem_interface $phpbb_filesystem + * @param \phpbb\language\language $language * @param \phpbb\mimetype\guesser $mimetype_guesser * @param \phpbb\plupload\plupload $plupload */ - function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { $this->plupload = $plupload; $this->mimetype_guesser = $mimetype_guesser; $this->filesystem = $phpbb_filesystem; + $this->language = $language; } /** @@ -383,7 +390,7 @@ class filespec */ function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false) { - global $user, $phpbb_root_path; + global $phpbb_root_path; if (sizeof($this->error)) { @@ -410,7 +417,7 @@ class filespec if (file_exists($this->destination_file) && !$overwrite) { @unlink($this->filename); - $this->error[] = $user->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file); + $this->error[] = $this->language->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file); $this->file_moved = false; return false; } @@ -429,7 +436,7 @@ class filespec { if (!@move_uploaded_file($this->filename, $this->destination_file)) { - $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); + $this->error[] = $this->language->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file); } } @@ -441,7 +448,7 @@ class filespec { if (!@copy($this->filename, $this->destination_file)) { - $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); + $this->error[] = $this->language->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file); } } @@ -451,7 +458,7 @@ class filespec if (!@copy($this->filename, $this->destination_file)) { - $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); + $this->error[] = $this->language->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file); } break; @@ -502,23 +509,23 @@ class filespec { if (!isset($types[$this->image_info['type']])) { - $this->error[] = $user->lang('IMAGE_FILETYPE_INVALID', $this->image_info['type'], $this->mimetype); + $this->error[] = $this->language->lang('IMAGE_FILETYPE_INVALID', $this->image_info['type'], $this->mimetype); } else { - $this->error[] = $user->lang('IMAGE_FILETYPE_MISMATCH', $types[$this->image_info['type']][0], $this->extension); + $this->error[] = $this->language->lang('IMAGE_FILETYPE_MISMATCH', $types[$this->image_info['type']][0], $this->extension); } } // Make sure the dimensions match a valid image if (empty($this->width) || empty($this->height)) { - $this->error[] = $user->lang['ATTACHED_IMAGE_NOT_IMAGE']; + $this->error[] = $this->language->lang('ATTACHED_IMAGE_NOT_IMAGE'); } } else { - $this->error[] = $user->lang['UNABLE_GET_IMAGE_SIZE']; + $this->error[] = $this->language->lang('UNABLE_GET_IMAGE_SIZE'); } } @@ -536,8 +543,6 @@ class filespec */ function additional_checks() { - global $user; - if (!$this->file_moved) { return false; @@ -548,20 +553,20 @@ class filespec { $max_filesize = get_formatted_filesize($this->upload->max_filesize, false); - $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']); + $this->error[] = $this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit']); return false; } if (!$this->upload->valid_dimensions($this)) { - $this->error[] = $user->lang($this->upload->error_prefix . 'WRONG_SIZE', - $user->lang('PIXELS', (int) $this->upload->min_width), - $user->lang('PIXELS', (int) $this->upload->min_height), - $user->lang('PIXELS', (int) $this->upload->max_width), - $user->lang('PIXELS', (int) $this->upload->max_height), - $user->lang('PIXELS', (int) $this->width), - $user->lang('PIXELS', (int) $this->height)); + $this->error[] = $this->language->lang($this->upload->error_prefix . 'WRONG_SIZE', + $this->language->lang('PIXELS', (int) $this->upload->min_width), + $this->language->lang('PIXELS', (int) $this->upload->min_height), + $this->language->lang('PIXELS', (int) $this->upload->max_width), + $this->language->lang('PIXELS', (int) $this->upload->max_height), + $this->language->lang('PIXELS', (int) $this->width), + $this->language->lang('PIXELS', (int) $this->height)); return false; } -- cgit v1.2.1 From 47f8f2cc88bdcd40087c8e391be1d33d36a2d308 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 2 Jun 2015 15:24:38 +0200 Subject: [ticket/13904] Pass request service to upload instead of using global PHPBB3-13904 --- phpBB/phpbb/files/upload.php | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index e37f90e820..e62c29883a 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -13,7 +13,10 @@ namespace phpbb\files; +use \phpbb\filesystem\filesystem_interface; use \phpbb\language\language; +use \phpbb\plupload\plupload; +use \phpbb\request\request_interface; /** * File upload class @@ -57,18 +60,23 @@ class upload /** @var \phpbb\language\language Language class */ protected $language; + /** @var \phpbb\request\request_interface Request class */ + protected $request; + /** * Init file upload class. * * @param \phpbb\filesystem\filesystem_interface $filesystem * @param \phpbb\files\factory $factory Files factory * @param \phpbb\language\language $language Language class + * @param \phpbb\request\request_interface $request Request class */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, factory $factory, language $language) + public function __construct(filesystem_interface $filesystem, factory $factory, language $language, request_interface $request) { $this->filesystem = $filesystem; $this->factory = $factory; $this->language = $language; + $this->request = $request; } /** @@ -178,11 +186,9 @@ class upload * @return filespec $file Object "filespec" is returned, all further operations can be done with this object * @access public */ - function form_upload($form_name, \phpbb\plupload\plupload $plupload = null) + function form_upload($form_name, plupload $plupload = null) { - global $request; - - $upload = $request->file($form_name); + $upload = $this->request->file($form_name); unset($upload['local_mode']); if ($plupload) @@ -264,8 +270,6 @@ class upload */ function local_upload($source_file, $filedata = false) { - global $request; - $upload = array(); $upload['local_mode'] = true; @@ -331,7 +335,7 @@ class upload } $this->common_checks($file); - $request->overwrite('local', $upload, \phpbb\request\request_interface::FILES); + $this->request->overwrite('local', $upload, request_interface::FILES); return $file; } @@ -657,8 +661,7 @@ class upload */ function is_valid($form_name) { - global $request; - $upload = $request->file($form_name); + $upload = $this->request->file($form_name); return (!empty($upload) && $upload['name'] !== 'none'); } -- cgit v1.2.1 From 52652ca1824e91ecfe7549167aebd92c314af678 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 2 Jun 2015 15:29:32 +0200 Subject: [ticket/13904] Remove phpbb_root_path global from upload class PHPBB3-13904 --- phpBB/phpbb/files/upload.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index e62c29883a..38aad5a3bd 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -63,6 +63,9 @@ class upload /** @var \phpbb\request\request_interface Request class */ protected $request; + /** @var string phpBB root path */ + protected $phpbb_root_path; + /** * Init file upload class. * @@ -70,13 +73,15 @@ class upload * @param \phpbb\files\factory $factory Files factory * @param \phpbb\language\language $language Language class * @param \phpbb\request\request_interface $request Request class + * @param string $phpbb_root_path phpBB root path */ - public function __construct(filesystem_interface $filesystem, factory $factory, language $language, request_interface $request) + public function __construct(filesystem_interface $filesystem, factory $factory, language $language, request_interface $request, $phpbb_root_path) { $this->filesystem = $filesystem; $this->factory = $factory; $this->language = $language; $this->request = $request; + $this->phpbb_root_path = $phpbb_root_path; } /** @@ -350,8 +355,6 @@ class upload */ function remote_upload($upload_url) { - global $phpbb_root_path; - $upload_ary = array(); $upload_ary['local_mode'] = true; @@ -504,7 +507,7 @@ class upload return $this->factory->get('filespec')->set_error($this->error_prefix . 'EMPTY_REMOTE_DATA'); } - $tmp_path = (!@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'off') ? false : $phpbb_root_path . 'cache'; + $tmp_path = (!@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'off') ? false : $this->phpbb_root_path . 'cache'; $filename = tempnam($tmp_path, unique_id() . '-'); if (!($fp = @fopen($filename, 'wb'))) -- cgit v1.2.1 From b871dbcf1f2d0483cbe19cddf94a5bdc9659ab00 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 2 Jun 2015 15:46:41 +0200 Subject: [ticket/13904] Remove phpbb_root_path global from filespec class PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 5e685615d7..736610f6c2 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -86,20 +86,25 @@ class filespec /** @var \phpbb\language\language Language class */ protected $language; + /** @var string phpBB root path */ + protected $phpbb_root_path; + /** * File upload class * - * @param \phpbb\filesystem\filesystem_interface $phpbb_filesystem - * @param \phpbb\language\language $language - * @param \phpbb\mimetype\guesser $mimetype_guesser - * @param \phpbb\plupload\plupload $plupload + * @param \phpbb\filesystem\filesystem_interface $phpbb_filesystem Filesystem + * @param \phpbb\language\language $language Language + * @param string $phpbb_root_path phpBB root path + * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser + * @param \phpbb\plupload\plupload $plupload Plupload */ - function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { $this->plupload = $plupload; $this->mimetype_guesser = $mimetype_guesser; $this->filesystem = $phpbb_filesystem; $this->language = $language; + $this->phpbb_root_path = $phpbb_root_path; } /** @@ -390,8 +395,6 @@ class filespec */ function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false) { - global $phpbb_root_path; - if (sizeof($this->error)) { return false; @@ -400,7 +403,7 @@ class filespec $chmod = ($chmod === false) ? CHMOD_READ | CHMOD_WRITE : $chmod; // We need to trust the admin in specifying valid upload directories and an attacker not being able to overwrite it... - $this->destination_path = $phpbb_root_path . $destination; + $this->destination_path = $this->phpbb_root_path . $destination; // Check if the destination path exist... if (!file_exists($this->destination_path)) -- cgit v1.2.1 From 11b2c938c6c3a6a14465f04ed356fbd013276143 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 14 Jul 2015 16:15:39 +0200 Subject: [ticket/13904] Move form_upload to its own class and define type classes PHPBB3-13904 --- phpBB/phpbb/files/factory.php | 2 +- phpBB/phpbb/files/types/form.php | 151 +++++++++++++++++++++++++++++ phpBB/phpbb/files/types/type_interface.php | 38 ++++++++ phpBB/phpbb/files/upload.php | 90 +++-------------- 4 files changed, 202 insertions(+), 79 deletions(-) create mode 100644 phpBB/phpbb/files/types/form.php create mode 100644 phpBB/phpbb/files/types/type_interface.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/factory.php b/phpBB/phpbb/files/factory.php index b28a7ab659..508c50c6ce 100644 --- a/phpBB/phpbb/files/factory.php +++ b/phpBB/phpbb/files/factory.php @@ -42,7 +42,7 @@ class factory { $service = false; - $name = (strpos($name, 'files.') === false && strpos($name, '.') === false) ? 'files.' . $name : $name; + $name = (strpos($name, 'files.') === false) ? 'files.' . $name : $name; try { diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php new file mode 100644 index 0000000000..5c5c332906 --- /dev/null +++ b/phpBB/phpbb/files/types/form.php @@ -0,0 +1,151 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files\types; + +use \phpbb\files\factory; +use \phpbb\files\filespec; +use \phpbb\files\upload; +use \phpbb\plupload\plupload; +use \phpbb\request\request_interface; + +class form implements type_interface +{ + /** @var factory Files factory */ + protected $factory; + + /** @var plupload */ + protected $plupload; + + /** @var request_interface */ + protected $request; + + /** @var upload */ + protected $upload; + + /** + * Construct a form upload type + * + * @param factory $factory + * @param request_interface $request + */ + public function __construct(factory $factory, plupload $plupload, request_interface $request) + { + $this->factory = $factory; + $this->plupload = $plupload; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public function upload() + { + $args = func_get_args(); + return $this->form_upload($args[0], $args[1]); + } + + /** + * {@inheritdoc} + */ + public function set_upload(upload $upload) + { + $this->upload = $upload; + + return $this; + } + + /** + * Form upload method + * Upload file from users harddisk + * + * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) + * @param plupload $plupload The plupload object + * + * @return filespec $file Object "filespec" is returned, all further operations can be done with this object + * @access public + */ + protected function form_upload($form_name, plupload $plupload = null) + { + $upload = $this->request->file($form_name); + unset($upload['local_mode']); + + if ($plupload) + { + $result = $plupload->handle_upload($form_name); + if (is_array($result)) + { + $upload = array_merge($upload, $result); + } + } + + /** @var filespec $file */ + $file = $this->factory->get('filespec') + ->set_upload_ary($upload) + ->set_upload_namespace($this->upload); + + if ($file->init_error()) + { + $file->error[] = ''; + return $file; + } + + // Error array filled? + if (isset($upload['error'])) + { + $error = $this->upload->assign_internal_error($upload['error']); + + if ($error !== false) + { + $file->error[] = $error; + return $file; + } + } + + // Check if empty file got uploaded (not catched by is_uploaded_file) + if (isset($upload['size']) && $upload['size'] == 0) + { + $file->error[] = $this->language->lang($this->error_prefix . 'EMPTY_FILEUPLOAD'); + return $file; + } + + // PHP Upload filesize exceeded + if ($file->get('filename') == 'none') + { + $max_filesize = @ini_get('upload_max_filesize'); + $unit = 'MB'; + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $max_filesize = (int) $max_filesize; + + $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); + } + + $file->error[] = (empty($max_filesize)) ? $this->language->lang($this->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); + return $file; + } + + // Not correctly uploaded + if (!$file->is_uploaded()) + { + $file->error[] = $this->language->lang($this->error_prefix . 'NOT_UPLOADED'); + return $file; + } + + $this->upload->common_checks($file); + + return $file; + } +} diff --git a/phpBB/phpbb/files/types/type_interface.php b/phpBB/phpbb/files/types/type_interface.php new file mode 100644 index 0000000000..adfbb75293 --- /dev/null +++ b/phpBB/phpbb/files/types/type_interface.php @@ -0,0 +1,38 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files\types; + +use \phpbb\files\upload; + +interface type_interface +{ + /** + * Handle upload for upload types. Arguments passed to this method will be + * handled by the upload type classes themselves. + * + * @return \phpbb\files\filespec|bool Filespec instance if upload is + * successful or false if not + */ + public function upload(); + + /** + * Set upload instance + * Needs to be executed before every upload. + * + * @param upload $upload Upload instance + * + * @return type_interface Returns itself + */ + public function set_upload(upload $upload); +} diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 38aad5a3bd..09f2b9408d 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -182,87 +182,21 @@ class upload } /** - * Form upload method - * Upload file from users harddisk + * Handle upload based on type * - * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) - * @param \phpbb\plupload\plupload $plupload The plupload object + * @param string $type Upload type * - * @return filespec $file Object "filespec" is returned, all further operations can be done with this object - * @access public + * @return \phpbb\files\filespec|bool A filespec instance if upload was + * successful, false if there were issues or the type is not supported */ - function form_upload($form_name, plupload $plupload = null) + public function handle_upload($type) { - $upload = $this->request->file($form_name); - unset($upload['local_mode']); - - if ($plupload) - { - $result = $plupload->handle_upload($form_name); - if (is_array($result)) - { - $upload = array_merge($upload, $result); - } - } - - /** @var filespec $file */ - $file = $this->factory->get('filespec') - ->set_upload_ary($upload) - ->set_upload_namespace($this); - - if ($file->init_error()) - { - $file->error[] = ''; - return $file; - } - - // Error array filled? - if (isset($upload['error'])) - { - $error = $this->assign_internal_error($upload['error']); - - if ($error !== false) - { - $file->error[] = $error; - return $file; - } - } - - // Check if empty file got uploaded (not catched by is_uploaded_file) - if (isset($upload['size']) && $upload['size'] == 0) - { - $file->error[] = $this->language->lang($this->error_prefix . 'EMPTY_FILEUPLOAD'); - return $file; - } - - // PHP Upload filesize exceeded - if ($file->get('filename') == 'none') - { - $max_filesize = @ini_get('upload_max_filesize'); - $unit = 'MB'; - - if (!empty($max_filesize)) - { - $unit = strtolower(substr($max_filesize, -1, 1)); - $max_filesize = (int) $max_filesize; + $args = func_get_args(); + array_shift($args); + $type_class = $this->factory->get('types.' . $type) + ->set_upload($this); - $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); - } - - $file->error[] = (empty($max_filesize)) ? $this->language->lang($this->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); - return $file; - } - - // Not correctly uploaded - if (!$file->is_uploaded()) - { - $file->error[] = $this->language->lang($this->error_prefix . 'NOT_UPLOADED'); - return $file; - } - - $this->common_checks($file); - - return $file; + return (is_object($type_class)) ? call_user_func_array(array($type_class, 'upload'), $args) : false; } /** @@ -536,9 +470,9 @@ class upload * @param string $errorcode Error code to assign * * @return string Error string - * @access private + * @access public */ - function assign_internal_error($errorcode) + public function assign_internal_error($errorcode) { switch ($errorcode) { -- cgit v1.2.1 From f9b69e73d4b754c7c5bab52d16b2df98812e5570 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 15 Jul 2015 13:35:38 +0200 Subject: [ticket/13904] Fix minor coding issues and don't use form_upload anymore PHPBB3-13904 --- phpBB/phpbb/avatar/driver/upload.php | 2 +- phpBB/phpbb/files/types/form.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index c1ce18cb12..ab5325f88a 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -116,7 +116,7 @@ class upload extends \phpbb\avatar\driver\driver if (!empty($upload_file['name'])) { - $file = $upload->form_upload('avatar_upload_file'); + $file = $upload->handle_upload('form', 'avatar_upload_file'); } else if (!empty($this->config['allow_avatar_remote_upload']) && !empty($url)) { diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php index 5c5c332906..d82df46fac 100644 --- a/phpBB/phpbb/files/types/form.php +++ b/phpBB/phpbb/files/types/form.php @@ -52,7 +52,7 @@ class form implements type_interface public function upload() { $args = func_get_args(); - return $this->form_upload($args[0], $args[1]); + return $this->form_upload($args[0], (isset($args[1])) ? $args[1] : null); } /** -- cgit v1.2.1 From cf9b6ed4742f95b75125963935f4f2d9e9cfa62c Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 15 Jul 2015 13:57:19 +0200 Subject: [ticket/13904] Use the class member plupload instead of argument PHPBB3-13904 --- phpBB/phpbb/files/types/form.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php index d82df46fac..130a64445b 100644 --- a/phpBB/phpbb/files/types/form.php +++ b/phpBB/phpbb/files/types/form.php @@ -52,7 +52,7 @@ class form implements type_interface public function upload() { $args = func_get_args(); - return $this->form_upload($args[0], (isset($args[1])) ? $args[1] : null); + return $this->form_upload($args[0]); } /** @@ -70,19 +70,18 @@ class form implements type_interface * Upload file from users harddisk * * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) - * @param plupload $plupload The plupload object * * @return filespec $file Object "filespec" is returned, all further operations can be done with this object * @access public */ - protected function form_upload($form_name, plupload $plupload = null) + protected function form_upload($form_name) { $upload = $this->request->file($form_name); unset($upload['local_mode']); - if ($plupload) + if ($this->plupload) { - $result = $plupload->handle_upload($form_name); + $result = $this->plupload->handle_upload($form_name); if (is_array($result)) { $upload = array_merge($upload, $result); -- cgit v1.2.1 From adcc901af181b6727dd7af89a3926c9923a58471 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 15 Jul 2015 16:08:20 +0200 Subject: [ticket/13904] Fix minor issues and move local_upload to its own class PHPBB3-13904 --- phpBB/phpbb/files/types/form.php | 39 +++++------ phpBB/phpbb/files/types/local.php | 137 ++++++++++++++++++++++++++++++++++++++ phpBB/phpbb/files/upload.php | 80 ---------------------- 3 files changed, 152 insertions(+), 104 deletions(-) create mode 100644 phpBB/phpbb/files/types/local.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php index 130a64445b..98d1c51d5f 100644 --- a/phpBB/phpbb/files/types/form.php +++ b/phpBB/phpbb/files/types/form.php @@ -16,14 +16,18 @@ namespace phpbb\files\types; use \phpbb\files\factory; use \phpbb\files\filespec; use \phpbb\files\upload; +use \phpbb\language\language; use \phpbb\plupload\plupload; use \phpbb\request\request_interface; -class form implements type_interface +class form extends base { /** @var factory Files factory */ protected $factory; + /** @var language */ + protected $language; + /** @var plupload */ protected $plupload; @@ -39,9 +43,10 @@ class form implements type_interface * @param factory $factory * @param request_interface $request */ - public function __construct(factory $factory, plupload $plupload, request_interface $request) + public function __construct(factory $factory, language $language, plupload $plupload, request_interface $request) { $this->factory = $factory; + $this->language = $language; $this->plupload = $plupload; $this->request = $request; } @@ -79,13 +84,10 @@ class form implements type_interface $upload = $this->request->file($form_name); unset($upload['local_mode']); - if ($this->plupload) + $result = $this->plupload->handle_upload($form_name); + if (is_array($result)) { - $result = $this->plupload->handle_upload($form_name); - if (is_array($result)) - { - $upload = array_merge($upload, $result); - } + $upload = array_merge($upload, $result); } /** @var filespec $file */ @@ -114,32 +116,21 @@ class form implements type_interface // Check if empty file got uploaded (not catched by is_uploaded_file) if (isset($upload['size']) && $upload['size'] == 0) { - $file->error[] = $this->language->lang($this->error_prefix . 'EMPTY_FILEUPLOAD'); + $file->error[] = $this->language->lang($this->upload->error_prefix . 'EMPTY_FILEUPLOAD'); return $file; } - // PHP Upload filesize exceeded - if ($file->get('filename') == 'none') + // PHP Upload filesize check + $file = $this->check_upload_size($file); + if (sizeof($file->error)) { - $max_filesize = @ini_get('upload_max_filesize'); - $unit = 'MB'; - - if (!empty($max_filesize)) - { - $unit = strtolower(substr($max_filesize, -1, 1)); - $max_filesize = (int) $max_filesize; - - $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); - } - - $file->error[] = (empty($max_filesize)) ? $this->language->lang($this->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); return $file; } // Not correctly uploaded if (!$file->is_uploaded()) { - $file->error[] = $this->language->lang($this->error_prefix . 'NOT_UPLOADED'); + $file->error[] = $this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED'); return $file; } diff --git a/phpBB/phpbb/files/types/local.php b/phpBB/phpbb/files/types/local.php new file mode 100644 index 0000000000..38876d8ab4 --- /dev/null +++ b/phpBB/phpbb/files/types/local.php @@ -0,0 +1,137 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files\types; + +use \phpbb\files\factory; +use \phpbb\files\filespec; +use \phpbb\files\upload; +use \phpbb\language\language; +use \phpbb\request\request_interface; + +class local extends base +{ + /** @var factory Files factory */ + protected $factory; + + /** @var language */ + protected $language; + + /** @var request_interface */ + protected $request; + + /** @var upload */ + protected $upload; + + /** + * Construct a form upload type + * + * @param factory $factory + * @param request_interface $request + */ + public function __construct(factory $factory, language $language, request_interface $request) + { + $this->factory = $factory; + $this->language = $language; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public function upload() + { + $args = func_get_args(); + return $this->local_upload($args[0], isset($args[1]) ? $args[1] : false); + } + + /** + * Move file from another location to phpBB + * + * @param string $source_file Filename of source file + * @param array|bool $filedata Array with filedata or false + * + * @return filespec Object "filespec" is returned, all further operations can be done with this object + */ + protected function local_upload($source_file, $filedata = false) + { + $upload = array(); + + $upload['local_mode'] = true; + $upload['tmp_name'] = $source_file; + + if ($filedata === false) + { + $upload['name'] = utf8_basename($source_file); + $upload['size'] = 0; + } + else + { + $upload['name'] = $filedata['realname']; + $upload['size'] = $filedata['size']; + $upload['type'] = $filedata['type']; + } + + /** @var filespec $file */ + $file = $this->factory->get('filespec') + ->set_upload_ary($upload) + ->set_upload_namespace($this->upload); + + if ($file->init_error()) + { + $file->error[] = ''; + return $file; + } + + if (isset($upload['error'])) + { + $error = $this->upload->assign_internal_error($upload['error']); + + if ($error !== false) + { + $file->error[] = $error; + return $file; + } + } + + // PHP Upload filesize exceeded + if ($file->get('filename') == 'none') + { + $max_filesize = @ini_get('upload_max_filesize'); + $unit = 'MB'; + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $max_filesize = (int) $max_filesize; + + $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); + } + + $file->error[] = (empty($max_filesize)) ?$this->language->lang($this->upload->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->upload->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); + return $file; + } + + // Not correctly uploaded + if (!$file->is_uploaded()) + { + $file->error[] = $this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED'); + return $file; + } + + $this->upload->common_checks($file); + $this->request->overwrite('local', $upload, request_interface::FILES); + + return $file; + } +} diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 09f2b9408d..471c9c378f 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -199,86 +199,6 @@ class upload return (is_object($type_class)) ? call_user_func_array(array($type_class, 'upload'), $args) : false; } - /** - * Move file from another location to phpBB - * - * @param string $source_file Filename of source file - * @param array|bool $filedata Array with filedata or false - * - * @return filespec Object "filespec" is returned, all further operations can be done with this object - */ - function local_upload($source_file, $filedata = false) - { - $upload = array(); - - $upload['local_mode'] = true; - $upload['tmp_name'] = $source_file; - - if ($filedata === false) - { - $upload['name'] = utf8_basename($source_file); - $upload['size'] = 0; - } - else - { - $upload['name'] = $filedata['realname']; - $upload['size'] = $filedata['size']; - $upload['type'] = $filedata['type']; - } - - /** @var filespec $file */ - $file = $this->factory->get('filespec') - ->set_upload_ary($upload) - ->set_upload_namespace($this); - - if ($file->init_error()) - { - $file->error[] = ''; - return $file; - } - - if (isset($upload['error'])) - { - $error = $this->assign_internal_error($upload['error']); - - if ($error !== false) - { - $file->error[] = $error; - return $file; - } - } - - // PHP Upload filesize exceeded - if ($file->get('filename') == 'none') - { - $max_filesize = @ini_get('upload_max_filesize'); - $unit = 'MB'; - - if (!empty($max_filesize)) - { - $unit = strtolower(substr($max_filesize, -1, 1)); - $max_filesize = (int) $max_filesize; - - $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); - } - - $file->error[] = (empty($max_filesize)) ?$this->language->lang($this->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); - return $file; - } - - // Not correctly uploaded - if (!$file->is_uploaded()) - { - $file->error[] = $this->language->lang($this->error_prefix . 'NOT_UPLOADED'); - return $file; - } - - $this->common_checks($file); - $this->request->overwrite('local', $upload, request_interface::FILES); - - return $file; - } - /** * Remote upload method * Uploads file from given url -- cgit v1.2.1 From 167cc58f27da138e138310dafaeff5b53ccedef0 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 15 Jul 2015 16:08:49 +0200 Subject: [ticket/13904] Add types base class PHPBB3-13904 --- phpBB/phpbb/files/types/base.php | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 phpBB/phpbb/files/types/base.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/base.php b/phpBB/phpbb/files/types/base.php new file mode 100644 index 0000000000..686ce6f695 --- /dev/null +++ b/phpBB/phpbb/files/types/base.php @@ -0,0 +1,66 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files\types; + +use \phpbb\files\filespec; +use \phpbb\files\upload; +use \phpbb\language\language; + +abstract class base implements type_interface +{ + /** @var language */ + protected $language; + + /** @var upload */ + protected $upload; + + /** + * Check if upload exceeds maximum file size + * + * @param filespec $file Filespec object + * + * @return filespec Returns same filespec instance + */ + public function check_upload_size($file) + { + // PHP Upload filesize exceeded + if ($file->get('filename') == 'none') + { + $max_filesize = @ini_get('upload_max_filesize'); + $unit = 'MB'; + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $max_filesize = (int) $max_filesize; + + $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); + } + + $file->error[] = (empty($max_filesize)) ? $this->language->lang($this->upload->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->upload->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); + } + + return $file; + } + + /** + * {@inheritdoc} + */ + public function set_upload(upload $upload) + { + $this->upload = $upload; + + return $this; + } +} -- cgit v1.2.1 From 636a29d589e92765b5746a977b3b53c1bb4e818c Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 15 Jul 2015 17:12:24 +0200 Subject: [ticket/13904] Split up local_upload method PHPBB3-13904 --- phpBB/phpbb/files/types/local.php | 47 ++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/local.php b/phpBB/phpbb/files/types/local.php index 38876d8ab4..d439f01866 100644 --- a/phpBB/phpbb/files/types/local.php +++ b/phpBB/phpbb/files/types/local.php @@ -65,22 +65,7 @@ class local extends base */ protected function local_upload($source_file, $filedata = false) { - $upload = array(); - - $upload['local_mode'] = true; - $upload['tmp_name'] = $source_file; - - if ($filedata === false) - { - $upload['name'] = utf8_basename($source_file); - $upload['size'] = 0; - } - else - { - $upload['name'] = $filedata['realname']; - $upload['size'] = $filedata['size']; - $upload['type'] = $filedata['type']; - } + $upload = $this->get_upload_ary($source_file, $filedata); /** @var filespec $file */ $file = $this->factory->get('filespec') @@ -134,4 +119,34 @@ class local extends base return $file; } + + /** + * Retrieve upload array + * + * @param string $source_file Source file name + * @param array $filedata File data array + * + * @return array Upload array + */ + protected function get_upload_ary($source_file, $filedata) + { + $upload = array(); + + $upload['local_mode'] = true; + $upload['tmp_name'] = $source_file; + + if ($filedata === false) + { + $upload['name'] = utf8_basename($source_file); + $upload['size'] = 0; + } + else + { + $upload['name'] = $filedata['realname']; + $upload['size'] = $filedata['size']; + $upload['type'] = $filedata['type']; + } + + return $upload; + } } -- cgit v1.2.1 From 5b21830ba81b5512b7c3f945a899da9103c80558 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 15 Jul 2015 18:00:26 +0200 Subject: [ticket/13904] Improve docblock PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 4 ++-- phpBB/phpbb/files/types/local.php | 3 +-- phpBB/phpbb/files/upload.php | 13 ++++++------- 3 files changed, 9 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 736610f6c2..ed64b7ff5c 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -83,7 +83,7 @@ class filespec */ protected $mimetype_guesser; - /** @var \phpbb\language\language Language class */ + /** @var language Language class */ protected $language; /** @var string phpBB root path */ @@ -93,7 +93,7 @@ class filespec * File upload class * * @param \phpbb\filesystem\filesystem_interface $phpbb_filesystem Filesystem - * @param \phpbb\language\language $language Language + * @param language $language Language * @param string $phpbb_root_path phpBB root path * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser * @param \phpbb\plupload\plupload $plupload Plupload diff --git a/phpBB/phpbb/files/types/local.php b/phpBB/phpbb/files/types/local.php index d439f01866..bb5994841f 100644 --- a/phpBB/phpbb/files/types/local.php +++ b/phpBB/phpbb/files/types/local.php @@ -15,7 +15,6 @@ namespace phpbb\files\types; use \phpbb\files\factory; use \phpbb\files\filespec; -use \phpbb\files\upload; use \phpbb\language\language; use \phpbb\request\request_interface; @@ -30,7 +29,7 @@ class local extends base /** @var request_interface */ protected $request; - /** @var upload */ + /** @var \phpbb\files\upload */ protected $upload; /** diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 471c9c378f..43f06c3503 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -15,7 +15,6 @@ namespace phpbb\files; use \phpbb\filesystem\filesystem_interface; use \phpbb\language\language; -use \phpbb\plupload\plupload; use \phpbb\request\request_interface; /** @@ -51,7 +50,7 @@ class upload /** @var int Timeout for remote upload */ var $upload_timeout = 6; - /** @var \phpbb\filesystem\filesystem_interface */ + /** @var filesystem_interface */ protected $filesystem; /** @var \phpbb\files\factory Files factory */ @@ -60,7 +59,7 @@ class upload /** @var \phpbb\language\language Language class */ protected $language; - /** @var \phpbb\request\request_interface Request class */ + /** @var request_interface Request class */ protected $request; /** @var string phpBB root path */ @@ -69,10 +68,10 @@ class upload /** * Init file upload class. * - * @param \phpbb\filesystem\filesystem_interface $filesystem - * @param \phpbb\files\factory $factory Files factory - * @param \phpbb\language\language $language Language class - * @param \phpbb\request\request_interface $request Request class + * @param filesystem_interface $filesystem + * @param factory $factory Files factory + * @param language $language Language class + * @param request_interface $request Request class * @param string $phpbb_root_path phpBB root path */ public function __construct(filesystem_interface $filesystem, factory $factory, language $language, request_interface $request, $phpbb_root_path) -- cgit v1.2.1 From 57ccfe0c483254e54b7b40bc1906ef946daf4f55 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 15 Jul 2015 18:00:52 +0200 Subject: [ticket/13904] Move remote upload to its own type class PHPBB3-13904 --- phpBB/phpbb/avatar/driver/upload.php | 2 +- phpBB/phpbb/files/types/remote.php | 242 +++++++++++++++++++++++++++++++++++ phpBB/phpbb/files/upload.php | 185 -------------------------- 3 files changed, 243 insertions(+), 186 deletions(-) create mode 100644 phpBB/phpbb/files/types/remote.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index ab5325f88a..2bd23a26a8 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -146,7 +146,7 @@ class upload extends \phpbb\avatar\driver\driver return false; } - $file = $upload->remote_upload($url); + $file = $upload->handle_upload('remote', $url); } else { diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php new file mode 100644 index 0000000000..c70f1557e7 --- /dev/null +++ b/phpBB/phpbb/files/types/remote.php @@ -0,0 +1,242 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files\types; + +use \phpbb\files\factory; +use \phpbb\files\filespec; +use \phpbb\files\upload; +use \phpbb\language\language; +use \phpbb\request\request_interface; + +class remote extends base +{ + /** @var factory Files factory */ + protected $factory; + + /** @var language */ + protected $language; + + /** @var request_interface */ + protected $request; + + /** @var upload */ + protected $upload; + + /** + * Construct a form upload type + * + * @param factory $factory + * @param request_interface $request + */ + public function __construct(factory $factory, language $language, request_interface $request) + { + $this->factory = $factory; + $this->language = $language; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public function upload() + { + $args = func_get_args(); + return $this->remote_upload($args[0]); + } + + /** + * Remote upload method + * Uploads file from given url + * + * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif + * @return filespec $file Object "filespec" is returned, all further operations can be done with this object + * @access public + */ + protected function remote_upload($upload_url) + { + $upload_ary = array(); + $upload_ary['local_mode'] = true; + + if (!preg_match('#^(https?://).*?\.(' . implode('|', $this->upload->allowed_extensions) . ')$#i', $upload_url, $match)) + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'URL_INVALID')); + } + + if (empty($match[2])) + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'URL_INVALID')); + } + + $url = parse_url($upload_url); + + $host = $url['host']; + $path = $url['path']; + $port = (!empty($url['port'])) ? (int) $url['port'] : 80; + + $upload_ary['type'] = 'application/octet-stream'; + + $url['path'] = explode('.', $url['path']); + $ext = array_pop($url['path']); + + $url['path'] = implode('', $url['path']); + $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : ''); + $filename = $url['path']; + $filesize = 0; + + $remote_max_filesize = $this->upload->max_filesize; + if (!$remote_max_filesize) + { + $max_filesize = @ini_get('upload_max_filesize'); + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $remote_max_filesize = (int) $max_filesize; + + switch ($unit) + { + case 'g': + $remote_max_filesize *= 1024; + // no break + case 'm': + $remote_max_filesize *= 1024; + // no break + case 'k': + $remote_max_filesize *= 1024; + // no break + } + } + } + + $errno = 0; + $errstr = ''; + + if (!($fsock = @fsockopen($host, $port, $errno, $errstr))) + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + } + + // Make sure $path not beginning with / + if (strpos($path, '/') === 0) + { + $path = substr($path, 1); + } + + fputs($fsock, 'GET /' . $path . " HTTP/1.1\r\n"); + fputs($fsock, "HOST: " . $host . "\r\n"); + fputs($fsock, "Connection: close\r\n\r\n"); + + // Set a proper timeout for the socket + socket_set_timeout($fsock, $this->upload->upload_timeout); + + $get_info = false; + $data = ''; + $length = false; + $timer_stop = time() + $this->upload->upload_timeout; + + while ((!$length || $filesize < $length) && !@feof($fsock)) + { + if ($get_info) + { + if ($length) + { + // Don't attempt to read past end of file if server indicated length + $block = @fread($fsock, min($length - $filesize, 1024)); + } + else + { + $block = @fread($fsock, 1024); + } + + $filesize += strlen($block); + + if ($remote_max_filesize && $filesize > $remote_max_filesize) + { + $max_filesize = get_formatted_filesize($remote_max_filesize, false); + + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); + } + + $data .= $block; + } + else + { + $line = @fgets($fsock, 1024); + + if ($line == "\r\n") + { + $get_info = true; + } + else + { + if (stripos($line, 'content-type: ') !== false) + { + $upload_ary['type'] = rtrim(str_replace('content-type: ', '', strtolower($line))); + } + else if ($this->upload->max_filesize && stripos($line, 'content-length: ') !== false) + { + $length = (int) str_replace('content-length: ', '', strtolower($line)); + + if ($remote_max_filesize && $length && $length > $remote_max_filesize) + { + $max_filesize = get_formatted_filesize($remote_max_filesize, false); + + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); + } + } + else if (stripos($line, '404 not found') !== false) + { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); + } + } + } + + $stream_meta_data = stream_get_meta_data($fsock); + + // Cancel upload if we exceed timeout + if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) + { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); + } + } + @fclose($fsock); + + if (empty($data)) + { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA'); + } + + $tmp_path = (!@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'off') ? false : $this->phpbb_root_path . 'cache'; + $filename = tempnam($tmp_path, unique_id() . '-'); + + if (!($fp = @fopen($filename, 'wb'))) + { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'NOT_UPLOADED'); + } + + $upload_ary['size'] = fwrite($fp, $data); + fclose($fp); + unset($data); + + $upload_ary['tmp_name'] = $filename; + + /** @var filespec $file */ + $file = $this->factory->get('filespec') + ->set_upload_ary($upload_ary) + ->set_upload_namespace($this); + $this->upload->common_checks($file); + + return $file; + } +} diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 43f06c3503..ceb7e1a741 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -198,191 +198,6 @@ class upload return (is_object($type_class)) ? call_user_func_array(array($type_class, 'upload'), $args) : false; } - /** - * Remote upload method - * Uploads file from given url - * - * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif - * @return filespec $file Object "filespec" is returned, all further operations can be done with this object - * @access public - */ - function remote_upload($upload_url) - { - $upload_ary = array(); - $upload_ary['local_mode'] = true; - - if (!preg_match('#^(https?://).*?\.(' . implode('|', $this->allowed_extensions) . ')$#i', $upload_url, $match)) - { - return $this->factory->get('filespec')->set_error($this->language->lang($this->error_prefix . 'URL_INVALID')); - } - - if (empty($match[2])) - { - return $this->factory->get('filespec')->set_error($this->language->lang($this->error_prefix . 'URL_INVALID')); - } - - $url = parse_url($upload_url); - - $host = $url['host']; - $path = $url['path']; - $port = (!empty($url['port'])) ? (int) $url['port'] : 80; - - $upload_ary['type'] = 'application/octet-stream'; - - $url['path'] = explode('.', $url['path']); - $ext = array_pop($url['path']); - - $url['path'] = implode('', $url['path']); - $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : ''); - $filename = $url['path']; - $filesize = 0; - - $remote_max_filesize = $this->max_filesize; - if (!$remote_max_filesize) - { - $max_filesize = @ini_get('upload_max_filesize'); - - if (!empty($max_filesize)) - { - $unit = strtolower(substr($max_filesize, -1, 1)); - $remote_max_filesize = (int) $max_filesize; - - switch ($unit) - { - case 'g': - $remote_max_filesize *= 1024; - // no break - case 'm': - $remote_max_filesize *= 1024; - // no break - case 'k': - $remote_max_filesize *= 1024; - // no break - } - } - } - - $errno = 0; - $errstr = ''; - - if (!($fsock = @fsockopen($host, $port, $errno, $errstr))) - { - return $this->factory->get('filespec')->set_error($this->language->lang($this->error_prefix . 'NOT_UPLOADED')); - } - - // Make sure $path not beginning with / - if (strpos($path, '/') === 0) - { - $path = substr($path, 1); - } - - fputs($fsock, 'GET /' . $path . " HTTP/1.1\r\n"); - fputs($fsock, "HOST: " . $host . "\r\n"); - fputs($fsock, "Connection: close\r\n\r\n"); - - // Set a proper timeout for the socket - socket_set_timeout($fsock, $this->upload_timeout); - - $get_info = false; - $data = ''; - $length = false; - $timer_stop = time() + $this->upload_timeout; - - while ((!$length || $filesize < $length) && !@feof($fsock)) - { - if ($get_info) - { - if ($length) - { - // Don't attempt to read past end of file if server indicated length - $block = @fread($fsock, min($length - $filesize, 1024)); - } - else - { - $block = @fread($fsock, 1024); - } - - $filesize += strlen($block); - - if ($remote_max_filesize && $filesize > $remote_max_filesize) - { - $max_filesize = get_formatted_filesize($remote_max_filesize, false); - - return $this->factory->get('filespec')->set_error($this->language->lang($this->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); - } - - $data .= $block; - } - else - { - $line = @fgets($fsock, 1024); - - if ($line == "\r\n") - { - $get_info = true; - } - else - { - if (stripos($line, 'content-type: ') !== false) - { - $upload_ary['type'] = rtrim(str_replace('content-type: ', '', strtolower($line))); - } - else if ($this->max_filesize && stripos($line, 'content-length: ') !== false) - { - $length = (int) str_replace('content-length: ', '', strtolower($line)); - - if ($remote_max_filesize && $length && $length > $remote_max_filesize) - { - $max_filesize = get_formatted_filesize($remote_max_filesize, false); - - return $this->factory->get('filespec')->set_error($this->language->lang($this->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); - } - } - else if (stripos($line, '404 not found') !== false) - { - return $this->factory->get('filespec')->set_error($this->error_prefix . 'URL_NOT_FOUND'); - } - } - } - - $stream_meta_data = stream_get_meta_data($fsock); - - // Cancel upload if we exceed timeout - if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) - { - return $this->factory->get('filespec')->set_error($this->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); - } - } - @fclose($fsock); - - if (empty($data)) - { - return $this->factory->get('filespec')->set_error($this->error_prefix . 'EMPTY_REMOTE_DATA'); - } - - $tmp_path = (!@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'off') ? false : $this->phpbb_root_path . 'cache'; - $filename = tempnam($tmp_path, unique_id() . '-'); - - if (!($fp = @fopen($filename, 'wb'))) - { - return $this->factory->get('filespec')->set_error($this->error_prefix . 'NOT_UPLOADED'); - } - - $upload_ary['size'] = fwrite($fp, $data); - fclose($fp); - unset($data); - - $upload_ary['tmp_name'] = $filename; - - /** @var filespec $file */ - $file = $this->factory->get('filespec') - ->set_upload_ary($upload_ary) - ->set_upload_namespace($this); - $this->common_checks($file); - - return $file; - } - /** * Assign internal error * -- cgit v1.2.1 From 759a1a09fae5147afe346729764f050ecc67076b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 15 Jul 2015 21:30:42 +0200 Subject: [ticket/13904] Fix remote upload functional tests PHPBB3-13904 --- phpBB/phpbb/files/types/remote.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index c70f1557e7..04263f9cba 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -234,7 +234,7 @@ class remote extends base /** @var filespec $file */ $file = $this->factory->get('filespec') ->set_upload_ary($upload_ary) - ->set_upload_namespace($this); + ->set_upload_namespace($this->upload); $this->upload->common_checks($file); return $file; -- cgit v1.2.1 From 0a6f54d522f7799819969fcd588a354b7beb3fa9 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 15 Jul 2015 22:40:17 +0200 Subject: [ticket/13904] Modify doc blocks PHPBB3-13904 --- phpBB/phpbb/files/types/base.php | 10 ++++------ phpBB/phpbb/files/types/remote.php | 3 +-- 2 files changed, 5 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/base.php b/phpBB/phpbb/files/types/base.php index 686ce6f695..77ebdb4f32 100644 --- a/phpBB/phpbb/files/types/base.php +++ b/phpBB/phpbb/files/types/base.php @@ -13,8 +13,6 @@ namespace phpbb\files\types; -use \phpbb\files\filespec; -use \phpbb\files\upload; use \phpbb\language\language; abstract class base implements type_interface @@ -22,15 +20,15 @@ abstract class base implements type_interface /** @var language */ protected $language; - /** @var upload */ + /** @var \phpbb\files\upload */ protected $upload; /** * Check if upload exceeds maximum file size * - * @param filespec $file Filespec object + * @param \phpbb\files\filespec $file Filespec object * - * @return filespec Returns same filespec instance + * @return \phpbb\files\filespec Returns same filespec instance */ public function check_upload_size($file) { @@ -57,7 +55,7 @@ abstract class base implements type_interface /** * {@inheritdoc} */ - public function set_upload(upload $upload) + public function set_upload(\phpbb\files\upload $upload) { $this->upload = $upload; diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 04263f9cba..f2db6c798c 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -15,7 +15,6 @@ namespace phpbb\files\types; use \phpbb\files\factory; use \phpbb\files\filespec; -use \phpbb\files\upload; use \phpbb\language\language; use \phpbb\request\request_interface; @@ -30,7 +29,7 @@ class remote extends base /** @var request_interface */ protected $request; - /** @var upload */ + /** @var \phpbb\files\upload */ protected $upload; /** -- cgit v1.2.1 From a09c6d1fb760151b1a6c654b597b4578c3136be1 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 15 Jul 2015 23:10:23 +0200 Subject: [ticket/13904] Split code up and pass root path to remote upload type PHPBB3-13904 --- phpBB/phpbb/files/types/remote.php | 66 +++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 25 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index f2db6c798c..65cff8ccc7 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -32,17 +32,21 @@ class remote extends base /** @var \phpbb\files\upload */ protected $upload; + /** @var string phpBB root path */ + protected $phpbb_root_path; + /** * Construct a form upload type * * @param factory $factory * @param request_interface $request */ - public function __construct(factory $factory, language $language, request_interface $request) + public function __construct(factory $factory, language $language, request_interface $request, $phpbb_root_path) { $this->factory = $factory; $this->language = $language; $this->request = $request; + $this->phpbb_root_path = $phpbb_root_path; } /** @@ -93,30 +97,7 @@ class remote extends base $filename = $url['path']; $filesize = 0; - $remote_max_filesize = $this->upload->max_filesize; - if (!$remote_max_filesize) - { - $max_filesize = @ini_get('upload_max_filesize'); - - if (!empty($max_filesize)) - { - $unit = strtolower(substr($max_filesize, -1, 1)); - $remote_max_filesize = (int) $max_filesize; - - switch ($unit) - { - case 'g': - $remote_max_filesize *= 1024; - // no break - case 'm': - $remote_max_filesize *= 1024; - // no break - case 'k': - $remote_max_filesize *= 1024; - // no break - } - } - } + $remote_max_filesize = $this->get_max_file_size(); $errno = 0; $errstr = ''; @@ -238,4 +219,39 @@ class remote extends base return $file; } + + /** + * Get maximum file size for remote uploads + * + * @return int Maximum file size + */ + protected function get_max_file_size() + { + $max_file_size = $this->upload->max_filesize; + if (!$max_file_size) + { + $max_file_size = @ini_get('upload_max_filesize'); + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_file_size, -1, 1)); + $max_file_size = (int) $max_filesize; + + switch ($unit) + { + case 'g': + $max_file_size *= 1024; + // no break + case 'm': + $max_file_size *= 1024; + // no break + case 'k': + $max_file_size *= 1024; + // no break + } + } + } + + return $max_file_size; + } } -- cgit v1.2.1 From 845233fc626b0d5e6d9e61039fde8e31b4dd28aa Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 16 Jul 2015 00:21:23 +0200 Subject: [ticket/13904] Improve test coverage and use constants instead of magic numbers PHPBB3-13904 --- phpBB/phpbb/files/upload.php | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index ceb7e1a741..234eb69735 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -210,7 +210,7 @@ class upload { switch ($errorcode) { - case 1: + case UPLOAD_ERR_INI_SIZE: $max_filesize = @ini_get('upload_max_filesize'); $unit = 'MB'; @@ -223,29 +223,37 @@ class upload } $error = (empty($max_filesize)) ? $this->language->lang($this->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); - break; + break; - case 2: + case UPLOAD_ERR_FORM_SIZE: $max_filesize = get_formatted_filesize($this->max_filesize, false); $error = $this->language->lang($this->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit']); - break; + break; - case 3: + case UPLOAD_ERR_PARTIAL: $error = $this->language->lang($this->error_prefix . 'PARTIAL_UPLOAD'); - break; + break; - case 4: + case UPLOAD_ERR_NO_FILE: $error = $this->language->lang($this->error_prefix . 'NOT_UPLOADED'); - break; + break; - case 6: + case UPLOAD_ERR_NO_TMP_DIR: $error = 'Temporary folder could not be found. Please check your PHP installation.'; - break; + break; + + case UPLOAD_ERR_CANT_WRITE: + $error = 'Can’t write to temporary folder.'; + break; + + case UPLOAD_ERR_EXTENSION: + $error = 'A PHP extension has stopped the file upload.'; + break; default: $error = false; - break; + break; } return $error; -- cgit v1.2.1 From 9e87e5a3437f3d88f7dac4c576a53fed53ff4bae Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 16 Jul 2015 00:23:10 +0200 Subject: [ticket/13904] Remove unused use statement PHPBB3-13904 --- phpBB/phpbb/files/types/base.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/base.php b/phpBB/phpbb/files/types/base.php index 77ebdb4f32..1ed06053a4 100644 --- a/phpBB/phpbb/files/types/base.php +++ b/phpBB/phpbb/files/types/base.php @@ -13,11 +13,9 @@ namespace phpbb\files\types; -use \phpbb\language\language; - abstract class base implements type_interface { - /** @var language */ + /** @var \phpbb\language\language */ protected $language; /** @var \phpbb\files\upload */ -- cgit v1.2.1 From 3e99816fa2f184b859d47308254aa8f07d68f1dd Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 16 Jul 2015 12:06:23 +0200 Subject: [ticket/13904] Set visibility in files and improve test coverage PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 78 +++++++++++++++++++++++------------------- phpBB/phpbb/files/upload.php | 40 +++++++++++----------- 2 files changed, 63 insertions(+), 55 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index ed64b7ff5c..e07aef9892 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -22,49 +22,52 @@ use \phpbb\language\language; class filespec { /** @var string File name */ - var $filename = ''; + protected $filename = ''; /** @var string Real name of file */ - var $realname = ''; + protected $realname = ''; /** @var string Upload name of file */ - var $uploadname = ''; + protected $uploadname = ''; /** @var string Mimetype of file */ - var $mimetype = ''; + protected $mimetype = ''; /** @var string File extension */ - var $extension = ''; + public $extension = ''; /** @var int File size */ - var $filesize = 0; + public $filesize = 0; /** @var int Width of file */ - var $width = 0; + protected $width = 0; /** @var int Height of file */ - var $height = 0; + protected $height = 0; /** @var array Image info including type and size */ - var $image_info = array(); + protected $image_info = array(); /** @var string Destination file name */ - var $destination_file = ''; + protected $destination_file = ''; /** @var string Destination file path */ - var $destination_path = ''; + protected $destination_path = ''; /** @var bool Whether file was moved */ - var $file_moved = false; + public $file_moved = false; - /** @var bool Whether file is local */ - var $local = false; + /** @var bool Whether file is local */ + public $local = false; + + /** @var bool Class initialization flag */ + protected $class_initialized = false; /** @var array Error array */ - var $error = array(); + public $error = array(); /** @var upload Instance of upload class */ - var $upload; + public $upload; /** * @var \phpbb\filesystem\filesystem_interface @@ -98,7 +101,7 @@ class filespec * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser * @param \phpbb\plupload\plupload $plupload Plupload */ - function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { $this->plupload = $plupload; $this->mimetype_guesser = $mimetype_guesser; @@ -116,6 +119,12 @@ class filespec */ public function set_upload_ary($upload_ary) { + if (!isset($upload_ary) || !sizeof($upload_ary)) + { + return $this; + } + + $this->class_initialized = true; $this->filename = $upload_ary['tmp_name']; $this->filesize = $upload_ary['size']; $name = (STRIP) ? stripslashes($upload_ary['name']) : $upload_ary['name']; @@ -165,7 +174,7 @@ class filespec */ public function init_error() { - return !isset($this->filename); + return !$this->class_initialized; } /** @@ -193,7 +202,7 @@ class filespec * *@access public */ - function clean_filename($mode = 'unique', $prefix = '', $user_id = '') + public function clean_filename($mode = 'unique', $prefix = '', $user_id = '') { if ($this->init_error()) { @@ -216,22 +225,21 @@ class filespec $this->realname = preg_replace("/%(\w{2})/", '_', $this->realname); $this->realname = $prefix . $this->realname . '.' . $this->extension; - break; + break; case 'unique': $this->realname = $prefix . md5(unique_id()); - break; + break; case 'avatar': $this->extension = strtolower($this->extension); $this->realname = $prefix . $user_id . '.' . $this->extension; - break; + break; case 'unique_ext': default: $this->realname = $prefix . md5(unique_id()) . '.' . $this->extension; - break; } } @@ -242,7 +250,7 @@ class filespec * * @return mixed Content of property */ - function get($property) + public function get($property) { if ($this->init_error() || !isset($this->$property)) { @@ -257,7 +265,7 @@ class filespec * * @return bool true if it is an image, false if not */ - function is_image() + public function is_image() { return (strpos($this->mimetype, 'image/') === 0); } @@ -267,7 +275,7 @@ class filespec * * @return bool true if it is a valid upload, false if not */ - function is_uploaded() + public function is_uploaded() { $is_plupload = $this->plupload && $this->plupload->is_active(); @@ -287,7 +295,7 @@ class filespec /** * Remove file */ - function remove() + public function remove() { if ($this->file_moved) { @@ -321,7 +329,7 @@ class filespec * @param string $filename Filename that needs to be checked * @return string Mime type of supplied filename */ - function get_mimetype($filename) + public function get_mimetype($filename) { if ($this->mimetype_guesser !== null) { @@ -343,7 +351,7 @@ class filespec * * @return int File size */ - function get_filesize($filename) + public function get_filesize($filename) { return @filesize($filename); } @@ -356,7 +364,7 @@ class filespec * * @return bool False if disallowed content found, true if not */ - function check_content($disallowed_content) + public function check_content($disallowed_content) { if (empty($disallowed_content)) { @@ -393,7 +401,7 @@ class filespec * @return bool True if file was moved, false if not * @access public */ - function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false) + public function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false) { if (sizeof($this->error)) { @@ -443,7 +451,7 @@ class filespec } } - break; + break; case 'move': @@ -455,7 +463,7 @@ class filespec } } - break; + break; case 'local': @@ -464,7 +472,7 @@ class filespec $this->error[] = $this->language->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file); } - break; + break; } // Remove temporary filename @@ -544,7 +552,7 @@ class filespec * * @return bool False if issue was found, true if not */ - function additional_checks() + public function additional_checks() { if (!$this->file_moved) { diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 234eb69735..397eb5af36 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -24,31 +24,31 @@ use \phpbb\request\request_interface; class upload { /** @var array Allowed file extensions */ - var $allowed_extensions = array(); + public $allowed_extensions = array(); /** @var array Disallowed content */ - var $disallowed_content = array('body', 'head', 'html', 'img', 'plaintext', 'a href', 'pre', 'script', 'table', 'title'); + protected $disallowed_content = array('body', 'head', 'html', 'img', 'plaintext', 'a href', 'pre', 'script', 'table', 'title'); /** @var int Maximum filesize */ - var $max_filesize = 0; + public $max_filesize = 0; /** @var int Minimum width of images */ - var $min_width = 0; + public $min_width = 0; /** @var int Minimum height of images */ - var $min_height = 0; + public $min_height = 0; /** @var int Maximum width of images */ - var $max_width = 0; + public $max_width = 0; /** @var int Maximum height of images */ - var $max_height = 0; + public $max_height = 0; /** @var string Prefix for language variables of errors */ - var $error_prefix = ''; + public $error_prefix = ''; /** @var int Timeout for remote upload */ - var $upload_timeout = 6; + public $upload_timeout = 6; /** @var filesystem_interface */ protected $filesystem; @@ -86,7 +86,7 @@ class upload /** * Reset vars */ - function reset_vars() + public function reset_vars() { $this->max_filesize = 0; $this->min_width = $this->min_height = $this->max_width = $this->max_height = 0; @@ -102,7 +102,7 @@ class upload * * @return \phpbb\files\upload This instance of upload */ - function set_allowed_extensions($allowed_extensions) + public function set_allowed_extensions($allowed_extensions) { if ($allowed_extensions !== false && is_array($allowed_extensions)) { @@ -122,7 +122,7 @@ class upload * * @return \phpbb\files\upload This instance of upload */ - function set_allowed_dimensions($min_width, $min_height, $max_width, $max_height) + public function set_allowed_dimensions($min_width, $min_height, $max_width, $max_height) { $this->min_width = (int) $min_width; $this->min_height = (int) $min_height; @@ -139,7 +139,7 @@ class upload * * @return \phpbb\files\upload This instance of upload */ - function set_max_filesize($max_filesize) + public function set_max_filesize($max_filesize) { if ($max_filesize !== false && (int) $max_filesize) { @@ -156,7 +156,7 @@ class upload * * @return \phpbb\files\upload This instance of upload */ - function set_disallowed_content($disallowed_content) + public function set_disallowed_content($disallowed_content) { if ($disallowed_content !== false && is_array($disallowed_content)) { @@ -173,7 +173,7 @@ class upload * * @return \phpbb\files\upload This instance of upload */ - function set_error_prefix($error_prefix) + public function set_error_prefix($error_prefix) { $this->error_prefix = $error_prefix; @@ -264,7 +264,7 @@ class upload * * @param filespec $file Instance of filespec class */ - function common_checks(&$file) + public function common_checks(&$file) { // Filesize is too big or it's 0 if it was larger than the maxsize in the upload form if ($this->max_filesize && ($file->get('filesize') > $this->max_filesize || $file->get('filesize') == 0)) @@ -300,7 +300,7 @@ class upload * * @return bool True if extension is allowed, false if not */ - function valid_extension(&$file) + public function valid_extension(&$file) { return (in_array($file->get('extension'), $this->allowed_extensions)) ? true : false; } @@ -313,7 +313,7 @@ class upload * @return bool True if dimensions are valid or no constraints set, false * if not */ - function valid_dimensions(&$file) + public function valid_dimensions(&$file) { if (!$this->max_width && !$this->max_height && !$this->min_width && !$this->min_height) { @@ -338,7 +338,7 @@ class upload * * @return bool True if form upload is valid, false if not */ - function is_valid($form_name) + public function is_valid($form_name) { $upload = $this->request->file($form_name); @@ -353,7 +353,7 @@ class upload * * @return bool True if content is valid, false if not */ - function valid_content(&$file) + public function valid_content(&$file) { return ($file->check_content($this->disallowed_content)); } -- cgit v1.2.1 From 02f94b7527298aad3bd15738676da872aa498039 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 14 Aug 2015 10:31:26 +0200 Subject: [ticket/13904] Update doc blocks PHPBB3-13904 --- phpBB/phpbb/files/types/form.php | 6 ++++-- phpBB/phpbb/files/types/local.php | 5 +++-- phpBB/phpbb/files/types/remote.php | 6 ++++-- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php index 98d1c51d5f..be0a425d57 100644 --- a/phpBB/phpbb/files/types/form.php +++ b/phpBB/phpbb/files/types/form.php @@ -40,8 +40,10 @@ class form extends base /** * Construct a form upload type * - * @param factory $factory - * @param request_interface $request + * @param factory $factory Files factory + * @param language $language Language class + * @param plupload $plupload Plupload + * @param request_interface $request Request object */ public function __construct(factory $factory, language $language, plupload $plupload, request_interface $request) { diff --git a/phpBB/phpbb/files/types/local.php b/phpBB/phpbb/files/types/local.php index bb5994841f..dfaabded9b 100644 --- a/phpBB/phpbb/files/types/local.php +++ b/phpBB/phpbb/files/types/local.php @@ -35,8 +35,9 @@ class local extends base /** * Construct a form upload type * - * @param factory $factory - * @param request_interface $request + * @param factory $factory Files factory + * @param language $language Language class + * @param request_interface $request Request object */ public function __construct(factory $factory, language $language, request_interface $request) { diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 65cff8ccc7..94bba8ad46 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -38,8 +38,10 @@ class remote extends base /** * Construct a form upload type * - * @param factory $factory - * @param request_interface $request + * @param factory $factory Files factory + * @param language $language Language class + * @param request_interface $request Request object + * @param string $phpbb_root_path phpBB root path */ public function __construct(factory $factory, language $language, request_interface $request, $phpbb_root_path) { -- cgit v1.2.1 From cdde86ce7e0c594fad5992789b3fae466bd526cc Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 26 Aug 2015 13:57:42 +0200 Subject: [ticket/13904] Use \phpbb\php\ini class for ini_get() PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 31 ++++++++++++++++++------------- phpBB/phpbb/files/upload.php | 9 +++++++-- 2 files changed, 25 insertions(+), 15 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index e07aef9892..34d86116c2 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -74,6 +74,15 @@ class filespec */ protected $filesystem; + /** @var \phpbb\php\ini ini_get() wrapper class */ + protected $php_ini; + + /** @var language Language class */ + protected $language; + + /** @var string phpBB root path */ + protected $phpbb_root_path; + /** * The plupload object * @var \phpbb\plupload\plupload @@ -86,28 +95,24 @@ class filespec */ protected $mimetype_guesser; - /** @var language Language class */ - protected $language; - - /** @var string phpBB root path */ - protected $phpbb_root_path; - /** * File upload class * * @param \phpbb\filesystem\filesystem_interface $phpbb_filesystem Filesystem + * @param \phpbb\php\ini $php_ini ini_get() wrapper * @param language $language Language - * @param string $phpbb_root_path phpBB root path - * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser - * @param \phpbb\plupload\plupload $plupload Plupload + * @param string $phpbb_root_path phpBB root path + * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser + * @param \phpbb\plupload\plupload $plupload Plupload */ - public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, \phpbb\php\ini $php_ini, language $language, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { - $this->plupload = $plupload; - $this->mimetype_guesser = $mimetype_guesser; $this->filesystem = $phpbb_filesystem; + $this->php_ini = $php_ini; $this->language = $language; $this->phpbb_root_path = $phpbb_root_path; + $this->plupload = $plupload; + $this->mimetype_guesser = $mimetype_guesser; } /** @@ -420,7 +425,7 @@ class filespec return false; } - $upload_mode = (@ini_get('open_basedir') || @ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'on') ? 'move' : 'copy'; + $upload_mode = ($this->php_ini->get_bool('open_basedir') || $this->php_ini->get_bool('safe_mode')) ? 'move' : 'copy'; $upload_mode = ($this->local) ? 'local' : $upload_mode; $this->destination_file = $this->destination_path . '/' . utf8_basename($this->realname); diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 397eb5af36..35107ccb45 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -56,6 +56,9 @@ class upload /** @var \phpbb\files\factory Files factory */ protected $factory; + /** @var \phpbb\php\ini ini_get() wrapper */ + protected $php_ini; + /** @var \phpbb\language\language Language class */ protected $language; @@ -70,14 +73,16 @@ class upload * * @param filesystem_interface $filesystem * @param factory $factory Files factory + * @param \phpbb\php\ini $php_ini ini_get() wrapper * @param language $language Language class * @param request_interface $request Request class * @param string $phpbb_root_path phpBB root path */ - public function __construct(filesystem_interface $filesystem, factory $factory, language $language, request_interface $request, $phpbb_root_path) + public function __construct(filesystem_interface $filesystem, factory $factory, \phpbb\php\ini $php_ini, language $language, request_interface $request, $phpbb_root_path) { $this->filesystem = $filesystem; $this->factory = $factory; + $this->php_ini = $php_ini; $this->language = $language; $this->request = $request; $this->phpbb_root_path = $phpbb_root_path; @@ -211,7 +216,7 @@ class upload switch ($errorcode) { case UPLOAD_ERR_INI_SIZE: - $max_filesize = @ini_get('upload_max_filesize'); + $max_filesize = $this->php_ini->get_string('upload_max_filesize'); $unit = 'MB'; if (!empty($max_filesize)) -- cgit v1.2.1 From 36545d5cbe7188efbedf2e1f44b1a7b9617b50c1 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 26 Aug 2015 16:18:10 +0200 Subject: [ticket/13904] Switch around constructor arguments PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 20 ++++++-------------- phpBB/phpbb/files/upload.php | 6 +++--- 2 files changed, 9 insertions(+), 17 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 34d86116c2..48e12f23ef 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -69,9 +69,7 @@ class filespec /** @var upload Instance of upload class */ public $upload; - /** - * @var \phpbb\filesystem\filesystem_interface - */ + /** @var \phpbb\filesystem\filesystem_interface */ protected $filesystem; /** @var \phpbb\php\ini ini_get() wrapper class */ @@ -83,33 +81,27 @@ class filespec /** @var string phpBB root path */ protected $phpbb_root_path; - /** - * The plupload object - * @var \phpbb\plupload\plupload - */ + /** @var \phpbb\plupload\plupload The plupload object */ protected $plupload; - /** - * phpBB Mimetype guesser - * @var \phpbb\mimetype\guesser - */ + /** @var \phpbb\mimetype\guesser phpBB Mimetype guesser */ protected $mimetype_guesser; /** * File upload class * * @param \phpbb\filesystem\filesystem_interface $phpbb_filesystem Filesystem - * @param \phpbb\php\ini $php_ini ini_get() wrapper * @param language $language Language + * @param \phpbb\php\ini $php_ini ini_get() wrapper * @param string $phpbb_root_path phpBB root path * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser * @param \phpbb\plupload\plupload $plupload Plupload */ - public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, \phpbb\php\ini $php_ini, language $language, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \phpbb\php\ini $php_ini, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { $this->filesystem = $phpbb_filesystem; - $this->php_ini = $php_ini; $this->language = $language; + $this->php_ini = $php_ini; $this->phpbb_root_path = $phpbb_root_path; $this->plupload = $plupload; $this->mimetype_guesser = $mimetype_guesser; diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 35107ccb45..036f216d22 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -73,17 +73,17 @@ class upload * * @param filesystem_interface $filesystem * @param factory $factory Files factory - * @param \phpbb\php\ini $php_ini ini_get() wrapper * @param language $language Language class + * @param \phpbb\php\ini $php_ini ini_get() wrapper * @param request_interface $request Request class * @param string $phpbb_root_path phpBB root path */ - public function __construct(filesystem_interface $filesystem, factory $factory, \phpbb\php\ini $php_ini, language $language, request_interface $request, $phpbb_root_path) + public function __construct(filesystem_interface $filesystem, factory $factory, language $language, \phpbb\php\ini $php_ini, request_interface $request, $phpbb_root_path) { $this->filesystem = $filesystem; $this->factory = $factory; - $this->php_ini = $php_ini; $this->language = $language; + $this->php_ini = $php_ini; $this->request = $request; $this->phpbb_root_path = $phpbb_root_path; } -- cgit v1.2.1 From 16f3b8c2b9de388223cbe8ace9e1d9bcf0ba5e11 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 27 Aug 2015 10:51:10 +0200 Subject: [ticket/13904] Modify files for changes in ini wrapper PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 8 ++++---- phpBB/phpbb/files/upload.php | 8 ++++---- phpBB/phpbb/install/helper/config.php | 8 ++++---- phpBB/phpbb/plupload/plupload.php | 12 ++++++------ 4 files changed, 18 insertions(+), 18 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 48e12f23ef..580016b281 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -72,7 +72,7 @@ class filespec /** @var \phpbb\filesystem\filesystem_interface */ protected $filesystem; - /** @var \phpbb\php\ini ini_get() wrapper class */ + /** @var \bantu\IniGetWrapper\IniGetWrapper ini_get() wrapper class */ protected $php_ini; /** @var language Language class */ @@ -92,12 +92,12 @@ class filespec * * @param \phpbb\filesystem\filesystem_interface $phpbb_filesystem Filesystem * @param language $language Language - * @param \phpbb\php\ini $php_ini ini_get() wrapper + * @param \bantu\IniGetWrapper\IniGetWrapper $php_ini ini_get() wrapper * @param string $phpbb_root_path phpBB root path * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser * @param \phpbb\plupload\plupload $plupload Plupload */ - public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \phpbb\php\ini $php_ini, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { $this->filesystem = $phpbb_filesystem; $this->language = $language; @@ -417,7 +417,7 @@ class filespec return false; } - $upload_mode = ($this->php_ini->get_bool('open_basedir') || $this->php_ini->get_bool('safe_mode')) ? 'move' : 'copy'; + $upload_mode = ($this->php_ini->getBool('open_basedir') || $this->php_ini->getBool('safe_mode')) ? 'move' : 'copy'; $upload_mode = ($this->local) ? 'local' : $upload_mode; $this->destination_file = $this->destination_path . '/' . utf8_basename($this->realname); diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 036f216d22..328dd49a06 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -56,7 +56,7 @@ class upload /** @var \phpbb\files\factory Files factory */ protected $factory; - /** @var \phpbb\php\ini ini_get() wrapper */ + /** @var \bantu\IniGetWrapper\IniGetWrapper ini_get() wrapper */ protected $php_ini; /** @var \phpbb\language\language Language class */ @@ -74,11 +74,11 @@ class upload * @param filesystem_interface $filesystem * @param factory $factory Files factory * @param language $language Language class - * @param \phpbb\php\ini $php_ini ini_get() wrapper + * @param \bantu\IniGetWrapper\IniGetWrapper $php_ini ini_get() wrapper * @param request_interface $request Request class * @param string $phpbb_root_path phpBB root path */ - public function __construct(filesystem_interface $filesystem, factory $factory, language $language, \phpbb\php\ini $php_ini, request_interface $request, $phpbb_root_path) + public function __construct(filesystem_interface $filesystem, factory $factory, language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path) { $this->filesystem = $filesystem; $this->factory = $factory; @@ -216,7 +216,7 @@ class upload switch ($errorcode) { case UPLOAD_ERR_INI_SIZE: - $max_filesize = $this->php_ini->get_string('upload_max_filesize'); + $max_filesize = $this->php_ini->getString('upload_max_filesize'); $unit = 'MB'; if (!empty($max_filesize)) diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php index b0480e7e5b..d5653f1924 100644 --- a/phpBB/phpbb/install/helper/config.php +++ b/phpBB/phpbb/install/helper/config.php @@ -41,7 +41,7 @@ class config protected $install_config_file; /** - * @var \phpbb\php\ini + * @var \bantu\IniGetWrapper\IniGetWrapper */ protected $php_ini; @@ -83,7 +83,7 @@ class config /** * Constructor */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, \phpbb\php\ini $php_ini, $phpbb_root_path) + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, \bantu\IniGetWrapper\IniGetWrapper $php_ini, $phpbb_root_path) { $this->filesystem = $filesystem; $this->php_ini = $php_ini; @@ -373,7 +373,7 @@ class config protected function setup_system_data() { // Query maximum runtime from php.ini - $execution_time = $this->php_ini->get_int('max_execution_time'); + $execution_time = $this->php_ini->getNumeric('max_execution_time'); $execution_time = min(15, $execution_time / 2); $this->system_data['max_execution_time'] = $execution_time; @@ -381,6 +381,6 @@ class config $this->system_data['start_time'] = time(); // Get memory limit - $this->system_data['memory_limit'] = $this->php_ini->get_bytes('memory_limit'); + $this->system_data['memory_limit'] = $this->php_ini->getBytes('memory_limit'); } } diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index 35f3a0071e..0e67ee209b 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -39,7 +39,7 @@ class plupload protected $user; /** - * @var \phpbb\php\ini + * @var \bantu\IniGetWrapper\IniGetWrapper */ protected $php_ini; @@ -67,10 +67,10 @@ class plupload * @param \phpbb\config\config $config * @param \phpbb\request\request_interface $request * @param \phpbb\user $user - * @param \phpbb\php\ini $php_ini + * @param \bantu\IniGetWrapper\IniGetWrapper $php_ini * @param \phpbb\mimetype\guesser $mimetype_guesser */ - public function __construct($phpbb_root_path, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\user $user, \phpbb\php\ini $php_ini, \phpbb\mimetype\guesser $mimetype_guesser) + public function __construct($phpbb_root_path, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\user $user, \bantu\IniGetWrapper\IniGetWrapper $php_ini, \phpbb\mimetype\guesser $mimetype_guesser) { $this->phpbb_root_path = $phpbb_root_path; $this->config = $config; @@ -284,9 +284,9 @@ class plupload public function get_chunk_size() { $max = min( - $this->php_ini->get_bytes('upload_max_filesize'), - $this->php_ini->get_bytes('post_max_size'), - max(1, $this->php_ini->get_bytes('memory_limit')), + $this->php_ini->getBytes('upload_max_filesize'), + $this->php_ini->getBytes('post_max_size'), + max(1, $this->php_ini->getBytes('memory_limit')), $this->config['max_filesize'] ); -- cgit v1.2.1 From b29b62debe4077ec688ebee9e9363db2c8614dd5 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 27 Aug 2015 12:48:06 +0200 Subject: [ticket/13904] Use ini_get() wrapper in file upload types PHPBB3-13904 --- phpBB/phpbb/files/types/base.php | 5 ++++- phpBB/phpbb/files/types/form.php | 10 ++++++++-- phpBB/phpbb/files/types/local.php | 26 +++++++++++--------------- phpBB/phpbb/files/types/remote.php | 12 +++++++++--- 4 files changed, 32 insertions(+), 21 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/base.php b/phpBB/phpbb/files/types/base.php index 1ed06053a4..3313ad040b 100644 --- a/phpBB/phpbb/files/types/base.php +++ b/phpBB/phpbb/files/types/base.php @@ -18,6 +18,9 @@ abstract class base implements type_interface /** @var \phpbb\language\language */ protected $language; + /** @var \bantu\IniGetWrapper\IniGetWrapper */ + protected $php_ini; + /** @var \phpbb\files\upload */ protected $upload; @@ -33,7 +36,7 @@ abstract class base implements type_interface // PHP Upload filesize exceeded if ($file->get('filename') == 'none') { - $max_filesize = @ini_get('upload_max_filesize'); + $max_filesize = $this->php_ini->getString('upload_max_filesize'); $unit = 'MB'; if (!empty($max_filesize)) diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php index be0a425d57..b8ad62f58b 100644 --- a/phpBB/phpbb/files/types/form.php +++ b/phpBB/phpbb/files/types/form.php @@ -13,6 +13,7 @@ namespace phpbb\files\types; +use \bantu\IniGetWrapper\IniGetWrapper; use \phpbb\files\factory; use \phpbb\files\filespec; use \phpbb\files\upload; @@ -28,6 +29,9 @@ class form extends base /** @var language */ protected $language; + /** @var IniGetWrapper */ + protected $php_ini; + /** @var plupload */ protected $plupload; @@ -42,13 +46,15 @@ class form extends base * * @param factory $factory Files factory * @param language $language Language class + * @param IniGetWrapper $php_ini ini_get() wrapper * @param plupload $plupload Plupload * @param request_interface $request Request object */ - public function __construct(factory $factory, language $language, plupload $plupload, request_interface $request) + public function __construct(factory $factory, language $language, IniGetWrapper $php_ini, plupload $plupload, request_interface $request) { $this->factory = $factory; $this->language = $language; + $this->php_ini = $php_ini; $this->plupload = $plupload; $this->request = $request; } @@ -122,7 +128,7 @@ class form extends base return $file; } - // PHP Upload filesize check + // PHP Upload file size check $file = $this->check_upload_size($file); if (sizeof($file->error)) { diff --git a/phpBB/phpbb/files/types/local.php b/phpBB/phpbb/files/types/local.php index dfaabded9b..96bfdaca7f 100644 --- a/phpBB/phpbb/files/types/local.php +++ b/phpBB/phpbb/files/types/local.php @@ -13,6 +13,7 @@ namespace phpbb\files\types; +use \bantu\IniGetWrapper\IniGetWrapper; use \phpbb\files\factory; use \phpbb\files\filespec; use \phpbb\language\language; @@ -26,6 +27,9 @@ class local extends base /** @var language */ protected $language; + /** @var IniGetWrapper */ + protected $php_ini; + /** @var request_interface */ protected $request; @@ -37,12 +41,14 @@ class local extends base * * @param factory $factory Files factory * @param language $language Language class + * @param IniGetWrapper $php_ini ini_get() wrapper * @param request_interface $request Request object */ - public function __construct(factory $factory, language $language, request_interface $request) + public function __construct(factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request) { $this->factory = $factory; $this->language = $language; + $this->php_ini = $php_ini; $this->request = $request; } @@ -89,21 +95,11 @@ class local extends base } } - // PHP Upload filesize exceeded - if ($file->get('filename') == 'none') + // PHP Upload file size check + $this->check_upload_size($file); + $file = $this->check_upload_size($file); + if (sizeof($file->error)) { - $max_filesize = @ini_get('upload_max_filesize'); - $unit = 'MB'; - - if (!empty($max_filesize)) - { - $unit = strtolower(substr($max_filesize, -1, 1)); - $max_filesize = (int) $max_filesize; - - $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); - } - - $file->error[] = (empty($max_filesize)) ?$this->language->lang($this->upload->error_prefix . 'PHP_SIZE_NA') : $this->language->lang($this->upload->error_prefix . 'PHP_SIZE_OVERRUN', $max_filesize, $this->language->lang($unit)); return $file; } diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 94bba8ad46..bad87243a5 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -13,6 +13,7 @@ namespace phpbb\files\types; +use \bantu\IniGetWrapper\IniGetWrapper; use \phpbb\files\factory; use \phpbb\files\filespec; use \phpbb\language\language; @@ -26,6 +27,9 @@ class remote extends base /** @var language */ protected $language; + /** @var IniGetWrapper */ + protected $php_ini; + /** @var request_interface */ protected $request; @@ -40,13 +44,15 @@ class remote extends base * * @param factory $factory Files factory * @param language $language Language class + * @param IniGetWrapper $php_ini ini_get() wrapper * @param request_interface $request Request object * @param string $phpbb_root_path phpBB root path */ - public function __construct(factory $factory, language $language, request_interface $request, $phpbb_root_path) + public function __construct(factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path) { $this->factory = $factory; $this->language = $language; + $this->php_ini = $php_ini; $this->request = $request; $this->phpbb_root_path = $phpbb_root_path; } @@ -199,7 +205,7 @@ class remote extends base return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA'); } - $tmp_path = (!@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'off') ? false : $this->phpbb_root_path . 'cache'; + $tmp_path = (!$this->php_ini->getBool('safe_mode')) ? false : $this->phpbb_root_path . 'cache'; $filename = tempnam($tmp_path, unique_id() . '-'); if (!($fp = @fopen($filename, 'wb'))) @@ -232,7 +238,7 @@ class remote extends base $max_file_size = $this->upload->max_filesize; if (!$max_file_size) { - $max_file_size = @ini_get('upload_max_filesize'); + $max_file_size = $this->php_ini->getString('upload_max_filesize'); if (!empty($max_filesize)) { -- cgit v1.2.1 From 591995267a3f1931131fa630bd3ff120476f881f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 3 Sep 2015 17:20:54 +0200 Subject: [ticket/13904] Improve test coverage of filespec class PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 580016b281..6ce54a4789 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -75,6 +75,9 @@ class filespec /** @var \bantu\IniGetWrapper\IniGetWrapper ini_get() wrapper class */ protected $php_ini; + /** @var \fastImageSize\fastImageSize */ + protected $imagesize; + /** @var language Language class */ protected $language; @@ -97,11 +100,12 @@ class filespec * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser * @param \phpbb\plupload\plupload $plupload Plupload */ - public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, \fastImageSize\fastImageSize $imagesize, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { $this->filesystem = $phpbb_filesystem; $this->language = $language; $this->php_ini = $php_ini; + $this->imagesize = $imagesize; $this->phpbb_root_path = $phpbb_root_path; $this->plupload = $plupload; $this->mimetype_guesser = $mimetype_guesser; @@ -500,10 +504,7 @@ class filespec { $this->width = $this->height = 0; - // Get imagesize class - $imagesize = new \fastImageSize\fastImageSize(); - - $this->image_info = $imagesize->getImageSize($this->destination_file, $this->mimetype); + $this->image_info = $this->imagesize->getImageSize($this->destination_file, $this->mimetype); if ($this->image_info !== false) { -- cgit v1.2.1 From 1b9e6e352fd4a78e195d22a7dad6cd4f8f11d97c Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 7 Sep 2015 11:34:42 +0200 Subject: [ticket/13904] Improve test coverage of form upload type PHPBB3-13904 --- phpBB/phpbb/files/types/form.php | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php index b8ad62f58b..1662e0e920 100644 --- a/phpBB/phpbb/files/types/form.php +++ b/phpBB/phpbb/files/types/form.php @@ -68,16 +68,6 @@ class form extends base return $this->form_upload($args[0]); } - /** - * {@inheritdoc} - */ - public function set_upload(upload $upload) - { - $this->upload = $upload; - - return $this; - } - /** * Form upload method * Upload file from users harddisk -- cgit v1.2.1 From 82bca32015b94b140b7c810fc5d7e721e8ee341f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 7 Sep 2015 11:35:12 +0200 Subject: [ticket/13904] Improve test coverage of remote upload type PHPBB3-13904 --- phpBB/phpbb/files/types/remote.php | 5 ----- 1 file changed, 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index bad87243a5..b5a0dade11 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -84,11 +84,6 @@ class remote extends base return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'URL_INVALID')); } - if (empty($match[2])) - { - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'URL_INVALID')); - } - $url = parse_url($upload_url); $host = $url['host']; -- cgit v1.2.1 From 7a92ad596c56c25728fd6a22c3a817504e8cb347 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 7 Sep 2015 12:19:48 +0200 Subject: [ticket/13904] Minor coding style fixes PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 1 + phpBB/phpbb/files/types/form.php | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 6ce54a4789..83007f11c0 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -96,6 +96,7 @@ class filespec * @param \phpbb\filesystem\filesystem_interface $phpbb_filesystem Filesystem * @param language $language Language * @param \bantu\IniGetWrapper\IniGetWrapper $php_ini ini_get() wrapper + * @param \fastImageSize\fastImageSize $imagesize Imagesize class * @param string $phpbb_root_path phpBB root path * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser * @param \phpbb\plupload\plupload $plupload Plupload diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php index 1662e0e920..4cf340ee7d 100644 --- a/phpBB/phpbb/files/types/form.php +++ b/phpBB/phpbb/files/types/form.php @@ -16,7 +16,6 @@ namespace phpbb\files\types; use \bantu\IniGetWrapper\IniGetWrapper; use \phpbb\files\factory; use \phpbb\files\filespec; -use \phpbb\files\upload; use \phpbb\language\language; use \phpbb\plupload\plupload; use \phpbb\request\request_interface; @@ -38,7 +37,7 @@ class form extends base /** @var request_interface */ protected $request; - /** @var upload */ + /** @var \phpbb\files\upload */ protected $upload; /** -- cgit v1.2.1 From 00e5ff9e2e9c0dd7325f33a22888d6888af4b197 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 7 Sep 2015 22:51:44 +0200 Subject: [ticket/13904] Add unit tests for local upload type PHPBB3-13904 --- phpBB/phpbb/files/types/local.php | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/local.php b/phpBB/phpbb/files/types/local.php index 96bfdaca7f..ff11890856 100644 --- a/phpBB/phpbb/files/types/local.php +++ b/phpBB/phpbb/files/types/local.php @@ -84,19 +84,7 @@ class local extends base return $file; } - if (isset($upload['error'])) - { - $error = $this->upload->assign_internal_error($upload['error']); - - if ($error !== false) - { - $file->error[] = $error; - return $file; - } - } - // PHP Upload file size check - $this->check_upload_size($file); $file = $this->check_upload_size($file); if (sizeof($file->error)) { -- cgit v1.2.1 From e60c8a5a8bfa1aa500c096ea90cd32fda9465f9a Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 7 Sep 2015 22:52:20 +0200 Subject: [ticket/13904] Improve code coverage PHPBB3-13904 --- phpBB/phpbb/files/types/remote.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index b5a0dade11..34ee97f1c9 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -235,10 +235,10 @@ class remote extends base { $max_file_size = $this->php_ini->getString('upload_max_filesize'); - if (!empty($max_filesize)) + if (!empty($max_file_size)) { $unit = strtolower(substr($max_file_size, -1, 1)); - $max_file_size = (int) $max_filesize; + $max_file_size = (int) $max_file_size; switch ($unit) { -- cgit v1.2.1 From 327e36a4d68ff9607967af52ef8f6a00c60343ff Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 9 Sep 2015 09:41:40 +0200 Subject: [ticket/13904] Modify files for updated fast-image-size library PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 83007f11c0..e171e7e68f 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -75,7 +75,7 @@ class filespec /** @var \bantu\IniGetWrapper\IniGetWrapper ini_get() wrapper class */ protected $php_ini; - /** @var \fastImageSize\fastImageSize */ + /** @var \FastImageSize\FastImageSize */ protected $imagesize; /** @var language Language class */ @@ -96,12 +96,12 @@ class filespec * @param \phpbb\filesystem\filesystem_interface $phpbb_filesystem Filesystem * @param language $language Language * @param \bantu\IniGetWrapper\IniGetWrapper $php_ini ini_get() wrapper - * @param \fastImageSize\fastImageSize $imagesize Imagesize class + * @param \FastImageSize\FastImageSize $imagesize Imagesize class * @param string $phpbb_root_path phpBB root path * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser * @param \phpbb\plupload\plupload $plupload Plupload */ - public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, \fastImageSize\fastImageSize $imagesize, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + public function __construct(\phpbb\filesystem\filesystem_interface $phpbb_filesystem, language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, \FastImageSize\FastImageSize $imagesize, $phpbb_root_path, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { $this->filesystem = $phpbb_filesystem; $this->language = $language; -- cgit v1.2.1 From 70ad0c6a8f7d16b767aa78cde2acc9a3b3512e6f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 9 Sep 2015 10:43:12 +0200 Subject: [ticket/13904] Add language entries for error messages in upload class PHPBB3-13904 --- phpBB/phpbb/files/upload.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 328dd49a06..bd379924e7 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -245,15 +245,12 @@ class upload break; case UPLOAD_ERR_NO_TMP_DIR: - $error = 'Temporary folder could not be found. Please check your PHP installation.'; - break; - case UPLOAD_ERR_CANT_WRITE: - $error = 'Can’t write to temporary folder.'; + $error = $this->language->lang($this->error_prefix . 'NO_TEMP_DIR'); break; case UPLOAD_ERR_EXTENSION: - $error = 'A PHP extension has stopped the file upload.'; + $error = $this->language->lang($this->error_prefix . 'PHP_UPLOAD_STOPPED'); break; default: -- cgit v1.2.1 From 5f91f1cad85eaf7f8dc62a1a140605a46431496f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 9 Sep 2015 10:46:14 +0200 Subject: [ticket/13904] Minor coding style fixes PHPBB3-13904 --- phpBB/phpbb/files/factory.php | 2 +- phpBB/phpbb/files/filespec.php | 4 +--- phpBB/phpbb/files/types/form.php | 12 ++++++------ phpBB/phpbb/files/types/local.php | 10 +++++----- phpBB/phpbb/files/types/remote.php | 10 +++++----- phpBB/phpbb/files/types/type_interface.php | 2 +- phpBB/phpbb/files/upload.php | 6 +++--- 7 files changed, 22 insertions(+), 24 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/factory.php b/phpBB/phpbb/files/factory.php index 508c50c6ce..84b7cc9449 100644 --- a/phpBB/phpbb/files/factory.php +++ b/phpBB/phpbb/files/factory.php @@ -42,7 +42,7 @@ class factory { $service = false; - $name = (strpos($name, 'files.') === false) ? 'files.' . $name : $name; + $name = (strpos($name, '.') === false) ? 'files.' . $name : $name; try { diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index e171e7e68f..7a42e6bd50 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -13,7 +13,7 @@ namespace phpbb\files; -use \phpbb\language\language; +use phpbb\language\language; /** * Responsible for holding all file relevant information, as well as doing file-specific operations. @@ -201,8 +201,6 @@ class filespec * character. Unique creates a unique filename. * @param string $prefix Prefix applied to filename * @param string $user_id The user_id is only needed for when cleaning a user's avatar - * - *@access public */ public function clean_filename($mode = 'unique', $prefix = '', $user_id = '') { diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php index 4cf340ee7d..832f090c47 100644 --- a/phpBB/phpbb/files/types/form.php +++ b/phpBB/phpbb/files/types/form.php @@ -13,12 +13,12 @@ namespace phpbb\files\types; -use \bantu\IniGetWrapper\IniGetWrapper; -use \phpbb\files\factory; -use \phpbb\files\filespec; -use \phpbb\language\language; -use \phpbb\plupload\plupload; -use \phpbb\request\request_interface; +use bantu\IniGetWrapper\IniGetWrapper; +use phpbb\files\factory; +use phpbb\files\filespec; +use phpbb\language\language; +use phpbb\plupload\plupload; +use phpbb\request\request_interface; class form extends base { diff --git a/phpBB/phpbb/files/types/local.php b/phpBB/phpbb/files/types/local.php index ff11890856..7e9210b196 100644 --- a/phpBB/phpbb/files/types/local.php +++ b/phpBB/phpbb/files/types/local.php @@ -13,11 +13,11 @@ namespace phpbb\files\types; -use \bantu\IniGetWrapper\IniGetWrapper; -use \phpbb\files\factory; -use \phpbb\files\filespec; -use \phpbb\language\language; -use \phpbb\request\request_interface; +use bantu\IniGetWrapper\IniGetWrapper; +use phpbb\files\factory; +use phpbb\files\filespec; +use phpbb\language\language; +use phpbb\request\request_interface; class local extends base { diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 34ee97f1c9..44feab0ece 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -13,11 +13,11 @@ namespace phpbb\files\types; -use \bantu\IniGetWrapper\IniGetWrapper; -use \phpbb\files\factory; -use \phpbb\files\filespec; -use \phpbb\language\language; -use \phpbb\request\request_interface; +use bantu\IniGetWrapper\IniGetWrapper; +use phpbb\files\factory; +use phpbb\files\filespec; +use phpbb\language\language; +use phpbb\request\request_interface; class remote extends base { diff --git a/phpBB/phpbb/files/types/type_interface.php b/phpBB/phpbb/files/types/type_interface.php index adfbb75293..e07078349a 100644 --- a/phpBB/phpbb/files/types/type_interface.php +++ b/phpBB/phpbb/files/types/type_interface.php @@ -13,7 +13,7 @@ namespace phpbb\files\types; -use \phpbb\files\upload; +use phpbb\files\upload; interface type_interface { diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index bd379924e7..45ff1c372f 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -13,9 +13,9 @@ namespace phpbb\files; -use \phpbb\filesystem\filesystem_interface; -use \phpbb\language\language; -use \phpbb\request\request_interface; +use phpbb\filesystem\filesystem_interface; +use phpbb\language\language; +use phpbb\request\request_interface; /** * File upload class -- cgit v1.2.1 From 40e614f56436447dffd272351e23b79c2da9fa3f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 9 Sep 2015 12:58:22 +0200 Subject: [ticket/13904] Fix tests after changes to factory PHPBB3-13904 --- phpBB/phpbb/avatar/driver/upload.php | 4 ++-- phpBB/phpbb/files/upload.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index 2bd23a26a8..a0c23cb624 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -116,7 +116,7 @@ class upload extends \phpbb\avatar\driver\driver if (!empty($upload_file['name'])) { - $file = $upload->handle_upload('form', 'avatar_upload_file'); + $file = $upload->handle_upload('files.types.form', 'avatar_upload_file'); } else if (!empty($this->config['allow_avatar_remote_upload']) && !empty($url)) { @@ -146,7 +146,7 @@ class upload extends \phpbb\avatar\driver\driver return false; } - $file = $upload->handle_upload('remote', $url); + $file = $upload->handle_upload('files.types.remote', $url); } else { diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index 45ff1c372f..e011e714e5 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -197,7 +197,7 @@ class upload { $args = func_get_args(); array_shift($args); - $type_class = $this->factory->get('types.' . $type) + $type_class = $this->factory->get($type) ->set_upload($this); return (is_object($type_class)) ? call_user_func_array(array($type_class, 'upload'), $args) : false; -- cgit v1.2.1 From 8629eac3933a701d0e763b61bca80741bb5b8b82 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 12 Sep 2015 11:15:06 +0200 Subject: [ticket/14158] Add language::lang_array() to avoid using call_user_func_array PHPBB3-14158 --- phpBB/phpbb/language/language.php | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/language/language.php b/phpBB/phpbb/language/language.php index 3ffb466c19..cc89e172df 100644 --- a/phpBB/phpbb/language/language.php +++ b/phpBB/phpbb/language/language.php @@ -238,6 +238,22 @@ class language * @return string Return localized string or the language key if the translation is not available */ public function lang() + { + $args = func_get_args(); + $key = array_shift($args); + + return $this->lang_array($key, $args); + } + + /** + * Act like lang() but takes a key and an array of parameters instead of using variadic + * + * @param string|array $key Language key + * @param array $args Parameters + * + * @return array|string + */ + public function lang_array($key, $args = []) { // Load common language files if they not loaded yet if (!$this->common_language_files_loaded) @@ -245,9 +261,6 @@ class language $this->load_common_language_files(); } - $args = func_get_args(); - $key = $args[0]; - if (is_array($key)) { $lang = &$this->lang[array_shift($key)]; @@ -271,26 +284,25 @@ class language // If the language entry is a string, we simply mimic sprintf() behaviour if (is_string($lang)) { - if (sizeof($args) == 1) + if (count($args) === 0) { return $lang; } // Replace key with language entry and simply pass along... - $args[0] = $lang; - return call_user_func_array('sprintf', $args); + return vsprintf($lang, $args); } else if (sizeof($lang) == 0) { // If the language entry is an empty array, we just return the language key - return $args[0]; + return $key; } // It is an array... now handle different nullar/singular/plural forms $key_found = false; // We now get the first number passed and will select the key based upon this number - for ($i = 1, $num_args = sizeof($args); $i < $num_args; $i++) + for ($i = 0, $num_args = sizeof($args); $i < $num_args; $i++) { if (is_int($args[$i]) || is_float($args[$i])) { @@ -337,8 +349,7 @@ class language } // Use the language string we determined and pass it to sprintf() - $args[0] = $lang[$key_found]; - return call_user_func_array('sprintf', $args); + return vsprintf($lang[$key_found], $args); } /** -- cgit v1.2.1 From 8aa8173ebfcd1f00d26f9a3dde5a7101579f2ed2 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sat, 12 Sep 2015 15:14:42 +0200 Subject: [ticket/14158] Fix 5.3 compatibility PHPBB3-14158 --- phpBB/phpbb/language/language.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/language/language.php b/phpBB/phpbb/language/language.php index cc89e172df..47f055f56a 100644 --- a/phpBB/phpbb/language/language.php +++ b/phpBB/phpbb/language/language.php @@ -253,7 +253,7 @@ class language * * @return array|string */ - public function lang_array($key, $args = []) + public function lang_array($key, $args = array()) { // Load common language files if they not loaded yet if (!$this->common_language_files_loaded) -- cgit v1.2.1 From 759dc9bb84d712c11148a9689d294c09aa0f81d4 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 13 Sep 2015 09:30:56 +0200 Subject: [ticket/13904] Set properties to protected where possible in filespec PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 7a42e6bd50..7fc9e923ea 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -34,10 +34,10 @@ class filespec protected $mimetype = ''; /** @var string File extension */ - public $extension = ''; + protected $extension = ''; /** @var int File size */ - public $filesize = 0; + protected $filesize = 0; /** @var int Width of file */ protected $width = 0; @@ -55,10 +55,10 @@ class filespec protected $destination_path = ''; /** @var bool Whether file was moved */ - public $file_moved = false; + protected $file_moved = false; /** @var bool Whether file is local */ - public $local = false; + protected $local = false; /** @var bool Class initialization flag */ protected $class_initialized = false; -- cgit v1.2.1 From 6651c1d8f4aead15f4750989670f75721390ee21 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 13 Sep 2015 09:31:23 +0200 Subject: [ticket/13904] Use filespec's get_filesize instead of calling filesize() PHPBB3-13904 --- phpBB/phpbb/files/filespec.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 7fc9e923ea..2ff2a92c83 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -145,7 +145,7 @@ class filespec $this->extension = strtolower(self::get_extension($this->realname)); // Try to get real filesize from temporary folder (not always working) ;) - $this->filesize = (@filesize($this->filename)) ? @filesize($this->filename) : $this->filesize; + $this->filesize = ($this->get_filesize($this->filename)) ?: $this->filesize; $this->width = $this->height = 0; $this->file_moved = false; @@ -494,7 +494,7 @@ class filespec } // Try to get real filesize from destination folder - $this->filesize = (@filesize($this->destination_file)) ? @filesize($this->destination_file) : $this->filesize; + $this->filesize = ($this->get_filesize($this->destination_file)) ?: $this->filesize; // Get mimetype of supplied file $this->mimetype = $this->get_mimetype($this->destination_file); -- cgit v1.2.1 From e9013db9b9b392199eb7728ba87afc0bdbdce6f5 Mon Sep 17 00:00:00 2001 From: Zoddo Date: Sun, 13 Sep 2015 22:13:02 +0200 Subject: [ticket/14078] Fix SQL error when editing a post with a quote PHPBB3-14078 --- phpBB/phpbb/notification/type/quote.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 57f77bba83..1cd879579a 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -117,7 +117,7 @@ class quote extends \phpbb\notification\type\post $notifications = array_keys($this->find_users_for_notification($post)); // Find the notifications we must delete - $remove_notifications = array_diff($old_notifications, array_keys($notifications)); + $remove_notifications = array_diff(array_keys($old_notifications), array_keys($notifications)); // Find the notifications we must add $add_notifications = array(); -- cgit v1.2.1 From 25f5e4f18f9aed7272b3f3f9e8647c287b689b29 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 17 Sep 2015 15:36:04 +0200 Subject: [ticket/12577] Lazy initialize the password manager PHPBB3-12577 --- phpBB/phpbb/passwords/manager.php | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php index aa9147ecf4..03729815ba 100644 --- a/phpBB/phpbb/passwords/manager.php +++ b/phpBB/phpbb/passwords/manager.php @@ -49,6 +49,10 @@ class manager */ protected $config; + private $initialized = false; + private $hashing_algorithms; + private $defaults; + /** * Construct a passwords object * @@ -62,9 +66,18 @@ class manager { $this->config = $config; $this->helper = $helper; + $this->hashing_algorithms = $hashing_algorithms; + $this->defaults = $defaults; + } - $this->fill_type_map($hashing_algorithms); - $this->register_default_type($defaults); + protected function initialize() + { + if (!$this->initialized) + { + $this->initialized = true; + $this->fill_type_map($this->hashing_algorithms); + $this->register_default_type($this->defaults); + } } /** @@ -144,6 +157,8 @@ class manager return false; } + $this->initialize(); + // Be on the lookout for multiple hashing algorithms // 2 is correct: H\2a > 2, H\P > 2 if (strlen($match[1]) > 2) @@ -192,6 +207,8 @@ class manager return false; } + $this->initialize(); + // Try to retrieve algorithm by service name if type doesn't // start with dollar sign if (!is_array($type) && strpos($type, '$') !== 0 && isset($this->algorithms[$type])) @@ -242,6 +259,8 @@ class manager return false; } + $this->initialize(); + // First find out what kind of hash we're dealing with $stored_hash_type = $this->detect_algorithm($hash); if ($stored_hash_type == false) @@ -297,6 +316,8 @@ class manager */ public function combined_hash_password($password_hash, $type) { + $this->initialize(); + $data = array( 'prefix' => '$', 'settings' => '$', -- cgit v1.2.1 From 956723af0ed94f79dbbeed2bcfc8617b2c73960e Mon Sep 17 00:00:00 2001 From: Michael Miday Date: Tue, 15 Sep 2015 22:23:24 +0200 Subject: [ticket/12769] Properly include FA --- .../db/migration/data/v320/font_awesome_update.php | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/font_awesome_update.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/font_awesome_update.php b/phpBB/phpbb/db/migration/data/v320/font_awesome_update.php new file mode 100644 index 0000000000..6ffaf18b4a --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/font_awesome_update.php @@ -0,0 +1,29 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class font_awesome_update extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return isset($this->config['load_font_awesome_url']); + } + + public function update_data() + { + return array( + array('config.add', array('load_font_awesome_url', 'https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css')), + ); + } +} -- cgit v1.2.1 From f9f7f935b4fe2742cd84d100be1dc03fd66919ec Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 18 Sep 2015 19:54:06 +0200 Subject: [ticket/12577] Docblock PHPBB3-12577 --- phpBB/phpbb/passwords/manager.php | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php index 03729815ba..b2caba81f2 100644 --- a/phpBB/phpbb/passwords/manager.php +++ b/phpBB/phpbb/passwords/manager.php @@ -49,18 +49,28 @@ class manager */ protected $config; + /** + * @var bool Whether or not initialized() has been called + */ private $initialized = false; + + /** + * @var array Hashing driver service collection + */ private $hashing_algorithms; + + /** + * @var array List of default driver types + */ private $defaults; /** * Construct a passwords object * - * @param \phpbb\config\config $config phpBB configuration - * @param array $hashing_algorithms Hashing driver - * service collection - * @param \phpbb\passwords\helper $helper Passwords helper object - * @param array $defaults List of default driver types + * @param \phpbb\config\config $config phpBB configuration + * @param array $hashing_algorithms Hashing driver service collection + * @param \phpbb\passwords\helper $helper Passwords helper object + * @param array $defaults List of default driver types */ public function __construct(\phpbb\config\config $config, $hashing_algorithms, helper $helper, $defaults) { @@ -70,6 +80,9 @@ class manager $this->defaults = $defaults; } + /** + * Initialize the internal state + */ protected function initialize() { if (!$this->initialized) -- cgit v1.2.1 From 4c004748453babcb8f0a277227c366a71c8c1bc6 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 18 Sep 2015 21:23:34 +0200 Subject: [ticket/12633] Doesn't use DEBUG to debug templates events Check the templates events on runtime only when Twig debug is on PHPBB3-12633 --- phpBB/phpbb/template/twig/node/event.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/node/event.php b/phpBB/phpbb/template/twig/node/event.php index b765bde98d..11fdb75247 100644 --- a/phpBB/phpbb/template/twig/node/event.php +++ b/phpBB/phpbb/template/twig/node/event.php @@ -46,7 +46,7 @@ class event extends \Twig_Node { $ext_namespace = str_replace('/', '_', $ext_namespace); - if (defined('DEBUG')) + if ($this->environment->isDebug()) { // If debug mode is enabled, lets check for new/removed EVENT // templates on page load rather than at compile. This is @@ -58,7 +58,7 @@ class event extends \Twig_Node ; } - if (defined('DEBUG') || $this->environment->getLoader()->exists('@' . $ext_namespace . '/' . $location . '.html')) + if ($this->environment->isDebug() || $this->environment->getLoader()->exists('@' . $ext_namespace . '/' . $location . '.html')) { $compiler ->write("\$previous_look_up_order = \$this->env->getNamespaceLookUpOrder();\n") @@ -70,7 +70,7 @@ class event extends \Twig_Node ; } - if (defined('DEBUG')) + if ($this->environment->isDebug()) { $compiler ->outdent() -- cgit v1.2.1 From 2596fba487a067cba36b5ebe50e1c73e4dc954d3 Mon Sep 17 00:00:00 2001 From: Zoddo Date: Sun, 13 Sep 2015 16:08:22 +0200 Subject: [ticket/14162] Add CLI command db:revert This command allow to revert a migration from the CLI PHPBB3-14162 --- phpBB/phpbb/console/command/db/migrate.php | 37 +--------- .../phpbb/console/command/db/migration_command.php | 56 +++++++++++++++ phpBB/phpbb/console/command/db/revert.php | 83 ++++++++++++++++++++++ phpBB/phpbb/db/migrator.php | 19 +++++ 4 files changed, 160 insertions(+), 35 deletions(-) create mode 100644 phpBB/phpbb/console/command/db/migration_command.php create mode 100644 phpBB/phpbb/console/command/db/revert.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php index 2490bf1310..43029b7458 100644 --- a/phpBB/phpbb/console/command/db/migrate.php +++ b/phpBB/phpbb/console/command/db/migrate.php @@ -15,20 +15,8 @@ namespace phpbb\console\command\db; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -class migrate extends \phpbb\console\command\command +class migrate extends \phpbb\console\command\db\migration_command { - /** @var \phpbb\db\migrator */ - protected $migrator; - - /** @var \phpbb\extension\manager */ - protected $extension_manager; - - /** @var \phpbb\config\config */ - protected $config; - - /** @var \phpbb\cache\service */ - protected $cache; - /** @var \phpbb\log\log */ protected $log; @@ -40,14 +28,10 @@ class migrate extends \phpbb\console\command\command function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) { - $this->migrator = $migrator; - $this->extension_manager = $extension_manager; - $this->config = $config; - $this->cache = $cache; $this->log = $log; $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; - parent::__construct($user); + parent::__construct($user, $migrator, $extension_manager, $config, $cache); $this->user->add_lang(array('common', 'install', 'migrator')); } @@ -91,21 +75,4 @@ class migrate extends \phpbb\console\command\command $this->finalise_update(); $output->writeln($this->user->lang['DATABASE_UPDATE_COMPLETE']); } - - protected function load_migrations() - { - $migrations = $this->extension_manager - ->get_finder() - ->core_path('phpbb/db/migration/data/') - ->extension_directory('/migrations') - ->get_classes(); - - $this->migrator->set_migrations($migrations); - } - - protected function finalise_update() - { - $this->cache->purge(); - $this->config->increment('assets_version', 1); - } } diff --git a/phpBB/phpbb/console/command/db/migration_command.php b/phpBB/phpbb/console/command/db/migration_command.php new file mode 100644 index 0000000000..d44ef8c5cb --- /dev/null +++ b/phpBB/phpbb/console/command/db/migration_command.php @@ -0,0 +1,56 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ +namespace phpbb\console\command\db; + +abstract class migration_command extends \phpbb\console\command\command +{ + /** @var \phpbb\db\migrator */ + protected $migrator; + + /** @var \phpbb\extension\manager */ + protected $extension_manager; + + /** @var \phpbb\config\config */ + protected $config; + + /** @var \phpbb\cache\service */ + protected $cache; + + function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache) + { + $this->migrator = $migrator; + $this->extension_manager = $extension_manager; + $this->config = $config; + $this->cache = $cache; + parent::__construct($user); + } + + protected function load_migrations() + { + $migrations = $this->extension_manager + ->get_finder() + ->core_path('phpbb/db/migration/data/') + ->extension_directory('/migrations') + ->get_classes(); + + $this->migrator->set_migrations($migrations); + + return $migrations; + } + + protected function finalise_update() + { + $this->cache->purge(); + $this->config->increment('assets_version', 1); + } +} diff --git a/phpBB/phpbb/console/command/db/revert.php b/phpBB/phpbb/console/command/db/revert.php new file mode 100644 index 0000000000..838640968e --- /dev/null +++ b/phpBB/phpbb/console/command/db/revert.php @@ -0,0 +1,83 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ +namespace phpbb\console\command\db; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class revert extends \phpbb\console\command\db\migration_command +{ + /** @var string phpBB root path */ + protected $phpbb_root_path; + + /** @var \phpbb\filesystem\filesystem_interface */ + protected $filesystem; + + function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) + { + $this->filesystem = $filesystem; + $this->phpbb_root_path = $phpbb_root_path; + parent::__construct($user, $migrator, $extension_manager, $config, $cache); + $this->user->add_lang(array('common', 'migrator')); + } + + protected function configure() + { + $this + ->setName('db:revert') + ->setDescription($this->user->lang('CLI_DESCRIPTION_DB_REVERT')) + ->addArgument( + 'name', + InputArgument::REQUIRED, + $this->user->lang('CLI_MIGRATION_NAME') + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $name = str_replace('/', '\\', $input->getArgument('name')); + + $this->migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($this->user, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem)); + + $this->cache->purge(); + + if (!in_array($name, $this->load_migrations())) + { + $output->writeln('' . $this->user->lang('MIGRATION_NOT_VALID', $name) . ''); + return 1; + } + else if ($this->migrator->migration_state($name) === false) + { + $output->writeln('' . $this->user->lang('MIGRATION_NOT_INSTALLED', $name) . ''); + return 1; + } + + try + { + while ($this->migrator->migration_state($name) !== false) + { + $this->migrator->revert($name); + } + } + catch (\phpbb\db\migration\exception $e) + { + $output->writeln('' . $e->getLocalisedMessage($this->user) . ''); + $this->finalise_update(); + return 1; + } + + $this->finalise_update(); + } +} diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 6902913c64..18c6403c07 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -416,6 +416,9 @@ class migrator if ($state['migration_data_done']) { + $this->output_handler->write(array('MIGRATION_REVERT_DATA_RUNNING', $name), migrator_output_handler_interface::VERBOSITY_VERBOSE); + $elapsed_time = microtime(true); + if ($state['migration_data_state'] !== 'revert_data') { $result = $this->process_data_step($migration->update_data(), $state['migration_data_state'], true); @@ -431,9 +434,22 @@ class migrator } $this->set_migration_state($name, $state); + + $elapsed_time = microtime(true) - $elapsed_time; + if ($state['migration_data_done']) + { + $this->output_handler->write(array('MIGRATION_REVERT_DATA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL); + } + else + { + $this->output_handler->write(array('MIGRATION_REVERT_DATA_IN_PROGRESS', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_VERY_VERBOSE); + } } else if ($state['migration_schema_done']) { + $this->output_handler->write(array('MIGRATION_REVERT_SCHEMA_RUNNING', $name), migrator_output_handler_interface::VERBOSITY_VERBOSE); + $elapsed_time = microtime(true); + $steps = $this->helper->get_schema_steps($migration->revert_schema()); $result = $this->process_data_step($steps, $state['migration_data_state']); @@ -448,6 +464,9 @@ class migrator unset($this->migration_state[$name]); } + + $elapsed_time = microtime(true) - $elapsed_time; + $this->output_handler->write(array('MIGRATION_REVERT_SCHEMA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL); } return true; -- cgit v1.2.1 From 60099cf97c13106b741ab779883a89a0dbc4b6fa Mon Sep 17 00:00:00 2001 From: Zoddo Date: Sun, 13 Sep 2015 17:15:35 +0200 Subject: [ticket/14162] Add CLI command db:list This command lists all installed and uninstalled migrations. Note: The class is named `list_command`, because `list` is a reserved word and can't be used as class name in PHP. PHPBB3-14162 --- phpBB/phpbb/console/command/db/list_command.php | 73 +++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 phpBB/phpbb/console/command/db/list_command.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/db/list_command.php b/phpBB/phpbb/console/command/db/list_command.php new file mode 100644 index 0000000000..708107b592 --- /dev/null +++ b/phpBB/phpbb/console/command/db/list_command.php @@ -0,0 +1,73 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ +namespace phpbb\console\command\db; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class list_command extends \phpbb\console\command\db\migration_command +{ + protected function configure() + { + $this + ->setName('db:list') + ->setDescription($this->user->lang('CLI_DESCRIPTION_DB_LIST')) + ->addOption( + 'available', + 'u', + InputOption::VALUE_NONE, + $this->user->lang('CLI_MIGRATIONS_ONLY_AVAILABLE') + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $show_installed = !$input->getOption('available'); + $installed = $available = array(); + + foreach ($this->load_migrations() as $name) + { + if ($this->migrator->migration_state($name) !== false) + { + $installed[] = $name; + } + else + { + $available[] = $name; + } + } + + if ($show_installed) + { + $output->writeln('' . $this->user->lang('CLI_MIGRATIONS_INSTALLED') . $this->user->lang('COLON') . ''); + $output->writeln($installed); + + if (empty($installed)) + { + $output->writeln($this->user->lang('CLI_MIGRATIONS_EMPTY')); + } + + $output->writeln(''); + } + + $output->writeln('' . $this->user->lang('CLI_MIGRATIONS_AVAILABLE') . $this->user->lang('COLON') . ''); + $output->writeln($available); + + if (empty($available)) + { + $output->writeln($this->user->lang('CLI_MIGRATIONS_EMPTY')); + } + } +} -- cgit v1.2.1 From a7ba640ea778bf1936a035952f99b78497feef22 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 21 Sep 2015 10:46:48 +0200 Subject: [ticket/14182] Move v310\notifications_board migration to v320\... PHPBB3-14182 --- .../db/migration/data/v310/notifications_board.php | 73 ---------------------- .../db/migration/data/v320/notifications_board.php | 73 ++++++++++++++++++++++ 2 files changed, 73 insertions(+), 73 deletions(-) delete mode 100644 phpBB/phpbb/db/migration/data/v310/notifications_board.php create mode 100644 phpBB/phpbb/db/migration/data/v320/notifications_board.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v310/notifications_board.php b/phpBB/phpbb/db/migration/data/v310/notifications_board.php deleted file mode 100644 index 525d94e984..0000000000 --- a/phpBB/phpbb/db/migration/data/v310/notifications_board.php +++ /dev/null @@ -1,73 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\db\migration\data\v310; - -class notifications_board extends \phpbb\db\migration\migration -{ - static public function depends_on() - { - return array('\phpbb\db\migration\data\v310\notifications'); - } - - public function update_data() - { - return array( - array('config.add', array('allow_board_notifications', 1)), - array('custom', array(array($this, 'update_user_subscriptions'))), - array('custom', array(array($this, 'update_module'))), - ); - } - - public function update_module() - { - $sql = 'UPDATE ' . MODULES_TABLE . " - SET auth = 'cfg_allow_board_notifications' - WHERE module_basename = 'ucp_notifications' - AND module_mode = 'notification_list'"; - $this->sql_query($sql); - } - - public function update_user_subscriptions() - { - $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . " - SET method = 'notification.method.board' - WHERE method = ''"; - $this->sql_query($sql); - } - - public function revert_data() - { - return array( - array('custom', array(array($this, 'revert_user_subscriptions'))), - array('custom', array(array($this, 'revert_module'))), - ); - } - - public function revert_user_subscriptions() - { - $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . " - SET method = '' - WHERE method = 'notification.method.board'"; - $this->sql_query($sql); - } - - public function revert_module() - { - $sql = 'UPDATE ' . MODULES_TABLE . " - SET auth = '' - WHERE module_basename = 'ucp_notifications' - AND module_mode = 'notification_list'"; - $this->sql_query($sql); - } -} diff --git a/phpBB/phpbb/db/migration/data/v320/notifications_board.php b/phpBB/phpbb/db/migration/data/v320/notifications_board.php new file mode 100644 index 0000000000..fd9f1a2ad6 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/notifications_board.php @@ -0,0 +1,73 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class notifications_board extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\notifications'); + } + + public function update_data() + { + return array( + array('config.add', array('allow_board_notifications', 1)), + array('custom', array(array($this, 'update_user_subscriptions'))), + array('custom', array(array($this, 'update_module'))), + ); + } + + public function update_module() + { + $sql = 'UPDATE ' . MODULES_TABLE . " + SET auth = 'cfg_allow_board_notifications' + WHERE module_basename = 'ucp_notifications' + AND module_mode = 'notification_list'"; + $this->sql_query($sql); + } + + public function update_user_subscriptions() + { + $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . " + SET method = 'notification.method.board' + WHERE method = ''"; + $this->sql_query($sql); + } + + public function revert_data() + { + return array( + array('custom', array(array($this, 'revert_user_subscriptions'))), + array('custom', array(array($this, 'revert_module'))), + ); + } + + public function revert_user_subscriptions() + { + $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . " + SET method = '' + WHERE method = 'notification.method.board'"; + $this->sql_query($sql); + } + + public function revert_module() + { + $sql = 'UPDATE ' . MODULES_TABLE . " + SET auth = '' + WHERE module_basename = 'ucp_notifications' + AND module_mode = 'notification_list'"; + $this->sql_query($sql); + } +} -- cgit v1.2.1 From f3dc2a801d7e077e5e10a143b8d450b0b4a3aa11 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 28 Sep 2015 17:40:24 +0200 Subject: [ticket/14205] Bump PHP requirement to PHP 5.4 PHPBB3-14205 --- phpBB/phpbb/composer.json | 2 +- .../phpbb/install/module/requirements/task/check_server_environment.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/composer.json b/phpBB/phpbb/composer.json index 175be4b0ab..8241091dc1 100644 --- a/phpBB/phpbb/composer.json +++ b/phpBB/phpbb/composer.json @@ -22,6 +22,6 @@ "classmap": [""] }, "require": { - "php": ">=5.3.9" + "php": ">=5.4" } } diff --git a/phpBB/phpbb/install/module/requirements/task/check_server_environment.php b/phpBB/phpbb/install/module/requirements/task/check_server_environment.php index 50efdc55a2..62485a2097 100644 --- a/phpBB/phpbb/install/module/requirements/task/check_server_environment.php +++ b/phpBB/phpbb/install/module/requirements/task/check_server_environment.php @@ -95,7 +95,7 @@ class check_server_environment extends \phpbb\install\task_base { $php_version = PHP_VERSION; - if (version_compare($php_version, '5.3.9') < 0) + if (version_compare($php_version, '5.4') < 0) { $this->response_helper->add_error_message('PHP_VERSION_REQD', 'PHP_VERSION_REQD_EXPLAIN'); -- cgit v1.2.1 From 403c647b9e84640977ca0f98d21d15ceb4957bdb Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 7 Oct 2015 23:09:13 +0200 Subject: [ticket/14220] Move route loading to services PHPBB3-14220 --- phpBB/phpbb/routing/file_locator.php | 33 ++ phpBB/phpbb/routing/loader_resolver.php | 49 +++ .../chained_resources_locator.php | 47 +++ .../default_resources_locator.php | 105 +++++++ .../resources_locator_interface.php | 27 ++ phpBB/phpbb/routing/router.php | 346 +++++++++------------ 6 files changed, 407 insertions(+), 200 deletions(-) create mode 100644 phpBB/phpbb/routing/file_locator.php create mode 100644 phpBB/phpbb/routing/loader_resolver.php create mode 100644 phpBB/phpbb/routing/resources_locator/chained_resources_locator.php create mode 100644 phpBB/phpbb/routing/resources_locator/default_resources_locator.php create mode 100644 phpBB/phpbb/routing/resources_locator/resources_locator_interface.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/file_locator.php b/phpBB/phpbb/routing/file_locator.php new file mode 100644 index 0000000000..64efcc6c76 --- /dev/null +++ b/phpBB/phpbb/routing/file_locator.php @@ -0,0 +1,33 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\routing; + +use phpbb\filesystem\filesystem_interface; +use Symfony\Component\Config\FileLocator; + +class file_locator extends FileLocator +{ + public function __construct(filesystem_interface $filesystem, $paths = []) + { + $paths = (array) $paths; + $absolute_paths = []; + + foreach ($paths as $path) + { + $absolute_paths[] = $filesystem->realpath($path); + } + + parent::__construct($absolute_paths); + } +} diff --git a/phpBB/phpbb/routing/loader_resolver.php b/phpBB/phpbb/routing/loader_resolver.php new file mode 100644 index 0000000000..e335051444 --- /dev/null +++ b/phpBB/phpbb/routing/loader_resolver.php @@ -0,0 +1,49 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\routing; + +use Symfony\Component\Config\Loader\LoaderResolverInterface; + +/** + * @see Symfony\Component\Config\Loader\LoaderResolver + */ +class loader_resolver implements LoaderResolverInterface +{ + /** + * @var \Symfony\Component\Config\Loader\LoaderInterface[] An array of LoaderInterface objects + */ + protected $loaders = []; + + public function __construct($loaders = []) + { + $this->loaders = $loaders; + } + + /** + * {@inheritdoc} + */ + public function resolve($resource, $type = null) + { + /** @var \Symfony\Component\Config\Loader\LoaderInterface $loader */ + foreach ($this->loaders as $loader) + { + if ($loader->supports($resource, $type)) + { + return $loader; + } + } + + return false; + } +} diff --git a/phpBB/phpbb/routing/resources_locator/chained_resources_locator.php b/phpBB/phpbb/routing/resources_locator/chained_resources_locator.php new file mode 100644 index 0000000000..db9abf2095 --- /dev/null +++ b/phpBB/phpbb/routing/resources_locator/chained_resources_locator.php @@ -0,0 +1,47 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\routing\resources_locator; + +class chained_resources_locator implements resources_locator_interface +{ + /** + * @var resources_locator_interface[] + */ + protected $locators; + + /** + * Construct method + * + * @param resources_locator_interface[] $locators Locators + */ + public function __construct($locators) + { + $this->locators = $locators; + } + + /** + * {@inheritdoc} + */ + public function locate_resources() + { + $resources = []; + + foreach ($this->locators as $locator) + { + $resources = array_merge($resources, $locator->locate_resources()); + } + + return $resources; + } +} diff --git a/phpBB/phpbb/routing/resources_locator/default_resources_locator.php b/phpBB/phpbb/routing/resources_locator/default_resources_locator.php new file mode 100644 index 0000000000..90c3877007 --- /dev/null +++ b/phpBB/phpbb/routing/resources_locator/default_resources_locator.php @@ -0,0 +1,105 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\routing\resources_locator; + +use phpbb\extension\manager; + +/** + * Locates the yaml routing resources located in the default locations + */ +class default_resources_locator implements resources_locator_interface +{ + /** + * phpBB root path + * + * @var string + */ + protected $phpbb_root_path; + + /** + * Name of the current environment + * + * @var string + */ + protected $environment; + + /** + * Extension manager + * + * @var manager + */ + protected $extension_manager; + + /** + * Construct method + * + * @param string $phpbb_root_path phpBB root path + * @param string $environment Name of the current environment + * @param manager $extension_manager Extension manager + */ + public function __construct($phpbb_root_path, $environment, manager $extension_manager = null) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->environment = $environment; + $this->extension_manager = $extension_manager; + } + + /** + * {@inheritdoc} + */ + public function locate_resources() + { + $resources = [['config/' . $this->environment . '/routing/environment.yml', 'yaml']]; + + $resources = $this->append_ext_resources($resources); + + return $resources; + } + + /** + * Append extension resources to an array of resouces + * + * @see resources_locator_interface::locate_resources() + * + * @param mixed[] $resources List of resources + * + * @return mixed[] List of resources + */ + protected function append_ext_resources(array $resources) + { + if ($this->extension_manager !== null) + { + foreach ($this->extension_manager->all_enabled(false) as $path) + { + if (file_exists($this->phpbb_root_path . $path . 'config/' . $this->environment . '/routing/environment.yml')) + { + $resources[] = [$path . 'config/' . $this->environment . '/routing/environment.yml', 'yaml']; + } + else if (!is_dir($this->phpbb_root_path . $path . 'config/' . $this->environment)) + { + if (file_exists($this->phpbb_root_path . $path . 'config/default/routing/environment.yml')) + { + $resources[] = [$path . 'config/default/routing/environment.yml', 'yaml']; + } + else if (!is_dir($this->phpbb_root_path . $path . 'config/default/routing') && file_exists($this->phpbb_root_path . $path . 'config/routing.yml')) + { + $resources[] = [$path . 'config/routing.yml', 'yaml']; + } + } + } + } + + return $resources; + } +} diff --git a/phpBB/phpbb/routing/resources_locator/resources_locator_interface.php b/phpBB/phpbb/routing/resources_locator/resources_locator_interface.php new file mode 100644 index 0000000000..46335cb288 --- /dev/null +++ b/phpBB/phpbb/routing/resources_locator/resources_locator_interface.php @@ -0,0 +1,27 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\routing\resources_locator; + +interface resources_locator_interface +{ + /** + * Locates a list of resources used to load the routes + * + * Each entry of the list can be either the resource or an array composed of 2 elements: + * the resource and its type. + * + * @return mixed[] List of resources + */ + public function locate_resources(); +} diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 5af005769f..5d237b6433 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -13,21 +13,20 @@ namespace phpbb\routing; +use phpbb\routing\resources_locator\resources_locator_interface; use Symfony\Component\Config\ConfigCache; -use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; use Symfony\Component\DependencyInjection\Exception\RuntimeException; -use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; +use Symfony\Component\Filesystem\Exception\IOException; use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper; -use Symfony\Component\Routing\Matcher\UrlMatcher; use Symfony\Component\Routing\Generator\UrlGenerator; +use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; +use Symfony\Component\Routing\Matcher\UrlMatcher; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouterInterface; -use Symfony\Component\Routing\Loader\YamlFileLoader; -use Symfony\Component\Config\FileLocator; -use phpbb\extension\manager; /** * Integration of all pieces of the routing system for easier use. @@ -35,11 +34,19 @@ use phpbb\extension\manager; class router implements RouterInterface { /** - * Extension manager - * - * @var manager + * @var ContainerInterface */ - protected $extension_manager; + protected $container; + + /** + * @var resources_locator_interface + */ + protected $resources_locator; + + /** + * @var LoaderInterface + */ + protected $loader; /** * phpBB root path @@ -62,13 +69,6 @@ class router implements RouterInterface */ protected $environment; - /** - * YAML file(s) containing route information - * - * @var array - */ - protected $routing_files; - /** * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|null */ @@ -85,37 +85,25 @@ class router implements RouterInterface protected $context; /** - * @var RouteCollection|null + * @var RouteCollection */ protected $route_collection; - /** - * @var \phpbb\filesystem\filesystem_interface - */ - protected $filesystem; - - /** - * @var ContainerInterface - */ - protected $container; - /** * Construct method * - * @param ContainerInterface $container DI container - * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem helper - * @param string $phpbb_root_path phpBB root path - * @param string $php_ext PHP file extension - * @param string $environment Name of the current environment - * @param manager $extension_manager Extension manager - * @param array $routing_files Array of strings containing paths to YAML files holding route information + * @param ContainerInterface $container DI container + * @param resources_locator_interface $resources_locator Resources locator + * @param LoaderInterface $loader Resources loader + * @param string $phpbb_root_path phpBB root path + * @param string $php_ext PHP file extension + * @param string $environment Name of the current environment */ - public function __construct(ContainerInterface $container, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path, $php_ext, $environment, manager $extension_manager = null, $routing_files = array()) + public function __construct(ContainerInterface $container, resources_locator_interface $resources_locator, LoaderInterface $loader, $phpbb_root_path, $php_ext, $environment) { $this->container = $container; - $this->filesystem = $filesystem; - $this->extension_manager = $extension_manager; - $this->routing_files = $routing_files; + $this->resources_locator = $resources_locator; + $this->loader = $loader; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; $this->environment = $environment; @@ -123,178 +111,28 @@ class router implements RouterInterface } /** - * Find the list of routing files + * Get the list of routes * - * @param array $paths Array of paths where to look for routing files (they must be relative to the phpBB root path). - * @return router + * @return RouteCollection Get the route collection */ - public function find_routing_files(array $paths) + public function get_routes() { - $this->routing_files = array('config/' . $this->environment . '/routing/environment.yml'); - foreach ($paths as $path) + if ($this->route_collection === null /*|| $this->route_collection->count() === 0*/) { - if (file_exists($this->phpbb_root_path . $path . 'config/' . $this->environment . '/routing/environment.yml')) - { - $this->routing_files[] = $path . 'config/' . $this->environment . '/routing/environment.yml'; - } - else if (!is_dir($this->phpbb_root_path . $path . 'config/' . $this->environment)) + $this->route_collection = new RouteCollection; + foreach ($this->resources_locator->locate_resources() as $resource) { - if (file_exists($this->phpbb_root_path . $path . 'config/default/routing/environment.yml')) + if (is_array($resource)) { - $this->routing_files[] = $path . 'config/default/routing/environment.yml'; + $this->route_collection->addCollection($this->loader->load($resource[0], $resource[1])); } - else if (!is_dir($this->phpbb_root_path . $path . 'config/default/routing') && file_exists($this->phpbb_root_path . $path . 'config/routing.yml')) + else { - $this->routing_files[] = $path . 'config/routing.yml'; + $this->route_collection->addCollection($this->loader->load($resource)); } } - } - return $this; - } - - /** - * Find a list of controllers - * - * @param string $base_path Base path to prepend to file paths - * @return router - */ - public function find($base_path = '') - { - if ($this->route_collection === null || $this->route_collection->count() === 0) - { - $this->route_collection = new RouteCollection; - foreach ($this->routing_files as $file_path) - { - $loader = new YamlFileLoader(new FileLocator($this->filesystem->realpath($base_path))); - $this->route_collection->addCollection($loader->load($file_path)); - } - } - - $this->resolveParameters($this->route_collection); - - return $this; - } - - /** - * Replaces placeholders with service container parameter values in: - * - the route defaults, - * - the route requirements, - * - the route path, - * - the route host, - * - the route schemes, - * - the route methods. - * - * @param RouteCollection $collection - */ - private function resolveParameters(RouteCollection $collection) - { - foreach ($collection as $route) - { - foreach ($route->getDefaults() as $name => $value) - { - $route->setDefault($name, $this->resolve($value)); - } - - $requirements = $route->getRequirements(); - unset($requirements['_scheme']); - unset($requirements['_method']); - - foreach ($requirements as $name => $value) - { - $route->setRequirement($name, $this->resolve($value)); - } - - $route->setPath($this->resolve($route->getPath())); - $route->setHost($this->resolve($route->getHost())); - - $schemes = array(); - foreach ($route->getSchemes() as $scheme) - { - $schemes = array_merge($schemes, explode('|', $this->resolve($scheme))); - } - - $route->setSchemes($schemes); - $methods = array(); - foreach ($route->getMethods() as $method) - { - $methods = array_merge($methods, explode('|', $this->resolve($method))); - } - - $route->setMethods($methods); - $route->setCondition($this->resolve($route->getCondition())); - } - } - - /** - * Recursively replaces placeholders with the service container parameters. - * - * @param mixed $value The source which might contain "%placeholders%" - * - * @return mixed The source with the placeholders replaced by the container - * parameters. Arrays are resolved recursively. - * - * @throws ParameterNotFoundException When a placeholder does not exist as a container parameter - * @throws RuntimeException When a container value is not a string or a numeric value - */ - private function resolve($value) - { - if (is_array($value)) - { - foreach ($value as $key => $val) - { - $value[$key] = $this->resolve($val); - } - - return $value; - } - - if (!is_string($value)) - { - return $value; - } - - $container = $this->container; - $escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($container, $value) - { - // skip %% - if (!isset($match[1])) - { - return '%%'; - } - - $resolved = $container->getParameter($match[1]); - if (is_string($resolved) || is_numeric($resolved)) - { - return (string) $resolved; - } - - throw new RuntimeException(sprintf( - 'The container parameter "%s", used in the route configuration value "%s", '. - 'must be a string or numeric, but it is of type %s.', - $match[1], - $value, - gettype($resolved) - ) - ); - }, $value); - - return str_replace('%%', '%', $escapedValue); - } - - /** - * Get the list of routes - * - * @return RouteCollection Get the route collection - */ - public function get_routes() - { - if ($this->route_collection == null || empty($this->routing_files)) - { - $this->find_routing_files( - ($this->extension_manager !== null) ? $this->extension_manager->all_enabled(false) : array() - ) - ->find($this->phpbb_root_path); + $this->resolveParameters($this->route_collection); } return $this->route_collection; @@ -365,6 +203,7 @@ class router implements RouterInterface return $this->matcher; } + /** * Creates a new dumped URL Matcher (dump it if necessary) */ @@ -457,4 +296,111 @@ class router implements RouterInterface { $this->generator = new UrlGenerator($this->get_routes(), $this->context); } + + /** + * Replaces placeholders with service container parameter values in: + * - the route defaults, + * - the route requirements, + * - the route path, + * - the route host, + * - the route schemes, + * - the route methods. + * + * @param RouteCollection $collection + */ + protected function resolveParameters(RouteCollection $collection) + { + /** @var \Symfony\Component\Routing\Route $route */ + foreach ($collection as $route) + { + foreach ($route->getDefaults() as $name => $value) + { + $route->setDefault($name, $this->resolve($value)); + } + + $requirements = $route->getRequirements(); + unset($requirements['_scheme']); + unset($requirements['_method']); + + foreach ($requirements as $name => $value) + { + $route->setRequirement($name, $this->resolve($value)); + } + + $route->setPath($this->resolve($route->getPath())); + $route->setHost($this->resolve($route->getHost())); + + $schemes = array(); + foreach ($route->getSchemes() as $scheme) + { + $schemes = array_merge($schemes, explode('|', $this->resolve($scheme))); + } + + $route->setSchemes($schemes); + $methods = array(); + foreach ($route->getMethods() as $method) + { + $methods = array_merge($methods, explode('|', $this->resolve($method))); + } + + $route->setMethods($methods); + $route->setCondition($this->resolve($route->getCondition())); + } + } + + /** + * Recursively replaces placeholders with the service container parameters. + * + * @param mixed $value The source which might contain "%placeholders%" + * + * @return mixed The source with the placeholders replaced by the container + * parameters. Arrays are resolved recursively. + * + * @throws ParameterNotFoundException When a placeholder does not exist as a container parameter + * @throws RuntimeException When a container value is not a string or a numeric value + */ + private function resolve($value) + { + if (is_array($value)) + { + foreach ($value as $key => $val) + { + $value[$key] = $this->resolve($val); + } + + return $value; + } + + if (!is_string($value)) + { + return $value; + } + + $container = $this->container; + $escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($container, $value) + { + // skip %% + if (!isset($match[1])) + { + return '%%'; + } + + $resolved = $container->getParameter($match[1]); + if (is_string($resolved) || is_numeric($resolved)) + { + return (string) $resolved; + } + + throw new RuntimeException(sprintf( + 'The container parameter "%s", used in the route configuration value "%s", '. + 'must be a string or numeric, but it is of type %s.', + $match[1], + $value, + gettype($resolved) + ) + ); + }, $value); + + return str_replace('%%', '%', $escapedValue); + } } -- cgit v1.2.1 From 0799a4808d82c3deafc4d9b74dc777b88ee9862f Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 8 Oct 2015 23:16:40 +0200 Subject: [ticket/14225] Inject the loader resolver when using the delegating loader PHPBB3-14225 --- phpBB/phpbb/routing/loader_resolver.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/loader_resolver.php b/phpBB/phpbb/routing/loader_resolver.php index e335051444..13fbc6405c 100644 --- a/phpBB/phpbb/routing/loader_resolver.php +++ b/phpBB/phpbb/routing/loader_resolver.php @@ -40,6 +40,7 @@ class loader_resolver implements LoaderResolverInterface { if ($loader->supports($resource, $type)) { + $loader->setResolver($this); return $loader; } } -- cgit v1.2.1 From e50718008a44953181e133de1e37304ed6a5994f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 19 Sep 2015 16:39:17 +0200 Subject: [ticket/14168] Add attachment upload class PHPBB3-14168 --- phpBB/phpbb/attachment/upload.php | 261 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 phpBB/phpbb/attachment/upload.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php new file mode 100644 index 0000000000..a175dee0b3 --- /dev/null +++ b/phpBB/phpbb/attachment/upload.php @@ -0,0 +1,261 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\attachment; + +use phpbb\auth\auth; +use \phpbb\cache\service; +use \phpbb\config\config; +use \phpbb\event\dispatcher; +use \phpbb\language\language; +use \phpbb\mimetype\guesser; +use \phpbb\plupload\plupload; +use \phpbb\user; + +/** + * Attachment upload class + */ + +class upload +{ + /** @var auth */ + protected $auth; + + /** @var service */ + protected $cache; + + /** @var config */ + protected $config; + + /** @var \phpbb\files\upload Upload class */ + protected $files_upload; + + /** @var \phpbb\language\language */ + protected $language; + + /** @var guesser Mimetype guesser */ + protected $mimetype_guesser; + + /** @var dispatcher */ + protected $phpbb_dispatcher; + + /** @var plupload Plupload */ + protected $plupload; + + /** @var user */ + protected $user; + + /** + * Constructor for attachments upload class + * + * @param auth $auth + * @param service $cache + * @param config $config + * @param \phpbb\files\upload $files_upload + * @param language $language + * @param guesser $mimetype_guesser + * @param dispatcher $phpbb_dispatcher + * @param plupload $plupload + * @param user $user + * @param $phpbb_root_path + */ + public function __construct(auth $auth, service $cache, config $config, \phpbb\files\upload $files_upload, language $language, guesser $mimetype_guesser, dispatcher $phpbb_dispatcher, plupload $plupload, user $user, $phpbb_root_path) + { + $this->auth = $auth; + $this->cache = $cache; + $this->config = $config; + $this->files_upload = $files_upload; + $this->language = $language; + $this->mimetype_guesser = $mimetype_guesser; + $this->phpbb_dispatcher = $phpbb_dispatcher; + $this->plupload = $plupload; + $this->user = $user; + $this->phpbb_root_path = $phpbb_root_path; + } + + /** + * Upload Attachment - filedata is generated here + * Uses upload class + * + * @param string $form_name The form name of the file upload input + * @param int $forum_id The id of the forum + * @param bool $local Whether the file is local or not + * @param string $local_storage The path to the local file + * @param bool $is_message Whether it is a PM or not + * @param array $local_filedata An file data object created for the local file + * + * @return object filespec + */ + public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false) + { + $filedata = array( + 'error' => array() + ); + + if ($this->config['check_attachment_content'] && isset($this->config['mime_triggers'])) + { + $this->files_upload->set_disallowed_content(explode('|', $this->config['mime_triggers'])); + } + else if (!$this->config['check_attachment_content']) + { + $this->files_upload->set_disallowed_content(array()); + } + + $filedata['post_attach'] = $local || $this->files_upload->is_valid($form_name); + + if (!$filedata['post_attach']) + { + $filedata['error'][] = $this->user->lang['NO_UPLOAD_FORM_FOUND']; + return $filedata; + } + + $extensions = $this->cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id)); + $this->files_upload->set_allowed_extensions(array_keys($extensions['_allowed_'])); + + /** @var \phpbb\files\filespec $file */ + $file = ($local) ? $this->files_upload->handle_upload('files.types.local', $local_storage, $local_filedata) : $this->files_upload->handle_upload('files.types.form', $form_name); + + if ($file->init_error()) + { + $filedata['post_attach'] = false; + return $filedata; + } + + // Whether the uploaded file is in the image category + $is_image = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false; + + if (!$this->auth->acl_get('a_') && !$this->auth->acl_get('m_', $forum_id)) + { + // Check Image Size, if it is an image + if ($is_image) + { + $file->upload->set_allowed_dimensions(0, 0, $this->config['img_max_width'], $this->config['img_max_height']); + } + + // Admins and mods are allowed to exceed the allowed filesize + if (!empty($extensions[$file->get('extension')]['max_filesize'])) + { + $allowed_filesize = $extensions[$file->get('extension')]['max_filesize']; + } + else + { + $allowed_filesize = ($is_message) ? $this->config['max_filesize_pm'] : $this->config['max_filesize']; + } + + $file->upload->set_max_filesize($allowed_filesize); + } + + $file->clean_filename('unique', $this->user->data['user_id'] . '_'); + + // Are we uploading an image *and* this image being within the image category? + // Only then perform additional image checks. + $file->move_file($this->config['upload_path'], false, !$is_image); + + // Do we have to create a thumbnail? + $filedata['thumbnail'] = ($is_image && $this->config['img_create_thumbnail']) ? 1 : 0; + + if (sizeof($file->error)) + { + $file->remove(); + $filedata['error'] = array_merge($filedata['error'], $file->error); + $filedata['post_attach'] = false; + + return $filedata; + } + + // Make sure the image category only holds valid images... + if ($is_image && !$file->is_image()) + { + $file->remove(); + + if ($this->plupload && $this->plupload->is_active()) + { + $this->plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE'); + } + + // If this error occurs a user tried to exploit an IE Bug by renaming extensions + // Since the image category is displaying content inline we need to catch this. + trigger_error($this->user->lang['ATTACHED_IMAGE_NOT_IMAGE']); + } + + $filedata['filesize'] = $file->get('filesize'); + $filedata['mimetype'] = $file->get('mimetype'); + $filedata['extension'] = $file->get('extension'); + $filedata['physical_filename'] = $file->get('realname'); + $filedata['real_filename'] = $file->get('uploadname'); + $filedata['filetime'] = time(); + + /** + * Event to modify uploaded file before submit to the post + * + * @event core.modify_uploaded_file + * @var array filedata Array containing uploaded file data + * @var bool is_image Flag indicating if the file is an image + * @since 3.1.0-RC3 + */ + $vars = array( + 'filedata', + 'is_image', + ); + extract($this->phpbb_dispatcher->trigger_event('core.modify_uploaded_file', compact($vars))); + + // Check our complete quota + if ($this->config['attachment_quota']) + { + if (intval($this->config['upload_dir_size']) + $file->get('filesize') > $this->config['attachment_quota']) + { + $filedata['error'][] = $this->user->lang['ATTACH_QUOTA_REACHED']; + $filedata['post_attach'] = false; + + $file->remove(); + + return $filedata; + } + } + + // Check free disk space + if ($free_space = @disk_free_space($this->phpbb_root_path . $this->config['upload_path'])) + { + if ($free_space <= $file->get('filesize')) + { + if ($this->auth->acl_get('a_')) + { + $filedata['error'][] = $this->user->lang['ATTACH_DISK_FULL']; + } + else + { + $filedata['error'][] = $this->user->lang['ATTACH_QUOTA_REACHED']; + } + $filedata['post_attach'] = false; + + $file->remove(); + + return $filedata; + } + } + + // Create Thumbnail + if ($filedata['thumbnail']) + { + $source = $file->get('destination_file'); + $destination = $file->get('destination_path') . '/thumb_' . $file->get('realname'); + + if (!create_thumbnail($source, $destination, $file->get('mimetype'))) + { + $filedata['thumbnail'] = 0; + } + } + + return $filedata; + } +} -- cgit v1.2.1 From 07c8e21e8033f35483b5c96653f616b6f094138e Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 19 Sep 2015 16:45:51 +0200 Subject: [ticket/14168] Use language class and fix incorrect docblock PHPBB3-14168 --- phpBB/phpbb/attachment/upload.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php index a175dee0b3..c7de323699 100644 --- a/phpBB/phpbb/attachment/upload.php +++ b/phpBB/phpbb/attachment/upload.php @@ -96,7 +96,7 @@ class upload * * @return object filespec */ - public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false) + public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = array()) { $filedata = array( 'error' => array() @@ -115,7 +115,7 @@ class upload if (!$filedata['post_attach']) { - $filedata['error'][] = $this->user->lang['NO_UPLOAD_FORM_FOUND']; + $filedata['error'][] = $this->language->lang('NO_UPLOAD_FORM_FOUND'); return $filedata; } @@ -185,7 +185,7 @@ class upload // If this error occurs a user tried to exploit an IE Bug by renaming extensions // Since the image category is displaying content inline we need to catch this. - trigger_error($this->user->lang['ATTACHED_IMAGE_NOT_IMAGE']); + trigger_error($this->language->lang('ATTACHED_IMAGE_NOT_IMAGE')); } $filedata['filesize'] = $file->get('filesize'); @@ -214,7 +214,7 @@ class upload { if (intval($this->config['upload_dir_size']) + $file->get('filesize') > $this->config['attachment_quota']) { - $filedata['error'][] = $this->user->lang['ATTACH_QUOTA_REACHED']; + $filedata['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED'); $filedata['post_attach'] = false; $file->remove(); @@ -230,11 +230,11 @@ class upload { if ($this->auth->acl_get('a_')) { - $filedata['error'][] = $this->user->lang['ATTACH_DISK_FULL']; + $filedata['error'][] = $this->language->lang('ATTACH_DISK_FULL'); } else { - $filedata['error'][] = $this->user->lang['ATTACH_QUOTA_REACHED']; + $filedata['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED'); } $filedata['post_attach'] = false; -- cgit v1.2.1 From 6c1cd26b7a3602932f3571eebcd5a21d1ce8ae51 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 19 Sep 2015 16:50:21 +0200 Subject: [ticket/14168] Split thumbnail creation to separate method PHPBB3-14168 --- phpBB/phpbb/attachment/upload.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php index c7de323699..fa6fbad60d 100644 --- a/phpBB/phpbb/attachment/upload.php +++ b/phpBB/phpbb/attachment/upload.php @@ -245,6 +245,21 @@ class upload } // Create Thumbnail + $filedata = $this->create_thumbnail($file, $filedata); + + return $filedata; + } + + /** + * Create thumbnail for file if necessary + * + * @param \phpbb\files\filespec $file + * @param array $filedata File's filedata + * + * @return array Updated $filedata + */ + protected function create_thumbnail(\phpbb\files\filespec $file, $filedata) + { if ($filedata['thumbnail']) { $source = $file->get('destination_file'); -- cgit v1.2.1 From e10aa45470889cba22b51ac4f43582ecfa131310 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 20 Sep 2015 00:51:51 +0200 Subject: [ticket/14168] Further split up attachment upload class PHPBB3-14168 --- phpBB/phpbb/attachment/upload.php | 130 +++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 52 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php index fa6fbad60d..2880e9e42e 100644 --- a/phpBB/phpbb/attachment/upload.php +++ b/phpBB/phpbb/attachment/upload.php @@ -55,6 +55,12 @@ class upload /** @var user */ protected $user; + /** @var \phpbb\files\filespec Current filespec instance */ + private $file; + + /** @var array Extensions array */ + private $extensions; + /** * Constructor for attachments upload class * @@ -102,14 +108,7 @@ class upload 'error' => array() ); - if ($this->config['check_attachment_content'] && isset($this->config['mime_triggers'])) - { - $this->files_upload->set_disallowed_content(explode('|', $this->config['mime_triggers'])); - } - else if (!$this->config['check_attachment_content']) - { - $this->files_upload->set_disallowed_content(array()); - } + $this->init_files_upload($forum_id, $is_message); $filedata['post_attach'] = $local || $this->files_upload->is_valid($form_name); @@ -119,80 +118,64 @@ class upload return $filedata; } - $extensions = $this->cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id)); - $this->files_upload->set_allowed_extensions(array_keys($extensions['_allowed_'])); - - /** @var \phpbb\files\filespec $file */ - $file = ($local) ? $this->files_upload->handle_upload('files.types.local', $local_storage, $local_filedata) : $this->files_upload->handle_upload('files.types.form', $form_name); + $this->file = ($local) ? $this->files_upload->handle_upload('files.types.local', $local_storage, $local_filedata) : $this->files_upload->handle_upload('files.types.form', $form_name); - if ($file->init_error()) + if ($this->file->init_error()) { $filedata['post_attach'] = false; return $filedata; } // Whether the uploaded file is in the image category - $is_image = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false; + $is_image = (isset($this->extensions[$this->file->get('extension')]['display_cat'])) ? $this->extensions[$this->file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false; if (!$this->auth->acl_get('a_') && !$this->auth->acl_get('m_', $forum_id)) { // Check Image Size, if it is an image if ($is_image) { - $file->upload->set_allowed_dimensions(0, 0, $this->config['img_max_width'], $this->config['img_max_height']); + $this->file->upload->set_allowed_dimensions(0, 0, $this->config['img_max_width'], $this->config['img_max_height']); } // Admins and mods are allowed to exceed the allowed filesize - if (!empty($extensions[$file->get('extension')]['max_filesize'])) + if (!empty($this->extensions[$this->file->get('extension')]['max_filesize'])) { - $allowed_filesize = $extensions[$file->get('extension')]['max_filesize']; + $allowed_filesize = $this->extensions[$this->file->get('extension')]['max_filesize']; } else { $allowed_filesize = ($is_message) ? $this->config['max_filesize_pm'] : $this->config['max_filesize']; } - $file->upload->set_max_filesize($allowed_filesize); + $this->file->upload->set_max_filesize($allowed_filesize); } - $file->clean_filename('unique', $this->user->data['user_id'] . '_'); + $this->file->clean_filename('unique', $this->user->data['user_id'] . '_'); // Are we uploading an image *and* this image being within the image category? // Only then perform additional image checks. - $file->move_file($this->config['upload_path'], false, !$is_image); + $this->file->move_file($this->config['upload_path'], false, !$is_image); // Do we have to create a thumbnail? $filedata['thumbnail'] = ($is_image && $this->config['img_create_thumbnail']) ? 1 : 0; - if (sizeof($file->error)) + if (sizeof($this->file->error)) { - $file->remove(); - $filedata['error'] = array_merge($filedata['error'], $file->error); + $this->file->remove(); + $filedata['error'] = array_merge($filedata['error'], $this->file->error); $filedata['post_attach'] = false; return $filedata; } // Make sure the image category only holds valid images... - if ($is_image && !$file->is_image()) - { - $file->remove(); - - if ($this->plupload && $this->plupload->is_active()) - { - $this->plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE'); - } - - // If this error occurs a user tried to exploit an IE Bug by renaming extensions - // Since the image category is displaying content inline we need to catch this. - trigger_error($this->language->lang('ATTACHED_IMAGE_NOT_IMAGE')); - } + $this->check_image($is_image); - $filedata['filesize'] = $file->get('filesize'); - $filedata['mimetype'] = $file->get('mimetype'); - $filedata['extension'] = $file->get('extension'); - $filedata['physical_filename'] = $file->get('realname'); - $filedata['real_filename'] = $file->get('uploadname'); + $filedata['filesize'] = $this->file->get('filesize'); + $filedata['mimetype'] = $this->file->get('mimetype'); + $filedata['extension'] = $this->file->get('extension'); + $filedata['physical_filename'] = $this->file->get('realname'); + $filedata['real_filename'] = $this->file->get('uploadname'); $filedata['filetime'] = time(); /** @@ -212,12 +195,12 @@ class upload // Check our complete quota if ($this->config['attachment_quota']) { - if (intval($this->config['upload_dir_size']) + $file->get('filesize') > $this->config['attachment_quota']) + if (intval($this->config['upload_dir_size']) + $this->file->get('filesize') > $this->config['attachment_quota']) { $filedata['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED'); $filedata['post_attach'] = false; - $file->remove(); + $this->file->remove(); return $filedata; } @@ -226,7 +209,7 @@ class upload // Check free disk space if ($free_space = @disk_free_space($this->phpbb_root_path . $this->config['upload_path'])) { - if ($free_space <= $file->get('filesize')) + if ($free_space <= $this->file->get('filesize')) { if ($this->auth->acl_get('a_')) { @@ -238,14 +221,14 @@ class upload } $filedata['post_attach'] = false; - $file->remove(); + $this->file->remove(); return $filedata; } } // Create Thumbnail - $filedata = $this->create_thumbnail($file, $filedata); + $filedata = $this->create_thumbnail($filedata); return $filedata; } @@ -253,19 +236,18 @@ class upload /** * Create thumbnail for file if necessary * - * @param \phpbb\files\filespec $file * @param array $filedata File's filedata * * @return array Updated $filedata */ - protected function create_thumbnail(\phpbb\files\filespec $file, $filedata) + protected function create_thumbnail($filedata) { if ($filedata['thumbnail']) { - $source = $file->get('destination_file'); - $destination = $file->get('destination_path') . '/thumb_' . $file->get('realname'); + $source = $this->file->get('destination_file'); + $destination = $this->file->get('destination_path') . '/thumb_' . $this->file->get('realname'); - if (!create_thumbnail($source, $destination, $file->get('mimetype'))) + if (!create_thumbnail($source, $destination, $this->file->get('mimetype'))) { $filedata['thumbnail'] = 0; } @@ -273,4 +255,48 @@ class upload return $filedata; } + + /** + * Init files upload class + * + * @param int $forum_id Forum ID + * @param bool $is_message Whether attachment is inside PM or not + */ + protected function init_files_upload($forum_id, $is_message) + { + if ($this->config['check_attachment_content'] && isset($this->config['mime_triggers'])) + { + $this->files_upload->set_disallowed_content(explode('|', $this->config['mime_triggers'])); + } + else if (!$this->config['check_attachment_content']) + { + $this->files_upload->set_disallowed_content(array()); + } + + $this->extensions = $this->cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id)); + $this->files_upload->set_allowed_extensions(array_keys($this->extensions['_allowed_'])); + } + + /** + * Check if uploaded file is really an image + * + * @param bool $is_image Whether file is image + */ + protected function check_image($is_image) + { + // Make sure the image category only holds valid images... + if ($is_image && !$this->file->is_image()) + { + $this->file->remove(); + + if ($this->plupload && $this->plupload->is_active()) + { + $this->plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE'); + } + + // If this error occurs a user tried to exploit an IE Bug by renaming extensions + // Since the image category is displaying content inline we need to catch this. + trigger_error($this->language->lang('ATTACHED_IMAGE_NOT_IMAGE')); + } + } } -- cgit v1.2.1 From a60beb6f2f9d75e34c67a53c9b2332e15fe21b4a Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 20 Sep 2015 12:18:58 +0200 Subject: [ticket/14168] Further split up attachment upload class PHPBB3-14168 --- phpBB/phpbb/attachment/upload.php | 155 +++++++++++++++++++++++--------------- 1 file changed, 94 insertions(+), 61 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php index 2880e9e42e..d57b33b137 100644 --- a/phpBB/phpbb/attachment/upload.php +++ b/phpBB/phpbb/attachment/upload.php @@ -58,6 +58,11 @@ class upload /** @var \phpbb\files\filespec Current filespec instance */ private $file; + /** @var array File data */ + private $file_data = array( + 'error' => array() + ); + /** @var array Extensions array */ private $extensions; @@ -104,26 +109,22 @@ class upload */ public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = array()) { - $filedata = array( - 'error' => array() - ); - $this->init_files_upload($forum_id, $is_message); - $filedata['post_attach'] = $local || $this->files_upload->is_valid($form_name); + $this->file_data['post_attach'] = $local || $this->files_upload->is_valid($form_name); - if (!$filedata['post_attach']) + if (!$this->file_data['post_attach']) { - $filedata['error'][] = $this->language->lang('NO_UPLOAD_FORM_FOUND'); - return $filedata; + $this->file_data['error'][] = $this->language->lang('NO_UPLOAD_FORM_FOUND'); + return $this->file_data; } $this->file = ($local) ? $this->files_upload->handle_upload('files.types.local', $local_storage, $local_filedata) : $this->files_upload->handle_upload('files.types.form', $form_name); if ($this->file->init_error()) { - $filedata['post_attach'] = false; - return $filedata; + $this->file_data['post_attach'] = false; + return $this->file_data; } // Whether the uploaded file is in the image category @@ -157,26 +158,23 @@ class upload $this->file->move_file($this->config['upload_path'], false, !$is_image); // Do we have to create a thumbnail? - $filedata['thumbnail'] = ($is_image && $this->config['img_create_thumbnail']) ? 1 : 0; + $this->file_data['thumbnail'] = ($is_image && $this->config['img_create_thumbnail']) ? 1 : 0; if (sizeof($this->file->error)) { $this->file->remove(); - $filedata['error'] = array_merge($filedata['error'], $this->file->error); - $filedata['post_attach'] = false; + $this->file_data['error'] = array_merge($this->file_data['error'], $this->file->error); + $this->file_data['post_attach'] = false; - return $filedata; + return $this->file_data; } // Make sure the image category only holds valid images... $this->check_image($is_image); - $filedata['filesize'] = $this->file->get('filesize'); - $filedata['mimetype'] = $this->file->get('mimetype'); - $filedata['extension'] = $this->file->get('extension'); - $filedata['physical_filename'] = $this->file->get('realname'); - $filedata['real_filename'] = $this->file->get('uploadname'); - $filedata['filetime'] = time(); + $this->fill_file_data(); + + $filedata = $this->file_data; /** * Event to modify uploaded file before submit to the post @@ -191,69 +189,38 @@ class upload 'is_image', ); extract($this->phpbb_dispatcher->trigger_event('core.modify_uploaded_file', compact($vars))); + $this->file_data = $filedata; + unset($filedata); - // Check our complete quota - if ($this->config['attachment_quota']) - { - if (intval($this->config['upload_dir_size']) + $this->file->get('filesize') > $this->config['attachment_quota']) - { - $filedata['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED'); - $filedata['post_attach'] = false; - - $this->file->remove(); - - return $filedata; - } - } - - // Check free disk space - if ($free_space = @disk_free_space($this->phpbb_root_path . $this->config['upload_path'])) + // Check for attachment quota and free space + if (!$this->check_attach_quota() || !$this->check_disk_space()) { - if ($free_space <= $this->file->get('filesize')) - { - if ($this->auth->acl_get('a_')) - { - $filedata['error'][] = $this->language->lang('ATTACH_DISK_FULL'); - } - else - { - $filedata['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED'); - } - $filedata['post_attach'] = false; - - $this->file->remove(); - - return $filedata; - } + return $this->file_data; } // Create Thumbnail - $filedata = $this->create_thumbnail($filedata); + $this->create_thumbnail(); - return $filedata; + return $this->file_data; } /** * Create thumbnail for file if necessary * - * @param array $filedata File's filedata - * * @return array Updated $filedata */ - protected function create_thumbnail($filedata) + protected function create_thumbnail() { - if ($filedata['thumbnail']) + if ($this->file_data['thumbnail']) { $source = $this->file->get('destination_file'); $destination = $this->file->get('destination_path') . '/thumb_' . $this->file->get('realname'); if (!create_thumbnail($source, $destination, $this->file->get('mimetype'))) { - $filedata['thumbnail'] = 0; + $this->file_data['thumbnail'] = 0; } } - - return $filedata; } /** @@ -299,4 +266,70 @@ class upload trigger_error($this->language->lang('ATTACHED_IMAGE_NOT_IMAGE')); } } + + /** + * Check if attachment quota was reached + * + * @return bool False if attachment quota was reached, true if not + */ + protected function check_attach_quota() + { + if ($this->config['attachment_quota']) + { + if (intval($this->config['upload_dir_size']) + $this->file->get('filesize') > $this->config['attachment_quota']) + { + $this->file_data['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED'); + $this->file_data['post_attach'] = false; + + $this->file->remove(); + + return false; + } + } + + return true; + } + + /** + * Check if there is enough free space available on disk + * + * @return bool True if disk space is available, false if not + */ + protected function check_disk_space() + { + if ($free_space = @disk_free_space($this->phpbb_root_path . $this->config['upload_path'])) + { + if ($free_space <= $this->file->get('filesize')) + { + if ($this->auth->acl_get('a_')) + { + $this->file_data['error'][] = $this->language->lang('ATTACH_DISK_FULL'); + } + else + { + $this->file_data['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED'); + } + $this->file_data['post_attach'] = false; + + $this->file->remove(); + + return false; + } + } + + return true; + } + + /** + * Fills file data with file information and current time as filetime + */ + protected function fill_file_data() + { + $this->file_data['filesize'] = $this->file->get('filesize'); + $this->file_data['mimetype'] = $this->file->get('mimetype'); + $this->file_data['extension'] = $this->file->get('extension'); + $this->file_data['physical_filename'] = $this->file->get('realname'); + $this->file_data['real_filename'] = $this->file->get('uploadname'); + $this->file_data['filetime'] = time(); + } } -- cgit v1.2.1 From d1030450f5f2ddca88f1ef17cc7b949541e64bd8 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 21 Sep 2015 08:54:57 +0200 Subject: [ticket/14168] Move function for attachment deletion into class PHPBB3-14168 --- phpBB/phpbb/attachment/delete.php | 398 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 phpBB/phpbb/attachment/delete.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php new file mode 100644 index 0000000000..a2fe1a8cdf --- /dev/null +++ b/phpBB/phpbb/attachment/delete.php @@ -0,0 +1,398 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\attachment; + +use \phpbb\config\config; +use \phpbb\db\driver\driver_interface; +use \phpbb\event\dispatcher; + +/** + * Attachment delete class + */ + +class delete +{ + /** @var \phpbb\config\config */ + protected $config; + + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\event\dispatcher */ + protected $dispatcher; + + /** @var array Attachement IDs */ + protected $ids; + + /** + * Attachment delete class constructor + * + * @param config $config + * @param driver_interface $db + * @param dispatcher>>>>>>> 85b6020... [ticket/14168] Move function for attachment deletion into class + */ + public function __construct(config $config, driver_interface $db, dispatcher $dispatcher) + { + $this->config = $config; + $this->db = $db; + $this->dispatcher = $dispatcher; + } + + /** + * Delete Attachments + * + * @param string $mode can be: post|message|topic|attach|user + * @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids + * @param bool $resync set this to false if you are deleting posts or topics + * + * @return int|bool Number of deleted attachments or false if something + * went wrong during attachment deletion + */ + function delete($mode, $ids, $resync = true) + { + if (!$this->set_attachment_ids($ids)) + { + return false; + } + + $sql_where = ''; + + switch ($mode) + { + case 'post': + case 'message': + $sql_id = 'post_msg_id'; + $sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0); + break; + + case 'topic': + $sql_id = 'topic_id'; + break; + + case 'user': + $sql_id = 'poster_id'; + break; + + case 'attach': + default: + $sql_id = 'attach_id'; + break; + } + + $post_ids = $message_ids = $topic_ids = $physical = array(); + + /** + * Perform additional actions before collecting data for attachment(s) deletion + * + * @event core.delete_attachments_collect_data_before + * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user + * @var mixed ids Array or comma separated list of ids corresponding to the mode + * @var bool resync Flag indicating if posts/messages/topics should be synchronized + * @var string sql_id The field name to collect/delete data for depending on the mode + * @since 3.1.7-RC1 + */ + $vars = array( + 'mode', + 'ids', + 'resync', + 'sql_id', + ); + extract($this->dispatcher->trigger_event('core.delete_attachments_collect_data_before', compact($vars))); + + // Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled) + $sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan + FROM ' . ATTACHMENTS_TABLE . ' + WHERE ' . $this->db->sql_in_set($sql_id, $ids); + + $sql .= $sql_where; + + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + // We only need to store post/message/topic ids if resync is enabled and the file is not orphaned + if ($resync && !$row['is_orphan']) + { + if (!$row['in_message']) + { + $post_ids[] = $row['post_msg_id']; + $topic_ids[] = $row['topic_id']; + } + else + { + $message_ids[] = $row['post_msg_id']; + } + } + + $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize'], 'is_orphan' => $row['is_orphan']); + } + $this->db->sql_freeresult($result); + + /** + * Perform additional actions before attachment(s) deletion + * + * @event core.delete_attachments_before + * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user + * @var mixed ids Array or comma separated list of ids corresponding to the mode + * @var bool resync Flag indicating if posts/messages/topics should be synchronized + * @var string sql_id The field name to collect/delete data for depending on the mode + * @var array post_ids Array with post ids for deleted attachment(s) + * @var array topic_ids Array with topic ids for deleted attachment(s) + * @var array message_ids Array with private message ids for deleted attachment(s) + * @var array physical Array with deleted attachment(s) physical file(s) data + * @since 3.1.7-RC1 + */ + $vars = array( + 'mode', + 'ids', + 'resync', + 'sql_id', + 'post_ids', + 'topic_ids', + 'message_ids', + 'physical', + ); + extract($this->dispatcher->trigger_event('core.delete_attachments_before', compact($vars))); + + // Delete attachments + $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' + WHERE ' . $this->db->sql_in_set($sql_id, $ids); + + $sql .= $sql_where; + + $this->db->sql_query($sql); + $num_deleted = $this->db->sql_affectedrows(); + + /** + * Perform additional actions after attachment(s) deletion from the database + * + * @event core.delete_attachments_from_database_after + * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user + * @var mixed ids Array or comma separated list of ids corresponding to the mode + * @var bool resync Flag indicating if posts/messages/topics should be synchronized + * @var string sql_id The field name to collect/delete data for depending on the mode + * @var array post_ids Array with post ids for deleted attachment(s) + * @var array topic_ids Array with topic ids for deleted attachment(s) + * @var array message_ids Array with private message ids for deleted attachment(s) + * @var array physical Array with deleted attachment(s) physical file(s) data + * @var int num_deleted The number of deleted attachment(s) from the database + * @since 3.1.7-RC1 + */ + $vars = array( + 'mode', + 'ids', + 'resync', + 'sql_id', + 'post_ids', + 'topic_ids', + 'message_ids', + 'physical', + 'num_deleted', + ); + extract($this->dispatcher->trigger_event('core.delete_attachments_from_database_after', compact($vars))); + + if (!$num_deleted) + { + return 0; + } + + // Delete attachments from filesystem + $space_removed = $files_removed = 0; + foreach ($physical as $file_ary) + { + if (phpbb_unlink($file_ary['filename'], 'file', true) && !$file_ary['is_orphan']) + { + // Only non-orphaned files count to the file size + $space_removed += $file_ary['filesize']; + $files_removed++; + } + + if ($file_ary['thumbnail']) + { + phpbb_unlink($file_ary['filename'], 'thumbnail', true); + } + } + + /** + * Perform additional actions after attachment(s) deletion from the filesystem + * + * @event core.delete_attachments_from_filesystem_after + * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user + * @var mixed ids Array or comma separated list of ids corresponding to the mode + * @var bool resync Flag indicating if posts/messages/topics should be synchronized + * @var string sql_id The field name to collect/delete data for depending on the mode + * @var array post_ids Array with post ids for deleted attachment(s) + * @var array topic_ids Array with topic ids for deleted attachment(s) + * @var array message_ids Array with private message ids for deleted attachment(s) + * @var array physical Array with deleted attachment(s) physical file(s) data + * @var int num_deleted The number of deleted attachment(s) from the database + * @var int space_removed The size of deleted files(s) from the filesystem + * @var int files_removed The number of deleted file(s) from the filesystem + * @since 3.1.7-RC1 + */ + $vars = array( + 'mode', + 'ids', + 'resync', + 'sql_id', + 'post_ids', + 'topic_ids', + 'message_ids', + 'physical', + 'num_deleted', + 'space_removed', + 'files_removed', + ); + extract($this->dispatcher->trigger_event('core.delete_attachments_from_filesystem_after', compact($vars))); + + if ($space_removed || $files_removed) + { + $this->config->increment('upload_dir_size', $space_removed * (-1), false); + $this->config->increment('num_files', $files_removed * (-1), false); + } + + // If we do not resync, we do not need to adjust any message, post, topic or user entries + if (!$resync) + { + return $num_deleted; + } + + // No more use for the original ids + unset($ids); + + // Now, we need to resync posts, messages, topics. We go through every one of them + $post_ids = array_unique($post_ids); + $message_ids = array_unique($message_ids); + $topic_ids = array_unique($topic_ids); + + // Update post indicators for posts now no longer having attachments + if (sizeof($post_ids)) + { + // Just check which posts are still having an assigned attachment not orphaned by querying the attachments table + $sql = 'SELECT post_msg_id + FROM ' . ATTACHMENTS_TABLE . ' + WHERE ' . $this->db->sql_in_set('post_msg_id', $post_ids) . ' + AND in_message = 0 + AND is_orphan = 0'; + $result = $this->db->sql_query($sql); + + $remaining_ids = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $remaining_ids[] = $row['post_msg_id']; + } + $this->db->sql_freeresult($result); + + // Now only unset those ids remaining + $post_ids = array_diff($post_ids, $remaining_ids); + + if (sizeof($post_ids)) + { + $sql = 'UPDATE ' . POSTS_TABLE . ' + SET post_attachment = 0 + WHERE ' . $this->db->sql_in_set('post_id', $post_ids); + $this->db->sql_query($sql); + } + } + + // Update message table if messages are affected + if (sizeof($message_ids)) + { + // Just check which messages are still having an assigned attachment not orphaned by querying the attachments table + $sql = 'SELECT post_msg_id + FROM ' . ATTACHMENTS_TABLE . ' + WHERE ' . $this->db->sql_in_set('post_msg_id', $message_ids) . ' + AND in_message = 1 + AND is_orphan = 0'; + $result = $this->db->sql_query($sql); + + $remaining_ids = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $remaining_ids[] = $row['post_msg_id']; + } + $this->db->sql_freeresult($result); + + // Now only unset those ids remaining + $message_ids = array_diff($message_ids, $remaining_ids); + + if (sizeof($message_ids)) + { + $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' + SET message_attachment = 0 + WHERE ' . $this->db->sql_in_set('msg_id', $message_ids); + $this->db->sql_query($sql); + } + } + + // Now update the topics. This is a bit trickier, because there could be posts still having attachments within the topic + if (sizeof($topic_ids)) + { + // Just check which topics are still having an assigned attachment not orphaned by querying the attachments table (much less entries expected) + $sql = 'SELECT topic_id + FROM ' . ATTACHMENTS_TABLE . ' + WHERE ' . $this->db->sql_in_set('topic_id', $topic_ids) . ' + AND is_orphan = 0'; + $result = $this->db->sql_query($sql); + + $remaining_ids = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $remaining_ids[] = $row['topic_id']; + } + $this->db->sql_freeresult($result); + + // Now only unset those ids remaining + $topic_ids = array_diff($topic_ids, $remaining_ids); + + if (sizeof($topic_ids)) + { + $sql = 'UPDATE ' . TOPICS_TABLE . ' + SET topic_attachment = 0 + WHERE ' . $this->db->sql_in_set('topic_id', $topic_ids); + $this->db->sql_query($sql); + } + } + + return $num_deleted; + } + + /** + * Set attachment IDs + * + * @param array $ids + * + * @return bool True if attachment IDs were set, false if not + */ + protected function set_attachment_ids($ids) + { + // 0 is as bad as an empty array + if (empty($ids)) + { + return false; + } + + if (is_array($ids)) + { + $ids = array_unique($ids); + $this->ids = array_map('intval', $ids); + } + else + { + $this->ids = array((int) $ids); + } + + return true; + } +} \ No newline at end of file -- cgit v1.2.1 From ebfdd69525cc10446fba6c6e8600b44e1124a64d Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 21 Sep 2015 10:28:09 +0200 Subject: [ticket/14168] Further split up attachment delete class PHPBB3-14168 --- phpBB/phpbb/attachment/delete.php | 379 ++++++++++++++++++++++---------------- 1 file changed, 218 insertions(+), 161 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php index a2fe1a8cdf..7a168c2243 100644 --- a/phpBB/phpbb/attachment/delete.php +++ b/phpBB/phpbb/attachment/delete.php @@ -35,6 +35,27 @@ class delete /** @var array Attachement IDs */ protected $ids; + /** @var string SQL ID string */ + private $sql_id; + + /** @var string SQL where string */ + private $sql_where = ''; + + /** @var int Number of deleted items */ + private $num_deleted; + + /** @var array Post IDs */ + private $post_ids = array(); + + /** @var array Message IDs */ + private $message_ids = array(); + + /** @var array Topic IDs */ + private $topic_ids = array(); + + /** @var array Info of physical file */ + private $physical = array(); + /** * Attachment delete class constructor * @@ -66,31 +87,7 @@ class delete return false; } - $sql_where = ''; - - switch ($mode) - { - case 'post': - case 'message': - $sql_id = 'post_msg_id'; - $sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0); - break; - - case 'topic': - $sql_id = 'topic_id'; - break; - - case 'user': - $sql_id = 'poster_id'; - break; - - case 'attach': - default: - $sql_id = 'attach_id'; - break; - } - - $post_ids = $message_ids = $topic_ids = $physical = array(); + $this->set_sql_constraints($mode); /** * Perform additional actions before collecting data for attachment(s) deletion @@ -111,68 +108,10 @@ class delete extract($this->dispatcher->trigger_event('core.delete_attachments_collect_data_before', compact($vars))); // Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled) - $sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan - FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $this->db->sql_in_set($sql_id, $ids); - - $sql .= $sql_where; - - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - // We only need to store post/message/topic ids if resync is enabled and the file is not orphaned - if ($resync && !$row['is_orphan']) - { - if (!$row['in_message']) - { - $post_ids[] = $row['post_msg_id']; - $topic_ids[] = $row['topic_id']; - } - else - { - $message_ids[] = $row['post_msg_id']; - } - } - - $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize'], 'is_orphan' => $row['is_orphan']); - } - $this->db->sql_freeresult($result); - - /** - * Perform additional actions before attachment(s) deletion - * - * @event core.delete_attachments_before - * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user - * @var mixed ids Array or comma separated list of ids corresponding to the mode - * @var bool resync Flag indicating if posts/messages/topics should be synchronized - * @var string sql_id The field name to collect/delete data for depending on the mode - * @var array post_ids Array with post ids for deleted attachment(s) - * @var array topic_ids Array with topic ids for deleted attachment(s) - * @var array message_ids Array with private message ids for deleted attachment(s) - * @var array physical Array with deleted attachment(s) physical file(s) data - * @since 3.1.7-RC1 - */ - $vars = array( - 'mode', - 'ids', - 'resync', - 'sql_id', - 'post_ids', - 'topic_ids', - 'message_ids', - 'physical', - ); - extract($this->dispatcher->trigger_event('core.delete_attachments_before', compact($vars))); + $this->collect_attachment_info($resync); - // Delete attachments - $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $this->db->sql_in_set($sql_id, $ids); - - $sql .= $sql_where; - - $this->db->sql_query($sql); - $num_deleted = $this->db->sql_affectedrows(); + // Delete attachments from database + $this->delete_attachments_from_db(); /** * Perform additional actions after attachment(s) deletion from the database @@ -202,87 +141,31 @@ class delete ); extract($this->dispatcher->trigger_event('core.delete_attachments_from_database_after', compact($vars))); - if (!$num_deleted) + if (!$this->num_deleted) { return 0; } // Delete attachments from filesystem - $space_removed = $files_removed = 0; - foreach ($physical as $file_ary) - { - if (phpbb_unlink($file_ary['filename'], 'file', true) && !$file_ary['is_orphan']) - { - // Only non-orphaned files count to the file size - $space_removed += $file_ary['filesize']; - $files_removed++; - } - - if ($file_ary['thumbnail']) - { - phpbb_unlink($file_ary['filename'], 'thumbnail', true); - } - } - - /** - * Perform additional actions after attachment(s) deletion from the filesystem - * - * @event core.delete_attachments_from_filesystem_after - * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user - * @var mixed ids Array or comma separated list of ids corresponding to the mode - * @var bool resync Flag indicating if posts/messages/topics should be synchronized - * @var string sql_id The field name to collect/delete data for depending on the mode - * @var array post_ids Array with post ids for deleted attachment(s) - * @var array topic_ids Array with topic ids for deleted attachment(s) - * @var array message_ids Array with private message ids for deleted attachment(s) - * @var array physical Array with deleted attachment(s) physical file(s) data - * @var int num_deleted The number of deleted attachment(s) from the database - * @var int space_removed The size of deleted files(s) from the filesystem - * @var int files_removed The number of deleted file(s) from the filesystem - * @since 3.1.7-RC1 - */ - $vars = array( - 'mode', - 'ids', - 'resync', - 'sql_id', - 'post_ids', - 'topic_ids', - 'message_ids', - 'physical', - 'num_deleted', - 'space_removed', - 'files_removed', - ); - extract($this->dispatcher->trigger_event('core.delete_attachments_from_filesystem_after', compact($vars))); - - if ($space_removed || $files_removed) - { - $this->config->increment('upload_dir_size', $space_removed * (-1), false); - $this->config->increment('num_files', $files_removed * (-1), false); - } + $this->delete_attachments_from_filesystem(); // If we do not resync, we do not need to adjust any message, post, topic or user entries if (!$resync) { - return $num_deleted; + return $this->num_deleted; } // No more use for the original ids unset($ids); // Now, we need to resync posts, messages, topics. We go through every one of them - $post_ids = array_unique($post_ids); - $message_ids = array_unique($message_ids); - $topic_ids = array_unique($topic_ids); - // Update post indicators for posts now no longer having attachments - if (sizeof($post_ids)) + if (sizeof($this->post_ids)) { // Just check which posts are still having an assigned attachment not orphaned by querying the attachments table $sql = 'SELECT post_msg_id FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $this->db->sql_in_set('post_msg_id', $post_ids) . ' + WHERE ' . $this->db->sql_in_set('post_msg_id', $this->post_ids) . ' AND in_message = 0 AND is_orphan = 0'; $result = $this->db->sql_query($sql); @@ -295,24 +178,24 @@ class delete $this->db->sql_freeresult($result); // Now only unset those ids remaining - $post_ids = array_diff($post_ids, $remaining_ids); + $this->post_ids = array_diff($this->post_ids, $remaining_ids); - if (sizeof($post_ids)) + if (sizeof($this->post_ids)) { $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_attachment = 0 - WHERE ' . $this->db->sql_in_set('post_id', $post_ids); + WHERE ' . $this->db->sql_in_set('post_id', $this->post_ids); $this->db->sql_query($sql); } } // Update message table if messages are affected - if (sizeof($message_ids)) + if (sizeof($this->message_ids)) { // Just check which messages are still having an assigned attachment not orphaned by querying the attachments table $sql = 'SELECT post_msg_id FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $this->db->sql_in_set('post_msg_id', $message_ids) . ' + WHERE ' . $this->db->sql_in_set('post_msg_id', $this->message_ids) . ' AND in_message = 1 AND is_orphan = 0'; $result = $this->db->sql_query($sql); @@ -325,24 +208,24 @@ class delete $this->db->sql_freeresult($result); // Now only unset those ids remaining - $message_ids = array_diff($message_ids, $remaining_ids); + $this->message_ids = array_diff($this->message_ids, $remaining_ids); - if (sizeof($message_ids)) + if (sizeof($this->message_ids)) { $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' SET message_attachment = 0 - WHERE ' . $this->db->sql_in_set('msg_id', $message_ids); + WHERE ' . $this->db->sql_in_set('msg_id', $this->message_ids); $this->db->sql_query($sql); } } // Now update the topics. This is a bit trickier, because there could be posts still having attachments within the topic - if (sizeof($topic_ids)) + if (sizeof($this->topic_ids)) { // Just check which topics are still having an assigned attachment not orphaned by querying the attachments table (much less entries expected) $sql = 'SELECT topic_id FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $this->db->sql_in_set('topic_id', $topic_ids) . ' + WHERE ' . $this->db->sql_in_set('topic_id', $this->topic_ids) . ' AND is_orphan = 0'; $result = $this->db->sql_query($sql); @@ -354,18 +237,18 @@ class delete $this->db->sql_freeresult($result); // Now only unset those ids remaining - $topic_ids = array_diff($topic_ids, $remaining_ids); + $this->topic_ids = array_diff($this->topic_ids, $remaining_ids); - if (sizeof($topic_ids)) + if (sizeof($this->topic_ids)) { $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_attachment = 0 - WHERE ' . $this->db->sql_in_set('topic_id', $topic_ids); + WHERE ' . $this->db->sql_in_set('topic_id', $this->topic_ids); $this->db->sql_query($sql); } } - return $num_deleted; + return $this->num_deleted; } /** @@ -395,4 +278,178 @@ class delete return true; } + + /** + * Set SQL constraints based on mode + * + * @param string $mode Delete mode; can be: post|message|topic|attach|user + */ + private function set_sql_constraints($mode) + { + switch ($mode) + { + case 'post': + case 'message': + $this->sql_id = 'post_msg_id'; + $this->sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0); + break; + + case 'topic': + $this->sql_id = 'topic_id'; + break; + + case 'user': + $this->sql_id = 'poster_id'; + break; + + case 'attach': + default: + $this->sql_id = 'attach_id'; + break; + } + } + + /** + * Collect info about attachment IDs + * + * @param bool $resync Whether topics/posts should be resynced after delete + */ + protected function collect_attachment_info($resync) + { + // Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled) + $sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan + FROM ' . ATTACHMENTS_TABLE . ' + WHERE ' . $this->db->sql_in_set($this->sql_id, $this->ids); + + $sql .= $this->sql_where; + + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + // We only need to store post/message/topic ids if resync is enabled and the file is not orphaned + if ($resync && !$row['is_orphan']) + { + if (!$row['in_message']) + { + $this->post_ids[] = $row['post_msg_id']; + $this->topic_ids[] = $row['topic_id']; + } + else + { + $this->message_ids[] = $row['post_msg_id']; + } + } + + $this->physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize'], 'is_orphan' => $row['is_orphan']); + } + $this->db->sql_freeresult($result); + + // IDs should be unique + $this->post_ids = array_unique($this->post_ids); + $this->message_ids = array_unique($this->message_ids); + $this->topic_ids = array_unique($this->topic_ids); + } + + /** + * Delete attachments from database table + */ + protected function delete_attachments_from_db() + { + /** + * Perform additional actions before attachment(s) deletion + * + * @event core.delete_attachments_before + * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user + * @var mixed ids Array or comma separated list of ids corresponding to the mode + * @var bool resync Flag indicating if posts/messages/topics should be synchronized + * @var string sql_id The field name to collect/delete data for depending on the mode + * @var array post_ids Array with post ids for deleted attachment(s) + * @var array topic_ids Array with topic ids for deleted attachment(s) + * @var array message_ids Array with private message ids for deleted attachment(s) + * @var array physical Array with deleted attachment(s) physical file(s) data + * @since 3.1.7-RC1 + */ + $vars = array( + 'mode', + 'ids', + 'resync', + 'sql_id', + 'post_ids', + 'topic_ids', + 'message_ids', + 'physical', + ); + extract($this->dispatcher->trigger_event('core.delete_attachments_before', compact($vars))); + + // Delete attachments + $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' + WHERE ' . $this->db->sql_in_set($this->sql_id, $this->ids); + + $sql .= $this->sql_where; + + $this->db->sql_query($sql); + $this->num_deleted = $this->db->sql_affectedrows(); + } + + /** + * Delete attachments from filesystem + */ + protected function delete_attachments_from_filesystem() + { + $space_removed = $files_removed = 0; + + foreach ($this->physical as $file_ary) + { + if (phpbb_unlink($file_ary['filename'], 'file', true) && !$file_ary['is_orphan']) + { + // Only non-orphaned files count to the file size + $space_removed += $file_ary['filesize']; + $files_removed++; + } + + if ($file_ary['thumbnail']) + { + phpbb_unlink($file_ary['filename'], 'thumbnail', true); + } + } + + /** + * Perform additional actions after attachment(s) deletion from the filesystem + * + * @event core.delete_attachments_from_filesystem_after + * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user + * @var mixed ids Array or comma separated list of ids corresponding to the mode + * @var bool resync Flag indicating if posts/messages/topics should be synchronized + * @var string sql_id The field name to collect/delete data for depending on the mode + * @var array post_ids Array with post ids for deleted attachment(s) + * @var array topic_ids Array with topic ids for deleted attachment(s) + * @var array message_ids Array with private message ids for deleted attachment(s) + * @var array physical Array with deleted attachment(s) physical file(s) data + * @var int num_deleted The number of deleted attachment(s) from the database + * @var int space_removed The size of deleted files(s) from the filesystem + * @var int files_removed The number of deleted file(s) from the filesystem + * @since 3.1.7-RC1 + */ + $vars = array( + 'mode', + 'ids', + 'resync', + 'sql_id', + 'post_ids', + 'topic_ids', + 'message_ids', + 'physical', + 'num_deleted', + 'space_removed', + 'files_removed', + ); + extract($this->dispatcher->trigger_event('core.delete_attachments_from_filesystem_after', compact($vars))); + + if ($space_removed || $files_removed) + { + $this->config->increment('upload_dir_size', $space_removed * (-1), false); + $this->config->increment('num_files', $files_removed * (-1), false); + } + } } \ No newline at end of file -- cgit v1.2.1 From 40117c77304468120245ae05b6b99f1d2a68c9f6 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 21 Sep 2015 10:56:32 +0200 Subject: [ticket/14168] Add attachment resync class PHPBB3-14168 --- phpBB/phpbb/attachment/delete.php | 98 ++++-------------------------- phpBB/phpbb/attachment/resync.php | 123 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 87 deletions(-) create mode 100644 phpBB/phpbb/attachment/resync.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php index 7a168c2243..4ef320eab4 100644 --- a/phpBB/phpbb/attachment/delete.php +++ b/phpBB/phpbb/attachment/delete.php @@ -32,6 +32,9 @@ class delete /** @var \phpbb\event\dispatcher */ protected $dispatcher; + /** @var \phpbb\attachment\resync */ + protected $resync; + /** @var array Attachement IDs */ protected $ids; @@ -61,13 +64,15 @@ class delete * * @param config $config * @param driver_interface $db - * @param dispatcher>>>>>>> 85b6020... [ticket/14168] Move function for attachment deletion into class + * @param dispatcher $dispatcher + * @param resync $resync */ - public function __construct(config $config, driver_interface $db, dispatcher $dispatcher) + public function __construct(config $config, driver_interface $db, dispatcher $dispatcher, resync $resync) { $this->config = $config; $this->db = $db; $this->dispatcher = $dispatcher; + $this->resync = $resync; } /** @@ -158,95 +163,14 @@ class delete // No more use for the original ids unset($ids); - // Now, we need to resync posts, messages, topics. We go through every one of them // Update post indicators for posts now no longer having attachments - if (sizeof($this->post_ids)) - { - // Just check which posts are still having an assigned attachment not orphaned by querying the attachments table - $sql = 'SELECT post_msg_id - FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $this->db->sql_in_set('post_msg_id', $this->post_ids) . ' - AND in_message = 0 - AND is_orphan = 0'; - $result = $this->db->sql_query($sql); - - $remaining_ids = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $remaining_ids[] = $row['post_msg_id']; - } - $this->db->sql_freeresult($result); - - // Now only unset those ids remaining - $this->post_ids = array_diff($this->post_ids, $remaining_ids); - - if (sizeof($this->post_ids)) - { - $sql = 'UPDATE ' . POSTS_TABLE . ' - SET post_attachment = 0 - WHERE ' . $this->db->sql_in_set('post_id', $this->post_ids); - $this->db->sql_query($sql); - } - } + $this->resync->resync('post', $this->post_ids); // Update message table if messages are affected - if (sizeof($this->message_ids)) - { - // Just check which messages are still having an assigned attachment not orphaned by querying the attachments table - $sql = 'SELECT post_msg_id - FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $this->db->sql_in_set('post_msg_id', $this->message_ids) . ' - AND in_message = 1 - AND is_orphan = 0'; - $result = $this->db->sql_query($sql); - - $remaining_ids = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $remaining_ids[] = $row['post_msg_id']; - } - $this->db->sql_freeresult($result); - - // Now only unset those ids remaining - $this->message_ids = array_diff($this->message_ids, $remaining_ids); - - if (sizeof($this->message_ids)) - { - $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' - SET message_attachment = 0 - WHERE ' . $this->db->sql_in_set('msg_id', $this->message_ids); - $this->db->sql_query($sql); - } - } + $this->resync->resync('message', $this->message_ids); // Now update the topics. This is a bit trickier, because there could be posts still having attachments within the topic - if (sizeof($this->topic_ids)) - { - // Just check which topics are still having an assigned attachment not orphaned by querying the attachments table (much less entries expected) - $sql = 'SELECT topic_id - FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $this->db->sql_in_set('topic_id', $this->topic_ids) . ' - AND is_orphan = 0'; - $result = $this->db->sql_query($sql); - - $remaining_ids = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $remaining_ids[] = $row['topic_id']; - } - $this->db->sql_freeresult($result); - - // Now only unset those ids remaining - $this->topic_ids = array_diff($this->topic_ids, $remaining_ids); - - if (sizeof($this->topic_ids)) - { - $sql = 'UPDATE ' . TOPICS_TABLE . ' - SET topic_attachment = 0 - WHERE ' . $this->db->sql_in_set('topic_id', $this->topic_ids); - $this->db->sql_query($sql); - } - } + $this->resync->resync('topic', $this->topic_ids); return $this->num_deleted; } @@ -384,7 +308,7 @@ class delete // Delete attachments $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $this->db->sql_in_set($this->sql_id, $this->ids); + WHERE ' . $this->db->sql_in_set($this->sql_id, $this->ids); $sql .= $this->sql_where; diff --git a/phpBB/phpbb/attachment/resync.php b/phpBB/phpbb/attachment/resync.php new file mode 100644 index 0000000000..c247fcce7a --- /dev/null +++ b/phpBB/phpbb/attachment/resync.php @@ -0,0 +1,123 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\attachment; + +use \phpbb\db\driver\driver_interface; + +/** + * Attachment delete class + */ + +class resync +{ + /** @var driver_interface */ + protected $db; + + /** @var string Attachment table SQL ID */ + private $attach_sql_id; + + /** @var string Resync table SQL ID */ + private $resync_sql_id; + + /** @var string Resync SQL table */ + private $resync_table; + + /** @var string SQL where statement */ + private $sql_where; + + /** + * Constructor for attachment resync class + * + * @param driver_interface $db Database driver + */ + public function __construct(driver_interface $db) + { + $this->db = $db; + } + + /** + * Set type constraints for attachment resync + * + * @param string $type Type of resync; can be: message|post|topic + */ + protected function set_type_constraints($type) + { + switch ($type) + { + case 'message': + $this->attach_sql_id = 'post_msg_id'; + $this->sql_where = ' AND in_message = 1 + AND is_orphan = 0'; + $this->resync_table = PRIVMSGS_TABLE; + $this->resync_sql_id = 'msg_id'; + break; + + case 'post': + $this->attach_sql_id = 'post_msg_id'; + $this->sql_where = ' AND in_message = 0 + AND is_orphan = 0'; + $this->resync_table = POSTS_TABLE; + $this->resync_sql_id = 'post_id'; + break; + + case 'topic': + $this->attach_sql_id = 'topic_id'; + $this->sql_where = ' AND is_orphan = 0'; + $this->resync_table = TOPICS_TABLE; + $this->resync_sql_id = 'topic_id'; + break; + } + } + + /** + * Resync specified type + * + * @param string $type Type of resync + * @param array $ids IDs to resync + */ + public function resync($type, $ids) + { + if (empty($type) || !is_array($ids) || !sizeof($ids) || !in_array($type, array('post', 'topic', 'message'))) + { + return; + } + + // Just check which elements are still having an assigned attachment + // not orphaned by querying the attachments table + $sql = 'SELECT ' . $this->attach_sql_id . ' + FROM ' . ATTACHMENTS_TABLE . ' + WHERE ' . $this->db->sql_in_set($this->attach_sql_id, $ids) + . $this->sql_where; + $result = $this->db->sql_query($sql); + + $remaining_ids = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $remaining_ids[] = $row[$this->attach_sql_id]; + } + $this->db->sql_freeresult($result); + + // Now only unset those ids remaining + $ids = array_diff($ids, $remaining_ids); + + if (sizeof($ids)) + { + $sql = 'UPDATE ' . POSTS_TABLE . ' + SET ' . $type . '_attachment = 0 + WHERE ' . $this->db->sql_in_set($this->resync_sql_id, $ids); + $this->db->sql_query($sql); + } + } + +} \ No newline at end of file -- cgit v1.2.1 From e158db5daa8b9eedfea9d17b5d678320ac7f8f61 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 21 Sep 2015 11:01:01 +0200 Subject: [ticket/14168] Minor coding style fixes PHPBB3-14168 --- phpBB/phpbb/attachment/delete.php | 2 +- phpBB/phpbb/attachment/resync.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php index 4ef320eab4..32469c124c 100644 --- a/phpBB/phpbb/attachment/delete.php +++ b/phpBB/phpbb/attachment/delete.php @@ -376,4 +376,4 @@ class delete $this->config->increment('num_files', $files_removed * (-1), false); } } -} \ No newline at end of file +} diff --git a/phpBB/phpbb/attachment/resync.php b/phpBB/phpbb/attachment/resync.php index c247fcce7a..9abf961c6b 100644 --- a/phpBB/phpbb/attachment/resync.php +++ b/phpBB/phpbb/attachment/resync.php @@ -120,4 +120,4 @@ class resync } } -} \ No newline at end of file +} -- cgit v1.2.1 From cebc064f4c15b9c53210cc3729756b4d7888041b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 21 Sep 2015 14:51:39 +0200 Subject: [ticket/14168] Coding guidelines fixes PHPBB3-14168 --- phpBB/phpbb/attachment/delete.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php index 32469c124c..4c863a2205 100644 --- a/phpBB/phpbb/attachment/delete.php +++ b/phpBB/phpbb/attachment/delete.php @@ -216,20 +216,20 @@ class delete case 'message': $this->sql_id = 'post_msg_id'; $this->sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0); - break; + break; case 'topic': $this->sql_id = 'topic_id'; - break; + break; case 'user': $this->sql_id = 'poster_id'; - break; + break; case 'attach': default: $this->sql_id = 'attach_id'; - break; + break; } } -- cgit v1.2.1 From 583f42a2aa5ba8132e9e516b363ba0180fe46289 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 21 Sep 2015 16:28:53 +0200 Subject: [ticket/14168] Add tests for attachment resync class PHPBB3-14168 --- phpBB/phpbb/attachment/resync.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/resync.php b/phpBB/phpbb/attachment/resync.php index 9abf961c6b..adb642fe97 100644 --- a/phpBB/phpbb/attachment/resync.php +++ b/phpBB/phpbb/attachment/resync.php @@ -93,6 +93,8 @@ class resync return; } + $this->set_type_constraints($type); + // Just check which elements are still having an assigned attachment // not orphaned by querying the attachments table $sql = 'SELECT ' . $this->attach_sql_id . ' @@ -113,7 +115,7 @@ class resync if (sizeof($ids)) { - $sql = 'UPDATE ' . POSTS_TABLE . ' + $sql = 'UPDATE ' . $this->resync_table . ' SET ' . $type . '_attachment = 0 WHERE ' . $this->db->sql_in_set($this->resync_sql_id, $ids); $this->db->sql_query($sql); -- cgit v1.2.1 From b00c7511f022dfafb32f570db1f5fe762a62ef21 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 21 Sep 2015 22:16:23 +0200 Subject: [ticket/14168] Add tests for attachment delete class PHPBB3-14168 --- phpBB/phpbb/attachment/delete.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php index 4c863a2205..372495aef0 100644 --- a/phpBB/phpbb/attachment/delete.php +++ b/phpBB/phpbb/attachment/delete.php @@ -85,7 +85,7 @@ class delete * @return int|bool Number of deleted attachments or false if something * went wrong during attachment deletion */ - function delete($mode, $ids, $resync = true) + public function delete($mode, $ids, $resync = true) { if (!$this->set_attachment_ids($ids)) { -- cgit v1.2.1 From 04786313892df25f5adce555ebae6b2e5ad4d222 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 23 Sep 2015 10:17:38 +0200 Subject: [ticket/14168] Move phpbb_unlink() into attachment delete class PHPBB3-14168 --- phpBB/phpbb/attachment/delete.php | 70 ++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php index 372495aef0..ad385861a1 100644 --- a/phpBB/phpbb/attachment/delete.php +++ b/phpBB/phpbb/attachment/delete.php @@ -16,6 +16,7 @@ namespace phpbb\attachment; use \phpbb\config\config; use \phpbb\db\driver\driver_interface; use \phpbb\event\dispatcher; +use \phpbb\filesystem\filesystem; /** * Attachment delete class @@ -23,18 +24,24 @@ use \phpbb\event\dispatcher; class delete { - /** @var \phpbb\config\config */ + /** @var config */ protected $config; - /** @var \phpbb\db\driver\driver_interface */ + /** @var driver_interface */ protected $db; /** @var \phpbb\event\dispatcher */ protected $dispatcher; - /** @var \phpbb\attachment\resync */ + /** @var filesystem */ + protected $filesystem; + + /** @var resync */ protected $resync; + /** @var string phpBB root path */ + protected $phpbb_root_path; + /** @var array Attachement IDs */ protected $ids; @@ -65,14 +72,18 @@ class delete * @param config $config * @param driver_interface $db * @param dispatcher $dispatcher + * @param filesystem $filesystem * @param resync $resync + * @param string $phpbb_root_path */ - public function __construct(config $config, driver_interface $db, dispatcher $dispatcher, resync $resync) + public function __construct(config $config, driver_interface $db, dispatcher $dispatcher, filesystem $filesystem, resync $resync, $phpbb_root_path) { $this->config = $config; $this->db = $db; $this->dispatcher = $dispatcher; + $this->filesystem = $filesystem; $this->resync = $resync; + $this->phpbb_root_path = $phpbb_root_path; } /** @@ -152,7 +163,7 @@ class delete } // Delete attachments from filesystem - $this->delete_attachments_from_filesystem(); + $this->remove_from_filesystem(); // If we do not resync, we do not need to adjust any message, post, topic or user entries if (!$resync) @@ -319,13 +330,13 @@ class delete /** * Delete attachments from filesystem */ - protected function delete_attachments_from_filesystem() + protected function remove_from_filesystem() { $space_removed = $files_removed = 0; foreach ($this->physical as $file_ary) { - if (phpbb_unlink($file_ary['filename'], 'file', true) && !$file_ary['is_orphan']) + if ($this->unlink_attachment($file_ary['filename'], 'file', true) && !$file_ary['is_orphan']) { // Only non-orphaned files count to the file size $space_removed += $file_ary['filesize']; @@ -334,7 +345,7 @@ class delete if ($file_ary['thumbnail']) { - phpbb_unlink($file_ary['filename'], 'thumbnail', true); + $this->unlink_attachment($file_ary['filename'], 'thumbnail', true); } } @@ -376,4 +387,47 @@ class delete $this->config->increment('num_files', $files_removed * (-1), false); } } + + /** + * Delete attachment from filesystem + * + * @param string $filename Filename of attachment + * @param string $mode Delete mode + * @param bool $entry_removed Whether entry was removed. Defaults to false + * @return bool True if file was removed, false if not + */ + public function unlink_attachment($filename, $mode = 'file', $entry_removed = false) + { + // Because of copying topics or modifications a physical filename could be assigned more than once. If so, do not remove the file itself. + $sql = 'SELECT COUNT(attach_id) AS num_entries + FROM ' . ATTACHMENTS_TABLE . " + WHERE physical_filename = '" . $this->db->sql_escape(utf8_basename($filename)) . "'"; + $result = $this->db->sql_query($sql); + $num_entries = (int) $this->db->sql_fetchfield('num_entries'); + $this->db->sql_freeresult($result); + + // Do not remove file if at least one additional entry with the same name exist. + if (($entry_removed && $num_entries > 0) || (!$entry_removed && $num_entries > 1)) + { + return false; + } + + $filename = ($mode == 'thumbnail') ? 'thumb_' . utf8_basename($filename) : utf8_basename($filename); + $filepath = $this->phpbb_root_path . $this->config['upload_path'] . '/' . $filename; + + try + { + if ($this->filesystem->exists($filepath)) + { + $this->filesystem->remove($this->phpbb_root_path . $this->config['upload_path'] . '/' . $filename); + return true; + } + } + catch (\phpbb\filesystem\exception\filesystem_exception $exception) + { + // Fail is covered by return statement below + } + + return false; + } } -- cgit v1.2.1 From 36ea105236c87e84ca2b9f0a193b5b8721e8cf97 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 4 Oct 2015 11:10:07 +0200 Subject: [ticket/14168] Move image check and don't use trigger_error() PHPBB3-14168 --- phpBB/phpbb/attachment/upload.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php index d57b33b137..ae8d70c18e 100644 --- a/phpBB/phpbb/attachment/upload.php +++ b/phpBB/phpbb/attachment/upload.php @@ -160,6 +160,9 @@ class upload // Do we have to create a thumbnail? $this->file_data['thumbnail'] = ($is_image && $this->config['img_create_thumbnail']) ? 1 : 0; + // Make sure the image category only holds valid images... + $this->check_image($is_image); + if (sizeof($this->file->error)) { $this->file->remove(); @@ -169,9 +172,6 @@ class upload return $this->file_data; } - // Make sure the image category only holds valid images... - $this->check_image($is_image); - $this->fill_file_data(); $filedata = $this->file_data; @@ -263,7 +263,7 @@ class upload // If this error occurs a user tried to exploit an IE Bug by renaming extensions // Since the image category is displaying content inline we need to catch this. - trigger_error($this->language->lang('ATTACHED_IMAGE_NOT_IMAGE')); + $this->file->set_error($this->language->lang('ATTACHED_IMAGE_NOT_IMAGE')); } } -- cgit v1.2.1 From 80e3c79f383366915b799675c6bcd3e15715780e Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 7 Oct 2015 11:04:15 +0200 Subject: [ticket/14168] Minor coding style fixes PHPBB3-14168 --- phpBB/phpbb/attachment/delete.php | 3 +-- phpBB/phpbb/attachment/resync.php | 1 - phpBB/phpbb/attachment/upload.php | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php index ad385861a1..e093da8865 100644 --- a/phpBB/phpbb/attachment/delete.php +++ b/phpBB/phpbb/attachment/delete.php @@ -21,7 +21,6 @@ use \phpbb\filesystem\filesystem; /** * Attachment delete class */ - class delete { /** @var config */ @@ -189,7 +188,7 @@ class delete /** * Set attachment IDs * - * @param array $ids + * @param mixed $ids ID or array of IDs * * @return bool True if attachment IDs were set, false if not */ diff --git a/phpBB/phpbb/attachment/resync.php b/phpBB/phpbb/attachment/resync.php index adb642fe97..699d37340d 100644 --- a/phpBB/phpbb/attachment/resync.php +++ b/phpBB/phpbb/attachment/resync.php @@ -18,7 +18,6 @@ use \phpbb\db\driver\driver_interface; /** * Attachment delete class */ - class resync { /** @var driver_interface */ diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php index ae8d70c18e..2d49e05b71 100644 --- a/phpBB/phpbb/attachment/upload.php +++ b/phpBB/phpbb/attachment/upload.php @@ -25,7 +25,6 @@ use \phpbb\user; /** * Attachment upload class */ - class upload { /** @var auth */ -- cgit v1.2.1 From 22b36d9d0e50fdc820912cca0164fccc7b5785a1 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 9 Oct 2015 08:03:53 +0200 Subject: [ticket/14168] Use correct docblock PHPBB3-14168 --- phpBB/phpbb/attachment/resync.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/resync.php b/phpBB/phpbb/attachment/resync.php index 699d37340d..6c2e0a8b0d 100644 --- a/phpBB/phpbb/attachment/resync.php +++ b/phpBB/phpbb/attachment/resync.php @@ -16,7 +16,7 @@ namespace phpbb\attachment; use \phpbb\db\driver\driver_interface; /** - * Attachment delete class + * Attachment resync class */ class resync { -- cgit v1.2.1 From c78dbd2eea2dae14b076d8d800474c8715982277 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 9 Oct 2015 09:45:28 +0200 Subject: [ticket/14168] Add attachment manager service PHPBB3-14168 --- phpBB/phpbb/attachment/manager.php | 99 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 phpBB/phpbb/attachment/manager.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/manager.php b/phpBB/phpbb/attachment/manager.php new file mode 100644 index 0000000000..0aeadf3e3e --- /dev/null +++ b/phpBB/phpbb/attachment/manager.php @@ -0,0 +1,99 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\attachment; + +/** + * Attachment manager + */ +class manager +{ + /** @var delete Attachment delete class */ + protected $delete; + + /** @var resync Attachment resync class */ + protected $resync; + + /** @var upload Attachment upload class */ + protected $upload; + + /** + * Constructor for attachment manager + * + * @param delete $delete Attachment delete class + * @param resync $resync Attachment resync class + * @param upload $upload Attachment upload class + */ + public function __construct(delete $delete, resync $resync, upload $upload) + { + $this->delete = $delete; + $this->resync = $resync; + $this->upload = $upload; + } + + /** + * Wrapper method for deleting attachments + * + * @param string $mode can be: post|message|topic|attach|user + * @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids + * @param bool $resync set this to false if you are deleting posts or topics + * + * @return int|bool Number of deleted attachments or false if something + * went wrong during attachment deletion + */ + public function delete($mode, $id, $resync = true) + { + $this->delete->delete($mode, $id, $resync); + } + + /** + * Wrapper method for deleting attachments from filesystem + * + * @param string $filename Filename of attachment + * @param string $mode Delete mode + * @param bool $entry_removed Whether entry was removed. Defaults to false + * @return bool True if file was removed, false if not + */ + public function unlink($filename, $mode = 'file', $entry_removed = false) + { + $this->delete->unlink_attachment($filename, $mode, $entry_removed); + } + + /** + * Wrapper method for resyncing specified type + * + * @param string $type Type of resync + * @param array $ids IDs to resync + */ + public function resync($type, $ids) + { + $this->resync->resync($type, $ids); + } + + /** + * Wrapper method for uploading attachment + * + * @param string $form_name The form name of the file upload input + * @param int $forum_id The id of the forum + * @param bool $local Whether the file is local or not + * @param string $local_storage The path to the local file + * @param bool $is_message Whether it is a PM or not + * @param array $local_filedata An file data object created for the local file + * + * @return object filespec + */ + public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = []) + { + $this->upload->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata); + } +} -- cgit v1.2.1 From 53008c87828746c316019e758641a2a4e37f522b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 9 Oct 2015 12:14:19 +0200 Subject: [ticket/14168] Fix tabs in manager and add test file PHPBB3-14168 --- phpBB/phpbb/attachment/manager.php | 142 ++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 71 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/manager.php b/phpBB/phpbb/attachment/manager.php index 0aeadf3e3e..414a8edfdd 100644 --- a/phpBB/phpbb/attachment/manager.php +++ b/phpBB/phpbb/attachment/manager.php @@ -18,82 +18,82 @@ namespace phpbb\attachment; */ class manager { - /** @var delete Attachment delete class */ - protected $delete; + /** @var delete Attachment delete class */ + protected $delete; - /** @var resync Attachment resync class */ - protected $resync; + /** @var resync Attachment resync class */ + protected $resync; - /** @var upload Attachment upload class */ - protected $upload; + /** @var upload Attachment upload class */ + protected $upload; - /** - * Constructor for attachment manager - * - * @param delete $delete Attachment delete class - * @param resync $resync Attachment resync class - * @param upload $upload Attachment upload class - */ - public function __construct(delete $delete, resync $resync, upload $upload) - { - $this->delete = $delete; - $this->resync = $resync; - $this->upload = $upload; - } + /** + * Constructor for attachment manager + * + * @param delete $delete Attachment delete class + * @param resync $resync Attachment resync class + * @param upload $upload Attachment upload class + */ + public function __construct(delete $delete, resync $resync, upload $upload) + { + $this->delete = $delete; + $this->resync = $resync; + $this->upload = $upload; + } - /** - * Wrapper method for deleting attachments - * - * @param string $mode can be: post|message|topic|attach|user - * @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids - * @param bool $resync set this to false if you are deleting posts or topics - * - * @return int|bool Number of deleted attachments or false if something - * went wrong during attachment deletion - */ - public function delete($mode, $id, $resync = true) - { - $this->delete->delete($mode, $id, $resync); - } + /** + * Wrapper method for deleting attachments + * + * @param string $mode can be: post|message|topic|attach|user + * @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids + * @param bool $resync set this to false if you are deleting posts or topics + * + * @return int|bool Number of deleted attachments or false if something + * went wrong during attachment deletion + */ + public function delete($mode, $id, $resync = true) + { + return $this->delete->delete($mode, $id, $resync); + } - /** - * Wrapper method for deleting attachments from filesystem - * - * @param string $filename Filename of attachment - * @param string $mode Delete mode - * @param bool $entry_removed Whether entry was removed. Defaults to false - * @return bool True if file was removed, false if not - */ - public function unlink($filename, $mode = 'file', $entry_removed = false) - { - $this->delete->unlink_attachment($filename, $mode, $entry_removed); - } + /** + * Wrapper method for deleting attachments from filesystem + * + * @param string $filename Filename of attachment + * @param string $mode Delete mode + * @param bool $entry_removed Whether entry was removed. Defaults to false + * @return bool True if file was removed, false if not + */ + public function unlink($filename, $mode = 'file', $entry_removed = false) + { + return $this->delete->unlink_attachment($filename, $mode, $entry_removed); + } - /** - * Wrapper method for resyncing specified type - * - * @param string $type Type of resync - * @param array $ids IDs to resync - */ - public function resync($type, $ids) - { - $this->resync->resync($type, $ids); - } + /** + * Wrapper method for resyncing specified type + * + * @param string $type Type of resync + * @param array $ids IDs to resync + */ + public function resync($type, $ids) + { + $this->resync->resync($type, $ids); + } - /** - * Wrapper method for uploading attachment - * - * @param string $form_name The form name of the file upload input - * @param int $forum_id The id of the forum - * @param bool $local Whether the file is local or not - * @param string $local_storage The path to the local file - * @param bool $is_message Whether it is a PM or not - * @param array $local_filedata An file data object created for the local file - * - * @return object filespec - */ - public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = []) - { - $this->upload->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata); - } + /** + * Wrapper method for uploading attachment + * + * @param string $form_name The form name of the file upload input + * @param int $forum_id The id of the forum + * @param bool $local Whether the file is local or not + * @param string $local_storage The path to the local file + * @param bool $is_message Whether it is a PM or not + * @param array $local_filedata An file data object created for the local file + * + * @return object filespec + */ + public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = []) + { + return $this->upload->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata); + } } -- cgit v1.2.1 From a0167ad41037d7fe9214ca36c4c7097177361a6b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 9 Oct 2015 14:35:40 +0200 Subject: [ticket/14168] Fix docblock in manager PHPBB3-14168 --- phpBB/phpbb/attachment/manager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/manager.php b/phpBB/phpbb/attachment/manager.php index 414a8edfdd..9dcd3c5c92 100644 --- a/phpBB/phpbb/attachment/manager.php +++ b/phpBB/phpbb/attachment/manager.php @@ -51,9 +51,9 @@ class manager * @return int|bool Number of deleted attachments or false if something * went wrong during attachment deletion */ - public function delete($mode, $id, $resync = true) + public function delete($mode, $ids, $resync = true) { - return $this->delete->delete($mode, $id, $resync); + return $this->delete->delete($mode, $ids, $resync); } /** -- cgit v1.2.1 From 21201aa1ab6dd94534c6f87f235d312d07d1db24 Mon Sep 17 00:00:00 2001 From: Zoddo Date: Sun, 13 Sep 2015 14:43:50 +0200 Subject: [ticket/13101] Remove existing MSN/WLM custom profile field PHPBB3-13101 --- .../data/v320/remove_profilefield_wlm.php | 150 +++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/remove_profilefield_wlm.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/remove_profilefield_wlm.php b/phpBB/phpbb/db/migration/data/v320/remove_profilefield_wlm.php new file mode 100644 index 0000000000..2898c708f8 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/remove_profilefield_wlm.php @@ -0,0 +1,150 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class remove_profilefield_wlm extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\profilefield_wlm'); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'profile_fields_data' => array( + 'pf_phpbb_wlm', + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'profile_fields_data' => array( + 'pf_phpbb_wlm' => array('VCHAR', ''), + ), + ), + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'delete_custom_profile_field_data'))), + ); + } + + public function revert_data() + { + return array( + array('custom', array(array($this, 'create_custom_field'))), + ); + } + + public function delete_custom_profile_field_data() + { + $field_id = $this->get_custom_profile_field_id(); + + $sql = 'DELETE FROM ' . PROFILE_FIELDS_TABLE . ' + WHERE field_id = ' . (int) $field_id; + $this->db->sql_query($sql); + + $sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . ' + WHERE field_id = ' . (int) $field_id; + $this->db->sql_query($sql); + + $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . ' + WHERE field_id = ' . (int) $field_id; + $this->db->sql_query($sql); + } + + /** + * Get custom profile field id + * @return int custom profile filed id + */ + public function get_custom_profile_field_id() + { + $sql = 'SELECT field_id + FROM ' . PROFILE_FIELDS_TABLE . " + WHERE field_name = 'phpbb_wlm'"; + $result = $this->db->sql_query($sql); + $field_id = (int) $this->db->sql_fetchfield('field_id'); + $this->db->sql_freeresult($result); + + return $field_id; + } + + public function create_custom_field() + { + $sql = 'SELECT MAX(field_order) as max_field_order + FROM ' . PROFILE_FIELDS_TABLE; + $result = $this->db->sql_query($sql); + $max_field_order = (int) $this->db->sql_fetchfield('max_field_order'); + $this->db->sql_freeresult($result); + + $sql_ary = array( + 'field_name' => 'phpbb_wlm', + 'field_type' => 'profilefields.type.string', + 'field_ident' => 'phpbb_wlm', + 'field_length' => '40', + 'field_minlen' => '5', + 'field_maxlen' => '255', + 'field_novalue' => '', + 'field_default_value' => '', + 'field_validation' => '.*', + 'field_required' => 0, + 'field_show_novalue' => 0, + 'field_show_on_reg' => 0, + 'field_show_on_pm' => 1, + 'field_show_on_vt' => 1, + 'field_show_on_ml' => 0, + 'field_show_profile' => 1, + 'field_hide' => 0, + 'field_no_view' => 0, + 'field_active' => 1, + 'field_is_contact' => 1, + 'field_contact_desc' => '', + 'field_contact_url' => '', + 'field_order' => $max_field_order + 1, + ); + + $sql = 'INSERT INTO ' . PROFILE_FIELDS_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); + $this->db->sql_query($sql); + $field_id = (int) $this->db->sql_nextid(); + + $insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, PROFILE_LANG_TABLE); + + $sql = 'SELECT lang_id + FROM ' . LANG_TABLE; + $result = $this->db->sql_query($sql); + $lang_name = 'WLM'; + while ($lang_id = (int) $this->db->sql_fetchfield('lang_id')) + { + $insert_buffer->insert(array( + 'field_id' => (int) $field_id, + 'lang_id' => (int) $lang_id, + 'lang_name' => $lang_name, + 'lang_explain' => '', + 'lang_default_value' => '', + )); + } + $this->db->sql_freeresult($result); + + $insert_buffer->flush(); + } +} -- cgit v1.2.1 From 3937f1f4ae77b29faf69292783cc3ae267785ee4 Mon Sep 17 00:00:00 2001 From: Zoddo Date: Sat, 12 Sep 2015 00:53:33 +0200 Subject: [ticket/14157] Allow to set the alt/title attribute on post icons PHPBB3-14157 --- phpBB/phpbb/cache/service.php | 1 + phpBB/phpbb/db/migration/data/v320/icons_alt.php | 44 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/icons_alt.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/service.php b/phpBB/phpbb/cache/service.php index 56727c2ad5..a022c00bc6 100644 --- a/phpBB/phpbb/cache/service.php +++ b/phpBB/phpbb/cache/service.php @@ -141,6 +141,7 @@ class service $icons[$row['icons_id']]['img'] = $row['icons_url']; $icons[$row['icons_id']]['width'] = (int) $row['icons_width']; $icons[$row['icons_id']]['height'] = (int) $row['icons_height']; + $icons[$row['icons_id']]['alt'] = ($row['icons_alt']) ? $row['icons_alt'] : ''; $icons[$row['icons_id']]['display'] = (bool) $row['display_on_posting']; } $this->db->sql_freeresult($result); diff --git a/phpBB/phpbb/db/migration/data/v320/icons_alt.php b/phpBB/phpbb/db/migration/data/v320/icons_alt.php new file mode 100644 index 0000000000..7071ae78db --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/icons_alt.php @@ -0,0 +1,44 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class icons_alt extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\dev'); + } + + public function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'icons' => array( + 'icons_alt' => array('VCHAR', '', 'after' => 'icons_height'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'icons' => array( + 'icons_alt', + ), + ), + ); + } +} -- cgit v1.2.1 From bb2634b5e5bdee53118eff8cdba3fea73932ff47 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 12 Oct 2015 12:11:26 +0200 Subject: [ticket/14168] Correctly state return type of upload and upload_attachment PHPBB3-14168 --- phpBB/phpbb/attachment/manager.php | 2 +- phpBB/phpbb/attachment/upload.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/manager.php b/phpBB/phpbb/attachment/manager.php index 9dcd3c5c92..3c47171b2f 100644 --- a/phpBB/phpbb/attachment/manager.php +++ b/phpBB/phpbb/attachment/manager.php @@ -90,7 +90,7 @@ class manager * @param bool $is_message Whether it is a PM or not * @param array $local_filedata An file data object created for the local file * - * @return object filespec + * @return array File data array */ public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = []) { diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php index 2d49e05b71..957558768b 100644 --- a/phpBB/phpbb/attachment/upload.php +++ b/phpBB/phpbb/attachment/upload.php @@ -104,7 +104,7 @@ class upload * @param bool $is_message Whether it is a PM or not * @param array $local_filedata An file data object created for the local file * - * @return object filespec + * @return array File data array */ public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = array()) { -- cgit v1.2.1 From b64a37d451132dcf7ef5fc3d6e700a6fb6decd90 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Tue, 13 Oct 2015 23:40:52 -0700 Subject: [ticket/14237] Use $language class for notifications PHPBB3-14237 --- phpBB/phpbb/notification/manager.php | 36 +++++++++--- phpBB/phpbb/notification/method/board.php | 1 + phpBB/phpbb/notification/method/messenger_base.php | 1 + .../notification/type/admin_activate_user.php | 2 +- phpBB/phpbb/notification/type/base.php | 64 +++++++++++++--------- phpBB/phpbb/notification/type/disapprove_post.php | 6 +- phpBB/phpbb/notification/type/disapprove_topic.php | 6 +- phpBB/phpbb/notification/type/group_request.php | 2 +- .../notification/type/group_request_approved.php | 2 +- phpBB/phpbb/notification/type/pm.php | 4 +- phpBB/phpbb/notification/type/post.php | 11 ++-- phpBB/phpbb/notification/type/quote.php | 1 + phpBB/phpbb/notification/type/report_pm.php | 23 ++++---- phpBB/phpbb/notification/type/report_pm_closed.php | 4 +- phpBB/phpbb/notification/type/report_post.php | 16 +++--- .../phpbb/notification/type/report_post_closed.php | 4 +- phpBB/phpbb/notification/type/topic.php | 8 ++- 17 files changed, 115 insertions(+), 76 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index 4be678ac91..080d2ecb1d 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -44,6 +44,9 @@ class manager /** @var \phpbb\cache\service */ protected $cache; + /** @var \phpbb\language\language */ + protected $language; + /** @var \phpbb\user */ protected $user; @@ -63,13 +66,14 @@ class manager * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\cache\service $cache + * @param \phpbb\language\language $language * @param \phpbb\user $user * @param string $notification_types_table * @param string $user_notifications_table * * @return \phpbb\notification\manager */ - public function __construct($notification_types, $notification_methods, ContainerInterface $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\event\dispatcher_interface $phpbb_dispatcher, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\user $user, $notification_types_table, $user_notifications_table) + public function __construct($notification_types, $notification_methods, ContainerInterface $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\event\dispatcher_interface $phpbb_dispatcher, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\language\language $language, \phpbb\user $user, $notification_types_table, $user_notifications_table) { $this->notification_types = $notification_types; $this->notification_methods = $notification_methods; @@ -79,6 +83,7 @@ class manager $this->phpbb_dispatcher = $phpbb_dispatcher; $this->db = $db; $this->cache = $cache; + $this->language = $language; $this->user = $user; $this->notification_types_table = $notification_types_table; @@ -111,7 +116,7 @@ class manager if (! $method instanceof \phpbb\notification\method\method_interface) { - throw new \phpbb\notification\exception($this->user->lang('NOTIFICATION_METHOD_INVALID', $method_name)); + throw new \phpbb\notification\exception($this->language->lang('NOTIFICATION_METHOD_INVALID', $method_name)); } else if ($method->is_available()) { @@ -166,7 +171,7 @@ class manager $notification_type_id = false; } - /** @var method_interface $method */ + /** @var method\method_interface $method */ foreach ($this->get_available_subscription_methods() as $method) { $method->mark_notifications($notification_type_id, $item_id, $user_id, $time, $mark_read); @@ -208,6 +213,7 @@ class manager $notification_type_id = $this->get_notification_type_id($notification_type_name); } + /** @var method\method_interface $method */ foreach ($this->get_available_subscription_methods() as $method) { $method->mark_notifications_by_parent($notification_type_id, $item_parent_id, $user_id, $time, $mark_read); @@ -263,8 +269,6 @@ class manager return $notified_users; } - $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data); - // find out which users want to receive this type of notification $notify_users = $this->get_item_type_class($notification_type_name)->find_users_for_notification($data, $options); @@ -317,7 +321,7 @@ class manager $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data); $user_ids = array(); - $notification_objects = $notification_methods = array(); + $notification_methods = array(); // Never send notifications to the anonymous user! unset($notify_users[ANONYMOUS]); @@ -325,6 +329,7 @@ class manager // Make sure not to send new notifications to users who've already been notified about this item // This may happen when an item was added, but now new users are able to see the item // We remove each user which was already notified by at least one method. + /** @var method\method_interface $method */ foreach ($this->get_subscription_methods_instances() as $method) { $notified_users = $method->get_notified_users($notification_type_id, array('item_id' => $item_id)); @@ -415,6 +420,7 @@ class manager $options['item_id'] = $notification->get_item_id($data); } + /** @var method\method_interface $method */ foreach ($this->get_available_subscription_methods() as $method) { $method->update_notification($notification, $data, $options); @@ -443,6 +449,7 @@ class manager $notification_type_id = $this->get_notification_type_id($notification_type_name); + /** @var method\method_interface $method */ foreach ($this->get_available_subscription_methods() as $method) { $method->delete_notifications($notification_type_id, $item_id, $parent_id, $user_id); @@ -462,6 +469,7 @@ class manager foreach ($this->notification_types as $type_name => $data) { + /** @var type\base $type */ $type = $this->get_item_type_class($type_name); if ($type instanceof \phpbb\notification\type\type_interface && $type->is_available()) @@ -497,6 +505,7 @@ class manager { $subscription_methods = array(); + /** @var method\method_interface $method */ foreach ($this->get_available_subscription_methods() as $method_name => $method) { $subscription_methods[$method_name] = array( @@ -539,6 +548,7 @@ class manager { $subscription_methods = array(); + /** @var method\method_interface $method */ foreach ($this->get_subscription_methods_instances() as $method_name => $method) { if ($method->is_available()) @@ -768,6 +778,7 @@ class manager { $notification_type_id = $this->get_notification_type_id($notification_type_name); + /** @var method\method_interface $method */ foreach ($this->get_available_subscription_methods() as $method) { $method->purge_notifications($notification_type_id); @@ -805,6 +816,7 @@ class manager */ public function prune_notifications($timestamp, $only_read = true) { + /** @var method\method_interface $method */ foreach ($this->get_available_subscription_methods() as $method) { $method->prune_notifications($timestamp, $only_read); @@ -834,7 +846,9 @@ class manager /** * Helper to get the notifications item type class and set it up * - * @return type\type_interface + * @param string $notification_type_name + * @param array $data + * @return \phpbb\notification\type\type_interface */ public function get_item_type_class($notification_type_name, $data = array()) { @@ -848,7 +862,8 @@ class manager /** * Helper to get the notifications method class and set it up * - * @return method\method_interface + * @param string $method_name + * @return \phpbb\notification\method\method_interface */ public function get_method_class($method_name) { @@ -858,7 +873,8 @@ class manager /** * Helper to load objects (notification types/methods) * - * @return method\method_interface|type\type_interface + * @param string $object_name + * @return \phpbb\notification\method\method_interface|\phpbb\notification\type\type_interface */ protected function load_object($object_name) { @@ -950,6 +966,8 @@ class manager $notification_type_id = $this->get_notification_type_id($notification_type_name); $notified_users = array(); + + /** @var method\method_interface $method */ foreach ($this->get_available_subscription_methods() as $method) { $notified_users = $notified_users + $method->get_notified_users($notification_type_id, $options); diff --git a/phpBB/phpbb/notification/method/board.php b/phpBB/phpbb/notification/method/board.php index c45f3a8caa..931b252daa 100644 --- a/phpBB/phpbb/notification/method/board.php +++ b/phpBB/phpbb/notification/method/board.php @@ -266,6 +266,7 @@ class board extends \phpbb\notification\method\base { $insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, $this->notifications_table); + /** @var \phpbb\notification\type\type_interface $notification */ foreach ($this->queue as $notification) { $data = $notification->get_insert_array(); diff --git a/phpBB/phpbb/notification/method/messenger_base.php b/phpBB/phpbb/notification/method/messenger_base.php index 61119b9882..8a8e284e13 100644 --- a/phpBB/phpbb/notification/method/messenger_base.php +++ b/phpBB/phpbb/notification/method/messenger_base.php @@ -82,6 +82,7 @@ abstract class messenger_base extends \phpbb\notification\method\base $messenger = new \messenger(); // Time to go through the queue and send emails + /** @var \phpbb\notification\type\type_interface $notification */ foreach ($this->queue as $notification) { if ($notification->get_email_template() === false) diff --git a/phpBB/phpbb/notification/type/admin_activate_user.php b/phpBB/phpbb/notification/type/admin_activate_user.php index b191fa62ae..9f2ae857ef 100644 --- a/phpBB/phpbb/notification/type/admin_activate_user.php +++ b/phpBB/phpbb/notification/type/admin_activate_user.php @@ -130,7 +130,7 @@ class admin_activate_user extends \phpbb\notification\type\base { $username = $this->user_loader->get_username($this->item_id, 'no_profile'); - return $this->user->lang($this->language_key, $username); + return $this->language->lang($this->language_key, $username); } /** diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index 31e853d7d9..4aacb1c99e 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -24,6 +24,9 @@ abstract class base implements \phpbb\notification\type\type_interface /** @var \phpbb\db\driver\driver_interface */ protected $db; + /** @var \phpbb\language\language */ + protected $language; + /** @var \phpbb\user */ protected $user; @@ -56,7 +59,7 @@ abstract class base implements \phpbb\notification\type\type_interface protected $notification_type_id; /** - * Indentification data + * Identification data * notification_type_id - ID of the item type (auto generated, from notification types table) * item_id - ID of the item (e.g. post_id, msg_id) * item_parent_id - Parent item id (ex: for topic => forum_id, for post => topic_id, etc) @@ -71,19 +74,20 @@ abstract class base implements \phpbb\notification\type\type_interface private $data = array(); /** - * Notification Type Base Constructor - * - * @param \phpbb\db\driver\driver_interface $db - * @param \phpbb\user $user - * @param \phpbb\auth\auth $auth - * @param string $phpbb_root_path - * @param string $php_ext - * @param string $user_notifications_table - * @return \phpbb\notification\type\base - */ - public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext, $user_notifications_table) + * Notification Type Base Constructor + * + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\language\language $language + * @param \phpbb\user $user + * @param \phpbb\auth\auth $auth + * @param string $phpbb_root_path + * @param string $php_ext + * @param string $user_notifications_table + */ + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\language\language $language, \phpbb\user $user, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext, $user_notifications_table) { $this->db = $db; + $this->language = $language; $this->user = $user; $this->auth = $auth; @@ -192,7 +196,7 @@ abstract class base implements \phpbb\notification\type\type_interface 'notification_time' => time(), 'notification_read' => false, - 'notification_data' => array(), + 'notification_data' => array(), ), $this->data); } @@ -304,6 +308,7 @@ abstract class base implements \phpbb\notification\type\type_interface * URL to unsubscribe to this notification (fall back) * * @param string|bool $method Method name to unsubscribe from (email|jabber|etc), False to unsubscribe from all notifications for this item + * @return false */ public function get_unsubscribe_url($method = false) { @@ -371,8 +376,11 @@ abstract class base implements \phpbb\notification\type\type_interface } /** - * Load the special items (fall back) - */ + * Load the special items (fall back) + * + * @param array $data + * @param array $notifications + */ public function load_special($data, $notifications) { return; @@ -389,10 +397,12 @@ abstract class base implements \phpbb\notification\type\type_interface } /** - * Pre create insert array function (fall back) - * - * @return array - */ + * Pre create insert array function (fall back) + * + * @param array $type_data + * @param array $notify_users + * @return array + */ public function pre_create_insert_array($type_data, $notify_users) { return array(); @@ -403,13 +413,13 @@ abstract class base implements \phpbb\notification\type\type_interface */ /** - * Find the users who want to receive notifications (helper) - * - * @param array $user_ids User IDs to check if they want to receive notifications - * (Bool False to check all users besides anonymous and bots (USER_IGNORE)) - * - * @return array - */ + * Find the users who want to receive notifications (helper) + * + * @param array|bool $user_ids User IDs to check if they want to receive notifications + * (Bool False to check all users besides anonymous and bots (USER_IGNORE)) + * @param array $options + * @return array + */ protected function check_user_notification_options($user_ids = false, $options = array()) { $options = array_merge(array( @@ -505,6 +515,8 @@ abstract class base implements \phpbb\notification\type\type_interface { $this->notification_manager->mark_notifications($this->get_type(), (int) $this->item_id, (int) $this->user_id, false, $this->notification_read); } + + return null; } /** diff --git a/phpBB/phpbb/notification/type/disapprove_post.php b/phpBB/phpbb/notification/type/disapprove_post.php index 21338bddb7..2d908eb254 100644 --- a/phpBB/phpbb/notification/type/disapprove_post.php +++ b/phpBB/phpbb/notification/type/disapprove_post.php @@ -73,7 +73,7 @@ class disapprove_post extends \phpbb\notification\type\approve_post */ public function get_title() { - return $this->user->lang($this->language_key); + return $this->language->lang($this->language_key); } /** @@ -83,7 +83,7 @@ class disapprove_post extends \phpbb\notification\type\approve_post */ public function get_reference() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REFERENCE', censor_text($this->get_data('topic_title')) ); @@ -96,7 +96,7 @@ class disapprove_post extends \phpbb\notification\type\approve_post */ public function get_reason() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REASON', $this->get_data('disapprove_reason') ); diff --git a/phpBB/phpbb/notification/type/disapprove_topic.php b/phpBB/phpbb/notification/type/disapprove_topic.php index 30a23a83fe..c2522fb562 100644 --- a/phpBB/phpbb/notification/type/disapprove_topic.php +++ b/phpBB/phpbb/notification/type/disapprove_topic.php @@ -73,7 +73,7 @@ class disapprove_topic extends \phpbb\notification\type\approve_topic */ public function get_title() { - return $this->user->lang($this->language_key); + return $this->language->lang($this->language_key); } /** @@ -83,7 +83,7 @@ class disapprove_topic extends \phpbb\notification\type\approve_topic */ public function get_reference() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REFERENCE', censor_text($this->get_data('topic_title')) ); @@ -96,7 +96,7 @@ class disapprove_topic extends \phpbb\notification\type\approve_topic */ public function get_reason() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REASON', $this->get_data('disapprove_reason') ); diff --git a/phpBB/phpbb/notification/type/group_request.php b/phpBB/phpbb/notification/type/group_request.php index 8a0027bfec..28a9e73bf9 100644 --- a/phpBB/phpbb/notification/type/group_request.php +++ b/phpBB/phpbb/notification/type/group_request.php @@ -114,7 +114,7 @@ class group_request extends \phpbb\notification\type\base { $username = $this->user_loader->get_username($this->item_id, 'no_profile'); - return $this->user->lang('NOTIFICATION_GROUP_REQUEST', $username, $this->get_data('group_name')); + return $this->language->lang('NOTIFICATION_GROUP_REQUEST', $username, $this->get_data('group_name')); } /** diff --git a/phpBB/phpbb/notification/type/group_request_approved.php b/phpBB/phpbb/notification/type/group_request_approved.php index dc353f3380..f55d28bafd 100644 --- a/phpBB/phpbb/notification/type/group_request_approved.php +++ b/phpBB/phpbb/notification/type/group_request_approved.php @@ -69,7 +69,7 @@ class group_request_approved extends \phpbb\notification\type\base */ public function get_title() { - return $this->user->lang('NOTIFICATION_GROUP_REQUEST_APPROVED', $this->get_data('group_name')); + return $this->language->lang('NOTIFICATION_GROUP_REQUEST_APPROVED', $this->get_data('group_name')); } /** diff --git a/phpBB/phpbb/notification/type/pm.php b/phpBB/phpbb/notification/type/pm.php index 2de2dcfa0b..8fb9172911 100644 --- a/phpBB/phpbb/notification/type/pm.php +++ b/phpBB/phpbb/notification/type/pm.php @@ -128,7 +128,7 @@ class pm extends \phpbb\notification\type\base { $username = $this->user_loader->get_username($this->get_data('from_user_id'), 'no_profile'); - return $this->user->lang('NOTIFICATION_PM', $username); + return $this->language->lang('NOTIFICATION_PM', $username); } /** @@ -138,7 +138,7 @@ class pm extends \phpbb\notification\type\base */ public function get_reference() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REFERENCE', $this->get_data('message_subject') ); diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index f3dd6d531a..b54a6610b2 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -83,6 +83,7 @@ class post extends \phpbb\notification\type\base * Get the id of the item * * @param array $post The data from the post + * @return int The post id */ static public function get_item_id($post) { @@ -93,6 +94,7 @@ class post extends \phpbb\notification\type\base * Get the id of the parent * * @param array $post The data from the post + * @return int The topic id */ static public function get_item_parent_id($post) { @@ -218,14 +220,14 @@ class post extends \phpbb\notification\type\base if ($trimmed_responders_cnt > 20) { - $usernames[] = $this->user->lang('NOTIFICATION_MANY_OTHERS'); + $usernames[] = $this->language->lang('NOTIFICATION_MANY_OTHERS'); } else if ($trimmed_responders_cnt) { - $usernames[] = $this->user->lang('NOTIFICATION_X_OTHERS', $trimmed_responders_cnt); + $usernames[] = $this->language->lang('NOTIFICATION_X_OTHERS', $trimmed_responders_cnt); } - return $this->user->lang( + return $this->language->lang( $this->language_key, phpbb_generate_string_list($usernames, $this->user), $responders_cnt @@ -239,7 +241,7 @@ class post extends \phpbb\notification\type\base */ public function get_reference() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REFERENCE', censor_text($this->get_data('topic_title')) ); @@ -407,6 +409,7 @@ class post extends \phpbb\notification\type\base * Add responders to the notification * * @param mixed $post + * @return array Array of responder data */ public function add_responders($post) { diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 1cd879579a..9e759ef137 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -106,6 +106,7 @@ class quote extends \phpbb\notification\type\post * Update a notification * * @param array $post Data specific for this type that will be updated + * @return true */ public function update_notifications($post) { diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php index 0f7dce0a68..b80afc1039 100644 --- a/phpBB/phpbb/notification/type/report_pm.php +++ b/phpBB/phpbb/notification/type/report_pm.php @@ -70,6 +70,7 @@ class report_pm extends \phpbb\notification\type\pm * Get the id of the parent * * @param array $pm The data from the pm + * @return int The report id */ static public function get_item_parent_id($pm) { @@ -144,10 +145,10 @@ class report_pm extends \phpbb\notification\type\pm $user_data = $this->user_loader->get_username($this->get_data('reporter_id'), 'no_profile'); return array( - 'AUTHOR_NAME' => htmlspecialchars_decode($user_data['username']), - 'SUBJECT' => htmlspecialchars_decode(censor_text($this->get_data('message_subject'))), + 'AUTHOR_NAME' => htmlspecialchars_decode($user_data['username']), + 'SUBJECT' => htmlspecialchars_decode(censor_text($this->get_data('message_subject'))), - 'U_VIEW_REPORT' => generate_board_url() . "mcp.{$this->php_ext}?r={$this->item_parent_id}&i=pm_reports&mode=pm_report_details", + 'U_VIEW_REPORT' => generate_board_url() . "mcp.{$this->php_ext}?r={$this->item_parent_id}&i=pm_reports&mode=pm_report_details", ); } @@ -168,11 +169,11 @@ class report_pm extends \phpbb\notification\type\pm */ public function get_title() { - $this->user->add_lang('mcp'); + $this->language->add_lang('mcp'); $username = $this->user_loader->get_username($this->get_data('reporter_id'), 'no_profile'); - return $this->user->lang( + return $this->language->lang( $this->language_key, $username ); @@ -185,7 +186,7 @@ class report_pm extends \phpbb\notification\type\pm */ public function get_reference() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REFERENCE', censor_text($this->get_data('message_subject')) ); @@ -200,21 +201,21 @@ class report_pm extends \phpbb\notification\type\pm { if ($this->get_data('report_text')) { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REASON', $this->get_data('report_text') ); } - if (isset($this->user->lang[$this->get_data('reason_title')])) + if ($this->language->is_set($this->get_data('reason_title'))) { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REASON', - $this->user->lang[$this->get_data('reason_title')] + $this->language->lang($this->get_data('reason_title')) ); } - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REASON', $this->get_data('reason_description') ); diff --git a/phpBB/phpbb/notification/type/report_pm_closed.php b/phpBB/phpbb/notification/type/report_pm_closed.php index f793c7df9a..5e98eb5feb 100644 --- a/phpBB/phpbb/notification/type/report_pm_closed.php +++ b/phpBB/phpbb/notification/type/report_pm_closed.php @@ -106,7 +106,7 @@ class report_pm_closed extends \phpbb\notification\type\pm { $username = $this->user_loader->get_username($this->get_data('closer_id'), 'no_profile'); - return $this->user->lang( + return $this->language->lang( $this->language_key, $username ); @@ -119,7 +119,7 @@ class report_pm_closed extends \phpbb\notification\type\pm */ public function get_reference() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REFERENCE', censor_text($this->get_data('message_subject')) ); diff --git a/phpBB/phpbb/notification/type/report_post.php b/phpBB/phpbb/notification/type/report_post.php index 6eefd53832..84a5241417 100644 --- a/phpBB/phpbb/notification/type/report_post.php +++ b/phpBB/phpbb/notification/type/report_post.php @@ -139,11 +139,11 @@ class report_post extends \phpbb\notification\type\post_in_queue */ public function get_title() { - $this->user->add_lang('mcp'); + $this->language->add_lang('mcp'); $username = $this->user_loader->get_username($this->get_data('reporter_id'), 'no_profile'); - return $this->user->lang( + return $this->language->lang( $this->language_key, $username ); @@ -156,7 +156,7 @@ class report_post extends \phpbb\notification\type\post_in_queue */ public function get_reference() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REFERENCE', censor_text($this->get_data('post_subject')) ); @@ -171,21 +171,21 @@ class report_post extends \phpbb\notification\type\post_in_queue { if ($this->get_data('report_text')) { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REASON', $this->get_data('report_text') ); } - if (isset($this->user->lang[$this->get_data('reason_title')])) + if ($this->language->is_set($this->get_data('reason_title'))) { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REASON', - $this->user->lang[$this->get_data('reason_title')] + $this->language->lang($this->get_data('reason_title')) ); } - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REASON', $this->get_data('reason_description') ); diff --git a/phpBB/phpbb/notification/type/report_post_closed.php b/phpBB/phpbb/notification/type/report_post_closed.php index 6327011f2d..165034d57e 100644 --- a/phpBB/phpbb/notification/type/report_post_closed.php +++ b/phpBB/phpbb/notification/type/report_post_closed.php @@ -113,7 +113,7 @@ class report_post_closed extends \phpbb\notification\type\post { $username = $this->user_loader->get_username($this->get_data('closer_id'), 'no_profile'); - return $this->user->lang( + return $this->language->lang( $this->language_key, $username ); @@ -126,7 +126,7 @@ class report_post_closed extends \phpbb\notification\type\post */ public function get_reference() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REFERENCE', censor_text($this->get_data('post_subject')) ); diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php index 4812e8b5af..671c34fe96 100644 --- a/phpBB/phpbb/notification/type/topic.php +++ b/phpBB/phpbb/notification/type/topic.php @@ -83,6 +83,7 @@ class topic extends \phpbb\notification\type\base * Get the id of the item * * @param array $post The data from the post + * @return int The topic id */ static public function get_item_id($post) { @@ -93,6 +94,7 @@ class topic extends \phpbb\notification\type\base * Get the id of the parent * * @param array $post The data from the post + * @return int The forum id */ static public function get_item_parent_id($post) { @@ -154,7 +156,7 @@ class topic extends \phpbb\notification\type\base $username = $this->user_loader->get_username($this->get_data('poster_id'), 'no_profile'); } - return $this->user->lang( + return $this->language->lang( $this->language_key, $username ); @@ -167,7 +169,7 @@ class topic extends \phpbb\notification\type\base */ public function get_reference() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_REFERENCE', censor_text($this->get_data('topic_title')) ); @@ -180,7 +182,7 @@ class topic extends \phpbb\notification\type\base */ public function get_forum() { - return $this->user->lang( + return $this->language->lang( 'NOTIFICATION_FORUM', $this->get_data('forum_name') ); -- cgit v1.2.1 From 28cc98a7ac69f5670ccb2746f8e4158681aa7926 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 14 Oct 2015 01:05:34 -0700 Subject: [ticket/14237] Consistent references to classes in docblocks PHPBB3-14237 --- phpBB/phpbb/notification/manager.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index 080d2ecb1d..ea1b800dc5 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -848,7 +848,7 @@ class manager * * @param string $notification_type_name * @param array $data - * @return \phpbb\notification\type\type_interface + * @return type\type_interface */ public function get_item_type_class($notification_type_name, $data = array()) { @@ -863,7 +863,7 @@ class manager * Helper to get the notifications method class and set it up * * @param string $method_name - * @return \phpbb\notification\method\method_interface + * @return method\method_interface */ public function get_method_class($method_name) { @@ -874,7 +874,7 @@ class manager * Helper to load objects (notification types/methods) * * @param string $object_name - * @return \phpbb\notification\method\method_interface|\phpbb\notification\type\type_interface + * @return method\method_interface|type\type_interface */ protected function load_object($object_name) { -- cgit v1.2.1 From 84150d0d440d552ff45b5875edf28f6d7fda0f9c Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 14 Oct 2015 17:15:09 +0200 Subject: [ticket/13652] Fix coding style PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index e497e6dda1..7e2d7a5ea6 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -915,7 +915,7 @@ abstract class driver implements driver_interface } - if($operation === 'NOT') + if ($operation === 'NOT') { $operations_ary = implode("", $operations_ary); } -- cgit v1.2.1 From 90038e32cd6d35aa7a516a8d4f998e9504112c6a Mon Sep 17 00:00:00 2001 From: Cesar G Date: Tue, 13 Oct 2015 07:39:46 -0700 Subject: [ticket/13789] Upgrade reCaptcha plugin to 2.0 API. PHPBB3-13789 --- phpBB/phpbb/captcha/plugins/recaptcha.php | 127 +++--------------------------- 1 file changed, 10 insertions(+), 117 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/captcha/plugins/recaptcha.php b/phpBB/phpbb/captcha/plugins/recaptcha.php index 98132ab47d..152709a9ea 100644 --- a/phpBB/phpbb/captcha/plugins/recaptcha.php +++ b/phpBB/phpbb/captcha/plugins/recaptcha.php @@ -18,12 +18,6 @@ class recaptcha extends captcha_abstract var $recaptcha_server = 'http://www.google.com/recaptcha/api'; var $recaptcha_server_secure = 'https://www.google.com/recaptcha/api'; // class constants :( - // We are opening a socket to port 80 of this host and send - // the POST request asking for verification to the path specified here. - var $recaptcha_verify_server = 'www.google.com'; - var $recaptcha_verify_path = '/recaptcha/api/verify'; - - var $challenge; var $response; /** @@ -37,12 +31,11 @@ class recaptcha extends captcha_abstract function init($type) { - global $config, $db, $user, $request; + global $user, $request; $user->add_lang('captcha_recaptcha'); parent::init($type); - $this->challenge = $request->variable('recaptcha_challenge_field', ''); - $this->response = $request->variable('recaptcha_response_field', ''); + $this->response = $request->variable('g-recaptcha-response', ''); } public function is_available() @@ -75,7 +68,7 @@ class recaptcha extends captcha_abstract function acp_page($id, &$module) { - global $config, $db, $template, $user, $phpbb_log, $request; + global $config, $template, $user, $phpbb_log, $request; $captcha_vars = array( 'recaptcha_pubkey' => 'RECAPTCHA_PUBKEY', @@ -151,7 +144,6 @@ class recaptcha extends captcha_abstract $template->assign_vars(array( 'RECAPTCHA_SERVER' => $this->recaptcha_server, 'RECAPTCHA_PUBKEY' => isset($config['recaptcha_pubkey']) ? $config['recaptcha_pubkey'] : '', - 'RECAPTCHA_ERRORGET' => '', 'S_RECAPTCHA_AVAILABLE' => self::is_available(), 'S_CONFIRM_CODE' => true, 'S_TYPE' => $this->type, @@ -202,106 +194,25 @@ class recaptcha extends captcha_abstract } } -// Code from here on is based on recaptchalib.php -/* - * This is a PHP library that handles calling reCAPTCHA. - * - Documentation and latest version - * http://recaptcha.net/plugins/php/ - * - Get a reCAPTCHA API Key - * http://recaptcha.net/api/getkey - * - Discussion group - * http://groups.google.com/group/recaptcha - * - * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net - * AUTHORS: - * Mike Crawford - * Ben Maurer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Submits an HTTP POST to a reCAPTCHA server - * @param string $host - * @param string $path - * @param array $data - * @param int port - * @return array response - */ - function _recaptcha_http_post($host, $path, $data, $port = 80) - { - $req = $this->_recaptcha_qsencode ($data); - - $http_request = "POST $path HTTP/1.0\r\n"; - $http_request .= "Host: $host\r\n"; - $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; - $http_request .= "Content-Length: " . strlen($req) . "\r\n"; - $http_request .= "User-Agent: reCAPTCHA/PHP/phpBB\r\n"; - $http_request .= "\r\n"; - $http_request .= $req; - - $response = ''; - if (false == ($fs = @fsockopen($host, $port, $errno, $errstr, 10))) - { - trigger_error('RECAPTCHA_SOCKET_ERROR', E_USER_ERROR); - } - - fwrite($fs, $http_request); - - while (!feof($fs)) - { - // One TCP-IP packet - $response .= fgets($fs, 1160); - } - fclose($fs); - $response = explode("\r\n\r\n", $response, 2); - - return $response; - } - /** * Calls an HTTP POST function to verify if the user's guess was correct - * @param array $extra_params an array of extra variables to post to the server - * @return ReCaptchaResponse + * + * @return bool|string Returns false on success or error string on failure. */ - function recaptcha_check_answer($extra_params = array()) + function recaptcha_check_answer() { global $config, $user; //discard spam submissions - if ($this->challenge == null || strlen($this->challenge) == 0 || $this->response == null || strlen($this->response) == 0) + if ($this->response == null || strlen($this->response) == 0) { return $user->lang['RECAPTCHA_INCORRECT']; } - $response = $this->_recaptcha_http_post($this->recaptcha_verify_server, $this->recaptcha_verify_path, - array( - 'privatekey' => $config['recaptcha_privkey'], - 'remoteip' => $user->ip, - 'challenge' => $this->challenge, - 'response' => $this->response - ) + $extra_params - ); - - $answers = explode("\n", $response[1]); + $recaptcha = new \ReCaptcha\ReCaptcha($config['recaptcha_privkey']); + $result = $recaptcha->verify($this->response, $user->ip); - if (trim($answers[0]) === 'true') + if ($result->isSuccess()) { $this->solved = true; return false; @@ -311,22 +222,4 @@ class recaptcha extends captcha_abstract return $user->lang['RECAPTCHA_INCORRECT']; } } - - /** - * Encodes the given data into a query string format - * @param $data - array of string elements to be encoded - * @return string - encoded request - */ - function _recaptcha_qsencode($data) - { - $req = ''; - foreach ($data as $key => $value) - { - $req .= $key . '=' . urlencode(stripslashes($value)) . '&'; - } - - // Cut the last '&' - $req = substr($req, 0, strlen($req) - 1); - return $req; - } } -- cgit v1.2.1 From 8f5a0ad6f73e7b7757b02c827436384c96069b5a Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Fri, 24 Jul 2015 09:20:50 +0200 Subject: [ticket/14039] Revamp updater PHPBB3-14039 --- .../command/db/console_migrator_output_handler.php | 2 +- phpBB/phpbb/console/command/db/migrate.php | 9 +- phpBB/phpbb/console/command/db/revert.php | 9 +- phpBB/phpbb/db/html_migrator_output_handler.php | 48 ---- .../db/log_wrapper_migrator_output_handler.php | 102 ------- phpBB/phpbb/db/migrator.php | 4 +- .../phpbb/db/migrator_output_handler_interface.php | 31 --- phpBB/phpbb/db/null_migrator_output_handler.php | 24 -- .../html_migrator_output_handler.php | 46 ++++ .../installer_migrator_output_handler.php | 46 ++++ .../log_wrapper_migrator_output_handler.php | 100 +++++++ .../migrator_output_handler_interface.php | 31 +++ .../null_migrator_output_handler.php | 24 ++ phpBB/phpbb/di/container_builder.php | 1 + phpBB/phpbb/event/kernel_exception_subscriber.php | 22 +- phpBB/phpbb/hook/finder.php | 13 +- .../phpbb/install/controller/archive_download.php | 92 +++++++ phpBB/phpbb/install/controller/helper.php | 96 +++++-- phpBB/phpbb/install/controller/install.php | 43 +-- phpBB/phpbb/install/controller/update.php | 162 ++++++++++++ .../exception/file_updater_failure_exception.php | 22 ++ .../exception/jump_to_restart_point_exception.php | 44 +++ phpBB/phpbb/install/helper/config.php | 52 ++++ phpBB/phpbb/install/helper/container_factory.php | 19 +- phpBB/phpbb/install/helper/database.php | 2 +- .../file_updater/compression_file_updater.php | 131 +++++++++ .../phpbb/install/helper/file_updater/factory.php | 69 +++++ .../install/helper/file_updater/file_updater.php | 210 +++++++++++++++ .../helper/file_updater/file_updater_interface.php | 49 ++++ .../helper/file_updater/ftp_file_updater.php | 136 ++++++++++ .../install/helper/iohandler/ajax_iohandler.php | 119 ++++++++- .../install/helper/iohandler/cli_iohandler.php | 24 +- .../install/helper/iohandler/iohandler_base.php | 4 +- .../helper/iohandler/iohandler_interface.php | 19 +- .../helper/navigation/update_navigation.php | 80 ++++++ phpBB/phpbb/install/helper/update_helper.php | 118 +++++++++ phpBB/phpbb/install/installer.php | 14 +- .../install/module/obtain_data/install_module.php | 33 +++ phpBB/phpbb/install/module/obtain_data/module.php | 33 --- .../module/obtain_data/task/obtain_admin_data.php | 2 +- .../module/obtain_data/task/obtain_board_data.php | 2 +- .../task/obtain_file_updater_method.php | 168 ++++++++++++ .../obtain_data/task/obtain_update_files.php | 113 ++++++++ .../obtain_data/task/obtain_update_ftp_data.php | 164 ++++++++++++ .../obtain_data/task/obtain_update_settings.php | 103 ++++++++ .../install/module/obtain_data/update_module.php | 33 +++ .../requirements/abstract_requirements_module.php | 106 ++++++++ .../install/module/requirements/install_module.php | 25 ++ phpBB/phpbb/install/module/requirements/module.php | 110 -------- .../module/requirements/task/check_filesystem.php | 16 +- .../module/requirements/task/check_update.php | 185 +++++++++++++ .../install/module/requirements/update_module.php | 25 ++ .../install/module/update_database/module.php | 33 +++ .../install/module/update_database/task/update.php | 212 +++++++++++++++ .../install/module/update_filesystem/module.php | 33 +++ .../module/update_filesystem/task/diff_files.php | 205 ++++++++++++++ .../task/download_updated_files.php | 124 +++++++++ .../module/update_filesystem/task/file_check.php | 186 +++++++++++++ .../update_filesystem/task/show_file_status.php | 168 ++++++++++++ .../module/update_filesystem/task/update_files.php | 294 +++++++++++++++++++++ phpBB/phpbb/install/module_base.php | 2 +- phpBB/phpbb/install/task_base.php | 2 +- .../installer_resources_locator.php | 78 ++++++ 63 files changed, 4015 insertions(+), 457 deletions(-) delete mode 100644 phpBB/phpbb/db/html_migrator_output_handler.php delete mode 100644 phpBB/phpbb/db/log_wrapper_migrator_output_handler.php delete mode 100644 phpBB/phpbb/db/migrator_output_handler_interface.php delete mode 100644 phpBB/phpbb/db/null_migrator_output_handler.php create mode 100644 phpBB/phpbb/db/output_handler/html_migrator_output_handler.php create mode 100644 phpBB/phpbb/db/output_handler/installer_migrator_output_handler.php create mode 100644 phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php create mode 100644 phpBB/phpbb/db/output_handler/migrator_output_handler_interface.php create mode 100644 phpBB/phpbb/db/output_handler/null_migrator_output_handler.php create mode 100644 phpBB/phpbb/install/controller/archive_download.php create mode 100644 phpBB/phpbb/install/controller/update.php create mode 100644 phpBB/phpbb/install/exception/file_updater_failure_exception.php create mode 100644 phpBB/phpbb/install/exception/jump_to_restart_point_exception.php create mode 100644 phpBB/phpbb/install/helper/file_updater/compression_file_updater.php create mode 100644 phpBB/phpbb/install/helper/file_updater/factory.php create mode 100644 phpBB/phpbb/install/helper/file_updater/file_updater.php create mode 100644 phpBB/phpbb/install/helper/file_updater/file_updater_interface.php create mode 100644 phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php create mode 100644 phpBB/phpbb/install/helper/navigation/update_navigation.php create mode 100644 phpBB/phpbb/install/helper/update_helper.php create mode 100644 phpBB/phpbb/install/module/obtain_data/install_module.php delete mode 100644 phpBB/phpbb/install/module/obtain_data/module.php create mode 100644 phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php create mode 100644 phpBB/phpbb/install/module/obtain_data/task/obtain_update_files.php create mode 100644 phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php create mode 100644 phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php create mode 100644 phpBB/phpbb/install/module/obtain_data/update_module.php create mode 100644 phpBB/phpbb/install/module/requirements/abstract_requirements_module.php create mode 100644 phpBB/phpbb/install/module/requirements/install_module.php delete mode 100644 phpBB/phpbb/install/module/requirements/module.php create mode 100644 phpBB/phpbb/install/module/requirements/task/check_update.php create mode 100644 phpBB/phpbb/install/module/requirements/update_module.php create mode 100644 phpBB/phpbb/install/module/update_database/module.php create mode 100644 phpBB/phpbb/install/module/update_database/task/update.php create mode 100644 phpBB/phpbb/install/module/update_filesystem/module.php create mode 100644 phpBB/phpbb/install/module/update_filesystem/task/diff_files.php create mode 100644 phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php create mode 100644 phpBB/phpbb/install/module/update_filesystem/task/file_check.php create mode 100644 phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php create mode 100644 phpBB/phpbb/install/module/update_filesystem/task/update_files.php create mode 100644 phpBB/phpbb/routing/resources_locator/installer_resources_locator.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/db/console_migrator_output_handler.php b/phpBB/phpbb/console/command/db/console_migrator_output_handler.php index b9741a3838..568b2646d4 100644 --- a/phpBB/phpbb/console/command/db/console_migrator_output_handler.php +++ b/phpBB/phpbb/console/command/db/console_migrator_output_handler.php @@ -13,8 +13,8 @@ namespace phpbb\console\command\db; +use phpbb\db\output_handler\migrator_output_handler_interface; use phpbb\user; -use phpbb\db\migrator_output_handler_interface; use Symfony\Component\Console\Output\OutputInterface; class console_migrator_output_handler implements migrator_output_handler_interface diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php index 43029b7458..ae4211f7be 100644 --- a/phpBB/phpbb/console/command/db/migrate.php +++ b/phpBB/phpbb/console/command/db/migrate.php @@ -12,6 +12,7 @@ */ namespace phpbb\console\command\db; +use phpbb\db\output_handler\log_wrapper_migrator_output_handler; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -26,8 +27,12 @@ class migrate extends \phpbb\console\command\db\migration_command /** @var \phpbb\filesystem\filesystem_interface */ protected $filesystem; - function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) + /** @var \phpbb\language\language */ + protected $language; + + function __construct(\phpbb\user $user, \phpbb\language\language $language, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) { + $this->language = $language; $this->log = $log; $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; @@ -45,7 +50,7 @@ class migrate extends \phpbb\console\command\db\migration_command protected function execute(InputInterface $input, OutputInterface $output) { - $this->migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($this->user, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem)); + $this->migrator->set_output_handler(new log_wrapper_migrator_output_handler($this->language, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem)); $this->migrator->create_migrations_table(); diff --git a/phpBB/phpbb/console/command/db/revert.php b/phpBB/phpbb/console/command/db/revert.php index 838640968e..3fa2e17515 100644 --- a/phpBB/phpbb/console/command/db/revert.php +++ b/phpBB/phpbb/console/command/db/revert.php @@ -12,6 +12,7 @@ */ namespace phpbb\console\command\db; +use phpbb\db\output_handler\log_wrapper_migrator_output_handler; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -24,9 +25,13 @@ class revert extends \phpbb\console\command\db\migration_command /** @var \phpbb\filesystem\filesystem_interface */ protected $filesystem; - function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) + /** @var \phpbb\language\language */ + protected $language; + + function __construct(\phpbb\user $user, \phpbb\language\language $language, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) { $this->filesystem = $filesystem; + $this->language = $language; $this->phpbb_root_path = $phpbb_root_path; parent::__construct($user, $migrator, $extension_manager, $config, $cache); $this->user->add_lang(array('common', 'migrator')); @@ -49,7 +54,7 @@ class revert extends \phpbb\console\command\db\migration_command { $name = str_replace('/', '\\', $input->getArgument('name')); - $this->migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($this->user, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem)); + $this->migrator->set_output_handler(new log_wrapper_migrator_output_handler($this->language, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem)); $this->cache->purge(); diff --git a/phpBB/phpbb/db/html_migrator_output_handler.php b/phpBB/phpbb/db/html_migrator_output_handler.php deleted file mode 100644 index e37c667463..0000000000 --- a/phpBB/phpbb/db/html_migrator_output_handler.php +++ /dev/null @@ -1,48 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\db; - -use phpbb\user; - -class html_migrator_output_handler implements migrator_output_handler_interface -{ - /** - * User object. - * - * @var user - */ - private $user; - - /** - * Constructor - * - * @param user $user User object - */ - public function __construct(user $user) - { - $this->user = $user; - } - - /** - * {@inheritdoc} - */ - public function write($message, $verbosity) - { - if ($verbosity <= migrator_output_handler_interface::VERBOSITY_VERBOSE) - { - $final_message = call_user_func_array(array($this->user, 'lang'), $message); - echo $final_message . "
\n"; - } - } -} diff --git a/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php b/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php deleted file mode 100644 index 4c85bf4d67..0000000000 --- a/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php +++ /dev/null @@ -1,102 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\db; - -use phpbb\user; - -class log_wrapper_migrator_output_handler implements migrator_output_handler_interface -{ - /** - * User object. - * - * @var user - */ - protected $user; - - /** - * A migrator output handler - * - * @var migrator_output_handler_interface - */ - protected $migrator; - - /** - * Log file handle - * @var resource - */ - protected $file_handle = false; - - /** - * @var \phpbb\filesystem\filesystem_interface - */ - protected $filesystem; - - /** - * Constructor - * - * @param user $user User object - * @param migrator_output_handler_interface $migrator Migrator output handler - * @param string $log_file File to log to - * @param \phpbb\filesystem\filesystem_interface phpBB filesystem object - */ - public function __construct(user $user, migrator_output_handler_interface $migrator, $log_file, \phpbb\filesystem\filesystem_interface $filesystem) - { - $this->user = $user; - $this->migrator = $migrator; - $this->filesystem = $filesystem; - $this->file_open($log_file); - } - - /** - * Open file for logging - * - * @param string $file File to open - */ - protected function file_open($file) - { - if ($this->filesystem->is_writable(dirname($file))) - { - $this->file_handle = fopen($file, 'w'); - } - else - { - throw new \RuntimeException('Unable to write to migrator log file'); - } - } - - /** - * {@inheritdoc} - */ - public function write($message, $verbosity) - { - $this->migrator->write($message, $verbosity); - - if ($this->file_handle !== false) - { - $translated_message = call_user_func_array(array($this->user, 'lang'), $message) . "\n"; - - if ($verbosity <= migrator_output_handler_interface::VERBOSITY_NORMAL) - { - $translated_message = '[INFO] ' . $translated_message; - } - else - { - $translated_message = '[DEBUG] ' . $translated_message; - } - - fwrite($this->file_handle, $translated_message); - fflush($this->file_handle); - } - } -} diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 18c6403c07..a809bc14f9 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -13,6 +13,8 @@ namespace phpbb\db; +use phpbb\db\output_handler\migrator_output_handler_interface; +use phpbb\db\output_handler\null_migrator_output_handler; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -122,7 +124,7 @@ class migrator /** * Set the output handler. * - * @param migrator_output_handler $handler The output handler + * @param migrator_output_handler_interface $handler The output handler */ public function set_output_handler(migrator_output_handler_interface $handler) { diff --git a/phpBB/phpbb/db/migrator_output_handler_interface.php b/phpBB/phpbb/db/migrator_output_handler_interface.php deleted file mode 100644 index a923af99f6..0000000000 --- a/phpBB/phpbb/db/migrator_output_handler_interface.php +++ /dev/null @@ -1,31 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\db; - -interface migrator_output_handler_interface -{ - const VERBOSITY_QUIET = 0; - const VERBOSITY_NORMAL = 1; - const VERBOSITY_VERBOSE = 2; - const VERBOSITY_VERY_VERBOSE = 3; - const VERBOSITY_DEBUG = 4; - - /** - * Write output using the configured closure. - * - * @param string|array $message The message to write or an array containing the language key and all of its parameters. - * @param int $verbosity The verbosity of the message. - */ - public function write($message, $verbosity); -} diff --git a/phpBB/phpbb/db/null_migrator_output_handler.php b/phpBB/phpbb/db/null_migrator_output_handler.php deleted file mode 100644 index 0e8cfbb049..0000000000 --- a/phpBB/phpbb/db/null_migrator_output_handler.php +++ /dev/null @@ -1,24 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\db; - -class null_migrator_output_handler implements migrator_output_handler_interface -{ - /** - * {@inheritdoc} - */ - public function write($message, $verbosity) - { - } -} diff --git a/phpBB/phpbb/db/output_handler/html_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/html_migrator_output_handler.php new file mode 100644 index 0000000000..f15b8e5913 --- /dev/null +++ b/phpBB/phpbb/db/output_handler/html_migrator_output_handler.php @@ -0,0 +1,46 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\output_handler; + +class html_migrator_output_handler implements migrator_output_handler_interface +{ + /** + * Language object. + * + * @var \phpbb\language\language + */ + private $language; + + /** + * Constructor + * + * @param \phpbb\language\language $language Language object + */ + public function __construct(\phpbb\language\language $language) + { + $this->language = $language; + } + + /** + * {@inheritdoc} + */ + public function write($message, $verbosity) + { + if ($verbosity <= migrator_output_handler_interface::VERBOSITY_VERBOSE) + { + $final_message = $this->language->lang_array($message); + echo $final_message . "
\n"; + } + } +} diff --git a/phpBB/phpbb/db/output_handler/installer_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/installer_migrator_output_handler.php new file mode 100644 index 0000000000..56d5cf49a1 --- /dev/null +++ b/phpBB/phpbb/db/output_handler/installer_migrator_output_handler.php @@ -0,0 +1,46 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\output_handler; + +use phpbb\install\helper\iohandler\iohandler_interface; + +class installer_migrator_output_handler implements migrator_output_handler_interface +{ + /** + * @var iohandler_interface + */ + protected $iohandler; + + /** + * Constructor + * + * @param iohandler_interface $iohandler Installer's IO-handler + */ + public function __construct(iohandler_interface $iohandler) + { + $this->iohandler = $iohandler; + } + + /** + * {@inheritdoc} + */ + public function write($message, $verbosity) + { + if ($verbosity <= migrator_output_handler_interface::VERBOSITY_VERBOSE) + { + $this->iohandler->add_log_message($message); + $this->iohandler->send_response(); + } + } +} diff --git a/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php new file mode 100644 index 0000000000..475b2616e5 --- /dev/null +++ b/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php @@ -0,0 +1,100 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\output_handler; + +class log_wrapper_migrator_output_handler implements migrator_output_handler_interface +{ + /** + * Language object. + * + * @var \phpbb\language\language + */ + protected $language; + + /** + * A migrator output handler + * + * @var migrator_output_handler_interface + */ + protected $migrator; + + /** + * Log file handle + * @var resource + */ + protected $file_handle = false; + + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + /** + * Constructor + * + * @param \phpbb\language\language $language Language object + * @param migrator_output_handler_interface $migrator Migrator output handler + * @param string $log_file File to log to + * @param \phpbb\filesystem\filesystem_interface $filesystem phpBB filesystem object + */ + public function __construct(\phpbb\language\language $language, migrator_output_handler_interface $migrator, $log_file, \phpbb\filesystem\filesystem_interface $filesystem) + { + $this->language = $language; + $this->migrator = $migrator; + $this->filesystem = $filesystem; + $this->file_open($log_file); + } + + /** + * Open file for logging + * + * @param string $file File to open + */ + protected function file_open($file) + { + if ($this->filesystem->is_writable(dirname($file))) + { + $this->file_handle = fopen($file, 'w'); + } + else + { + throw new \RuntimeException('Unable to write to migrator log file'); + } + } + + /** + * {@inheritdoc} + */ + public function write($message, $verbosity) + { + $this->migrator->write($message, $verbosity); + + if ($this->file_handle !== false) + { + $translated_message = $this->language->lang_array($message); + + if ($verbosity <= migrator_output_handler_interface::VERBOSITY_NORMAL) + { + $translated_message = '[INFO] ' . $translated_message; + } + else + { + $translated_message = '[DEBUG] ' . $translated_message; + } + + fwrite($this->file_handle, $translated_message); + fflush($this->file_handle); + } + } +} diff --git a/phpBB/phpbb/db/output_handler/migrator_output_handler_interface.php b/phpBB/phpbb/db/output_handler/migrator_output_handler_interface.php new file mode 100644 index 0000000000..7bb5c73fec --- /dev/null +++ b/phpBB/phpbb/db/output_handler/migrator_output_handler_interface.php @@ -0,0 +1,31 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\output_handler; + +interface migrator_output_handler_interface +{ + const VERBOSITY_QUIET = 0; + const VERBOSITY_NORMAL = 1; + const VERBOSITY_VERBOSE = 2; + const VERBOSITY_VERY_VERBOSE = 3; + const VERBOSITY_DEBUG = 4; + + /** + * Write output using the configured closure. + * + * @param string|array $message The message to write or an array containing the language key and all of its parameters. + * @param int $verbosity The verbosity of the message. + */ + public function write($message, $verbosity); +} diff --git a/phpBB/phpbb/db/output_handler/null_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/null_migrator_output_handler.php new file mode 100644 index 0000000000..5fc2a52577 --- /dev/null +++ b/phpBB/phpbb/db/output_handler/null_migrator_output_handler.php @@ -0,0 +1,24 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\output_handler; + +class null_migrator_output_handler implements migrator_output_handler_interface +{ + /** + * {@inheritdoc} + */ + public function write($message, $verbosity) + { + } +} diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index fb391760ce..0a94aac98d 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -355,6 +355,7 @@ class container_builder ->without_cache() ->without_extensions() ->with_config($this->config_php_file) + ->with_config_path($this->get_config_path()) ->with_environment('production') ->without_compiled_container() ->get_container() diff --git a/phpBB/phpbb/event/kernel_exception_subscriber.php b/phpBB/phpbb/event/kernel_exception_subscriber.php index 0a8a0183dc..e427abf5e3 100644 --- a/phpBB/phpbb/event/kernel_exception_subscriber.php +++ b/phpBB/phpbb/event/kernel_exception_subscriber.php @@ -24,26 +24,28 @@ class kernel_exception_subscriber implements EventSubscriberInterface { /** * Template object + * * @var \phpbb\template\template */ protected $template; /** - * User object - * @var \phpbb\user + * Language object + * + * @var \phpbb\language\language */ - protected $user; + protected $language; /** * Construct method * - * @param \phpbb\template\template $template Template object - * @param \phpbb\user $user User object + * @param \phpbb\template\template $template Template object + * @param \phpbb\language\language $language Language object */ - public function __construct(\phpbb\template\template $template, \phpbb\user $user) + public function __construct(\phpbb\template\template $template, \phpbb\language\language $language) { $this->template = $template; - $this->user = $user; + $this->language = $language; } /** @@ -60,15 +62,15 @@ class kernel_exception_subscriber implements EventSubscriberInterface if ($exception instanceof \phpbb\exception\exception_interface) { - $message = call_user_func_array(array($this->user, 'lang'), array_merge(array($message), $exception->get_parameters())); + $message = $this->language->lang_array($message, $exception->get_parameters()); } if (!$event->getRequest()->isXmlHttpRequest()) { - page_header($this->user->lang('INFORMATION')); + page_header($this->language->lang('INFORMATION')); $this->template->assign_vars(array( - 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'), + 'MESSAGE_TITLE' => $this->language->lang('INFORMATION'), 'MESSAGE_TEXT' => $message, )); diff --git a/phpBB/phpbb/hook/finder.php b/phpBB/phpbb/hook/finder.php index a3d02d3aa0..f5a68a1370 100644 --- a/phpBB/phpbb/hook/finder.php +++ b/phpBB/phpbb/hook/finder.php @@ -18,8 +18,19 @@ namespace phpbb\hook; */ class finder { - protected $phpbb_root_path; + /** + * @var \phpbb\cache\driver\driver_interface + */ protected $cache; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var string + */ protected $php_ext; /** diff --git a/phpBB/phpbb/install/controller/archive_download.php b/phpBB/phpbb/install/controller/archive_download.php new file mode 100644 index 0000000000..711e1f2f0c --- /dev/null +++ b/phpBB/phpbb/install/controller/archive_download.php @@ -0,0 +1,92 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\controller; + +use phpbb\install\helper\config; +use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Symfony\Component\HttpFoundation\ResponseHeaderBag; + +class archive_download +{ + /** + * @var config + */ + protected $installer_config; + + /** + * Constructor + * + * @param config $config + */ + public function __construct(config $config) + { + $this->installer_config = $config; + $this->installer_config->load_config(); + } + + /** + * Sends response with the merge conflict archive + * + * Merge conflicts are always have to be resolved manually, + * so we use a different archive for that. + * + * @return BinaryFileResponse + */ + public function conflict_archive() + { + $filename = $this->installer_config->get('update_file_conflict_archive', false); + + if (!$filename) + { + die ('The requested file is not exist.'); + } + + return $this->send_response($filename); + } + + /** + * Sends response with the updated files' archive + * + * @return BinaryFileResponse + */ + public function update_archive() + { + $filename = $this->installer_config->get('update_file_archive', ''); + + if (!$filename) + { + die ('The requested file is not exist.'); + } + + return $this->send_response($filename); + } + + /** + * Generates a download response + * + * @param string $filename Path to the file to download + * + * @return BinaryFileResponse Response object + */ + private function send_response($filename) + { + $response = new BinaryFileResponse($filename); + $response->setContentDisposition( + ResponseHeaderBag::DISPOSITION_ATTACHMENT, + basename($filename) + ); + + return $response; + } +} diff --git a/phpBB/phpbb/install/controller/helper.php b/phpBB/phpbb/install/controller/helper.php index fdfa6821ed..ef6b8ba3c2 100644 --- a/phpBB/phpbb/install/controller/helper.php +++ b/phpBB/phpbb/install/controller/helper.php @@ -13,6 +13,7 @@ namespace phpbb\install\controller; +use phpbb\install\helper\config; use phpbb\install\helper\navigation\navigation_provider; use phpbb\language\language; use phpbb\language\language_file_helper; @@ -33,6 +34,11 @@ use Symfony\Component\HttpFoundation\Cookie; */ class helper { + /** + * @var config + */ + protected $installer_config; + /** * @var \phpbb\language\language */ @@ -91,6 +97,7 @@ class helper /** * Constructor * + * @param config $config * @param language $language * @param language_file_helper $lang_helper * @param navigation_provider $nav @@ -101,8 +108,9 @@ class helper * @param router $router * @param string $phpbb_root_path */ - public function __construct(language $language, language_file_helper $lang_helper, navigation_provider $nav, template $template, path_helper $path_helper, request $phpbb_request, symfony_request $request, router $router, $phpbb_root_path) + public function __construct(config $config, language $language, language_file_helper $lang_helper, navigation_provider $nav, template $template, path_helper $path_helper, request $phpbb_request, symfony_request $request, router $router, $phpbb_root_path) { + $this->installer_config = $config; $this->language = $language; $this->language_cookie = false; $this->lang_helper = $lang_helper; @@ -199,6 +207,47 @@ class helper } } + /** + * Process navigation data to reflect active/completed stages + * + * @param \phpbb\install\helper\iohandler\iohandler_interface|null $iohandler + */ + public function handle_navigation($iohandler = null) + { + $nav_data = $this->installer_config->get_navigation_data(); + + // Set active navigation stage + if (isset($nav_data['active']) && is_array($nav_data['active'])) + { + if ($iohandler !== null) + { + $iohandler->set_active_stage_menu($nav_data['active']); + } + + $this->navigation_provider->set_nav_property($nav_data['active'], array( + 'selected' => true, + 'completed' => false, + )); + } + + // Set finished navigation stages + if (isset($nav_data['finished']) && is_array($nav_data['finished'])) + { + foreach ($nav_data['finished'] as $finished_stage) + { + if ($iohandler !== null) + { + $iohandler->set_finished_stage_menu($finished_stage); + } + + $this->navigation_provider->set_nav_property($finished_stage, array( + 'selected' => false, + 'completed' => true, + )); + } + } + } + /** * Set default template variables * @@ -207,27 +256,32 @@ class helper */ protected function page_header($page_title, $selected_language = false) { + // Path to templates + $paths = array($this->phpbb_root_path . 'install/update/new/adm/', $this->phpbb_admin_path); + $paths = array_filter($paths, 'is_dir'); + $path = array_shift($paths); + $path = substr($path, strlen($this->phpbb_root_path)); + $this->template->assign_vars(array( - 'L_CHANGE' => $this->language->lang('CHANGE'), - 'L_COLON' => $this->language->lang('COLON'), - 'L_INSTALL_PANEL' => $this->language->lang('INSTALL_PANEL'), - 'L_SELECT_LANG' => $this->language->lang('SELECT_LANG'), - 'L_SKIP' => $this->language->lang('SKIP'), - 'PAGE_TITLE' => $this->language->lang($page_title), - 'T_IMAGE_PATH' => htmlspecialchars($this->phpbb_admin_path) . 'images/', - 'T_JQUERY_LINK' => $this->path_helper->get_web_root_path() . 'assets/javascript/jquery.min.js', - 'T_TEMPLATE_PATH' => $this->path_helper->get_web_root_path() . 'adm/style', - 'T_ASSETS_PATH' => $this->path_helper->get_web_root_path() . 'assets/', - - 'S_CONTENT_DIRECTION' => $this->language->lang('DIRECTION'), - 'S_CONTENT_FLOW_BEGIN' => ($this->language->lang('DIRECTION') === 'ltr') ? 'left' : 'right', - 'S_CONTENT_FLOW_END' => ($this->language->lang('DIRECTION') === 'ltr') ? 'right' : 'left', - 'S_CONTENT_ENCODING' => 'UTF-8', - 'S_LANG_SELECT' => $selected_language, - - 'S_USER_LANG' => $this->language->lang('USER_LANG'), - ) - ); + 'L_CHANGE' => $this->language->lang('CHANGE'), + 'L_COLON' => $this->language->lang('COLON'), + 'L_INSTALL_PANEL' => $this->language->lang('INSTALL_PANEL'), + 'L_SELECT_LANG' => $this->language->lang('SELECT_LANG'), + 'L_SKIP' => $this->language->lang('SKIP'), + 'PAGE_TITLE' => $this->language->lang($page_title), + 'T_IMAGE_PATH' => $this->path_helper->get_web_root_path() . $path . 'images/', + 'T_JQUERY_LINK' => $this->path_helper->get_web_root_path() . $path . '../assets/javascript/jquery.min.js', + 'T_TEMPLATE_PATH' => $this->path_helper->get_web_root_path() . $path . 'style', + 'T_ASSETS_PATH' => $this->path_helper->get_web_root_path() . $path . '../assets/', + + 'S_CONTENT_DIRECTION' => $this->language->lang('DIRECTION'), + 'S_CONTENT_FLOW_BEGIN' => ($this->language->lang('DIRECTION') === 'ltr') ? 'left' : 'right', + 'S_CONTENT_FLOW_END' => ($this->language->lang('DIRECTION') === 'ltr') ? 'right' : 'left', + 'S_CONTENT_ENCODING' => 'UTF-8', + 'S_LANG_SELECT' => $selected_language, + + 'S_USER_LANG' => $this->language->lang('USER_LANG'), + )); $this->render_navigation(); } diff --git a/phpBB/phpbb/install/controller/install.php b/phpBB/phpbb/install/controller/install.php index 80f6651a39..8d5ff95958 100644 --- a/phpBB/phpbb/install/controller/install.php +++ b/phpBB/phpbb/install/controller/install.php @@ -13,7 +13,6 @@ namespace phpbb\install\controller; -use phpbb\install\helper\config; use phpbb\install\helper\install_helper; use phpbb\install\helper\navigation\navigation_provider; use Symfony\Component\HttpFoundation\StreamedResponse; @@ -35,11 +34,6 @@ class install */ protected $controller_helper; - /** - * @var config - */ - protected $installer_config; - /** * @var factory */ @@ -79,7 +73,6 @@ class install * Constructor * * @param helper $helper - * @param config $install_config * @param factory $factory * @param navigation_provider $nav_provider * @param language $language @@ -88,10 +81,9 @@ class install * @param installer $installer * @param install_helper $install_helper */ - public function __construct(helper $helper, config $install_config, factory $factory, navigation_provider $nav_provider, language $language, template $template, request_interface $request, installer $installer, install_helper $install_helper) + public function __construct(helper $helper, factory $factory, navigation_provider $nav_provider, language $language, template $template, request_interface $request, installer $installer, install_helper $install_helper) { $this->controller_helper = $helper; - $this->installer_config = $install_config; $this->iohandler_factory = $factory; $this->menu_provider = $nav_provider; $this->language = $language; @@ -130,34 +122,6 @@ class install // Set the appropriate input-output handler $this->installer->set_iohandler($this->iohandler_factory->get()); - // Set up navigation - $nav_data = $this->installer_config->get_navigation_data(); - /** @var \phpbb\install\helper\iohandler\iohandler_interface $iohandler */ - $iohandler = $this->iohandler_factory->get(); - - // Set active navigation stage - if (isset($nav_data['active']) && is_array($nav_data['active'])) - { - $iohandler->set_active_stage_menu($nav_data['active']); - $this->menu_provider->set_nav_property($nav_data['active'], array( - 'selected' => true, - 'completed' => false, - )); - } - - // Set finished navigation stages - if (isset($nav_data['finished']) && is_array($nav_data['finished'])) - { - foreach ($nav_data['finished'] as $finished_stage) - { - $iohandler->set_finished_stage_menu($finished_stage); - $this->menu_provider->set_nav_property($finished_stage, array( - 'selected' => false, - 'completed' => true, - )); - } - } - if ($this->request->is_ajax()) { $installer = $this->installer; @@ -193,6 +157,11 @@ class install 'TITLE' => $this->language->lang('INSTALL_INTRO'), 'CONTENT' => $this->language->lang('INSTALL_INTRO_BODY'), )); + + /** @var \phpbb\install\helper\iohandler\iohandler_interface $iohandler */ + $iohandler = $this->iohandler_factory->get(); + $this->controller_helper->handle_navigation($iohandler); + return $this->controller_helper->render('installer_install.html', 'INSTALL', true); } diff --git a/phpBB/phpbb/install/controller/update.php b/phpBB/phpbb/install/controller/update.php new file mode 100644 index 0000000000..5212ba7f26 --- /dev/null +++ b/phpBB/phpbb/install/controller/update.php @@ -0,0 +1,162 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\controller; + +use phpbb\install\helper\install_helper; +use phpbb\install\helper\iohandler\factory; +use phpbb\install\helper\navigation\navigation_provider; +use phpbb\install\installer; +use phpbb\language\language; +use phpbb\request\request_interface; +use phpbb\template\template; +use Symfony\Component\HttpFoundation\StreamedResponse; + +/** + * Updater controller + */ +class update +{ + /** + * @var helper + */ + protected $controller_helper; + + /** + * @var installer + */ + protected $installer; + + /** + * @var install_helper + */ + protected $install_helper; + + /** + * @var factory + */ + protected $iohandler_factory; + + /** + * @var language + */ + protected $language; + + /** + * @var navigation_provider + */ + protected $menu_provider; + + /** + * @var request_interface + */ + protected $request; + + /** + * @var template + */ + protected $template; + + /** + * Constructor + * + * @param helper $controller_helper + * @param installer $installer + * @param install_helper $install_helper + * @param factory $iohandler + * @param language $language + * @param navigation_provider $menu_provider + * @param request_interface $request + * @param template $template + */ + public function __construct(helper $controller_helper, installer $installer, install_helper $install_helper, factory $iohandler, language $language, navigation_provider $menu_provider, request_interface $request, template $template) + { + $this->controller_helper = $controller_helper; + $this->installer = $installer; + $this->install_helper = $install_helper; + $this->iohandler_factory = $iohandler; + $this->language = $language; + $this->menu_provider = $menu_provider; + $this->request = $request; + $this->template = $template; + } + + /** + * Controller entry point + */ + public function handle() + { + if (!$this->install_helper->is_phpbb_installed()) + { + die ('phpBB is not installed'); + } + + $this->template->assign_vars(array( + 'U_ACTION' => $this->controller_helper->route('phpbb_installer_update'), + )); + + // Set up input-output handler + if ($this->request->is_ajax()) + { + $this->iohandler_factory->set_environment('ajax'); + } + else + { + $this->iohandler_factory->set_environment('nojs'); + } + + // Set the appropriate input-output handler + $this->installer->set_iohandler($this->iohandler_factory->get()); + + // Render the intro page + if ($this->request->is_ajax()) + { + $installer = $this->installer; + $response = new StreamedResponse(); + $response->setCallback(function() use ($installer) { + $installer->run(); + }); + + // Try to bypass any server output buffers + $response->headers->set('X-Accel-Buffering', 'no'); + $response->headers->set('Content-type', 'application/json'); + + return $response; + } + else + { + $this->controller_helper->handle_language_select(); + + // Set active stage + $this->menu_provider->set_nav_property( + array('update', 0, 'introduction'), + array( + 'selected' => true, + 'completed' => false, + ) + ); + + $this->template->assign_vars(array( + 'SHOW_INSTALL_START_FORM' => true, + 'TITLE' => $this->language->lang('UPDATE_INSTALLATION'), + 'CONTENT' => $this->language->lang('UPDATE_INSTALLATION_EXPLAIN'), + )); + + /** @var \phpbb\install\helper\iohandler\iohandler_interface $iohandler */ + $iohandler = $this->iohandler_factory->get(); + $this->controller_helper->handle_navigation($iohandler); + + return $this->controller_helper->render('installer_update.html', 'UPDATE_INSTALLATION', true); + } + } +} diff --git a/phpBB/phpbb/install/exception/file_updater_failure_exception.php b/phpBB/phpbb/install/exception/file_updater_failure_exception.php new file mode 100644 index 0000000000..46ba2ed32d --- /dev/null +++ b/phpBB/phpbb/install/exception/file_updater_failure_exception.php @@ -0,0 +1,22 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\exception; + +/** + * Thrown when the file updater fails + */ +class file_updater_failure_exception extends installer_exception +{ + +} diff --git a/phpBB/phpbb/install/exception/jump_to_restart_point_exception.php b/phpBB/phpbb/install/exception/jump_to_restart_point_exception.php new file mode 100644 index 0000000000..b628c4fbe3 --- /dev/null +++ b/phpBB/phpbb/install/exception/jump_to_restart_point_exception.php @@ -0,0 +1,44 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\exception; + +class jump_to_restart_point_exception extends installer_exception +{ + /** + * @var string + */ + protected $restart_point_name; + + /** + * Constructor + * + * @param string $restart_point_name + */ + public function __construct($restart_point_name) + { + $this->restart_point_name = $restart_point_name; + + parent::__construct(); + } + + /** + * Returns the restart point's name + * + * @return string + */ + public function get_restart_point_name() + { + return $this->restart_point_name; + } +} diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php index d5653f1924..e73e07208e 100644 --- a/phpBB/phpbb/install/helper/config.php +++ b/phpBB/phpbb/install/helper/config.php @@ -99,6 +99,8 @@ class config 'last_task_name' => '', // Stores the service name of the latest finished task 'max_task_progress' => 0, 'current_task_progress' => 0, + '_restart_points' => array(), + 'use_restart_point' => false, ); $this->install_config_file = $this->phpbb_root_path . 'store/install_config.php'; @@ -239,6 +241,56 @@ class config } } + /** + * Creates a progress restart point + * + * Restart points can be used to repeat certain tasks periodically. + * You need to call this method from the first task you want to repeat. + * + * @param string $name Name of the restart point + */ + public function create_progress_restart_point($name) + { + $tmp_progress_data = $this->progress_data; + unset($tmp_progress_data['_restart_points']); + + $this->progress_data['_restart_points'][$name] = $tmp_progress_data; + } + + /** + * Set restart point to continue from + * + * @param string $name Name of the restart point + * + * @return bool Returns false if the restart point name is not exist, true otherwise + */ + public function jump_to_restart_point($name) + { + if (!isset($this->progress_data['_restart_points'][$name]) || empty($this->progress_data['_restart_points'][$name])) + { + return false; + } + + foreach ($this->progress_data['_restart_points'][$name] as $key => $value) + { + $this->progress_data[$key] = $value; + } + + return true; + } + + /** + * Returns whether a restart point with a given name exists or not + * + * @param string $name Name of the restart point + * + * @return bool + */ + public function has_restart_point($name) + { + return isset($this->progress_data['_restart_points'][$name]); + } + /** * Dumps install configuration to disk */ diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php index dc0eef6485..fd42d53c00 100644 --- a/phpBB/phpbb/install/helper/container_factory.php +++ b/phpBB/phpbb/install/helper/container_factory.php @@ -134,8 +134,13 @@ class container_factory $this->request->enable_super_globals(); } - $this->container = $phpbb_container = $phpbb_container_builder + $other_config_path = $this->phpbb_root_path . 'install/update/new/config'; + $config_path = (is_dir($other_config_path)) ? $other_config_path : $this->phpbb_root_path . 'config'; + + $this->container = $phpbb_container_builder + ->with_environment('production') ->with_config($phpbb_config_php_file) + ->with_config_path($config_path) ->without_cache() ->without_compiled_container() ->get_container(); @@ -145,11 +150,17 @@ class container_factory $this->container->register('request')->setSynthetic(true); $this->container->set('request', $this->request); - // Replace cache service, as config gets cached, and we don't want that - $this->container->register('cache.driver')->setSynthetic(true); - $this->container->set('cache.driver', new dummy()); + // Replace cache service, as config gets cached, and we don't want that when we are installing + if (!is_dir($other_config_path)) + { + $this->container->register('cache.driver')->setSynthetic(true); + $this->container->set('cache.driver', new dummy()); + } + $this->container->compile(); + $phpbb_container = $this->container; + // Restore super globals to previous state if ($disable_super_globals) { diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php index 627e9ea9b0..c4c90a01a4 100644 --- a/phpBB/phpbb/install/helper/database.php +++ b/phpBB/phpbb/install/helper/database.php @@ -338,7 +338,7 @@ class database $db->sql_return_on_error(true); // Check that we actually have a database name before going any further - if (!in_array($dbms_info['SCHEMA'], array('sqlite', 'oracle')) && $dbname === '') + if (!in_array($dbms_info['SCHEMA'], array('sqlite', 'oracle'), true) && $dbname === '') { $errors[] = array( 'title' => 'INST_ERR_DB_NO_NAME', diff --git a/phpBB/phpbb/install/helper/file_updater/compression_file_updater.php b/phpBB/phpbb/install/helper/file_updater/compression_file_updater.php new file mode 100644 index 0000000000..a6eca36653 --- /dev/null +++ b/phpBB/phpbb/install/helper/file_updater/compression_file_updater.php @@ -0,0 +1,131 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\helper\file_updater; + +use phpbb\install\helper\update_helper; + +/** + * File updater for generating archive with updated files + */ +class compression_file_updater implements file_updater_interface +{ + /** + * @var \compress + */ + protected $compress; + + /** + * @var update_helper + */ + protected $update_helper; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var string + */ + protected $php_ext; + + /** + * Constructor + * + * @param update_helper $update_helper + * @param string $phpbb_root_path + * @param string $php_ext + */ + public function __construct(update_helper $update_helper, $phpbb_root_path, $php_ext) + { + $this->compress = null; + $this->update_helper = $update_helper; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + } + + /** + * Set the compression method + * + * @param string $method Compression method's file extension + * + * @return string Archive's filename + */ + public function init($method) + { + $this->update_helper->include_file('includes/functions_compress.' . $this->php_ext); + + $archive_filename = 'update_archive_' . time() . '_' . uniqid(); + $path = $this->phpbb_root_path . 'store/' . $archive_filename . '' . $method; + + if ($method === '.zip') + { + $this->compress = new \compress_zip('w', $path); + } + else + { + $this->compress = new \compress_tar('w', $path, $method); + } + + return $path; + } + + /** + * Close archive writing process + */ + public function close() + { + $this->compress->close(); + } + + /** + * {@inheritdoc} + */ + public function delete_file($path_to_file) + { + // We do absolutely nothing here + } + + /** + * {@inheritdoc} + */ + public function create_new_file($path_to_file_to_create, $source, $create_from_content = false) + { + if ($create_from_content) + { + $this->compress->add_data($source, $path_to_file_to_create); + } + else + { + $this->compress->add_custom_file($source, $path_to_file_to_create); + } + } + + /** + * {@inheritdoc} + */ + public function update_file($path_to_file_to_update, $source, $create_from_content = false) + { + // Both functions are identical here + $this->create_new_file($path_to_file_to_update, $source, $create_from_content); + } + + /** + * {@inheritdoc} + */ + public function get_method_name() + { + return 'compression'; + } +} diff --git a/phpBB/phpbb/install/helper/file_updater/factory.php b/phpBB/phpbb/install/helper/file_updater/factory.php new file mode 100644 index 0000000000..d3a2f22782 --- /dev/null +++ b/phpBB/phpbb/install/helper/file_updater/factory.php @@ -0,0 +1,69 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\helper\file_updater; + +use phpbb\di\service_collection; +use phpbb\install\exception\file_updater_failure_exception; + +/** + * File updater factory + */ +class factory +{ + /** + * @var array + */ + protected $file_updaters; + + /** + * Constructor + * + * @param service_collection $collection File updater service collection + */ + public function __construct(service_collection $collection) + { + foreach ($collection as $service) + { + $this->register($service); + } + } + + /** + * Register updater object + * + * @param file_updater_interface $updater Updater object + */ + public function register(file_updater_interface $updater) + { + $name = $updater->get_method_name(); + $this->file_updaters[$name] = $updater; + } + + /** + * Returns file updater object + * + * @param string $name Name of the updater method + * + * @throws file_updater_failure_exception When the specified file updater does not exist + */ + public function get($name) + { + if (!isset($this->file_updaters[$name])) + { + throw new file_updater_failure_exception(); + } + + return $this->file_updaters[$name]; + } +} diff --git a/phpBB/phpbb/install/helper/file_updater/file_updater.php b/phpBB/phpbb/install/helper/file_updater/file_updater.php new file mode 100644 index 0000000000..8ebbf64253 --- /dev/null +++ b/phpBB/phpbb/install/helper/file_updater/file_updater.php @@ -0,0 +1,210 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\helper\file_updater; + +use phpbb\filesystem\exception\filesystem_exception; +use phpbb\filesystem\filesystem; +use phpbb\install\exception\file_updater_failure_exception; + +/** + * File updater for direct filesystem access + */ +class file_updater implements file_updater_interface +{ + /** + * @var filesystem + */ + protected $filesystem; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * Constructor + * + * @param filesystem $filesystem + * @param string $phpbb_root_path + */ + public function __construct(filesystem $filesystem, $phpbb_root_path) + { + $this->filesystem = $filesystem; + $this->phpbb_root_path = $phpbb_root_path; + } + + /** + * {@inheritdoc} + * + * @throws file_updater_failure_exception When the file is not writable + * @throws filesystem_exception When the filesystem class fails + */ + public function delete_file($path_to_file) + { + $this->filesystem->remove($this->phpbb_root_path . $path_to_file); + } + + /** + * {@inheritdoc} + * + * @throws file_updater_failure_exception When the file is not writable + * @throws filesystem_exception When the filesystem class fails + */ + public function create_new_file($path_to_file_to_create, $source, $create_from_content = false) + { + $path_to_file_to_create = $this->phpbb_root_path . $path_to_file_to_create; + + $dir = dirname($path_to_file_to_create); + if (!$this->filesystem->exists($dir)) + { + $this->make_dir($dir); + } + + $original_dir_perms = false; + + if (!$this->filesystem->is_writable($dir)) + { + // Extract last 9 bits we actually need + $original_dir_perms = @fileperms($dir) & 511; + $this->filesystem->phpbb_chmod($dir, filesystem::CHMOD_ALL); + } + + if (!$create_from_content) + { + try + { + $this->filesystem->copy($source, $path_to_file_to_create); + } + catch (filesystem_exception $e) + { + $this->write_file($path_to_file_to_create, $source, $create_from_content); + } + } + else + { + $this->write_file($path_to_file_to_create, $source, $create_from_content); + } + + if ($original_dir_perms !== false) + { + $this->filesystem->phpbb_chmod($dir, $original_dir_perms); + } + } + + /** + * {@inheritdoc} + * + * @throws file_updater_failure_exception When the file is not writable + * @throws filesystem_exception When the filesystem class fails + */ + public function update_file($path_to_file_to_update, $source, $create_from_content = false) + { + $path_to_file_to_update = $this->phpbb_root_path . $path_to_file_to_update; + $original_file_perms = false; + + if (!$this->filesystem->is_writable($path_to_file_to_update)) + { + // Extract last 9 bits we actually need + $original_file_perms = @fileperms($path_to_file_to_update) & 511; + $this->filesystem->phpbb_chmod($path_to_file_to_update, filesystem::CHMOD_WRITE); + } + + if (!$create_from_content) + { + try + { + $this->filesystem->copy($source, $path_to_file_to_update, true); + } + catch (filesystem_exception $e) + { + $this->write_file($path_to_file_to_update, $source, $create_from_content); + } + } + else + { + $this->write_file($path_to_file_to_update, $source, $create_from_content); + } + + if ($original_file_perms !== false) + { + $this->filesystem->phpbb_chmod($path_to_file_to_update, $original_file_perms); + } + } + + /** + * Creates directory structure + * + * @param string $path Path to the directory where the file should be placed (and non-existent) + */ + private function make_dir($path) + { + if (is_dir($path)) + { + return; + } + + $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); + $dirs = explode('/', $path); + $dirs_to_create = array(); + + do + { + $path .= '../'; + $dirs_to_create[] = array_pop($dirs); + } + while (!is_dir($path)); + + foreach ($dirs_to_create as $directory) + { + $path .= $directory; + $this->filesystem->mkdir($path, 493); // 493 === 0755 + $path .= '/'; + } + } + + /** + * Fallback function for file writing + * + * @param string $path_to_file Path to the file's location + * @param string $source Path to file to copy or string with the new file's content + * @param bool|false $create_from_content Whether or not to use $source as the content, false by default + * + * @throws file_updater_failure_exception When the file is not writable + */ + private function write_file($path_to_file, $source, $create_from_content = false) + { + if (!$create_from_content) + { + $source = @file_get_contents($source); + } + + $file_pointer = @fopen($path_to_file, 'w'); + + if (!is_resource($file_pointer)) + { + throw new file_updater_failure_exception(); + } + + @fwrite($file_pointer, $source); + @fclose($file_pointer); + } + + /** + * {@inheritdoc} + */ + public function get_method_name() + { + return 'direct_file'; + } +} diff --git a/phpBB/phpbb/install/helper/file_updater/file_updater_interface.php b/phpBB/phpbb/install/helper/file_updater/file_updater_interface.php new file mode 100644 index 0000000000..b13d7c9fe1 --- /dev/null +++ b/phpBB/phpbb/install/helper/file_updater/file_updater_interface.php @@ -0,0 +1,49 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\helper\file_updater; + +interface file_updater_interface +{ + /** + * Deletes a file + * + * @param string $path_to_file Path to the file to delete + */ + public function delete_file($path_to_file); + + /** + * Creates a new file + * + * @param string $path_to_file_to_create Path to the new file's location + * @param string $source Path to file to copy or string with the new file's content + * @param bool $create_from_content Whether or not to use $source as the content, false by default + */ + public function create_new_file($path_to_file_to_create, $source, $create_from_content = false); + + /** + * Update file + * + * @param string $path_to_file_to_update Path to the file's location + * @param string $source Path to file to copy or string with the new file's content + * @param bool $create_from_content Whether or not to use $source as the content, false by default + */ + public function update_file($path_to_file_to_update, $source, $create_from_content = false); + + /** + * Returns the name of the file updater method + * + * @return string + */ + public function get_method_name(); +} diff --git a/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php b/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php new file mode 100644 index 0000000000..258a035768 --- /dev/null +++ b/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php @@ -0,0 +1,136 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\helper\file_updater; + +use phpbb\install\helper\update_helper; + +/** + * File updater for FTP updates + */ +class ftp_file_updater implements file_updater_interface +{ + /** + * @var \transfer + */ + protected $transfer; + + /** + * @var update_helper + */ + protected $update_helper; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var string + */ + protected $php_ext; + + /** + * Constructor + * + * @param update_helper $update_helper + * @param string $phpbb_root_path + * @param string $php_ext + */ + public function __constructor(update_helper $update_helper, $phpbb_root_path, $php_ext) + { + $this->transfer = null; + $this->update_helper = $update_helper; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + } + + /** + * Initialize FTP connection + * + * @param string $method + * @param string $host + * @param string $user + * @param string $pass + * @param string $path + * @param int $port + * @param int $timeout + */ + public function init($method, $host, $user, $pass, $path, $port, $timeout) + { + $this->update_helper->include_file('includes/functions_transfer.' . $this->php_ext); + $this->transfer = new $method($host, $user, $pass, $path, $port, $timeout); + $this->transfer->open_session(); + } + + /** + * Close FTP session + */ + public function close() + { + $this->transfer->close_session(); + } + + /** + * {@inheritdoc} + */ + public function delete_file($path_to_file) + { + $this->transfer->delete_file($path_to_file); + } + + /** + * {@inheritdoc} + */ + public function create_new_file($path_to_file_to_create, $source, $create_from_content = false) + { + $dirname = dirname($path_to_file_to_create); + + if ($dirname && !file_exists($this->phpbb_root_path . $dirname)) + { + $this->transfer->make_dir($dirname); + } + + if ($create_from_content) + { + $this->transfer->write_file($path_to_file_to_create, $source); + } + else + { + $this->transfer->copy_file($path_to_file_to_create, $source); + } + } + + /** + * {@inheritdoc} + */ + public function update_file($path_to_file_to_update, $source, $create_from_content = false) + { + if ($create_from_content) + { + $this->transfer->write_file($path_to_file_to_update, $source); + } + else + { + $this->transfer->copy_file($path_to_file_to_update, $source); + } + } + + /** + * {@inheritdoc} + */ + public function get_method_name() + { + return 'ftp'; + } +} diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php index fa628f3365..1342ffa30f 100644 --- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -13,11 +13,19 @@ namespace phpbb\install\helper\iohandler; +use phpbb\path_helper; +use phpbb\routing\router; + /** * Input-Output handler for the AJAX frontend */ class ajax_iohandler extends iohandler_base { + /** + * @var path_helper + */ + protected $path_helper; + /** * @var \phpbb\request\request_interface */ @@ -28,6 +36,16 @@ class ajax_iohandler extends iohandler_base */ protected $template; + /** + * @var router + */ + protected $router; + + /** + * @var string + */ + protected $file_status; + /** * @var string */ @@ -48,19 +66,30 @@ class ajax_iohandler extends iohandler_base */ protected $cookies; + /** + * @var array + */ + protected $download; + /** * Constructor * + * @param path_helper $path_helper * @param \phpbb\request\request_interface $request HTTP request interface * @param \phpbb\template\template $template Template engine + * @param router $router Router */ - public function __construct(\phpbb\request\request_interface $request, \phpbb\template\template $template) + public function __construct(path_helper $path_helper, \phpbb\request\request_interface $request, \phpbb\template\template $template, router $router) { + $this->path_helper = $path_helper; $this->request = $request; + $this->router = $router; $this->template = $template; $this->form = ''; $this->nav_data = array(); $this->cookies = array(); + $this->download = array(); + $this->file_status = ''; parent::__construct(); } @@ -102,13 +131,13 @@ class ajax_iohandler extends iohandler_base */ public function add_user_form_group($title, $form) { - $this->template->assign_var('S_FORM_ELEM_COUNT', sizeof($form)); - $this->template->assign_block_vars('options', array( 'LEGEND' => $this->language->lang($title), 'S_LEGEND' => true, )); + $not_button_form = false; + foreach ($form as $input_name => $input_options) { if (!isset($input_options['type'])) @@ -117,6 +146,7 @@ class ajax_iohandler extends iohandler_base } $tpl_ary = array(); + $not_button_form = ($input_options['type'] !== 'submit' || $not_button_form); $tpl_ary['TYPE'] = $input_options['type']; $tpl_ary['TITLE'] = $this->language->lang($input_options['label']); @@ -136,7 +166,7 @@ class ajax_iohandler extends iohandler_base $tpl_ary['S_EXPLAIN'] = true; } - if (in_array($input_options['type'], array('select', 'radio'))) + if (in_array($input_options['type'], array('select', 'radio'), true)) { for ($i = 0, $total = sizeof($input_options['options']); $i < $total; $i++) { @@ -149,9 +179,12 @@ class ajax_iohandler extends iohandler_base $tpl_ary['OPTIONS'] = $input_options['options']; } - $this->template->assign_block_vars('options', $tpl_ary); + $block_name = ($input_options['type'] === 'submit') ? 'submit_buttons' : 'options'; + $this->template->assign_block_vars($block_name, $tpl_ary); } + $this->template->assign_var('S_NOT_ONLY_BUTTON_FORM', $not_button_form); + $this->template->set_filenames(array( 'form_install' => 'installer_form.html', )); @@ -185,14 +218,27 @@ class ajax_iohandler extends iohandler_base 'warnings' => $this->warnings, 'logs' => $this->logs, 'success' => $this->success, + 'download' => $this->download, ); + $this->errors = array(); + $this->warnings = array(); + $this->logs = array(); + $this->success = array(); + $this->download = array(); + if (!empty($this->form)) { $json_array['form'] = $this->form; $this->form = ''; } + if (!empty($this->file_status)) + { + $json_array['file_status'] = $this->file_status; + $this->file_status = ''; + } + // If current task name is set, we push progress message to the client side if (!empty($this->current_task_name)) { @@ -201,19 +247,20 @@ class ajax_iohandler extends iohandler_base 'task_num' => $this->current_task_progress, 'task_count' => $this->task_progress_count, ); + + if ($this->restart_progress_bar) + { + $json_array['progress']['restart'] = 1; + $this->restart_progress_bar = false; + } } if (!empty($this->nav_data)) { $json_array['nav'] = $this->nav_data; + $this->nav_data = array(); } - $this->errors = array(); - $this->warnings = array(); - $this->logs = array(); - $this->success = array(); - $this->nav_data = array(); - if ($this->request_client_refresh) { $json_array['refresh'] = true; @@ -275,6 +322,56 @@ class ajax_iohandler extends iohandler_base ); } + /** + * {@inheritdoc} + */ + public function add_download_link($route, $title, $msg = null) + { + $link_properties = array( + 'href' => $this->router->generate($route), + 'title' => $this->language->lang($title), + 'download' => $this->language->lang('DOWNLOAD'), + ); + + if ($msg !== null) + { + $link_properties['msg'] = htmlspecialchars_decode($this->language->lang($msg)); + } + + $this->download[] = $link_properties; + } + + /** + * {@inheritdoc} + */ + public function render_update_file_status($status_array) + { + $this->template->assign_vars(array( + 'T_IMAGE_PATH' => $this->path_helper->get_web_root_path() . 'adm/images/', + )); + + foreach ($status_array as $block => $list) + { + foreach ($list as $filename) + { + $dirname = dirname($filename); + + $this->template->assign_block_vars($block, array( + 'STATUS' => $block, + 'FILENAME' => $filename, + 'DIR_PART' => (!empty($dirname) && $dirname !== '.') ? dirname($filename) . '/' : false, + 'FILE_PART' => basename($filename), + )); + } + } + + $this->template->set_filenames(array( + 'file_status' => 'installer_update_file_status.html', + )); + + $this->file_status = $this->template->assign_display('file_status'); + } + /** * Callback function for language replacing * diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php index c5b2bb06bc..abdd730d2e 100644 --- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -181,9 +181,12 @@ class cli_iohandler extends iohandler_base } } - public function set_task_count($task_count) + /** + * {@inheritdoc} + */ + public function set_task_count($task_count, $restart = false) { - parent::set_task_count($task_count); + parent::set_task_count($task_count, $restart); if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL) { @@ -206,6 +209,9 @@ class cli_iohandler extends iohandler_base } } + /** + * {@inheritdoc} + */ public function set_progress($task_lang_key, $task_number) { parent::set_progress($task_lang_key, $task_number); @@ -262,4 +268,18 @@ class cli_iohandler extends iohandler_base public function set_cookie($cookie_name, $cookie_value) { } + + /** + * {@inheritdoc} + */ + public function add_download_link($route, $title, $msg = null) + { + } + + /** + * {@inheritdoc} + */ + public function render_update_file_status($status_array) + { + } } diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php index 006411f1e3..530cb4766b 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php @@ -80,6 +80,7 @@ abstract class iohandler_base implements iohandler_interface $this->logs = array(); $this->success = array(); + $this->restart_progress_bar = false; $this->task_progress_count = 0; $this->current_task_progress = 0; $this->current_task_name = ''; @@ -130,9 +131,10 @@ abstract class iohandler_base implements iohandler_interface /** * {@inheritdoc} */ - public function set_task_count($task_count) + public function set_task_count($task_count, $restart = false) { $this->task_progress_count = $task_count; + $this->restart_progress_bar = $restart; } /** diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php index 5f5f8499d6..00aab3283e 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php @@ -127,8 +127,9 @@ interface iohandler_interface * Sets the number of tasks belonging to the installer in the current mode. * * @param int $task_count Number of tasks + * @param bool $restart Whether or not to restart the progress bar, false by default */ - public function set_task_count($task_count); + public function set_task_count($task_count, $restart = false); /** * Sets the progress information @@ -164,6 +165,22 @@ interface iohandler_interface */ public function finish_progress($message_lang_key); + /** + * Adds a download link + * + * @param string $route Route for the link + * @param string $title Language key for the title + * @param string|null|array $msg Language key for the message + */ + public function add_download_link($route, $title, $msg = null); + + /** + * Renders the status of update files + * + * @param array $status_array Array containing files in groups to render + */ + public function render_update_file_status($status_array); + /** * Sends and sets cookies * diff --git a/phpBB/phpbb/install/helper/navigation/update_navigation.php b/phpBB/phpbb/install/helper/navigation/update_navigation.php new file mode 100644 index 0000000000..3d239c3451 --- /dev/null +++ b/phpBB/phpbb/install/helper/navigation/update_navigation.php @@ -0,0 +1,80 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\helper\navigation; + +use phpbb\install\helper\install_helper; + +class update_navigation implements navigation_interface +{ + /** + * @var install_helper + */ + private $install_helper; + + /** + * Constructor + * + * @param install_helper $install_helper + */ + public function __construct(install_helper $install_helper) + { + $this->install_helper = $install_helper; + } + + /** + * {@inheritdoc} + */ + public function get() + { + if (!$this->install_helper->is_phpbb_installed()) + { + return array(); + } + + return array( + 'update' => array( + 'label' => 'UPDATE', + 'route' => 'phpbb_installer_update', + 'order' => 1, + array( + 'introduction' => array( + 'label' => 'INTRODUCTION_TITLE', + 'stage' => true, + 'order' => 0, + ), + 'requirements' => array( + 'label' => 'STAGE_REQUIREMENTS', + 'stage' => true, + 'order' => 1, + ), + 'obtain_data' => array( + 'label' => 'STAGE_OBTAIN_DATA', + 'stage' => true, + 'order' => 2, + ), + 'update_files' => array( + 'label' => 'STAGE_UPDATE_FILES', + 'stage' => true, + 'order' => 3, + ), + 'update_database' => array( + 'label' => 'STAGE_UPDATE_DATABASE', + 'stage' => true, + 'order' => 4, + ), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/install/helper/update_helper.php b/phpBB/phpbb/install/helper/update_helper.php new file mode 100644 index 0000000000..2a3e6ceb0a --- /dev/null +++ b/phpBB/phpbb/install/helper/update_helper.php @@ -0,0 +1,118 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\helper; + +/** + * General helper functionality for the updater + */ +class update_helper +{ + /** + * @var string + */ + protected $path_to_new_files; + + /** + * @var string + */ + protected $path_to_old_files; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * Constructor + * + * @param string $phpbb_root_path + */ + public function __construct($phpbb_root_path) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->path_to_new_files = $phpbb_root_path . 'install/update/new/'; + $this->path_to_old_files = $phpbb_root_path . 'install/update/old/'; + } + + /** + * Returns path to new update files + * + * @return string + */ + public function get_path_to_new_update_files() + { + return $this->path_to_new_files; + } + + /** + * Returns path to new update files + * + * @return string + */ + public function get_path_to_old_update_files() + { + return $this->path_to_old_files; + } + + /** + * Includes the updated file if available + * + * @param string $filename Path to the file relative to phpBB root path + */ + public function include_file($filename) + { + if (!is_file($this->phpbb_root_path . $filename)) + { + return; + } + + if (is_file($this->path_to_new_files . $filename)) + { + include_once($this->path_to_new_files . $filename); + } + else + { + include_once($this->phpbb_root_path . $filename); + } + } + + /** + * Customized version_compare() + * + * @param string $version_number1 + * @param string $version_number2 + * @param string|null $operator + * @return int|bool The returned value is identical to the PHP build-in function version_compare() + */ + public function phpbb_version_compare($version_number1, $version_number2, $operator = null) + { + if ($operator === null) + { + $result = version_compare( + str_replace('rc', 'RC', strtolower($version_number1)), + str_replace('rc', 'RC', strtolower($version_number2)) + ); + } + else + { + $result = version_compare( + str_replace('rc', 'RC', strtolower($version_number1)), + str_replace('rc', 'RC', strtolower($version_number2)), + $operator + ); + } + + return $result; + } +} diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index 755edb5297..8a0374b1f0 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -15,6 +15,7 @@ namespace phpbb\install; use phpbb\di\ordered_service_collection; use phpbb\install\exception\installer_config_not_writable_exception; +use phpbb\install\exception\jump_to_restart_point_exception; use phpbb\install\exception\resource_limit_reached_exception; use phpbb\install\exception\user_interaction_required_exception; use phpbb\install\helper\config; @@ -94,6 +95,7 @@ class installer // Variable used to check if the install process have been finished $install_finished = false; $fail_cleanup = false; + $send_refresh = false; // We are installing something, so the introduction stage can go now... $this->install_config->set_finished_navigation_stage(array('install', 0, 'introduction')); @@ -142,7 +144,7 @@ class installer $this->install_config->set_active_module($name); // Run until there are available resources - if ($this->install_config->get_time_remaining() <= 0 && $this->install_config->get_memory_remaining() <= 0) + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) { throw new resource_limit_reached_exception(); } @@ -208,7 +210,12 @@ class installer } catch (resource_limit_reached_exception $e) { - // Do nothing + $send_refresh = true; + } + catch (jump_to_restart_point_exception $e) + { + $this->install_config->jump_to_restart_point($e->get_restart_point_name()); + $send_refresh = true; } catch (\Exception $e) { @@ -222,9 +229,10 @@ class installer // Send install finished message $this->iohandler->set_progress('INSTALLER_FINISHED', $this->install_config->get_task_progress_count()); } - else if (!$fail_cleanup) + else if ($send_refresh) { $this->iohandler->request_refresh(); + $this->iohandler->send_response(); } // Save install progress diff --git a/phpBB/phpbb/install/module/obtain_data/install_module.php b/phpBB/phpbb/install/module/obtain_data/install_module.php new file mode 100644 index 0000000000..deb4be90d8 --- /dev/null +++ b/phpBB/phpbb/install/module/obtain_data/install_module.php @@ -0,0 +1,33 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\obtain_data; + +class install_module extends \phpbb\install\module_base +{ + /** + * {@inheritdoc} + */ + public function get_navigation_stage_path() + { + return array('install', 0, 'obtain_data'); + } + + /** + * {@inheritdoc} + */ + public function get_step_count() + { + return 0; + } +} diff --git a/phpBB/phpbb/install/module/obtain_data/module.php b/phpBB/phpbb/install/module/obtain_data/module.php deleted file mode 100644 index 0e008796c5..0000000000 --- a/phpBB/phpbb/install/module/obtain_data/module.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -namespace phpbb\install\module\obtain_data; - -class module extends \phpbb\install\module_base -{ - /** - * {@inheritdoc} - */ - public function get_navigation_stage_path() - { - return array('install', 0, 'obtain_data'); - } - - /** - * {@inheritdoc} - */ - public function get_step_count() - { - return 0; - } -} diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php index b2250e524b..41616e995a 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php @@ -155,7 +155,7 @@ class obtain_admin_data extends \phpbb\install\task_base implements \phpbb\insta $data_valid = true; // Check if none of admin data is empty - if (in_array('', array($username, $pass1, $pass2, $email))) + if (in_array('', array($username, $pass1, $pass2, $email), true)) { $this->io_handler->add_error_message('INST_ERR_MISSING_DATA'); $data_valid = false; diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php index 821c221123..0726cc449c 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php @@ -165,7 +165,7 @@ class obtain_board_data extends \phpbb\install\task_base implements \phpbb\insta $this->io_handler->add_user_form_group('BOARD_CONFIG', $board_form); $this->io_handler->send_response(); - throw new user_interaction_required_exception; + throw new user_interaction_required_exception(); } /** diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php new file mode 100644 index 0000000000..9bcb73a6a9 --- /dev/null +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php @@ -0,0 +1,168 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\obtain_data\task; + +use phpbb\install\exception\user_interaction_required_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\task_base; + +class obtain_file_updater_method extends task_base +{ + /** + * @var array Supported compression methods + * + * Note: .tar is assumed to be supported, but not in the list + */ + protected $available_methods; + + /** + * @var \phpbb\install\helper\config + */ + protected $installer_config; + + /** + * @var \phpbb\install\helper\iohandler\iohandler_interface + */ + protected $iohandler; + + /** + * Constructor + * + * @param config $installer_config + * @param iohandler_interface $iohandler + */ + public function __construct(config $installer_config, iohandler_interface $iohandler) + { + $this->installer_config = $installer_config; + $this->iohandler = $iohandler; + + $this->available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib'); + + parent::__construct(false); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + return $this->installer_config->get('do_update_files', false); + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Check if data is sent + if ($this->iohandler->get_input('submit_update_file', false)) + { + $supported_methods = array('compression', 'ftp', 'direct_file'); + $method = $this->iohandler->get_input('method', 'compression'); + $update_method = (in_array($method, $supported_methods, true)) ? $method : 'compression'; + $this->installer_config->set('file_update_method', $update_method); + + $compression = $this->iohandler->get_input('compression_method', '.zip'); + $supported_methods = array_keys($this->available_methods); + $supported_methods[] = '.tar'; + $compression = (in_array($compression, $supported_methods, true)) ? $compression : '.zip'; + $this->installer_config->set('file_update_compression', $compression); + } + else + { + $this->iohandler->add_user_form_group('UPDATE_FILE_METHOD_TITLE', array( + 'method' => array( + 'label' => 'UPDATE_FILE_METHOD', + 'type' => 'select', + 'options' => array( + array( + 'value' => 'compression', + 'label' => 'UPDATE_FILE_METHOD_DOWNLOAD', + 'selected' => true, + ), + array( + 'value' => 'ftp', + 'label' => 'UPDATE_FILE_METHOD_FTP', + 'selected' => false, + ), + array( + 'value' => 'direct_file', + 'label' => 'UPDATE_FILE_METHOD_FILESYSTEM', + 'selected' => false, + ), + ), + ), + 'compression_method' => array( + 'label' => 'SELECT_DOWNLOAD_FORMAT', + 'type' => 'select', + 'options' => $this->get_available_compression_methods(), + ), + 'submit_update_file' => array( + 'label' => 'SUBMIT', + 'type' => 'submit', + ), + )); + + $this->iohandler->send_response(); + throw new user_interaction_required_exception(); + } + } + + /** + * Returns form elements in an array of available compression methods + * + * @return array + */ + protected function get_available_compression_methods() + { + $methods[] = array( + 'value' => '.tar', + 'label' => '.tar', + 'selected' => true, + ); + + foreach ($this->available_methods as $type => $module) + { + if (!@extension_loaded($module)) + { + continue; + } + + $methods[] = array( + 'value' => $type, + 'label' => $type, + 'selected' => false, + ); + } + + return $methods; + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_files.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_files.php new file mode 100644 index 0000000000..0cb809154e --- /dev/null +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_files.php @@ -0,0 +1,113 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\obtain_data\task; + +use phpbb\install\exception\user_interaction_required_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\task_base; + +class obtain_update_files extends task_base +{ + /** + * @var config + */ + protected $installer_config; + + /** + * @var iohandler_interface + */ + protected $iohandler; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var string + */ + protected $php_ext; + + /** + * Constructor + * + * @param config $config + * @param iohandler_interface $iohandler + * @param string $phpbb_root_path + * @param string $php_ext + */ + public function __construct(config $config, iohandler_interface $iohandler, $phpbb_root_path, $php_ext) + { + $this->installer_config = $config; + $this->iohandler = $iohandler; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + parent::__construct(false); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + return $this->installer_config->get('do_update_files', false); + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Load update info file + // The file should be checked in the requirements, so we assume that it exists + $update_info_file = $this->phpbb_root_path . 'install/update/index.' . $this->php_ext; + include($update_info_file); + $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info; + + // If the file is invalid, abort mission + if (!$info) + { + $this->iohandler->add_error_message('WRONG_INFO_FILE_FORMAT'); + throw new user_interaction_required_exception(); + } + + // Replace .php with $this->php_ext if needed + if ($this->php_ext !== 'php') + { + $custom_extension = '.' . $this->php_ext; + $info['files'] = preg_replace('#\.php$#i', $custom_extension, $info['files']); + } + + // Save update info + $this->installer_config->set('update_info_unprocessed', $info); + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php new file mode 100644 index 0000000000..a4d362a0f1 --- /dev/null +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php @@ -0,0 +1,164 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\obtain_data\task; + +use phpbb\install\exception\user_interaction_required_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\helper\update_helper; +use phpbb\install\task_base; + +class obtain_update_ftp_data extends task_base +{ + /** + * @var \phpbb\install\helper\config + */ + protected $installer_config; + + /** + * @var \phpbb\install\helper\iohandler\iohandler_interface + */ + protected $iohandler; + + /** + * @var update_helper + */ + protected $update_helper; + + /** + * @var string + */ + protected $php_ext; + + /** + * Constructor + * + * @param config $installer_config + * @param iohandler_interface $iohandler + * @param update_helper $update_helper + * @param string $php_ext + */ + public function __construct(config $installer_config, iohandler_interface $iohandler, update_helper $update_helper, $php_ext) + { + $this->installer_config = $installer_config; + $this->iohandler = $iohandler; + $this->update_helper = $update_helper; + $this->php_ext = $php_ext; + + parent::__construct(false); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + return ($this->installer_config->get('do_update_files', false) && + ($this->installer_config->get('file_update_method', '') === 'ftp') + ); + } + + /** + * {@inheritdoc} + */ + public function run() + { + if ($this->iohandler->get_input('submit_ftp', false)) + { + $this->update_helper->include_file('includes/functions_transfer.' . $this->php_ext); + + $method = 'ftp'; + $methods = \transfer::methods(); + if (!in_array($method, $methods, true)) + { + $method = $methods[0]; + } + + $ftp_host = $this->iohandler->get_input('ftp_host', ''); + $ftp_user = $this->iohandler->get_input('ftp_user', ''); + $ftp_pass = htmlspecialchars_decode($this->iohandler->get_input('ftp_pass', '')); + $ftp_path = $this->iohandler->get_input('ftp_path', ''); + $ftp_port = $this->iohandler->get_input('ftp_port', 21); + $ftp_time = $this->iohandler->get_input('ftp_timeout', 10); + + $this->installer_config->set('ftp_host', $ftp_host); + $this->installer_config->set('ftp_user', $ftp_user); + $this->installer_config->set('ftp_pass', $ftp_pass); + $this->installer_config->set('ftp_path', $ftp_path); + $this->installer_config->set('ftp_port', (int) $ftp_port); + $this->installer_config->set('ftp_timeout', (int) $ftp_time); + $this->installer_config->set('ftp_method', $method); + } + else + { + $this->iohandler->add_user_form_group('FTP_SETTINGS', array( + 'ftp_host' => array( + 'label' => 'FTP_HOST', + 'description' => 'FTP_HOST_EXPLAIN', + 'type' => 'text', + ), + 'ftp_user' => array( + 'label' => 'FTP_USERNAME', + 'description' => 'FTP_USERNAME_EXPLAIN', + 'type' => 'text', + ), + 'ftp_pass' => array( + 'label' => 'FTP_PASSWORD', + 'description' => 'FTP_PASSWORD_EXPLAIN', + 'type' => 'password', + ), + 'ftp_path' => array( + 'label' => 'FTP_ROOT_PATH', + 'description' => 'FTP_ROOT_PATH_EXPLAIN', + 'type' => 'text', + ), + 'ftp_port' => array( + 'label' => 'FTP_PORT', + 'description' => 'FTP_PORT_EXPLAIN', + 'type' => 'text', + 'default' => 21, + ), + 'ftp_timeout' => array( + 'label' => 'FTP_TIMEOUT', + 'description' => 'FTP_TIMEOUT_EXPLAIN', + 'type' => 'text', + 'default' => 10, + ), + 'submit_ftp' => array( + 'label' => 'SUBMIT', + 'type' => 'submit', + ), + )); + + $this->iohandler->send_response(); + throw new user_interaction_required_exception(); + } + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php new file mode 100644 index 0000000000..6a98721e77 --- /dev/null +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php @@ -0,0 +1,103 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\obtain_data\task; + +use phpbb\install\exception\user_interaction_required_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\task_base; + +class obtain_update_settings extends task_base +{ + /** + * @var \phpbb\install\helper\config + */ + protected $installer_config; + + /** + * @var \phpbb\install\helper\iohandler\iohandler_interface + */ + protected $iohandler; + + /** + * Constructor + * + * @param config $installer_config + * @param iohandler_interface $iohandler + */ + public function __construct(config $installer_config, iohandler_interface $iohandler) + { + $this->installer_config = $installer_config; + $this->iohandler = $iohandler; + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Check if data is sent + if ($this->iohandler->get_input('submit_update', false)) + { + $update_files = $this->iohandler->get_input('update_type', 'all') === 'all'; + $this->installer_config->set('do_update_files', $update_files); + } + else + { + $this->iohandler->add_user_form_group('UPDATE_TYPE', array( + 'update_type' => array( + 'label' => 'UPDATE_TYPE', + 'type' => 'radio', + 'options' => array( + array( + 'value' => 'all', + 'label' => 'UPDATE_TYPE_ALL', + 'selected' => true, + ), + array( + 'value' => 'db_only', + 'label' => 'UPDATE_TYPE_DB_ONLY', + 'selected' => false, + ), + ), + ), + 'submit_update' => array( + 'label' => 'SUBMIT', + 'type' => 'submit', + ), + )); + + $this->iohandler->send_response(); + throw new user_interaction_required_exception(); + } + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module/obtain_data/update_module.php b/phpBB/phpbb/install/module/obtain_data/update_module.php new file mode 100644 index 0000000000..c2f9019d34 --- /dev/null +++ b/phpBB/phpbb/install/module/obtain_data/update_module.php @@ -0,0 +1,33 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\obtain_data; + +class update_module extends \phpbb\install\module_base +{ + /** + * {@inheritdoc} + */ + public function get_navigation_stage_path() + { + return array('update', 0, 'obtain_data'); + } + + /** + * {@inheritdoc} + */ + public function get_step_count() + { + return 0; + } +} diff --git a/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php b/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php new file mode 100644 index 0000000000..26593e6777 --- /dev/null +++ b/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php @@ -0,0 +1,106 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\requirements; + +use phpbb\install\exception\resource_limit_reached_exception; +use phpbb\install\exception\user_interaction_required_exception; +use phpbb\install\module_base; + +/** + * Base class for requirements installer module + */ +abstract class abstract_requirements_module extends module_base +{ + public function run() + { + $tests_passed = true; + + // Recover install progress + $task_name = $this->recover_progress(); + $task_found = false; + + /** + * @var string $name ID of the service + * @var \phpbb\install\task_interface $task Task object + */ + foreach ($this->task_collection as $name => $task) + { + // Run until there are available resources + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) + { + throw new resource_limit_reached_exception(); + } + + // Skip forward until the next task is reached + if (!$task_found) + { + if ($name === $task_name || empty($task_name)) + { + $task_found = true; + + if ($name === $task_name) + { + continue; + } + } + else + { + continue; + } + } + + // Check if we can run the task + if (!$task->is_essential() && !$task->check_requirements()) + { + continue; + } + + if ($this->allow_progress_bar) + { + $this->install_config->increment_current_task_progress(); + } + + $test_result = $task->run(); + $tests_passed = ($tests_passed) ? $test_result : false; + } + + // Module finished, so clear task progress + $this->install_config->set_finished_task(''); + + // Check if tests have failed + if (!$tests_passed) + { + // If requirements are not met, exit form installer + // Set up UI for retesting + $this->iohandler->add_user_form_group('', array( + 'install' => array( + 'label' => 'RETEST_REQUIREMENTS', + 'type' => 'submit', + ), + )); + + // Send the response and quit + $this->iohandler->send_response(); + throw new user_interaction_required_exception(); + } + } + + /** + * {@inheritdoc} + */ + public function get_step_count() + { + return 0; + } +} diff --git a/phpBB/phpbb/install/module/requirements/install_module.php b/phpBB/phpbb/install/module/requirements/install_module.php new file mode 100644 index 0000000000..ed0c5fbd94 --- /dev/null +++ b/phpBB/phpbb/install/module/requirements/install_module.php @@ -0,0 +1,25 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\requirements; + +class install_module extends abstract_requirements_module +{ + /** + * {@inheritdoc} + */ + public function get_navigation_stage_path() + { + return array('install', 0, 'requirements'); + } +} diff --git a/phpBB/phpbb/install/module/requirements/module.php b/phpBB/phpbb/install/module/requirements/module.php deleted file mode 100644 index 79a031bad9..0000000000 --- a/phpBB/phpbb/install/module/requirements/module.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -namespace phpbb\install\module\requirements; - -use phpbb\install\exception\resource_limit_reached_exception; -use phpbb\install\exception\user_interaction_required_exception; - -class module extends \phpbb\install\module_base -{ - public function run() - { - $tests_passed = true; - - // Recover install progress - $task_name = $this->recover_progress(); - $task_found = false; - - /** - * @var string $name ID of the service - * @var \phpbb\install\task_interface $task Task object - */ - foreach ($this->task_collection as $name => $task) - { - // Run until there are available resources - if ($this->install_config->get_time_remaining() <= 0 && $this->install_config->get_memory_remaining() <= 0) - { - throw new resource_limit_reached_exception(); - } - - // Skip forward until the next task is reached - if (!$task_found) - { - if ($name === $task_name || empty($task_name)) - { - $task_found = true; - - if ($name === $task_name) - { - continue; - } - } - else - { - continue; - } - } - - // Check if we can run the task - if (!$task->is_essential() && !$task->check_requirements()) - { - continue; - } - - if ($this->allow_progress_bar) - { - $this->install_config->increment_current_task_progress(); - } - - $test_result = $task->run(); - $tests_passed = ($tests_passed) ? $test_result : false; - } - - // Module finished, so clear task progress - $this->install_config->set_finished_task(''); - - // Check if tests have failed - if (!$tests_passed) - { - // If requirements are not met, exit form installer - // Set up UI for retesting - $this->iohandler->add_user_form_group('', array( - 'install' => array( - 'label' => 'RETEST_REQUIREMENTS', - 'type' => 'submit', - ), - )); - - // Send the response and quit - $this->iohandler->send_response(); - throw new user_interaction_required_exception(); - } - } - - /** - * {@inheritdoc} - */ - public function get_step_count() - { - return 0; - } - - /** - * {@inheritdoc} - */ - public function get_navigation_stage_path() - { - return array('install', 0, 'requirements'); - } -} diff --git a/phpBB/phpbb/install/module/requirements/task/check_filesystem.php b/phpBB/phpbb/install/module/requirements/task/check_filesystem.php index ab6b1091e2..2aec3915e0 100644 --- a/phpBB/phpbb/install/module/requirements/task/check_filesystem.php +++ b/phpBB/phpbb/install/module/requirements/task/check_filesystem.php @@ -50,11 +50,9 @@ class check_filesystem extends \phpbb\install\task_base * @param \phpbb\install\helper\iohandler\iohandler_interface $response response helper * @param string $phpbb_root_path relative path to phpBB's root * @param string $php_ext extension of php files + * @param bool $check_config_php Whether or not to check if config.php is writable */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, - \phpbb\install\helper\iohandler\iohandler_interface $response, - $phpbb_root_path, - $php_ext) + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, \phpbb\install\helper\iohandler\iohandler_interface $response, $phpbb_root_path, $php_ext, $check_config_php = true) { parent::__construct(true); @@ -87,12 +85,16 @@ class check_filesystem extends \phpbb\install\task_base 'failable' => true, 'is_file' => false, ), - array( + ); + + if ($check_config_php) + { + $this->files_to_check[] = array( 'path' => "config.$php_ext", 'failable' => false, 'is_file' => true, - ), - ); + ); + } } /** diff --git a/phpBB/phpbb/install/module/requirements/task/check_update.php b/phpBB/phpbb/install/module/requirements/task/check_update.php new file mode 100644 index 0000000000..c986c76810 --- /dev/null +++ b/phpBB/phpbb/install/module/requirements/task/check_update.php @@ -0,0 +1,185 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\requirements\task; + +use phpbb\filesystem\filesystem; +use phpbb\install\helper\container_factory; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\helper\update_helper; +use phpbb\install\task_base; + +/** + * Check the availability of updater files and update version + */ +class check_update extends task_base +{ + /** + * @var \phpbb\config\db + */ + protected $config; + + /** + * @var filesystem + */ + protected $filesystem; + + /** + * @var iohandler_interface + */ + protected $iohandler; + + /** + * @var update_helper + */ + protected $update_helper; + + /** + * @var \phpbb\version_helper + */ + protected $version_helper; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var string + */ + protected $php_ext; + + /** + * @var bool + */ + protected $tests_passed; + + /** + * Constructor + * + * @param container_factory $container + * @param filesystem $filesystem + * @param iohandler_interface $iohandler + * @param update_helper $update_helper + * @param string $phpbb_root_path + * @param string $php_ext + */ + public function __construct(container_factory $container, filesystem $filesystem, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path, $php_ext) + { + $this->filesystem = $filesystem; + $this->iohandler = $iohandler; + $this->update_helper = $update_helper; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->tests_passed = true; + + $this->config = $container->get('config'); + $this->version_helper = $container->get('version_helper'); + + parent::__construct(true); + } + + /** + * Sets $this->tests_passed + * + * @param bool $is_passed + */ + protected function set_test_passed($is_passed) + { + // If one test failed, tests_passed should be false + $this->tests_passed = $this->tests_passed && $is_passed; + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Array of update files + $update_files = array( + $this->phpbb_root_path . 'install/update', + $this->phpbb_root_path . 'install/update/index.' . $this->php_ext, + ); + + // Check for a valid update directory + if (!$this->filesystem->exists($update_files) || !$this->filesystem->is_readable($update_files)) + { + $this->iohandler->add_error_message('UPDATE_FILES_NOT_FOUND'); + $this->set_test_passed(false); + + // If there are no update files, we can't check the version + return false; + } + + // Recover version numbers + $update_info = array(); + @include($this->phpbb_root_path . 'install/update/index.' . $this->php_ext); + $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info; + $update_version = false; + + if ($info !== false) + { + $update_version = (!empty($info['version']['to'])) ? trim($info['version']['to']) : false; + } + + // Get current and latest version + try + { + $latest_version = $this->version_helper->get_latest_on_current_branch(true); + } + catch (\RuntimeException $e) + { + $latest_version = $update_version; + } + + $current_version = (!empty($this->config['version_update_from'])) ? $this->config['version_update_from'] : $this->config['version']; + + // Check if the update package + if (!$this->update_helper->phpbb_version_compare($current_version, $update_version, '<')) + { + $this->iohandler->add_error_message('NO_UPDATE_FILES_UP_TO_DATE'); + $this->tests_passed = false; + } + + // Check if the update package works with the installed version + if (empty($info['version']['from']) || $info['version']['from'] !== $current_version) + { + $this->iohandler->add_error_message(array('INCOMPATIBLE_UPDATE_FILES', $current_version, $info['version']['from'], $update_version)); + $this->tests_passed = false; + } + + // check if this is the latest update package + if ($this->update_helper->phpbb_version_compare($update_version, $latest_version, '<')) + { + $this->iohandler->add_warning_message(array('OLD_UPDATE_FILES', $info['version']['from'], $update_version, $latest_version)); + } + + return $this->tests_passed; + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module/requirements/update_module.php b/phpBB/phpbb/install/module/requirements/update_module.php new file mode 100644 index 0000000000..223d12faf3 --- /dev/null +++ b/phpBB/phpbb/install/module/requirements/update_module.php @@ -0,0 +1,25 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\requirements; + +class update_module extends abstract_requirements_module +{ + /** + * {@inheritdoc} + */ + public function get_navigation_stage_path() + { + return array('update', 0, 'requirements'); + } +} diff --git a/phpBB/phpbb/install/module/update_database/module.php b/phpBB/phpbb/install/module/update_database/module.php new file mode 100644 index 0000000000..ee38afe17d --- /dev/null +++ b/phpBB/phpbb/install/module/update_database/module.php @@ -0,0 +1,33 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\update_database; + +class module extends \phpbb\install\module_base +{ + /** + * {@inheritdoc} + */ + public function get_navigation_stage_path() + { + return array('update', 0, 'update_database'); + } + + /** + * {@inheritdoc} + */ + public function get_step_count() + { + return 0; + } +} diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php new file mode 100644 index 0000000000..2d640134a3 --- /dev/null +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -0,0 +1,212 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\update_database\task; + +use phpbb\db\migration\exception; +use phpbb\db\output_handler\installer_migrator_output_handler; +use phpbb\db\output_handler\log_wrapper_migrator_output_handler; +use phpbb\install\exception\resource_limit_reached_exception; +use phpbb\install\exception\user_interaction_required_exception; +use phpbb\install\task_base; + +/** + * Database updater task + */ +class update extends task_base +{ + /** + * @var \phpbb\cache\driver\driver_interface + */ + protected $cache; + + /** + * @var \phpbb\config\config + */ + protected $config; + + /** + * @var \phpbb\extension\manager + */ + protected $extension_manager; + + /** + * @var \phpbb\filesystem\filesystem + */ + protected $filesystem; + + /** + * @var \phpbb\install\helper\config + */ + protected $installer_config; + + /** + * @var \phpbb\install\helper\iohandler\iohandler_interface + */ + protected $iohandler; + + /** + * @var \phpbb\language\language + */ + protected $language; + + /** + * @var \phpbb\log\log + */ + protected $log; + + /** + * @var \phpbb\db\migrator + */ + protected $migrator; + + /** + * @var \phpbb\user + */ + protected $user; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * Constructor + * + * @param \phpbb\install\helper\container_factory $container + * @param \phpbb\filesystem\filesystem $filesystem + * @param \phpbb\install\helper\config $installer_config + * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler + * @param \phpbb\language\language $language + * @param string $phpbb_root_path + */ + public function __construct(\phpbb\install\helper\container_factory $container, \phpbb\filesystem\filesystem $filesystem, \phpbb\install\helper\config $installer_config, \phpbb\install\helper\iohandler\iohandler_interface $iohandler, \phpbb\language\language $language, $phpbb_root_path) + { + $this->filesystem = $filesystem; + $this->installer_config = $installer_config; + $this->iohandler = $iohandler; + $this->language = $language; + $this->phpbb_root_path = $phpbb_root_path; + + $this->cache = $container->get('cache.driver'); + $this->config = $container->get('config'); + $this->extension_manager = $container->get('ext.manager'); + $this->log = $container->get('log'); + $this->migrator = $container->get('migrator'); + $this->user = $container->get('user'); + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->language->add_lang('migrator'); + + if (!isset($this->config['version_update_from'])) + { + $this->config->set('version_update_from', $this->config['version']); + } + + $original_version = $this->config['version_update_from']; + + $this->migrator->set_output_handler( + new log_wrapper_migrator_output_handler( + $this->language, + new installer_migrator_output_handler($this->iohandler), + $this->phpbb_root_path . 'store/migrations_' . time() . '.log', + $this->filesystem + ) + ); + + $this->migrator->create_migrations_table(); + + $migrations = $this->extension_manager + ->get_finder() + ->core_path('phpbb/db/migration/data/') + ->extension_directory('/migrations') + ->get_classes(); + + $this->migrator->set_migrations($migrations); + $migration_count = count($migrations); + $this->iohandler->set_task_count($migration_count, true); + $progress_count = $this->installer_config->get('database_update_count', 0); + + while (!$this->migrator->finished()) + { + try + { + $this->migrator->update(); + $progress_count++; + $this->iohandler->set_progress('STAGE_UPDATE_DATABASE', $progress_count); + } + catch (exception $e) + { + $msg = $e->getParameters(); + array_unshift($msg, $e->getMessage()); + + $this->iohandler->add_error_message($msg); + throw new user_interaction_required_exception(); + } + + if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0) + { + $this->installer_config->set('database_update_count', $progress_count); + throw new resource_limit_reached_exception(); + } + } + + if ($original_version !== $this->config['version']) + { + $this->log->add( + 'admin', + $this->user->data['user_id'], + $this->user->ip, + 'LOG_UPDATE_DATABASE', + false, + array( + $original_version, + $this->config['version'] + ) + ); + } + + $this->iohandler->finish_progress('INLINE_UPDATE_SUCCESSFUL'); + + $this->iohandler->add_success_message('INLINE_UPDATE_SUCCESSFUL'); + + $this->config->delete('version_update_from'); + + $this->cache->purge(); + + $this->config->increment('assets_version', 1); + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module/update_filesystem/module.php b/phpBB/phpbb/install/module/update_filesystem/module.php new file mode 100644 index 0000000000..157c78a1ac --- /dev/null +++ b/phpBB/phpbb/install/module/update_filesystem/module.php @@ -0,0 +1,33 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\update_filesystem; + +class module extends \phpbb\install\module_base +{ + /** + * {@inheritdoc} + */ + public function get_navigation_stage_path() + { + return array('update', 0, 'update_files'); + } + + /** + * {@inheritdoc} + */ + public function get_step_count() + { + return 0; + } +} diff --git a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php new file mode 100644 index 0000000000..e3e6db6263 --- /dev/null +++ b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php @@ -0,0 +1,205 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\update_filesystem\task; + +use phpbb\install\exception\resource_limit_reached_exception; +use phpbb\install\exception\user_interaction_required_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\container_factory; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\helper\update_helper; +use phpbb\install\task_base; + +/** + * Merges user made changes into the files + */ +class diff_files extends task_base +{ + /** + * @var \phpbb\cache\driver\driver_interface + */ + protected $cache; + + /** + * @var config + */ + protected $installer_config; + + /** + * @var iohandler_interface + */ + protected $iohandler; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var string + */ + protected $php_ext; + + /** + * @var update_helper + */ + protected $update_helper; + + /** + * Constructor + * + * @param container_factory $container + * @param config $config + * @param iohandler_interface $iohandler + * @param update_helper $update_helper + * @param string $phpbb_root_path + * @param string $php_ext + */ + public function __construct(container_factory $container, config $config, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path, $php_ext) + { + $this->installer_config = $config; + $this->iohandler = $iohandler; + $this->update_helper = $update_helper; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + $this->cache = $container->get('cache.driver'); + + parent::__construct(false); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + $files_to_diff = $this->installer_config->get('update_files', array()); + $files_to_diff = (isset($files_to_diff['update_with_diff'])) ? $files_to_diff['update_with_diff'] : array(); + + return $this->installer_config->get('do_update_files', false) && count($files_to_diff) > 0; + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Include diff engine + $this->update_helper->include_file('includes/diff/diff.' . $this->php_ext); + $this->update_helper->include_file('includes/diff/engine.' . $this->php_ext); + + // Set up basic vars + $old_path = $this->update_helper->get_path_to_old_update_files(); + $new_path = $this->update_helper->get_path_to_new_update_files(); + + $files_to_diff = $this->installer_config->get('update_files', array()); + $files_to_diff = $files_to_diff['update_with_diff']; + + // Set progress bar + $this->iohandler->set_task_count(count($files_to_diff), true); + $this->iohandler->set_progress('UPDATE_FILE_DIFF', 0); + $progress_count = $this->installer_config->get('file_diff_update_count', 0); + + // Recover progress + $progress_key = $this->installer_config->get('differ_progress_key', -1); + $progress_recovered = ($progress_key === -1); + $merge_conflicts = $this->installer_config->get('merge_conflict_list', array()); + + foreach ($files_to_diff as $key => $filename) + { + if ($progress_recovered === false) + { + if ($progress_key === $key) + { + $progress_recovered = true; + } + + continue; + } + + // Read in files' content + $file_contents = array(); + + // Handle the special case when user created a file with the filename that is now new in the core + $file_contents[0] = (file_exists($old_path . $filename)) ? file_get_contents($old_path . $filename) : ''; + + $filenames = array( + $this->phpbb_root_path . $filename, + $new_path . $filename + ); + + foreach ($filenames as $file_to_diff) + { + $file_contents[] = file_get_contents($file_to_diff); + + if ($file_contents[sizeof($file_contents) - 1] === false) + { + $this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); + unset($file_contents); + throw new user_interaction_required_exception(); + } + } + + $diff = new \diff3($file_contents[0], $file_contents[1], $file_contents[2]); + unset($file_contents); + + // Handle conflicts + if ($diff->get_num_conflicts() !== 0) + { + $merge_conflicts[] = $filename; + } + + // Save merged output + $this->cache->put( + '_file_' . md5($filename), + base64_encode(implode("\n", $diff->merged_output())) + ); + + unset($diff); + + $progress_count++; + $this->iohandler->set_progress('UPDATE_FILE_DIFF', $progress_count); + + if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0) + { + // Save differ progress + $this->installer_config->set('differ_progress_key', $key); + $this->installer_config->set('merge_conflict_list', $merge_conflicts); + $this->installer_config->set('file_diff_update_count', $progress_count); + + // Request refresh + throw new resource_limit_reached_exception(); + } + } + + $this->iohandler->finish_progress('ALL_FILES_DIFFED'); + $this->installer_config->set('merge_conflict_list', $merge_conflicts); + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php new file mode 100644 index 0000000000..9271e8fd50 --- /dev/null +++ b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php @@ -0,0 +1,124 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\update_filesystem\task; + +use phpbb\filesystem\filesystem; +use phpbb\install\exception\jump_to_restart_point_exception; +use phpbb\install\exception\user_interaction_required_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\task_base; + +class download_updated_files extends task_base +{ + /** + * @var config + */ + protected $installer_config; + + /** + * @var filesystem + */ + protected $filesystem; + + /** + * @var iohandler_interface + */ + protected $iohandler; + + /** + * Constructor + * + * @param config $config + * @param iohandler_interface $iohandler + * @param filesystem $filesystem + */ + public function __construct(config $config, iohandler_interface $iohandler, filesystem $filesystem) + { + $this->installer_config = $config; + $this->iohandler = $iohandler; + $this->filesystem = $filesystem; + + parent::__construct(false); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + return $this->installer_config->get('do_update_files', false) + && $this->installer_config->get('file_update_method', '') === 'compression'; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if ($this->iohandler->get_input('database_update_submit', false)) + { + // Remove archive + $this->filesystem->remove( + $this->installer_config->get('update_file_archive', null) + ); + + $this->installer_config->set('update_file_archive', null); + } + else if ($this->iohandler->get_input('update_recheck_files_submit', false)) + { + throw new jump_to_restart_point_exception('check_update_files'); + } + else + { + // Render download box + $this->iohandler->add_download_link( + 'phpbb_installer_update_file_download', + 'DOWNLOAD_UPDATE_METHOD', + 'DOWNLOAD_UPDATE_METHOD_EXPLAIN' + ); + + // Add form to continue update + $this->iohandler->add_user_form_group('UPDATE_CONTINUE_UPDATE_PROCESS', array( + 'update_recheck_files_submit' => array( + 'label' => 'UPDATE_RECHECK_UPDATE_FILES', + 'type' => 'submit', + ), + 'database_update_submit' => array( + 'label' => 'UPDATE_CONTINUE_UPDATE_PROCESS', + 'type' => 'submit', + ), + )); + + $this->iohandler->send_response(); + throw new user_interaction_required_exception(); + } + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php new file mode 100644 index 0000000000..9945e61714 --- /dev/null +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -0,0 +1,186 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\update_filesystem\task; + +use phpbb\filesystem\filesystem; +use phpbb\install\exception\resource_limit_reached_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\helper\update_helper; +use phpbb\install\task_base; + +/** + * Updater task performing file checking + */ +class file_check extends task_base +{ + /** + * @var filesystem + */ + protected $filesystem; + + /** + * @var config + */ + protected $installer_config; + + /** + * @var iohandler_interface + */ + protected $iohandler; + + /** + * @var update_helper + */ + protected $update_helper; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * Construct + * + * @param filesystem $filesystem + * @param config $config + * @param iohandler_interface $iohandler + * @param update_helper $update_helper + * @param string $phpbb_root_path + */ + public function __construct(filesystem $filesystem, config $config, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path) + { + $this->filesystem = $filesystem; + $this->installer_config = $config; + $this->iohandler = $iohandler; + $this->update_helper = $update_helper; + $this->phpbb_root_path = $phpbb_root_path; + + parent::__construct(false); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + return $this->installer_config->get('do_update_files', false); + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->installer_config->has_restart_point('check_update_files')) + { + $this->installer_config->create_progress_restart_point('check_update_files'); + } + + $old_path = $this->update_helper->get_path_to_old_update_files(); + $new_path = $this->update_helper->get_path_to_new_update_files(); + + $update_info = $this->installer_config->get('update_info', array()); + $file_update_info = $this->installer_config->get('update_files', array()); + + if (empty($update_info)) + { + $root_path = $this->phpbb_root_path; + + $update_info = $this->installer_config->get('update_info_unprocessed', array()); + + $file_update_info = array(); + $file_update_info['update_without_diff'] = $update_info['binary']; + + // Filter out files that are already deleted + $file_update_info['delete'] = array_filter( + $update_info['deleted'], + function ($filename) use ($root_path) + { + return !file_exists($root_path . $filename); + } + ); + } + + $progress_count = $this->installer_config->get('file_check_progress_count', 0); + $task_count = count($update_info['files']); + $this->iohandler->set_task_count($task_count); + $this->iohandler->set_progress('UPDATE_CHECK_FILES', 0); + + foreach ($update_info['files'] as $key => $filename) + { + $old_file = $old_path . $filename; + $new_file = $new_path . $filename; + $file = $this->phpbb_root_path . $filename; + + if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0) + { + // Save progress + $this->installer_config->set('update_info', $update_info); + $this->installer_config->set('file_check_progress_count', $progress_count); + $this->installer_config->set('update_files', $file_update_info); + + // Request refresh + throw new resource_limit_reached_exception(); + } + + $progress_count++; + $this->iohandler->set_progress('UPDATE_CHECK_FILES', $progress_count); + + if (!$this->filesystem->exists($file)) + { + $file_update_info['new'][] = $filename; + } + else + { + $file_checksum = md5_file($file); + + if ($file_checksum === md5_file($new_file)) + { + // File already up to date + continue; + } + else if ($this->filesystem->exists($old_file) && $file_checksum === md5_file($old_file)) + { + // No need to diff the file + $file_update_info['update_without_diff'][] = $filename; + } + else + { + $file_update_info['update_with_diff'][] = $filename; + } + } + + unset($update_info['files'][$key]); + } + + $this->installer_config->set('update_files', $file_update_info); + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php new file mode 100644 index 0000000000..1c6b9aa058 --- /dev/null +++ b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php @@ -0,0 +1,168 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\update_filesystem\task; + +use phpbb\filesystem\filesystem; +use phpbb\install\exception\user_interaction_required_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\container_factory; +use phpbb\install\helper\file_updater\factory; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\task_base; + +class show_file_status extends task_base +{ + /** + * @var \phpbb\cache\driver\driver_interface + */ + protected $cache; + + /** + * @var filesystem + */ + protected $filesystem; + + /** + * @var config + */ + protected $installer_config; + + /** + * @var iohandler_interface + */ + protected $iohandler; + + /** + * @var \phpbb\install\helper\file_updater\compression_file_updater + */ + protected $file_updater; + + /** + * Constructor + * + * @param container_factory $container + * @param config $config + * @param iohandler_interface $iohandler + * @param filesystem $filesystem + * @param factory $file_updater_factory + */ + public function __construct(container_factory $container, config $config, iohandler_interface $iohandler, filesystem $filesystem, factory $file_updater_factory) + { + $this->installer_config = $config; + $this->iohandler = $iohandler; + $this->filesystem = $filesystem; + + $this->cache = $container->get('cache.driver'); + + // Initialize compression file updater + $compression_method = $this->installer_config->get('compression_method', ''); + $this->file_updater = $file_updater_factory->get('compression'); + $conflict_archive = $this->file_updater->init($compression_method); + + $this->installer_config->set('update_file_conflict_archive', $conflict_archive); + + parent::__construct(false); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + return $this->installer_config->get('do_update_files', false); + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->iohandler->get_input('submit_continue_file_update', false)) + { + // Handle merge conflicts + $merge_conflicts = $this->installer_config->get('merge_conflict_list', array()); + + // Create archive for merge conflicts + if (!empty($merge_conflicts)) + { + foreach ($merge_conflicts as $filename) + { + $this->file_updater->create_new_file( + $filename, + $this->cache->get('_file_' . md5($filename)), + true + ); + } + + // Render download box + $this->iohandler->add_download_link( + 'phpbb_installer_update_conflict_download', + 'DOWNLOAD_CONFLICTS', + 'DOWNLOAD_CONFLICTS_EXPLAIN' + ); + } + + $this->file_updater->close(); + + // Render update file statuses + $file_update_info = $this->installer_config->get('update_files', array()); + $file_status = array( + 'deleted' => (!isset($file_update_info['delete'])) ? array() : $file_update_info['delete'], + 'new' => (!isset($file_update_info['new'])) ? array() : $file_update_info['new'], + 'conflict' => $this->installer_config->get('merge_conflict_list', array()), + 'modified' => (!isset($file_update_info['update_with_diff'])) ? array() : $file_update_info['update_with_diff'], + 'not_modified' => (!isset($file_update_info['update_without_diff'])) ? array() : $file_update_info['update_without_diff'], + ); + + $this->iohandler->render_update_file_status($file_status); + + // Add form to continue update + $this->iohandler->add_user_form_group('UPDATE_CONTINUE_FILE_UPDATE', array( + 'submit_continue_file_update' => array( + 'label' => 'UPDATE_CONTINUE_FILE_UPDATE', + 'type' => 'submit', + ), + )); + + // Show results to the user + $this->iohandler->send_response(); + throw new user_interaction_required_exception(); + } + else + { + // Remove archive + $this->filesystem->remove( + $this->installer_config->get('update_file_conflict_archive', null) + ); + + $this->installer_config->set('update_file_conflict_archive', null); + } + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module/update_filesystem/task/update_files.php b/phpBB/phpbb/install/module/update_filesystem/task/update_files.php new file mode 100644 index 0000000000..747a86281b --- /dev/null +++ b/phpBB/phpbb/install/module/update_filesystem/task/update_files.php @@ -0,0 +1,294 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\update_filesystem\task; + +use phpbb\exception\runtime_exception; +use phpbb\install\exception\resource_limit_reached_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\container_factory; +use phpbb\install\helper\file_updater\factory; +use phpbb\install\helper\file_updater\file_updater_interface; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\helper\update_helper; +use phpbb\install\task_base; + +/** + * File updater task + */ +class update_files extends task_base +{ + /** + * @var \phpbb\cache\driver\driver_interface + */ + protected $cache; + + /** + * @var config + */ + protected $installer_config; + + /** + * @var iohandler_interface + */ + protected $iohandler; + + /** + * @var factory + */ + protected $factory; + + /** + * @var file_updater_interface + */ + protected $file_updater; + + /** + * @var update_helper + */ + protected $update_helper; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * Constructor + * + * @param container_factory $container + * @param config $config + * @param iohandler_interface $iohandler + * @param factory $file_updater_factory + * @param update_helper $update_helper + * @param string $phpbb_root_path + */ + public function __construct(container_factory $container, config $config, iohandler_interface $iohandler, factory $file_updater_factory, update_helper $update_helper, $phpbb_root_path) + { + $this->factory = $file_updater_factory; + $this->installer_config = $config; + $this->iohandler = $iohandler; + $this->update_helper = $update_helper; + $this->phpbb_root_path = $phpbb_root_path; + + $this->cache = $container->get('cache.driver'); + $this->file_updater = null; + + parent::__construct(false); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + return $this->installer_config->get('do_update_files', false); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $new_path = $this->update_helper->get_path_to_new_update_files(); + + $file_update_info = $this->installer_config->get('update_files', array()); + + $update_type_progress = $this->installer_config->get('file_updater_type_progress', ''); + $update_elem_progress = $this->installer_config->get('file_updater_elem_progress', ''); + $type_progress_found = false; + $elem_progress_found = false; + + // Progress bar + $task_count = 0; + foreach ($file_update_info as $sub_array) + { + $task_count += count($sub_array); + } + + // Everything is up to date, so just continue + if ($task_count === 0) + { + return; + } + + $progress_count = $this->installer_config->get('file_update_progress_count', 0); + $this->iohandler->set_task_count($task_count, true); + $this->iohandler->set_progress('UPDATE_UPDATING_FILES', 0); + + $this->file_updater = $this->get_file_updater(); + + // File updater fallback logic + try + { + // Update files + foreach ($file_update_info as $type => $file_update_vector) + { + if (!$type_progress_found) + { + if ($type === $update_type_progress || empty($update_elem_progress)) + { + $type_progress_found = true; + } + else + { + continue; + } + } + + foreach ($file_update_vector as $path) + { + if (!$elem_progress_found) + { + if ($path === $update_elem_progress || empty($update_elem_progress)) + { + $elem_progress_found = true; + } + else + { + continue; + } + } + + switch ($type) + { + case 'delete': + $this->file_updater->delete_file($path); + break; + case 'new': + $this->file_updater->create_new_file($path, $new_path . $path); + break; + case 'update_without_diff': + $this->file_updater->update_file($path, $new_path . $path); + break; + case 'update_with_diff': + $this->file_updater->update_file( + $path, + $this->cache->get('_file_' . md5($path)), + true + ); + break; + } + + // Save progress + $this->installer_config->set('file_updater_type_progress', $type); + $this->installer_config->set('file_updater_elem_progress', $path); + $progress_count++; + $this->iohandler->set_progress('UPDATE_UPDATING_FILES', $progress_count); + + if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0) + { + // Request refresh + throw new resource_limit_reached_exception(); + } + } + } + + $this->iohandler->finish_progress('UPDATE_UPDATING_FILES'); + } + catch (runtime_exception $e) + { + if ($e instanceof resource_limit_reached_exception) + { + throw new resource_limit_reached_exception(); + } + + $current_method = $this->installer_config->get('file_update_method', ''); + + // File updater failed, try to fallback to download file update mode + if ($current_method !== 'compression') + { + $this->iohandler->add_warning_message(array( + 'UPDATE_FILE_UPDATER_HAS_FAILED', + $current_method, + 'compression' + )); + $this->installer_config->set('file_update_method', 'compression'); + + // We only want a simple refresh here + throw new resource_limit_reached_exception(); + } + else + { + // Nowhere to fallback to :( + // Due to the way the installer handles fatal errors, we need to throw a low level exception + throw new runtime_exception('UPDATE_FILE_UPDATERS_HAVE_FAILED'); + } + } + + $file_updater_method = $this->installer_config->get('file_update_method', ''); + if ($file_updater_method === 'compression' || $file_updater_method === 'ftp') + { + $this->file_updater->close(); + } + } + + /** + * Get file updater + * + * @param null|string $file_updater_method Name of the file updater to use + * + * @return file_updater_interface File updater + */ + protected function get_file_updater($file_updater_method = null) + { + $file_updater_method = ($file_updater_method === null) ? $this->installer_config->get('file_update_method', '') : $file_updater_method; + + if ($file_updater_method === 'compression') + { + $compression_method = $this->installer_config->get('file_update_compression', ''); + + /** @var \phpbb\install\helper\file_updater\compression_file_updater $file_updater */ + $file_updater = $this->factory->get('compression'); + $archive_path = $file_updater->init($compression_method); + $this->installer_config->set('update_file_archive', $archive_path); + } + else if ($file_updater_method === 'ftp') + { + /** @var \phpbb\install\helper\file_updater\ftp_file_updater $file_updater */ + $file_updater = $this->factory->get('ftp'); + $file_updater->init( + $this->installer_config->get('ftp_method', ''), + $this->installer_config->get('ftp_host', ''), + $this->installer_config->get('ftp_user', ''), + $this->installer_config->get('ftp_pass', ''), + $this->installer_config->get('ftp_path', ''), + $this->installer_config->get('ftp_port', 0), + $this->installer_config->get('ftp_timeout', 10) + ); + } + else + { + /** @var file_updater_interface $file_updater */ + $file_updater = $this->factory->get('direct_file'); + } + + return $file_updater; + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return ''; + } +} diff --git a/phpBB/phpbb/install/module_base.php b/phpBB/phpbb/install/module_base.php index a933d4987c..fb68c3aca2 100644 --- a/phpBB/phpbb/install/module_base.php +++ b/phpBB/phpbb/install/module_base.php @@ -115,7 +115,7 @@ abstract class module_base implements module_interface foreach ($this->task_collection as $name => $task) { // Run until there are available resources - if ($this->install_config->get_time_remaining() <= 0 && $this->install_config->get_memory_remaining() <= 0) + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) { throw new resource_limit_reached_exception(); } diff --git a/phpBB/phpbb/install/task_base.php b/phpBB/phpbb/install/task_base.php index 5946be8c52..b5199be4af 100644 --- a/phpBB/phpbb/install/task_base.php +++ b/phpBB/phpbb/install/task_base.php @@ -44,7 +44,7 @@ abstract class task_base implements task_interface /** * {@inheritdoc} * - * Overwrite this method if your task is non-essential! + * Note: Overwrite this method if your task is non-essential! */ public function check_requirements() { diff --git a/phpBB/phpbb/routing/resources_locator/installer_resources_locator.php b/phpBB/phpbb/routing/resources_locator/installer_resources_locator.php new file mode 100644 index 0000000000..42cd0f11af --- /dev/null +++ b/phpBB/phpbb/routing/resources_locator/installer_resources_locator.php @@ -0,0 +1,78 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\routing\resources_locator; + +use phpbb\filesystem\filesystem_interface; + +/** + * Locates the yaml routing resources taking update directories into consideration + */ +class installer_resources_locator implements resources_locator_interface +{ + /** + * phpBB's filesystem handler + * + * @var filesystem_interface + */ + protected $filesystem; + + /** + * phpBB root path + * + * @var string + */ + protected $phpbb_root_path; + + /** + * Name of the current environment + * + * @var string + */ + protected $environment; + + /** + * Construct method + * + * @param filesystem_interface $filesystem phpBB's filesystem handler + * @param string $phpbb_root_path phpBB root path + * @param string $environment Name of the current environment + */ + public function __construct(filesystem_interface $filesystem, $phpbb_root_path, $environment) + { + $this->filesystem = $filesystem; + $this->phpbb_root_path = $phpbb_root_path; + $this->environment = $environment; + } + + /** + * {@inheritdoc} + */ + public function locate_resources() + { + if ($this->filesystem->exists($this->phpbb_root_path . 'install/update/new/config')) + { + $resources = array( + array('install/update/new/config/' . $this->environment . '/routing/environment.yml', 'yaml') + ); + } + else + { + $resources = array( + array('config/' . $this->environment . '/routing/environment.yml', 'yaml') + ); + } + + return $resources; + } +} -- cgit v1.2.1 From 85eb6a0bc0575c687eb43efe61cf206b26b26af8 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 11:21:56 +0200 Subject: [ticket/14039] Fix language constants and comments PHPBB3-14039 --- phpBB/phpbb/install/controller/archive_download.php | 2 +- phpBB/phpbb/install/helper/config.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/archive_download.php b/phpBB/phpbb/install/controller/archive_download.php index 711e1f2f0c..e1f7634963 100644 --- a/phpBB/phpbb/install/controller/archive_download.php +++ b/phpBB/phpbb/install/controller/archive_download.php @@ -38,7 +38,7 @@ class archive_download /** * Sends response with the merge conflict archive * - * Merge conflicts are always have to be resolved manually, + * Merge conflicts always have to be resolved manually, * so we use a different archive for that. * * @return BinaryFileResponse diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php index e73e07208e..0f0840f470 100644 --- a/phpBB/phpbb/install/helper/config.php +++ b/phpBB/phpbb/install/helper/config.php @@ -262,7 +262,7 @@ class config * * @param string $name Name of the restart point * - * @return bool Returns false if the restart point name is not exist, true otherwise + * @return bool Returns false if the restart point name does not exist, otherwise true */ public function jump_to_restart_point($name) { -- cgit v1.2.1 From afe91fa7d3af0d30389c49428b30c9aeb0fe0916 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 11:22:19 +0200 Subject: [ticket/14039] Fix T_TEMPLATE_PATH constant PHPBB3-14039 --- phpBB/phpbb/install/controller/helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/helper.php b/phpBB/phpbb/install/controller/helper.php index ef6b8ba3c2..bfa9ec6238 100644 --- a/phpBB/phpbb/install/controller/helper.php +++ b/phpBB/phpbb/install/controller/helper.php @@ -271,7 +271,7 @@ class helper 'PAGE_TITLE' => $this->language->lang($page_title), 'T_IMAGE_PATH' => $this->path_helper->get_web_root_path() . $path . 'images/', 'T_JQUERY_LINK' => $this->path_helper->get_web_root_path() . $path . '../assets/javascript/jquery.min.js', - 'T_TEMPLATE_PATH' => $this->path_helper->get_web_root_path() . $path . 'style', + 'T_TEMPLATE_PATH' => $this->path_helper->get_web_root_path() . $path . 'style/', 'T_ASSETS_PATH' => $this->path_helper->get_web_root_path() . $path . '../assets/', 'S_CONTENT_DIRECTION' => $this->language->lang('DIRECTION'), -- cgit v1.2.1 From 100bb8f27c52b2faffddf2a6926c5d7b49faa421 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 11:26:41 +0200 Subject: [ticket/14039] Use http_exception instead of die() PHPBB3-14039 --- phpBB/phpbb/install/controller/archive_download.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/archive_download.php b/phpBB/phpbb/install/controller/archive_download.php index e1f7634963..a0f0ba181d 100644 --- a/phpBB/phpbb/install/controller/archive_download.php +++ b/phpBB/phpbb/install/controller/archive_download.php @@ -13,6 +13,7 @@ namespace phpbb\install\controller; +use phpbb\exception\http_exception; use phpbb\install\helper\config; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\ResponseHeaderBag; @@ -49,7 +50,7 @@ class archive_download if (!$filename) { - die ('The requested file is not exist.'); + throw new http_exception(404, 'URL_NOT_FOUND'); } return $this->send_response($filename); @@ -66,7 +67,7 @@ class archive_download if (!$filename) { - die ('The requested file is not exist.'); + throw new http_exception(404, 'URL_NOT_FOUND'); } return $this->send_response($filename); -- cgit v1.2.1 From 6b561b9eae320b06178725fdccbc3e67c0990837 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 11:30:09 +0200 Subject: [ticket/14039] Use compatibility globals from the update package PHPBB3-14039 --- phpBB/phpbb/install/helper/container_factory.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php index fd42d53c00..8c007de39f 100644 --- a/phpBB/phpbb/install/helper/container_factory.php +++ b/phpBB/phpbb/install/helper/container_factory.php @@ -168,6 +168,13 @@ class container_factory } // Get compatibilty globals - require ($this->phpbb_root_path . 'includes/compatibility_globals.' . $this->php_ext); + if (file_exists($this->phpbb_root_path . 'install/update/new/includes/compatibility_globals.' . $this->php_ext)) + { + require($this->phpbb_root_path . 'install/update/new/includes/compatibility_globals.' . $this->php_ext); + } + else + { + require($this->phpbb_root_path . 'includes/compatibility_globals.' . $this->php_ext); + } } } -- cgit v1.2.1 From dd8580632765c051ea68b877ce608ca69b5655fe Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 14:00:53 +0200 Subject: [ticket/14039] Fix filesystem file updater's mkdir usage PHPBB3-14039 --- .../phpbb/install/helper/file_updater/file_updater.php | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/file_updater/file_updater.php b/phpBB/phpbb/install/helper/file_updater/file_updater.php index 8ebbf64253..00cb0d17bd 100644 --- a/phpBB/phpbb/install/helper/file_updater/file_updater.php +++ b/phpBB/phpbb/install/helper/file_updater/file_updater.php @@ -155,22 +155,7 @@ class file_updater implements file_updater_interface } $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); - $dirs = explode('/', $path); - $dirs_to_create = array(); - - do - { - $path .= '../'; - $dirs_to_create[] = array_pop($dirs); - } - while (!is_dir($path)); - - foreach ($dirs_to_create as $directory) - { - $path .= $directory; - $this->filesystem->mkdir($path, 493); // 493 === 0755 - $path .= '/'; - } + $this->filesystem->mkdir($path, 493); // 493 === 0755 } /** -- cgit v1.2.1 From 29908e54bcdf734150371fded932d04042580505 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 17:31:12 +0200 Subject: [ticket/14039] Use shared language service in the container factory PHPBB3-14039 --- phpBB/phpbb/install/helper/container_factory.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php index 8c007de39f..efbe278628 100644 --- a/phpBB/phpbb/install/helper/container_factory.php +++ b/phpBB/phpbb/install/helper/container_factory.php @@ -15,9 +15,16 @@ namespace phpbb\install\helper; use phpbb\cache\driver\dummy; use phpbb\install\exception\cannot_build_container_exception; +use phpbb\language\language; +use phpbb\request\request; class container_factory { + /** + * @var language + */ + protected $language; + /** * @var string */ @@ -43,12 +50,14 @@ class container_factory /** * Constructor * - * @param \phpbb\request\request $request Request interface - * @param string $phpbb_root_path Path to phpBB's root - * @param string $php_ext Extension of PHP files + * @param language $language Language service + * @param request $request Request interface + * @param string $phpbb_root_path Path to phpBB's root + * @param string $php_ext Extension of PHP files */ - public function __construct(\phpbb\request\request $request, $phpbb_root_path, $php_ext) + public function __construct(language $language, request $request, $phpbb_root_path, $php_ext) { + $this->language = $language; $this->request = $request; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; @@ -150,6 +159,9 @@ class container_factory $this->container->register('request')->setSynthetic(true); $this->container->set('request', $this->request); + $this->container->register('language')->setSynthetic(true); + $this->container->set('language', $this->language); + // Replace cache service, as config gets cached, and we don't want that when we are installing if (!is_dir($other_config_path)) { -- cgit v1.2.1 From 3b593c5d522f8ac374ea443925ae8159782ff9dd Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 18:17:28 +0200 Subject: [ticket/14039] Fix misunderstandable comment in the archive file updater PHPBB3-14039 --- phpBB/phpbb/install/helper/file_updater/compression_file_updater.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/file_updater/compression_file_updater.php b/phpBB/phpbb/install/helper/file_updater/compression_file_updater.php index a6eca36653..ede992fb6e 100644 --- a/phpBB/phpbb/install/helper/file_updater/compression_file_updater.php +++ b/phpBB/phpbb/install/helper/file_updater/compression_file_updater.php @@ -94,7 +94,9 @@ class compression_file_updater implements file_updater_interface */ public function delete_file($path_to_file) { - // We do absolutely nothing here + // We do absolutely nothing here, as this function is called when a file should be + // removed from the filesystem, but since this is an archive generator, it clearly + // cannot do that. } /** -- cgit v1.2.1 From 94bd35fd3b24b727adb91ba325e6bb8d1522c7b0 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 18:28:12 +0200 Subject: [ticket/14039] Fix migrator's language calls PHPBB3-14039 --- phpBB/phpbb/db/output_handler/html_migrator_output_handler.php | 2 +- phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/output_handler/html_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/html_migrator_output_handler.php index f15b8e5913..67309649c9 100644 --- a/phpBB/phpbb/db/output_handler/html_migrator_output_handler.php +++ b/phpBB/phpbb/db/output_handler/html_migrator_output_handler.php @@ -39,7 +39,7 @@ class html_migrator_output_handler implements migrator_output_handler_interface { if ($verbosity <= migrator_output_handler_interface::VERBOSITY_VERBOSE) { - $final_message = $this->language->lang_array($message); + $final_message = $this->language->lang_array(array_shift($message), $message); echo $final_message . "
\n"; } } diff --git a/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php index 475b2616e5..20991746ac 100644 --- a/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php +++ b/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php @@ -82,7 +82,8 @@ class log_wrapper_migrator_output_handler implements migrator_output_handler_int if ($this->file_handle !== false) { - $translated_message = $this->language->lang_array($message); + + $translated_message = $this->language->lang_array(array_shift($message), $message); if ($verbosity <= migrator_output_handler_interface::VERBOSITY_NORMAL) { -- cgit v1.2.1 From 56093d1c82d6f4d5c0f2741769eb071eb7bec5d7 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 19:18:53 +0200 Subject: [ticket/14039] Fix constants for the updater PHPBB3-14039 --- phpBB/phpbb/install/helper/container_factory.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php index efbe278628..bf19efe22e 100644 --- a/phpBB/phpbb/install/helper/container_factory.php +++ b/phpBB/phpbb/install/helper/container_factory.php @@ -133,7 +133,7 @@ class container_factory $phpbb_container_builder = new \phpbb\di\container_builder($this->phpbb_root_path, $this->php_ext); // For BC with functions that we need during install - global $phpbb_container; + global $phpbb_container, $table_prefix; $disable_super_globals = $this->request->super_globals_disabled(); @@ -172,6 +172,7 @@ class container_factory $this->container->compile(); $phpbb_container = $this->container; + $table_prefix = $phpbb_config_php_file->get('table_prefix'); // Restore super globals to previous state if ($disable_super_globals) @@ -188,5 +189,15 @@ class container_factory { require($this->phpbb_root_path . 'includes/compatibility_globals.' . $this->php_ext); } + + // Get compatibilty globals + if (file_exists($this->phpbb_root_path . 'install/update/new/includes/constants.' . $this->php_ext)) + { + require($this->phpbb_root_path . 'install/update/new/includes/constants.' . $this->php_ext); + } + else + { + require($this->phpbb_root_path . 'includes/constants.' . $this->php_ext); + } } } -- cgit v1.2.1 From ed442198d1fff379b65b8d4a1c3bfb15890cfed1 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 19:27:50 +0200 Subject: [ticket/14039] Fix ACP link generation PHPBB3-14039 --- phpBB/phpbb/install/installer.php | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index 8a0374b1f0..bdff62e0b1 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -21,6 +21,7 @@ use phpbb\install\exception\user_interaction_required_exception; use phpbb\install\helper\config; use phpbb\install\helper\iohandler\cli_iohandler; use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\path_helper; class installer { @@ -39,6 +40,11 @@ class installer */ protected $iohandler; + /** + * @var string + */ + protected $web_root; + /** * Stores the number of steps that a given module has * @@ -49,12 +55,14 @@ class installer /** * Constructor * - * @param config $config Installer config handler + * @param config $config Installer config handler + * @param path_helper $path_helper Path helper */ - public function __construct(config $config) + public function __construct(config $config, path_helper $path_helper) { $this->install_config = $config; $this->installer_modules = null; + $this->web_root = $path_helper->get_web_root_path(); } /** @@ -183,21 +191,7 @@ class installer else { global $SID; - - // Construct ACP url - $acp_url = $protocol = $this->install_config->get('server_protocol'); - $acp_url .= $this->install_config->get('server_name'); - $port = $this->install_config->get('server_port'); - - if (!((strpos($protocol, 'https:') === 0 && $port === 443) - || (strpos($protocol, 'http:') === 0 && $port === 80))) - { - $acp_url .= ':' . $port; - } - - $acp_url .= $this->install_config->get('script_path'); - $acp_url .= '/adm/index.php' . $SID; - + $acp_url = $this->web_root . '/adm/index.php' . $SID; $this->iohandler->add_success_message('INSTALLER_FINISHED', array( 'ACP_LINK', $acp_url, -- cgit v1.2.1 From 0ce72f94a21d7407b08c8d2cb233d445434743b4 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 22:33:31 +0200 Subject: [ticket/14039] Fix acp link PHPBB3-14039 --- phpBB/phpbb/install/installer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index bdff62e0b1..77e0a896bc 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -191,7 +191,7 @@ class installer else { global $SID; - $acp_url = $this->web_root . '/adm/index.php' . $SID; + $acp_url = $this->web_root . 'adm/index.php' . $SID; $this->iohandler->add_success_message('INSTALLER_FINISHED', array( 'ACP_LINK', $acp_url, -- cgit v1.2.1 From 4b447c71de8af0530574958e4c788186b606346f Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 23:04:53 +0200 Subject: [ticket/14039] Fix file check for deleted files PHPBB3-14039 --- phpBB/phpbb/install/module/update_filesystem/task/file_check.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php index 9945e61714..4d9f736b0a 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -108,7 +108,7 @@ class file_check extends task_base $update_info['deleted'], function ($filename) use ($root_path) { - return !file_exists($root_path . $filename); + return file_exists($root_path . $filename); } ); } -- cgit v1.2.1 From 2f8ef80d92457e29f688155cd5433a92fa981139 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 23:11:20 +0200 Subject: [ticket/14039] Fix folder creation and deleted binary file issue PHPBB3-14039 --- phpBB/phpbb/install/helper/file_updater/file_updater.php | 7 +++++++ phpBB/phpbb/install/module/update_filesystem/task/file_check.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/file_updater/file_updater.php b/phpBB/phpbb/install/helper/file_updater/file_updater.php index 00cb0d17bd..cc0f5c6b5f 100644 --- a/phpBB/phpbb/install/helper/file_updater/file_updater.php +++ b/phpBB/phpbb/install/helper/file_updater/file_updater.php @@ -113,6 +113,13 @@ class file_updater implements file_updater_interface $path_to_file_to_update = $this->phpbb_root_path . $path_to_file_to_update; $original_file_perms = false; + // Maybe necessary for binary files + $dir = dirname($path_to_file_to_update); + if (!$this->filesystem->exists($dir)) + { + $this->make_dir($dir); + } + if (!$this->filesystem->is_writable($path_to_file_to_update)) { // Extract last 9 bits we actually need diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php index 4d9f736b0a..5dbee6c259 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -101,7 +101,7 @@ class file_check extends task_base $update_info = $this->installer_config->get('update_info_unprocessed', array()); $file_update_info = array(); - $file_update_info['update_without_diff'] = $update_info['binary']; + $file_update_info['update_without_diff'] = array_diff($update_info['binary'], $update_info['deleted']); // Filter out files that are already deleted $file_update_info['delete'] = array_filter( -- cgit v1.2.1 From de729110c8d723b64da333f515ba0acf2723c88c Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Mon, 19 Oct 2015 01:19:31 +0200 Subject: [ticket/14039] Fix inclusion logic in update helper PHPBB3-14039 --- phpBB/phpbb/install/helper/update_helper.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/update_helper.php b/phpBB/phpbb/install/helper/update_helper.php index 2a3e6ceb0a..a00731d317 100644 --- a/phpBB/phpbb/install/helper/update_helper.php +++ b/phpBB/phpbb/install/helper/update_helper.php @@ -72,16 +72,11 @@ class update_helper */ public function include_file($filename) { - if (!is_file($this->phpbb_root_path . $filename)) - { - return; - } - if (is_file($this->path_to_new_files . $filename)) { include_once($this->path_to_new_files . $filename); } - else + else if (is_file($this->phpbb_root_path . $filename)) { include_once($this->phpbb_root_path . $filename); } -- cgit v1.2.1 From d45f146814a1709a16fb8e4951374242d50b6aed Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Mon, 19 Oct 2015 09:12:26 +0200 Subject: [ticket/14039] Use update helper to include files in container factory PHPBB3-14039 --- phpBB/phpbb/install/helper/container_factory.php | 39 +++++++++--------------- 1 file changed, 15 insertions(+), 24 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php index bf19efe22e..6c1ecd2d02 100644 --- a/phpBB/phpbb/install/helper/container_factory.php +++ b/phpBB/phpbb/install/helper/container_factory.php @@ -40,6 +40,11 @@ class container_factory */ protected $request; + /** + * @var update_helper + */ + protected $update_helper; + /** * The full phpBB container * @@ -50,15 +55,17 @@ class container_factory /** * Constructor * - * @param language $language Language service - * @param request $request Request interface - * @param string $phpbb_root_path Path to phpBB's root - * @param string $php_ext Extension of PHP files + * @param language $language Language service + * @param request $request Request interface + * @param update_helper $update_helper Update helper + * @param string $phpbb_root_path Path to phpBB's root + * @param string $php_ext Extension of PHP files */ - public function __construct(language $language, request $request, $phpbb_root_path, $php_ext) + public function __construct(language $language, request $request, update_helper $update_helper, $phpbb_root_path, $php_ext) { $this->language = $language; $this->request = $request; + $this->update_helper = $update_helper; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; $this->container = null; @@ -180,24 +187,8 @@ class container_factory $this->request->disable_super_globals(); } - // Get compatibilty globals - if (file_exists($this->phpbb_root_path . 'install/update/new/includes/compatibility_globals.' . $this->php_ext)) - { - require($this->phpbb_root_path . 'install/update/new/includes/compatibility_globals.' . $this->php_ext); - } - else - { - require($this->phpbb_root_path . 'includes/compatibility_globals.' . $this->php_ext); - } - - // Get compatibilty globals - if (file_exists($this->phpbb_root_path . 'install/update/new/includes/constants.' . $this->php_ext)) - { - require($this->phpbb_root_path . 'install/update/new/includes/constants.' . $this->php_ext); - } - else - { - require($this->phpbb_root_path . 'includes/constants.' . $this->php_ext); - } + // Get compatibilty globals and constants + $this->update_helper->include_file('includes/compatibility_globals.' . $this->php_ext); + $this->update_helper->include_file('includes/constants.' . $this->php_ext); } } -- cgit v1.2.1 From 597297b169e2ae14684ad1f40c8e083be22b241d Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 18 Oct 2015 22:47:04 +0200 Subject: [ticket/14044] Deduplicate the installers PHPBB3-14044 --- .../module/install_database/task/create_schema.php | 13 +++++++--- .../install_filesystem/task/create_config_file.php | 29 +++++++++++++++------- .../module/install_finish/task/notify_user.php | 2 ++ .../install_finish/task/populate_migrations.php | 2 ++ 4 files changed, 34 insertions(+), 12 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_database/task/create_schema.php b/phpBB/phpbb/install/module/install_database/task/create_schema.php index 7cc521eee8..cabb78787f 100644 --- a/phpBB/phpbb/install/module/install_database/task/create_schema.php +++ b/phpBB/phpbb/install/module/install_database/task/create_schema.php @@ -80,6 +80,16 @@ class create_schema extends \phpbb\install\task_base $factory = new \phpbb\db\tools\factory(); $this->db = new $dbms(); + $this->db->sql_connect( + $config->get('dbhost'), + $config->get('dbuser'), + $config->get('dbpasswd'), + $config->get('dbname'), + $config->get('dbport'), + false, + false + ); + $this->config = $config; $this->db_tools = $factory->get($this->db); $this->database_helper = $db_helper; @@ -89,9 +99,6 @@ class create_schema extends \phpbb\install\task_base $this->php_ext = $php_ext; parent::__construct(true); - - // Connect to DB - $this->db->sql_connect($config->get('dbhost'), $config->get('dbuser'), $config->get('dbpasswd'), $config->get('dbname'), $config->get('dbport'), false, false); } /** diff --git a/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php b/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php index 337d401216..e0890a929c 100644 --- a/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php +++ b/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php @@ -50,6 +50,11 @@ class create_config_file extends \phpbb\install\task_base */ protected $php_ext; + /** + * @var array + */ + protected $options; + /** * Constructor * @@ -59,13 +64,15 @@ class create_config_file extends \phpbb\install\task_base * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler * @param string $phpbb_root_path * @param string $php_ext + * @param array $options */ public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, \phpbb\install\helper\config $install_config, \phpbb\install\helper\database $db_helper, \phpbb\install\helper\iohandler\iohandler_interface $iohandler, $phpbb_root_path, - $php_ext) + $php_ext, + $options = array()) { $this->install_config = $install_config; $this->db_helper = $db_helper; @@ -73,6 +80,11 @@ class create_config_file extends \phpbb\install\task_base $this->iohandler = $iohandler; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; + $this->options = array_merge(array( + 'debug' => false, + 'debug_container' => false, + 'environment' => null, + ), $options); parent::__construct(true); } @@ -93,7 +105,7 @@ class create_config_file extends \phpbb\install\task_base $config_written = false; } - $config_content = $this->get_config_data(); + $config_content = $this->get_config_data($this->options['debug'], $this->options['debug_container'], $this->options['environment']); if (!@fwrite($fp, $config_content)) { @@ -145,15 +157,14 @@ class create_config_file extends \phpbb\install\task_base /** * Returns the content which should be dumped to config.php * - * @param bool $debug If the debug constants should be enabled by default or not - * @param bool $debug_container If the container should be compiled on + * @param bool $debug If the debug constants should be enabled by default or not + * @param bool $debug_container If the container should be compiled on * every page load or not - * @param bool $debug_test If the DEBUG_TEST constant should be added - * NOTE: Only for use within the testing framework + * @param string $environment The environment to use * * @return string content to be written to the config file */ - protected function get_config_data($debug = false, $debug_container = false, $debug_test = false) + protected function get_config_data($debug = false, $debug_container = false, $environment = null) { $config_content = "get('cache.driver'), $container->get_parameter('tables.config') ); + + parent::__construct(true); } /** diff --git a/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php b/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php index b2a4800f86..8629d9aea3 100644 --- a/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php +++ b/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php @@ -37,6 +37,8 @@ class populate_migrations extends \phpbb\install\task_base { $this->extension_manager = $container->get('ext.manager'); $this->migrator = $container->get('migrator'); + + parent::__construct(true); } /** -- cgit v1.2.1 From e0d06ee83ebf9ae72ef9746385155168fb083fa9 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 22 Oct 2015 11:27:03 +0200 Subject: [ticket/14044] Fix Sqlite error in tests PHPBB3-14044 --- phpBB/phpbb/db/driver/sqlite3.php | 14 +++++++++++++- phpBB/phpbb/search/fulltext_native.php | 10 ++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/sqlite3.php b/phpBB/phpbb/db/driver/sqlite3.php index b7f6e60337..2000acb251 100644 --- a/phpBB/phpbb/db/driver/sqlite3.php +++ b/phpBB/phpbb/db/driver/sqlite3.php @@ -136,7 +136,19 @@ class sqlite3 extends \phpbb\db\driver\driver { if (($this->query_result = @$this->dbo->query($query)) === false) { - $this->sql_error($query); + // Try to recover a lost database connection + if ($this->dbo && !@$this->dbo->lastErrorMsg()) + { + if ($this->sql_connect($this->server, $this->user, '', $this->dbname)) + { + $this->query_result = @$this->dbo->query($query); + } + } + + if ($this->query_result === false) + { + $this->sql_error($query); + } } if (defined('DEBUG')) diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 3a74955a18..5fc276170d 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -1478,10 +1478,7 @@ class fulltext_native extends \phpbb\search\base $this->db->sql_return_on_error(false); } unset($new_words, $sql_ary); - } - else - { - $this->db->sql_transaction('begin'); + $this->db->sql_transaction('commit'); } // now update the search match table, remove links to removed words and add links to new words @@ -1513,6 +1510,11 @@ class fulltext_native extends \phpbb\search\base } } + if (!count($unique_add_words)) + { + $this->db->sql_transaction('begin'); + } + $this->db->sql_return_on_error(true); foreach ($words['add'] as $word_in => $word_ary) { -- cgit v1.2.1 From d34d6378bc7db03daa763aa54739b69b07610702 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Fri, 23 Oct 2015 13:25:00 +0200 Subject: [ticket/14044] Use empty instead of !count PHPBB3-14044 --- phpBB/phpbb/search/fulltext_native.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 5fc276170d..516316dc54 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -1510,7 +1510,7 @@ class fulltext_native extends \phpbb\search\base } } - if (!count($unique_add_words)) + if (empty($unique_add_words)) { $this->db->sql_transaction('begin'); } -- cgit v1.2.1 From df53d409226dd9a0ccbeac93f017a4363a1c98cf Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 23 Oct 2015 16:34:01 +0200 Subject: [ticket/14044] Automatically trigger rollback on insert in transaction This will cause the sqlite3 driver to automatically rollback transactions if an insert fails during a transaction. Other dbms trigger a rollback inside the sql_error() function with a rollback command. However, this manual rollback command might fail on sqlite3 due to ongoing queries. With this change, sqlite3 itself will abort any ongoing queries and initiate the rollback automatically. Since manually triggered rollbacks will fail after the rollback was started automatically, we catch exceptions output by the exec() command during rollback and any exception that might be thrown by fetchArray() due to aborted queries. PHPBB3-14044 --- phpBB/phpbb/db/driver/sqlite3.php | 10 ++++++++-- phpBB/phpbb/search/fulltext_native.php | 10 ++++------ 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/sqlite3.php b/phpBB/phpbb/db/driver/sqlite3.php index 2000acb251..0508500c52 100644 --- a/phpBB/phpbb/db/driver/sqlite3.php +++ b/phpBB/phpbb/db/driver/sqlite3.php @@ -102,7 +102,7 @@ class sqlite3 extends \phpbb\db\driver\driver break; case 'rollback': - return $this->dbo->exec('ROLLBACK'); + return @$this->dbo->exec('ROLLBACK'); break; } @@ -134,6 +134,11 @@ class sqlite3 extends \phpbb\db\driver\driver if ($this->query_result === false) { + if ($this->transaction === true && strpos($query, 'INSERT') === 0) + { + $query = preg_replace('/^INSERT INTO/', 'INSERT OR ROLLBACK INTO', $query); + } + if (($this->query_result = @$this->dbo->query($query)) === false) { // Try to recover a lost database connection @@ -225,6 +230,7 @@ class sqlite3 extends \phpbb\db\driver\driver if ($query_id === false) { + /** @var \SQLite3Result $query_id */ $query_id = $this->query_result; } @@ -233,7 +239,7 @@ class sqlite3 extends \phpbb\db\driver\driver return $cache->sql_fetchrow($query_id); } - return is_object($query_id) ? $query_id->fetchArray(SQLITE3_ASSOC) : false; + return is_object($query_id) ? @$query_id->fetchArray(SQLITE3_ASSOC) : false; } /** diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 516316dc54..3a74955a18 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -1478,7 +1478,10 @@ class fulltext_native extends \phpbb\search\base $this->db->sql_return_on_error(false); } unset($new_words, $sql_ary); - $this->db->sql_transaction('commit'); + } + else + { + $this->db->sql_transaction('begin'); } // now update the search match table, remove links to removed words and add links to new words @@ -1510,11 +1513,6 @@ class fulltext_native extends \phpbb\search\base } } - if (empty($unique_add_words)) - { - $this->db->sql_transaction('begin'); - } - $this->db->sql_return_on_error(true); foreach ($words['add'] as $word_in => $word_ary) { -- cgit v1.2.1 From 8376c6552a7860036640a5840f26dba239c20750 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sat, 24 Oct 2015 19:59:51 +0200 Subject: [ticket/14257] Add cron tasks for reparsing text PHPBB3-14257 --- phpBB/phpbb/cron/task/text_reparser/reparser.php | 197 +++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 phpBB/phpbb/cron/task/text_reparser/reparser.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cron/task/text_reparser/reparser.php b/phpBB/phpbb/cron/task/text_reparser/reparser.php new file mode 100644 index 0000000000..334ce46c26 --- /dev/null +++ b/phpBB/phpbb/cron/task/text_reparser/reparser.php @@ -0,0 +1,197 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\cron\task\text_reparser; + +/** + * Reparse text cron task + */ +class reparser extends \phpbb\cron\task\base +{ + const MIN = 1; + const SIZE = 100; + + /** + * @var \phpbb\config\config + */ + protected $config; + + /** + * @var \phpbb\config\db_text + */ + protected $config_text; + + /** + * @var \phpbb\lock\db + */ + protected $reparse_lock; + + /** + * @var \phpbb\di\service_collection + */ + protected $reparsers; + + /** + * @var string + */ + protected $reparser_name; + + /** + * @var array + */ + protected $resume_data; + + /** + * Constructor + * + * @param \phpbb\config\config $config + * @param \phpbb\config\db_text $config_text + * @param \phpbb\lock\db $reparse_lock + * @param \phpbb\di\service_collection $reparsers + */ + public function __construct(\phpbb\config\config $config, \phpbb\config\db_text $config_text, \phpbb\lock\db $reparse_lock, \phpbb\di\service_collection $reparsers) + { + $this->config = $config; + $this->config_text = $config_text; + $this->reparse_lock = $reparse_lock; + $this->reparsers = $reparsers; + } + + /** + * Sets the reparser for this cron task + * + * @param string $reparser + */ + public function set_reparser($reparser) + { + if (isset($this->reparsers[$reparser])) + { + $this->reparser_name = preg_replace('(^text_reparser\\.)', '', $reparser); + } + else if (isset($this->reparsers['text_reparser.' . $reparser])) + { + $this->reparser_name = $reparser; + } + + if ($this->resume_data === null) + { + $this->load_resume_data(); + } + } + + /** + * {@inheritdoc} + */ + public function is_runnable() + { + if ($this->resume_data === null) + { + $this->load_resume_data(); + } + + if (empty($this->resume_data[$this->reparser_name]['range-max']) || $this->resume_data[$this->reparser_name]['range-max'] === $this->resume_data[$this->reparser_name]['range-min']) + { + return true; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function should_run() + { + if (!empty($this->config['reparse_lock'])) + { + $last_run = explode(' ', $this->config['reparse_lock']); + + if ($last_run[0] + 3600 >= time()) + { + return false; + } + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if ($this->reparse_lock->acquire()) + { + if ($this->resume_data === null) + { + $this->load_resume_data(); + } + + /** + * @var \phpbb\textreparser\reparser_interface $reparser + */ + $reparser = isset($this->reparsers[$this->reparser_name]) ? $this->reparsers[$this->reparser_name] : $this->reparsers['text_reparser.' . $this->reparser_name]; + + $min = !empty($this->resume_data[$this->reparser_name]['range-min']) ? $this->resume_data[$this->reparser_name]['range-min'] : self::MIN; + $current = !empty($this->resume_data[$this->reparser_name]['range-max']) ? $this->resume_data[$this->reparser_name]['range-max'] : $reparser->get_max_id(); + $size = !empty($this->resume_data[$this->reparser_name]['range-size']) ? $this->resume_data[$this->reparser_name]['range-size'] : self::SIZE; + + if ($current >= $min) + { + $start = max($min, $current + 1 - $size); + $end = max($min, $current); + + $reparser->reparse_range($start, $end); + + $this->update_resume_data($this->reparser_name, $min, $start - 1, $size); + } + + $this->reparse_lock->release(); + } + } + + /** + * Load the resume data from the database + */ + protected function load_resume_data() + { + $resume_data = $this->config_text->get('reparser_resume'); + $this->resume_data = (empty($resume_data)) ? array() : unserialize($resume_data); + } + + /** + * Save the resume data to the database + */ + protected function save_resume_data() + { + $this->config_text->set('reparser_resume', serialize($this->resume_data)); + } + + /** + * Save the resume data to the database + * + * @param string $name Reparser name + * @param int $min Lowest record ID + * @param int $current Current ID + * @param int $size Number of records to process at a time + */ + protected function update_resume_data($name, $min, $current, $size) + { + $this->resume_data[$name] = array( + 'range-min' => $min, + 'range-max' => $current, + 'range-size' => $size, + ); + $this->save_resume_data(); + } +} -- cgit v1.2.1 From c7ecb1310f7663e5fdaafb655381663b9410c31a Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sat, 24 Oct 2015 20:10:16 +0200 Subject: [ticket/14257] Add reparse_lock to CLI command PHPBB3-14257 --- phpBB/phpbb/console/command/reparser/reparse.php | 50 ++++++++++++++++-------- 1 file changed, 34 insertions(+), 16 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/reparser/reparse.php b/phpBB/phpbb/console/command/reparser/reparse.php index 63124b4b8c..e77b384d8e 100644 --- a/phpBB/phpbb/console/command/reparser/reparse.php +++ b/phpBB/phpbb/console/command/reparser/reparse.php @@ -13,6 +13,7 @@ namespace phpbb\console\command\reparser; +use phpbb\exception\runtime_exception; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; @@ -41,6 +42,11 @@ class reparse extends \phpbb\console\command\command */ protected $output; + /** + * @var \phpbb\lock\db + */ + protected $reparse_lock; + /** * @var \phpbb\di\service_collection */ @@ -57,13 +63,15 @@ class reparse extends \phpbb\console\command\command * @param \phpbb\user $user * @param \phpbb\di\service_collection $reparsers * @param \phpbb\config\db_text $config_text + * @param \phpbb\lock\db $reparse_lock */ - public function __construct(\phpbb\user $user, \phpbb\di\service_collection $reparsers, \phpbb\config\db_text $config_text) + public function __construct(\phpbb\user $user, \phpbb\di\service_collection $reparsers, \phpbb\config\db_text $config_text, \phpbb\lock\db $reparse_lock) { require_once __DIR__ . '/../../../../includes/functions_content.php'; $this->config_text = $config_text; $this->reparsers = $reparsers; + $this->reparse_lock = $reparse_lock; parent::__construct($user); } @@ -163,29 +171,39 @@ class reparse extends \phpbb\console\command\command $this->input = $input; $this->output = $output; $this->io = new SymfonyStyle($input, $output); - $this->load_resume_data(); - $name = $input->getArgument('reparser-name'); - if (isset($name)) + if (!$this->reparse_lock->acquire()) { - // Allow "post_text" to be an alias for "text_reparser.post_text" - if (!isset($this->reparsers[$name])) + $this->load_resume_data(); + + $name = $input->getArgument('reparser-name'); + if (isset($name)) { - $name = 'text_reparser.' . $name; + // Allow "post_text" to be an alias for "text_reparser.post_text" + if (!isset($this->reparsers[$name])) + { + $name = 'text_reparser.' . $name; + } + $this->reparse($name); } - $this->reparse($name); - } - else - { - foreach ($this->reparsers as $name => $service) + else { - $this->reparse($name); + foreach ($this->reparsers as $name => $service) + { + $this->reparse($name); + } } - } - $this->io->success($this->user->lang('CLI_REPARSER_REPARSE_SUCCESS')); + $this->io->success($this->user->lang('CLI_REPARSER_REPARSE_SUCCESS')); - return 0; + $this->reparse_lock->release(); + + return 0; + } + else + { + throw new runtime_exception('REPARSE_LOCK_ERROR', array(), null, 1); + } } /** -- cgit v1.2.1 From c7ebbcf9f2bf8670ac219fd919f6ee37c5aeb37f Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sat, 24 Oct 2015 21:24:34 +0200 Subject: [ticket/14257] Fix if condition PHPBB3-14257 --- phpBB/phpbb/cron/task/text_reparser/reparser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cron/task/text_reparser/reparser.php b/phpBB/phpbb/cron/task/text_reparser/reparser.php index 334ce46c26..a8faca3d06 100644 --- a/phpBB/phpbb/cron/task/text_reparser/reparser.php +++ b/phpBB/phpbb/cron/task/text_reparser/reparser.php @@ -99,7 +99,7 @@ class reparser extends \phpbb\cron\task\base $this->load_resume_data(); } - if (empty($this->resume_data[$this->reparser_name]['range-max']) || $this->resume_data[$this->reparser_name]['range-max'] === $this->resume_data[$this->reparser_name]['range-min']) + if (empty($this->resume_data[$this->reparser_name]['range-max']) || $this->resume_data[$this->reparser_name]['range-max'] >= $this->resume_data[$this->reparser_name]['range-min']) { return true; } -- cgit v1.2.1 From 8b0f8d7b3cf7e7687f11c2fc0a15d4919c91b6c1 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sun, 25 Oct 2015 02:31:22 +0200 Subject: [ticket/14257] Fix lock acquire in CLI command PHPBB3-14257 --- phpBB/phpbb/console/command/reparser/reparse.php | 42 +++++++++++------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/reparser/reparse.php b/phpBB/phpbb/console/command/reparser/reparse.php index e77b384d8e..6fac3db854 100644 --- a/phpBB/phpbb/console/command/reparser/reparse.php +++ b/phpBB/phpbb/console/command/reparser/reparse.php @@ -174,36 +174,34 @@ class reparse extends \phpbb\console\command\command if (!$this->reparse_lock->acquire()) { - $this->load_resume_data(); + throw new runtime_exception('REPARSE_LOCK_ERROR', array(), null, 1); + } - $name = $input->getArgument('reparser-name'); - if (isset($name)) + $this->load_resume_data(); + + $name = $input->getArgument('reparser-name'); + if (isset($name)) + { + // Allow "post_text" to be an alias for "text_reparser.post_text" + if (!isset($this->reparsers[$name])) { - // Allow "post_text" to be an alias for "text_reparser.post_text" - if (!isset($this->reparsers[$name])) - { - $name = 'text_reparser.' . $name; - } - $this->reparse($name); + $name = 'text_reparser.' . $name; } - else + $this->reparse($name); + } + else + { + foreach ($this->reparsers as $name => $service) { - foreach ($this->reparsers as $name => $service) - { - $this->reparse($name); - } + $this->reparse($name); } + } - $this->io->success($this->user->lang('CLI_REPARSER_REPARSE_SUCCESS')); + $this->io->success($this->user->lang('CLI_REPARSER_REPARSE_SUCCESS')); - $this->reparse_lock->release(); + $this->reparse_lock->release(); - return 0; - } - else - { - throw new runtime_exception('REPARSE_LOCK_ERROR', array(), null, 1); - } + return 0; } /** -- cgit v1.2.1 From 33500fd3728f6e3444d5479b09b941b2570ff47c Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sun, 25 Oct 2015 02:07:40 +0100 Subject: [ticket/14257] Use migrations instead of cron job for some reparsers PHPBB3-14257 --- .../phpbb/db/migration/data/v320/reparse_fast.php | 87 ++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/reparse_fast.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/reparse_fast.php b/phpBB/phpbb/db/migration/data/v320/reparse_fast.php new file mode 100644 index 0000000000..ddb11f7f67 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/reparse_fast.php @@ -0,0 +1,87 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v320; + +class reparse_fast extends \phpbb\db\migration\container_aware_migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\contact_admin_form'); + } + + public function effectively_installed() + { + return isset($this->config['reparse_lock']); + } + + public function update_data() + { + return array( + array('config.add', array('reparse_lock', 0, true)), + array('custom', array(array($this, 'reparse'))), + ); + } + + public function reparse($resume_data) + { + // Somtimes a cron job is too much + $limit = 200; + $fast_reparsers = array( + 'text_reparser.contact_admin_info', + 'text_reparser.forum_description', + 'text_reparser.forum_rules', + 'text_reparser.group_description', + ); + + if (!is_array($resume_data)) + { + $resume_data = array( + 'reparser' => 0, + 'current' => $this->container->get($fast_reparsers[0])->get_max_id(), + ); + } + + $fast_reparsers_size = sizeof($fast_reparsers); + $processed_records = 0; + while ($processed_records < $limit && $resume_data['reparser'] < $fast_reparsers_size) + { + $reparser = $this->container->get($fast_reparsers[$resume_data['reparser']]); + + // New reparser + if ($resume_data['current'] === 0) + { + $resume_data['current'] = $reparser->get_max_id(); + } + + $start = max(1, $resume_data['current'] + 1 - ($limit - $processed_records)); + $end = max(1, $resume_data['current']); + $reparser->reparse_range($start, $end); + + $processed_records = $end - $start + 1; + $resume_data['current'] = $start - 1; + + if ($start === 1) + { + $resume_data['reparser']++; + } + } + + if ($resume_data['reparser'] === $fast_reparsers_size) + { + return true; + } + + return $resume_data; + } +} -- cgit v1.2.1 From 25e2b17837f5b1c2330d07a86f88b25bb55d96c1 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Mon, 26 Oct 2015 01:39:52 +0100 Subject: [ticket/14257] Add text_reparser manager PHPBB3-14257 --- phpBB/phpbb/console/command/reparser/reparse.php | 54 ++------- phpBB/phpbb/cron/task/text_reparser/reparser.php | 83 +++++-------- .../phpbb/db/migration/data/v320/reparse_fast.php | 87 -------------- .../phpbb/db/migration/data/v320/text_reparser.php | 101 ++++++++++++++++ phpBB/phpbb/textreparser/manager.php | 128 +++++++++++++++++++++ 5 files changed, 266 insertions(+), 187 deletions(-) delete mode 100644 phpBB/phpbb/db/migration/data/v320/reparse_fast.php create mode 100644 phpBB/phpbb/db/migration/data/v320/text_reparser.php create mode 100644 phpBB/phpbb/textreparser/manager.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/reparser/reparse.php b/phpBB/phpbb/console/command/reparser/reparse.php index 6fac3db854..575e447a78 100644 --- a/phpBB/phpbb/console/command/reparser/reparse.php +++ b/phpBB/phpbb/console/command/reparser/reparse.php @@ -22,11 +22,6 @@ use Symfony\Component\Console\Style\SymfonyStyle; class reparse extends \phpbb\console\command\command { - /** - * @var \phpbb\config\db_text - */ - protected $config_text; - /** * @var InputInterface */ @@ -47,6 +42,11 @@ class reparse extends \phpbb\console\command\command */ protected $reparse_lock; + /** + * @var \phpbb\textreparser\manager + */ + protected $reparser_manager; + /** * @var \phpbb\di\service_collection */ @@ -65,13 +65,13 @@ class reparse extends \phpbb\console\command\command * @param \phpbb\config\db_text $config_text * @param \phpbb\lock\db $reparse_lock */ - public function __construct(\phpbb\user $user, \phpbb\di\service_collection $reparsers, \phpbb\config\db_text $config_text, \phpbb\lock\db $reparse_lock) + public function __construct(\phpbb\user $user, \phpbb\lock\db $reparse_lock, \phpbb\textreparser\manager $reparser_manager, \phpbb\di\service_collection $reparsers) { require_once __DIR__ . '/../../../../includes/functions_content.php'; - $this->config_text = $config_text; - $this->reparsers = $reparsers; $this->reparse_lock = $reparse_lock; + $this->reparser_manager = $reparser_manager; + $this->reparsers = $reparsers; parent::__construct($user); } @@ -177,8 +177,6 @@ class reparse extends \phpbb\console\command\command throw new runtime_exception('REPARSE_LOCK_ERROR', array(), null, 1); } - $this->load_resume_data(); - $name = $input->getArgument('reparser-name'); if (isset($name)) { @@ -233,15 +231,6 @@ class reparse extends \phpbb\console\command\command return $value; } - /** - * Load the resume data from the database - */ - protected function load_resume_data() - { - $resume_data = $this->config_text->get('reparser_resume'); - $this->resume_data = (empty($resume_data)) ? array() : unserialize($resume_data); - } - /** * Reparse all text handled by given reparser within given range * @@ -250,6 +239,7 @@ class reparse extends \phpbb\console\command\command protected function reparse($name) { $reparser = $this->reparsers[$name]; + $this->resume_data = $this->reparser_manager->get_resume_data($name); if ($this->input->getOption('dry-run')) { $reparser->disable_save(); @@ -288,34 +278,10 @@ class reparse extends \phpbb\console\command\command $current = $start - 1; $progress->setProgress($max + 1 - $start); - $this->update_resume_data($name, $current); + $this->reparser_manager->update_resume_data($name, $min, $current, $size, !$this->input->getOption('dry-run')); } $progress->finish(); $this->io->newLine(2); } - - /** - * Save the resume data to the database - */ - protected function save_resume_data() - { - $this->config_text->set('reparser_resume', serialize($this->resume_data)); - } - - /** - * Save the resume data to the database - * - * @param string $name Reparser name - * @param string $current Current ID - */ - protected function update_resume_data($name, $current) - { - $this->resume_data[$name] = array( - 'range-min' => $this->get_option($name, 'range-min'), - 'range-max' => $current, - 'range-size' => $this->get_option($name, 'range-size'), - ); - $this->save_resume_data(); - } } diff --git a/phpBB/phpbb/cron/task/text_reparser/reparser.php b/phpBB/phpbb/cron/task/text_reparser/reparser.php index a8faca3d06..9ce886a6d9 100644 --- a/phpBB/phpbb/cron/task/text_reparser/reparser.php +++ b/phpBB/phpbb/cron/task/text_reparser/reparser.php @@ -37,15 +37,20 @@ class reparser extends \phpbb\cron\task\base protected $reparse_lock; /** - * @var \phpbb\di\service_collection + * @var \phpbb\textreparser\manager */ - protected $reparsers; + protected $reparser_manager; /** * @var string */ protected $reparser_name; + /** + * @var \phpbb\di\service_collection + */ + protected $reparsers; + /** * @var array */ @@ -57,13 +62,15 @@ class reparser extends \phpbb\cron\task\base * @param \phpbb\config\config $config * @param \phpbb\config\db_text $config_text * @param \phpbb\lock\db $reparse_lock + * @param \phpbb\textreparser\manager $reparser_manager * @param \phpbb\di\service_collection $reparsers */ - public function __construct(\phpbb\config\config $config, \phpbb\config\db_text $config_text, \phpbb\lock\db $reparse_lock, \phpbb\di\service_collection $reparsers) + public function __construct(\phpbb\config\config $config, \phpbb\config\db_text $config_text, \phpbb\lock\db $reparse_lock, \phpbb\textreparser\manager $reparser_manager, \phpbb\di\service_collection $reparsers) { $this->config = $config; $this->config_text = $config_text; $this->reparse_lock = $reparse_lock; + $this->reparser_manager = $reparser_manager; $this->reparsers = $reparsers; } @@ -74,18 +81,11 @@ class reparser extends \phpbb\cron\task\base */ public function set_reparser($reparser) { - if (isset($this->reparsers[$reparser])) - { - $this->reparser_name = preg_replace('(^text_reparser\\.)', '', $reparser); - } - else if (isset($this->reparsers['text_reparser.' . $reparser])) - { - $this->reparser_name = $reparser; - } + $this->reparser_name = (!isset($this->reparsers[$reparser]) ? 'text_reparser.' : '') . $reparser; if ($this->resume_data === null) { - $this->load_resume_data(); + $this->reparser_manager->get_resume_data($this->reparser_name); } } @@ -96,10 +96,10 @@ class reparser extends \phpbb\cron\task\base { if ($this->resume_data === null) { - $this->load_resume_data(); + $this->reparser_manager->get_resume_data($this->reparser_name); } - if (empty($this->resume_data[$this->reparser_name]['range-max']) || $this->resume_data[$this->reparser_name]['range-max'] >= $this->resume_data[$this->reparser_name]['range-min']) + if (empty($this->resume_data['range-max']) || $this->resume_data['range-max'] >= $this->resume_data['range-min']) { return true; } @@ -122,7 +122,12 @@ class reparser extends \phpbb\cron\task\base } } - return true; + if ($this->config[$this->reparser_name . '_cron_interval'] != -1) + { + return $this->config[$this->reparser_name . '_last_cron'] < time() - $this->config[$this->reparser_name . '_cron_interval']; + } + + return false; } /** @@ -134,17 +139,17 @@ class reparser extends \phpbb\cron\task\base { if ($this->resume_data === null) { - $this->load_resume_data(); + $this->resume_data = $this->reparser_manager->get_resume_data($this->reparser_name); } /** * @var \phpbb\textreparser\reparser_interface $reparser */ - $reparser = isset($this->reparsers[$this->reparser_name]) ? $this->reparsers[$this->reparser_name] : $this->reparsers['text_reparser.' . $this->reparser_name]; + $reparser = $this->reparsers[$this->reparser_name]; - $min = !empty($this->resume_data[$this->reparser_name]['range-min']) ? $this->resume_data[$this->reparser_name]['range-min'] : self::MIN; - $current = !empty($this->resume_data[$this->reparser_name]['range-max']) ? $this->resume_data[$this->reparser_name]['range-max'] : $reparser->get_max_id(); - $size = !empty($this->resume_data[$this->reparser_name]['range-size']) ? $this->resume_data[$this->reparser_name]['range-size'] : self::SIZE; + $min = !empty($this->resume_data['range-min']) ? $this->resume_data['range-min'] : self::MIN; + $current = !empty($this->resume_data['range-max']) ? $this->resume_data['range-max'] : $reparser->get_max_id(); + $size = !empty($this->resume_data['range-size']) ? $this->resume_data['range-size'] : self::SIZE; if ($current >= $min) { @@ -153,45 +158,11 @@ class reparser extends \phpbb\cron\task\base $reparser->reparse_range($start, $end); - $this->update_resume_data($this->reparser_name, $min, $start - 1, $size); + $this->reparser_manager->update_resume_data($this->reparser_name, $min, $start - 1, $size); } + $this->config->set($this->reparser_name . '_last_cron', time()); $this->reparse_lock->release(); } } - - /** - * Load the resume data from the database - */ - protected function load_resume_data() - { - $resume_data = $this->config_text->get('reparser_resume'); - $this->resume_data = (empty($resume_data)) ? array() : unserialize($resume_data); - } - - /** - * Save the resume data to the database - */ - protected function save_resume_data() - { - $this->config_text->set('reparser_resume', serialize($this->resume_data)); - } - - /** - * Save the resume data to the database - * - * @param string $name Reparser name - * @param int $min Lowest record ID - * @param int $current Current ID - * @param int $size Number of records to process at a time - */ - protected function update_resume_data($name, $min, $current, $size) - { - $this->resume_data[$name] = array( - 'range-min' => $min, - 'range-max' => $current, - 'range-size' => $size, - ); - $this->save_resume_data(); - } } diff --git a/phpBB/phpbb/db/migration/data/v320/reparse_fast.php b/phpBB/phpbb/db/migration/data/v320/reparse_fast.php deleted file mode 100644 index ddb11f7f67..0000000000 --- a/phpBB/phpbb/db/migration/data/v320/reparse_fast.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -namespace phpbb\db\migration\data\v320; - -class reparse_fast extends \phpbb\db\migration\container_aware_migration -{ - static public function depends_on() - { - return array('\phpbb\db\migration\data\v310\contact_admin_form'); - } - - public function effectively_installed() - { - return isset($this->config['reparse_lock']); - } - - public function update_data() - { - return array( - array('config.add', array('reparse_lock', 0, true)), - array('custom', array(array($this, 'reparse'))), - ); - } - - public function reparse($resume_data) - { - // Somtimes a cron job is too much - $limit = 200; - $fast_reparsers = array( - 'text_reparser.contact_admin_info', - 'text_reparser.forum_description', - 'text_reparser.forum_rules', - 'text_reparser.group_description', - ); - - if (!is_array($resume_data)) - { - $resume_data = array( - 'reparser' => 0, - 'current' => $this->container->get($fast_reparsers[0])->get_max_id(), - ); - } - - $fast_reparsers_size = sizeof($fast_reparsers); - $processed_records = 0; - while ($processed_records < $limit && $resume_data['reparser'] < $fast_reparsers_size) - { - $reparser = $this->container->get($fast_reparsers[$resume_data['reparser']]); - - // New reparser - if ($resume_data['current'] === 0) - { - $resume_data['current'] = $reparser->get_max_id(); - } - - $start = max(1, $resume_data['current'] + 1 - ($limit - $processed_records)); - $end = max(1, $resume_data['current']); - $reparser->reparse_range($start, $end); - - $processed_records = $end - $start + 1; - $resume_data['current'] = $start - 1; - - if ($start === 1) - { - $resume_data['reparser']++; - } - } - - if ($resume_data['reparser'] === $fast_reparsers_size) - { - return true; - } - - return $resume_data; - } -} diff --git a/phpBB/phpbb/db/migration/data/v320/text_reparser.php b/phpBB/phpbb/db/migration/data/v320/text_reparser.php new file mode 100644 index 0000000000..0d8fd2ebb5 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/text_reparser.php @@ -0,0 +1,101 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v320; + +class text_reparser extends \phpbb\db\migration\container_aware_migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\contact_admin_form'); + } + + public function effectively_installed() + { + return isset($this->config['reparse_lock']); + } + + public function update_data() + { + return array( + array('config.add', array('reparse_lock', 0, true)), + array('config.add', array('text_reparser.pm_text_cron_interval', 0)), + array('config.add', array('text_reparser.pm_text_last_cron', 0)), + array('config.add', array('text_reparser.poll_option_cron_interval', 0)), + array('config.add', array('text_reparser.poll_option_last_cron', 0)), + array('config.add', array('text_reparser.poll_title_cron_interval', 0)), + array('config.add', array('text_reparser.poll_title_last_cron', 0)), + array('config.add', array('text_reparser.post_text_cron_interval', 0)), + array('config.add', array('text_reparser.post_text_last_cron', 0)), + array('config.add', array('text_reparser.user_signature_cron_interval', 0)), + array('config.add', array('text_reparser.user_signature_last_cron', 0)), + array('custom', array(array($this, 'reparse'))), + ); + } + + public function reparse($resume_data) + { + // Somtimes a cron job is too much + $limit = 100; + $fast_reparsers = array( + 'text_reparser.contact_admin_info', + 'text_reparser.forum_description', + 'text_reparser.forum_rules', + 'text_reparser.group_description', + ); + + if (!is_array($resume_data)) + { + $resume_data = array( + 'reparser' => 0, + 'current' => $this->container->get($fast_reparsers[0])->get_max_id(), + ); + } + + $fast_reparsers_size = sizeof($fast_reparsers); + $processed_records = 0; + while ($processed_records < $limit && $resume_data['reparser'] < $fast_reparsers_size) + { + $reparser = $this->container->get($fast_reparsers[$resume_data['reparser']]); + + // New reparser + if ($resume_data['current'] === 0) + { + $resume_data['current'] = $reparser->get_max_id(); + } + + $start = max(1, $resume_data['current'] + 1 - ($limit - $processed_records)); + $end = max(1, $resume_data['current']); + $reparser->reparse_range($start, $end); + + $processed_records = $end - $start + 1; + $resume_data['current'] = $start - 1; + + if ($start === 1) + { + // Prevent CLI command from running these reparsers again + $reparser_manager = $this->container->get('text_reparser.manager'); + $reparser_manager->update_resume_data($fast_reparsers[$resume_data['reparser']], 1, 0, $limit); + + $resume_data['reparser']++; + } + } + + if ($resume_data['reparser'] === $fast_reparsers_size) + { + return true; + } + + return $resume_data; + } +} diff --git a/phpBB/phpbb/textreparser/manager.php b/phpBB/phpbb/textreparser/manager.php new file mode 100644 index 0000000000..8e997f60ef --- /dev/null +++ b/phpBB/phpbb/textreparser/manager.php @@ -0,0 +1,128 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\textreparser; + +class manager +{ + /** + * @var \phpbb\config\config + */ + protected $config; + + /** + * @var \phpbb\config\db_text + */ + protected $config_text; + + /** + * @var \phpbb\di\service_collection + */ + protected $reparsers; + + /** + * @var array + */ + protected $resume_data; + + /** + * Constructor + * + * @param \phpbb\config\config $config + * @param \phpbb\config\db_text $config_text + * @param \phpbb\di\service_collection $reparsers + */ + public function __construct(\phpbb\config\config $config, \phpbb\config\db_text $config_text, \phpbb\di\service_collection $reparsers) + { + $this->config = $config; + $this->config_text = $config_text; + $this->reparsers = $reparsers; + } + + /** + * Loads resume data from the database + * + * @param string $name Name of the reparser to which the resume data belongs + * + * @return array + */ + public function get_resume_data($name) + { + if ($this->resume_data === null) + { + $resume_data = $this->config_text->get('reparser_resume'); + $this->resume_data = !empty($resume_data) ? unserialize($resume_data) : array(); + } + + return isset($this->resume_data[$name]) ? $this->resume_data[$name] : array(); + } + + /** + * Updates the resume data in the database + * + * @param string $name Name of the reparser to which the resume data belongs + * @param int $min Lowest record ID + * @param int $current Current record ID + * @param int $size Number of records to process at a time + * @param bool $update_db True if the resume data should be written to the database, false if not. (default: true) + */ + public function update_resume_data($name, $min, $current, $size, $update_db = true) + { + // Prevent overwriting the old, stored array + if ($this->resume_data === null) + { + $this->get_resume_data(''); + } + + $this->resume_data[$name] = array( + 'range-min' => $min, + 'range-max' => $current, + 'range-size' => $size, + ); + + if ($update_db) + { + $this->config_text->set('reparser_resume', serialize($this->resume_data)); + } + } + + /** + * Sets the interval for a text_reparser cron task + * + * @param string $name Name of the reparser to schedule + * @param int $interval Interval in seconds, -1 to disable the cron task + */ + public function schedule($name, $interval) + { + if (isset($this->reparsers[$name]) && isset($this->config[$name . '_cron_interval'])) + { + $this->config->set($name . '_cron_interval', $interval); + } + } + + /** + * Sets the interval for all text_reparser cron tasks + * + * @param int $interval Interval in seconds, -1 to disable the cron task + */ + public function schedule_all($interval) + { + // This way we don't construct every registered reparser + $reparser_array = array_keys($this->reparsers->getArrayCopy()); + + foreach ($reparser_array as $reparser) + { + $this->schedule($reparser, $interval); + } + } +} -- cgit v1.2.1 From c805fd2a7378bc431ff11f93efd74fb829f558d9 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Mon, 26 Oct 2015 01:49:11 +0100 Subject: [ticket/14257] Fix phpdoc in CLI command PHPBB3-14257 --- phpBB/phpbb/console/command/reparser/reparse.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/reparser/reparse.php b/phpBB/phpbb/console/command/reparser/reparse.php index 575e447a78..6137a79b89 100644 --- a/phpBB/phpbb/console/command/reparser/reparse.php +++ b/phpBB/phpbb/console/command/reparser/reparse.php @@ -61,9 +61,9 @@ class reparse extends \phpbb\console\command\command * Constructor * * @param \phpbb\user $user - * @param \phpbb\di\service_collection $reparsers - * @param \phpbb\config\db_text $config_text * @param \phpbb\lock\db $reparse_lock + * @param \phpbb\textreparser\manager $reparser_manager + * @param \phpbb\di\service_collection $reparsers */ public function __construct(\phpbb\user $user, \phpbb\lock\db $reparse_lock, \phpbb\textreparser\manager $reparser_manager, \phpbb\di\service_collection $reparsers) { -- cgit v1.2.1 From 369024b56fd96a9ca7174f36a706d9dce478ac3b Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Wed, 28 Oct 2015 00:58:34 +0100 Subject: [ticket/14044] Try to fix missing table prefix PHPBB3-14044 --- phpBB/phpbb/install/module/update_database/task/update.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index 2d640134a3..015935e1de 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -98,6 +98,10 @@ class update extends task_base $this->language = $language; $this->phpbb_root_path = $phpbb_root_path; + // BC global for migrations + global $table_prefix; + $table_prefix = $container->get_parameter('table_prefix'); + $this->cache = $container->get('cache.driver'); $this->config = $container->get('config'); $this->extension_manager = $container->get('ext.manager'); -- cgit v1.2.1 From 33db26d0cf3161edb7c840c499c94f5b8f14a4e9 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Wed, 28 Oct 2015 01:12:52 +0100 Subject: [ticket/14044] global $table_prefix in constants.php PHPBB3-14044 --- phpBB/phpbb/install/module/update_database/task/update.php | 4 ---- 1 file changed, 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index 015935e1de..2d640134a3 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -98,10 +98,6 @@ class update extends task_base $this->language = $language; $this->phpbb_root_path = $phpbb_root_path; - // BC global for migrations - global $table_prefix; - $table_prefix = $container->get_parameter('table_prefix'); - $this->cache = $container->get('cache.driver'); $this->config = $container->get('config'); $this->extension_manager = $container->get('ext.manager'); -- cgit v1.2.1 From 3ac10ef5443a1bbc8aa2f13b7fb98f33ca2ff702 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Wed, 28 Oct 2015 14:14:49 +0100 Subject: [ticket/14044] Solve missing email template error PHPBB3-14044 --- phpBB/phpbb/install/module/install_finish/task/notify_user.php | 8 +++++++- phpBB/phpbb/language/language.php | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/notify_user.php b/phpBB/phpbb/install/module/install_finish/task/notify_user.php index 83c03ce367..1cbc27ab6a 100644 --- a/phpBB/phpbb/install/module/install_finish/task/notify_user.php +++ b/phpBB/phpbb/install/module/install_finish/task/notify_user.php @@ -40,6 +40,11 @@ class notify_user extends \phpbb\install\task_base */ protected $config; + /** + * @var \phpbb\language\language + */ + protected $language; + /** * @var \phpbb\log\log_interface */ @@ -75,6 +80,7 @@ class notify_user extends \phpbb\install\task_base $this->iohandler = $iohandler; $this->auth = $container->get('auth'); + $this->language = $container->get('language'); $this->log = $container->get('log'); $this->user = $container->get('user'); $this->phpbb_root_path = $phpbb_root_path; @@ -103,7 +109,7 @@ class notify_user extends \phpbb\install\task_base include ($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext); $messenger = new \messenger(false); - $messenger->template('installed', $this->install_config->get('language')); + $messenger->template('installed', $this->language->get_used_language()); $messenger->to($this->config['board_email'], $this->install_config->get('admin_name')); $messenger->anti_abuse_headers($this->config, $this->user); $messenger->assign_vars(array( diff --git a/phpBB/phpbb/language/language.php b/phpBB/phpbb/language/language.php index 47f055f56a..c4e48a4c0d 100644 --- a/phpBB/phpbb/language/language.php +++ b/phpBB/phpbb/language/language.php @@ -548,6 +548,16 @@ class language } } + /** + * Returns the ISO code of the used language + * + * @return string The ISO code of the currently used language + */ + public function get_used_language() + { + return $this->language_fallback[0]; + } + /** * Returns language fallback data * -- cgit v1.2.1 From 71ec5185e16c389d6d25b9999e73a4e6298cd721 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Wed, 28 Oct 2015 14:17:29 +0100 Subject: [ticket/14044] Fix wrong descriptions in install PHPBB3-14044 --- phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php index ae7526a9e3..b04b8e353f 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php @@ -116,12 +116,12 @@ class obtain_email_data extends \phpbb\install\task_base implements \phpbb\insta ), 'smtp_host' => array( 'label' => 'SMTP_SERVER', - 'description' => 'SMTP_SERVER_EXPLAIN', 'type' => 'text', 'default' => $smtp_host, ), 'smtp_auth' => array( 'label' => 'SMTP_AUTH_METHOD', + 'description' => 'SMTP_AUTH_METHOD_EXPLAIN', 'type' => 'select', 'options' => $auth_options, ), -- cgit v1.2.1 From 0990894cf87598f36bbc8c8bfbaa783267e17d51 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Fri, 30 Oct 2015 15:25:27 +0100 Subject: [ticket/14044] Patch language::set_fallback_array() PHPBB3-14044 --- phpBB/phpbb/language/language.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/language/language.php b/phpBB/phpbb/language/language.php index c4e48a4c0d..382d4db89e 100644 --- a/phpBB/phpbb/language/language.php +++ b/phpBB/phpbb/language/language.php @@ -569,12 +569,12 @@ class language { $fallback_array = array(); - if ($this->user_language !== false) + if ($this->user_language) { $fallback_array[] = $this->user_language; } - if ($this->default_language !== false) + if ($this->default_language) { $fallback_array[] = $this->default_language; } -- cgit v1.2.1 From 719f42c54a45ab669a983964c1e8a6f75a4d4b02 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Fri, 30 Oct 2015 15:46:39 +0100 Subject: [ticket/14044] Fix language selection data loss PHPBB3-14044 --- phpBB/phpbb/install/controller/helper.php | 1 + .../install/module/install_database/task/add_config_settings.php | 2 +- phpBB/phpbb/install/module/install_finish/task/notify_user.php | 4 +++- phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/helper.php b/phpBB/phpbb/install/controller/helper.php index bfa9ec6238..fdb07d9c4a 100644 --- a/phpBB/phpbb/install/controller/helper.php +++ b/phpBB/phpbb/install/controller/helper.php @@ -204,6 +204,7 @@ class helper if ($lang !== null) { $this->language->set_user_language($lang, true); + $this->installer_config->set('user_language', $lang); } } diff --git a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php index 25da36e01d..6fb03ff73d 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php +++ b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php @@ -233,7 +233,7 @@ class add_config_settings extends \phpbb\install\task_base SET username = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "', user_password='" . $this->password_manager->hash($this->install_config->get('admin_passwd')) . "', user_ip = '" . $this->db->sql_escape($user_ip) . "', - user_lang = '" . $this->db->sql_escape($this->install_config->get('language')) . "', + user_lang = '" . $this->db->sql_escape($this->install_config->get('user_language', 'en')) . "', user_email='" . $this->db->sql_escape($this->install_config->get('board_email')) . "', user_dateformat='" . $this->db->sql_escape($this->language->lang('default_dateformat')) . "', user_email_hash = " . $this->db->sql_escape(phpbb_email_hash($this->install_config->get('board_email'))) . ", diff --git a/phpBB/phpbb/install/module/install_finish/task/notify_user.php b/phpBB/phpbb/install/module/install_finish/task/notify_user.php index 1cbc27ab6a..2a8ee0f12e 100644 --- a/phpBB/phpbb/install/module/install_finish/task/notify_user.php +++ b/phpBB/phpbb/install/module/install_finish/task/notify_user.php @@ -104,12 +104,14 @@ class notify_user extends \phpbb\install\task_base $this->user->session_begin(); $this->user->setup('common'); + $this->language->set_default_language($this->config['default_lang']); + if ($this->config['email_enable']) { include ($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext); $messenger = new \messenger(false); - $messenger->template('installed', $this->language->get_used_language()); + $messenger->template('installed', $this->install_config->get('user_language', 'en')); $messenger->to($this->config['board_email'], $this->install_config->get('admin_name')); $messenger->anti_abuse_headers($this->config, $this->user); $messenger->assign_vars(array( diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php index 0726cc449c..4e977981ce 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php @@ -126,7 +126,7 @@ class obtain_board_data extends \phpbb\install\task_base implements \phpbb\insta } // Use language because we only check this to be valid - $default_lang = $this->install_config->get('language', ''); + $default_lang = $this->install_config->get('user_language', 'en'); $langs = $this->language_helper->get_available_languages(); $lang_options = array(); -- cgit v1.2.1 From f991e484da91e24f82fbcb05d0b2ae11ca51852b Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Tue, 3 Nov 2015 02:16:23 +0100 Subject: [ticket/14044] Add config as global in notify user PHPBB3-14044 --- phpBB/phpbb/install/module/install_finish/task/notify_user.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/notify_user.php b/phpBB/phpbb/install/module/install_finish/task/notify_user.php index 2a8ee0f12e..5268b85a42 100644 --- a/phpBB/phpbb/install/module/install_finish/task/notify_user.php +++ b/phpBB/phpbb/install/module/install_finish/task/notify_user.php @@ -104,12 +104,15 @@ class notify_user extends \phpbb\install\task_base $this->user->session_begin(); $this->user->setup('common'); - $this->language->set_default_language($this->config['default_lang']); - if ($this->config['email_enable']) { include ($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext); + // functions_messenger.php uses config to determine language paths + // Remove when able + global $config; + $config = $this->config; + $messenger = new \messenger(false); $messenger->template('installed', $this->install_config->get('user_language', 'en')); $messenger->to($this->config['board_email'], $this->install_config->get('admin_name')); -- cgit v1.2.1 From 2016550a32168ee5fcf11bfdd367ce48fbcf88b1 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Thu, 29 Oct 2015 01:48:52 +0100 Subject: [ticket/14264] Don't use constants as return values This will prevent BC breaking in the future if we decide to get rid of constants. PHPBB3-14264 --- .../textreparser/plugins/forum_description.php | 8 -------- phpBB/phpbb/textreparser/plugins/forum_rules.php | 8 -------- .../textreparser/plugins/group_description.php | 8 -------- phpBB/phpbb/textreparser/plugins/pm_text.php | 8 -------- phpBB/phpbb/textreparser/plugins/poll_title.php | 8 -------- phpBB/phpbb/textreparser/plugins/post_text.php | 8 -------- .../phpbb/textreparser/plugins/user_signature.php | 8 -------- phpBB/phpbb/textreparser/row_based_plugin.php | 22 +++++++++++----------- 8 files changed, 11 insertions(+), 67 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/plugins/forum_description.php b/phpBB/phpbb/textreparser/plugins/forum_description.php index 0302dc3082..b0f5a42452 100644 --- a/phpBB/phpbb/textreparser/plugins/forum_description.php +++ b/phpBB/phpbb/textreparser/plugins/forum_description.php @@ -27,12 +27,4 @@ class forum_description extends \phpbb\textreparser\row_based_plugin 'options' => 'forum_desc_options', ); } - - /** - * {@inheritdoc} - */ - public function get_table_name() - { - return FORUMS_TABLE; - } } diff --git a/phpBB/phpbb/textreparser/plugins/forum_rules.php b/phpBB/phpbb/textreparser/plugins/forum_rules.php index ce550225f2..d131d00707 100644 --- a/phpBB/phpbb/textreparser/plugins/forum_rules.php +++ b/phpBB/phpbb/textreparser/plugins/forum_rules.php @@ -27,12 +27,4 @@ class forum_rules extends \phpbb\textreparser\row_based_plugin 'options' => 'forum_rules_options', ); } - - /** - * {@inheritdoc} - */ - public function get_table_name() - { - return FORUMS_TABLE; - } } diff --git a/phpBB/phpbb/textreparser/plugins/group_description.php b/phpBB/phpbb/textreparser/plugins/group_description.php index 3346ccf25e..2c45c00474 100644 --- a/phpBB/phpbb/textreparser/plugins/group_description.php +++ b/phpBB/phpbb/textreparser/plugins/group_description.php @@ -27,12 +27,4 @@ class group_description extends \phpbb\textreparser\row_based_plugin 'options' => 'group_desc_options', ); } - - /** - * {@inheritdoc} - */ - public function get_table_name() - { - return GROUPS_TABLE; - } } diff --git a/phpBB/phpbb/textreparser/plugins/pm_text.php b/phpBB/phpbb/textreparser/plugins/pm_text.php index 4d06a2878b..867da624ee 100644 --- a/phpBB/phpbb/textreparser/plugins/pm_text.php +++ b/phpBB/phpbb/textreparser/plugins/pm_text.php @@ -29,12 +29,4 @@ class pm_text extends \phpbb\textreparser\row_based_plugin 'bbcode_uid' => 'bbcode_uid', ); } - - /** - * {@inheritdoc} - */ - public function get_table_name() - { - return PRIVMSGS_TABLE; - } } diff --git a/phpBB/phpbb/textreparser/plugins/poll_title.php b/phpBB/phpbb/textreparser/plugins/poll_title.php index 038ae0c366..76d30655c9 100644 --- a/phpBB/phpbb/textreparser/plugins/poll_title.php +++ b/phpBB/phpbb/textreparser/plugins/poll_title.php @@ -39,12 +39,4 @@ class poll_title extends \phpbb\textreparser\row_based_plugin return $sql; } - - /** - * {@inheritdoc} - */ - public function get_table_name() - { - return TOPICS_TABLE; - } } diff --git a/phpBB/phpbb/textreparser/plugins/post_text.php b/phpBB/phpbb/textreparser/plugins/post_text.php index 4a07c98cea..1c98e86067 100644 --- a/phpBB/phpbb/textreparser/plugins/post_text.php +++ b/phpBB/phpbb/textreparser/plugins/post_text.php @@ -29,12 +29,4 @@ class post_text extends \phpbb\textreparser\row_based_plugin 'bbcode_uid' => 'bbcode_uid', ); } - - /** - * {@inheritdoc} - */ - public function get_table_name() - { - return POSTS_TABLE; - } } diff --git a/phpBB/phpbb/textreparser/plugins/user_signature.php b/phpBB/phpbb/textreparser/plugins/user_signature.php index f657a45d38..647d3a7b14 100644 --- a/phpBB/phpbb/textreparser/plugins/user_signature.php +++ b/phpBB/phpbb/textreparser/plugins/user_signature.php @@ -54,14 +54,6 @@ class user_signature extends \phpbb\textreparser\row_based_plugin ); } - /** - * {@inheritdoc} - */ - public function get_table_name() - { - return USERS_TABLE; - } - /** * Save the keyoptions var from \phpbb\user */ diff --git a/phpBB/phpbb/textreparser/row_based_plugin.php b/phpBB/phpbb/textreparser/row_based_plugin.php index d3ca334591..2d32104493 100644 --- a/phpBB/phpbb/textreparser/row_based_plugin.php +++ b/phpBB/phpbb/textreparser/row_based_plugin.php @@ -20,14 +20,21 @@ abstract class row_based_plugin extends base */ protected $db; + /** + * @var string + */ + protected $table; + /** * Constructor * * @param \phpbb\db\driver\driver_interface $db Database connection + * @param string $table */ - public function __construct(\phpbb\db\driver\driver_interface $db) + public function __construct(\phpbb\db\driver\driver_interface $db, $table) { $this->db = $db; + $this->table = $table; } /** @@ -37,13 +44,6 @@ abstract class row_based_plugin extends base */ abstract public function get_columns(); - /** - * Return the name of the table used by this plugin - * - * @return string - */ - abstract public function get_table_name(); - /** * {@inheritdoc} */ @@ -51,7 +51,7 @@ abstract class row_based_plugin extends base { $columns = $this->get_columns(); - $sql = 'SELECT MAX(' . $columns['id'] . ') AS max_id FROM ' . $this->get_table_name(); + $sql = 'SELECT MAX(' . $columns['id'] . ') AS max_id FROM ' . $this->table; $result = $this->db->sql_query($sql); $max_id = (int) $this->db->sql_fetchfield('max_id'); $this->db->sql_freeresult($result); @@ -96,7 +96,7 @@ abstract class row_based_plugin extends base } $sql = 'SELECT ' . implode(', ', $fields) . ' - FROM ' . $this->get_table_name() . ' + FROM ' . $this->table . ' WHERE ' . $columns['id'] . ' BETWEEN ' . $min_id . ' AND ' . $max_id; return $sql; @@ -109,7 +109,7 @@ abstract class row_based_plugin extends base { $columns = $this->get_columns(); - $sql = 'UPDATE ' . $this->get_table_name() . ' + $sql = 'UPDATE ' . $this->table . ' SET ' . $columns['text'] . " = '" . $this->db->sql_escape($record['text']) . "' WHERE " . $columns['id'] . ' = ' . $record['id']; $this->db->sql_query($sql); -- cgit v1.2.1 From a92083169a181a6524e383de657c78af1bff2887 Mon Sep 17 00:00:00 2001 From: Cesar G Date: Thu, 5 Nov 2015 13:52:04 -0800 Subject: [ticket/14273] Remove unused core.root_path dependency in files.upload service PHPBB3-14273 --- phpBB/phpbb/files/upload.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/upload.php b/phpBB/phpbb/files/upload.php index e011e714e5..a9bf74094d 100644 --- a/phpBB/phpbb/files/upload.php +++ b/phpBB/phpbb/files/upload.php @@ -65,9 +65,6 @@ class upload /** @var request_interface Request class */ protected $request; - /** @var string phpBB root path */ - protected $phpbb_root_path; - /** * Init file upload class. * @@ -76,16 +73,14 @@ class upload * @param language $language Language class * @param \bantu\IniGetWrapper\IniGetWrapper $php_ini ini_get() wrapper * @param request_interface $request Request class - * @param string $phpbb_root_path phpBB root path */ - public function __construct(filesystem_interface $filesystem, factory $factory, language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path) + public function __construct(filesystem_interface $filesystem, factory $factory, language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, request_interface $request) { $this->filesystem = $filesystem; $this->factory = $factory; $this->language = $language; $this->php_ini = $php_ini; $this->request = $request; - $this->phpbb_root_path = $phpbb_root_path; } /** -- cgit v1.2.1 From 50d102c9751bd156be2a9207862dda3e6680de8e Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 5 Nov 2015 16:32:19 -0800 Subject: [ticket/14274] Include user functions during installer PHPBB3-14274 --- phpBB/phpbb/install/module/install_data/task/add_bots.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_data/task/add_bots.php b/phpBB/phpbb/install/module/install_data/task/add_bots.php index b45d3808db..2ee641ff63 100644 --- a/phpBB/phpbb/install/module/install_data/task/add_bots.php +++ b/phpBB/phpbb/install/module/install_data/task/add_bots.php @@ -197,6 +197,11 @@ class add_bots extends \phpbb\install\task_base 'user_allow_pm' => 0, ); + if (!function_exists('user_add')) + { + include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); + } + $user_id = user_add($user_row); if (!$user_id) -- cgit v1.2.1 From 900ccd79af816d8d54e6974e9163d9999a823513 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sun, 1 Nov 2015 03:49:01 +0100 Subject: [ticket/14257] Fix CLI reparser and set cron interval PHPBB3-14257 --- phpBB/phpbb/console/command/reparser/reparse.php | 31 ++++++++++------------ phpBB/phpbb/cron/task/text_reparser/reparser.php | 2 +- .../phpbb/db/migration/data/v320/text_reparser.php | 10 +++---- phpBB/phpbb/textreparser/manager.php | 4 +-- 4 files changed, 22 insertions(+), 25 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/reparser/reparse.php b/phpBB/phpbb/console/command/reparser/reparse.php index 6137a79b89..ddc97a1d1d 100644 --- a/phpBB/phpbb/console/command/reparser/reparse.php +++ b/phpBB/phpbb/console/command/reparser/reparse.php @@ -53,7 +53,7 @@ class reparse extends \phpbb\console\command\command protected $reparsers; /** - * @var array Reparser names as keys, and their last $current ID as values + * @var array The reparser's last $current ID as values */ protected $resume_data; @@ -208,27 +208,18 @@ class reparse extends \phpbb\console\command\command * Will use the last saved value if --resume is set and the option was not specified * on the command line * - * @param string $reparser_name Reparser name * @param string $option_name Option name * @return integer */ - protected function get_option($reparser_name, $option_name) + protected function get_option($option_name) { // Return the option from the resume_data if applicable - if ($this->input->getOption('resume') && isset($this->resume_data[$reparser_name][$option_name]) && !$this->input->hasParameterOption('--' . $option_name)) + if ($this->input->getOption('resume') && isset($this->resume_data[$option_name]) && !$this->input->hasParameterOption('--' . $option_name)) { - return $this->resume_data[$reparser_name][$option_name]; + return $this->resume_data[$option_name]; } - $value = $this->input->getOption($option_name); - - // range-max has no default value, it must be computed for each reparser - if ($option_name === 'range-max' && $value === null) - { - $value = $this->reparsers[$reparser_name]->get_max_id(); - } - - return $value; + return $this->input->getOption($option_name); } /** @@ -250,9 +241,15 @@ class reparse extends \phpbb\console\command\command } // Start at range-max if specified or at the highest ID otherwise - $max = $this->get_option($name, 'range-max'); - $min = $this->get_option($name, 'range-min'); - $size = $this->get_option($name, 'range-size'); + $max = $this->get_option('range-max'); + $min = $this->get_option('range-min'); + $size = $this->get_option('range-size'); + + // range-max has no default value, it must be computed for each reparser + if ($max == null) + { + $max = $reparser->get_max_id(); + } if ($max < $min) { diff --git a/phpBB/phpbb/cron/task/text_reparser/reparser.php b/phpBB/phpbb/cron/task/text_reparser/reparser.php index 9ce886a6d9..aa644de827 100644 --- a/phpBB/phpbb/cron/task/text_reparser/reparser.php +++ b/phpBB/phpbb/cron/task/text_reparser/reparser.php @@ -122,7 +122,7 @@ class reparser extends \phpbb\cron\task\base } } - if ($this->config[$this->reparser_name . '_cron_interval'] != -1) + if ($this->config[$this->reparser_name . '_cron_interval']) { return $this->config[$this->reparser_name . '_last_cron'] < time() - $this->config[$this->reparser_name . '_cron_interval']; } diff --git a/phpBB/phpbb/db/migration/data/v320/text_reparser.php b/phpBB/phpbb/db/migration/data/v320/text_reparser.php index 0d8fd2ebb5..1d73b74a76 100644 --- a/phpBB/phpbb/db/migration/data/v320/text_reparser.php +++ b/phpBB/phpbb/db/migration/data/v320/text_reparser.php @@ -29,15 +29,15 @@ class text_reparser extends \phpbb\db\migration\container_aware_migration { return array( array('config.add', array('reparse_lock', 0, true)), - array('config.add', array('text_reparser.pm_text_cron_interval', 0)), + array('config.add', array('text_reparser.pm_text_cron_interval', 10)), array('config.add', array('text_reparser.pm_text_last_cron', 0)), - array('config.add', array('text_reparser.poll_option_cron_interval', 0)), + array('config.add', array('text_reparser.poll_option_cron_interval', 10)), array('config.add', array('text_reparser.poll_option_last_cron', 0)), - array('config.add', array('text_reparser.poll_title_cron_interval', 0)), + array('config.add', array('text_reparser.poll_title_cron_interval', 10)), array('config.add', array('text_reparser.poll_title_last_cron', 0)), - array('config.add', array('text_reparser.post_text_cron_interval', 0)), + array('config.add', array('text_reparser.post_text_cron_interval', 10)), array('config.add', array('text_reparser.post_text_last_cron', 0)), - array('config.add', array('text_reparser.user_signature_cron_interval', 0)), + array('config.add', array('text_reparser.user_signature_cron_interval', 10)), array('config.add', array('text_reparser.user_signature_last_cron', 0)), array('custom', array(array($this, 'reparse'))), ); diff --git a/phpBB/phpbb/textreparser/manager.php b/phpBB/phpbb/textreparser/manager.php index 8e997f60ef..fddd867923 100644 --- a/phpBB/phpbb/textreparser/manager.php +++ b/phpBB/phpbb/textreparser/manager.php @@ -100,7 +100,7 @@ class manager * Sets the interval for a text_reparser cron task * * @param string $name Name of the reparser to schedule - * @param int $interval Interval in seconds, -1 to disable the cron task + * @param int $interval Interval in seconds, 0 to disable the cron task */ public function schedule($name, $interval) { @@ -113,7 +113,7 @@ class manager /** * Sets the interval for all text_reparser cron tasks * - * @param int $interval Interval in seconds, -1 to disable the cron task + * @param int $interval Interval in seconds, 0 to disable the cron task */ public function schedule_all($interval) { -- cgit v1.2.1 From 8d178f15f06e0f6b5e64447dc07157a796645572 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Wed, 4 Nov 2015 17:25:38 +0100 Subject: [ticket/14270] Purge cache when the installer is finished PHPBB3-14270 --- phpBB/phpbb/install/installer.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index 77e0a896bc..a41b4cd6a6 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -13,6 +13,7 @@ namespace phpbb\install; +use phpbb\cache\driver\driver_interface; use phpbb\di\ordered_service_collection; use phpbb\install\exception\installer_config_not_writable_exception; use phpbb\install\exception\jump_to_restart_point_exception; @@ -25,6 +26,11 @@ use phpbb\path_helper; class installer { + /** + * @var driver_interface + */ + protected $cache; + /** * @var config */ @@ -55,11 +61,13 @@ class installer /** * Constructor * - * @param config $config Installer config handler - * @param path_helper $path_helper Path helper + * @param driver_interface $cache Cache service + * @param config $config Installer config handler + * @param path_helper $path_helper Path helper */ - public function __construct(config $config, path_helper $path_helper) + public function __construct(driver_interface $cache, config $config, path_helper $path_helper) { + $this->cache = $cache; $this->install_config = $config; $this->installer_modules = null; $this->web_root = $path_helper->get_web_root_path(); @@ -235,6 +243,7 @@ class installer if ($install_finished || $fail_cleanup) { $this->install_config->clean_up_config_file(); + $this->cache->purge(); } else { -- cgit v1.2.1 From e02432ec82a03539b94cad2814f2603d8bfe3a0b Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 8 Nov 2015 22:06:10 +0100 Subject: [ticket/14277] Fix undefined index error in migrations PHPBB3-14277 --- phpBB/phpbb/db/migration/tool/module.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 69ac71abb7..7110760868 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -262,7 +262,7 @@ class module implements \phpbb\db\migration\tool\tool_interface // Success $module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']); - $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_ADD', false, array($module_log_name)); + $phpbb_log->add('admin', ANONYMOUS, $user->ip, 'LOG_MODULE_ADD', false, array($module_log_name)); // Move the module if requested above/below an existing one if (isset($data['before']) && $data['before']) -- cgit v1.2.1 From d04c7687c05b0474d3b3d42da94bc1383026ca7f Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Mon, 9 Nov 2015 09:11:03 +0100 Subject: [ticket/14277] Use user_id if available PHPBB3-14277 --- phpBB/phpbb/db/migration/tool/module.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 7110760868..a5ed62fd65 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -262,7 +262,7 @@ class module implements \phpbb\db\migration\tool\tool_interface // Success $module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']); - $phpbb_log->add('admin', ANONYMOUS, $user->ip, 'LOG_MODULE_ADD', false, array($module_log_name)); + $phpbb_log->add('admin', (isset($user->data['user_id'])) ? $user->data['user_id'] : ANONYMOUS, $user->ip, 'LOG_MODULE_ADD', false, array($module_log_name)); // Move the module if requested above/below an existing one if (isset($data['before']) && $data['before']) -- cgit v1.2.1 From d77455309b0edbcc65e4a347dc777542b1189328 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 9 Nov 2015 15:27:10 +0100 Subject: [ticket/14278] Check if user_id is set and fall back to ANONYMOUS PHPBB3-14278 --- phpBB/phpbb/install/module/update_database/task/update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index 2d640134a3..84ec6f73f5 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -172,7 +172,7 @@ class update extends task_base { $this->log->add( 'admin', - $this->user->data['user_id'], + (isset($this->user->data['user_id'])) ? $this->user->data['user_id'] : ANONYMOUS, $this->user->ip, 'LOG_UPDATE_DATABASE', false, -- cgit v1.2.1 From 2144f35e9daf17d69f040082fd236c80bb71d04f Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 15 Oct 2015 10:57:46 +0200 Subject: [prep-release-3.2.0-a1] Add migration for 3.2.0-a1 --- .../migration/data/v320/allowed_schemes_links.php | 7 ++++ .../data/v320/announce_global_permission.php | 4 +- phpBB/phpbb/db/migration/data/v320/dev.php | 36 ++++++++++++++++++ .../db/migration/data/v320/font_awesome_update.php | 7 ++++ phpBB/phpbb/db/migration/data/v320/icons_alt.php | 4 +- phpBB/phpbb/db/migration/data/v320/log_post_id.php | 4 +- .../db/migration/data/v320/notifications_board.php | 4 +- .../migration/data/v320/remove_outdated_media.php | 7 ++++ .../data/v320/remove_profilefield_wlm.php | 4 +- phpBB/phpbb/db/migration/data/v320/v320a1.php | 44 ++++++++++++++++++++++ 10 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 phpBB/phpbb/db/migration/data/v320/dev.php create mode 100644 phpBB/phpbb/db/migration/data/v320/v320a1.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/allowed_schemes_links.php b/phpBB/phpbb/db/migration/data/v320/allowed_schemes_links.php index de127e3745..726822bc71 100644 --- a/phpBB/phpbb/db/migration/data/v320/allowed_schemes_links.php +++ b/phpBB/phpbb/db/migration/data/v320/allowed_schemes_links.php @@ -15,6 +15,13 @@ namespace phpbb\db\migration\data\v320; class allowed_schemes_links extends \phpbb\db\migration\migration { + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\dev', + ); + } + public function update_data() { return array( diff --git a/phpBB/phpbb/db/migration/data/v320/announce_global_permission.php b/phpBB/phpbb/db/migration/data/v320/announce_global_permission.php index fe30a1c1b8..7afecb884b 100644 --- a/phpBB/phpbb/db/migration/data/v320/announce_global_permission.php +++ b/phpBB/phpbb/db/migration/data/v320/announce_global_permission.php @@ -29,7 +29,9 @@ class announce_global_permission extends \phpbb\db\migration\migration static public function depends_on() { - return array('\phpbb\db\migration\data\v310\rc2'); + return array( + '\phpbb\db\migration\data\v320\dev', + ); } public function update_data() diff --git a/phpBB/phpbb/db/migration/data/v320/dev.php b/phpBB/phpbb/db/migration/data/v320/dev.php new file mode 100644 index 0000000000..ad2da3c1f4 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/dev.php @@ -0,0 +1,36 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class dev extends \phpbb\db\migration\container_aware_migration +{ + public function effectively_installed() + { + return version_compare($this->config['version'], '3.2.0-dev', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v316', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.0-dev')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v320/font_awesome_update.php b/phpBB/phpbb/db/migration/data/v320/font_awesome_update.php index 6ffaf18b4a..817b638037 100644 --- a/phpBB/phpbb/db/migration/data/v320/font_awesome_update.php +++ b/phpBB/phpbb/db/migration/data/v320/font_awesome_update.php @@ -15,6 +15,13 @@ namespace phpbb\db\migration\data\v320; class font_awesome_update extends \phpbb\db\migration\migration { + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\dev', + ); + } + public function effectively_installed() { return isset($this->config['load_font_awesome_url']); diff --git a/phpBB/phpbb/db/migration/data/v320/icons_alt.php b/phpBB/phpbb/db/migration/data/v320/icons_alt.php index 7071ae78db..80132e579e 100644 --- a/phpBB/phpbb/db/migration/data/v320/icons_alt.php +++ b/phpBB/phpbb/db/migration/data/v320/icons_alt.php @@ -17,7 +17,9 @@ class icons_alt extends \phpbb\db\migration\migration { static public function depends_on() { - return array('\phpbb\db\migration\data\v310\dev'); + return array( + '\phpbb\db\migration\data\v320\dev', + ); } public function update_schema() diff --git a/phpBB/phpbb/db/migration/data/v320/log_post_id.php b/phpBB/phpbb/db/migration/data/v320/log_post_id.php index 0f155d543c..ead53c8138 100644 --- a/phpBB/phpbb/db/migration/data/v320/log_post_id.php +++ b/phpBB/phpbb/db/migration/data/v320/log_post_id.php @@ -17,7 +17,9 @@ class log_post_id extends \phpbb\db\migration\migration { static public function depends_on() { - return array('\phpbb\db\migration\data\v310\dev'); + return array( + '\phpbb\db\migration\data\v320\dev', + ); } public function update_schema() diff --git a/phpBB/phpbb/db/migration/data/v320/notifications_board.php b/phpBB/phpbb/db/migration/data/v320/notifications_board.php index fd9f1a2ad6..8a76ebab58 100644 --- a/phpBB/phpbb/db/migration/data/v320/notifications_board.php +++ b/phpBB/phpbb/db/migration/data/v320/notifications_board.php @@ -17,7 +17,9 @@ class notifications_board extends \phpbb\db\migration\migration { static public function depends_on() { - return array('\phpbb\db\migration\data\v310\notifications'); + return array( + '\phpbb\db\migration\data\v320\dev', + ); } public function update_data() diff --git a/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php b/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php index 59208be4dc..c14d31f1c0 100644 --- a/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php +++ b/phpBB/phpbb/db/migration/data/v320/remove_outdated_media.php @@ -21,6 +21,13 @@ class remove_outdated_media extends \phpbb\db\migration\migration ATTACHMENT_CATEGORY_QUICKTIME, ); + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\dev', + ); + } + public function update_data() { return array( diff --git a/phpBB/phpbb/db/migration/data/v320/remove_profilefield_wlm.php b/phpBB/phpbb/db/migration/data/v320/remove_profilefield_wlm.php index 2898c708f8..1cb9070bf9 100644 --- a/phpBB/phpbb/db/migration/data/v320/remove_profilefield_wlm.php +++ b/phpBB/phpbb/db/migration/data/v320/remove_profilefield_wlm.php @@ -17,7 +17,9 @@ class remove_profilefield_wlm extends \phpbb\db\migration\migration { static public function depends_on() { - return array('\phpbb\db\migration\data\v310\profilefield_wlm'); + return array( + '\phpbb\db\migration\data\v320\dev', + ); } public function update_schema() diff --git a/phpBB/phpbb/db/migration/data/v320/v320a1.php b/phpBB/phpbb/db/migration/data/v320/v320a1.php new file mode 100644 index 0000000000..d7ecb36f90 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/v320a1.php @@ -0,0 +1,44 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class v320a1 extends \phpbb\db\migration\container_aware_migration +{ + public function effectively_installed() + { + return version_compare($this->config['version'], '3.2.0-a1', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\dev', + '\phpbb\db\migration\data\v320\allowed_schemes_links', + '\phpbb\db\migration\data\v320\announce_global_permission', + '\phpbb\db\migration\data\v320\remove_profilefield_wlm', + '\phpbb\db\migration\data\v320\font_awesome_update', + '\phpbb\db\migration\data\v320\icons_alt', + '\phpbb\db\migration\data\v320\log_post_id', + '\phpbb\db\migration\data\v320\remove_outdated_media', + '\phpbb\db\migration\data\v320\notifications_board', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.0-dev')), + ); + } +} -- cgit v1.2.1 From 079b3d074d905c1982ec22840caae808c3b588f3 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 10 Nov 2015 15:01:18 +0100 Subject: [ticket/14281] Fix installer CLI after recent changes PHPBB3-14281 --- phpBB/phpbb/install/console/command/install/config/show.php | 2 +- phpBB/phpbb/install/console/command/install/install.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/console/command/install/config/show.php b/phpBB/phpbb/install/console/command/install/config/show.php index 4155440fc3..587b5f4846 100644 --- a/phpBB/phpbb/install/console/command/install/config/show.php +++ b/phpBB/phpbb/install/console/command/install/config/show.php @@ -96,7 +96,7 @@ class show extends \phpbb\console\command\command if (!is_file($config_file)) { - $iohandler->add_error_message(array('MISSING_FILE', array($config_file))); + $iohandler->add_error_message('MISSING_FILE', array($config_file)); return; } diff --git a/phpBB/phpbb/install/console/command/install/install.php b/phpBB/phpbb/install/console/command/install/install.php index 81ad1039f6..d76182af92 100644 --- a/phpBB/phpbb/install/console/command/install/install.php +++ b/phpBB/phpbb/install/console/command/install/install.php @@ -116,7 +116,7 @@ class install extends \phpbb\console\command\command if (!is_file($config_file)) { - $iohandler->add_error_message(array('MISSING_FILE', array($config_file))); + $iohandler->add_error_message(array('MISSING_FILE', $config_file)); return 1; } @@ -127,7 +127,7 @@ class install extends \phpbb\console\command\command } catch (ParseException $e) { - $iohandler->add_error_message('INVALID_YAML_FILE'); + $iohandler->add_error_message(array('INVALID_YAML_FILE', $config_file)); return 1; } -- cgit v1.2.1 From a1abf8253f2328f0a5c7b8d7c5885c6cec93f547 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 10 Nov 2015 16:49:30 +0100 Subject: [ticket/14281] Correctly pass parameters to add_error_message PHPBB3-14281 --- phpBB/phpbb/install/console/command/install/config/show.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/console/command/install/config/show.php b/phpBB/phpbb/install/console/command/install/config/show.php index 587b5f4846..5d82d8d1ef 100644 --- a/phpBB/phpbb/install/console/command/install/config/show.php +++ b/phpBB/phpbb/install/console/command/install/config/show.php @@ -96,7 +96,7 @@ class show extends \phpbb\console\command\command if (!is_file($config_file)) { - $iohandler->add_error_message('MISSING_FILE', array($config_file)); + $iohandler->add_error_message(array('MISSING_FILE', $config_file)); return; } -- cgit v1.2.1 From bb260f02e0de549f0ac2327b1d7b4f4a236a9a2a Mon Sep 17 00:00:00 2001 From: brunoais Date: Sat, 24 Oct 2015 14:36:41 +0100 Subject: [feature/sql-bool-builder] Changing syntax Changing the syntax used to the one Nicofuma suggested. PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 7e2d7a5ea6..410dd17b32 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -812,16 +812,16 @@ abstract class driver implements driver_interface if ($operations_ary[0] !== 'AND' && $operations_ary[0] !== 'OR') { - $operations_ary = array('AND', $operations_ary); + $operations_ary = array('AND', array($operations_ary)); } return $this->_process_boolean_tree($operations_ary) . "\n"; } protected function _process_boolean_tree($operations_ary) { - $operation = array_shift($operations_ary); + $operation = $operations_ary[0]; - foreach ($operations_ary as &$condition) + foreach ($operations_ary[1] as &$condition) { switch ($condition[0]) { @@ -917,11 +917,11 @@ abstract class driver implements driver_interface if ($operation === 'NOT') { - $operations_ary = implode("", $operations_ary); + $operations_ary = implode("", $operations_ary[1]); } else { - $operations_ary = implode(" \n $operation ", $operations_ary); + $operations_ary = implode(" \n $operation ", $operations_ary[1]); } return $operations_ary; -- cgit v1.2.1 From 9725f5757e590ac6a2eecb5735f1d15bc5c4e8db Mon Sep 17 00:00:00 2001 From: brunoais Date: Wed, 11 Nov 2015 08:35:28 +0000 Subject: [feature/sql-bool-builder] Changing syntax pt3. Don't use magic numbers PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 410dd17b32..c7305e61a7 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -66,6 +66,15 @@ abstract class driver implements driver_interface */ var $sql_server_version = false; + const LOGICAL_OP = 0; + const STATEMENTS = 1; + const LEFT_STMT = 0; + const COMPARE_OP = 1; + const RIGHT_STMT = 2; + const SUBQUERY_OP = 3; + const SUBQUERY_SELECT_TYPE = 4; + const SUBQUERY_BUILD = 5; + /** * Constructor */ @@ -809,8 +818,8 @@ abstract class driver implements driver_interface { // In cases where an array exists but there is no head condition, // it should be because there's only 1 WHERE clause. This seems the best way to deal with it. - if ($operations_ary[0] !== 'AND' && - $operations_ary[0] !== 'OR') + if ($operations_ary[self::LOGICAL_OP] !== 'AND' && + $operations_ary[self::LOGICAL_OP] !== 'OR') { $operations_ary = array('AND', array($operations_ary)); } @@ -819,11 +828,11 @@ abstract class driver implements driver_interface protected function _process_boolean_tree($operations_ary) { - $operation = $operations_ary[0]; + $operation = $operations_ary[self::LOGICAL_OP]; foreach ($operations_ary[1] as &$condition) { - switch ($condition[0]) + switch ($condition[self::LOGICAL_OP]) { case 'AND': case 'OR': @@ -844,40 +853,40 @@ abstract class driver implements driver_interface case 3: // Typical 3 element clause with {left hand} {operator} {right hand} - switch ($condition[1]) + switch ($condition[self::COMPARE_OP]) { case 'IN': case 'NOT_IN': // As this is used with an IN, assume it is a set of elements for sql_in_set() - $condition = $this->sql_in_set($condition[0], $condition[2], $condition[1] === 'NOT_IN', true); + $condition = $this->sql_in_set($condition[self::LEFT_STMT], $condition[self::RIGHT_STMT], $condition[Cself::OMPARE_OP] === 'NOT_IN', true); break; case 'LIKE': - $condition = $condition[0] . ' ' . $this->sql_like_expression($condition[2]) . ' '; + $condition = $condition[self::LEFT_STMT] . ' ' . $this->sql_like_expression($condition[self::RIGHT_STMT]) . ' '; break; case 'NOT_LIKE': - $condition = $condition[0] . ' ' . $this->sql_not_like_expression($condition[2]) . ' '; + $condition = $condition[self::LEFT_STMT] . ' ' . $this->sql_not_like_expression($condition[self::RIGHT_STMT]) . ' '; break; case 'IS_NOT': - $condition[1] = 'IS NOT'; + $condition[self::COMPARE_OP] = 'IS NOT'; // no break case 'IS': // If the value is NULL, the string of it is the empty string ('') which is not the intended result. // this should solve that - if ($condition[2] === null) + if ($condition[self::RIGHT_STMT] === null) { - $condition[2] = 'NULL'; + $condition[self::RIGHT_STMT] = 'NULL'; } $condition = implode(' ', $condition); @@ -897,8 +906,8 @@ abstract class driver implements driver_interface // Subquery with {left hand} {operator} {compare kind} {SELECT Kind } {Sub Query} - $condition = $condition[0] . ' ' . $condition[1] . ' ' . $condition[2] . ' ( '; - $condition .= $this->sql_build_query($condition[3], $condition[4]); + $condition = $condition[self::LEFT_STMT] . ' ' . $condition[self::COMPARE_OP] . ' ' . $condition[self::SUBQUERY_OP] . ' ( '; + $condition .= $this->sql_build_query($condition[self::SUBQUERY_SELECT_TYPE], $condition[self::SUBQUERY_BUILD]); $condition .= ' )'; break; @@ -917,11 +926,11 @@ abstract class driver implements driver_interface if ($operation === 'NOT') { - $operations_ary = implode("", $operations_ary[1]); + $operations_ary = implode("", $operations_ary[self::STATEMENTS]); } else { - $operations_ary = implode(" \n $operation ", $operations_ary[1]); + $operations_ary = implode(" \n $operation ", $operations_ary[self::STATEMENTS]); } return $operations_ary; -- cgit v1.2.1 From 335be2e59fe9f5b63391a04ce7d79af56a4801a0 Mon Sep 17 00:00:00 2001 From: brunoais Date: Thu, 12 Nov 2015 06:52:34 +0000 Subject: [feature/sql-bool-builder] Fixing typos in previous commit PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index c7305e61a7..a65d8caa52 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -830,7 +830,7 @@ abstract class driver implements driver_interface { $operation = $operations_ary[self::LOGICAL_OP]; - foreach ($operations_ary[1] as &$condition) + foreach ($operations_ary[self::LOGICAL_OP] as &$condition) { switch ($condition[self::LOGICAL_OP]) { @@ -859,7 +859,7 @@ abstract class driver implements driver_interface case 'NOT_IN': // As this is used with an IN, assume it is a set of elements for sql_in_set() - $condition = $this->sql_in_set($condition[self::LEFT_STMT], $condition[self::RIGHT_STMT], $condition[Cself::OMPARE_OP] === 'NOT_IN', true); + $condition = $this->sql_in_set($condition[self::LEFT_STMT], $condition[self::RIGHT_STMT], $condition[self::COMPARE_OP] === 'NOT_IN', true); break; -- cgit v1.2.1 From a3a163dea1c3ba23a1d3a1c80c4c63c6831c37df Mon Sep 17 00:00:00 2001 From: brunoais Date: Tue, 24 Nov 2015 07:31:37 +0000 Subject: [feature/sql-bool-builder] Fixing misuse of LOGICAL_OP instead of STATEMENTS PHPBB3-13652 --- phpBB/phpbb/db/driver/driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index a65d8caa52..5f06cb08fc 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -830,7 +830,7 @@ abstract class driver implements driver_interface { $operation = $operations_ary[self::LOGICAL_OP]; - foreach ($operations_ary[self::LOGICAL_OP] as &$condition) + foreach ($operations_ary[self::STATEMENTS] as &$condition) { switch ($condition[self::LOGICAL_OP]) { -- cgit v1.2.1 From c3b9b3ab5bbe475ce7b5368a959786fc64122ad4 Mon Sep 17 00:00:00 2001 From: rxu Date: Tue, 24 Nov 2015 22:07:02 +0700 Subject: [ticket/14308] Fix multibyte input for installer PHPBB3-14308 --- phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php | 2 +- phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php index 41616e995a..ac305e8ab5 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php @@ -70,7 +70,7 @@ class obtain_admin_data extends \phpbb\install\task_base implements \phpbb\insta $admin_name = $this->io_handler->get_input('admin_name', '', true); $admin_pass1 = $this->io_handler->get_input('admin_pass1', '', true); $admin_pass2 = $this->io_handler->get_input('admin_pass2', '', true); - $board_email = $this->io_handler->get_input('board_email', ''); + $board_email = $this->io_handler->get_input('board_email', '', true); $admin_data_valid = $this->check_admin_data($admin_name, $admin_pass1, $admin_pass2, $board_email); diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php index 4e977981ce..6c54561d14 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php @@ -76,8 +76,8 @@ class obtain_board_data extends \phpbb\install\task_base implements \phpbb\insta { // Board data $default_lang = $this->io_handler->get_input('default_lang', ''); - $board_name = $this->io_handler->get_input('board_name', ''); - $board_desc = $this->io_handler->get_input('board_description', ''); + $board_name = $this->io_handler->get_input('board_name', '', true); + $board_desc = $this->io_handler->get_input('board_description', '', true); // Check default lang $langs = $this->language_helper->get_available_languages(); @@ -116,8 +116,8 @@ class obtain_board_data extends \phpbb\install\task_base implements \phpbb\insta { if ($use_request_data) { - $board_name = $this->io_handler->get_input('board_name', ''); - $board_desc = $this->io_handler->get_input('board_description', ''); + $board_name = $this->io_handler->get_input('board_name', '', true); + $board_desc = $this->io_handler->get_input('board_description', '', true); } else { -- cgit v1.2.1 From 93b37b24c2d546a2bc80830508d64338a24f9afa Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Wed, 4 Nov 2015 14:00:59 +0100 Subject: [ticket/14269] Use http_exceptions in the installer instead of die() PHPBB3-14269 --- phpBB/phpbb/install/controller/install.php | 5 +- phpBB/phpbb/install/controller/update.php | 7 +- .../install/event/kernel_exception_subscriber.php | 125 +++++++++++++++++++++ 3 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 phpBB/phpbb/install/event/kernel_exception_subscriber.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/install.php b/phpBB/phpbb/install/controller/install.php index 8d5ff95958..0fd4e8897c 100644 --- a/phpBB/phpbb/install/controller/install.php +++ b/phpBB/phpbb/install/controller/install.php @@ -13,6 +13,7 @@ namespace phpbb\install\controller; +use phpbb\exception\http_exception; use phpbb\install\helper\install_helper; use phpbb\install\helper\navigation\navigation_provider; use Symfony\Component\HttpFoundation\StreamedResponse; @@ -97,12 +98,14 @@ class install * Controller logic * * @return Response|StreamedResponse + * + * @throws http_exception When phpBB is already installed */ public function handle() { if ($this->install_helper->is_phpbb_installed()) { - die ('phpBB is already installed'); + throw new http_exception(404, 'INSTALL_PHPBB_IS_ALREADY_INSTALLED'); } $this->template->assign_vars(array( diff --git a/phpBB/phpbb/install/controller/update.php b/phpBB/phpbb/install/controller/update.php index 5212ba7f26..6a4341710a 100644 --- a/phpBB/phpbb/install/controller/update.php +++ b/phpBB/phpbb/install/controller/update.php @@ -13,6 +13,7 @@ namespace phpbb\install\controller; +use phpbb\exception\http_exception; use phpbb\install\helper\install_helper; use phpbb\install\helper\iohandler\factory; use phpbb\install\helper\navigation\navigation_provider; @@ -93,12 +94,16 @@ class update /** * Controller entry point + * + * @return Response|StreamedResponse + * + * @throws http_exception When phpBB is not installed */ public function handle() { if (!$this->install_helper->is_phpbb_installed()) { - die ('phpBB is not installed'); + throw new http_exception(404, 'INSTALL_PHPBB_IS_NOT_INSTALLED'); } $this->template->assign_vars(array( diff --git a/phpBB/phpbb/install/event/kernel_exception_subscriber.php b/phpBB/phpbb/install/event/kernel_exception_subscriber.php new file mode 100644 index 0000000000..2e6f9ca74d --- /dev/null +++ b/phpBB/phpbb/install/event/kernel_exception_subscriber.php @@ -0,0 +1,125 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\event; + +use phpbb\exception\exception_interface; +use phpbb\install\controller\helper; +use phpbb\language\language; +use phpbb\template\template; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; + +/** + * Exception handler for the installer + */ +class kernel_exception_subscriber implements EventSubscriberInterface +{ + /** + * @var helper + */ + protected $controller_helper; + + /** + * @var language + */ + protected $language; + + /** + * @var template + */ + protected $template; + + /** + * Constructor + * + * @param helper $controller_helper + * @param language $language + * @param template $template + */ + public function __construct(helper $controller_helper, language $language, template $template) + { + $this->controller_helper = $controller_helper; + $this->language = $language; + $this->template = $template; + } + + /** + * This listener is run when the KernelEvents::EXCEPTION event is triggered + * + * @param GetResponseForExceptionEvent $event + */ + public function on_kernel_exception(GetResponseForExceptionEvent $event) + { + $exception = $event->getException(); + $message = $exception->getMessage(); + + if ($exception instanceof exception_interface) + { + $message = $this->language->lang_array($message, $exception->get_parameters()); + } + + if (!$event->getRequest()->isXmlHttpRequest()) + { + $this->template->assign_vars(array( + 'TITLE' => $this->language->lang('INFORMATION'), + 'BODY' => $message, + )); + + $response = $this->controller_helper->render( + 'installer_main.html', + $this->language->lang('INFORMATION'), + false, + 500 + ); + } + else + { + $data = array(); + + if (!empty($message)) + { + $data['message'] = $message; + } + + if (defined('DEBUG')) + { + $data['trace'] = $exception->getTrace(); + } + + $response = new JsonResponse($data, 500); + } + + if ($exception instanceof HttpExceptionInterface) + { + $response->setStatusCode($exception->getStatusCode()); + $response->headers->add($exception->getHeaders()); + } + + $event->setResponse($response); + } + + /** + * Returns an array of the events the object is subscribed to + * + * @return array Array of the events the object is subscribed to + */ + static public function getSubscribedEvents() + { + return array( + KernelEvents::EXCEPTION => 'on_kernel_exception', + ); + } +} -- cgit v1.2.1 From 4aac878ec792cfbae01b708dd3d0336a75704405 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sun, 29 Nov 2015 15:49:18 +0100 Subject: [ticket/14320] Fix language selector in the installer PHPBB3-14320 --- phpBB/phpbb/install/controller/helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/helper.php b/phpBB/phpbb/install/controller/helper.php index fdb07d9c4a..ed817f7396 100644 --- a/phpBB/phpbb/install/controller/helper.php +++ b/phpBB/phpbb/install/controller/helper.php @@ -197,7 +197,7 @@ class helper $this->language_cookie = $lang; } - $lang = (!empty($lang) && strpos($lang, '/')) ? $lang : null; + $lang = (!empty($lang) && strpos($lang, '/') === false) ? $lang : null; $this->render_language_select($lang); -- cgit v1.2.1 From e95414ed541647d4a42b9349d1bb939725b57b0b Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Mon, 30 Nov 2015 23:17:00 +0100 Subject: [ticket/14326] Decode diffed file's content during update PHPBB3-14326 --- .../install/module/update_filesystem/task/show_file_status.php | 2 +- .../install/module/update_filesystem/task/update_files.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php index 1c6b9aa058..e712b8ad6a 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php @@ -100,7 +100,7 @@ class show_file_status extends task_base { $this->file_updater->create_new_file( $filename, - $this->cache->get('_file_' . md5($filename)), + base64_decode($this->cache->get('_file_' . md5($filename))), true ); } diff --git a/phpBB/phpbb/install/module/update_filesystem/task/update_files.php b/phpBB/phpbb/install/module/update_filesystem/task/update_files.php index 747a86281b..fbb465cc66 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/update_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/update_files.php @@ -164,20 +164,20 @@ class update_files extends task_base { case 'delete': $this->file_updater->delete_file($path); - break; + break; case 'new': $this->file_updater->create_new_file($path, $new_path . $path); - break; + break; case 'update_without_diff': $this->file_updater->update_file($path, $new_path . $path); - break; + break; case 'update_with_diff': $this->file_updater->update_file( $path, - $this->cache->get('_file_' . md5($path)), + base64_decode($this->cache->get('_file_' . md5($path))), true ); - break; + break; } // Save progress -- cgit v1.2.1 From 02a9264780f3896cf88b9d793dbf8831aa54e029 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Thu, 3 Dec 2015 20:31:49 +0100 Subject: [ticket/14269] Fix comments and language var names PHPBB3-14269 --- phpBB/phpbb/install/controller/install.php | 2 +- phpBB/phpbb/install/controller/update.php | 2 +- phpBB/phpbb/install/event/kernel_exception_subscriber.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/install.php b/phpBB/phpbb/install/controller/install.php index 0fd4e8897c..baa4e4807a 100644 --- a/phpBB/phpbb/install/controller/install.php +++ b/phpBB/phpbb/install/controller/install.php @@ -105,7 +105,7 @@ class install { if ($this->install_helper->is_phpbb_installed()) { - throw new http_exception(404, 'INSTALL_PHPBB_IS_ALREADY_INSTALLED'); + throw new http_exception(404, 'INSTALL_PHPBB_INSTALLED'); } $this->template->assign_vars(array( diff --git a/phpBB/phpbb/install/controller/update.php b/phpBB/phpbb/install/controller/update.php index 6a4341710a..8ecd8b3cb8 100644 --- a/phpBB/phpbb/install/controller/update.php +++ b/phpBB/phpbb/install/controller/update.php @@ -103,7 +103,7 @@ class update { if (!$this->install_helper->is_phpbb_installed()) { - throw new http_exception(404, 'INSTALL_PHPBB_IS_NOT_INSTALLED'); + throw new http_exception(404, 'INSTALL_PHPBB_NOT_INSTALLED'); } $this->template->assign_vars(array( diff --git a/phpBB/phpbb/install/event/kernel_exception_subscriber.php b/phpBB/phpbb/install/event/kernel_exception_subscriber.php index 2e6f9ca74d..c2960cb13c 100644 --- a/phpBB/phpbb/install/event/kernel_exception_subscriber.php +++ b/phpBB/phpbb/install/event/kernel_exception_subscriber.php @@ -112,9 +112,9 @@ class kernel_exception_subscriber implements EventSubscriberInterface } /** - * Returns an array of the events the object is subscribed to + * Returns an array of events the object is subscribed to * - * @return array Array of the events the object is subscribed to + * @return array Array of events the object is subscribed to */ static public function getSubscribedEvents() { -- cgit v1.2.1 From 44a90c9812c4eff73051e75647362859f9407a5f Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sat, 5 Dec 2015 15:42:22 +0100 Subject: [ticket/14269] Change HTTP status codes to 403 PHPBB3-14269 --- phpBB/phpbb/install/controller/install.php | 2 +- phpBB/phpbb/install/controller/update.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/install.php b/phpBB/phpbb/install/controller/install.php index baa4e4807a..8bf9062b08 100644 --- a/phpBB/phpbb/install/controller/install.php +++ b/phpBB/phpbb/install/controller/install.php @@ -105,7 +105,7 @@ class install { if ($this->install_helper->is_phpbb_installed()) { - throw new http_exception(404, 'INSTALL_PHPBB_INSTALLED'); + throw new http_exception(403, 'INSTALL_PHPBB_INSTALLED'); } $this->template->assign_vars(array( diff --git a/phpBB/phpbb/install/controller/update.php b/phpBB/phpbb/install/controller/update.php index 8ecd8b3cb8..9fff11cae8 100644 --- a/phpBB/phpbb/install/controller/update.php +++ b/phpBB/phpbb/install/controller/update.php @@ -103,7 +103,7 @@ class update { if (!$this->install_helper->is_phpbb_installed()) { - throw new http_exception(404, 'INSTALL_PHPBB_NOT_INSTALLED'); + throw new http_exception(403, 'INSTALL_PHPBB_NOT_INSTALLED'); } $this->template->assign_vars(array( -- cgit v1.2.1 From 1b9ae803c5cf887c8acc2e7580ccb6fe76522d58 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 7 Dec 2015 13:53:44 +0100 Subject: [ticket/14345] Check if description exists in message ary PHPBB3-14345 --- phpBB/phpbb/install/helper/iohandler/cli_iohandler.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php index abdd730d2e..dae5d339a5 100644 --- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -126,7 +126,8 @@ class cli_iohandler extends iohandler_base $this->io->newLine(); $message = $this->translate_message($error_title, $error_description); - $this->io->error($message['title'] . "\n" . $message['description']); + $message_string = $message['title'] . "\n" . (!empty($message['description']) ? $message['description'] : ''); + $this->io->error($message_string); if ($this->progress_bar !== null) { @@ -143,7 +144,8 @@ class cli_iohandler extends iohandler_base $this->io->newLine(); $message = $this->translate_message($warning_title, $warning_description); - $this->io->warning($message['title'] . "\n" . $message['description']); + $message_string = $message['title'] . "\n" . (!empty($message['description']) ? $message['description'] : ''); + $this->io->warning($message_string); if ($this->progress_bar !== null) { @@ -172,7 +174,8 @@ class cli_iohandler extends iohandler_base $this->io->newLine(); $message = $this->translate_message($error_title, $error_description); - $this->io->success($message['title'] . "\n" . $message['description']); + $message_string = $message['title'] . "\n" . (!empty($message['description']) ? $message['description'] : ''); + $this->io->success($message_string); if ($this->progress_bar !== null) { -- cgit v1.2.1 From 41b4fee6557c34d9ff534e7c1693d4e84e166ce1 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 7 Dec 2015 16:59:04 +0100 Subject: [ticket/14345] Move new line to ternary comparison PHPBB3-14345 --- phpBB/phpbb/install/helper/iohandler/cli_iohandler.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php index dae5d339a5..4d0341ef12 100644 --- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -126,7 +126,7 @@ class cli_iohandler extends iohandler_base $this->io->newLine(); $message = $this->translate_message($error_title, $error_description); - $message_string = $message['title'] . "\n" . (!empty($message['description']) ? $message['description'] : ''); + $message_string = $message['title'] . (!empty($message['description']) ? "\n" . $message['description'] : ''); $this->io->error($message_string); if ($this->progress_bar !== null) @@ -144,7 +144,7 @@ class cli_iohandler extends iohandler_base $this->io->newLine(); $message = $this->translate_message($warning_title, $warning_description); - $message_string = $message['title'] . "\n" . (!empty($message['description']) ? $message['description'] : ''); + $message_string = $message['title'] . (!empty($message['description']) ? "\n" . $message['description'] : ''); $this->io->warning($message_string); if ($this->progress_bar !== null) @@ -174,7 +174,7 @@ class cli_iohandler extends iohandler_base $this->io->newLine(); $message = $this->translate_message($error_title, $error_description); - $message_string = $message['title'] . "\n" . (!empty($message['description']) ? $message['description'] : ''); + $message_string = $message['title'] . (!empty($message['description']) ? "\n" . $message['description'] : ''); $this->io->success($message_string); if ($this->progress_bar !== null) -- cgit v1.2.1 From 6188a8777950ffeaa80593d815600c84911ac932 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 7 Dec 2015 23:36:49 +0100 Subject: [ticket/14344] Improve output of HTML errors trigged during install PHPBB3-14344 --- phpBB/phpbb/install/helper/iohandler/cli_iohandler.php | 4 ++++ phpBB/phpbb/install/helper/iohandler/iohandler_base.php | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php index 4d0341ef12..89f3594378 100644 --- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -125,6 +125,10 @@ class cli_iohandler extends iohandler_base { $this->io->newLine(); + if (strpos($error_title, '
') !== false) + { + $error_title = strip_tags(str_replace('
', "\n", $error_title)); + } $message = $this->translate_message($error_title, $error_description); $message_string = $message['title'] . (!empty($message['description']) ? "\n" . $message['description'] : ''); $this->io->error($message_string); diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php index 530cb4766b..8dee5390a9 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php @@ -101,6 +101,10 @@ abstract class iohandler_base implements iohandler_interface */ public function add_error_message($error_title, $error_description = false) { + if (strpos($error_title, '
') !== false) + { + $error_title = strip_tags(htmlspecialchars_decode($error_title)); + } $this->errors[] = $this->translate_message($error_title, $error_description); } -- cgit v1.2.1 From dee22f4a281335b51333ff493b34c026f36e1804 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 11 Dec 2015 21:05:53 +0100 Subject: [ticket/14177] Uses Symfony's Debug ErrorHandler in development environment PHPBB3-14177 --- phpBB/phpbb/debug/debug.php | 70 +++++++++++++++++++++++++++++++++++++ phpBB/phpbb/debug/error_handler.php | 32 +++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 phpBB/phpbb/debug/debug.php create mode 100644 phpBB/phpbb/debug/error_handler.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/debug/debug.php b/phpBB/phpbb/debug/debug.php new file mode 100644 index 0000000000..76308e9197 --- /dev/null +++ b/phpBB/phpbb/debug/debug.php @@ -0,0 +1,70 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\debug; + +use Symfony\Component\Debug\BufferingLogger; +use Symfony\Component\Debug\DebugClassLoader; +use Symfony\Component\Debug\ExceptionHandler; +use Symfony\Component\Filesystem\Exception\IOException; + +/** + * Registers all the debug tools. + + * @see Symfony\Component\Debug\Debug + */ +class Debug +{ + private static $enabled = false; + + /** + * Enables the debug tools. + * + * This method registers an error handler and an exception handler. + * + * If the Symfony ClassLoader component is available, a special + * class loader is also registered. + * + * @param int $errorReportingLevel The level of error reporting you want + * @param bool $displayErrors Whether to display errors (for development) or just log them (for production) + */ + public static function enable($errorReportingLevel = null, $displayErrors = true) + { + if (static::$enabled) { + return; + } + + static::$enabled = true; + + if (null !== $errorReportingLevel) { + error_reporting($errorReportingLevel); + } else { + error_reporting(-1); + } + + if ('cli' !== php_sapi_name()) { + ini_set('display_errors', 0); + ExceptionHandler::register(); + } elseif ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) { + // CLI - display errors only if they're not already logged to STDERR + ini_set('display_errors', 1); + } + if ($displayErrors) { + error_handler::register(new error_handler(new BufferingLogger())); + } else { + error_handler::register()->throwAt(0, true); + } + + DebugClassLoader::enable(); + } +} diff --git a/phpBB/phpbb/debug/error_handler.php b/phpBB/phpbb/debug/error_handler.php new file mode 100644 index 0000000000..2b182628a8 --- /dev/null +++ b/phpBB/phpbb/debug/error_handler.php @@ -0,0 +1,32 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\debug; + +use Symfony\Component\Debug\ErrorHandler; +use Symfony\Component\Filesystem\Exception\IOException; + +class error_handler extends ErrorHandler +{ + public function handleError($type, $message, $file, $line, array $context, array $backtrace = null) + { + if ($type === E_USER_WARNING|| $type === E_USER_NOTICE) + { + $handler = defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'; + + $handler($type, $message, $file, $line); + } + + return parent::handleError($type, $message, $file, $line, $context, $backtrace); + } +} -- cgit v1.2.1 From 6ffbd26377ae7a29dd10f3df5a3a4f76504e7d77 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 11 Dec 2015 21:39:24 +0100 Subject: [ticket/14177] CS PHPBB3-14177 --- phpBB/phpbb/debug/debug.php | 28 +++++++++++++++++++--------- phpBB/phpbb/debug/error_handler.php | 3 +-- 2 files changed, 20 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/debug/debug.php b/phpBB/phpbb/debug/debug.php index 76308e9197..c5ffada2e5 100644 --- a/phpBB/phpbb/debug/debug.php +++ b/phpBB/phpbb/debug/debug.php @@ -16,14 +16,13 @@ namespace phpbb\debug; use Symfony\Component\Debug\BufferingLogger; use Symfony\Component\Debug\DebugClassLoader; use Symfony\Component\Debug\ExceptionHandler; -use Symfony\Component\Filesystem\Exception\IOException; /** * Registers all the debug tools. * @see Symfony\Component\Debug\Debug */ -class Debug +class debug { private static $enabled = false; @@ -40,28 +39,39 @@ class Debug */ public static function enable($errorReportingLevel = null, $displayErrors = true) { - if (static::$enabled) { + if (static::$enabled) + { return; } static::$enabled = true; - if (null !== $errorReportingLevel) { + if ($errorReportingLevel !== null) + { error_reporting($errorReportingLevel); - } else { + } + else + { error_reporting(-1); } - if ('cli' !== php_sapi_name()) { + if ('cli' !== php_sapi_name()) + { ini_set('display_errors', 0); ExceptionHandler::register(); - } elseif ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) { + } + else if ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) + { // CLI - display errors only if they're not already logged to STDERR ini_set('display_errors', 1); } - if ($displayErrors) { + + if ($displayErrors) + { error_handler::register(new error_handler(new BufferingLogger())); - } else { + } + else + { error_handler::register()->throwAt(0, true); } diff --git a/phpBB/phpbb/debug/error_handler.php b/phpBB/phpbb/debug/error_handler.php index 2b182628a8..246e724f56 100644 --- a/phpBB/phpbb/debug/error_handler.php +++ b/phpBB/phpbb/debug/error_handler.php @@ -14,13 +14,12 @@ namespace phpbb\debug; use Symfony\Component\Debug\ErrorHandler; -use Symfony\Component\Filesystem\Exception\IOException; class error_handler extends ErrorHandler { public function handleError($type, $message, $file, $line, array $context, array $backtrace = null) { - if ($type === E_USER_WARNING|| $type === E_USER_NOTICE) + if ($type === E_USER_WARNING || $type === E_USER_NOTICE) { $handler = defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'; -- cgit v1.2.1 From 8daeb6962aa0f86798e40ae94c59fac9184155c0 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 14 Dec 2015 22:39:10 +0100 Subject: [prep-release-3.2.0-a2] Add migration for 3.2.0-a2 --- phpBB/phpbb/db/migration/data/v320/v320a2.php | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/v320a2.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/v320a2.php b/phpBB/phpbb/db/migration/data/v320/v320a2.php new file mode 100644 index 0000000000..ae53a73210 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/v320a2.php @@ -0,0 +1,38 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class v320a2 extends \phpbb\db\migration\container_aware_migration +{ + public function effectively_installed() + { + return version_compare($this->config['version'], '3.2.0-a2', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v317rc1', + '\phpbb\db\migration\data\v320\text_reparser', + '\phpbb\db\migration\data\v320\v320a1', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.0-a2')), + ); + } +} -- cgit v1.2.1 From 2fe81c1ccb20035c9d66503726a7ff8df8b7fd78 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 20 Dec 2015 22:20:56 +0100 Subject: [ticket/14373] Do not pass arrays to strpos() PHPBB3-14373 --- phpBB/phpbb/install/helper/iohandler/iohandler_base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php index 8dee5390a9..7271fe9bc0 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php @@ -101,7 +101,7 @@ abstract class iohandler_base implements iohandler_interface */ public function add_error_message($error_title, $error_description = false) { - if (strpos($error_title, '
') !== false) + if (!is_array($error_title) && strpos($error_title, '
') !== false) { $error_title = strip_tags(htmlspecialchars_decode($error_title)); } -- cgit v1.2.1 From d44e34aa141361781eae67814278b390cebaf4e5 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Tue, 22 Dec 2015 18:48:12 +0100 Subject: [ticket/14377] Allow extensions to register compiler pass PHPBB3-14377 --- phpBB/phpbb/di/container_builder.php | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 0a94aac98d..8f175c966c 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -22,6 +22,7 @@ use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Finder\Finder; use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; class container_builder @@ -158,6 +159,11 @@ class container_builder // Event listeners "Symfony style" $this->container->addCompilerPass(new RegisterListenersPass('dispatcher')); + if ($this->use_extensions) + { + $this->register_ext_compiler_pass(); + } + $filesystem = new filesystem(); $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path()))); $loader->load($this->container->getParameter('core.environment') . '/config.yml'); @@ -512,4 +518,34 @@ class container_builder { return $this->environment ?: PHPBB_ENVIRONMENT; } + + private function register_ext_compiler_pass() + { + $finder = new Finder(); + $finder + ->name('*_pass.php') + ->path('di/pass') + ->files() + ->ignoreDotFiles(true) + ->ignoreUnreadableDirs(true) + ->ignoreVCS(true) + ->followLinks() + ->in($this->phpbb_root_path . 'ext/') + ; + + /** @var \SplFileInfo $pass */ + foreach ($finder as $pass) + { + $filename = $pass->getPathname(); + $filename = substr($filename, 0, -strlen('.' . $pass->getExtension())); + $filename = str_replace(DIRECTORY_SEPARATOR, '/', $filename); + $className = preg_replace('#^.*ext/#', '', $filename); + $className = '\\' . str_replace('/', '\\', $className); + + if (class_exists($className) && in_array('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface', class_implements($className), true)) + { + $this->container->addCompilerPass(new $className()); + } + } + } } -- cgit v1.2.1 From c02fc0f63fb8098cd4096481ad27b31f8069d5d1 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 22 Dec 2015 20:01:22 +0100 Subject: [ticket/14378] Use consistent template variable paths PHPBB3-14378 --- phpBB/phpbb/install/controller/helper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/helper.php b/phpBB/phpbb/install/controller/helper.php index ed817f7396..2dad42b4b6 100644 --- a/phpBB/phpbb/install/controller/helper.php +++ b/phpBB/phpbb/install/controller/helper.php @@ -270,10 +270,10 @@ class helper 'L_SELECT_LANG' => $this->language->lang('SELECT_LANG'), 'L_SKIP' => $this->language->lang('SKIP'), 'PAGE_TITLE' => $this->language->lang($page_title), - 'T_IMAGE_PATH' => $this->path_helper->get_web_root_path() . $path . 'images/', + 'T_IMAGE_PATH' => $this->path_helper->get_web_root_path() . $path . 'images', 'T_JQUERY_LINK' => $this->path_helper->get_web_root_path() . $path . '../assets/javascript/jquery.min.js', - 'T_TEMPLATE_PATH' => $this->path_helper->get_web_root_path() . $path . 'style/', - 'T_ASSETS_PATH' => $this->path_helper->get_web_root_path() . $path . '../assets/', + 'T_TEMPLATE_PATH' => $this->path_helper->get_web_root_path() . $path . 'style', + 'T_ASSETS_PATH' => $this->path_helper->get_web_root_path() . $path . '../assets', 'S_CONTENT_DIRECTION' => $this->language->lang('DIRECTION'), 'S_CONTENT_FLOW_BEGIN' => ($this->language->lang('DIRECTION') === 'ltr') ? 'left' : 'right', -- cgit v1.2.1 From eb6ceb963ea7b32ef852b53d3da3a7e795291359 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sat, 5 Dec 2015 07:55:52 +0100 Subject: [ticket/14323] Added support for truncating long URLs PHPBB3-14323 --- phpBB/phpbb/textformatter/s9e/factory.php | 28 ++++++++++++++++++++-- phpBB/phpbb/textformatter/s9e/parser.php | 40 +++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 63b23d2fd0..dd3102d4de 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -332,8 +332,7 @@ class factory implements \phpbb\textformatter\cache_interface } // Load the magic links plugins. We do that after BBCodes so that they use the same tags - $configurator->plugins->load('Autoemail'); - $configurator->plugins->load('Autolink', array('matchWww' => true)); + $this->configure_autolink($configurator); // Register some vars with a default value. Those should be set at runtime by whatever calls // the parser @@ -394,6 +393,31 @@ class factory implements \phpbb\textformatter\cache_interface return array('parser' => $parser, 'renderer' => $renderer); } + /** + * Configure the Autolink / Autoemail plugins used to linkify text + * + * @param \s9e\TextFormatter\Configurator $configurator + * @return void + */ + protected function configure_autolink(Configurator $configurator) + { + $configurator->plugins->load('Autoemail'); + $configurator->plugins->load('Autolink', array('matchWww' => true)); + + // Create a tag that will be used to display the truncated text by replacing the original + // content with the content of the @text attribute + $tag = $configurator->tags->add('AUTOLINK_TEXT'); + $tag->attributes->add('text'); + $tag->template = ''; + + // Add a tag filter that replaces the text of links that were created by the Autolink plugin + $configurator->Autolink->getTag()->filterChain + ->add(__NAMESPACE__ . '\\parser::generate_autolink_text') + ->resetParameters() + ->addParameterByName('tag') + ->addParameterByName('parser'); + } + /** * Return the default BBCodes configuration * diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index ffaffbc63c..faddc806cd 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -393,4 +393,44 @@ class parser implements \phpbb\textformatter\parser_interface return $url; } + + /** + * Replace the content displayed inside of a URL tag + * + * Will only apply to URL tags that do not use any markup (e.g. not "[url]") on the assumption + * that those tags were created by the Autolink plugin to linkify URLs found in plain text + * + * @param \s9e\TextFormatter\Parser\Tag $url_tag URL tag (start tag) + * @param \s9e\TextFormatter\Parser $parser Parser + * @return bool Always TRUE to indicate that the tag is valid + */ + public static function generate_autolink_text(\s9e\TextFormatter\Parser\Tag $url_tag, \s9e\TextFormatter\Parser $parser) + { + // If the tag consumes any text then we ignore it because it's not a linkified URL. Same if + // it's not paired with an end tag that doesn't consume any text either + if ($url_tag->getLen() > 0 || !$url_tag->getEndTag()) + { + return true; + } + + // Capture the text between the start tag and its end tag + $start = $url_tag->getPos(); + $end = $url_tag->getEndTag()->getPos(); + $length = $end - $start; + $text = substr($parser->getText(), $start, $length); + + if ($length <= 55 || utf8_strlen($text) <= 55) + { + // Do not do anything if the text is not longer than 55 characters + return true; + } + + $tag = $parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length); + $url_tag->cascadeInvalidationTo($tag); + + $text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10); + $tag->setAttribute('text', $text); + + return true; + } } -- cgit v1.2.1 From 8fe94a19b46c4e33a117c1a040415f2b1c397e7c Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sat, 5 Dec 2015 19:48:01 +0100 Subject: [ticket/14323] Added support for truncating local URLs PHPBB3-14323 --- phpBB/phpbb/textformatter/s9e/factory.php | 3 ++- phpBB/phpbb/textformatter/s9e/parser.php | 25 +++++++++++++++---------- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index dd3102d4de..63e49b6dd4 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -415,7 +415,8 @@ class factory implements \phpbb\textformatter\cache_interface ->add(__NAMESPACE__ . '\\parser::generate_autolink_text') ->resetParameters() ->addParameterByName('tag') - ->addParameterByName('parser'); + ->addParameterByName('parser') + ->addParameterByValue(generate_board_url() . '/'); } /** diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index faddc806cd..d8a2b8d62c 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -400,11 +400,12 @@ class parser implements \phpbb\textformatter\parser_interface * Will only apply to URL tags that do not use any markup (e.g. not "[url]") on the assumption * that those tags were created by the Autolink plugin to linkify URLs found in plain text * - * @param \s9e\TextFormatter\Parser\Tag $url_tag URL tag (start tag) - * @param \s9e\TextFormatter\Parser $parser Parser - * @return bool Always TRUE to indicate that the tag is valid + * @param \s9e\TextFormatter\Parser\Tag $url_tag URL tag (start tag) + * @param \s9e\TextFormatter\Parser $parser Parser + * @param string $board_url Forum's root URL (with trailing slash) + * @return bool Always TRUE to indicate that the tag is valid */ - public static function generate_autolink_text(\s9e\TextFormatter\Parser\Tag $url_tag, \s9e\TextFormatter\Parser $parser) + public static function generate_autolink_text(\s9e\TextFormatter\Parser\Tag $url_tag, \s9e\TextFormatter\Parser $parser, $board_url) { // If the tag consumes any text then we ignore it because it's not a linkified URL. Same if // it's not paired with an end tag that doesn't consume any text either @@ -419,16 +420,20 @@ class parser implements \phpbb\textformatter\parser_interface $length = $end - $start; $text = substr($parser->getText(), $start, $length); - if ($length <= 55 || utf8_strlen($text) <= 55) + // Remove the board's root URL from the link if applicable + if (stripos($text, $board_url) === 0 && strlen($text) > strlen($board_url)) { - // Do not do anything if the text is not longer than 55 characters - return true; + $text = substr($text, strlen($board_url)); } - $tag = $parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length); - $url_tag->cascadeInvalidationTo($tag); + // Truncate the text if it's longer than 55 characters + if (utf8_strlen($text) > 55) + { + $text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10); + } - $text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10); + // Create a tag that consumes the link's text + $tag = $parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length); $tag->setAttribute('text', $text); return true; -- cgit v1.2.1 From 9a8fb2e1df0d63f46ee0a6e4b64dc8530b8db809 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 6 Dec 2015 15:11:26 +0100 Subject: [ticket/14323] Stylistic change [ci skip] PHPBB3-14323 --- phpBB/phpbb/textformatter/s9e/parser.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index d8a2b8d62c..beb737c816 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -397,18 +397,20 @@ class parser implements \phpbb\textformatter\parser_interface /** * Replace the content displayed inside of a URL tag * - * Will only apply to URL tags that do not use any markup (e.g. not "[url]") on the assumption - * that those tags were created by the Autolink plugin to linkify URLs found in plain text + * Will only apply to URL tags that do not use any markup (e.g. not "[url]") + * on the assumption that those tags were created by the Autolink plugin to + * linkify URLs found in plain text * * @param \s9e\TextFormatter\Parser\Tag $url_tag URL tag (start tag) * @param \s9e\TextFormatter\Parser $parser Parser * @param string $board_url Forum's root URL (with trailing slash) - * @return bool Always TRUE to indicate that the tag is valid + * @return bool Always true to indicate that the tag is valid */ public static function generate_autolink_text(\s9e\TextFormatter\Parser\Tag $url_tag, \s9e\TextFormatter\Parser $parser, $board_url) { - // If the tag consumes any text then we ignore it because it's not a linkified URL. Same if - // it's not paired with an end tag that doesn't consume any text either + // If the tag consumes any text then we ignore it because it's not a + // linkified URL. Same if it's not paired with an end tag that doesn't + // consume any text either if ($url_tag->getLen() > 0 || !$url_tag->getEndTag()) { return true; -- cgit v1.2.1 From ad2c032d3b748d177403fd495685977f7964f8d4 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 6 Dec 2015 22:08:00 +0100 Subject: [ticket/14323] Moved autolink-related functions to a separate helper PHPBB3-14323 --- phpBB/phpbb/textformatter/s9e/autolink_helper.php | 105 ++++++++++++++++++++++ phpBB/phpbb/textformatter/s9e/factory.php | 37 ++++++-- phpBB/phpbb/textformatter/s9e/parser.php | 47 ---------- 3 files changed, 135 insertions(+), 54 deletions(-) create mode 100644 phpBB/phpbb/textformatter/s9e/autolink_helper.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/autolink_helper.php b/phpBB/phpbb/textformatter/s9e/autolink_helper.php new file mode 100644 index 0000000000..8fb171f413 --- /dev/null +++ b/phpBB/phpbb/textformatter/s9e/autolink_helper.php @@ -0,0 +1,105 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter\s9e; + +class autolink_helper +{ + /** + * Clean up and invalidate an AUTOLINK_TEXT tag if applicable + * + * @param \s9e\TextFormatter\Parser\Tag $tag AUTOLINK_TEXT tag + * @param \s9e\TextFormatter\Parser $parser Parser + * @return bool Whether the tag is valid + */ + public function cleanup_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser) + { + // Remove the url attribute because it's not needed. + $tag->removeAttribute('url'); + + // Invalidate if the content of the tag matches the text attribute + $text = substr($parser->getText(), $tag->getPos(), $tag->getLen()); + + return ($text !== $tag->getAttribute('text')); + } + + /** + * Create an AUTOLINK_TEXT tag inside of a link created by the Autolink plugin + * + * Will only apply to URL tags that do not use any markup (e.g. not "[url]") + * on the assumption that those tags were created by the Autolink plugin to + * linkify URLs found in plain text + * + * @param \s9e\TextFormatter\Parser\Tag $tag URL tag (start tag) + * @param \s9e\TextFormatter\Parser $parser Parser + * @return bool Always true to indicate that the tag is valid + */ + public function generate_autolink_text_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser) + { + // If the tag consumes any text then we ignore it because it's not a + // linkified URL. Same if it's not paired with an end tag that doesn't + // consume any text either + if ($tag->getLen() > 0 || !$tag->getEndTag()) + { + return true; + } + + // Capture the text between the start tag and its end tag + $start = $tag->getPos(); + $end = $tag->getEndTag()->getPos(); + $length = $end - $start; + $text = substr($parser->getText(), $start, $length); + + // Create a tag that consumes the link's text + $parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length)->setAttribute('text', $text); + + return true; + } + + /** + * Remove the board's root URL from a the start of a string + * + * @param \s9e\TextFormatter\Parser\Tag $tag AUTOLINK_TEXT tag + * @param string $board_url Forum's root URL (with trailing slash) + * @return bool Always true to indicate that the tag is valid + */ + public function truncate_local_url(\s9e\TextFormatter\Parser\Tag $tag, $board_url) + { + $text = $tag->getAttribute('text'); + if (stripos($text, $board_url) === 0 && strlen($text) > strlen($board_url)) + { + $tag->setAttribute('text', substr($text, strlen($board_url))); + } + + return true; + } + + /** + * Truncate the replacement text set in an AUTOLINK_TEXT tag + * + * @param \s9e\TextFormatter\Parser\Tag $tag AUTOLINK_TEXT tag + * @return bool Always true to indicate that the tag is valid + */ + public function truncate_text(\s9e\TextFormatter\Parser\Tag $tag) + { + $text = $tag->getAttribute('text'); + if (utf8_strlen($text) > 55) + { + $text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10); + } + + $tag->setAttribute('text', $text); + + return true; + } +} diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 63e49b6dd4..736f9a9f8a 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -22,6 +22,11 @@ use s9e\TextFormatter\Configurator\Items\UnsafeTemplate; */ class factory implements \phpbb\textformatter\cache_interface { + /** + * @var \phpbb\textformatter\s9e\autolink_helper + */ + protected $autolink_helper; + /** * @var \phpbb\cache\driver\driver_interface */ @@ -133,12 +138,14 @@ class factory implements \phpbb\textformatter\cache_interface * @param \phpbb\cache\driver\driver_interface $cache * @param \phpbb\event\dispatcher_interface $dispatcher * @param \phpbb\config\config $config + * @param \phpbb\textformatter\s9e\autolink_helper $autolink_helper * @param string $cache_dir Path to the cache dir * @param string $cache_key_parser Cache key used for the parser * @param string $cache_key_renderer Cache key used for the renderer */ - public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, $cache_dir, $cache_key_parser, $cache_key_renderer) + public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, \phpbb\textformatter\s9e\autolink_helper $autolink_helper, $cache_dir, $cache_key_parser, $cache_key_renderer) { + $this->autolink_helper = $autolink_helper; $this->cache = $cache; $this->cache_dir = $cache_dir; $this->cache_key_parser = $cache_key_parser; @@ -404,19 +411,35 @@ class factory implements \phpbb\textformatter\cache_interface $configurator->plugins->load('Autoemail'); $configurator->plugins->load('Autolink', array('matchWww' => true)); - // Create a tag that will be used to display the truncated text by replacing the original - // content with the content of the @text attribute + // Add a tag filter that creates a tag that stores and replace the + // content of a link created by the Autolink plugin + $configurator->Autolink->getTag()->filterChain + ->add(array($this->autolink_helper, 'generate_autolink_text_tag')) + ->resetParameters() + ->addParameterByName('tag') + ->addParameterByName('parser'); + + // Create a tag that will be used to display the truncated text by + // replacing the original content with the content of the @text attribute $tag = $configurator->tags->add('AUTOLINK_TEXT'); $tag->attributes->add('text'); + $tag->attributes->add('url', array('required' => false))->filterChain->add('#url'); $tag->template = ''; - // Add a tag filter that replaces the text of links that were created by the Autolink plugin - $configurator->Autolink->getTag()->filterChain - ->add(__NAMESPACE__ . '\\parser::generate_autolink_text') + $tag->filterChain + ->add(array($this->autolink_helper, 'truncate_local_url')) ->resetParameters() ->addParameterByName('tag') - ->addParameterByName('parser') ->addParameterByValue(generate_board_url() . '/'); + $tag->filterChain + ->add(array($this->autolink_helper, 'truncate_text')) + ->resetParameters() + ->addParameterByName('tag'); + $tag->filterChain + ->add(array($this->autolink_helper, 'cleanup_tag')) + ->resetParameters() + ->addParameterByName('tag') + ->addParameterByName('parser'); } /** diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index beb737c816..ffaffbc63c 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -393,51 +393,4 @@ class parser implements \phpbb\textformatter\parser_interface return $url; } - - /** - * Replace the content displayed inside of a URL tag - * - * Will only apply to URL tags that do not use any markup (e.g. not "[url]") - * on the assumption that those tags were created by the Autolink plugin to - * linkify URLs found in plain text - * - * @param \s9e\TextFormatter\Parser\Tag $url_tag URL tag (start tag) - * @param \s9e\TextFormatter\Parser $parser Parser - * @param string $board_url Forum's root URL (with trailing slash) - * @return bool Always true to indicate that the tag is valid - */ - public static function generate_autolink_text(\s9e\TextFormatter\Parser\Tag $url_tag, \s9e\TextFormatter\Parser $parser, $board_url) - { - // If the tag consumes any text then we ignore it because it's not a - // linkified URL. Same if it's not paired with an end tag that doesn't - // consume any text either - if ($url_tag->getLen() > 0 || !$url_tag->getEndTag()) - { - return true; - } - - // Capture the text between the start tag and its end tag - $start = $url_tag->getPos(); - $end = $url_tag->getEndTag()->getPos(); - $length = $end - $start; - $text = substr($parser->getText(), $start, $length); - - // Remove the board's root URL from the link if applicable - if (stripos($text, $board_url) === 0 && strlen($text) > strlen($board_url)) - { - $text = substr($text, strlen($board_url)); - } - - // Truncate the text if it's longer than 55 characters - if (utf8_strlen($text) > 55) - { - $text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10); - } - - // Create a tag that consumes the link's text - $tag = $parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length); - $tag->setAttribute('text', $text); - - return true; - } } -- cgit v1.2.1 From 5c8373dc20f3cef80b00304ec3b9e27fa86346e5 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sat, 26 Dec 2015 17:01:37 +0100 Subject: [ticket/14323] Added comment [ci skip] PHPBB3-14323 --- phpBB/phpbb/textformatter/s9e/autolink_helper.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/autolink_helper.php b/phpBB/phpbb/textformatter/s9e/autolink_helper.php index 8fb171f413..81ebc6d029 100644 --- a/phpBB/phpbb/textformatter/s9e/autolink_helper.php +++ b/phpBB/phpbb/textformatter/s9e/autolink_helper.php @@ -18,6 +18,9 @@ class autolink_helper /** * Clean up and invalidate an AUTOLINK_TEXT tag if applicable * + * Will invalidate the tag if its replacement text is the same as the original + * text and would have no visible effect + * * @param \s9e\TextFormatter\Parser\Tag $tag AUTOLINK_TEXT tag * @param \s9e\TextFormatter\Parser $parser Parser * @return bool Whether the tag is valid -- cgit v1.2.1 From 909f8653ec0bf2905ed8d8a9591486f7eefe4d56 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 27 Dec 2015 16:43:45 +0100 Subject: [ticket/14323] Renamed AUTOLINK_TEXT to LINK_TEXT Expanded link text shortening to [url] BBCodes with no parameters PHPBB3-14323 --- phpBB/phpbb/textformatter/s9e/autolink_helper.php | 108 ---------------------- phpBB/phpbb/textformatter/s9e/factory.php | 21 ++--- phpBB/phpbb/textformatter/s9e/link_helper.php | 103 +++++++++++++++++++++ 3 files changed, 113 insertions(+), 119 deletions(-) delete mode 100644 phpBB/phpbb/textformatter/s9e/autolink_helper.php create mode 100644 phpBB/phpbb/textformatter/s9e/link_helper.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/autolink_helper.php b/phpBB/phpbb/textformatter/s9e/autolink_helper.php deleted file mode 100644 index 81ebc6d029..0000000000 --- a/phpBB/phpbb/textformatter/s9e/autolink_helper.php +++ /dev/null @@ -1,108 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\textformatter\s9e; - -class autolink_helper -{ - /** - * Clean up and invalidate an AUTOLINK_TEXT tag if applicable - * - * Will invalidate the tag if its replacement text is the same as the original - * text and would have no visible effect - * - * @param \s9e\TextFormatter\Parser\Tag $tag AUTOLINK_TEXT tag - * @param \s9e\TextFormatter\Parser $parser Parser - * @return bool Whether the tag is valid - */ - public function cleanup_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser) - { - // Remove the url attribute because it's not needed. - $tag->removeAttribute('url'); - - // Invalidate if the content of the tag matches the text attribute - $text = substr($parser->getText(), $tag->getPos(), $tag->getLen()); - - return ($text !== $tag->getAttribute('text')); - } - - /** - * Create an AUTOLINK_TEXT tag inside of a link created by the Autolink plugin - * - * Will only apply to URL tags that do not use any markup (e.g. not "[url]") - * on the assumption that those tags were created by the Autolink plugin to - * linkify URLs found in plain text - * - * @param \s9e\TextFormatter\Parser\Tag $tag URL tag (start tag) - * @param \s9e\TextFormatter\Parser $parser Parser - * @return bool Always true to indicate that the tag is valid - */ - public function generate_autolink_text_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser) - { - // If the tag consumes any text then we ignore it because it's not a - // linkified URL. Same if it's not paired with an end tag that doesn't - // consume any text either - if ($tag->getLen() > 0 || !$tag->getEndTag()) - { - return true; - } - - // Capture the text between the start tag and its end tag - $start = $tag->getPos(); - $end = $tag->getEndTag()->getPos(); - $length = $end - $start; - $text = substr($parser->getText(), $start, $length); - - // Create a tag that consumes the link's text - $parser->addSelfClosingTag('AUTOLINK_TEXT', $start, $length)->setAttribute('text', $text); - - return true; - } - - /** - * Remove the board's root URL from a the start of a string - * - * @param \s9e\TextFormatter\Parser\Tag $tag AUTOLINK_TEXT tag - * @param string $board_url Forum's root URL (with trailing slash) - * @return bool Always true to indicate that the tag is valid - */ - public function truncate_local_url(\s9e\TextFormatter\Parser\Tag $tag, $board_url) - { - $text = $tag->getAttribute('text'); - if (stripos($text, $board_url) === 0 && strlen($text) > strlen($board_url)) - { - $tag->setAttribute('text', substr($text, strlen($board_url))); - } - - return true; - } - - /** - * Truncate the replacement text set in an AUTOLINK_TEXT tag - * - * @param \s9e\TextFormatter\Parser\Tag $tag AUTOLINK_TEXT tag - * @return bool Always true to indicate that the tag is valid - */ - public function truncate_text(\s9e\TextFormatter\Parser\Tag $tag) - { - $text = $tag->getAttribute('text'); - if (utf8_strlen($text) > 55) - { - $text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10); - } - - $tag->setAttribute('text', $text); - - return true; - } -} diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 736f9a9f8a..7fdc5afeed 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -23,9 +23,9 @@ use s9e\TextFormatter\Configurator\Items\UnsafeTemplate; class factory implements \phpbb\textformatter\cache_interface { /** - * @var \phpbb\textformatter\s9e\autolink_helper + * @var \phpbb\textformatter\s9e\link_helper */ - protected $autolink_helper; + protected $link_helper; /** * @var \phpbb\cache\driver\driver_interface @@ -138,14 +138,14 @@ class factory implements \phpbb\textformatter\cache_interface * @param \phpbb\cache\driver\driver_interface $cache * @param \phpbb\event\dispatcher_interface $dispatcher * @param \phpbb\config\config $config - * @param \phpbb\textformatter\s9e\autolink_helper $autolink_helper + * @param \phpbb\textformatter\s9e\link_helper $link_helper * @param string $cache_dir Path to the cache dir * @param string $cache_key_parser Cache key used for the parser * @param string $cache_key_renderer Cache key used for the renderer */ - public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, \phpbb\textformatter\s9e\autolink_helper $autolink_helper, $cache_dir, $cache_key_parser, $cache_key_renderer) + public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, \phpbb\textformatter\s9e\link_helper $link_helper, $cache_dir, $cache_key_parser, $cache_key_renderer) { - $this->autolink_helper = $autolink_helper; + $this->link_helper = $link_helper; $this->cache = $cache; $this->cache_dir = $cache_dir; $this->cache_key_parser = $cache_key_parser; @@ -414,29 +414,28 @@ class factory implements \phpbb\textformatter\cache_interface // Add a tag filter that creates a tag that stores and replace the // content of a link created by the Autolink plugin $configurator->Autolink->getTag()->filterChain - ->add(array($this->autolink_helper, 'generate_autolink_text_tag')) + ->add(array($this->link_helper, 'generate_link_text_tag')) ->resetParameters() ->addParameterByName('tag') ->addParameterByName('parser'); // Create a tag that will be used to display the truncated text by // replacing the original content with the content of the @text attribute - $tag = $configurator->tags->add('AUTOLINK_TEXT'); + $tag = $configurator->tags->add('LINK_TEXT'); $tag->attributes->add('text'); - $tag->attributes->add('url', array('required' => false))->filterChain->add('#url'); $tag->template = ''; $tag->filterChain - ->add(array($this->autolink_helper, 'truncate_local_url')) + ->add(array($this->link_helper, 'truncate_local_url')) ->resetParameters() ->addParameterByName('tag') ->addParameterByValue(generate_board_url() . '/'); $tag->filterChain - ->add(array($this->autolink_helper, 'truncate_text')) + ->add(array($this->link_helper, 'truncate_text')) ->resetParameters() ->addParameterByName('tag'); $tag->filterChain - ->add(array($this->autolink_helper, 'cleanup_tag')) + ->add(array($this->link_helper, 'cleanup_tag')) ->resetParameters() ->addParameterByName('tag') ->addParameterByName('parser'); diff --git a/phpBB/phpbb/textformatter/s9e/link_helper.php b/phpBB/phpbb/textformatter/s9e/link_helper.php new file mode 100644 index 0000000000..76948159ba --- /dev/null +++ b/phpBB/phpbb/textformatter/s9e/link_helper.php @@ -0,0 +1,103 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter\s9e; + +class link_helper +{ + /** + * Clean up and invalidate a LINK_TEXT tag if applicable + * + * Will invalidate the tag if its replacement text is the same as the original + * text and would have no visible effect + * + * @param \s9e\TextFormatter\Parser\Tag $tag LINK_TEXT tag + * @param \s9e\TextFormatter\Parser $parser Parser + * @return bool Whether the tag is valid + */ + public function cleanup_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser) + { + // Invalidate if the content of the tag matches the text attribute + $text = substr($parser->getText(), $tag->getPos(), $tag->getLen()); + + return ($text !== $tag->getAttribute('text')); + } + + /** + * Create a LINK_TEXT tag inside of a link + * + * Meant to only apply to linkified URLs and [url] BBCodes without a parameter + * + * @param \s9e\TextFormatter\Parser\Tag $tag URL tag (start tag) + * @param \s9e\TextFormatter\Parser $parser Parser + * @return bool Always true to indicate that the tag is valid + */ + public function generate_link_text_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser) + { + // Only create a LINK_TEXT tag if the start tag is paired with an end + // tag, which is the case with tags from the Autolink plugins and with + // the [url] BBCode when its content is used for the URL + if (!$tag->getEndTag()) + { + return true; + } + + // Capture the text between the start tag and its end tag + $start = $tag->getPos() + $tag->getLen(); + $end = $tag->getEndTag()->getPos(); + $length = $end - $start; + $text = substr($parser->getText(), $start, $length); + + // Create a tag that consumes the link's text + $parser->addSelfClosingTag('LINK_TEXT', $start, $length)->setAttribute('text', $text); + + return true; + } + + /** + * Remove the board's root URL from a the start of a string + * + * @param \s9e\TextFormatter\Parser\Tag $tag LINK_TEXT tag + * @param string $board_url Forum's root URL (with trailing slash) + * @return bool Always true to indicate that the tag is valid + */ + public function truncate_local_url(\s9e\TextFormatter\Parser\Tag $tag, $board_url) + { + $text = $tag->getAttribute('text'); + if (stripos($text, $board_url) === 0 && strlen($text) > strlen($board_url)) + { + $tag->setAttribute('text', substr($text, strlen($board_url))); + } + + return true; + } + + /** + * Truncate the replacement text set in a LINK_TEXT tag + * + * @param \s9e\TextFormatter\Parser\Tag $tag LINK_TEXT tag + * @return bool Always true to indicate that the tag is valid + */ + public function truncate_text(\s9e\TextFormatter\Parser\Tag $tag) + { + $text = $tag->getAttribute('text'); + if (utf8_strlen($text) > 55) + { + $text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10); + } + + $tag->setAttribute('text', $text); + + return true; + } +} -- cgit v1.2.1 From bc5d976786d60d8d33cf77fccf81ce351b59fcdc Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 28 Dec 2015 04:19:21 +0100 Subject: [ticket/14323] Added should_shorten() Explicitly tests a tag's markup to determine whether a link should be shortened PHPBB3-14323 --- phpBB/phpbb/textformatter/s9e/link_helper.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/link_helper.php b/phpBB/phpbb/textformatter/s9e/link_helper.php index 76948159ba..0f44603dec 100644 --- a/phpBB/phpbb/textformatter/s9e/link_helper.php +++ b/phpBB/phpbb/textformatter/s9e/link_helper.php @@ -47,7 +47,7 @@ class link_helper // Only create a LINK_TEXT tag if the start tag is paired with an end // tag, which is the case with tags from the Autolink plugins and with // the [url] BBCode when its content is used for the URL - if (!$tag->getEndTag()) + if (!$tag->getEndTag() || !$this->should_shorten($tag, $parser->getText())) { return true; } @@ -64,6 +64,21 @@ class link_helper return true; } + /** + * Test whether we should shorten this tag's text + * + * Will test whether the tag either does not use any markup or uses a single + * [url] BBCode + * + * @param \s9e\TextFormatter\Parser\Tag $tag URL tag + * @param string $text Original text + * @return bool + */ + protected function should_shorten(\s9e\TextFormatter\Parser\Tag $tag, $text) + { + return ($tag->getLen() === 0 || strtolower(substr($text, $tag->getPos(), $tag->getLen())) === '[url]'); + } + /** * Remove the board's root URL from a the start of a string * -- cgit v1.2.1 From 8ed59fb82a9381914a4ccce91c0c5fac44616556 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Fri, 23 Oct 2015 02:44:41 +0200 Subject: [ticket/14250] Change token_storage class to fit changed interface PHPBB3-14250 --- phpBB/phpbb/auth/provider/oauth/oauth.php | 21 +- phpBB/phpbb/auth/provider/oauth/token_storage.php | 232 ++++++++++++++++++++- .../phpbb/db/migration/data/v320/oauth_states.php | 56 +++++ 3 files changed, 294 insertions(+), 15 deletions(-) create mode 100644 phpBB/phpbb/db/migration/data/v320/oauth_states.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index be0fbf5831..bfeac2dd32 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -62,6 +62,13 @@ class oauth extends \phpbb\auth\provider\base */ protected $auth_provider_oauth_token_storage_table; + /** + * OAuth state table + * + * @var string + */ + protected $auth_provider_oauth_state_table; + /** * OAuth account association table * @@ -120,6 +127,7 @@ class oauth extends \phpbb\auth\provider\base * @param \phpbb\request\request_interface $request * @param \phpbb\user $user * @param string $auth_provider_oauth_token_storage_table + * @param string $auth_provider_oauth_state_table * @param string $auth_provider_oauth_token_account_assoc * @param \phpbb\di\service_collection $service_providers Contains \phpbb\auth\provider\oauth\service_interface * @param string $users_table @@ -127,7 +135,7 @@ class oauth extends \phpbb\auth\provider\base * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_state_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; @@ -135,6 +143,7 @@ class oauth extends \phpbb\auth\provider\base $this->request = $request; $this->user = $user; $this->auth_provider_oauth_token_storage_table = $auth_provider_oauth_token_storage_table; + $this->auth_provider_oauth_state_table = $auth_provider_oauth_state_table; $this->auth_provider_oauth_token_account_assoc = $auth_provider_oauth_token_account_assoc; $this->service_providers = $service_providers; $this->users_table = $users_table; @@ -188,7 +197,7 @@ class oauth extends \phpbb\auth\provider\base // Get the service credentials for the given service $service_credentials = $this->service_providers[$service_name]->get_service_credentials(); - $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); + $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table); $query = 'mode=login&login=external&oauth_service=' . $service_name_original; $service = $this->get_service($service_name_original, $storage, $service_credentials, $query, $this->service_providers[$service_name]->get_auth_scope()); @@ -456,7 +465,7 @@ class oauth extends \phpbb\auth\provider\base */ protected function link_account_login_link(array $link_data, $service_name) { - $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); + $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table); // Check for an access token, they should have one if (!$storage->has_access_token_by_session($service_name)) @@ -499,7 +508,7 @@ class oauth extends \phpbb\auth\provider\base */ protected function link_account_auth_link(array $link_data, $service_name) { - $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); + $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table); $query = 'i=ucp_auth_link&mode=auth_link&link=1&oauth_service=' . strtolower($link_data['oauth_service']); $service_credentials = $this->service_providers[$service_name]->get_service_credentials(); $scopes = $this->service_providers[$service_name]->get_auth_scope(); @@ -544,7 +553,7 @@ class oauth extends \phpbb\auth\provider\base public function logout($data, $new_session) { // Clear all tokens belonging to the user - $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); + $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table); $storage->clearAllTokens(); return; @@ -627,7 +636,7 @@ class oauth extends \phpbb\auth\provider\base // Clear all tokens belonging to the user on this servce $service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']); - $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); + $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table); $storage->clearToken($service_name); } } diff --git a/phpBB/phpbb/auth/provider/oauth/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php index 9b6afae255..e922342ef6 100644 --- a/phpBB/phpbb/auth/provider/oauth/token_storage.php +++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php @@ -17,6 +17,7 @@ use OAuth\OAuth1\Token\StdOAuth1Token; use OAuth\Common\Token\TokenInterface; use OAuth\Common\Storage\TokenStorageInterface; use OAuth\Common\Storage\Exception\TokenNotFoundException; +use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException; /** * OAuth storage wrapper for phpbb's cache @@ -42,25 +43,39 @@ class token_storage implements TokenStorageInterface * * @var string */ - protected $auth_provider_oauth_table; + protected $oauth_token_table; + + /** + * OAuth state table + * + * @var string + */ + protected $oauth_state_table; /** * @var object|TokenInterface */ protected $cachedToken; + /** + * @var string + */ + protected $cachedState; + /** * Creates token storage for phpBB. * * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\user $user - * @param string $auth_provider_oauth_table + * @param string $oauth_token_table + * @param string $oauth_state_table */ - public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $auth_provider_oauth_table) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $oauth_token_table, $oauth_state_table) { $this->db = $db; $this->user = $user; - $this->auth_provider_oauth_table = $auth_provider_oauth_table; + $this->oauth_token_table = $oauth_token_table; + $this->oauth_state_table = $oauth_state_table; } /** @@ -104,9 +119,11 @@ class token_storage implements TokenStorageInterface 'session_id' => $this->user->data['session_id'], ); - $sql = 'INSERT INTO ' . $this->auth_provider_oauth_table . ' + $sql = 'INSERT INTO ' . $this->oauth_token_table . ' ' . $this->db->sql_build_array('INSERT', $data); $this->db->sql_query($sql); + + return $this; } /** @@ -143,7 +160,7 @@ class token_storage implements TokenStorageInterface $this->cachedToken = null; - $sql = 'DELETE FROM ' . $this->auth_provider_oauth_table . ' + $sql = 'DELETE FROM ' . $this->oauth_token_table . ' WHERE user_id = ' . (int) $this->user->data['user_id'] . " AND provider = '" . $this->db->sql_escape($service) . "'"; @@ -153,6 +170,8 @@ class token_storage implements TokenStorageInterface } $this->db->sql_query($sql); + + return $this; } /** @@ -162,7 +181,123 @@ class token_storage implements TokenStorageInterface { $this->cachedToken = null; - $sql = 'DELETE FROM ' . $this->auth_provider_oauth_table . ' + $sql = 'DELETE FROM ' . $this->oauth_token_table . ' + WHERE user_id = ' . (int) $this->user->data['user_id']; + + if ((int) $this->user->data['user_id'] === ANONYMOUS) + { + $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'"; + } + + $this->db->sql_query($sql); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function storeAuthorizationState($service, $state) + { + $service = $this->get_service_name_for_db($service); + + $this->cachedState = $state; + + $data = array( + 'user_id' => (int) $this->user->data['user_id'], + 'provider' => $service, + 'oauth_state' => $state, + 'session_id' => $this->user->data['session_id'], + ); + + $sql = 'INSERT INTO ' . $this->oauth_state_table . ' + ' . $this->db->sql_build_array('INSERT', $data); + $this->db->sql_query($sql); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function hasAuthorizationState($service) + { + $service = $this->get_service_name_for_db($service); + + if ($this->cachedState) + { + return true; + } + + $data = array( + 'user_id' => (int) $this->user->data['user_id'], + 'provider' => $service, + ); + + if ((int) $this->user->data['user_id'] === ANONYMOUS) + { + $data['session_id'] = $this->user->data['session_id']; + } + + return (bool) $this->get_state_row($data); + } + + /** + * {@inheritdoc} + */ + public function retrieveAuthorizationState($service) + { + $service = $this->get_service_name_for_db($service); + + if ($this->cachedState) + { + return $this->cachedState; + } + + $data = array( + 'user_id' => (int) $this->user->data['user_id'], + 'provider' => $service, + ); + + if ((int) $this->user->data['user_id'] === ANONYMOUS) + { + $data['session_id'] = $this->user->data['session_id']; + } + + return $this->get_state_row($data); + } + + /** + * {@inheritdoc} + */ + public function clearAuthorizationState($service) + { + $service = $this->get_service_name_for_db($service); + + $this->cachedState = null; + + $sql = 'DELETE FROM ' . $this->oauth_state_table . ' + WHERE user_id = ' . (int) $this->user->data['user_id'] . " + AND provider = '" . $this->db->sql_escape($service) . "'"; + + if ((int) $this->user->data['user_id'] === ANONYMOUS) + { + $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'"; + } + + $this->db->sql_query($sql); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function clearAllAuthorizationStates() + { + $this->cachedState = null; + + $sql = 'DELETE FROM ' . $this->oauth_state_table . ' WHERE user_id = ' . (int) $this->user->data['user_id']; if ((int) $this->user->data['user_id'] === ANONYMOUS) @@ -171,6 +306,8 @@ class token_storage implements TokenStorageInterface } $this->db->sql_query($sql); + + return $this; } /** @@ -185,7 +322,7 @@ class token_storage implements TokenStorageInterface return; } - $sql = 'UPDATE ' . $this->auth_provider_oauth_table . ' + $sql = 'UPDATE ' . $this->oauth_token_table . ' SET ' . $this->db->sql_build_array('UPDATE', array( 'user_id' => (int) $user_id )) . ' @@ -217,6 +354,29 @@ class token_storage implements TokenStorageInterface return $this->_has_acess_token($data); } + /** + * Checks to see if a state exists solely by the session_id of the user + * + * @param string $service The name of the OAuth service + * @return bool true if they have state, false if they don't + */ + public function has_state_by_session($service) + { + $service = $this->get_service_name_for_db($service); + + if ($this->cachedState) + { + return true; + } + + $data = array( + 'session_id' => $this->user->data['session_id'], + 'provider' => $service, + ); + + return (bool) $this->get_state_row($data); + } + /** * A helper function that performs the query for has access token functions * @@ -245,6 +405,23 @@ class token_storage implements TokenStorageInterface return $this->_retrieve_access_token($data); } + public function retrieve_state_by_session($service) + { + $service = $this->get_service_name_for_db($service); + + if ($this->cachedState) + { + return $this->cachedState; + } + + $data = array( + 'session_id' => $this->user->data['session_id'], + 'provider' => $service, + ); + + return $this->_retrieve_state($data); + } + /** * A helper function that performs the query for retrieve access token functions * Also checks if the token is a valid token @@ -275,6 +452,26 @@ class token_storage implements TokenStorageInterface return $token; } + /** + * A helper function that performs the query for retrieve state functions + * + * @param array $data + * @return mixed + * @throws \OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException + */ + protected function _retrieve_state($data) + { + $row = $this->get_state_row($data); + + if (!$row) + { + throw new AuthorizationStateNotFoundException(); + } + + $this->cachedState = $row['oauth_state']; + return $this->cachedState; + } + /** * A helper function that performs the query for retrieving an access token * @@ -283,7 +480,24 @@ class token_storage implements TokenStorageInterface */ protected function get_access_token_row($data) { - $sql = 'SELECT oauth_token FROM ' . $this->auth_provider_oauth_table . ' + $sql = 'SELECT oauth_token FROM ' . $this->oauth_token_table . ' + WHERE ' . $this->db->sql_build_array('SELECT', $data); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + return $row; + } + + /** + * A helper function that performs the query for retrieving a state + * + * @param array $data + * @return mixed + */ + protected function get_state_row($data) + { + $sql = 'SELECT oauth_state FROM ' . $this->oauth_state_table . ' WHERE ' . $this->db->sql_build_array('SELECT', $data); $result = $this->db->sql_query($sql); $row = $this->db->sql_fetchrow($result); diff --git a/phpBB/phpbb/db/migration/data/v320/oauth_states.php b/phpBB/phpbb/db/migration/data/v320/oauth_states.php new file mode 100644 index 0000000000..22ab2dabb3 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/oauth_states.php @@ -0,0 +1,56 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class oauth_states extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\auth_provider_oauth'); + } + + public function effectively_installed() + { + return $this->db_tools->sql_table_exists($this->table_prefix . 'oauth_states'); + } + + public function update_schema() + { + return array( + 'add_tables' => array( + $this->table_prefix . 'oauth_states' => array( + 'COLUMNS' => array( + 'user_id' => array('UINT', 0), + 'session_id' => array('CHAR:32', ''), + 'provider' => array('VCHAR', ''), + 'oauth_state' => array('VCHAR', ''), + ), + 'KEYS' => array( + 'user_id' => array('INDEX', 'user_id'), + 'provider' => array('INDEX', 'provider'), + ), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_tables' => array( + $this->table_prefix . 'oauth_states', + ), + ); + } +} -- cgit v1.2.1 From 59481da9dac23ccb8382202eb6623c3fc71030a0 Mon Sep 17 00:00:00 2001 From: Erwan Nader Date: Sun, 3 Jan 2016 11:29:53 +0100 Subject: [ticket/14386] Use of sys_get_temp_dir() PHPBB3-14386 --- phpBB/phpbb/files/types/remote.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 44feab0ece..4f4ce15c18 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -200,8 +200,7 @@ class remote extends base return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA'); } - $tmp_path = (!$this->php_ini->getBool('safe_mode')) ? false : $this->phpbb_root_path . 'cache'; - $filename = tempnam($tmp_path, unique_id() . '-'); + $filename = tempnam(sys_get_temp_dir(), unique_id() . '-'); if (!($fp = @fopen($filename, 'wb'))) { -- cgit v1.2.1 From 73e6e5b77faadbb7676961bf38122d669de111db Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 3 Dec 2015 17:50:29 +0100 Subject: [ticket/13454] Remove unused variables This is the first part of the changes. More to come. PHPBB3-13454 --- phpBB/phpbb/captcha/gd.php | 5 +---- phpBB/phpbb/captcha/gd_wave.php | 5 +---- phpBB/phpbb/captcha/plugins/captcha_abstract.php | 8 +++----- phpBB/phpbb/captcha/plugins/gd.php | 11 ++--------- phpBB/phpbb/captcha/plugins/gd_wave.php | 2 +- phpBB/phpbb/db/driver/oracle.php | 2 -- phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php | 2 +- .../db/migration/data/v31x/update_custom_bbcodes_with_idn.php | 1 - phpBB/phpbb/files/types/remote.php | 1 - .../phpbb/install/console/command/install/config/validate.php | 2 +- phpBB/phpbb/install/controller/install.php | 1 - phpBB/phpbb/report/report_handler_post.php | 2 +- phpBB/phpbb/template/twig/node/includejs.php | 2 -- phpBB/phpbb/textformatter/s9e/parser.php | 3 --- phpBB/phpbb/textformatter/s9e/renderer.php | 1 - 15 files changed, 11 insertions(+), 37 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/captcha/gd.php b/phpBB/phpbb/captcha/gd.php index 652df28f8a..e9538439c6 100644 --- a/phpBB/phpbb/captcha/gd.php +++ b/phpBB/phpbb/captcha/gd.php @@ -97,13 +97,12 @@ class gd if ($config['captcha_gd_3d_noise']) { - $xoffset = mt_rand(0,9); $noise_bitmaps = $this->captcha_noise_bg_bitmaps(); for ($i = 0; $i < $code_len; ++$i) { $noise[$i] = new char_cube3d($noise_bitmaps, mt_rand(1, sizeof($noise_bitmaps['data']))); - list($min, $max) = $noise[$i]->range(); + $noise[$i]->range(); //$box = $noise[$i]->dimensions($sizes[$i]); } $xoffset = 0; @@ -151,8 +150,6 @@ class gd */ function wave($img) { - global $config; - $period_x = mt_rand(12,18); $period_y = mt_rand(7,14); $amp_x = mt_rand(5,10); diff --git a/phpBB/phpbb/captcha/gd_wave.php b/phpBB/phpbb/captcha/gd_wave.php index d48fc753a5..f2ec4137d2 100644 --- a/phpBB/phpbb/captcha/gd_wave.php +++ b/phpBB/phpbb/captcha/gd_wave.php @@ -23,8 +23,6 @@ class gd_wave function execute($code, $seed) { - global $starttime; - // seed the random generator mt_srand($seed); @@ -77,7 +75,6 @@ class gd_wave // TODO $background = imagecolorallocate($img, mt_rand(155, 255), mt_rand(155, 255), mt_rand(155, 255)); imagefill($img, 0, 0, $background); - $black = imagecolorallocate($img, 0, 0, 0); $random = array(); $fontcolors = array(); @@ -155,7 +152,7 @@ class gd_wave // rather than recalculating from absolute coordinates // What we cache into the $img_buffer contains the raised text coordinates. $img_pos_prev = $img_buffer[0][0] = array($box['upper_left']['x'], $box['upper_left']['y']); - $cur_height = $prev_height = $this->wave_height(0, 0, $subdivision_factor); + $prev_height = $this->wave_height(0, 0, $subdivision_factor); $full_x = $plane_x * $subdivision_factor; $full_y = $plane_y * $subdivision_factor; diff --git a/phpBB/phpbb/captcha/plugins/captcha_abstract.php b/phpBB/phpbb/captcha/plugins/captcha_abstract.php index b29f144f97..357de0e0a5 100644 --- a/phpBB/phpbb/captcha/plugins/captcha_abstract.php +++ b/phpBB/phpbb/captcha/plugins/captcha_abstract.php @@ -34,7 +34,7 @@ abstract class captcha_abstract function init($type) { - global $config, $db, $user, $request; + global $config, $request; // read input $this->confirm_id = $request->variable('confirm_id', ''); @@ -56,8 +56,6 @@ abstract class captcha_abstract function execute_demo() { - global $user; - $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); $this->seed = hexdec(substr(unique_id(), 4, 10)); @@ -117,7 +115,7 @@ abstract class captcha_abstract function get_demo_template($id) { - global $config, $user, $template, $request, $phpbb_admin_path, $phpEx; + global $config, $template, $request, $phpbb_admin_path, $phpEx; $variables = ''; @@ -153,7 +151,7 @@ abstract class captcha_abstract function garbage_collect($type) { - global $db, $config; + global $db; $sql = 'SELECT DISTINCT c.session_id FROM ' . CONFIRM_TABLE . ' c diff --git a/phpBB/phpbb/captcha/plugins/gd.php b/phpBB/phpbb/captcha/plugins/gd.php index 1727dcc1bb..831e5bcfdf 100644 --- a/phpBB/phpbb/captcha/plugins/gd.php +++ b/phpBB/phpbb/captcha/plugins/gd.php @@ -53,18 +53,11 @@ class gd extends captcha_abstract function acp_page($id, &$module) { - global $db, $user, $auth, $template, $phpbb_log, $request; - global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; + global $user, $template, $phpbb_log, $request; + global $config; $user->add_lang('acp/board'); - $config_vars = array( - 'enable_confirm' => 'REG_ENABLE', - 'enable_post_confirm' => 'POST_ENABLE', - 'confirm_refresh' => 'CONFIRM_REFRESH', - 'captcha_gd' => 'CAPTCHA_GD', - ); - $module->tpl_name = 'captcha_gd_acp'; $module->page_title = 'ACP_VC_SETTINGS'; $form_key = 'acp_captcha'; diff --git a/phpBB/phpbb/captcha/plugins/gd_wave.php b/phpBB/phpbb/captcha/plugins/gd_wave.php index e1d44df778..bde46f8815 100644 --- a/phpBB/phpbb/captcha/plugins/gd_wave.php +++ b/phpBB/phpbb/captcha/plugins/gd_wave.php @@ -35,7 +35,7 @@ class gd_wave extends captcha_abstract function acp_page($id, &$module) { - global $config, $db, $template, $user; + global $user; trigger_error($user->lang['CAPTCHA_NO_OPTIONS'] . adm_back_link($module->u_action)); } diff --git a/phpBB/phpbb/db/driver/oracle.php b/phpBB/phpbb/db/driver/oracle.php index 89e1b68aac..54238a15ef 100644 --- a/phpBB/phpbb/db/driver/oracle.php +++ b/phpBB/phpbb/db/driver/oracle.php @@ -84,8 +84,6 @@ class oracle extends \phpbb\db\driver\driver * but I assume its because the Oracle extension provides a direct method to access it * without a query. */ - - $use_cache = false; /* global $cache; diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php index 9f6e3efb91..084d00a13a 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php @@ -118,7 +118,7 @@ class release_3_0_5_rc1 extends container_aware_migration $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); + $this->db->sql_fetchrow($result); while ($row = $this->db->sql_fetchrow($result)) { diff --git a/phpBB/phpbb/db/migration/data/v31x/update_custom_bbcodes_with_idn.php b/phpBB/phpbb/db/migration/data/v31x/update_custom_bbcodes_with_idn.php index 854ed1f568..14b7b7b0f6 100644 --- a/phpBB/phpbb/db/migration/data/v31x/update_custom_bbcodes_with_idn.php +++ b/phpBB/phpbb/db/migration/data/v31x/update_custom_bbcodes_with_idn.php @@ -45,7 +45,6 @@ class update_custom_bbcodes_with_idn extends \phpbb\db\migration\migration $sql_ary = array(); while ($row = $this->db->sql_fetchrow($result)) { - $data = array(); if (preg_match('/(URL|LOCAL_URL|RELATIVE_URL)/', $row['bbcode_match'])) { $data = $bbcodes->build_regexp($row['bbcode_match'], $row['bbcode_tpl']); diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 4f4ce15c18..33cbfb00ae 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -97,7 +97,6 @@ class remote extends base $url['path'] = implode('', $url['path']); $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : ''); - $filename = $url['path']; $filesize = 0; $remote_max_filesize = $this->get_max_file_size(); diff --git a/phpBB/phpbb/install/console/command/install/config/validate.php b/phpBB/phpbb/install/console/command/install/config/validate.php index 19b6f99a8b..3bbbc23e34 100644 --- a/phpBB/phpbb/install/console/command/install/config/validate.php +++ b/phpBB/phpbb/install/console/command/install/config/validate.php @@ -117,7 +117,7 @@ class validate extends \phpbb\console\command\command try { - $config = $processor->processConfiguration($configuration, $config); + $processor->processConfiguration($configuration, $config); } catch (Exception $e) { diff --git a/phpBB/phpbb/install/controller/install.php b/phpBB/phpbb/install/controller/install.php index 8bf9062b08..b987d91c6a 100644 --- a/phpBB/phpbb/install/controller/install.php +++ b/phpBB/phpbb/install/controller/install.php @@ -19,7 +19,6 @@ use phpbb\install\helper\navigation\navigation_provider; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\Response; use phpbb\install\helper\iohandler\factory; -use phpbb\install\controller\helper; use phpbb\template\template; use phpbb\request\request_interface; use phpbb\install\installer; diff --git a/phpBB/phpbb/report/report_handler_post.php b/phpBB/phpbb/report/report_handler_post.php index ce4ed67d27..5574a16dc0 100644 --- a/phpBB/phpbb/report/report_handler_post.php +++ b/phpBB/phpbb/report/report_handler_post.php @@ -66,7 +66,7 @@ class report_handler_post extends report_handler 'reported_post_enable_magic_url' => $this->report_data['enable_magic_url'], ); - $report_id = $this->create_report($report_data); + $this->create_report($report_data); $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_reported = 1 diff --git a/phpBB/phpbb/template/twig/node/includejs.php b/phpBB/phpbb/template/twig/node/includejs.php index 0f67f9ff60..e77f2afeed 100644 --- a/phpBB/phpbb/template/twig/node/includejs.php +++ b/phpBB/phpbb/template/twig/node/includejs.php @@ -28,8 +28,6 @@ class includejs extends \phpbb\template\twig\node\includeasset */ protected function append_asset(\Twig_Compiler $compiler) { - $config = $this->environment->get_phpbb_config(); - $compiler ->raw("\n"; + } + + return $output; + } +} diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 6e75403159..709505a75f 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -13,6 +13,8 @@ namespace phpbb\template\twig; +use phpbb\template\assets_bag; + class environment extends \Twig_Environment { /** @var \phpbb\config\config */ @@ -39,6 +41,9 @@ class environment extends \Twig_Environment /** @var array **/ protected $namespace_look_up_order = array('__main__'); + /** @var assets_bag */ + protected $assets_bag; + /** * Constructor * @@ -63,6 +68,8 @@ class environment extends \Twig_Environment $this->phpbb_root_path = $this->phpbb_path_helper->get_phpbb_root_path(); $this->web_root_path = $this->phpbb_path_helper->get_web_root_path(); + $this->assets_bag = new assets_bag(); + $options = array_merge(array( 'cache' => (defined('IN_INSTALL')) ? false : $cache_path, 'debug' => false, @@ -150,6 +157,16 @@ class environment extends \Twig_Environment return $this->phpbb_path_helper; } + /** + * Gets the assets bag + * + * @return assets_bag + */ + public function get_assets_bag() + { + return $this->assets_bag; + } + /** * Get the namespace look up order * @@ -173,6 +190,43 @@ class environment extends \Twig_Environment return $this; } + /** + * {@inheritdoc} + */ + public function render($name, array $context = []) + { + $output = parent::render($name, $context); + + return $this->inject_assets($output); + } + + /** + * {@inheritdoc} + */ + public function display($name, array $context = []) + { + ob_start(); + parent::display($name, $context); + $output = ob_get_clean(); + + echo $this->inject_assets($output); + } + + /** + * Injects the assets (from INCLUDECSS/JS) in the output. + * + * @param string $output + * + * @return string + */ + private function inject_assets($output) + { + $output = str_replace('__STYLESHEETS_PLACEHOLDER__', $this->assets_bag->get_stylesheets_content(), $output); + $output = str_replace('__SCRIPTS_PLACEHOLDER__', $this->assets_bag->get_scripts_content(), $output); + + return $output; + } + /** * Loads a template by name. * diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php index 324823b8d7..3d3c6e4df8 100644 --- a/phpBB/phpbb/template/twig/node/includeasset.php +++ b/phpBB/phpbb/template/twig/node/includeasset.php @@ -49,33 +49,20 @@ abstract class includeasset extends \Twig_Node ->write("\$local_file = \$this->getEnvironment()->findTemplate(\$asset_path);\n") ->write("\$asset->set_path(\$local_file, true);\n") ->outdent() - ->write("\$asset->add_assets_version('{$config['assets_version']}');\n") - ->write("\$asset_file = \$asset->get_url();\n") ->write("}\n") + ->write("\$asset->add_assets_version('{$config['assets_version']}');\n") ->outdent() ->write("}\n") - ->write("\$context['definition']->append('{$this->get_definition_name()}', '") - ; - - $this->append_asset($compiler); - - $compiler - ->raw("\n');\n") + ->write("\$context['definition']->set('STYLESHEETS', '__STYLESHEETS_PLACEHOLDER__');\n") + ->write("\$context['definition']->set('SCRIPTS', '__SCRIPTS_PLACEHOLDER__');\n") + ->write("\$this->getEnvironment()->get_assets_bag()->add_{$this->get_setters_name()}(\$asset);") ; } /** - * Get the definition name + * Get the name of the assets bag setter * - * @return string (e.g. 'SCRIPTS') - */ - abstract public function get_definition_name(); - - /** - * Append the output code for the asset - * - * @param \Twig_Compiler A Twig_Compiler instance - * @return null + * @return string (e.g. 'script') */ - abstract protected function append_asset(\Twig_Compiler $compiler); + abstract public function get_setters_name(); } diff --git a/phpBB/phpbb/template/twig/node/includecss.php b/phpBB/phpbb/template/twig/node/includecss.php index 2dac154036..2e97d4972d 100644 --- a/phpBB/phpbb/template/twig/node/includecss.php +++ b/phpBB/phpbb/template/twig/node/includecss.php @@ -18,20 +18,8 @@ class includecss extends \phpbb\template\twig\node\includeasset /** * {@inheritdoc} */ - public function get_definition_name() + public function get_setters_name() { - return 'STYLESHEETS'; - } - - /** - * {@inheritdoc} - */ - public function append_asset(\Twig_Compiler $compiler) - { - $compiler - ->raw("raw("\$asset_file . '\"") - ->raw(' rel="stylesheet" type="text/css" media="screen" />') - ; + return 'stylesheet'; } } diff --git a/phpBB/phpbb/template/twig/node/includejs.php b/phpBB/phpbb/template/twig/node/includejs.php index e77f2afeed..505b49757b 100644 --- a/phpBB/phpbb/template/twig/node/includejs.php +++ b/phpBB/phpbb/template/twig/node/includejs.php @@ -18,20 +18,8 @@ class includejs extends \phpbb\template\twig\node\includeasset /** * {@inheritdoc} */ - public function get_definition_name() + public function get_setters_name() { - return 'SCRIPTS'; - } - - /** - * {@inheritdoc} - */ - protected function append_asset(\Twig_Compiler $compiler) - { - $compiler - ->raw("\n") - ; + return 'script'; } } -- cgit v1.2.1 From e91b1fa464c01d2ebf9fc9c732e8d2810223bc00 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 25 Jan 2016 00:31:13 +0100 Subject: =?UTF-8?q?[ticket/13717]=C2=A0Fix=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHPBB3-13717 --- phpBB/phpbb/template/twig/environment.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 709505a75f..5660ddc3a4 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -205,8 +205,23 @@ class environment extends \Twig_Environment */ public function display($name, array $context = []) { + $level = ob_get_level(); ob_start(); - parent::display($name, $context); + + try + { + parent::display($name, $context); + } + catch (\Exception $e) + { + while (ob_get_level() > $level) + { + ob_end_clean(); + } + + throw $e; + } + $output = ob_get_clean(); echo $this->inject_assets($output); -- cgit v1.2.1 From 7d2a58e27100e5c776b44223e2cc6837c293db02 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Tue, 26 Jan 2016 11:45:06 -0800 Subject: [ticket/14434] Schema generator should ignore migration helpers PHPBB3-14434 --- phpBB/phpbb/db/migration/schema_generator.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/schema_generator.php b/phpBB/phpbb/db/migration/schema_generator.php index 7003844bc4..55ab4452ed 100644 --- a/phpBB/phpbb/db/migration/schema_generator.php +++ b/phpBB/phpbb/db/migration/schema_generator.php @@ -77,8 +77,18 @@ class schema_generator $check_dependencies = true; while (!empty($migrations)) { - foreach ($migrations as $migration_class) + foreach ($migrations as $key => $migration_class) { + if (class_exists($migration_class)) + { + $reflector = new \ReflectionClass($migration_class); + if (!$reflector->implementsInterface('\phpbb\db\migration\migration_interface') || !$reflector->isInstantiable()) + { + unset($migrations[$key]); + continue; + } + } + $open_dependencies = array_diff($migration_class::depends_on(), $tree); if (empty($open_dependencies)) -- cgit v1.2.1 From cc38bf550b6d044938532d96a98dd92767e69b61 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 25 Jan 2016 13:50:23 +0100 Subject: [ticket/14129] Caches extensions autoloaders PHPBB3-14129 --- phpBB/phpbb/cache/driver/base.php | 1 + phpBB/phpbb/di/container_builder.php | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/base.php b/phpBB/phpbb/cache/driver/base.php index 55cd4668de..85762c4d95 100644 --- a/phpBB/phpbb/cache/driver/base.php +++ b/phpBB/phpbb/cache/driver/base.php @@ -49,6 +49,7 @@ abstract class base implements \phpbb\cache\driver\driver_interface $this->remove_dir($fileInfo->getPathname()); } else if (strpos($filename, 'container_') === 0 || + strpos($filename, 'autoload_') === 0 || strpos($filename, 'url_matcher') === 0 || strpos($filename, 'url_generator') === 0 || strpos($filename, 'sql_') === 0 || diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 433847b285..9583da14f5 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -135,6 +135,11 @@ class container_builder $config_cache = new ConfigCache($container_filename, defined('DEBUG')); if ($this->use_cache && $config_cache->isFresh()) { + if ($this->use_extensions) + { + require($this->get_autoload_filename()); + } + require($config_cache->getPath()); $this->container = new \phpbb_cache_container(); } @@ -405,6 +410,15 @@ class container_builder $extensions = $ext_container->get('ext.manager')->all_enabled(); // Load each extension found + $autoloaders = ' $path) { $extension_class = '\\' . str_replace('/', '\\', $ext_name) . '\\di\\extension'; @@ -420,9 +434,14 @@ class container_builder $filename = $path . 'vendor/autoload.php'; if (file_exists($filename)) { - require $filename; + $autoloaders .= "require('{$filename}');\n"; } } + + $configCache = new ConfigCache($this->get_autoload_filename(), false); + $configCache->write($autoloaders); + + require($this->get_autoload_filename()); } else { @@ -539,6 +558,16 @@ class container_builder return $this->get_cache_dir() . 'container_' . md5($this->phpbb_root_path) . '.' . $this->php_ext; } + /** + * Get the filename under which the dumped extensions autoloader will be stored. + * + * @return string Path for dumped extensions autoloader + */ + protected function get_autoload_filename() + { + return $this->get_cache_dir() . 'autoload_' . md5($this->phpbb_root_path) . '.' . $this->php_ext; + } + /** * Return the name of the current environment. * -- cgit v1.2.1 From f5ca8c363bbd6776e9be8d2e05c3cf54685b0a59 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Tue, 26 Jan 2016 22:32:08 +0100 Subject: [ticket/14432] Adds a method to get raw language values PHPBB3-14432 --- phpBB/phpbb/language/language.php | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/language/language.php b/phpBB/phpbb/language/language.php index 382d4db89e..42429c2c07 100644 --- a/phpBB/phpbb/language/language.php +++ b/phpBB/phpbb/language/language.php @@ -246,14 +246,14 @@ class language } /** - * Act like lang() but takes a key and an array of parameters instead of using variadic + * Returns the raw value associated to a language key or the language key no translation is available. + * No parameter substitution is performed, can be a string or an array. * * @param string|array $key Language key - * @param array $args Parameters * * @return array|string */ - public function lang_array($key, $args = array()) + public function lang_raw($key) { // Load common language files if they not loaded yet if (!$this->common_language_files_loaded) @@ -281,6 +281,26 @@ class language return $key; } + return $lang; + } + + /** + * Act like lang() but takes a key and an array of parameters instead of using variadic + * + * @param string|array $key Language key + * @param array $args Parameters + * + * @return string + */ + public function lang_array($key, $args = array()) + { + $lang = $this->lang_raw($key); + + if ($lang === $key) + { + return $key; + } + // If the language entry is a string, we simply mimic sprintf() behaviour if (is_string($lang)) { -- cgit v1.2.1 From daa92f7996f7026a12a5224a89297c9716d658a4 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 27 Jan 2016 16:51:34 +0100 Subject: [ticket/14436] Add dependency on oauth_states migration PHPBB3-14436 --- phpBB/phpbb/db/migration/data/v320/default_data_type_ids.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/default_data_type_ids.php b/phpBB/phpbb/db/migration/data/v320/default_data_type_ids.php index ecee09ce77..65e5b3fa73 100644 --- a/phpBB/phpbb/db/migration/data/v320/default_data_type_ids.php +++ b/phpBB/phpbb/db/migration/data/v320/default_data_type_ids.php @@ -17,7 +17,10 @@ class default_data_type_ids extends \phpbb\db\migration\migration { static public function depends_on() { - return array('\phpbb\db\migration\data\v320\v320a2'); + return array( + '\phpbb\db\migration\data\v320\v320a2', + '\phpbb\db\migration\data\v320\oauth_states', + ); } public function update_schema() -- cgit v1.2.1 From 47d8aeebde6f763ec7247daf0df16dd2388b25b6 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 27 Jan 2016 10:50:22 -0800 Subject: [ticket/14434] Extract migration check to a reusable method PHPBB3-14434 --- phpBB/phpbb/db/migration/schema_generator.php | 12 +++----- phpBB/phpbb/db/migrator.php | 44 +++++++++++++++++++++++++-- phpBB/phpbb/extension/base.php | 14 +-------- 3 files changed, 47 insertions(+), 23 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/schema_generator.php b/phpBB/phpbb/db/migration/schema_generator.php index 55ab4452ed..dc685bb161 100644 --- a/phpBB/phpbb/db/migration/schema_generator.php +++ b/phpBB/phpbb/db/migration/schema_generator.php @@ -79,14 +79,12 @@ class schema_generator { foreach ($migrations as $key => $migration_class) { - if (class_exists($migration_class)) + // Unset classes that do not exist or do not extend the + // abstract class phpbb\db\migration\migration + if (\phpbb\db\migrator::is_migration($migration_class) === false) { - $reflector = new \ReflectionClass($migration_class); - if (!$reflector->implementsInterface('\phpbb\db\migration\migration_interface') || !$reflector->isInstantiable()) - { - unset($migrations[$key]); - continue; - } + unset($migrations[$key]); + continue; } $open_dependencies = array_diff($migration_class::depends_on(), $tree); diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index d91860949a..563958b258 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -226,7 +226,7 @@ class migrator */ protected function try_apply($name) { - if (!class_exists($name)) + if (!class_exists($name) || !self::is_migration($name)) { $this->output_handler->write(array('MIGRATION_NOT_VALID', $name), migrator_output_handler_interface::VERBOSITY_DEBUG); return false; @@ -401,7 +401,7 @@ class migrator */ protected function try_revert($name) { - if (!class_exists($name)) + if (!class_exists($name) || !self::is_migration($name)) { return false; } @@ -719,7 +719,7 @@ class migrator return false; } - if (!class_exists($name)) + if (!class_exists($name) || !self::is_migration($name)) { return $name; } @@ -857,4 +857,42 @@ class migrator )); } } + + /** + * Check if a class is a migration. + * + * @param mixed $migration An array of migration name strings, or + * a single migration name string. + * @return bool Returns true or false for a single migration. + * If an array was received, non-migrations will + * be removed from the array, and false is returned. + */ + static public function is_migration(&$migration) + { + if (is_array($migration)) + { + foreach ($migration as $key => $name) + { + if (self::is_migration($name)) + { + continue; + } + + unset($migration[$key]); + } + } + else if (class_exists($migration)) + { + // Migration classes should extend the abstract class + // phpbb\db\migration\migration which implements the + // migration_interface and be instantiable. + $reflector = new \ReflectionClass($migration); + if ($reflector->implementsInterface('\phpbb\db\migration\migration_interface') && $reflector->isInstantiable()) + { + return true; + } + } + + return false; + } } diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index b647242b98..b05c1af8d4 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -139,19 +139,7 @@ class base implements \phpbb\extension\extension_interface // Unset classes that do not exist or do not extend the // abstract class phpbb\db\migration\migration - foreach ($migrations as $key => $migration) - { - if (class_exists($migration)) - { - $reflector = new \ReflectionClass($migration); - if ($reflector->implementsInterface('\phpbb\db\migration\migration_interface') && $reflector->isInstantiable()) - { - continue; - } - } - - unset($migrations[$key]); - } + \phpbb\db\migrator::is_migration($migrations); return $migrations; } -- cgit v1.2.1 From 3bd8a2ba196f240c5b982271af1ee8b2a2f8332b Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 27 Jan 2016 11:46:04 -0800 Subject: [ticket/14434] Remove recursion to simplify is_migration method PHPBB3-14434 --- phpBB/phpbb/db/migration/schema_generator.php | 3 +-- phpBB/phpbb/db/migrator.php | 27 ++++++--------------------- phpBB/phpbb/extension/base.php | 13 ++++++++++--- 3 files changed, 17 insertions(+), 26 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/schema_generator.php b/phpBB/phpbb/db/migration/schema_generator.php index dc685bb161..c579e25824 100644 --- a/phpBB/phpbb/db/migration/schema_generator.php +++ b/phpBB/phpbb/db/migration/schema_generator.php @@ -79,8 +79,7 @@ class schema_generator { foreach ($migrations as $key => $migration_class) { - // Unset classes that do not exist or do not extend the - // abstract class phpbb\db\migration\migration + // Unset classes that are not a valid migration if (\phpbb\db\migrator::is_migration($migration_class) === false) { unset($migrations[$key]); diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 563958b258..2f280ec5a5 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -861,31 +861,16 @@ class migrator /** * Check if a class is a migration. * - * @param mixed $migration An array of migration name strings, or - * a single migration name string. - * @return bool Returns true or false for a single migration. - * If an array was received, non-migrations will - * be removed from the array, and false is returned. + * @param string $migration A migration class name + * @return bool Return true if class is a migration, false otherwise */ - static public function is_migration(&$migration) + static public function is_migration($migration) { - if (is_array($migration)) - { - foreach ($migration as $key => $name) - { - if (self::is_migration($name)) - { - continue; - } - - unset($migration[$key]); - } - } - else if (class_exists($migration)) + if (class_exists($migration)) { // Migration classes should extend the abstract class - // phpbb\db\migration\migration which implements the - // migration_interface and be instantiable. + // phpbb\db\migration\migration (which implements the + // migration_interface) and be instantiable. $reflector = new \ReflectionClass($migration); if ($reflector->implementsInterface('\phpbb\db\migration\migration_interface') && $reflector->isInstantiable()) { diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index b05c1af8d4..abdb10df88 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -137,9 +137,16 @@ class base implements \phpbb\extension\extension_interface $migrations = $this->extension_finder->get_classes_from_files($migrations); - // Unset classes that do not exist or do not extend the - // abstract class phpbb\db\migration\migration - \phpbb\db\migrator::is_migration($migrations); + // Unset classes that are not a valid migration + foreach ($migrations as $key => $migration) + { + if (\phpbb\db\migrator::is_migration($migration) === true) + { + continue; + } + + unset($migrations[$key]); + } return $migrations; } -- cgit v1.2.1 From ae7aa5dc579f65ee2206e6ed7736d2b320bdaad1 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 27 Jan 2016 11:48:24 -0800 Subject: [ticket/14434] Fix whitespace mistakes PHPBB3-14434 --- phpBB/phpbb/extension/base.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index abdb10df88..a7531350f7 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -143,10 +143,10 @@ class base implements \phpbb\extension\extension_interface if (\phpbb\db\migrator::is_migration($migration) === true) { continue; - } + } - unset($migrations[$key]); - } + unset($migrations[$key]); + } return $migrations; } -- cgit v1.2.1 From 996441a1da472b587d367994cb6b6dcf711b027c Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 27 Jan 2016 12:24:18 -0800 Subject: [ticket/14434] Remove redundant conditional PHPBB3-14434 --- phpBB/phpbb/db/migrator.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 2f280ec5a5..8f3b860b93 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -226,7 +226,7 @@ class migrator */ protected function try_apply($name) { - if (!class_exists($name) || !self::is_migration($name)) + if (!self::is_migration($name)) { $this->output_handler->write(array('MIGRATION_NOT_VALID', $name), migrator_output_handler_interface::VERBOSITY_DEBUG); return false; @@ -401,7 +401,7 @@ class migrator */ protected function try_revert($name) { - if (!class_exists($name) || !self::is_migration($name)) + if (!self::is_migration($name)) { return false; } @@ -719,7 +719,7 @@ class migrator return false; } - if (!class_exists($name) || !self::is_migration($name)) + if (!self::is_migration($name)) { return $name; } -- cgit v1.2.1 From fc72862ca4bb5c9f9b23867173543efb899de4db Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 27 Jan 2016 12:47:31 -0800 Subject: [ticket/14434] Do not include non-migrations in CLI list PHPBB3-14434 --- phpBB/phpbb/console/command/db/list_command.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/db/list_command.php b/phpBB/phpbb/console/command/db/list_command.php index 708107b592..dfec5c7da2 100644 --- a/phpBB/phpbb/console/command/db/list_command.php +++ b/phpBB/phpbb/console/command/db/list_command.php @@ -39,6 +39,12 @@ class list_command extends \phpbb\console\command\db\migration_command foreach ($this->load_migrations() as $name) { + // Ignore non-migration files + if (\phpbb\db\migrator::is_migration($name) === false) + { + continue; + } + if ($this->migrator->migration_state($name) !== false) { $installed[] = $name; -- cgit v1.2.1 From fb1acb0ef463bc38421248497e7f0b7b271600f7 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 28 Jan 2016 07:04:55 -0800 Subject: [ticket/14434] Check migrations in the database updater task PHPBB3-14434 --- phpBB/phpbb/install/module/update_database/task/update.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index 84ec6f73f5..eb9bdc8138 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -139,6 +139,15 @@ class update extends task_base ->extension_directory('/migrations') ->get_classes(); + // Unset classes that are not a valid migration + foreach ($migrations as $key => $migration_class) + { + if (\phpbb\db\migrator::is_migration($migration_class) === false) + { + unset($migrations[$key]); + } + } + $this->migrator->set_migrations($migrations); $migration_count = count($migrations); $this->iohandler->set_task_count($migration_count, true); -- cgit v1.2.1 From 27027deb9ce2076f64dbfdecba494efe1aa523dc Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 28 Jan 2016 11:22:30 -0800 Subject: [ticket/14434] Refactored to check migrations when setting them PHPBB3-14434 --- phpBB/phpbb/console/command/db/list_command.php | 6 ------ .../phpbb/console/command/db/migration_command.php | 2 +- phpBB/phpbb/db/migrator.php | 24 +++++++++++++++++++--- phpBB/phpbb/extension/base.php | 17 +++------------ .../install/module/update_database/task/update.php | 11 +--------- 5 files changed, 26 insertions(+), 34 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/db/list_command.php b/phpBB/phpbb/console/command/db/list_command.php index dfec5c7da2..708107b592 100644 --- a/phpBB/phpbb/console/command/db/list_command.php +++ b/phpBB/phpbb/console/command/db/list_command.php @@ -39,12 +39,6 @@ class list_command extends \phpbb\console\command\db\migration_command foreach ($this->load_migrations() as $name) { - // Ignore non-migration files - if (\phpbb\db\migrator::is_migration($name) === false) - { - continue; - } - if ($this->migrator->migration_state($name) !== false) { $installed[] = $name; diff --git a/phpBB/phpbb/console/command/db/migration_command.php b/phpBB/phpbb/console/command/db/migration_command.php index d44ef8c5cb..b951560588 100644 --- a/phpBB/phpbb/console/command/db/migration_command.php +++ b/phpBB/phpbb/console/command/db/migration_command.php @@ -45,7 +45,7 @@ abstract class migration_command extends \phpbb\console\command\command $this->migrator->set_migrations($migrations); - return $migrations; + return $this->migrator->get_migrations(); } protected function finalise_update() diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 8f3b860b93..a1e93942cd 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -170,9 +170,27 @@ class migrator */ public function set_migrations($class_names) { + foreach ($class_names as $key => $class) + { + if (!self::is_migration($class)) + { + unset($class_names[$key]); + } + } + $this->migrations = $class_names; } + /** + * Get the list of available migration class names + * + * @return array Array of all migrations available to be run + */ + public function get_migrations() + { + return $this->migrations; + } + /** * Runs a single update step from the next migration to be applied. * @@ -226,7 +244,7 @@ class migrator */ protected function try_apply($name) { - if (!self::is_migration($name)) + if (!class_exists($name)) { $this->output_handler->write(array('MIGRATION_NOT_VALID', $name), migrator_output_handler_interface::VERBOSITY_DEBUG); return false; @@ -401,7 +419,7 @@ class migrator */ protected function try_revert($name) { - if (!self::is_migration($name)) + if (!class_exists($name)) { return false; } @@ -719,7 +737,7 @@ class migrator return false; } - if (!self::is_migration($name)) + if (!class_exists($name)) { return $name; } diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index a7531350f7..c7778cfed1 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -73,9 +73,7 @@ class base implements \phpbb\extension\extension_interface */ public function enable_step($old_state) { - $migrations = $this->get_migration_file_list(); - - $this->migrator->set_migrations($migrations); + $this->get_migration_file_list(); $this->migrator->update(); @@ -103,8 +101,6 @@ class base implements \phpbb\extension\extension_interface { $migrations = $this->get_migration_file_list(); - $this->migrator->set_migrations($migrations); - foreach ($migrations as $migration) { while ($this->migrator->migration_state($migration) !== false) @@ -137,16 +133,9 @@ class base implements \phpbb\extension\extension_interface $migrations = $this->extension_finder->get_classes_from_files($migrations); - // Unset classes that are not a valid migration - foreach ($migrations as $key => $migration) - { - if (\phpbb\db\migrator::is_migration($migration) === true) - { - continue; - } + $this->migrator->set_migrations($migrations); - unset($migrations[$key]); - } + $migrations = $this->migrator->get_migrations(); return $migrations; } diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index eb9bdc8138..4b2baf2c23 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -139,17 +139,8 @@ class update extends task_base ->extension_directory('/migrations') ->get_classes(); - // Unset classes that are not a valid migration - foreach ($migrations as $key => $migration_class) - { - if (\phpbb\db\migrator::is_migration($migration_class) === false) - { - unset($migrations[$key]); - } - } - $this->migrator->set_migrations($migrations); - $migration_count = count($migrations); + $migration_count = count($this->migrator->get_migrations()); $this->iohandler->set_task_count($migration_count, true); $progress_count = $this->installer_config->get('database_update_count', 0); -- cgit v1.2.1 From a649768e17d25bcf55ae539420abe4eb4b7a1ef1 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Wed, 28 Oct 2015 15:00:11 +0100 Subject: [ticket/14262] Move convertor to controller PHPBB3-14262 --- phpBB/phpbb/install/controller/helper.php | 5 +- .../install/helper/iohandler/ajax_iohandler.php | 31 ++++++++- .../install/helper/iohandler/cli_iohandler.php | 7 ++ .../install/helper/iohandler/iohandler_base.php | 8 +++ .../helper/iohandler/iohandler_interface.php | 18 +++++ .../helper/navigation/convertor_navigation.php | 78 ++++++++++++++++++++++ 6 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 phpBB/phpbb/install/helper/navigation/convertor_navigation.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/helper.php b/phpBB/phpbb/install/controller/helper.php index 2dad42b4b6..6859414236 100644 --- a/phpBB/phpbb/install/controller/helper.php +++ b/phpBB/phpbb/install/controller/helper.php @@ -160,12 +160,13 @@ class helper * Returns path from route name * * @param string $route_name + * @param array $parameters * * @return string */ - public function route($route_name) + public function route($route_name, $parameters = array()) { - $url = $this->router->generate($route_name); + $url = $this->router->generate($route_name, $parameters); return $url; } diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php index 1342ffa30f..31474ae4e9 100644 --- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -71,6 +71,11 @@ class ajax_iohandler extends iohandler_base */ protected $download; + /** + * @var array + */ + protected $redirect_url; + /** * Constructor * @@ -89,6 +94,7 @@ class ajax_iohandler extends iohandler_base $this->nav_data = array(); $this->cookies = array(); $this->download = array(); + $this->redirect_url = array(); $this->file_status = ''; parent::__construct(); @@ -130,6 +136,14 @@ class ajax_iohandler extends iohandler_base * {@inheritdoc} */ public function add_user_form_group($title, $form) + { + $this->form = $this->generate_form_render_data($title, $form); + } + + /** + * {@inheritdoc} + */ + public function generate_form_render_data($title, $form) { $this->template->assign_block_vars('options', array( 'LEGEND' => $this->language->lang($title), @@ -189,7 +203,7 @@ class ajax_iohandler extends iohandler_base 'form_install' => 'installer_form.html', )); - $this->form = $this->template->assign_display('form_install'); + return $this->template->assign_display('form_install'); } /** @@ -273,6 +287,12 @@ class ajax_iohandler extends iohandler_base $this->cookies = array(); } + if (!empty($this->redirect_url)) + { + $json_array['redirect'] = $this->redirect_url; + $this->redirect_url = array(); + } + return $json_array; } @@ -372,6 +392,15 @@ class ajax_iohandler extends iohandler_base $this->file_status = $this->template->assign_display('file_status'); } + /** + * {@inheritdoc} + */ + public function redirect($url, $use_ajax = false) + { + $this->redirect_url = array('url' => $url, 'use_ajax' => $use_ajax); + $this->send_response(); + } + /** * Callback function for language replacing * diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php index 89f3594378..7945904524 100644 --- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -289,4 +289,11 @@ class cli_iohandler extends iohandler_base public function render_update_file_status($status_array) { } + + /** + * {@inheritdoc} + */ + public function redirect($url, $use_ajax = false) + { + } } diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php index 7271fe9bc0..fed4bc101f 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php @@ -169,6 +169,14 @@ abstract class iohandler_base implements iohandler_interface $this->current_task_progress = $this->task_progress_count; } + /** + * {@inheritdoc} + */ + public function generate_form_render_data($title, $form) + { + return ''; + } + /** * Localize message. * diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php index 00aab3283e..6b3839506f 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php @@ -123,6 +123,16 @@ interface iohandler_interface */ public function add_user_form_group($title, $form); + /** + * Returns the rendering information for the form + * + * @param string $title Language variable with the title of the form + * @param array $form An array describing the required data (options etc) + * + * @return string Information to render the form + */ + public function generate_form_render_data($title, $form); + /** * Sets the number of tasks belonging to the installer in the current mode. * @@ -174,6 +184,14 @@ interface iohandler_interface */ public function add_download_link($route, $title, $msg = null); + /** + * Redirects the user to a new page + * + * @param string $url URL to redirect to + * @param bool $use_ajax Whether or not to use AJAX redirect + */ + public function redirect($url, $use_ajax = false); + /** * Renders the status of update files * diff --git a/phpBB/phpbb/install/helper/navigation/convertor_navigation.php b/phpBB/phpbb/install/helper/navigation/convertor_navigation.php new file mode 100644 index 0000000000..54cab83b1d --- /dev/null +++ b/phpBB/phpbb/install/helper/navigation/convertor_navigation.php @@ -0,0 +1,78 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\helper\navigation; + +use phpbb\install\helper\install_helper; + +class convertor_navigation implements navigation_interface +{ + /** + * @var install_helper + */ + private $install_helper; + + /** + * Constructor + * + * @param install_helper $install_helper + */ + public function __construct(install_helper $install_helper) + { + $this->install_helper = $install_helper; + } + + /** + * {@inheritdoc} + */ + public function get() + { + if (!$this->install_helper->is_phpbb_installed()) + { + return array(); + } + + return array( + 'convert' => array( + 'label' => 'CONVERT', + 'route' => 'phpbb_convert_intro', + 'order' => 3, + array( + 'intro' => array( + 'label' => 'SUB_INTRO', + 'stage' => true, + 'order' => 0, + ), + 'settings' => array( + 'label' => 'STAGE_SETTINGS', + 'stage' => true, + 'route' => 'phpbb_convert_settings', + 'order' => 1, + ), + 'convert' => array( + 'label' => 'STAGE_IN_PROGRESS', + 'stage' => true, + 'route' => 'phpbb_convert_convert', + 'order' => 2, + ), + 'finish' => array( + 'label' => 'CONVERT_COMPLETE', + 'stage' => true, + 'route' => 'phpbb_convert_finish', + 'order' => 3, + ), + ), + ), + ); + } +} -- cgit v1.2.1 From 94f87d931854bf25fb051a27be9a1883510389c4 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 2 Feb 2016 17:06:12 +0100 Subject: [ticket/14446] Add predefined placeholder variables to twig definition PHPBB3-14446 --- phpBB/phpbb/template/twig/definition.php | 5 ++++- phpBB/phpbb/template/twig/node/includeasset.php | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/definition.php b/phpBB/phpbb/template/twig/definition.php index cb3c953692..205f0e68ee 100644 --- a/phpBB/phpbb/template/twig/definition.php +++ b/phpBB/phpbb/template/twig/definition.php @@ -19,7 +19,10 @@ namespace phpbb\template\twig; class definition { /** @var array **/ - protected $definitions = array(); + protected $definitions = array( + 'SCRIPTS' => '__SCRIPTS_PLACEHOLDER__', + 'STYLESHEETS' => '__STYLESHEETS_PLACEHOLDER__' + ); /** * Get a DEFINE'd variable diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php index 3d3c6e4df8..6d50eafc9d 100644 --- a/phpBB/phpbb/template/twig/node/includeasset.php +++ b/phpBB/phpbb/template/twig/node/includeasset.php @@ -53,8 +53,6 @@ abstract class includeasset extends \Twig_Node ->write("\$asset->add_assets_version('{$config['assets_version']}');\n") ->outdent() ->write("}\n") - ->write("\$context['definition']->set('STYLESHEETS', '__STYLESHEETS_PLACEHOLDER__');\n") - ->write("\$context['definition']->set('SCRIPTS', '__SCRIPTS_PLACEHOLDER__');\n") ->write("\$this->getEnvironment()->get_assets_bag()->add_{$this->get_setters_name()}(\$asset);") ; } -- cgit v1.2.1 From debd1bb9d655106eb5454ac4687837c9323a99ae Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Tue, 2 Feb 2016 17:53:10 +0100 Subject: [ticket/14321] Clean up arcihve controller logic PHPBB3-14321 --- phpBB/phpbb/install/controller/archive_download.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/archive_download.php b/phpBB/phpbb/install/controller/archive_download.php index a0f0ba181d..eabc0a9976 100644 --- a/phpBB/phpbb/install/controller/archive_download.php +++ b/phpBB/phpbb/install/controller/archive_download.php @@ -46,9 +46,9 @@ class archive_download */ public function conflict_archive() { - $filename = $this->installer_config->get('update_file_conflict_archive', false); + $filename = $this->installer_config->get('update_file_conflict_archive', ''); - if (!$filename) + if (empty($filename)) { throw new http_exception(404, 'URL_NOT_FOUND'); } @@ -65,7 +65,7 @@ class archive_download { $filename = $this->installer_config->get('update_file_archive', ''); - if (!$filename) + if (empty($filename)) { throw new http_exception(404, 'URL_NOT_FOUND'); } -- cgit v1.2.1 From 8f4889da58e0aa4779ec6bf7c0e747c26a13aee3 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Tue, 2 Feb 2016 17:16:15 +0100 Subject: [ticket/14445] Force refresh before schema generation PHPBB3-14445 --- phpBB/phpbb/install/helper/config.php | 6 +++--- .../install/module/install_database/task/create_schema.php | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php index 0f0840f470..ab5af86320 100644 --- a/phpBB/phpbb/install/helper/config.php +++ b/phpBB/phpbb/install/helper/config.php @@ -157,10 +157,10 @@ class config { if ($this->system_data['max_execution_time'] <= 0) { - return 1; + return PHP_INT_MAX; } - return ($this->system_data['start_time'] + $this->system_data['max_execution_time']) - time(); + return ($this->system_data['start_time'] + $this->system_data['max_execution_time']) - microtime(true); } /** @@ -430,7 +430,7 @@ class config $this->system_data['max_execution_time'] = $execution_time; // Set start time - $this->system_data['start_time'] = time(); + $this->system_data['start_time'] = microtime(true); // Get memory limit $this->system_data['memory_limit'] = $this->php_ini->getBytes('memory_limit'); diff --git a/phpBB/phpbb/install/module/install_database/task/create_schema.php b/phpBB/phpbb/install/module/install_database/task/create_schema.php index cabb78787f..a5635d5dbe 100644 --- a/phpBB/phpbb/install/module/install_database/task/create_schema.php +++ b/phpBB/phpbb/install/module/install_database/task/create_schema.php @@ -13,6 +13,8 @@ namespace phpbb\install\module\install_database\task; +use phpbb\install\exception\resource_limit_reached_exception; + /** * Create database schema */ @@ -106,6 +108,17 @@ class create_schema extends \phpbb\install\task_base */ public function run() { + // As this task may take a large amount of time to complete refreshing the page might be necessary for some + // server configurations with limited resources + if (!$this->config->get('pre_schema_forced_refresh')) + { + if ($this->config->get_time_remaining() < 5) + { + $this->config->set('pre_schema_forced_refresh', true); + throw new resource_limit_reached_exception(); + } + } + $this->db->sql_return_on_error(true); $dbms = $this->config->get('dbms'); -- cgit v1.2.1 From cec63974c393b71770eae7d740e136b43ed1c78f Mon Sep 17 00:00:00 2001 From: Scott Dutton Date: Mon, 25 Jan 2016 21:45:43 +0000 Subject: [ticket/14431] Remote avatar uploading replace the 3.1 way with guzzle Adds guzzle as a dependency Removed a test as it wont wont with guzzle (as far as I know) PHPBB3-14431 --- phpBB/phpbb/files/types/remote.php | 122 ++++++------------------------------- 1 file changed, 19 insertions(+), 103 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index d311face98..e990149501 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -86,19 +86,6 @@ class remote extends base $url = parse_url($upload_url); - $default_port = 80; - $hostname = $url['host']; - - if ($url['scheme'] == 'https') - { - $default_port = 443; - $hostname = 'tls://' . $url['host']; - } - - $host = $url['host']; - $path = $url['path']; - $port = (!empty($url['port'])) ? (int) $url['port'] : $default_port; - $upload_ary['type'] = 'application/octet-stream'; $url['path'] = explode('.', $url['path']); @@ -110,103 +97,32 @@ class remote extends base $remote_max_filesize = $this->get_max_file_size(); - $errno = 0; - $errstr = ''; - - if (!($fsock = @fsockopen($hostname, $port, $errno, $errstr))) - { + $client = new \Guzzle\Http\Client([ + 'timeout' => $this->upload->upload_timeout, + 'connect_timeout' => $this->upload->upload_timeout, + ]); + + try { + $response = $client->get($upload_url)->send(); + } catch (\Guzzle\Http\Exception\ClientErrorResponseException $responseException) { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); + } catch (\Guzzle\Http\Exception\CurlException $curlException) { + //curl exceptions are when the DNS fails etc + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + } catch (\Guzzle\Http\Exception\RequestException $requestException) { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); + } catch (\Exception $e) { return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } - // Make sure $path not beginning with / - if (strpos($path, '/') === 0) - { - $path = substr($path, 1); - } - - fputs($fsock, 'GET /' . $path . " HTTP/1.1\r\n"); - fputs($fsock, "HOST: " . $host . "\r\n"); - fputs($fsock, "Connection: close\r\n\r\n"); - - // Set a proper timeout for the socket - socket_set_timeout($fsock, $this->upload->upload_timeout); - - $get_info = false; - $data = ''; - $length = false; - $timer_stop = time() + $this->upload->upload_timeout; - - while ((!$length || $filesize < $length) && !@feof($fsock)) + if ($remote_max_filesize && $response->getContentType() > $remote_max_filesize) { - if ($get_info) - { - if ($length) - { - // Don't attempt to read past end of file if server indicated length - $block = @fread($fsock, min($length - $filesize, 1024)); - } - else - { - $block = @fread($fsock, 1024); - } + $max_filesize = get_formatted_filesize($remote_max_filesize, false); - $filesize += strlen($block); - - if ($remote_max_filesize && $filesize > $remote_max_filesize) - { - $max_filesize = get_formatted_filesize($remote_max_filesize, false); - - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); - } - - $data .= $block; - } - else - { - $line = @fgets($fsock, 1024); - - if ($line == "\r\n") - { - $get_info = true; - } - else - { - if (stripos($line, 'content-type: ') !== false) - { - $upload_ary['type'] = rtrim(str_replace('content-type: ', '', strtolower($line))); - } - else if ($this->upload->max_filesize && stripos($line, 'content-length: ') !== false) - { - $length = (int) str_replace('content-length: ', '', strtolower($line)); - - if ($remote_max_filesize && $length && $length > $remote_max_filesize) - { - $max_filesize = get_formatted_filesize($remote_max_filesize, false); - - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); - } - } - else if (stripos($line, '404 not found') !== false) - { - return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); - } - } - } - - $stream_meta_data = stream_get_meta_data($fsock); - - // Cancel upload if we exceed timeout - if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) - { - return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); - } + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); } - @fclose($fsock); - if (empty($data)) - { - return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA'); - } + $data = $response->getBody(); $filename = tempnam(sys_get_temp_dir(), unique_id() . '-'); -- cgit v1.2.1 From 49dd9f021924551bf0cfc5db3962ddb50c9e98a2 Mon Sep 17 00:00:00 2001 From: Scott Dutton Date: Wed, 3 Feb 2016 05:45:24 +0000 Subject: [ticket/14431] Remote avatar uploading Fixed content length bug Ran composer update PHPBB3-14431 --- phpBB/phpbb/files/types/remote.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index e990149501..92e0e3b9bc 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -115,13 +115,19 @@ class remote extends base return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } - if ($remote_max_filesize && $response->getContentType() > $remote_max_filesize) + $content_length = $response->getContentLength(); + if ($remote_max_filesize && $content_length > $remote_max_filesize) { $max_filesize = get_formatted_filesize($remote_max_filesize, false); return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); } + if ($content_length == 0) + { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA'); + } + $data = $response->getBody(); $filename = tempnam(sys_get_temp_dir(), unique_id() . '-'); -- cgit v1.2.1 From c83db45f55858c78648a6650aec39a9fc627a50b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 3 Feb 2016 14:06:10 +0100 Subject: [ticket/14448] Use GuzzleHttp and try to verify certs PHPBB3-14448 --- phpBB/phpbb/files/types/remote.php | 48 ++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 92e0e3b9bc..f4a4fa70d1 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -93,29 +93,53 @@ class remote extends base $url['path'] = implode('', $url['path']); $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : ''); - $filesize = 0; $remote_max_filesize = $this->get_max_file_size(); - $client = new \Guzzle\Http\Client([ + $guzzle_options = [ 'timeout' => $this->upload->upload_timeout, 'connect_timeout' => $this->upload->upload_timeout, - ]); + ]; + $client = new \GuzzleHttp\Client($guzzle_options); - try { - $response = $client->get($upload_url)->send(); - } catch (\Guzzle\Http\Exception\ClientErrorResponseException $responseException) { + try + { + $response = $client->get($upload_url, $guzzle_options); + } + catch (\GuzzleHttp\Exception\ClientException $clientException) + { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); - } catch (\Guzzle\Http\Exception\CurlException $curlException) { - //curl exceptions are when the DNS fails etc - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); - } catch (\Guzzle\Http\Exception\RequestException $requestException) { - return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); + } + catch (\GuzzleHttp\Exception\RequestException $requestException) + { + if (strpos($requestException->getMessage(), 'cURL error 28') !== false || preg_match('/408|504/', $requestException->getCode())) + { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); + } + else + { + if (strpos($requestException->getMessage(), 'cURL error 60') !== false) + { + // Work around non existent CA file + try + { + $response = $client->get($upload_url, array_merge($guzzle_options, ['verify' => false])); + } + catch (\GuzzleHttp\Exception\RequestException $requestException) + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + } + } + else + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + } + } } catch (\Exception $e) { return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } - $content_length = $response->getContentLength(); + $content_length = $response->getBody()->getSize(); if ($remote_max_filesize && $content_length > $remote_max_filesize) { $max_filesize = get_formatted_filesize($remote_max_filesize, false); -- cgit v1.2.1 From 7ec6dd75f388bf449016d78e39c93d3c13f99e69 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 4 Feb 2016 00:23:42 +0100 Subject: [ticket/14440] Correctly remove the web root path in update_web_root_path PHPBB3-14440 --- phpBB/phpbb/path_helper.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php index 7b0d6f0fba..c5e006120a 100644 --- a/phpBB/phpbb/path_helper.php +++ b/phpBB/phpbb/path_helper.php @@ -100,11 +100,17 @@ class path_helper */ public function update_web_root_path($path) { + $web_root_path = $this->get_web_root_path(); + + if (strpos($path, $web_root_path) === 0) + { + $path = $this->phpbb_root_path . substr($path, strlen($web_root_path)); + } + if (strpos($path, $this->phpbb_root_path) === 0) { $path = substr($path, strlen($this->phpbb_root_path)); - $web_root_path = $this->get_web_root_path(); if (substr($web_root_path, -8) === 'app.php/' && substr($path, 0, 7) === 'app.php') { $path = substr($path, 8); -- cgit v1.2.1 From fd9c05309d186332728b533467aaecad5c543c52 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 4 Feb 2016 17:10:59 +0100 Subject: [ticket/14448] Let user decide if remote upload certs should be checked Also fixed some minor issues like coding style. PHPBB3-14448 --- .../data/v320/remote_upload_validation.php | 31 ++++++++++++++++++++ phpBB/phpbb/files/types/remote.php | 34 +++++++++------------- 2 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php b/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php new file mode 100644 index 0000000000..d61f6b96fd --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php @@ -0,0 +1,31 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class remote_upload_validation extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320a2', + ); + } + + public function update_data() + { + return array( + array('config.add', array('remote_upload_verify', '0')), + ); + } +} diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index f4a4fa70d1..7e5157baa9 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -14,6 +14,7 @@ namespace phpbb\files\types; use bantu\IniGetWrapper\IniGetWrapper; +use phpbb\config\config; use phpbb\files\factory; use phpbb\files\filespec; use phpbb\language\language; @@ -21,6 +22,9 @@ use phpbb\request\request_interface; class remote extends base { + /** @var config phpBB config */ + protected $config; + /** @var factory Files factory */ protected $factory; @@ -42,14 +46,16 @@ class remote extends base /** * Construct a form upload type * + * @param config $config phpBB config * @param factory $factory Files factory * @param language $language Language class * @param IniGetWrapper $php_ini ini_get() wrapper * @param request_interface $request Request object * @param string $phpbb_root_path phpBB root path */ - public function __construct(factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path) + public function __construct(config $config, factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path) { + $this->config = $config; $this->factory = $factory; $this->language = $language; $this->php_ini = $php_ini; @@ -97,8 +103,9 @@ class remote extends base $remote_max_filesize = $this->get_max_file_size(); $guzzle_options = [ - 'timeout' => $this->upload->upload_timeout, - 'connect_timeout' => $this->upload->upload_timeout, + 'timeout' => $this->upload->upload_timeout, + 'connect_timeout' => $this->upload->upload_timeout, + 'verify' => !empty($this->config['remote_upload_verify']), ]; $client = new \GuzzleHttp\Client($guzzle_options); @@ -118,24 +125,11 @@ class remote extends base } else { - if (strpos($requestException->getMessage(), 'cURL error 60') !== false) - { - // Work around non existent CA file - try - { - $response = $client->get($upload_url, array_merge($guzzle_options, ['verify' => false])); - } - catch (\GuzzleHttp\Exception\RequestException $requestException) - { - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); - } - } - else - { - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); - } + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } - } catch (\Exception $e) { + } + catch (\Exception $e) + { return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } -- cgit v1.2.1 From 2f6f9a05eb1ae25a29fcb90bb301ce507298a474 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Thu, 4 Feb 2016 21:20:02 +0100 Subject: [ticket/14312] Push migration error messages to the user PHPBB3-14312 --- phpBB/phpbb/install/module/update_database/task/update.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index 4b2baf2c23..aa44d403dd 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -158,6 +158,7 @@ class update extends task_base array_unshift($msg, $e->getMessage()); $this->iohandler->add_error_message($msg); + $this->iohandler->send_response(); throw new user_interaction_required_exception(); } -- cgit v1.2.1 From ad7b3ed17865b4ac91df24812fce4a9192f44fa1 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Thu, 4 Feb 2016 21:35:45 +0100 Subject: [ticket/14312] Allow updating without having the update directory PHPBB3-14312 --- .../obtain_data/task/obtain_update_settings.php | 37 +++++++++++++++------- .../module/requirements/task/check_update.php | 16 ++++++++-- 2 files changed, 38 insertions(+), 15 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php index 6a98721e77..be6404dcd8 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php @@ -57,22 +57,35 @@ class obtain_update_settings extends task_base } else { + if ($this->installer_config->get('disable_filesystem_update', false)) + { + $options[] = array( + 'value' => 'db_only', + 'label' => 'UPDATE_TYPE_DB_ONLY', + 'selected' => true, + ); + } + else + { + $options = array( + array( + 'value' => 'all', + 'label' => 'UPDATE_TYPE_ALL', + 'selected' => true, + ), + array( + 'value' => 'db_only', + 'label' => 'UPDATE_TYPE_DB_ONLY', + 'selected' => false, + ), + ); + } + $this->iohandler->add_user_form_group('UPDATE_TYPE', array( 'update_type' => array( 'label' => 'UPDATE_TYPE', 'type' => 'radio', - 'options' => array( - array( - 'value' => 'all', - 'label' => 'UPDATE_TYPE_ALL', - 'selected' => true, - ), - array( - 'value' => 'db_only', - 'label' => 'UPDATE_TYPE_DB_ONLY', - 'selected' => false, - ), - ), + 'options' => $options, ), 'submit_update' => array( 'label' => 'SUBMIT', diff --git a/phpBB/phpbb/install/module/requirements/task/check_update.php b/phpBB/phpbb/install/module/requirements/task/check_update.php index c986c76810..4e9124ff47 100644 --- a/phpBB/phpbb/install/module/requirements/task/check_update.php +++ b/phpBB/phpbb/install/module/requirements/task/check_update.php @@ -14,6 +14,7 @@ namespace phpbb\install\module\requirements\task; use phpbb\filesystem\filesystem; +use phpbb\install\helper\config; use phpbb\install\helper\container_factory; use phpbb\install\helper\iohandler\iohandler_interface; use phpbb\install\helper\update_helper; @@ -34,6 +35,11 @@ class check_update extends task_base */ protected $filesystem; + /** + * @var config + */ + protected $installer_config; + /** * @var iohandler_interface */ @@ -69,14 +75,16 @@ class check_update extends task_base * * @param container_factory $container * @param filesystem $filesystem + * @param config $config * @param iohandler_interface $iohandler * @param update_helper $update_helper * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(container_factory $container, filesystem $filesystem, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path, $php_ext) + public function __construct(container_factory $container, filesystem $filesystem, config $config, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path, $php_ext) { $this->filesystem = $filesystem; + $this->installer_config = $config; $this->iohandler = $iohandler; $this->update_helper = $update_helper; $this->phpbb_root_path = $phpbb_root_path; @@ -117,8 +125,10 @@ class check_update extends task_base $this->iohandler->add_error_message('UPDATE_FILES_NOT_FOUND'); $this->set_test_passed(false); - // If there are no update files, we can't check the version - return false; + // If there are no update files, we can't check the version etc + // However, we can let the users run migrations if they really want to... + $this->installer_config->set('disable_filesystem_update', true); + return true; } // Recover version numbers -- cgit v1.2.1 From 3846b6a6e38e7241655e29dc05c453356b06581b Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 5 Feb 2016 11:58:51 +0100 Subject: [ticket/14453] Add missing dependency in the text_reparser migration PHPBB3-14453 --- phpBB/phpbb/db/migration/data/v320/text_reparser.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/text_reparser.php b/phpBB/phpbb/db/migration/data/v320/text_reparser.php index 1d73b74a76..8673a3488a 100644 --- a/phpBB/phpbb/db/migration/data/v320/text_reparser.php +++ b/phpBB/phpbb/db/migration/data/v320/text_reparser.php @@ -17,7 +17,10 @@ class text_reparser extends \phpbb\db\migration\container_aware_migration { static public function depends_on() { - return array('\phpbb\db\migration\data\v310\contact_admin_form'); + return array( + '\phpbb\db\migration\data\v310\contact_admin_form', + '\phpbb\db\migration\data\v320\allowed_schemes_links', + ); } public function effectively_installed() -- cgit v1.2.1 From 379634a102877ceebadf18b16d449899ddb9aa73 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 3 Feb 2016 22:22:30 +0100 Subject: [prep-release-3.2.0-b1] Add migration for 3.2.0-b1 --- phpBB/phpbb/db/migration/data/v320/v320b1.php | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/v320b1.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/v320b1.php b/phpBB/phpbb/db/migration/data/v320/v320b1.php new file mode 100644 index 0000000000..5c3a3797cd --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/v320b1.php @@ -0,0 +1,39 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class v320b1 extends \phpbb\db\migration\container_aware_migration +{ + public function effectively_installed() + { + return version_compare($this->config['version'], '3.2.0-b1', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v317pl1', + '\phpbb\db\migration\data\v320\v320a2', + '\phpbb\db\migration\data\v31x\increase_size_of_dateformat', + '\phpbb\db\migration\data\v320\default_data_type_ids', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.0-b1')), + ); + } +} -- cgit v1.2.1 From b40f9ce6e1df58f80d5e8878c9ff47178862d443 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 5 Feb 2016 11:58:51 +0100 Subject: [ticket/14453] Add missing dependency in the text_reparser migration PHPBB3-14453 --- phpBB/phpbb/db/migration/data/v320/text_reparser.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/text_reparser.php b/phpBB/phpbb/db/migration/data/v320/text_reparser.php index 1d73b74a76..8673a3488a 100644 --- a/phpBB/phpbb/db/migration/data/v320/text_reparser.php +++ b/phpBB/phpbb/db/migration/data/v320/text_reparser.php @@ -17,7 +17,10 @@ class text_reparser extends \phpbb\db\migration\container_aware_migration { static public function depends_on() { - return array('\phpbb\db\migration\data\v310\contact_admin_form'); + return array( + '\phpbb\db\migration\data\v310\contact_admin_form', + '\phpbb\db\migration\data\v320\allowed_schemes_links', + ); } public function effectively_installed() -- cgit v1.2.1 From 37705353c53a391aa44da7a30f10ed824a442cfc Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Sat, 6 Feb 2016 14:10:48 +0100 Subject: [ticket/14460] Use the selected language with AJAX requests as well PHPBB3-14460 --- phpBB/phpbb/install/controller/helper.php | 7 +------ phpBB/phpbb/install/controller/install.php | 3 +-- phpBB/phpbb/install/controller/update.php | 3 +-- phpBB/phpbb/install/helper/config.php | 16 ++++++++++------ phpBB/phpbb/install/helper/iohandler/factory.php | 2 -- 5 files changed, 13 insertions(+), 18 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/helper.php b/phpBB/phpbb/install/controller/helper.php index 6859414236..ff7e691224 100644 --- a/phpBB/phpbb/install/controller/helper.php +++ b/phpBB/phpbb/install/controller/helper.php @@ -183,11 +183,6 @@ class helper if (!empty($submit)) { $lang = $this->phpbb_request->variable('language', ''); - - if (!empty($lang)) - { - $this->language_cookie = $lang; - } } // Retrieve language from cookie @@ -195,10 +190,10 @@ class helper if (empty($lang) && !empty($lang_cookie)) { $lang = $lang_cookie; - $this->language_cookie = $lang; } $lang = (!empty($lang) && strpos($lang, '/') === false) ? $lang : null; + $this->language_cookie = $lang; $this->render_language_select($lang); diff --git a/phpBB/phpbb/install/controller/install.php b/phpBB/phpbb/install/controller/install.php index b987d91c6a..92506872a3 100644 --- a/phpBB/phpbb/install/controller/install.php +++ b/phpBB/phpbb/install/controller/install.php @@ -123,6 +123,7 @@ class install // Set the appropriate input-output handler $this->installer->set_iohandler($this->iohandler_factory->get()); + $this->controller_helper->handle_language_select(); if ($this->request->is_ajax()) { @@ -142,8 +143,6 @@ class install // Determine whether the installation was started or not if (true) { - $this->controller_helper->handle_language_select(); - // Set active stage $this->menu_provider->set_nav_property( array('install', 0, 'introduction'), diff --git a/phpBB/phpbb/install/controller/update.php b/phpBB/phpbb/install/controller/update.php index 9fff11cae8..6b88827940 100644 --- a/phpBB/phpbb/install/controller/update.php +++ b/phpBB/phpbb/install/controller/update.php @@ -122,6 +122,7 @@ class update // Set the appropriate input-output handler $this->installer->set_iohandler($this->iohandler_factory->get()); + $this->controller_helper->handle_language_select(); // Render the intro page if ($this->request->is_ajax()) @@ -140,8 +141,6 @@ class update } else { - $this->controller_helper->handle_language_select(); - // Set active stage $this->menu_provider->set_nav_property( array('update', 0, 'introduction'), diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php index ab5af86320..f58925899b 100644 --- a/phpBB/phpbb/install/helper/config.php +++ b/phpBB/phpbb/install/helper/config.php @@ -227,18 +227,22 @@ class config $file_content = @file_get_contents($this->install_config_file); $serialized_data = trim(substr($file_content, 8)); - $this->installer_config = array(); - $this->progress_data = array(); - $this->navigation_data = array(); + $installer_config = array(); + $progress_data = array(); + $navigation_data = array(); if (!empty($serialized_data)) { $unserialized_data = json_decode($serialized_data, true); - $this->installer_config = (is_array($unserialized_data['installer_config'])) ? $unserialized_data['installer_config'] : array(); - $this->progress_data = (is_array($unserialized_data['progress_data'])) ? $unserialized_data['progress_data'] : array(); - $this->navigation_data = (is_array($unserialized_data['navigation_data'])) ? $unserialized_data['navigation_data'] : array(); + $installer_config = (is_array($unserialized_data['installer_config'])) ? $unserialized_data['installer_config'] : array(); + $progress_data = (is_array($unserialized_data['progress_data'])) ? $unserialized_data['progress_data'] : array(); + $navigation_data = (is_array($unserialized_data['navigation_data'])) ? $unserialized_data['navigation_data'] : array(); } + + $this->installer_config = array_merge($this->installer_config, $installer_config); + $this->progress_data = array_merge($this->progress_data, $progress_data); + $this->navigation_data = array_merge($this->navigation_data, $navigation_data); } /** diff --git a/phpBB/phpbb/install/helper/iohandler/factory.php b/phpBB/phpbb/install/helper/iohandler/factory.php index 52d24e49b2..1e8395760a 100644 --- a/phpBB/phpbb/install/helper/iohandler/factory.php +++ b/phpBB/phpbb/install/helper/iohandler/factory.php @@ -75,7 +75,5 @@ class factory throw new iohandler_not_implemented_exception(); break; } - - throw new iohandler_not_implemented_exception(); } } -- cgit v1.2.1 From da08a6e3cbda3cb51052bd9c8b7ac697fba2305d Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sat, 6 Feb 2016 14:43:14 +0100 Subject: [ticket/14461] Correctly count up $processed_records PHPBB3-14461 --- phpBB/phpbb/db/migration/data/v320/text_reparser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/text_reparser.php b/phpBB/phpbb/db/migration/data/v320/text_reparser.php index 8673a3488a..ea614feb40 100644 --- a/phpBB/phpbb/db/migration/data/v320/text_reparser.php +++ b/phpBB/phpbb/db/migration/data/v320/text_reparser.php @@ -81,7 +81,7 @@ class text_reparser extends \phpbb\db\migration\container_aware_migration $end = max(1, $resume_data['current']); $reparser->reparse_range($start, $end); - $processed_records = $end - $start + 1; + $processed_records += $end - $start + 1; $resume_data['current'] = $start - 1; if ($start === 1) -- cgit v1.2.1 From 8cf086ef9b200f0b59348c0f0d4946f9ebc4adae Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 8 Feb 2016 13:26:19 +0100 Subject: [ticket/14448] Correctly pass verify setting if available PHPBB3-14448 --- phpBB/phpbb/files/types/remote.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 7e5157baa9..1fdba0ca32 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -105,7 +105,7 @@ class remote extends base $guzzle_options = [ 'timeout' => $this->upload->upload_timeout, 'connect_timeout' => $this->upload->upload_timeout, - 'verify' => !empty($this->config['remote_upload_verify']), + 'verify' => !empty($this->config['remote_upload_verify']) ? (bool) $this->config['remote_upload_verify'] : false, ]; $client = new \GuzzleHttp\Client($guzzle_options); -- cgit v1.2.1 From 5557760eccab67515990622471bd5de297e40f1e Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 11 Feb 2016 22:18:09 +0100 Subject: [ticket/14440] Add comments PHPBB3-14440 --- phpBB/phpbb/path_helper.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php index c5e006120a..154361ef64 100644 --- a/phpBB/phpbb/path_helper.php +++ b/phpBB/phpbb/path_helper.php @@ -102,6 +102,7 @@ class path_helper { $web_root_path = $this->get_web_root_path(); + // Removes the web root path if it is already present if (strpos($path, $web_root_path) === 0) { $path = $this->phpbb_root_path . substr($path, strlen($web_root_path)); -- cgit v1.2.1 From 955b9ede33c5696173a760ea271ec32d79e843b9 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Thu, 11 Feb 2016 13:18:30 +0100 Subject: [ticket/14462] Further speed improvements - Cache the secondary container - Only initialize tasks/modules that are being used - Add timeout error message in the AJAX UI PHPBB3-14462 --- phpBB/phpbb/install/helper/config.php | 20 ++-- phpBB/phpbb/install/helper/container_factory.php | 18 ++-- .../install/helper/iohandler/ajax_iohandler.php | 63 ++++++++--- .../install/helper/iohandler/cli_iohandler.php | 2 +- .../helper/iohandler/iohandler_interface.php | 4 +- phpBB/phpbb/install/installer.php | 116 ++++++++++++++------- .../install_filesystem/task/create_config_file.php | 2 - .../module/obtain_data/task/obtain_admin_data.php | 1 - .../module/obtain_data/task/obtain_board_data.php | 1 - .../obtain_data/task/obtain_database_data.php | 1 - .../module/obtain_data/task/obtain_email_data.php | 1 - .../task/obtain_file_updater_method.php | 1 - .../module/obtain_data/task/obtain_server_data.php | 1 - .../obtain_data/task/obtain_update_ftp_data.php | 1 - .../obtain_data/task/obtain_update_settings.php | 1 - .../requirements/abstract_requirements_module.php | 37 +------ .../install/module/update_database/task/update.php | 1 - .../task/download_updated_files.php | 1 - .../update_filesystem/task/show_file_status.php | 1 - phpBB/phpbb/install/module_base.php | 97 ++++++++--------- 20 files changed, 197 insertions(+), 173 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php index f58925899b..94abf9ca0b 100644 --- a/phpBB/phpbb/install/helper/config.php +++ b/phpBB/phpbb/install/helper/config.php @@ -95,8 +95,9 @@ class config $this->installer_config = array(); $this->system_data = array(); $this->progress_data = array( - 'last_task_module_name' => '', // Stores the service name of the latest finished module - 'last_task_name' => '', // Stores the service name of the latest finished task + 'last_task_module_neme' => '', // Stores the service name of the latest finished module + 'last_task_module_index' => 0, // Stores the index of the latest finished module + 'last_task_index' => 0, // Stores the index of the latest finished task 'max_task_progress' => 0, 'current_task_progress' => 0, '_restart_points' => array(), @@ -187,21 +188,23 @@ class config /** * Saves the latest executed task * - * @param string $task_service_name Name of the installer task service + * @param int $task_service_index Index of the installer task service in the module */ - public function set_finished_task($task_service_name) + public function set_finished_task($task_service_index) { - $this->progress_data['last_task_name'] = $task_service_name; + $this->progress_data['last_task_index'] = $task_service_index; } /** * Set active module * * @param string $module_service_name Name of the installer module service + * @param int $module_service_index Index of the installer module service */ - public function set_active_module($module_service_name) + public function set_active_module($module_service_name, $module_service_index) { $this->progress_data['last_task_module_name'] = $module_service_name; + $this->progress_data['last_task_module_index'] = $module_service_index; } /** @@ -391,6 +394,11 @@ class config */ public function set_finished_navigation_stage($nav_path) { + if (isset($this->navigation_data['finished']) && in_array($nav_path, $this->navigation_data['finished'])) + { + return; + } + $this->navigation_data['finished'][] = $nav_path; } diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php index 6c1ecd2d02..5cf4f8a283 100644 --- a/phpBB/phpbb/install/helper/container_factory.php +++ b/phpBB/phpbb/install/helper/container_factory.php @@ -13,7 +13,6 @@ namespace phpbb\install\helper; -use phpbb\cache\driver\dummy; use phpbb\install\exception\cannot_build_container_exception; use phpbb\language\language; use phpbb\request\request; @@ -157,25 +156,20 @@ class container_factory ->with_environment('production') ->with_config($phpbb_config_php_file) ->with_config_path($config_path) - ->without_cache() ->without_compiled_container() ->get_container(); // Setting request is required for the compatibility globals as those are generated from // this container - $this->container->register('request')->setSynthetic(true); - $this->container->set('request', $this->request); - - $this->container->register('language')->setSynthetic(true); - $this->container->set('language', $this->language); - - // Replace cache service, as config gets cached, and we don't want that when we are installing - if (!is_dir($other_config_path)) + if (!$this->container->isFrozen()) { - $this->container->register('cache.driver')->setSynthetic(true); - $this->container->set('cache.driver', new dummy()); + $this->container->register('request')->setSynthetic(true); + $this->container->register('language')->setSynthetic(true); } + $this->container->set('request', $this->request); + $this->container->set('language', $this->language); + $this->container->compile(); $phpbb_container = $this->container; diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php index 31474ae4e9..8c62ec7bd0 100644 --- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -209,9 +209,15 @@ class ajax_iohandler extends iohandler_base /** * {@inheritdoc} */ - public function send_response() + public function send_response($no_more_output = false) { - $json_data_array = $this->prepare_json_array(); + $json_data_array = $this->prepare_json_array($no_more_output); + + if (empty($json_data_array)) + { + return; + } + $json_data = json_encode($json_data_array); // Try to push content to the browser @@ -223,23 +229,43 @@ class ajax_iohandler extends iohandler_base /** * Prepares iohandler's data to be sent out to the client. * + * @param bool $no_more_output Whether or not there will be more output in this response + * * @return array */ - protected function prepare_json_array() + protected function prepare_json_array($no_more_output = false) { - $json_array = array( - 'errors' => $this->errors, - 'warnings' => $this->warnings, - 'logs' => $this->logs, - 'success' => $this->success, - 'download' => $this->download, - ); + $json_array = array(); + + if (!empty($this->errors)) + { + $json_array['errors'] = $this->errors; + $this->errors = array(); + } + + if (!empty($this->warnings)) + { + $json_array['warnings'] = $this->warnings; + $this->warnings = array(); + } - $this->errors = array(); - $this->warnings = array(); - $this->logs = array(); - $this->success = array(); - $this->download = array(); + if (!empty($this->logs)) + { + $json_array['logs'] = $this->logs; + $this->logs = array(); + } + + if (!empty($this->success)) + { + $json_array['success'] = $this->success; + $this->success = array(); + } + + if (!empty($this->download)) + { + $json_array['download'] = $this->download; + $this->download = array(); + } if (!empty($this->form)) { @@ -293,6 +319,11 @@ class ajax_iohandler extends iohandler_base $this->redirect_url = array(); } + if ($no_more_output) + { + $json_array['over'] = true; + } + return $json_array; } @@ -398,7 +429,7 @@ class ajax_iohandler extends iohandler_base public function redirect($url, $use_ajax = false) { $this->redirect_url = array('url' => $url, 'use_ajax' => $use_ajax); - $this->send_response(); + $this->send_response(true); } /** diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php index 7945904524..94550d2db0 100644 --- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -114,7 +114,7 @@ class cli_iohandler extends iohandler_base /** * {@inheritdoc} */ - public function send_response() + public function send_response($no_more_output = false) { } diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php index 6b3839506f..f22f33d9cb 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php @@ -20,8 +20,10 @@ interface iohandler_interface { /** * Renders or returns response message + * + * @param bool $no_more_output Whether or not there will be more output in this output unit */ - public function send_response(); + public function send_response($no_more_output = false); /** * Returns input variable diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index a41b4cd6a6..adf0ec8ac2 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -15,11 +15,13 @@ namespace phpbb\install; use phpbb\cache\driver\driver_interface; use phpbb\di\ordered_service_collection; +use phpbb\install\exception\cannot_build_container_exception; use phpbb\install\exception\installer_config_not_writable_exception; use phpbb\install\exception\jump_to_restart_point_exception; use phpbb\install\exception\resource_limit_reached_exception; use phpbb\install\exception\user_interaction_required_exception; use phpbb\install\helper\config; +use phpbb\install\helper\container_factory; use phpbb\install\helper\iohandler\cli_iohandler; use phpbb\install\helper\iohandler\iohandler_interface; use phpbb\path_helper; @@ -31,13 +33,18 @@ class installer */ protected $cache; + /** + * @var container_factory + */ + protected $container_factory; + /** * @var config */ protected $install_config; /** - * @var array + * @var ordered_service_collection */ protected $installer_modules; @@ -58,19 +65,27 @@ class installer */ protected $module_step_count; + /** + * @var bool + */ + protected $purge_cache_before; + /** * Constructor * * @param driver_interface $cache Cache service * @param config $config Installer config handler * @param path_helper $path_helper Path helper + * @param container_factory $container Container */ - public function __construct(driver_interface $cache, config $config, path_helper $path_helper) + public function __construct(driver_interface $cache, config $config, path_helper $path_helper, container_factory $container) { $this->cache = $cache; $this->install_config = $config; + $this->container_factory = $container; $this->installer_modules = null; $this->web_root = $path_helper->get_web_root_path(); + $this->purge_cache_before = false; } /** @@ -96,6 +111,16 @@ class installer $this->iohandler = $iohandler; } + /** + * Sets whether to purge cache before the installation process + * + * @param bool $purge_cache_before + */ + public function set_purge_cache_before($purge_cache_before) + { + $this->purge_cache_before = $purge_cache_before; + } + /** * Run phpBB installer */ @@ -104,9 +129,16 @@ class installer // Load install progress $this->install_config->load_config(); + if (!$this->install_config->get('cache_purged_before', false) && $this->purge_cache_before) + { + /** @var \phpbb\cache\driver\driver_interface $cache */ + $cache = $this->container_factory->get('cache.driver'); + $cache->purge(); + $this->install_config->set('cache_purged_before', true); + } + // Recover install progress - $module_name = $this->recover_progress(); - $module_found = false; + $module_index = $this->recover_progress(); // Variable used to check if the install process have been finished $install_finished = false; @@ -141,29 +173,13 @@ class installer try { - foreach ($this->installer_modules as $name => $module) - { - // Skip forward until the current task is reached - if (!$module_found) - { - if ($module_name === $name || empty($module_name)) - { - $module_found = true; - } - else - { - continue; - } - } + $iterator = $this->installer_modules->getIterator(); + $iterator->seek($module_index); - // Log progress - $this->install_config->set_active_module($name); - - // Run until there are available resources - if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) - { - throw new resource_limit_reached_exception(); - } + while ($iterator->valid()) + { + $module = $iterator->current(); + $name = $iterator->key(); // Check if module should be executed if (!$module->is_essential() && !$module->check_requirements()) @@ -176,17 +192,31 @@ class installer $name, )); $this->install_config->increment_current_task_progress($this->module_step_count[$name]); - continue; + } + else + { + // Set the correct stage in the navigation bar + $this->install_config->set_active_navigation_stage($module->get_navigation_stage_path()); + $this->iohandler->set_active_stage_menu($module->get_navigation_stage_path()); + + $this->iohandler->send_response(); + + $module->run(); + + $this->install_config->set_finished_navigation_stage($module->get_navigation_stage_path()); + $this->iohandler->set_finished_stage_menu($module->get_navigation_stage_path()); } - // Set the correct stage in the navigation bar - $this->install_config->set_active_navigation_stage($module->get_navigation_stage_path()); - $this->iohandler->set_active_stage_menu($module->get_navigation_stage_path()); + $module_index++; + $iterator->next(); - $module->run(); + // Save progress + $this->install_config->set_active_module($name, $module_index); - $this->install_config->set_finished_navigation_stage($module->get_navigation_stage_path()); - $this->iohandler->set_finished_stage_menu($module->get_navigation_stage_path()); + if ($iterator->valid() && ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0)) + { + throw new resource_limit_reached_exception(); + } } // Installation finished @@ -208,7 +238,7 @@ class installer } catch (user_interaction_required_exception $e) { - // Do nothing + $this->iohandler->send_response(true); } catch (resource_limit_reached_exception $e) { @@ -222,7 +252,7 @@ class installer catch (\Exception $e) { $this->iohandler->add_error_message($e->getMessage()); - $this->iohandler->send_response(); + $this->iohandler->send_response(true); $fail_cleanup = true; } @@ -230,11 +260,12 @@ class installer { // Send install finished message $this->iohandler->set_progress('INSTALLER_FINISHED', $this->install_config->get_task_progress_count()); + $this->iohandler->send_response(true); } else if ($send_refresh) { $this->iohandler->request_refresh(); - $this->iohandler->send_response(); + $this->iohandler->send_response(true); } // Save install progress @@ -244,6 +275,17 @@ class installer { $this->install_config->clean_up_config_file(); $this->cache->purge(); + + try + { + /** @var \phpbb\cache\driver\driver_interface $cache */ + $cache = $this->container_factory->get('cache.driver'); + $cache->purge(); + } + catch (cannot_build_container_exception $e) + { + // Do not do anything, this is just means there is no config.php yet + } } else { @@ -270,6 +312,6 @@ class installer protected function recover_progress() { $progress_array = $this->install_config->get_progress_data(); - return $progress_array['last_task_module_name']; + return $progress_array['last_task_module_index']; } } diff --git a/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php b/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php index e0890a929c..5bc425b929 100644 --- a/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php +++ b/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php @@ -129,7 +129,6 @@ class create_config_file extends \phpbb\install\task_base else { $this->iohandler->add_error_message('UNABLE_TO_WRITE_CONFIG_FILE'); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } @@ -139,7 +138,6 @@ class create_config_file extends \phpbb\install\task_base { // We were unable to create the lock file - abort $this->iohandler->add_error_message('UNABLE_TO_WRITE_LOCK'); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } @fclose($fp); diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php index ac305e8ab5..d1f1af6b83 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php @@ -136,7 +136,6 @@ class obtain_admin_data extends \phpbb\install\task_base implements \phpbb\insta $this->io_handler->add_user_form_group('ADMIN_CONFIG', $admin_form); // Require user interaction - $this->io_handler->send_response(); throw new user_interaction_required_exception(); } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php index 6c54561d14..ff2a0a2f86 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php @@ -164,7 +164,6 @@ class obtain_board_data extends \phpbb\install\task_base implements \phpbb\insta $this->io_handler->add_user_form_group('BOARD_CONFIG', $board_form); - $this->io_handler->send_response(); throw new user_interaction_required_exception(); } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php index 3458aab63e..ce720dbf76 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php @@ -188,7 +188,6 @@ class obtain_database_data extends \phpbb\install\task_base implements \phpbb\in $this->io_handler->add_user_form_group('DB_CONFIG', $database_form); // Require user interaction - $this->io_handler->send_response(); throw new user_interaction_required_exception(); } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php index b04b8e353f..606e4a2ddd 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php @@ -144,7 +144,6 @@ class obtain_email_data extends \phpbb\install\task_base implements \phpbb\insta $this->io_handler->add_user_form_group('EMAIL_CONFIG', $email_form); - $this->io_handler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php index 9bcb73a6a9..d5a8855c37 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php @@ -115,7 +115,6 @@ class obtain_file_updater_method extends task_base ), )); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php index 654b5534a9..1ef70eae08 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php @@ -180,7 +180,6 @@ class obtain_server_data extends \phpbb\install\task_base implements \phpbb\inst $this->io_handler->add_user_form_group('SERVER_CONFIG', $server_form); - $this->io_handler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php index a4d362a0f1..f31472fc58 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php @@ -141,7 +141,6 @@ class obtain_update_ftp_data extends task_base ), )); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php index be6404dcd8..c139b70fa4 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php @@ -93,7 +93,6 @@ class obtain_update_settings extends task_base ), )); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php b/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php index 26593e6777..121b4ff4e5 100644 --- a/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php +++ b/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php @@ -13,7 +13,6 @@ namespace phpbb\install\module\requirements; -use phpbb\install\exception\resource_limit_reached_exception; use phpbb\install\exception\user_interaction_required_exception; use phpbb\install\module_base; @@ -25,41 +24,8 @@ abstract class abstract_requirements_module extends module_base public function run() { $tests_passed = true; - - // Recover install progress - $task_name = $this->recover_progress(); - $task_found = false; - - /** - * @var string $name ID of the service - * @var \phpbb\install\task_interface $task Task object - */ foreach ($this->task_collection as $name => $task) { - // Run until there are available resources - if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) - { - throw new resource_limit_reached_exception(); - } - - // Skip forward until the next task is reached - if (!$task_found) - { - if ($name === $task_name || empty($task_name)) - { - $task_found = true; - - if ($name === $task_name) - { - continue; - } - } - else - { - continue; - } - } - // Check if we can run the task if (!$task->is_essential() && !$task->check_requirements()) { @@ -76,7 +42,7 @@ abstract class abstract_requirements_module extends module_base } // Module finished, so clear task progress - $this->install_config->set_finished_task(''); + $this->install_config->set_finished_task(0); // Check if tests have failed if (!$tests_passed) @@ -91,7 +57,6 @@ abstract class abstract_requirements_module extends module_base )); // Send the response and quit - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index aa44d403dd..4b2baf2c23 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -158,7 +158,6 @@ class update extends task_base array_unshift($msg, $e->getMessage()); $this->iohandler->add_error_message($msg); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } diff --git a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php index 9271e8fd50..f911b7ac62 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php @@ -101,7 +101,6 @@ class download_updated_files extends task_base ), )); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php index e712b8ad6a..c46c05500a 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php @@ -136,7 +136,6 @@ class show_file_status extends task_base )); // Show results to the user - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } else diff --git a/phpBB/phpbb/install/module_base.php b/phpBB/phpbb/install/module_base.php index fb68c3aca2..f75e8cda02 100644 --- a/phpBB/phpbb/install/module_base.php +++ b/phpBB/phpbb/install/module_base.php @@ -105,47 +105,23 @@ abstract class module_base implements module_interface public function run() { // Recover install progress - $task_name = $this->recover_progress(); - $task_found = false; - - /** - * @var string $name ID of the service - * @var \phpbb\install\task_interface $task Task object - */ - foreach ($this->task_collection as $name => $task) - { - // Run until there are available resources - if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) - { - throw new resource_limit_reached_exception(); - } + $task_index = $this->recover_progress(); + $iterator = $this->task_collection->getIterator(); - // Skip forward until the next task is reached - if (!$task_found) - { - if ($name === $task_name || empty($task_name)) - { - $task_found = true; - - if ($name === $task_name) - { - continue; - } - } - else - { - continue; - } - } + if ($task_index < $iterator->count()) + { + $iterator->seek($task_index); + } + else + { + $this->install_config->set_finished_task(0); + return; + } - // Send progress information - if ($this->allow_progress_bar) - { - $this->iohandler->set_progress( - $task->get_task_lang_name(), - $this->install_config->get_current_task_progress() - ); - } + while ($iterator->valid()) + { + $task = $iterator->current(); + $name = $iterator->key(); // Check if we can run the task if (!$task->is_essential() && !$task->check_requirements()) @@ -156,20 +132,33 @@ abstract class module_base implements module_interface )); $this->install_config->increment_current_task_progress($this->task_step_count[$name]); - continue; } - - if ($this->allow_progress_bar) + else { - // Only increment progress by one, as if a task has more than one steps - // then that should be incremented in the task itself - $this->install_config->increment_current_task_progress(); - } + // Send progress information + if ($this->allow_progress_bar) + { + $this->iohandler->set_progress( + $task->get_task_lang_name(), + $this->install_config->get_current_task_progress() + ); - $task->run(); + $this->iohandler->send_response(); + } - // Log install progress - $this->install_config->set_finished_task($name); + $task->run(); + + if ($this->allow_progress_bar) + { + // Only increment progress by one, as if a task has more than one steps + // then that should be incremented in the task itself + $this->install_config->increment_current_task_progress(); + } + } + + $task_index++; + $this->install_config->set_finished_task($task_index); + $iterator->next(); // Send progress information if ($this->allow_progress_bar) @@ -181,10 +170,16 @@ abstract class module_base implements module_interface } $this->iohandler->send_response(); + + // Run until there are available resources + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) + { + throw new resource_limit_reached_exception(); + } } // Module finished, so clear task progress - $this->install_config->set_finished_task(''); + $this->install_config->set_finished_task(0); } /** @@ -195,7 +190,7 @@ abstract class module_base implements module_interface protected function recover_progress() { $progress_array = $this->install_config->get_progress_data(); - return $progress_array['last_task_name']; + return $progress_array['last_task_index']; } /** -- cgit v1.2.1 From 68091561abef2c2f0674e3a461401f10f2ef5a25 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Fri, 12 Feb 2016 14:20:04 +0100 Subject: [ticket/14462] Refactor tasks to be more modular PHPBB3-14462 --- .../install/module/install_data/task/add_bots.php | 22 +- .../module/install_data/task/add_modules.php | 428 +++++++++++++-------- .../install_database/task/add_config_settings.php | 20 + .../install_database/task/add_default_data.php | 21 + .../module/install_database/task/add_tables.php | 151 ++++++++ .../install_database/task/create_schema_file.php | 164 ++++++++ .../install_database/task/set_up_database.php | 164 ++++++++ .../module/install_finish/task/notify_user.php | 6 +- .../install_finish/task/populate_migrations.php | 24 +- 9 files changed, 835 insertions(+), 165 deletions(-) create mode 100644 phpBB/phpbb/install/module/install_database/task/add_tables.php create mode 100644 phpBB/phpbb/install/module/install_database/task/create_schema_file.php create mode 100644 phpBB/phpbb/install/module/install_database/task/set_up_database.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_data/task/add_bots.php b/phpBB/phpbb/install/module/install_data/task/add_bots.php index 2ee641ff63..b22c8257e4 100644 --- a/phpBB/phpbb/install/module/install_data/task/add_bots.php +++ b/phpBB/phpbb/install/module/install_data/task/add_bots.php @@ -13,6 +13,8 @@ namespace phpbb\install\module\install_data\task; +use phpbb\install\exception\resource_limit_reached_exception; + class add_bots extends \phpbb\install\task_base { /** @@ -179,7 +181,10 @@ class add_bots extends \phpbb\install\task_base $this->io_handler->add_error_message('NO_GROUP'); } - foreach ($this->bot_list as $bot_name => $bot_ary) + $i = $this->install_config->get('add_bot_index', 0); + $bot_list = array_slice($this->bot_list, $i); + + foreach ($bot_list as $bot_name => $bot_ary) { $user_row = array( 'user_type' => USER_IGNORE, @@ -221,6 +226,21 @@ class add_bots extends \phpbb\install\task_base )); $this->db->sql_query($sql); + + $i++; + + // Run until there are available resources + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) + { + break; + } + } + + $this->install_config->set('add_bot_index', $i); + + if ($i < sizeof($this->bot_list)) + { + throw new resource_limit_reached_exception(); } } diff --git a/phpBB/phpbb/install/module/install_data/task/add_modules.php b/phpBB/phpbb/install/module/install_data/task/add_modules.php index bfbe6282bc..2f3a25a9c2 100644 --- a/phpBB/phpbb/install/module/install_data/task/add_modules.php +++ b/phpBB/phpbb/install/module/install_data/task/add_modules.php @@ -13,8 +13,18 @@ namespace phpbb\install\module\install_data\task; +use phpbb\install\exception\resource_limit_reached_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\container_factory; +use phpbb\install\helper\iohandler\iohandler_interface; + class add_modules extends \phpbb\install\task_base { + /** + * @var config + */ + protected $config; + /** * @var \phpbb\db\driver\driver_interface */ @@ -136,12 +146,13 @@ class add_modules extends \phpbb\install\task_base /** * Constructor * - * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler Installer's input-output handler - * @param \phpbb\install\helper\container_factory $container Installer's DI container + * @parma config $config Installer's config + * @param iohandler_interface $iohandler Installer's input-output handler + * @param container_factory $container Installer's DI container */ - public function __construct(\phpbb\install\helper\iohandler\iohandler_interface $iohandler, - \phpbb\install\helper\container_factory $container) + public function __construct(config $config, iohandler_interface $iohandler, container_factory $container) { + $this->config = $config; $this->db = $container->get('dbal.conn'); $this->extension_manager = $container->get('ext.manager'); $this->iohandler = $iohandler; @@ -158,11 +169,19 @@ class add_modules extends \phpbb\install\task_base $this->db->sql_return_on_error(true); $module_classes = array('acp', 'mcp', 'ucp'); + $total = sizeof($module_classes); + $i = $this->config->get('module_class_index', 0); + $module_classes = array_slice($module_classes, $i); + foreach ($module_classes as $module_class) { - $categories = array(); + $categories = $this->config->get('module_categories_array', array()); + + $k = $this->config->get('module_categories_index', 0); + $module_categories = array_slice($this->module_categories[$module_class], $k); + $timed_out = false; - foreach ($this->module_categories[$module_class] as $cat_name => $subs) + foreach ($module_categories as $cat_name => $subs) { // Check if this sub-category has a basename. If it has, use it. $basename = (isset($this->module_categories_basenames[$cat_name])) ? $this->module_categories_basenames[$cat_name] : ''; @@ -221,11 +240,31 @@ class add_modules extends \phpbb\install\task_base $categories[$level2_name]['parent_id'] = (int) $categories[$cat_name]['id']; } } + + $k++; + + // Run until there are available resources + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + $timed_out = true; + break; + } + } + + $this->config->set('module_categories_array', $categories); + $this->config->set('module_categories_index', $k); + + if ($timed_out) + { + throw new resource_limit_reached_exception(); } // Get the modules we want to add... returned sorted by name $module_info = $this->module_manager->get_module_infos($module_class); + $k = $this->config->get('module_info_index', 0); + $module_info = array_slice($module_info, $k); + foreach ($module_info as $module_basename => $fileinfo) { foreach ($fileinfo['modes'] as $module_mode => $row) @@ -258,189 +297,256 @@ class add_modules extends \phpbb\install\task_base } } } - } - // Move some of the modules around since the code above will put them in the wrong place - if ($module_class === 'acp') - { - // Move main module 4 up... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'acp_main' - AND module_class = 'acp' - AND module_mode = 'main'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + $k++; - $this->module_manager->move_module_by($row, 'acp', 'move_up', 4); - - // Move permissions intro screen module 4 up... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'acp_permissions' - AND module_class = 'acp' - AND module_mode = 'intro'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + // Run until there are available resources + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + $timed_out = true; + break; + } + } - $this->module_manager->move_module_by($row, 'acp', 'move_up', 4); + $this->config->set('module_info_index', $k); - // Move manage users screen module 5 up... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'acp_users' - AND module_class = 'acp' - AND module_mode = 'overview'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $this->module_manager->move_module_by($row, 'acp', 'move_up', 5); + // Run until there are available resources + if ($timed_out) + { + throw new resource_limit_reached_exception(); + } - // Move extension management module 1 up... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_langname = 'ACP_EXTENSION_MANAGEMENT' - AND module_class = 'acp' - AND module_mode = '' - AND module_basename = ''"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + // Move some of the modules around since the code above will put them in the wrong place + if (!$this->config->get('modules_ordered', false)) + { + $this->order_modules($module_class); + $this->config->set('modules_ordered', true); - $this->module_manager->move_module_by($row, 'acp', 'move_up', 1); + // Run until there are available resources + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + throw new resource_limit_reached_exception(); + } } - if ($module_class == 'mcp') + // And now for the special ones + // (these are modules which appear in multiple categories and thus get added manually + // to some for more control) + if (isset($this->module_extras[$module_class])) { - // Move pm report details module 3 down... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'mcp_pm_reports' - AND module_class = 'mcp' - AND module_mode = 'pm_report_details'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + $this->add_module_extras($module_class); + } - $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + $this->module_manager->remove_cache_file($module_class); - // Move closed pm reports module 3 down... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'mcp_pm_reports' - AND module_class = 'mcp' - AND module_mode = 'pm_reports_closed'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + $i++; - $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + $this->config->set('module_class_index', $i); + $this->config->set('module_categories_index', 0); + $this->config->set('module_info_index', 0); + $this->config->set('added_extra_modules', false); + $this->config->set('modules_ordered', false); + $this->config->set('module_categories_array', array()); - // Move open pm reports module 3 down... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'mcp_pm_reports' - AND module_class = 'mcp' - AND module_mode = 'pm_reports'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + // Run until there are available resources + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + break; } + } - if ($module_class == 'ucp') - { - // Move attachment module 4 down... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'ucp_attachments' - AND module_class = 'ucp' - AND module_mode = 'attachments'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + if ($i < $total) + { + throw new resource_limit_reached_exception(); + } + } - $this->module_manager->move_module_by($row, 'ucp', 'move_down', 4); + /** + * Move modules to their correct place + * + * @param string $module_class + */ + protected function order_modules($module_class) + { + if ($module_class == 'acp') + { + // Move main module 4 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'acp_main' + AND module_class = 'acp' + AND module_mode = 'main'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'acp', 'move_up', 4); + + // Move permissions intro screen module 4 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'acp_permissions' + AND module_class = 'acp' + AND module_mode = 'intro'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'acp', 'move_up', 4); + + // Move manage users screen module 5 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'acp_users' + AND module_class = 'acp' + AND module_mode = 'overview'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'acp', 'move_up', 5); + + // Move extension management module 1 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_langname = 'ACP_EXTENSION_MANAGEMENT' + AND module_class = 'acp' + AND module_mode = '' + AND module_basename = ''"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'acp', 'move_up', 1); + } - // Move notification options module 4 down... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'ucp_notifications' - AND module_class = 'ucp' - AND module_mode = 'notification_options'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + if ($module_class == 'mcp') + { + // Move pm report details module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_report_details'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + + // Move closed pm reports module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_reports_closed'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + + // Move open pm reports module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_reports'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + } - $this->module_manager->move_module_by($row, 'ucp', 'move_down', 4); + if ($module_class == 'ucp') + { + // Move attachment module 4 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_attachments' + AND module_class = 'ucp' + AND module_mode = 'attachments'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'ucp', 'move_down', 4); + + // Move notification options module 4 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_notifications' + AND module_class = 'ucp' + AND module_mode = 'notification_options'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'ucp', 'move_down', 4); + + // Move OAuth module 5 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_auth_link' + AND module_class = 'ucp' + AND module_mode = 'auth_link'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'ucp', 'move_down', 5); + } + } - // Move OAuth module 5 down... + /** + * Add extra modules + * + * @param string $module_class + */ + protected function add_module_extras($module_class) + { + foreach ($this->module_extras[$module_class] as $cat_name => $mods) + { + $sql = 'SELECT module_id, left_id, right_id + FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($cat_name) . "' + AND module_class = '" . $this->db->sql_escape($module_class) . "'"; + $result = $this->db->sql_query_limit($sql, 1); + $row2 = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + foreach ($mods as $mod_name) + { $sql = 'SELECT * FROM ' . MODULES_TABLE . " - WHERE module_basename = 'ucp_auth_link' - AND module_class = 'ucp' - AND module_mode = 'auth_link'"; - $result = $this->db->sql_query($sql); + WHERE module_langname = '" . $this->db->sql_escape($mod_name) . "' + AND module_class = '" . $this->db->sql_escape($module_class) . "' + AND module_basename <> ''"; + $result = $this->db->sql_query_limit($sql, 1); $row = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - $this->module_manager->move_module_by($row, 'ucp', 'move_down', 5); - } - - // And now for the special ones - // (these are modules which appear in multiple categories and thus get added manually - // to some for more control) - if (isset($this->module_extras[$module_class])) - { - foreach ($this->module_extras[$module_class] as $cat_name => $mods) - { - $sql = 'SELECT module_id, left_id, right_id - FROM ' . MODULES_TABLE . " - WHERE module_langname = '" . $this->db->sql_escape($cat_name) . "' - AND module_class = '" . $this->db->sql_escape($module_class) . "'"; - $result = $this->db->sql_query_limit($sql, 1); - $row2 = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - foreach ($mods as $mod_name) - { - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_langname = '" . $this->db->sql_escape($mod_name) . "' - AND module_class = '" . $this->db->sql_escape($module_class) . "' - AND module_basename <> ''"; - $result = $this->db->sql_query_limit($sql, 1); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $module_data = array( - 'module_basename' => $row['module_basename'], - 'module_enabled' => (int) $row['module_enabled'], - 'module_display' => (int) $row['module_display'], - 'parent_id' => (int) $row2['module_id'], - 'module_class' => $row['module_class'], - 'module_langname' => $row['module_langname'], - 'module_mode' => $row['module_mode'], - 'module_auth' => $row['module_auth'], - ); + $module_data = array( + 'module_basename' => $row['module_basename'], + 'module_enabled' => (int) $row['module_enabled'], + 'module_display' => (int) $row['module_display'], + 'parent_id' => (int) $row2['module_id'], + 'module_class' => $row['module_class'], + 'module_langname' => $row['module_langname'], + 'module_mode' => $row['module_mode'], + 'module_auth' => $row['module_auth'], + ); - $this->module_manager->update_module_data($module_data); + $this->module_manager->update_module_data($module_data); - // Check for last sql error happened - if ($this->db->get_sql_error_triggered()) - { - $error = $this->db->sql_error($this->db->get_sql_error_sql()); - $this->iohandler->add_error_message('INST_ERR_DB', $error['message']); - } - } + // Check for last sql error happened + if ($this->db->get_sql_error_triggered()) + { + $error = $this->db->sql_error($this->db->get_sql_error_sql()); + $this->iohandler->add_error_message('INST_ERR_DB', $error['message']); } } - - $this->module_manager->remove_cache_file($module_class); } } diff --git a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php index 6fb03ff73d..5fd99638c2 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php +++ b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php @@ -13,6 +13,8 @@ namespace phpbb\install\module\install_database\task; +use phpbb\install\exception\resource_limit_reached_exception; + /** * Create database schema */ @@ -313,6 +315,10 @@ class add_config_settings extends \phpbb\install\task_base WHERE config_name = 'allow_avatar_upload'"; } + $i = $this->install_config->get('add_config_settings_index', 0); + $total = sizeof($sql_ary); + $sql_ary = array_slice($sql_ary, $i); + foreach ($sql_ary as $sql) { if (!$this->db->sql_query($sql)) @@ -320,6 +326,20 @@ class add_config_settings extends \phpbb\install\task_base $error = $this->db->sql_error($this->db->get_sql_error_sql()); $this->iohandler->add_error_message('INST_ERR_DB', $error['message']); } + + $i++; + + // Run until there are available resources + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) + { + break; + } + } + + if ($i < $total) + { + $this->install_config->set('add_config_settings_index', $i); + throw new resource_limit_reached_exception(); } } diff --git a/phpBB/phpbb/install/module/install_database/task/add_default_data.php b/phpBB/phpbb/install/module/install_database/task/add_default_data.php index 3d73a74618..dd1829e6ed 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_default_data.php +++ b/phpBB/phpbb/install/module/install_database/task/add_default_data.php @@ -13,6 +13,8 @@ namespace phpbb\install\module\install_database\task; +use phpbb\install\exception\resource_limit_reached_exception; + /** * Create database schema */ @@ -96,6 +98,10 @@ class add_default_data extends \phpbb\install\task_base $sql_query = $this->database_helper->remove_comments($sql_query); $sql_query = $this->database_helper->split_sql_file($sql_query, $dbms_info[$dbms]['DELIM']); + $i = $this->config->get('add_default_data_index', 0); + $total = sizeof($sql_query); + $sql_query = array_slice($sql_query, $i); + foreach ($sql_query as $sql) { if (!$this->db->sql_query($sql)) @@ -103,6 +109,21 @@ class add_default_data extends \phpbb\install\task_base $error = $this->db->sql_error($this->db->get_sql_error_sql()); $this->iohandler->add_error_message('INST_ERR_DB', $error['message']); } + + $i++; + + // Run until there are available resources + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + break; + } + } + + $this->config->set('add_default_data_index', $i); + + if ($i < $total) + { + throw new resource_limit_reached_exception(); } } diff --git a/phpBB/phpbb/install/module/install_database/task/add_tables.php b/phpBB/phpbb/install/module/install_database/task/add_tables.php new file mode 100644 index 0000000000..a0b19950be --- /dev/null +++ b/phpBB/phpbb/install/module/install_database/task/add_tables.php @@ -0,0 +1,151 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\install_database\task; + +use phpbb\install\exception\resource_limit_reached_exception; + +/** + * Create tables + */ +class add_tables extends \phpbb\install\task_base +{ + /** + * @var \phpbb\install\helper\config + */ + protected $config; + + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var \phpbb\db\tools\tools_interface + */ + protected $db_tools; + + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + /** + * @var string + */ + protected $schema_file_path; + + /** + * Constructor + * + * @param \phpbb\install\helper\config $config + * @param \phpbb\install\helper\database $db_helper + * @param \phpbb\filesystem\filesystem_interface $filesystem + * @param string $phpbb_root_path + */ + public function __construct(\phpbb\install\helper\config $config, + \phpbb\install\helper\database $db_helper, + \phpbb\filesystem\filesystem_interface $filesystem, + $phpbb_root_path) + { + $dbms = $db_helper->get_available_dbms($config->get('dbms')); + $dbms = $dbms[$config->get('dbms')]['DRIVER']; + $factory = new \phpbb\db\tools\factory(); + + $this->db = new $dbms(); + $this->db->sql_connect( + $config->get('dbhost'), + $config->get('dbuser'), + $config->get('dbpasswd'), + $config->get('dbname'), + $config->get('dbport'), + false, + false + ); + + $this->config = $config; + $this->db_tools = $factory->get($this->db); + $this->filesystem = $filesystem; + $this->schema_file_path = $phpbb_root_path . 'store/schema.json'; + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->db->sql_return_on_error(true); + + $table_prefix = $this->config->get('table_prefix'); + $change_prefix = $this->config->get('change_table_prefix', true); + + if (!defined('CONFIG_TABLE')) + { + // CONFIG_TABLE is required by sql_create_index() to check the + // length of index names. However table_prefix is not defined + // here yet, so we need to create the constant ourselves. + define('CONFIG_TABLE', $table_prefix . 'config'); + } + + $db_table_schema = @file_get_contents($this->schema_file_path); + $db_table_schema = json_decode($db_table_schema, true); + $total = sizeof($db_table_schema); + $i = $this->config->get('add_table_index', 0); + $db_table_schema = array_slice($db_table_schema, $i); + + foreach ($db_table_schema as $table_name => $table_data) + { + $i++; + + $this->db_tools->sql_create_table( + ( ($change_prefix) ? ($table_prefix . substr($table_name, 6)) : $table_name ), + $table_data + ); + + // Run until there are available resources + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + break; + } + } + + $this->config->set('add_table_index', $i); + + if ($i < $total) + { + throw new resource_limit_reached_exception(); + } + else + { + @unlink($this->schema_file_path); + } + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_CREATE_TABLES'; + } +} diff --git a/phpBB/phpbb/install/module/install_database/task/create_schema_file.php b/phpBB/phpbb/install/module/install_database/task/create_schema_file.php new file mode 100644 index 0000000000..b6d6ece17f --- /dev/null +++ b/phpBB/phpbb/install/module/install_database/task/create_schema_file.php @@ -0,0 +1,164 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\install_database\task; + +use phpbb\install\exception\resource_limit_reached_exception; + +/** + * Create database schema + */ +class create_schema_file extends \phpbb\install\task_base +{ + /** + * @var \phpbb\install\helper\config + */ + protected $config; + + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var string + */ + protected $php_ext; + + /** + * Constructor + * + * @param \phpbb\install\helper\config $config Installer's config provider + * @param \phpbb\install\helper\database $db_helper Installer's database helper + * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem service + * @param string $phpbb_root_path Path phpBB's root + * @param string $php_ext Extension of PHP files + */ + public function __construct(\phpbb\install\helper\config $config, + \phpbb\install\helper\database $db_helper, + \phpbb\filesystem\filesystem_interface $filesystem, + $phpbb_root_path, + $php_ext) + { + $dbms = $db_helper->get_available_dbms($config->get('dbms')); + $dbms = $dbms[$config->get('dbms')]['DRIVER']; + + $this->db = new $dbms(); + $this->db->sql_connect( + $config->get('dbhost'), + $config->get('dbuser'), + $config->get('dbpasswd'), + $config->get('dbname'), + $config->get('dbport'), + false, + false + ); + + $this->config = $config; + $this->filesystem = $filesystem; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Generate database schema + if ($this->filesystem->exists($this->phpbb_root_path . 'install/schemas/schema.json')) + { + $db_table_schema = @file_get_contents($this->phpbb_root_path . 'install/schemas/schema.json'); + $this->config->set('change_table_prefix', true); + } + else + { + global $table_prefix; + + // As this task may take a large amount of time to complete refreshing the page might be necessary for some + // server configurations with limited resources + if (!$this->config->get('pre_schema_forced_refresh', false)) + { + if ($this->config->get_time_remaining() < 5) + { + $this->config->set('pre_schema_forced_refresh', true); + throw new resource_limit_reached_exception(); + } + } + + $table_prefix = $this->config->get('table_prefix'); + + if (!defined('CONFIG_TABLE')) + { + // We need to include the constants file for the table constants + // when we generate the schema from the migration files. + include ($this->phpbb_root_path . 'includes/constants.' . $this->php_ext); + } + + $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, null, $this->php_ext); + $migrator_classes = $finder->core_path('phpbb/db/migration/data/')->get_classes(); + $factory = new \phpbb\db\tools\factory(); + $db_tools = $factory->get($this->db, true); + $schema_generator = new \phpbb\db\migration\schema_generator( + $migrator_classes, + new \phpbb\config\config(array()), + $this->db, + $db_tools, + $this->phpbb_root_path, + $this->php_ext, + $table_prefix + ); + $db_table_schema = $schema_generator->get_schema(); + $db_table_schema = json_encode($db_table_schema, JSON_PRETTY_PRINT); + + $this->config->set('change_table_prefix', false); + } + + $fp = @fopen($this->phpbb_root_path . 'store/schema.json', 'wb'); + if (!$fp) + { + throw new \Exception('INST_SCHEMA_FILE_NOT_WRITABLE'); + } + + fwrite($fp, $db_table_schema); + fclose($fp); + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_CREATE_DATABASE_SCHEMA_FILE'; + } +} diff --git a/phpBB/phpbb/install/module/install_database/task/set_up_database.php b/phpBB/phpbb/install/module/install_database/task/set_up_database.php new file mode 100644 index 0000000000..49c8ea23ad --- /dev/null +++ b/phpBB/phpbb/install/module/install_database/task/set_up_database.php @@ -0,0 +1,164 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\install_database\task; + +/** + * Set up database for table generation + */ +class set_up_database extends \phpbb\install\task_base +{ + /** + * @var \phpbb\install\helper\config + */ + protected $config; + + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var \phpbb\install\helper\database + */ + protected $database_helper; + + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + /** + * @var \phpbb\install\helper\iohandler\iohandler_interface + */ + protected $iohandler; + + /** + * @var string + */ + protected $schema_file_path; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * Constructor + * + * @param \phpbb\install\helper\config $config + * @param \phpbb\install\helper\database $db_helper + * @param \phpbb\filesystem\filesystem_interface $filesystem + * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler + * @param string $phpbb_root_path + */ + public function __construct(\phpbb\install\helper\config $config, + \phpbb\install\helper\database $db_helper, + \phpbb\filesystem\filesystem_interface $filesystem, + \phpbb\install\helper\iohandler\iohandler_interface $iohandler, + $phpbb_root_path) + { + $dbms = $db_helper->get_available_dbms($config->get('dbms')); + $dbms = $dbms[$config->get('dbms')]['DRIVER']; + + $this->db = new $dbms(); + $this->db->sql_connect( + $config->get('dbhost'), + $config->get('dbuser'), + $config->get('dbpasswd'), + $config->get('dbname'), + $config->get('dbport'), + false, + false + ); + + $this->config = $config; + $this->database_helper = $db_helper; + $this->filesystem = $filesystem; + $this->iohandler = $iohandler; + $this->phpbb_root_path = $phpbb_root_path; + + parent::__construct(false); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + $dbms = $this->config->get('dbms'); + $dbms_info = $this->database_helper->get_available_dbms($dbms); + $schema_name = $dbms_info[$dbms]['SCHEMA']; + + if ($dbms === 'mysql') + { + if (version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) + { + $schema_name .= '_41'; + } + else + { + $schema_name .= '_40'; + } + } + + $this->schema_file_path = $this->phpbb_root_path . 'install/schemas/' . $schema_name . '_schema.sql'; + + return $this->filesystem->exists($this->schema_file_path); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->db->sql_return_on_error(true); + + $dbms = $this->config->get('dbms'); + $dbms_info = $this->database_helper->get_available_dbms($dbms); + $delimiter = $dbms_info[$dbms]['DELIM']; + $table_prefix = $this->config->get('table_prefix'); + + $sql_query = @file_get_contents($this->schema_file_path); + $sql_query = preg_replace('#phpbb_#i', $table_prefix, $sql_query); + $sql_query = $this->database_helper->remove_comments($sql_query); + $sql_query = $this->database_helper->split_sql_file($sql_query, $delimiter); + + foreach ($sql_query as $sql) + { + if (!$this->db->sql_query($sql)) + { + $error = $this->db->sql_error($this->db->get_sql_error_sql()); + $this->iohandler->add_error_message('INST_ERR_DB', $error['message']); + } + } + + unset($sql_query); + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_SETUP_DATABASE'; + } +} diff --git a/phpBB/phpbb/install/module/install_finish/task/notify_user.php b/phpBB/phpbb/install/module/install_finish/task/notify_user.php index 5268b85a42..292be57f5f 100644 --- a/phpBB/phpbb/install/module/install_finish/task/notify_user.php +++ b/phpBB/phpbb/install/module/install_finish/task/notify_user.php @@ -87,9 +87,13 @@ class notify_user extends \phpbb\install\task_base $this->php_ext = $php_ext; // We need to reload config for cases when it doesn't have all values + /** @var \phpbb\cache\driver\driver_interface $cache */ + $cache = $container->get('cache.driver'); + $cache->destroy('config'); + $this->config = new db( $container->get('dbal.conn'), - $container->get('cache.driver'), + $cache, $container->get_parameter('tables.config') ); diff --git a/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php b/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php index 8629d9aea3..34541c361e 100644 --- a/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php +++ b/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php @@ -13,11 +13,20 @@ namespace phpbb\install\module\install_finish\task; +use phpbb\install\exception\resource_limit_reached_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\container_factory; + /** * Populates migrations */ class populate_migrations extends \phpbb\install\task_base { + /** + * @var config + */ + protected $config; + /** * @var \phpbb\extension\manager */ @@ -31,10 +40,12 @@ class populate_migrations extends \phpbb\install\task_base /** * Constructor * - * @param \phpbb\install\helper\container_factory $container phpBB's DI contianer + * @param config $config Installer's config + * @param container_factory $container phpBB's DI contianer */ - public function __construct(\phpbb\install\helper\container_factory $container) + public function __construct(config $config, container_factory $container) { + $this->config = $config; $this->extension_manager = $container->get('ext.manager'); $this->migrator = $container->get('migrator'); @@ -46,6 +57,15 @@ class populate_migrations extends \phpbb\install\task_base */ public function run() { + if (!$this->config->get('populate_migration_refresh_before', false)) + { + if ($this->config->get_time_remaining() < 1) + { + $this->config->set('populate_migration_refresh_before', true); + throw new resource_limit_reached_exception(); + } + } + $finder = $this->extension_manager->get_finder(); $migrations = $finder -- cgit v1.2.1 From 7c0fb563ec995d0d1fcb24d885a7d9d18838ed9c Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Fri, 12 Feb 2016 15:38:34 +0100 Subject: [ticket/14462] Fix CS and typo PHPBB3-14462 --- phpBB/phpbb/install/helper/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php index 94abf9ca0b..fad6749019 100644 --- a/phpBB/phpbb/install/helper/config.php +++ b/phpBB/phpbb/install/helper/config.php @@ -95,7 +95,7 @@ class config $this->installer_config = array(); $this->system_data = array(); $this->progress_data = array( - 'last_task_module_neme' => '', // Stores the service name of the latest finished module + 'last_task_module_name' => '', // Stores the service name of the latest finished module 'last_task_module_index' => 0, // Stores the index of the latest finished module 'last_task_index' => 0, // Stores the index of the latest finished task 'max_task_progress' => 0, -- cgit v1.2.1 From 2efceffaebd96fd6d092c4be8c854a7bcf032592 Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Fri, 12 Feb 2016 23:30:32 +0100 Subject: [ticket/14462] Fix comments PHPBB3-14462 --- phpBB/phpbb/install/installer.php | 2 +- phpBB/phpbb/install/module/install_data/task/add_bots.php | 2 +- phpBB/phpbb/install/module/install_data/task/add_modules.php | 10 +++++----- .../module/install_database/task/add_config_settings.php | 2 +- .../install/module/install_database/task/add_default_data.php | 2 +- .../phpbb/install/module/install_database/task/add_tables.php | 2 +- phpBB/phpbb/install/module_base.php | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index adf0ec8ac2..b5709e96c7 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -284,7 +284,7 @@ class installer } catch (cannot_build_container_exception $e) { - // Do not do anything, this is just means there is no config.php yet + // Do not do anything, this just means there is no config.php yet } } else diff --git a/phpBB/phpbb/install/module/install_data/task/add_bots.php b/phpBB/phpbb/install/module/install_data/task/add_bots.php index b22c8257e4..d45a6839a0 100644 --- a/phpBB/phpbb/install/module/install_data/task/add_bots.php +++ b/phpBB/phpbb/install/module/install_data/task/add_bots.php @@ -229,7 +229,7 @@ class add_bots extends \phpbb\install\task_base $i++; - // Run until there are available resources + // Stop execution if resource limit is reached if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) { break; diff --git a/phpBB/phpbb/install/module/install_data/task/add_modules.php b/phpBB/phpbb/install/module/install_data/task/add_modules.php index 2f3a25a9c2..d21a5be823 100644 --- a/phpBB/phpbb/install/module/install_data/task/add_modules.php +++ b/phpBB/phpbb/install/module/install_data/task/add_modules.php @@ -243,7 +243,7 @@ class add_modules extends \phpbb\install\task_base $k++; - // Run until there are available resources + // Stop execution if resource limit is reached if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) { $timed_out = true; @@ -300,7 +300,7 @@ class add_modules extends \phpbb\install\task_base $k++; - // Run until there are available resources + // Stop execution if resource limit is reached if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) { $timed_out = true; @@ -310,7 +310,7 @@ class add_modules extends \phpbb\install\task_base $this->config->set('module_info_index', $k); - // Run until there are available resources + // Stop execution if resource limit is reached if ($timed_out) { throw new resource_limit_reached_exception(); @@ -322,7 +322,7 @@ class add_modules extends \phpbb\install\task_base $this->order_modules($module_class); $this->config->set('modules_ordered', true); - // Run until there are available resources + // Stop execution if resource limit is reached if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) { throw new resource_limit_reached_exception(); @@ -348,7 +348,7 @@ class add_modules extends \phpbb\install\task_base $this->config->set('modules_ordered', false); $this->config->set('module_categories_array', array()); - // Run until there are available resources + // Stop execution if resource limit is reached if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) { break; diff --git a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php index 5fd99638c2..20b7679ec1 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php +++ b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php @@ -329,7 +329,7 @@ class add_config_settings extends \phpbb\install\task_base $i++; - // Run until there are available resources + // Stop execution if resource limit is reached if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) { break; diff --git a/phpBB/phpbb/install/module/install_database/task/add_default_data.php b/phpBB/phpbb/install/module/install_database/task/add_default_data.php index dd1829e6ed..f5157637ee 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_default_data.php +++ b/phpBB/phpbb/install/module/install_database/task/add_default_data.php @@ -112,7 +112,7 @@ class add_default_data extends \phpbb\install\task_base $i++; - // Run until there are available resources + // Stop execution if resource limit is reached if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) { break; diff --git a/phpBB/phpbb/install/module/install_database/task/add_tables.php b/phpBB/phpbb/install/module/install_database/task/add_tables.php index a0b19950be..f344f91582 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_tables.php +++ b/phpBB/phpbb/install/module/install_database/task/add_tables.php @@ -114,7 +114,7 @@ class add_tables extends \phpbb\install\task_base $table_data ); - // Run until there are available resources + // Stop execution if resource limit is reached if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) { break; diff --git a/phpBB/phpbb/install/module_base.php b/phpBB/phpbb/install/module_base.php index f75e8cda02..527447b4a1 100644 --- a/phpBB/phpbb/install/module_base.php +++ b/phpBB/phpbb/install/module_base.php @@ -171,7 +171,7 @@ abstract class module_base implements module_interface $this->iohandler->send_response(); - // Run until there are available resources + // Stop execution if resource limit is reached if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) { throw new resource_limit_reached_exception(); -- cgit v1.2.1 From d34ffda9c1a8ac4354e6fd6cb05124de66d87f71 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 5 Feb 2016 20:30:02 +0100 Subject: [ticket/14457] Uses a random placeholder to inject css and js PHPBB3-14457 --- phpBB/phpbb/template/twig/definition.php | 5 +--- phpBB/phpbb/template/twig/environment.php | 38 +++++++++++++------------------ 2 files changed, 17 insertions(+), 26 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/definition.php b/phpBB/phpbb/template/twig/definition.php index 205f0e68ee..cb3c953692 100644 --- a/phpBB/phpbb/template/twig/definition.php +++ b/phpBB/phpbb/template/twig/definition.php @@ -19,10 +19,7 @@ namespace phpbb\template\twig; class definition { /** @var array **/ - protected $definitions = array( - 'SCRIPTS' => '__SCRIPTS_PLACEHOLDER__', - 'STYLESHEETS' => '__STYLESHEETS_PLACEHOLDER__' - ); + protected $definitions = array(); /** * Get a DEFINE'd variable diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 5660ddc3a4..8b35497122 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -195,9 +195,7 @@ class environment extends \Twig_Environment */ public function render($name, array $context = []) { - $output = parent::render($name, $context); - - return $this->inject_assets($output); + return $this->display_with_assets($name, $context); } /** @@ -205,26 +203,22 @@ class environment extends \Twig_Environment */ public function display($name, array $context = []) { - $level = ob_get_level(); - ob_start(); + echo $this->display_with_assets($name, $context); + } - try - { - parent::display($name, $context); - } - catch (\Exception $e) - { - while (ob_get_level() > $level) - { - ob_end_clean(); - } + /** + * {@inheritdoc} + */ + private function display_with_assets($name, array $context = []) + { + $placeholder_salt = unique_id(); - throw $e; - } + $context['definition']->set('SCRIPTS', '__SCRIPTS_'.$placeholder_salt.'__'); + $context['definition']->set('STYLESHEETS', '__STYLESHEETS_'.$placeholder_salt.'__'); - $output = ob_get_clean(); + $output = parent::render($name, $context); - echo $this->inject_assets($output); + return $this->inject_assets($output, $placeholder_salt); } /** @@ -234,10 +228,10 @@ class environment extends \Twig_Environment * * @return string */ - private function inject_assets($output) + private function inject_assets($output, $placeholder_salt) { - $output = str_replace('__STYLESHEETS_PLACEHOLDER__', $this->assets_bag->get_stylesheets_content(), $output); - $output = str_replace('__SCRIPTS_PLACEHOLDER__', $this->assets_bag->get_scripts_content(), $output); + $output = str_replace('__SCRIPTS_'.$placeholder_salt.'__', $this->assets_bag->get_stylesheets_content(), $output); + $output = str_replace('__STYLESHEETS_'.$placeholder_salt.'__', $this->assets_bag->get_scripts_content(), $output); return $output; } -- cgit v1.2.1 From f253a853b8381a343f98c29bb399c8128695b696 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 5 Feb 2016 21:21:41 +0100 Subject: [ticket/14457] Fix twig/twig::assign_display PHPBB3-14457 --- phpBB/phpbb/template/twig/twig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php index 6b3cf32bc8..f322778eda 100644 --- a/phpBB/phpbb/template/twig/twig.php +++ b/phpBB/phpbb/template/twig/twig.php @@ -335,7 +335,7 @@ class twig extends \phpbb\template\base return $this->twig->render($this->get_filename_from_handle($handle), $this->get_template_vars()); } - $this->assign_var($template_var, $this->twig->render($this->get_filename_from_handle($handle, $this->get_template_vars()))); + $this->assign_var($template_var, $this->twig->render($this->get_filename_from_handle($handle), $this->get_template_vars())); return $this; } -- cgit v1.2.1 From f7c5098c60688ab8553732d5129680c959355e15 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 7 Feb 2016 12:23:21 +0100 Subject: [ticket/14457] CS PHPBB3-14457 --- phpBB/phpbb/template/twig/environment.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 8b35497122..27a475f046 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -213,8 +213,8 @@ class environment extends \Twig_Environment { $placeholder_salt = unique_id(); - $context['definition']->set('SCRIPTS', '__SCRIPTS_'.$placeholder_salt.'__'); - $context['definition']->set('STYLESHEETS', '__STYLESHEETS_'.$placeholder_salt.'__'); + $context['definition']->set('SCRIPTS', '__SCRIPTS_' . $placeholder_salt . '__'); + $context['definition']->set('STYLESHEETS', '__STYLESHEETS_' . $placeholder_salt . '__'); $output = parent::render($name, $context); @@ -230,8 +230,8 @@ class environment extends \Twig_Environment */ private function inject_assets($output, $placeholder_salt) { - $output = str_replace('__SCRIPTS_'.$placeholder_salt.'__', $this->assets_bag->get_stylesheets_content(), $output); - $output = str_replace('__STYLESHEETS_'.$placeholder_salt.'__', $this->assets_bag->get_scripts_content(), $output); + $output = str_replace('__SCRIPTS_' . $placeholder_salt . '__', $this->assets_bag->get_stylesheets_content(), $output); + $output = str_replace('__STYLESHEETS_' . $placeholder_salt . '__', $this->assets_bag->get_scripts_content(), $output); return $output; } -- cgit v1.2.1 From 99ace63e62fddc934eded20afc6a7aebbc05e13b Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 7 Feb 2016 12:49:00 +0100 Subject: [ticket/14457] Don't set CSS to JS and JS to CSS PHPBB3-14457 --- phpBB/phpbb/template/twig/environment.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 27a475f046..65f1af5d9e 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -230,8 +230,8 @@ class environment extends \Twig_Environment */ private function inject_assets($output, $placeholder_salt) { - $output = str_replace('__SCRIPTS_' . $placeholder_salt . '__', $this->assets_bag->get_stylesheets_content(), $output); - $output = str_replace('__STYLESHEETS_' . $placeholder_salt . '__', $this->assets_bag->get_scripts_content(), $output); + $output = str_replace('__STYLESHEETS_' . $placeholder_salt . '__', $this->assets_bag->get_stylesheets_content(), $output); + $output = str_replace('__SCRIPTS_' . $placeholder_salt . '__', $this->assets_bag->get_scripts_content(), $output); return $output; } -- cgit v1.2.1 From 97bbf2d2b8b5b7689432ad8a35e96c38fd869dd7 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 7 Feb 2016 14:35:42 +0100 Subject: [ticket/14457] Handle the case where there isn't any 'definition' bag PHPBB3-14457 --- phpBB/phpbb/template/twig/environment.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 65f1af5d9e..56c85c8d71 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -213,8 +213,11 @@ class environment extends \Twig_Environment { $placeholder_salt = unique_id(); - $context['definition']->set('SCRIPTS', '__SCRIPTS_' . $placeholder_salt . '__'); - $context['definition']->set('STYLESHEETS', '__STYLESHEETS_' . $placeholder_salt . '__'); + if (array_key_exists('definition', $context)) + { + $context['definition']->set('SCRIPTS', '__SCRIPTS_' . $placeholder_salt . '__'); + $context['definition']->set('STYLESHEETS', '__STYLESHEETS_' . $placeholder_salt . '__'); + } $output = parent::render($name, $context); -- cgit v1.2.1 From 632418ad6e844c3d71a16a47cac8ae3a22a02f1e Mon Sep 17 00:00:00 2001 From: Mark Shaw Date: Thu, 18 Feb 2016 23:56:53 -0500 Subject: [ticket/14489] Fix bug where extension custom compiler pass cannot be found. This is returning an extra / on my machine which throws off the next code block, and then the class can't be found. PHPBB3-14489 --- phpBB/phpbb/di/container_builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 9583da14f5..2fb248082f 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -589,7 +589,7 @@ class container_builder ->ignoreUnreadableDirs(true) ->ignoreVCS(true) ->followLinks() - ->in($this->phpbb_root_path . 'ext/') + ->in($this->phpbb_root_path . 'ext') ; /** @var \SplFileInfo $pass */ -- cgit v1.2.1 From 294f926bfccc6be8a7098923b4c55ebab66e83e3 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 24 Feb 2016 22:24:08 +0100 Subject: [ticket/14495] Updates the version to 3.3.0-a1-dev PHPBB3-14495 --- phpBB/phpbb/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/composer.json b/phpBB/phpbb/composer.json index 758125234f..0b6299d6bc 100644 --- a/phpBB/phpbb/composer.json +++ b/phpBB/phpbb/composer.json @@ -26,7 +26,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-master": "3.3.x-dev" } } } -- cgit v1.2.1 From 5bdfc6167ba13fc525470f89602889ff5bc3ed79 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 25 Feb 2016 22:39:42 +0100 Subject: [ticket/14499] Add command to update the board from CLI PHPBB3-14499 --- .../console/command/install/config/show.php | 12 +- .../console/command/install/config/validate.php | 10 +- .../install/console/command/install/install.php | 2 +- .../install/console/command/update/config/show.php | 123 ++++++++++++++ .../console/command/update/config/validate.php | 124 +++++++++++++++ .../install/console/command/update/update.php | 176 +++++++++++++++++++++ .../obtain_data/task/obtain_update_settings.php | 8 + .../module/requirements/task/check_update.php | 2 +- phpBB/phpbb/install/updater_configuration.php | 40 +++++ 9 files changed, 476 insertions(+), 21 deletions(-) create mode 100644 phpBB/phpbb/install/console/command/update/config/show.php create mode 100644 phpBB/phpbb/install/console/command/update/config/validate.php create mode 100644 phpBB/phpbb/install/console/command/update/update.php create mode 100644 phpBB/phpbb/install/updater_configuration.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/console/command/install/config/show.php b/phpBB/phpbb/install/console/command/install/config/show.php index 5d82d8d1ef..b6c11956fe 100644 --- a/phpBB/phpbb/install/console/command/install/config/show.php +++ b/phpBB/phpbb/install/console/command/install/config/show.php @@ -14,7 +14,6 @@ namespace phpbb\install\console\command\install\config; use phpbb\install\helper\iohandler\factory; -use phpbb\install\installer; use phpbb\install\installer_configuration; use phpbb\language\language; use Symfony\Component\Config\Definition\Exception\Exception; @@ -33,11 +32,6 @@ class show extends \phpbb\console\command\command */ protected $iohandler_factory; - /** - * @var installer - */ - protected $installer; - /** * @var language */ @@ -48,12 +42,10 @@ class show extends \phpbb\console\command\command * * @param language $language * @param factory $factory - * @param installer $installer */ - public function __construct(language $language, factory $factory, installer $installer) + public function __construct(language $language, factory $factory) { $this->iohandler_factory = $factory; - $this->installer = $installer; $this->language = $language; parent::__construct(new \phpbb\user($language, 'datetime')); @@ -126,6 +118,6 @@ class show extends \phpbb\console\command\command return; } - $iohandler->add_log_message(Yaml::dump(array('installer' => $config), 10, 4, true, false)); + $style->block(Yaml::dump(array('installer' => $config), 10, 4, true, false)); } } diff --git a/phpBB/phpbb/install/console/command/install/config/validate.php b/phpBB/phpbb/install/console/command/install/config/validate.php index 3bbbc23e34..b48a1acbd4 100644 --- a/phpBB/phpbb/install/console/command/install/config/validate.php +++ b/phpBB/phpbb/install/console/command/install/config/validate.php @@ -14,7 +14,6 @@ namespace phpbb\install\console\command\install\config; use phpbb\install\helper\iohandler\factory; -use phpbb\install\installer; use phpbb\install\installer_configuration; use phpbb\language\language; use Symfony\Component\Config\Definition\Exception\Exception; @@ -33,11 +32,6 @@ class validate extends \phpbb\console\command\command */ protected $iohandler_factory; - /** - * @var installer - */ - protected $installer; - /** * @var language */ @@ -48,12 +42,10 @@ class validate extends \phpbb\console\command\command * * @param language $language * @param factory $factory - * @param installer $installer */ - public function __construct(language $language, factory $factory, installer $installer) + public function __construct(language $language, factory $factory) { $this->iohandler_factory = $factory; - $this->installer = $installer; $this->language = $language; parent::__construct(new \phpbb\user($language, 'datetime')); diff --git a/phpBB/phpbb/install/console/command/install/install.php b/phpBB/phpbb/install/console/command/install/install.php index d76182af92..50c23f6877 100644 --- a/phpBB/phpbb/install/console/command/install/install.php +++ b/phpBB/phpbb/install/console/command/install/install.php @@ -109,7 +109,7 @@ class install extends \phpbb\console\command\command if ($this->install_helper->is_phpbb_installed()) { - $iohandler->add_error_message('PHPBB_ALREADY_INSTALLED'); + $iohandler->add_error_message('INSTALL_PHPBB_INSTALLED'); return 1; } diff --git a/phpBB/phpbb/install/console/command/update/config/show.php b/phpBB/phpbb/install/console/command/update/config/show.php new file mode 100644 index 0000000000..e462763b5d --- /dev/null +++ b/phpBB/phpbb/install/console/command/update/config/show.php @@ -0,0 +1,123 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\install\console\command\update\config; + +use phpbb\install\helper\iohandler\factory; +use phpbb\install\updater_configuration; +use phpbb\language\language; +use Symfony\Component\Config\Definition\Exception\Exception; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Yaml; + +class show extends \phpbb\console\command\command +{ + /** + * @var factory + */ + protected $iohandler_factory; + + /** + * @var language + */ + protected $language; + + /** + * Constructor + * + * @param language $language + * @param factory $factory + */ + public function __construct(language $language, factory $factory) + { + $this->iohandler_factory = $factory; + $this->language = $language; + + parent::__construct(new \phpbb\user($language, 'datetime')); + } + + /** + * + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('update:config:show') + ->addArgument( + 'config-file', + InputArgument::REQUIRED, + $this->language->lang('CLI_CONFIG_FILE')) + ->setDescription($this->language->lang('CLI_INSTALL_SHOW_CONFIG')) + ; + } + + /** + * Show the validated configuration + * + * @param InputInterface $input An InputInterface instance + * @param OutputInterface $output An OutputInterface instance + * + * @return null + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->iohandler_factory->set_environment('cli'); + + /** @var \phpbb\install\helper\iohandler\cli_iohandler $iohandler */ + $iohandler = $this->iohandler_factory->get(); + $style = new SymfonyStyle($input, $output); + $iohandler->set_style($style, $output); + + $config_file = $input->getArgument('config-file'); + + if (!is_file($config_file)) + { + $iohandler->add_error_message(array('MISSING_FILE', $config_file)); + + return; + } + + try + { + $config = Yaml::parse(file_get_contents($config_file), true, false); + } + catch (ParseException $e) + { + $iohandler->add_error_message('INVALID_YAML_FILE'); + + return; + } + + $processor = new Processor(); + $configuration = new updater_configuration(); + + try + { + $config = $processor->processConfiguration($configuration, $config); + } + catch (Exception $e) + { + $iohandler->add_error_message('INVALID_CONFIGURATION', $e->getMessage()); + + return; + } + + $style->block(Yaml::dump(array('updater' => $config), 10, 4, true, false)); + } +} diff --git a/phpBB/phpbb/install/console/command/update/config/validate.php b/phpBB/phpbb/install/console/command/update/config/validate.php new file mode 100644 index 0000000000..18de5eab46 --- /dev/null +++ b/phpBB/phpbb/install/console/command/update/config/validate.php @@ -0,0 +1,124 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\install\console\command\update\config; + +use phpbb\install\helper\iohandler\factory; +use phpbb\install\updater_configuration; +use phpbb\language\language; +use Symfony\Component\Config\Definition\Exception\Exception; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Yaml; + +class validate extends \phpbb\console\command\command +{ + /** + * @var factory + */ + protected $iohandler_factory; + + /** + * @var language + */ + protected $language; + + /** + * Constructor + * + * @param language $language + * @param factory $factory + */ + public function __construct(language $language, factory $factory) + { + $this->iohandler_factory = $factory; + $this->language = $language; + + parent::__construct(new \phpbb\user($language, 'datetime')); + } + + /** + * + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('update:config:validate') + ->addArgument( + 'config-file', + InputArgument::REQUIRED, + $this->language->lang('CLI_CONFIG_FILE')) + ->setDescription($this->language->lang('CLI_INSTALL_VALIDATE_CONFIG')) + ; + } + + /** + * Validate the configuration file + * + * @param InputInterface $input An InputInterface instance + * @param OutputInterface $output An OutputInterface instance + * + * @return null + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->iohandler_factory->set_environment('cli'); + + /** @var \phpbb\install\helper\iohandler\cli_iohandler $iohandler */ + $iohandler = $this->iohandler_factory->get(); + $style = new SymfonyStyle($input, $output); + $iohandler->set_style($style, $output); + + $config_file = $input->getArgument('config-file'); + + if (!is_file($config_file)) + { + $iohandler->add_error_message(array('MISSING_FILE', array($config_file))); + + return 1; + } + + try + { + $config = Yaml::parse(file_get_contents($config_file), true, false); + } + catch (ParseException $e) + { + $iohandler->add_error_message('INVALID_YAML_FILE'); + + return 1; + } + + $processor = new Processor(); + $configuration = new updater_configuration(); + + try + { + $processor->processConfiguration($configuration, $config); + } + catch (Exception $e) + { + $iohandler->add_error_message('INVALID_CONFIGURATION', $e->getMessage()); + + return 1; + } + + $iohandler->add_success_message('CONFIGURATION_VALID'); + return 0; + } +} diff --git a/phpBB/phpbb/install/console/command/update/update.php b/phpBB/phpbb/install/console/command/update/update.php new file mode 100644 index 0000000000..8e0d45172c --- /dev/null +++ b/phpBB/phpbb/install/console/command/update/update.php @@ -0,0 +1,176 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\install\console\command\update; + +use phpbb\install\exception\installer_exception; +use phpbb\install\helper\install_helper; +use phpbb\install\helper\iohandler\cli_iohandler; +use phpbb\install\helper\iohandler\factory; +use phpbb\install\installer; +use phpbb\install\updater_configuration; +use phpbb\language\language; +use Symfony\Component\Config\Definition\Exception\Exception; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Yaml; + +class update extends \phpbb\console\command\command +{ + /** + * @var factory + */ + protected $iohandler_factory; + + /** + * @var installer + */ + protected $installer; + + /** + * @var install_helper + */ + protected $install_helper; + + /** + * @var language + */ + protected $language; + + /** + * Constructor + * + * @param language $language + * @param factory $factory + * @param installer $installer + * @param install_helper $install_helper + */ + public function __construct(language $language, factory $factory, installer $installer, install_helper $install_helper) + { + $this->iohandler_factory = $factory; + $this->installer = $installer; + $this->language = $language; + $this->install_helper = $install_helper; + + parent::__construct(new \phpbb\user($language, 'datetime')); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('update') + ->addArgument( + 'config-file', + InputArgument::REQUIRED, + $this->language->lang('CLI_CONFIG_FILE')) + ->setDescription($this->language->lang('CLI_UPDATE_BOARD')) + ; + } + + /** + * Executes the command update. + * + * Install the board + * + * @param InputInterface $input An InputInterface instance + * @param OutputInterface $output An OutputInterface instance + * + * @return int + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->iohandler_factory->set_environment('cli'); + + /** @var \phpbb\install\helper\iohandler\cli_iohandler $iohandler */ + $iohandler = $this->iohandler_factory->get(); + $style = new SymfonyStyle($input, $output); + $iohandler->set_style($style, $output); + + $this->installer->set_iohandler($iohandler); + + $config_file = $input->getArgument('config-file'); + + if (!$this->install_helper->is_phpbb_installed()) + { + $iohandler->add_error_message('INSTALL_PHPBB_NOT_INSTALLED'); + + return 1; + } + + if (!is_file($config_file)) + { + $iohandler->add_error_message(array('MISSING_FILE', $config_file)); + + return 1; + } + + try + { + $config = Yaml::parse(file_get_contents($config_file), true, false); + } + catch (ParseException $e) + { + $iohandler->add_error_message(array('INVALID_YAML_FILE', $config_file)); + + return 1; + } + + $processor = new Processor(); + $configuration = new updater_configuration(); + + try + { + $config = $processor->processConfiguration($configuration, $config); + } + catch (Exception $e) + { + $iohandler->add_error_message('INVALID_CONFIGURATION', $e->getMessage()); + + return 1; + } + + $this->register_configuration($iohandler, $config); + + try + { + $this->installer->run(); + } + catch (installer_exception $e) + { + $iohandler->add_error_message($e->getMessage()); + return 1; + } + } + + /** + * Register the configuration to simulate the forms. + * + * @param cli_iohandler $iohandler + * @param array $config + */ + private function register_configuration(cli_iohandler $iohandler, $config) + { + $iohandler->set_input('update_type', $config['type']); + $iohandler->set_input('submit_update', 'submit'); + + $iohandler->set_input('method', '.tar'); + $iohandler->set_input('submit_update_file', 'submit'); + } +} diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php index c139b70fa4..3b24e8ba40 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php @@ -53,6 +53,14 @@ class obtain_update_settings extends task_base if ($this->iohandler->get_input('submit_update', false)) { $update_files = $this->iohandler->get_input('update_type', 'all') === 'all'; + + if ($this->installer_config->get('disable_filesystem_update', false) && $update_files) + { + $this->iohandler->add_error_message('UPDATE_FILES_NOT_FOUND'); + + throw new user_interaction_required_exception(); + } + $this->installer_config->set('do_update_files', $update_files); } else diff --git a/phpBB/phpbb/install/module/requirements/task/check_update.php b/phpBB/phpbb/install/module/requirements/task/check_update.php index 4e9124ff47..cd66ffc8f9 100644 --- a/phpBB/phpbb/install/module/requirements/task/check_update.php +++ b/phpBB/phpbb/install/module/requirements/task/check_update.php @@ -122,7 +122,7 @@ class check_update extends task_base // Check for a valid update directory if (!$this->filesystem->exists($update_files) || !$this->filesystem->is_readable($update_files)) { - $this->iohandler->add_error_message('UPDATE_FILES_NOT_FOUND'); + $this->iohandler->add_warning_message('UPDATE_FILES_NOT_FOUND'); $this->set_test_passed(false); // If there are no update files, we can't check the version etc diff --git a/phpBB/phpbb/install/updater_configuration.php b/phpBB/phpbb/install/updater_configuration.php new file mode 100644 index 0000000000..e992356290 --- /dev/null +++ b/phpBB/phpbb/install/updater_configuration.php @@ -0,0 +1,40 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\install; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +class updater_configuration implements ConfigurationInterface +{ + + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('updater'); + $rootNode + ->addDefaultsIfNotSet() + ->children() + ->enumNode('type')->values(['all','db_only'])->defaultValue('all')->end() + ->end() + ; + + return $treeBuilder; + } +} -- cgit v1.2.1 From 062358f8b1d9a7fa3d9be97f6b58e06fea7ca844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Sun, 28 Feb 2016 00:19:24 +0100 Subject: [ticket/14487] Try to handle connection timeouts PHPBB3-14487 --- phpBB/phpbb/install/controller/timeout_check.php | 80 ++++++++++++++++++++++ .../install/helper/iohandler/ajax_iohandler.php | 41 ++++++++++- phpBB/phpbb/install/installer.php | 22 +++++- 3 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 phpBB/phpbb/install/controller/timeout_check.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/controller/timeout_check.php b/phpBB/phpbb/install/controller/timeout_check.php new file mode 100644 index 0000000000..1c90e3caf3 --- /dev/null +++ b/phpBB/phpbb/install/controller/timeout_check.php @@ -0,0 +1,80 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\controller; + +use Symfony\Component\HttpFoundation\JsonResponse; + +class timeout_check +{ + /** + * @var helper + */ + protected $helper; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * Constructor + * + * @param helper $helper + * @param string $phpbb_root_path + */ + public function __construct(helper $helper, $phpbb_root_path) + { + $this->helper = $helper; + $this->phpbb_root_path = $phpbb_root_path; + } + + /** + * Controller for querying installer status + */ + public function status() + { + $lock_file = $this->phpbb_root_path . 'store/io_lock.lock'; + $response = new JsonResponse(); + + if (!file_exists($lock_file)) + { + $response->setData(array( + 'status' => 'fail', + )); + } + else + { + $fp = @fopen($lock_file, 'r'); + + if ($fp && flock($fp, LOCK_EX | LOCK_NB)) + { + $status = (filesize($lock_file) >= 2 && fread($fp, 2) === 'ok') ? 'continue' : 'fail'; + + $response->setData(array( + 'status' => $status, + )); + flock($fp, LOCK_UN); + fclose($fp); + } + else + { + $response->setData(array( + 'status' => 'running', + )); + } + } + + return $response; + } +} diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php index 8c62ec7bd0..c168d26425 100644 --- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -41,6 +41,11 @@ class ajax_iohandler extends iohandler_base */ protected $router; + /** + * @var string + */ + protected $phpbb_root_path; + /** * @var string */ @@ -76,6 +81,11 @@ class ajax_iohandler extends iohandler_base */ protected $redirect_url; + /** + * @var resource + */ + protected $file_lock_pointer; + /** * Constructor * @@ -83,8 +93,9 @@ class ajax_iohandler extends iohandler_base * @param \phpbb\request\request_interface $request HTTP request interface * @param \phpbb\template\template $template Template engine * @param router $router Router + * @param string $root_path Path to phpBB's root */ - public function __construct(path_helper $path_helper, \phpbb\request\request_interface $request, \phpbb\template\template $template, router $router) + public function __construct(path_helper $path_helper, \phpbb\request\request_interface $request, \phpbb\template\template $template, router $router, $root_path) { $this->path_helper = $path_helper; $this->request = $request; @@ -96,6 +107,7 @@ class ajax_iohandler extends iohandler_base $this->download = array(); $this->redirect_url = array(); $this->file_status = ''; + $this->phpbb_root_path = $root_path; parent::__construct(); } @@ -432,6 +444,33 @@ class ajax_iohandler extends iohandler_base $this->send_response(true); } + /** + * Acquires a file lock + */ + public function acquire_lock() + { + $lock_file = $this->phpbb_root_path . 'store/io_lock.lock'; + $this->file_lock_pointer = @fopen($lock_file, 'w+'); + + if ($this->file_lock_pointer) + { + flock($this->file_lock_pointer, LOCK_EX); + } + } + + /** + * Release file lock + */ + public function release_lock() + { + if ($this->file_lock_pointer) + { + fwrite($this->file_lock_pointer, 'ok'); + flock($this->file_lock_pointer, LOCK_UN); + fclose($this->file_lock_pointer); + } + } + /** * Callback function for language replacing * diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index b5709e96c7..240423ae78 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -22,6 +22,7 @@ use phpbb\install\exception\resource_limit_reached_exception; use phpbb\install\exception\user_interaction_required_exception; use phpbb\install\helper\config; use phpbb\install\helper\container_factory; +use phpbb\install\helper\iohandler\ajax_iohandler; use phpbb\install\helper\iohandler\cli_iohandler; use phpbb\install\helper\iohandler\iohandler_interface; use phpbb\path_helper; @@ -126,6 +127,11 @@ class installer */ public function run() { + if ($this->iohandler instanceof ajax_iohandler) + { + $this->iohandler->acquire_lock(); + } + // Load install progress $this->install_config->load_config(); @@ -174,7 +180,16 @@ class installer try { $iterator = $this->installer_modules->getIterator(); - $iterator->seek($module_index); + + if ($module_index < $iterator->count()) + { + $iterator->seek($module_index); + } + else + { + $iterator->seek($module_index - 1); + $iterator->next(); + } while ($iterator->valid()) { @@ -256,6 +271,11 @@ class installer $fail_cleanup = true; } + if ($this->iohandler instanceof ajax_iohandler) + { + $this->iohandler->release_lock(); + } + if ($install_finished) { // Send install finished message -- cgit v1.2.1 From 8ec1a60156f66dd4fe0f0f6e2cfbee1c79132771 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 28 Feb 2016 20:49:18 +0100 Subject: [ticket/14499] Add missing config settings PHPBB3-14499 --- phpBB/phpbb/install/console/command/update/update.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/console/command/update/update.php b/phpBB/phpbb/install/console/command/update/update.php index 8e0d45172c..dfac13d5d7 100644 --- a/phpBB/phpbb/install/console/command/update/update.php +++ b/phpBB/phpbb/install/console/command/update/update.php @@ -170,7 +170,10 @@ class update extends \phpbb\console\command\command $iohandler->set_input('update_type', $config['type']); $iohandler->set_input('submit_update', 'submit'); - $iohandler->set_input('method', '.tar'); + $iohandler->set_input('compression_method', '.tar'); + $iohandler->set_input('method', 'direct_file'); $iohandler->set_input('submit_update_file', 'submit'); + + $iohandler->set_input('submit_continue_file_update', 'submit'); } } -- cgit v1.2.1 From 0102fa3f2d051173762736b6a1a1ba15be466b15 Mon Sep 17 00:00:00 2001 From: LEZY Thomas Date: Tue, 10 Jun 2014 11:07:46 +0200 Subject: [ticket/12684] Add command user:add PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 167 +++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 phpBB/phpbb/console/command/user/add.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php new file mode 100644 index 0000000000..e7a94a74da --- /dev/null +++ b/phpBB/phpbb/console/command/user/add.php @@ -0,0 +1,167 @@ +user = $user; + $this->db = $db; + $this->config = $config; + $this->password_manager = $password_manager; + + $this->user->add_lang('ucp'); + parent::__construct(); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('user:add') + ->setDescription($this->user->lang('CLI_DESCRIPTION_USER_ADD')) + ->addOption('username', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_USER_ADD_OPTION_USERNAME')) + ->addOption('password', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_USER_ADD_OPTION_PASSWORD')) + ->addOption('email', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_USER_ADD_OPTION_EMAIL')) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $dialog = $this->getHelperSet()->get('dialog'); + + $username = $input->getOption('username'); + if (!$username) { + $username = $dialog->ask( + $output, + $this->user->lang('USERNAME') . $this->user->lang('COLON') . ' ', + null + ); + } + + $password = $input->getOption('password'); + if (!$password) + { + $password = $this->get_password($output, $dialog); + } + + $email = $input->getOption('email'); + if (!$email) + { + $email = $dialog->ask( + $output, + $this->user->lang('EMAIL_ADDRESS') . $this->user->lang('COLON') . ' ', + null + ); + } + + try + { + $group_id = $this->get_group_id(); + } + catch (\RunTimeException $e) + { + $output->writeln($e->getMessage()); + return 1; + } + + $user_row = array( + 'username' => $username, + 'user_password' => $this->password_manager->hash($password), + 'user_email' => $email, + 'group_id' => $group_id, + 'user_timezone' => $config['board_timezone'], + 'user_lang' => $config['default_lang'], + 'user_type' => USER_NORMAL, + 'user_regdate' => time(), + ); + + if (!function_exists(user_add)) + { + require_once dirname(__FILE__) . '/../../../../includes/functions_user.php'; + } + user_add($user_row); + + $output->writeln('' . $this->user->lang('SUCCESS_ADD_USER', $username) . ''); + return 0; + } + + protected function get_password($output, $dialog) + { + $current_user = $this->user; + return $dialog->askHiddenResponseAndValidate( + $output, + $current_user->lang('PASSWORD') . $current_user->lang('COLON') . ' ', + function ($answer) use ($dialog, $output, $current_user) + { + $confirm = $dialog->askHiddenResponse( + $output, + $current_user->lang('CONFIRM_PASSWORD') . $current_user->lang('COLON') . ' ', + null + ); + if ($confirm != $answer) + { + throw new \RunTimeException($current_user->lang('NEW_PASSWORD_ERROR')); + } + return $answer; + }, + false, + null + ); + } + + protected function get_group_id() + { + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = '" . $this->db->sql_escape('REGISTERED') . "' + AND group_type = " . GROUP_SPECIAL; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row) + { + throw new \RunTimeException($this->user->lang('NO_GROUP')); + } + + return $row['group_id']; + } +} -- cgit v1.2.1 From 50761104ba6590de86ec651b5679983eaf2ff600 Mon Sep 17 00:00:00 2001 From: LEZY Thomas Date: Fri, 13 Jun 2014 11:38:02 +0200 Subject: [ticket/12684] Add doc blocks and test file for user:add PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 35 +++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index e7a94a74da..e3f8243c02 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -35,6 +35,9 @@ class add extends \phpbb\console\command\command * Construct method * * @param \phpbb\user $user The user object used for language information + * @param \phpbb\db\driver\driver_interface $db The database in wich will be inserted the user + * @param \phpbb\config\config $config The config object used to get default language and timezone + * @param \phpbb\passwords\manager $password_manager The password manager used to store the user's password */ public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $password_manager) { @@ -63,6 +66,17 @@ class add extends \phpbb\console\command\command ; } + /** + * Executes the command user:add + * + * If not given in option, asks the username, password and email. + * Then a new user is added in the database, with language and timezone found in the $config passed to the constructor, and the group_id found in the database. + * + * @param InputInterface $input The input stream used to get the options + * @param OutputInterface $output The output stream, used to print messages + * + * @return int 0 if all is well, 1 if a database error occured while trying to get the group_id + */ protected function execute(InputInterface $input, OutputInterface $output) { $dialog = $this->getHelperSet()->get('dialog'); @@ -123,6 +137,17 @@ class add extends \phpbb\console\command\command return 0; } + /** + * Get the password + * + * Asks a password to the user and asks for confirmation. + * This is repeted while the two are not the same + * + * @param OutputInterface $output The output stream, where messages are printed + * @param Symfony\Component\Console\Helper\DialogHelper $dialog The dialog helper used to get answers to questions asked to the user + * + * @return null + */ protected function get_password($output, $dialog) { $current_user = $this->user; @@ -147,6 +172,14 @@ class add extends \phpbb\console\command\command ); } + /** + * Get the group id + * + * Go and find in the database the group_id corresponding to 'REGISTERED' + * + * @throws RunTimeException if the group id does not exist in database. + * @return null + */ protected function get_group_id() { $sql = 'SELECT group_id @@ -157,7 +190,7 @@ class add extends \phpbb\console\command\command $row = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - if (!$row) + if (!$row || !$row['group_id']) { throw new \RunTimeException($this->user->lang('NO_GROUP')); } -- cgit v1.2.1 From df4a620ba146d895be4910761bc030045abbae93 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 27 Aug 2014 16:56:46 +0200 Subject: [ticket/12684] Fix tests PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index e3f8243c02..fab69738e3 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -19,9 +19,6 @@ use Symfony\Component\Console\Output\OutputInterface; class add extends \phpbb\console\command\command { - /** @var \phpbb\user */ - protected $user; - /** @var \phpbb\db\driver\driver_interface */ protected $db; @@ -41,13 +38,12 @@ class add extends \phpbb\console\command\command */ public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $password_manager) { - $this->user = $user; $this->db = $db; $this->config = $config; $this->password_manager = $password_manager; - $this->user->add_lang('ucp'); - parent::__construct(); + $user->add_lang('ucp'); + parent::__construct($user); } /** @@ -121,13 +117,13 @@ class add extends \phpbb\console\command\command 'user_password' => $this->password_manager->hash($password), 'user_email' => $email, 'group_id' => $group_id, - 'user_timezone' => $config['board_timezone'], - 'user_lang' => $config['default_lang'], + 'user_timezone' => $this->config['board_timezone'], + 'user_lang' => $this->config['default_lang'], 'user_type' => USER_NORMAL, 'user_regdate' => time(), ); - if (!function_exists(user_add)) + if (!function_exists('user_add')) { require_once dirname(__FILE__) . '/../../../../includes/functions_user.php'; } @@ -144,7 +140,7 @@ class add extends \phpbb\console\command\command * This is repeted while the two are not the same * * @param OutputInterface $output The output stream, where messages are printed - * @param Symfony\Component\Console\Helper\DialogHelper $dialog The dialog helper used to get answers to questions asked to the user + * @param \Symfony\Component\Console\Helper\DialogHelper $dialog The dialog helper used to get answers to questions asked to the user * * @return null */ @@ -177,7 +173,7 @@ class add extends \phpbb\console\command\command * * Go and find in the database the group_id corresponding to 'REGISTERED' * - * @throws RunTimeException if the group id does not exist in database. + * @throws \RunTimeException if the group id does not exist in database. * @return null */ protected function get_group_id() -- cgit v1.2.1 From 8f7aba6582c3fb748ed67720292f1d236d4e1270 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 15 Sep 2014 00:13:57 +0200 Subject: [ticket/12684] Fix header file PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index fab69738e3..10b0d0f727 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -3,7 +3,7 @@ * * This file is part of the phpBB Forum Software package. * -* @copyright (c) phpBB Limited +* @copyright (c) phpBB Limited * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see -- cgit v1.2.1 From 52dffef03cb97a54041b1fba638eafb3ed0a5ce0 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 29 Feb 2016 20:27:12 +0100 Subject: [ticket/14499] Fix wording and comments PHPBB3-14499 --- phpBB/phpbb/install/console/command/update/update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/console/command/update/update.php b/phpBB/phpbb/install/console/command/update/update.php index dfac13d5d7..116f42f758 100644 --- a/phpBB/phpbb/install/console/command/update/update.php +++ b/phpBB/phpbb/install/console/command/update/update.php @@ -87,7 +87,7 @@ class update extends \phpbb\console\command\command /** * Executes the command update. * - * Install the board + * Update the board * * @param InputInterface $input An InputInterface instance * @param OutputInterface $output An OutputInterface instance -- cgit v1.2.1 From 6fe084a2fd967c188bdca827a46647120a5ea58d Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 11:38:49 -0800 Subject: [ticket/12684] Updates for 3.2 API PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 42 ++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 10b0d0f727..f3b52349b7 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -13,9 +13,11 @@ namespace phpbb\console\command\user; +use phpbb\exception\runtime_exception; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class add extends \phpbb\console\command\command { @@ -28,6 +30,19 @@ class add extends \phpbb\console\command\command /** @var \phpbb\passwords\manager */ protected $password_manager; + /** + * phpBB root path + * @var string + */ + protected $phpbb_root_path; + + /** + * PHP extension. + * + * @var string + */ + protected $php_ext; + /** * Construct method * @@ -35,12 +50,16 @@ class add extends \phpbb\console\command\command * @param \phpbb\db\driver\driver_interface $db The database in wich will be inserted the user * @param \phpbb\config\config $config The config object used to get default language and timezone * @param \phpbb\passwords\manager $password_manager The password manager used to store the user's password + * @param string $phpbb_root_path Root path + * @param string $php_ext PHP extension */ - public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $password_manager) + public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $password_manager, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; $this->password_manager = $password_manager; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; $user->add_lang('ucp'); parent::__construct($user); @@ -75,6 +94,8 @@ class add extends \phpbb\console\command\command */ protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $dialog = $this->getHelperSet()->get('dialog'); $username = $input->getOption('username'); @@ -106,9 +127,9 @@ class add extends \phpbb\console\command\command { $group_id = $this->get_group_id(); } - catch (\RunTimeException $e) + catch (runtime_exception $e) { - $output->writeln($e->getMessage()); + $io->error($e->getMessage()); return 1; } @@ -125,11 +146,12 @@ class add extends \phpbb\console\command\command if (!function_exists('user_add')) { - require_once dirname(__FILE__) . '/../../../../includes/functions_user.php'; + require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); } - user_add($user_row); - $output->writeln('' . $this->user->lang('SUCCESS_ADD_USER', $username) . ''); + $user_id = user_add($user_row); + $io->success($this->user->lang('SUCCESS_ADD_USER', $username)); + return 0; } @@ -137,7 +159,7 @@ class add extends \phpbb\console\command\command * Get the password * * Asks a password to the user and asks for confirmation. - * This is repeted while the two are not the same + * This is repeated until the password match is confirmed. * * @param OutputInterface $output The output stream, where messages are printed * @param \Symfony\Component\Console\Helper\DialogHelper $dialog The dialog helper used to get answers to questions asked to the user @@ -159,7 +181,7 @@ class add extends \phpbb\console\command\command ); if ($confirm != $answer) { - throw new \RunTimeException($current_user->lang('NEW_PASSWORD_ERROR')); + throw new runtime_exception($current_user->lang('NEW_PASSWORD_ERROR')); } return $answer; }, @@ -173,7 +195,7 @@ class add extends \phpbb\console\command\command * * Go and find in the database the group_id corresponding to 'REGISTERED' * - * @throws \RunTimeException if the group id does not exist in database. + * @throws runtime_exception if the group id does not exist in database. * @return null */ protected function get_group_id() @@ -188,7 +210,7 @@ class add extends \phpbb\console\command\command if (!$row || !$row['group_id']) { - throw new \RunTimeException($this->user->lang('NO_GROUP')); + throw new runtime_exception($this->user->lang('NO_GROUP')); } return $row['group_id']; -- cgit v1.2.1 From d373428180e884f03a830aa69fe8ff2cd6a5140a Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 11:41:47 -0800 Subject: [ticket/12684] Add input validation PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index f3b52349b7..db06037947 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -123,6 +123,22 @@ class add extends \phpbb\console\command\command ); } + $data = array( + 'username' => $username, + 'new_password' => $password, + 'email' => $email, + ); + + try + { + $this->validate_user_data($data); + } + catch (runtime_exception $e) + { + $io->error($e->getMessage()); + return 1; + } + try { $group_id = $this->get_group_id(); @@ -190,6 +206,38 @@ class add extends \phpbb\console\command\command ); } + /** + * Validate the submitted user data + * + * @param array $data The user data array + * @throws runtime_exception if any data fails validation + * @return null + */ + protected function validate_user_data($data) + { + if (!function_exists('validate_data')) + { + require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); + } + + $error = validate_data($data, array( + 'username' => array( + array('string', false, $this->config['min_name_chars'], $this->config['max_name_chars']), + array('username', '')), + 'new_password' => array( + array('string', false, $this->config['min_pass_chars'], $this->config['max_pass_chars']), + array('password')), + 'email' => array( + array('string', false, 6, 60), + array('user_email')), + )); + + if ($error) + { + throw new runtime_exception(implode("\n", array_map(array($this->user, 'lang'), $error))); + } + } + /** * Get the group id * -- cgit v1.2.1 From f32b4c0547a596fcdd935560b23ed660f3d3f87c Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 11:42:23 -0800 Subject: [ticket/12684] Add send email option PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index db06037947..57100a773c 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -78,6 +78,7 @@ class add extends \phpbb\console\command\command ->addOption('username', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_USER_ADD_OPTION_USERNAME')) ->addOption('password', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_USER_ADD_OPTION_PASSWORD')) ->addOption('email', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_USER_ADD_OPTION_EMAIL')) + ->addOption('send-email', null, InputOption::VALUE_NONE, $this->user->lang('CLI_CONFIG_PRINT_WITHOUT_NEWLINE')) ; } @@ -166,6 +167,12 @@ class add extends \phpbb\console\command\command } $user_id = user_add($user_row); + + if ($input->getOption('send-email') && $this->config['email_enable']) + { + $this->send_activation_email($user_id, $data); + } + $io->success($this->user->lang('SUCCESS_ADD_USER', $username)); return 0; @@ -263,4 +270,52 @@ class add extends \phpbb\console\command\command return $row['group_id']; } + + /** + * Send account activation email + * + * @param int $user_id The new user's id + * @param array $data The user data array + * @return null + */ + protected function send_activation_email($user_id, $data) + { + if ($this->config['require_activation'] == USER_ACTIVATION_SELF) + { + $email_template = 'user_welcome_inactive'; + $user_actkey = gen_rand_string(mt_rand(6, 10)); + } + else if ($this->config['require_activation'] == USER_ACTIVATION_ADMIN) + { + $email_template = 'admin_welcome_inactive'; + $user_actkey = gen_rand_string(mt_rand(6, 10)); + } + else + { + $email_template = 'user_welcome'; + $user_actkey = ''; + } + + if (!class_exists('messenger')) + { + require($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext); + } + + $messenger = new \messenger(false); + + $messenger->template($email_template, $this->user->lang_name); + + $messenger->to($data['email'], $data['username']); + + $messenger->anti_abuse_headers($this->config, $this->user); + + $messenger->assign_vars(array( + 'WELCOME_MSG' => htmlspecialchars_decode($this->user->lang('WELCOME_SUBJECT', $this->config['sitename'])), + 'USERNAME' => htmlspecialchars_decode($data['username']), + 'PASSWORD' => htmlspecialchars_decode($data['new_password']), + 'U_ACTIVATE' => generate_board_url() . "/ucp.{$this->php_ext}?mode=activate&u=$user_id&k=$user_actkey") + ); + + $messenger->send(NOTIFY_EMAIL); + } } -- cgit v1.2.1 From 637b02690db0d3b7af2915c1da4bacc8fa054f6c Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 13:28:42 -0800 Subject: [ticket/12684] Update to use non-deprecated methods PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 279 +++++++++++++++---------------- 1 file changed, 136 insertions(+), 143 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 57100a773c..be9f484aeb 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -1,15 +1,15 @@ -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ namespace phpbb\console\command\user; @@ -17,6 +17,7 @@ use phpbb\exception\runtime_exception; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\SymfonyStyle; class add extends \phpbb\console\command\command @@ -27,108 +28,124 @@ class add extends \phpbb\console\command\command /** @var \phpbb\config\config */ protected $config; + /** @var \phpbb\language\language */ + protected $language; + /** @var \phpbb\passwords\manager */ protected $password_manager; /** - * phpBB root path - * @var string - */ + * phpBB root path + * + * @var string + */ protected $phpbb_root_path; /** - * PHP extension. - * - * @var string - */ + * PHP extension. + * + * @var string + */ protected $php_ext; /** - * Construct method - * - * @param \phpbb\user $user The user object used for language information - * @param \phpbb\db\driver\driver_interface $db The database in wich will be inserted the user - * @param \phpbb\config\config $config The config object used to get default language and timezone - * @param \phpbb\passwords\manager $password_manager The password manager used to store the user's password - * @param string $phpbb_root_path Root path - * @param string $php_ext PHP extension - */ - public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $password_manager, $phpbb_root_path, $php_ext) + * Construct method + * + * @param \phpbb\user $user + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\config\config $config + * @param \phpbb\language\language $language + * @param \phpbb\passwords\manager $password_manager + * @param string $phpbb_root_path + * @param string $php_ext + */ + public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\language\language $language, \phpbb\passwords\manager $password_manager, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; + $this->language = $language; $this->password_manager = $password_manager; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; - $user->add_lang('ucp'); + $language->add_lang('ucp'); parent::__construct($user); } /** - * Sets the command name and description - * - * @return null - */ + * Sets the command name and description + * + * @return null + */ protected function configure() { $this ->setName('user:add') - ->setDescription($this->user->lang('CLI_DESCRIPTION_USER_ADD')) - ->addOption('username', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_USER_ADD_OPTION_USERNAME')) - ->addOption('password', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_USER_ADD_OPTION_PASSWORD')) - ->addOption('email', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_USER_ADD_OPTION_EMAIL')) - ->addOption('send-email', null, InputOption::VALUE_NONE, $this->user->lang('CLI_CONFIG_PRINT_WITHOUT_NEWLINE')) + ->setDescription($this->language->lang('CLI_DESCRIPTION_USER_ADD')) + ->addOption('username', null, InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_USERNAME')) + ->addOption('password', null, InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_PASSWORD')) + ->addOption('email', null, InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_EMAIL')) + ->addOption('send-email', null, InputOption::VALUE_NONE, $this->language->lang('CLI_CONFIG_PRINT_WITHOUT_NEWLINE')) ; } /** - * Executes the command user:add - * - * If not given in option, asks the username, password and email. - * Then a new user is added in the database, with language and timezone found in the $config passed to the constructor, and the group_id found in the database. - * - * @param InputInterface $input The input stream used to get the options - * @param OutputInterface $output The output stream, used to print messages - * - * @return int 0 if all is well, 1 if a database error occured while trying to get the group_id - */ + * Executes the command user:add + * + * Adds a new user to the database. If options are not provided, it will ask for the username, password and email. + * User is added to the registered user group. Language and timezone default to $config settings. + * + * @param InputInterface $input The input stream used to get the options + * @param OutputInterface $output The output stream, used to print messages + * + * @return int 0 if all is well, 1 if any errors occurred + */ protected function execute(InputInterface $input, OutputInterface $output) { $io = new SymfonyStyle($input, $output); - $dialog = $this->getHelperSet()->get('dialog'); + $helper = $this->getHelper('question'); - $username = $input->getOption('username'); - if (!$username) { - $username = $dialog->ask( - $output, - $this->user->lang('USERNAME') . $this->user->lang('COLON') . ' ', - null - ); - } + $data = array( + 'username' => $input->getOption('username'), + 'new_password' => $input->getOption('password'), + 'email' => $input->getOption('email'), + ); - $password = $input->getOption('password'); - if (!$password) + if (!$data['username']) { - $password = $this->get_password($output, $dialog); + $question = new Question($this->ask_user('USERNAME'), null); + $data['username'] = $helper->ask($input, $output, $question); } - $email = $input->getOption('email'); - if (!$email) + if (!$data['new_password']) { - $email = $dialog->ask( - $output, - $this->user->lang('EMAIL_ADDRESS') . $this->user->lang('COLON') . ' ', - null - ); + $self = $this; + $question = new Question($this->ask_user('PASSWORD')); + $question->setValidator(function ($value) use ($self, $helper, $input, $output) { + $question = new Question($self->ask_user('CONFIRM_PASSWORD')); + $question->setHidden(true); + $question->setHiddenFallback(false); + + $confirm = $helper->ask($input, $output, $question); + if ($confirm != $value) + { + throw new runtime_exception($self->language->lang('NEW_PASSWORD_ERROR')); + } + return $value; + }); + $question->setHidden(true); + $question->setHiddenFallback(false); + $question->setMaxAttempts(5); + + $data['new_password'] = $helper->ask($input, $output, $question); } - $data = array( - 'username' => $username, - 'new_password' => $password, - 'email' => $email, - ); + if (!$data['email']) + { + $question = new Question($this->ask_user('EMAIL_ADDRESS'), null); + $data['email'] = $helper->ask($input, $output, $question); + } try { @@ -151,14 +168,14 @@ class add extends \phpbb\console\command\command } $user_row = array( - 'username' => $username, - 'user_password' => $this->password_manager->hash($password), - 'user_email' => $email, - 'group_id' => $group_id, - 'user_timezone' => $this->config['board_timezone'], - 'user_lang' => $this->config['default_lang'], - 'user_type' => USER_NORMAL, - 'user_regdate' => time(), + 'username' => $data['username'], + 'user_password' => $this->password_manager->hash($data['new_password']), + 'user_email' => $data['email'], + 'group_id' => $group_id, + 'user_timezone' => $this->config['board_timezone'], + 'user_lang' => $this->config['default_lang'], + 'user_type' => USER_NORMAL, + 'user_regdate' => time(), ); if (!function_exists('user_add')) @@ -166,60 +183,25 @@ class add extends \phpbb\console\command\command require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); } - $user_id = user_add($user_row); + $user_id = (int) user_add($user_row); if ($input->getOption('send-email') && $this->config['email_enable']) { $this->send_activation_email($user_id, $data); } - $io->success($this->user->lang('SUCCESS_ADD_USER', $username)); + $io->success($this->language->lang('SUCCESS_ADD_USER', $data['username'])); return 0; } /** - * Get the password - * - * Asks a password to the user and asks for confirmation. - * This is repeated until the password match is confirmed. - * - * @param OutputInterface $output The output stream, where messages are printed - * @param \Symfony\Component\Console\Helper\DialogHelper $dialog The dialog helper used to get answers to questions asked to the user - * - * @return null - */ - protected function get_password($output, $dialog) - { - $current_user = $this->user; - return $dialog->askHiddenResponseAndValidate( - $output, - $current_user->lang('PASSWORD') . $current_user->lang('COLON') . ' ', - function ($answer) use ($dialog, $output, $current_user) - { - $confirm = $dialog->askHiddenResponse( - $output, - $current_user->lang('CONFIRM_PASSWORD') . $current_user->lang('COLON') . ' ', - null - ); - if ($confirm != $answer) - { - throw new runtime_exception($current_user->lang('NEW_PASSWORD_ERROR')); - } - return $answer; - }, - false, - null - ); - } - - /** - * Validate the submitted user data - * - * @param array $data The user data array - * @throws runtime_exception if any data fails validation - * @return null - */ + * Validate the submitted user data + * + * @param array $data The user data array + * @throws runtime_exception if any data fails validation + * @return null + */ protected function validate_user_data($data) { if (!function_exists('validate_data')) @@ -228,13 +210,13 @@ class add extends \phpbb\console\command\command } $error = validate_data($data, array( - 'username' => array( + 'username' => array( array('string', false, $this->config['min_name_chars'], $this->config['max_name_chars']), array('username', '')), - 'new_password' => array( + 'new_password' => array( array('string', false, $this->config['min_pass_chars'], $this->config['max_pass_chars']), array('password')), - 'email' => array( + 'email' => array( array('string', false, 6, 60), array('user_email')), )); @@ -246,13 +228,13 @@ class add extends \phpbb\console\command\command } /** - * Get the group id - * - * Go and find in the database the group_id corresponding to 'REGISTERED' - * - * @throws runtime_exception if the group id does not exist in database. - * @return null - */ + * Get the group id + * + * Go and find in the database the group_id corresponding to 'REGISTERED' + * + * @throws runtime_exception if the group id does not exist in database. + * @return null + */ protected function get_group_id() { $sql = 'SELECT group_id @@ -265,19 +247,19 @@ class add extends \phpbb\console\command\command if (!$row || !$row['group_id']) { - throw new runtime_exception($this->user->lang('NO_GROUP')); + throw new runtime_exception($this->language->lang('NO_GROUP')); } return $row['group_id']; } /** - * Send account activation email - * - * @param int $user_id The new user's id - * @param array $data The user data array - * @return null - */ + * Send account activation email + * + * @param int $user_id The new user's id + * @param array $data The user data array + * @return null + */ protected function send_activation_email($user_id, $data) { if ($this->config['require_activation'] == USER_ACTIVATION_SELF) @@ -310,12 +292,23 @@ class add extends \phpbb\console\command\command $messenger->anti_abuse_headers($this->config, $this->user); $messenger->assign_vars(array( - 'WELCOME_MSG' => htmlspecialchars_decode($this->user->lang('WELCOME_SUBJECT', $this->config['sitename'])), - 'USERNAME' => htmlspecialchars_decode($data['username']), - 'PASSWORD' => htmlspecialchars_decode($data['new_password']), - 'U_ACTIVATE' => generate_board_url() . "/ucp.{$this->php_ext}?mode=activate&u=$user_id&k=$user_actkey") + 'WELCOME_MSG' => htmlspecialchars_decode($this->language->lang('WELCOME_SUBJECT', $this->config['sitename'])), + 'USERNAME' => htmlspecialchars_decode($data['username']), + 'PASSWORD' => htmlspecialchars_decode($data['new_password']), + 'U_ACTIVATE' => generate_board_url() . "/ucp.{$this->php_ext}?mode=activate&u=$user_id&k=$user_actkey") ); $messenger->send(NOTIFY_EMAIL); } + + /** + * Helper to translate questions to the user + * + * @param string $key The language key + * @return string The language key translated with a colon and space appended + */ + protected function ask_user($key) + { + return $this->language->lang($key) . $this->language->lang('COLON') . ' '; + } } -- cgit v1.2.1 From b1a136e7bd8cc06ee320655a4ee7cf72dcd7c611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Mon, 29 Feb 2016 23:23:31 +0100 Subject: [ticket/14487] Add missing use statement PHPBB3-14487 --- phpBB/phpbb/install/event/kernel_exception_subscriber.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/event/kernel_exception_subscriber.php b/phpBB/phpbb/install/event/kernel_exception_subscriber.php index c2960cb13c..60b7d9a400 100644 --- a/phpBB/phpbb/install/event/kernel_exception_subscriber.php +++ b/phpBB/phpbb/install/event/kernel_exception_subscriber.php @@ -21,6 +21,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpFoundation\JsonResponse; /** * Exception handler for the installer -- cgit v1.2.1 From fe31060fca4a07696029c50af2c74c88ab5d85fe Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 14:23:32 -0800 Subject: [ticket/12684] Fix tests PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index be9f484aeb..46056caffd 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -125,7 +125,6 @@ class add extends \phpbb\console\command\command $question->setValidator(function ($value) use ($self, $helper, $input, $output) { $question = new Question($self->ask_user('CONFIRM_PASSWORD')); $question->setHidden(true); - $question->setHiddenFallback(false); $confirm = $helper->ask($input, $output, $question); if ($confirm != $value) @@ -135,7 +134,6 @@ class add extends \phpbb\console\command\command return $value; }); $question->setHidden(true); - $question->setHiddenFallback(false); $question->setMaxAttempts(5); $data['new_password'] = $helper->ask($input, $output, $question); @@ -223,7 +221,7 @@ class add extends \phpbb\console\command\command if ($error) { - throw new runtime_exception(implode("\n", array_map(array($this->user, 'lang'), $error))); + throw new runtime_exception(implode("\n", array_map(array($this->language, 'lang'), $error))); } } -- cgit v1.2.1 From a84f77bf25c897067f5078ae2139214e5882192b Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 14:28:02 -0800 Subject: [ticket/12684] Another little fix PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 46056caffd..647c353dd0 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -68,7 +68,7 @@ class add extends \phpbb\console\command\command $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; - $language->add_lang('ucp'); + $this->language->add_lang('ucp'); parent::__construct($user); } -- cgit v1.2.1 From 97c6cce687d94071d6f902af272631c21dbacfcb Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 14:50:19 -0800 Subject: [ticket/12684] Some code clean up PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 647c353dd0..d85c9599c5 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -125,9 +125,7 @@ class add extends \phpbb\console\command\command $question->setValidator(function ($value) use ($self, $helper, $input, $output) { $question = new Question($self->ask_user('CONFIRM_PASSWORD')); $question->setHidden(true); - - $confirm = $helper->ask($input, $output, $question); - if ($confirm != $value) + if ($helper->ask($input, $output, $question) != $value) { throw new runtime_exception($self->language->lang('NEW_PASSWORD_ERROR')); } @@ -148,15 +146,6 @@ class add extends \phpbb\console\command\command try { $this->validate_user_data($data); - } - catch (runtime_exception $e) - { - $io->error($e->getMessage()); - return 1; - } - - try - { $group_id = $this->get_group_id(); } catch (runtime_exception $e) -- cgit v1.2.1 From e905c6226db367ab3a04e373bee56a85d8251cc7 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 16:52:17 -0800 Subject: [ticket/12684] Fix a few mistakes and clean it up PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index d85c9599c5..59d9eaa117 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -82,10 +82,30 @@ class add extends \phpbb\console\command\command $this ->setName('user:add') ->setDescription($this->language->lang('CLI_DESCRIPTION_USER_ADD')) - ->addOption('username', null, InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_USERNAME')) - ->addOption('password', null, InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_PASSWORD')) - ->addOption('email', null, InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_EMAIL')) - ->addOption('send-email', null, InputOption::VALUE_NONE, $this->language->lang('CLI_CONFIG_PRINT_WITHOUT_NEWLINE')) + ->addOption( + 'username', + null, + InputOption::VALUE_REQUIRED, + $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_USERNAME') + ) + ->addOption( + 'password', + null, + InputOption::VALUE_REQUIRED, + $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_PASSWORD') + ) + ->addOption( + 'email', + null, + InputOption::VALUE_REQUIRED, + $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_EMAIL') + ) + ->addOption( + 'send-email', + null, + InputOption::VALUE_NONE, + $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_NOTIFY') + ) ; } @@ -271,13 +291,9 @@ class add extends \phpbb\console\command\command } $messenger = new \messenger(false); - $messenger->template($email_template, $this->user->lang_name); - $messenger->to($data['email'], $data['username']); - $messenger->anti_abuse_headers($this->config, $this->user); - $messenger->assign_vars(array( 'WELCOME_MSG' => htmlspecialchars_decode($this->language->lang('WELCOME_SUBJECT', $this->config['sitename'])), 'USERNAME' => htmlspecialchars_decode($data['username']), -- cgit v1.2.1 From 0ca4484525f69ea5e7c5cd28f671364604725e40 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 21:03:32 -0800 Subject: [ticket/12684] Move all lang keys to cli PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 59d9eaa117..6edd214d14 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -197,7 +197,7 @@ class add extends \phpbb\console\command\command $this->send_activation_email($user_id, $data); } - $io->success($this->language->lang('SUCCESS_ADD_USER', $data['username'])); + $io->success($this->language->lang('CLI_USER_ADD_SUCCESS', $data['username'])); return 0; } -- cgit v1.2.1 From b17f9fc81c40a6b7a5a45cc53e378274e1b6922b Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 21:04:16 -0800 Subject: [ticket/12684] Allowed to use $this in enclosure PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 6edd214d14..6f0988db5e 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -140,14 +140,13 @@ class add extends \phpbb\console\command\command if (!$data['new_password']) { - $self = $this; $question = new Question($this->ask_user('PASSWORD')); - $question->setValidator(function ($value) use ($self, $helper, $input, $output) { - $question = new Question($self->ask_user('CONFIRM_PASSWORD')); + $question->setValidator(function ($value) use ($helper, $input, $output) { + $question = new Question($this->ask_user('CONFIRM_PASSWORD')); $question->setHidden(true); if ($helper->ask($input, $output, $question) != $value) { - throw new runtime_exception($self->language->lang('NEW_PASSWORD_ERROR')); + throw new runtime_exception($this->language->lang('NEW_PASSWORD_ERROR')); } return $value; }); -- cgit v1.2.1 From 07b8c0663d17bc891dcb19b7394a24a108316d36 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 21:04:41 -0800 Subject: [ticket/12684] Additional clean up PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 6f0988db5e..3e4fbe994f 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -184,11 +184,6 @@ class add extends \phpbb\console\command\command 'user_regdate' => time(), ); - if (!function_exists('user_add')) - { - require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); - } - $user_id = (int) user_add($user_row); if ($input->getOption('send-email') && $this->config['email_enable']) @@ -294,10 +289,10 @@ class add extends \phpbb\console\command\command $messenger->to($data['email'], $data['username']); $messenger->anti_abuse_headers($this->config, $this->user); $messenger->assign_vars(array( - 'WELCOME_MSG' => htmlspecialchars_decode($this->language->lang('WELCOME_SUBJECT', $this->config['sitename'])), - 'USERNAME' => htmlspecialchars_decode($data['username']), - 'PASSWORD' => htmlspecialchars_decode($data['new_password']), - 'U_ACTIVATE' => generate_board_url() . "/ucp.{$this->php_ext}?mode=activate&u=$user_id&k=$user_actkey") + 'WELCOME_MSG' => htmlspecialchars_decode($this->language->lang('WELCOME_SUBJECT', $this->config['sitename'])), + 'USERNAME' => htmlspecialchars_decode($data['username']), + 'PASSWORD' => htmlspecialchars_decode($data['new_password']), + 'U_ACTIVATE' => generate_board_url() . "/ucp.{$this->php_ext}?mode=activate&u=$user_id&k=$user_actkey") ); $messenger->send(NOTIFY_EMAIL); -- cgit v1.2.1 From 7b0452e53aa750761c3042183e5ad7dd2cb3b344 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 29 Feb 2016 23:24:01 -0800 Subject: [ticket/12684] Remove unnecessary null arguments PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 3e4fbe994f..6937cd17d2 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -134,7 +134,7 @@ class add extends \phpbb\console\command\command if (!$data['username']) { - $question = new Question($this->ask_user('USERNAME'), null); + $question = new Question($this->ask_user('USERNAME')); $data['username'] = $helper->ask($input, $output, $question); } @@ -158,7 +158,7 @@ class add extends \phpbb\console\command\command if (!$data['email']) { - $question = new Question($this->ask_user('EMAIL_ADDRESS'), null); + $question = new Question($this->ask_user('EMAIL_ADDRESS')); $data['email'] = $helper->ask($input, $output, $question); } -- cgit v1.2.1 From fa2ae3a14bebe34c84b0fa40323862c0f813c41b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Wed, 2 Mar 2016 21:48:10 +0100 Subject: [ticket/14510] Prevent infinite loop in add_bots task PHPBB3-14510 --- phpBB/phpbb/install/module/install_data/task/add_bots.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_data/task/add_bots.php b/phpBB/phpbb/install/module/install_data/task/add_bots.php index d45a6839a0..1f1cecceb2 100644 --- a/phpBB/phpbb/install/module/install_data/task/add_bots.php +++ b/phpBB/phpbb/install/module/install_data/task/add_bots.php @@ -214,6 +214,7 @@ class add_bots extends \phpbb\install\task_base // If we can't insert this user then continue to the next one to avoid inconsistent data $this->io_handler->add_error_message('CONV_ERROR_INSERT_BOT'); + $i++; continue; } -- cgit v1.2.1 From 517c1f88259e0d30ed787bd762dcbab0c3e692f2 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 2 Mar 2016 22:19:25 +0100 Subject: [prep-release-3.2.0-b2] Add migration for 3.2.0-b2 --- phpBB/phpbb/db/migration/data/v320/v320b2.php | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/v320b2.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/v320b2.php b/phpBB/phpbb/db/migration/data/v320/v320b2.php new file mode 100644 index 0000000000..007f7588e6 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/v320b2.php @@ -0,0 +1,40 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +use phpbb\db\migration\migration; + +class v320b2 extends migration +{ + public function effectively_installed() + { + return version_compare($this->config['version'], '3.2.0-b2', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v318', + '\phpbb\db\migration\data\v320\v320b1', + '\phpbb\db\migration\data\v320\remote_upload_validation', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.0-b2')), + ); + } +} -- cgit v1.2.1 From 8c5d6efad5262417db341491f7c625832b226b22 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sat, 5 Mar 2016 09:20:04 -0800 Subject: [ticket/12684] Add an error on user creation failure PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 6937cd17d2..187062f020 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -185,6 +185,12 @@ class add extends \phpbb\console\command\command ); $user_id = (int) user_add($user_row); + + if (!$user_id) + { + $io->error($this->language->lang('AUTH_NO_PROFILE_CREATED')); + return 1; + } if ($input->getOption('send-email') && $this->config['email_enable']) { -- cgit v1.2.1 From cc941e6e05d3be75ef60d9473dee43cd6320c85b Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sat, 5 Mar 2016 10:41:35 -0800 Subject: [ticket/12684] Remove whitespace PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 187062f020..943cdb67a5 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -185,7 +185,7 @@ class add extends \phpbb\console\command\command ); $user_id = (int) user_add($user_row); - + if (!$user_id) { $io->error($this->language->lang('AUTH_NO_PROFILE_CREATED')); -- cgit v1.2.1 From 0c1e7c2f9cf81c1e487a0dcd2fb9e053de14c275 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Tue, 8 Mar 2016 00:06:10 -0800 Subject: [ticket/12684] Add shorthand alternates to the options PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 943cdb67a5..42ff000ca4 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -84,19 +84,19 @@ class add extends \phpbb\console\command\command ->setDescription($this->language->lang('CLI_DESCRIPTION_USER_ADD')) ->addOption( 'username', - null, + 'U', InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_USERNAME') ) ->addOption( 'password', - null, + 'P', InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_PASSWORD') ) ->addOption( 'email', - null, + 'E', InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_EMAIL') ) -- cgit v1.2.1 From 0f8790dd2e804ccbc7d6c1e444c1d31412d7aaa4 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Tue, 8 Mar 2016 00:32:59 -0800 Subject: [ticket/12684] Add extended help for the user:add command PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 42ff000ca4..a0da15915d 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -82,6 +82,7 @@ class add extends \phpbb\console\command\command $this ->setName('user:add') ->setDescription($this->language->lang('CLI_DESCRIPTION_USER_ADD')) + ->setHelp($this->language->lang('CLI_HELP_USER_ADD')) ->addOption( 'username', 'U', -- cgit v1.2.1 From 693664f278e0d99efef9e81c3848fe3f7edf9e7f Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 9 Mar 2016 15:16:23 -0800 Subject: [ticket/12684] Extract interactivity to a method PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 89 +++++++++++++++++++------------- 1 file changed, 52 insertions(+), 37 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index a0da15915d..8151f3827c 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -125,43 +125,7 @@ class add extends \phpbb\console\command\command { $io = new SymfonyStyle($input, $output); - $helper = $this->getHelper('question'); - - $data = array( - 'username' => $input->getOption('username'), - 'new_password' => $input->getOption('password'), - 'email' => $input->getOption('email'), - ); - - if (!$data['username']) - { - $question = new Question($this->ask_user('USERNAME')); - $data['username'] = $helper->ask($input, $output, $question); - } - - if (!$data['new_password']) - { - $question = new Question($this->ask_user('PASSWORD')); - $question->setValidator(function ($value) use ($helper, $input, $output) { - $question = new Question($this->ask_user('CONFIRM_PASSWORD')); - $question->setHidden(true); - if ($helper->ask($input, $output, $question) != $value) - { - throw new runtime_exception($this->language->lang('NEW_PASSWORD_ERROR')); - } - return $value; - }); - $question->setHidden(true); - $question->setMaxAttempts(5); - - $data['new_password'] = $helper->ask($input, $output, $question); - } - - if (!$data['email']) - { - $question = new Question($this->ask_user('EMAIL_ADDRESS')); - $data['email'] = $helper->ask($input, $output, $question); - } + $data = $this->interact($input, $output); try { @@ -203,6 +167,57 @@ class add extends \phpbb\console\command\command return 0; } + /** + * Interact with the user to obtain the required options + * + * @param InputInterface $input The input stream used to get the options + * @param OutputInterface $output The output stream, used to print messages + * + * @return array Array of required user options + */ + protected function interact(InputInterface $input, OutputInterface $output) + { + $helper = $this->getHelper('question'); + + $data = array( + 'username' => $input->getOption('username'), + 'new_password' => $input->getOption('password'), + 'email' => $input->getOption('email'), + ); + + if (!$data['username']) + { + $question = new Question($this->ask_user('USERNAME')); + $data['username'] = $helper->ask($input, $output, $question); + } + + if (!$data['new_password']) + { + $question = new Question($this->ask_user('PASSWORD')); + $question->setValidator(function ($value) use ($helper, $input, $output) { + $question = new Question($this->ask_user('CONFIRM_PASSWORD')); + $question->setHidden(true); + if ($helper->ask($input, $output, $question) != $value) + { + throw new runtime_exception($this->language->lang('NEW_PASSWORD_ERROR')); + } + return $value; + }); + $question->setHidden(true); + $question->setMaxAttempts(5); + + $data['new_password'] = $helper->ask($input, $output, $question); + } + + if (!$data['email']) + { + $question = new Question($this->ask_user('EMAIL_ADDRESS')); + $data['email'] = $helper->ask($input, $output, $question); + } + + return $data; + } + /** * Validate the submitted user data * -- cgit v1.2.1 From 5917a8e72ef274b2c7c419abe5349ace9d814d8b Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 9 Mar 2016 17:40:58 -0800 Subject: [ticket/12684] Use interactive method correctly PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 55 +++++++++++++++----------------- 1 file changed, 25 insertions(+), 30 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 8151f3827c..3df0473acf 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -22,6 +22,9 @@ use Symfony\Component\Console\Style\SymfonyStyle; class add extends \phpbb\console\command\command { + /** @var array Array of interactively acquired options */ + protected $data; + /** @var \phpbb\db\driver\driver_interface */ protected $db; @@ -125,11 +128,9 @@ class add extends \phpbb\console\command\command { $io = new SymfonyStyle($input, $output); - $data = $this->interact($input, $output); - try { - $this->validate_user_data($data); + $this->validate_user_data(); $group_id = $this->get_group_id(); } catch (runtime_exception $e) @@ -139,9 +140,9 @@ class add extends \phpbb\console\command\command } $user_row = array( - 'username' => $data['username'], - 'user_password' => $this->password_manager->hash($data['new_password']), - 'user_email' => $data['email'], + 'username' => $this->data['username'], + 'user_password' => $this->password_manager->hash($this->data['new_password']), + 'user_email' => $this->data['email'], 'group_id' => $group_id, 'user_timezone' => $this->config['board_timezone'], 'user_lang' => $this->config['default_lang'], @@ -159,39 +160,37 @@ class add extends \phpbb\console\command\command if ($input->getOption('send-email') && $this->config['email_enable']) { - $this->send_activation_email($user_id, $data); + $this->send_activation_email($user_id); } - $io->success($this->language->lang('CLI_USER_ADD_SUCCESS', $data['username'])); + $io->success($this->language->lang('CLI_USER_ADD_SUCCESS', $this->data['username'])); return 0; } /** - * Interact with the user to obtain the required options - * - * @param InputInterface $input The input stream used to get the options - * @param OutputInterface $output The output stream, used to print messages + * Interacts with the user. * - * @return array Array of required user options + * @param InputInterface $input An InputInterface instance + * @param OutputInterface $output An OutputInterface instance */ protected function interact(InputInterface $input, OutputInterface $output) { $helper = $this->getHelper('question'); - $data = array( + $this->data = array( 'username' => $input->getOption('username'), 'new_password' => $input->getOption('password'), 'email' => $input->getOption('email'), ); - if (!$data['username']) + if (!$this->data['username']) { $question = new Question($this->ask_user('USERNAME')); - $data['username'] = $helper->ask($input, $output, $question); + $this->data['username'] = $helper->ask($input, $output, $question); } - if (!$data['new_password']) + if (!$this->data['new_password']) { $question = new Question($this->ask_user('PASSWORD')); $question->setValidator(function ($value) use ($helper, $input, $output) { @@ -206,33 +205,30 @@ class add extends \phpbb\console\command\command $question->setHidden(true); $question->setMaxAttempts(5); - $data['new_password'] = $helper->ask($input, $output, $question); + $this->data['new_password'] = $helper->ask($input, $output, $question); } - if (!$data['email']) + if (!$this->data['email']) { $question = new Question($this->ask_user('EMAIL_ADDRESS')); - $data['email'] = $helper->ask($input, $output, $question); + $this->data['email'] = $helper->ask($input, $output, $question); } - - return $data; } /** * Validate the submitted user data * - * @param array $data The user data array * @throws runtime_exception if any data fails validation * @return null */ - protected function validate_user_data($data) + protected function validate_user_data() { if (!function_exists('validate_data')) { require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); } - $error = validate_data($data, array( + $error = validate_data($this->data, array( 'username' => array( array('string', false, $this->config['min_name_chars'], $this->config['max_name_chars']), array('username', '')), @@ -280,10 +276,9 @@ class add extends \phpbb\console\command\command * Send account activation email * * @param int $user_id The new user's id - * @param array $data The user data array * @return null */ - protected function send_activation_email($user_id, $data) + protected function send_activation_email($user_id) { if ($this->config['require_activation'] == USER_ACTIVATION_SELF) { @@ -308,12 +303,12 @@ class add extends \phpbb\console\command\command $messenger = new \messenger(false); $messenger->template($email_template, $this->user->lang_name); - $messenger->to($data['email'], $data['username']); + $messenger->to($this->data['email'], $this->data['username']); $messenger->anti_abuse_headers($this->config, $this->user); $messenger->assign_vars(array( 'WELCOME_MSG' => htmlspecialchars_decode($this->language->lang('WELCOME_SUBJECT', $this->config['sitename'])), - 'USERNAME' => htmlspecialchars_decode($data['username']), - 'PASSWORD' => htmlspecialchars_decode($data['new_password']), + 'USERNAME' => htmlspecialchars_decode($this->data['username']), + 'PASSWORD' => htmlspecialchars_decode($this->data['new_password']), 'U_ACTIVATE' => generate_board_url() . "/ucp.{$this->php_ext}?mode=activate&u=$user_id&k=$user_actkey") ); -- cgit v1.2.1 From 933938a1d8452f2aa1ac833ab00db58aac67a8e6 Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Fri, 18 Mar 2016 10:34:32 +0100 Subject: [ticket/14318] Fix SQL error in Notifications Board migration PHPBB3-14318 --- phpBB/phpbb/db/migration/data/v320/notifications_board.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/notifications_board.php b/phpBB/phpbb/db/migration/data/v320/notifications_board.php index 8a76ebab58..ac1b3a0f2c 100644 --- a/phpBB/phpbb/db/migration/data/v320/notifications_board.php +++ b/phpBB/phpbb/db/migration/data/v320/notifications_board.php @@ -34,7 +34,7 @@ class notifications_board extends \phpbb\db\migration\migration public function update_module() { $sql = 'UPDATE ' . MODULES_TABLE . " - SET auth = 'cfg_allow_board_notifications' + SET module_auth = 'cfg_allow_board_notifications' WHERE module_basename = 'ucp_notifications' AND module_mode = 'notification_list'"; $this->sql_query($sql); -- cgit v1.2.1 From 5b3b0edd8010ccd4735d4000d284d7717bced897 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 21 Mar 2016 13:54:50 -0700 Subject: [ticket/12684] Use a switch statement for readability PHPBB3-12684 --- phpBB/phpbb/console/command/user/add.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index 3df0473acf..df1f4aa54a 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -280,20 +280,20 @@ class add extends \phpbb\console\command\command */ protected function send_activation_email($user_id) { - if ($this->config['require_activation'] == USER_ACTIVATION_SELF) + switch ($this->config['require_activation']) { - $email_template = 'user_welcome_inactive'; - $user_actkey = gen_rand_string(mt_rand(6, 10)); - } - else if ($this->config['require_activation'] == USER_ACTIVATION_ADMIN) - { - $email_template = 'admin_welcome_inactive'; - $user_actkey = gen_rand_string(mt_rand(6, 10)); - } - else - { - $email_template = 'user_welcome'; - $user_actkey = ''; + case USER_ACTIVATION_SELF: + $email_template = 'user_welcome_inactive'; + $user_actkey = gen_rand_string(mt_rand(6, 10)); + break; + case USER_ACTIVATION_ADMIN: + $email_template = 'admin_welcome_inactive'; + $user_actkey = gen_rand_string(mt_rand(6, 10)); + break; + default: + $email_template = 'user_welcome'; + $user_actkey = ''; + break; } if (!class_exists('messenger')) -- cgit v1.2.1 From 56c2caf6c0778c0da48fe0ac688c893777b89ee4 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 23 Mar 2016 22:48:58 +0100 Subject: [ticket/14555] Uniformize cache directory usages PHPBB3-14555 --- phpBB/phpbb/cache/driver/file.php | 4 ++-- phpBB/phpbb/cache/driver/memory.php | 4 ++-- phpBB/phpbb/cron/task/core/queue.php | 19 +++++++++++-------- phpBB/phpbb/di/container_builder.php | 1 + phpBB/phpbb/routing/router.php | 31 ++++++++++--------------------- 5 files changed, 26 insertions(+), 33 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index d994394249..a210d877f0 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -32,9 +32,9 @@ class file extends \phpbb\cache\driver\base */ function __construct($cache_dir = null) { - global $phpbb_root_path, $phpbb_container; + global $phpbb_container; - $this->cache_dir = !is_null($cache_dir) ? $cache_dir : $phpbb_root_path . 'cache/' . $phpbb_container->getParameter('core.environment') . '/'; + $this->cache_dir = !is_null($cache_dir) ? $cache_dir : $phpbb_container->getParameter('core.cache_dir'); $this->filesystem = new \phpbb\filesystem\filesystem(); if (!is_dir($this->cache_dir)) diff --git a/phpBB/phpbb/cache/driver/memory.php b/phpBB/phpbb/cache/driver/memory.php index baae22d809..cc03804705 100644 --- a/phpBB/phpbb/cache/driver/memory.php +++ b/phpBB/phpbb/cache/driver/memory.php @@ -25,9 +25,9 @@ abstract class memory extends \phpbb\cache\driver\base */ function __construct() { - global $phpbb_root_path, $dbname, $table_prefix; + global $phpbb_root_path, $dbname, $table_prefix, $phpbb_container; - $this->cache_dir = $phpbb_root_path . 'cache/'; + $this->cache_dir = $phpbb_container->getParameter('core.cache_dir'); $this->key_prefix = substr(md5($dbname . $table_prefix), 0, 8) . '_'; if (!isset($this->extension) || !extension_loaded($this->extension)) diff --git a/phpBB/phpbb/cron/task/core/queue.php b/phpBB/phpbb/cron/task/core/queue.php index a9345a44df..eca69a5041 100644 --- a/phpBB/phpbb/cron/task/core/queue.php +++ b/phpBB/phpbb/cron/task/core/queue.php @@ -20,20 +20,23 @@ class queue extends \phpbb\cron\task\base { protected $phpbb_root_path; protected $php_ext; + protected $cache_dir; protected $config; /** - * Constructor. - * - * @param string $phpbb_root_path The root path - * @param string $php_ext PHP file extension - * @param \phpbb\config\config $config The config - */ - public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config) + * Constructor. + * + * @param string $phpbb_root_path The root path + * @param string $php_ext PHP file extension + * @param \phpbb\config\config $config The config + * @param string $cache_dir phpBB cache directory + */ + public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, $cache_dir) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; $this->config = $config; + $this->cache_dir = $cache_dir; } /** @@ -60,7 +63,7 @@ class queue extends \phpbb\cron\task\base */ public function is_runnable() { - return file_exists($this->phpbb_root_path . 'cache/queue.' . $this->php_ext); + return file_exists($this->cache_dir . 'queue.' . $this->php_ext); } /** diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 2fb248082f..7bfe1bbb87 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -522,6 +522,7 @@ class container_builder 'core.php_ext' => $this->php_ext, 'core.environment' => $this->get_environment(), 'core.debug' => defined('DEBUG') ? DEBUG : false, + 'core.cache_dir' => $this->get_cache_dir(), ), $this->get_env_parameters() ); diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php index 5d237b6433..f19886fb0b 100644 --- a/phpBB/phpbb/routing/router.php +++ b/phpBB/phpbb/routing/router.php @@ -48,13 +48,6 @@ class router implements RouterInterface */ protected $loader; - /** - * phpBB root path - * - * @var string - */ - protected $phpbb_root_path; - /** * PHP file extensions * @@ -62,13 +55,6 @@ class router implements RouterInterface */ protected $php_ext; - /** - * Name of the current environment - * - * @var string - */ - protected $environment; - /** * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|null */ @@ -89,25 +75,28 @@ class router implements RouterInterface */ protected $route_collection; + /** + * @var string + */ + protected $cache_dir; + /** * Construct method * * @param ContainerInterface $container DI container * @param resources_locator_interface $resources_locator Resources locator * @param LoaderInterface $loader Resources loader - * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP file extension - * @param string $environment Name of the current environment + * @param string $cache_dir phpBB cache directory */ - public function __construct(ContainerInterface $container, resources_locator_interface $resources_locator, LoaderInterface $loader, $phpbb_root_path, $php_ext, $environment) + public function __construct(ContainerInterface $container, resources_locator_interface $resources_locator, LoaderInterface $loader, $php_ext, $cache_dir) { $this->container = $container; $this->resources_locator = $resources_locator; $this->loader = $loader; - $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; - $this->environment = $environment; $this->context = new RequestContext(); + $this->cache_dir = $cache_dir; } /** @@ -211,7 +200,7 @@ class router implements RouterInterface { try { - $cache = new ConfigCache("{$this->phpbb_root_path}cache/{$this->environment}/url_matcher.{$this->php_ext}", defined('DEBUG')); + $cache = new ConfigCache("{$this->cache_dir}url_matcher.{$this->php_ext}", defined('DEBUG')); if (!$cache->isFresh()) { $dumper = new PhpMatcherDumper($this->get_routes()); @@ -266,7 +255,7 @@ class router implements RouterInterface { try { - $cache = new ConfigCache("{$this->phpbb_root_path}cache/{$this->environment}/url_generator.{$this->php_ext}", defined('DEBUG')); + $cache = new ConfigCache("{$this->cache_dir}url_generator.{$this->php_ext}", defined('DEBUG')); if (!$cache->isFresh()) { $dumper = new PhpGeneratorDumper($this->get_routes()); -- cgit v1.2.1 From 0ff4a6b6a4151f25d94d7b4f651b069e21b036b2 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 24 Mar 2016 19:49:23 +0100 Subject: [ticket/14381] Set the mode in message parser to "reparse" The default mode is "post". By setting it to something else, all limits pertaining to posts (min/max length, etc...) should be disabled. PHPBB3-14381 --- phpBB/phpbb/textreparser/base.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php index 3e5ee248a1..afa5ccacad 100644 --- a/phpBB/phpbb/textreparser/base.php +++ b/phpBB/phpbb/textreparser/base.php @@ -230,7 +230,8 @@ abstract class base implements reparser_interface $unparsed['enable_img_bbcode'], $unparsed['enable_flash_bbcode'], $unparsed['enable_quote_bbcode'], - $unparsed['enable_url_bbcode'] + $unparsed['enable_url_bbcode'], + 'reparse' ); // Save the new text if it has changed and it's not a dry run -- cgit v1.2.1 From 3278ff03e7809dd0bb31771b3928e8676a09c572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Sun, 27 Mar 2016 18:25:06 +0200 Subject: [ticket/14393] Fix updater behaviour PHPBB3-14393 --- phpBB/phpbb/install/module/update_database/task/update.php | 2 +- .../phpbb/install/module/update_filesystem/task/file_check.php | 1 + .../install/module/update_filesystem/task/show_file_status.php | 10 +++++++--- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index 4b2baf2c23..d8807951d1 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -183,7 +183,7 @@ class update extends task_base ); } - $this->iohandler->finish_progress('INLINE_UPDATE_SUCCESSFUL'); + $this->iohandler->set_progress('INLINE_UPDATE_SUCCESSFUL', $migration_count); $this->iohandler->add_success_message('INLINE_UPDATE_SUCCESSFUL'); diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php index 5dbee6c259..f4b3870148 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -166,6 +166,7 @@ class file_check extends task_base } $this->installer_config->set('update_files', $file_update_info); + $this->installer_config->set('update_info', array()); } /** diff --git a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php index c46c05500a..329e6b9315 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php @@ -140,10 +140,14 @@ class show_file_status extends task_base } else { + $this->file_updater->close(); + $conflict_archive_path = $this->installer_config->get('update_file_conflict_archive', null); + // Remove archive - $this->filesystem->remove( - $this->installer_config->get('update_file_conflict_archive', null) - ); + if ($conflict_archive_path !== null && $this->filesystem->exists($conflict_archive_path)) + { + $this->filesystem->remove($conflict_archive_path); + } $this->installer_config->set('update_file_conflict_archive', null); } -- cgit v1.2.1 From 99196a42f201b716243fbc72554e4e0e31830472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Sun, 27 Mar 2016 19:25:00 +0200 Subject: [ticket/14564] Fix cookie domain calculation PHPBB3-14564 --- .../install/module/install_database/task/add_config_settings.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php index 20b7679ec1..7a2df01de6 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php +++ b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php @@ -129,12 +129,19 @@ class add_config_settings extends \phpbb\install\task_base $this->db->sql_return_on_error(true); $server_name = $this->install_config->get('server_name'); - $cookie_domain = $this->install_config->get('cookie_domain'); $current_time = time(); $user_ip = phpbb_ip_normalise($this->iohandler->get_server_variable('REMOTE_ADDR')); $user_ip = ($user_ip === false) ? '' : $user_ip; $referer = $this->iohandler->get_server_variable('REFERER'); + // Calculate cookie domain + $cookie_domain = $server_name; + + if (strpos($cookie_domain, 'www.') === 0) + { + $cookie_domain = substr($cookie_domain, 3); + } + // Set default config and post data, this applies to all DB's $sql_ary = array( 'INSERT INTO ' . $this->config_table . " (config_name, config_value) -- cgit v1.2.1 From c44a01fd9deba39b43bcaf6979483a5b82bf364e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Sun, 27 Mar 2016 20:10:45 +0200 Subject: [ticket/14393] Fix init for conflict archive PHPBB3-14393 --- .../module/update_filesystem/task/show_file_status.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php index 329e6b9315..7f18950cf6 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php @@ -66,11 +66,7 @@ class show_file_status extends task_base $this->cache = $container->get('cache.driver'); // Initialize compression file updater - $compression_method = $this->installer_config->get('compression_method', ''); $this->file_updater = $file_updater_factory->get('compression'); - $conflict_archive = $this->file_updater->init($compression_method); - - $this->installer_config->set('update_file_conflict_archive', $conflict_archive); parent::__construct(false); } @@ -96,6 +92,10 @@ class show_file_status extends task_base // Create archive for merge conflicts if (!empty($merge_conflicts)) { + $compression_method = $this->installer_config->get('compression_method', ''); + $conflict_archive = $this->file_updater->init($compression_method); + $this->installer_config->set('update_file_conflict_archive', $conflict_archive); + foreach ($merge_conflicts as $filename) { $this->file_updater->create_new_file( @@ -111,9 +111,9 @@ class show_file_status extends task_base 'DOWNLOAD_CONFLICTS', 'DOWNLOAD_CONFLICTS_EXPLAIN' ); - } - $this->file_updater->close(); + $this->file_updater->close(); + } // Render update file statuses $file_update_info = $this->installer_config->get('update_files', array()); @@ -140,7 +140,6 @@ class show_file_status extends task_base } else { - $this->file_updater->close(); $conflict_archive_path = $this->installer_config->get('update_file_conflict_archive', null); // Remove archive -- cgit v1.2.1 From a5f1ff85634eb8936afd109395fc1d305eaca61e Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 27 Mar 2016 20:06:02 +0200 Subject: [ticket/13683] Fix merge into 3.2.x PHPBB3-13683 --- phpBB/phpbb/routing/helper.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/helper.php b/phpBB/phpbb/routing/helper.php index f56974a354..011cc4bfef 100644 --- a/phpBB/phpbb/routing/helper.php +++ b/phpBB/phpbb/routing/helper.php @@ -104,6 +104,15 @@ class helper $context = new RequestContext(); $context->fromRequest($this->symfony_request); + if ($this->config['force_server_vars']) + { + $context->setHost($this->config['server_name']); + $context->setScheme(substr($this->config['server_protocol'], 0, -3)); + $context->setHttpPort($this->config['server_port']); + $context->setHttpsPort($this->config['server_port']); + $context->setBaseUrl($this->config['script_path']); + } + $script_name = $this->symfony_request->getScriptName(); $page_name = substr($script_name, -1, 1) == '/' ? '' : utf8_basename($script_name); @@ -119,7 +128,7 @@ class helper $base_url = str_replace('/' . $page_name, empty($this->config['enable_mod_rewrite']) ? '/app.' . $this->php_ext : '', $base_url); // We need to update the base url to move to the directory of the app.php file if the current script is not app.php - if ($page_name !== 'app.php') + if ($page_name !== 'app.php' && !$this->config['force_server_vars']) { if (empty($this->config['enable_mod_rewrite'])) { -- cgit v1.2.1 From 9fc01a42e678a934507dede60b9e1e806ccfd787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Wed, 30 Mar 2016 11:05:45 +0200 Subject: [ticket/14393] Fix db update progress bar PHPBB3-14393 --- phpBB/phpbb/install/module/update_database/task/update.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index d8807951d1..9fed2317e9 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -142,6 +142,7 @@ class update extends task_base $this->migrator->set_migrations($migrations); $migration_count = count($this->migrator->get_migrations()); $this->iohandler->set_task_count($migration_count, true); + $this->installer_config->set_task_progress_count($migration_count); $progress_count = $this->installer_config->get('database_update_count', 0); while (!$this->migrator->finished()) @@ -183,8 +184,6 @@ class update extends task_base ); } - $this->iohandler->set_progress('INLINE_UPDATE_SUCCESSFUL', $migration_count); - $this->iohandler->add_success_message('INLINE_UPDATE_SUCCESSFUL'); $this->config->delete('version_update_from'); -- cgit v1.2.1 From a643d04b05b33cfaee3d238e885dc6d1bca2e6c9 Mon Sep 17 00:00:00 2001 From: Greg Ryckman Date: Wed, 30 Mar 2016 12:53:44 -0400 Subject: [ticket/14572] Fix quote notification deletion Some array_key calls were incorrect in the notification checks for quotes. Two calls were being made in a row, resulting in incorrect arrays. PHPBB3-14572 --- phpBB/phpbb/notification/type/quote.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 684463c8c3..323c18b204 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -115,14 +115,14 @@ class quote extends \phpbb\notification\type\post )); // Find the new users to notify - $notifications = array_keys($this->find_users_for_notification($post)); + $notifications = $this->find_users_for_notification($post); // Find the notifications we must delete $remove_notifications = array_diff(array_keys($old_notifications), array_keys($notifications)); // Find the notifications we must add $add_notifications = array(); - foreach (array_diff(array_keys($notifications), $old_notifications) as $user_id) + foreach (array_diff(array_keys($notifications), array_keys($old_notifications)) as $user_id) { $add_notifications[$user_id] = $notifications[$user_id]; } -- cgit v1.2.1 From ff9632261e93d5f309541babd5e1fd48530e4c43 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 30 Mar 2016 22:22:38 +0200 Subject: [ticket/13683] Removes extra / in script_path PHPBB3-13683 --- phpBB/phpbb/routing/helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/routing/helper.php b/phpBB/phpbb/routing/helper.php index 011cc4bfef..c15608dce5 100644 --- a/phpBB/phpbb/routing/helper.php +++ b/phpBB/phpbb/routing/helper.php @@ -110,7 +110,7 @@ class helper $context->setScheme(substr($this->config['server_protocol'], 0, -3)); $context->setHttpPort($this->config['server_port']); $context->setHttpsPort($this->config['server_port']); - $context->setBaseUrl($this->config['script_path']); + $context->setBaseUrl(rtrim($this->config['script_path'], '/')); } $script_name = $this->symfony_request->getScriptName(); -- cgit v1.2.1 From 8a9429efa4b0a459a657a44b41a596969878ad65 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sat, 26 Mar 2016 12:35:38 -0700 Subject: [ticket/14561] User delete command PHPBB3-14561 --- phpBB/phpbb/console/command/user/delete.php | 175 ++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 phpBB/phpbb/console/command/user/delete.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/delete.php b/phpBB/phpbb/console/command/user/delete.php new file mode 100644 index 0000000000..360b119e17 --- /dev/null +++ b/phpBB/phpbb/console/command/user/delete.php @@ -0,0 +1,175 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\console\command\user; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Question\Question; +use Symfony\Component\Console\Style\SymfonyStyle; + +class delete extends \phpbb\console\command\command +{ + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\language\language */ + protected $language; + + /** @var \phpbb\log\log_interface */ + protected $log; + + /** + * phpBB root path + * + * @var string + */ + protected $phpbb_root_path; + + /** + * PHP extension. + * + * @var string + */ + protected $php_ext; + + /** + * Construct method + * + * @param \phpbb\user $user + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\language\language $language + * @param \phpbb\log\log_interface $log + * @param string $phpbb_root_path + * @param string $php_ext + */ + public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\language\language $language, \phpbb\log\log_interface $log, $phpbb_root_path, $php_ext) + { + $this->db = $db; + $this->language = $language; + $this->log = $log; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + $this->language->add_lang('acp/users'); + parent::__construct($user); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('user:delete') + ->setDescription($this->language->lang('CLI_DESCRIPTION_USER_DELETE')) + ->addArgument( + 'username', + InputArgument::REQUIRED, + $this->language->lang('CLI_DESCRIPTION_USER_DELETE_USERNAME') + ) + ->addOption( + 'delete-posts', + null, + InputOption::VALUE_NONE, + $this->language->lang('CLI_DESCRIPTION_USER_DELETE_OPTION_POSTS') + ) + ; + } + + /** + * Executes the command user:delete + * + * Deletes a user from the database. An option to delete the user's posts + * is available, by default posts will be retained. + * + * @param InputInterface $input The input stream used to get the options + * @param OutputInterface $output The output stream, used to print messages + * + * @return int 0 if all is well, 1 if any errors occurred + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $name = $input->getArgument('username'); + $mode = ($input->getOption('delete-posts')) ? 'remove' : 'retain'; + + if ($name) + { + $io = new SymfonyStyle($input, $output); + + if (!$user_row = $this->get_user_data($name)) + { + $io->error($this->language->lang('NO_USER')); + return 1; + } + + if (!function_exists('user_delete')) + { + require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); + } + + user_delete($mode, $user_row['user_id'], $user_row['username']); + + $this->log->add('admin', ANONYMOUS, '', 'LOG_USER_DELETED', false, array($user_row['username'])); + + $io->success($this->language->lang('USER_DELETED')); + } + + return 0; + } + + /** + * Interacts with the user. + * Confirm they really want to delete the account...last chance! + * + * @param InputInterface $input An InputInterface instance + * @param OutputInterface $output An OutputInterface instance + */ + protected function interact(InputInterface $input, OutputInterface $output) + { + $helper = $this->getHelper('question'); + + $question = new ConfirmationQuestion( + $this->language->lang('CLI_USER_DELETE_CONFIRM', $input->getArgument('username')), + false + ); + + if (!$helper->ask($input, $output, $question)) + { + $input->setArgument('username', false); + } + } + + /** + * Get the user's data from the database + * + * @param string $name A user name + * @return mixed The user's id and username if they exist, false otherwise. + */ + protected function get_user_data($name) + { + $sql = 'SELECT user_id, username + FROM ' . USERS_TABLE . " + WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($name)) . "'"; + $result = $this->db->sql_query_limit($sql, 1); + $user_row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + return $user_row; + } +} -- cgit v1.2.1 From 91f1116e046818fb49a19ff59652f684c6f5f736 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sat, 26 Mar 2016 12:37:27 -0700 Subject: [ticket/14561] User activate command PHPBB3-14561 --- phpBB/phpbb/console/command/user/activate.php | 223 ++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 phpBB/phpbb/console/command/user/activate.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/activate.php b/phpBB/phpbb/console/command/user/activate.php new file mode 100644 index 0000000000..890827afb6 --- /dev/null +++ b/phpBB/phpbb/console/command/user/activate.php @@ -0,0 +1,223 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\console\command\user; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Question\Question; +use Symfony\Component\Console\Style\SymfonyStyle; + +class activate extends \phpbb\console\command\command +{ + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\config\config */ + protected $config; + + /** @var \phpbb\language\language */ + protected $language; + + /** @var \phpbb\log\log_interface */ + protected $log; + + /** @var \phpbb\notification\manager */ + protected $notifications; + + /** + * phpBB root path + * + * @var string + */ + protected $phpbb_root_path; + + /** + * PHP extension. + * + * @var string + */ + protected $php_ext; + + /** + * Construct method + * + * @param \phpbb\user $user + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\config\config $config + * @param \phpbb\language\language $language + * @param \phpbb\log\log_interface $log + * @param \phpbb\notification\manager $notifications + * @param string $phpbb_root_path + * @param string $php_ext + */ + public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\language\language $language, \phpbb\log\log_interface $log, \phpbb\notification\manager $notifications, $phpbb_root_path, $php_ext) + { + $this->db = $db; + $this->config = $config; + $this->language = $language; + $this->log = $log; + $this->notifications = $notifications; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + $this->language->add_lang('acp/users'); + parent::__construct($user); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('user:activate') + ->setDescription($this->language->lang('CLI_DESCRIPTION_USER_ACTIVATE')) + ->setHelp($this->language->lang('CLI_HELP_USER_ACTIVATE')) + ->addArgument( + 'username', + InputArgument::REQUIRED, + $this->language->lang('CLI_DESCRIPTION_USER_ACTIVATE_USERNAME') + ) + ->addOption( + 'deactivate', + 'd', + InputOption::VALUE_NONE, + $this->language->lang('CLI_DESCRIPTION_USER_ACTIVATE_DEACTIVATE') + ) + ->addOption( + 'send-email', + null, + InputOption::VALUE_NONE, + $this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_NOTIFY') + ) + ; + } + + /** + * Executes the command user:activate + * + * Deletes a user from the database. An option to delete the user's posts + * is available, by default posts will be retained. + * + * @param InputInterface $input The input stream used to get the options + * @param OutputInterface $output The output stream, used to print messages + * + * @return int 0 if all is well, 1 if any errors occurred + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + + $name = $input->getArgument('username'); + $mode = ($input->getOption('deactivate')) ? 'deactivate' : 'activate'; + + if (!$user_row = $this->get_user_data($name)) + { + $io->error($this->language->lang('NO_USER')); + return 1; + } + + // Check if the user is already active (or inactive) + if ($mode == 'activate' && $user_row['user_type'] != USER_INACTIVE) + { + $io->error($this->language->lang('CLI_DESCRIPTION_USER_ACTIVATE_ACTIVE')); + return 1; + } + else if ($mode == 'deactivate' && $user_row['user_type'] == USER_INACTIVE) + { + $io->error($this->language->lang('CLI_DESCRIPTION_USER_ACTIVATE_INACTIVE')); + return 1; + } + + // Activate the user account + if (!function_exists('user_active_flip')) + { + require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); + } + + user_active_flip($mode, $user_row['user_id']); + + // Notify the user upon activation + if ($mode == 'activate' && $this->config['require_activation'] == USER_ACTIVATION_ADMIN) + { + $this->send_notification($user_row, $input); + } + + // Log and display the result + $msg = ($mode == 'activate') ? 'USER_ADMIN_ACTIVATED' : 'USER_ADMIN_DEACTIVED'; + $log = ($mode == 'activate') ? 'LOG_USER_ACTIVE' : 'LOG_USER_INACTIVE'; + + $this->log->add('admin', ANONYMOUS, '', $log, false, array($user_row['username'])); + $this->log->add('user', ANONYMOUS, '', $log . '_USER', false, array( + 'reportee_id' => $user_row['user_id'] + )); + + $io->success($this->language->lang($msg)); + + return 0; + } + + /** + * Send account activation notification to user + * + * @param array $user_row The user data array + * @param InputInterface $input The input stream used to get the options + * @return null + */ + protected function send_notification($user_row, InputInterface $input) + { + $this->notifications->delete_notifications('notification.type.admin_activate_user', $user_row['user_id']); + + if ($input->getOption('send-email')) + { + if (!class_exists('messenger')) + { + require($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext); + } + + $messenger = new \messenger(false); + $messenger->template('admin_welcome_activated', $user_row['user_lang']); + $messenger->set_addresses($user_row); + $messenger->anti_abuse_headers($this->config, $this->user); + $messenger->assign_vars(array( + 'USERNAME' => htmlspecialchars_decode($user_row['username'])) + ); + + $messenger->send(NOTIFY_EMAIL); + } + } + + /** + * Get the user's data from the database + * + * @param string $name A user name + * @return mixed The user's data array if they exist, false otherwise. + */ + protected function get_user_data($name) + { + $sql = 'SELECT * + FROM ' . USERS_TABLE . " + WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($name)) . "'"; + $result = $this->db->sql_query_limit($sql, 1); + $user_row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + return $user_row; + } +} -- cgit v1.2.1 From 16f9b4630cfc3c6247894ac82ac6b95577075753 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sat, 26 Mar 2016 12:38:07 -0700 Subject: [ticket/14561] Reclean usernames command PHPBB3-14561 --- phpBB/phpbb/console/command/user/reclean.php | 125 +++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 phpBB/phpbb/console/command/user/reclean.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/reclean.php b/phpBB/phpbb/console/command/user/reclean.php new file mode 100644 index 0000000000..c53d766cce --- /dev/null +++ b/phpBB/phpbb/console/command/user/reclean.php @@ -0,0 +1,125 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\console\command\user; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Question\Question; +use Symfony\Component\Console\Style\SymfonyStyle; + +class reclean extends \phpbb\console\command\command +{ + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\language\language */ + protected $language; + + /** @var int A count of the number of re-cleaned user names */ + protected $processed; + + /** + * Construct method + * + * @param \phpbb\user $user + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\language\language $language + */ + public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\language\language $language) + { + $this->db = $db; + $this->language = $language; + + parent::__construct($user); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('user:reclean') + ->setDescription($this->language->lang('CLI_DESCRIPTION_USER_RECLEAN')) + ; + } + + /** + * Executes the command user:reclean + * + * Cleans user names that are unclean. + * + * @param InputInterface $input The input stream used to get the options + * @param OutputInterface $output The output stream, used to print messages + * + * @return int 0 if all is well, 1 if any errors occurred + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->processed = 0; + + $stage = 0; + while ($stage !== true) + { + $stage = $this->reclean_usernames($stage); + } + + $io = new SymfonyStyle($input, $output); + $io->success($this->language->lang('CLI_USER_RECLEAN_SUCCESS', $this->processed)); + return 0; + } + + /** + * Re-clean user names + * Only user names that are unclean will be re-cleaned + * + * @param int $start An offset index + * @return bool|int Return the next offset index or true if all records have been processed. + */ + protected function reclean_usernames($start = 0) + { + $limit = 500; + $i = 0; + + $this->db->sql_transaction('begin'); + + $sql = 'SELECT user_id, username, username_clean FROM ' . USERS_TABLE; + $result = $this->db->sql_query_limit($sql, $limit, $start); + while ($row = $this->db->sql_fetchrow($result)) + { + $i++; + $username_clean = $this->db->sql_escape(utf8_clean_string($row['username'])); + + if ($username_clean != $row['username_clean']) + { + $sql = 'UPDATE ' . USERS_TABLE . " + SET username_clean = '$username_clean' + WHERE user_id = {$row['user_id']}"; + $this->db->sql_query($sql); + + $this->processed++; + } + } + $this->db->sql_freeresult($result); + + $this->db->sql_transaction('commit'); + + return ($i < $limit) ? true : $start + $i; + } +} -- cgit v1.2.1 From 13f365916caf9b01312da3717359316faa576521 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sat, 26 Mar 2016 14:50:45 -0700 Subject: [ticket/14561] Remove unused use statements PHPBB3-14561 --- phpBB/phpbb/console/command/user/activate.php | 2 -- phpBB/phpbb/console/command/user/delete.php | 1 - phpBB/phpbb/console/command/user/reclean.php | 4 ---- 3 files changed, 7 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/activate.php b/phpBB/phpbb/console/command/user/activate.php index 890827afb6..697c1e5abe 100644 --- a/phpBB/phpbb/console/command/user/activate.php +++ b/phpBB/phpbb/console/command/user/activate.php @@ -17,8 +17,6 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\SymfonyStyle; class activate extends \phpbb\console\command\command diff --git a/phpBB/phpbb/console/command/user/delete.php b/phpBB/phpbb/console/command/user/delete.php index 360b119e17..7251ecb3a5 100644 --- a/phpBB/phpbb/console/command/user/delete.php +++ b/phpBB/phpbb/console/command/user/delete.php @@ -18,7 +18,6 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\SymfonyStyle; class delete extends \phpbb\console\command\command diff --git a/phpBB/phpbb/console/command/user/reclean.php b/phpBB/phpbb/console/command/user/reclean.php index c53d766cce..cd5fc60a05 100644 --- a/phpBB/phpbb/console/command/user/reclean.php +++ b/phpBB/phpbb/console/command/user/reclean.php @@ -13,12 +13,8 @@ namespace phpbb\console\command\user; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\SymfonyStyle; class reclean extends \phpbb\console\command\command -- cgit v1.2.1 From aee3eec439b39ac1f8aa79582b302a499a23acc0 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 27 Mar 2016 09:31:47 -0700 Subject: [ticket/14561] Import classes with use statements PHPBB3-14561 --- phpBB/phpbb/console/command/user/activate.php | 37 ++++++++++++++++----------- phpBB/phpbb/console/command/user/add.php | 32 +++++++++++++---------- phpBB/phpbb/console/command/user/delete.php | 27 +++++++++++-------- phpBB/phpbb/console/command/user/reclean.php | 18 ++++++++----- 4 files changed, 68 insertions(+), 46 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/activate.php b/phpBB/phpbb/console/command/user/activate.php index 697c1e5abe..9eab06847c 100644 --- a/phpBB/phpbb/console/command/user/activate.php +++ b/phpBB/phpbb/console/command/user/activate.php @@ -13,27 +13,34 @@ namespace phpbb\console\command\user; +use phpbb\config\config; +use phpbb\console\command\command; +use phpbb\db\driver\driver_interface; +use phpbb\language\language; +use phpbb\log\log_interface; +use phpbb\notification\manager; +use phpbb\user; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; -class activate extends \phpbb\console\command\command +class activate extends command { - /** @var \phpbb\db\driver\driver_interface */ + /** @var driver_interface */ protected $db; - /** @var \phpbb\config\config */ + /** @var config */ protected $config; - /** @var \phpbb\language\language */ + /** @var language */ protected $language; - /** @var \phpbb\log\log_interface */ + /** @var log_interface */ protected $log; - /** @var \phpbb\notification\manager */ + /** @var manager */ protected $notifications; /** @@ -53,16 +60,16 @@ class activate extends \phpbb\console\command\command /** * Construct method * - * @param \phpbb\user $user - * @param \phpbb\db\driver\driver_interface $db - * @param \phpbb\config\config $config - * @param \phpbb\language\language $language - * @param \phpbb\log\log_interface $log - * @param \phpbb\notification\manager $notifications - * @param string $phpbb_root_path - * @param string $php_ext + * @param user $user + * @param driver_interface $db + * @param config $config + * @param language $language + * @param log_interface $log + * @param manager $notifications + * @param string $phpbb_root_path + * @param string $php_ext */ - public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\language\language $language, \phpbb\log\log_interface $log, \phpbb\notification\manager $notifications, $phpbb_root_path, $php_ext) + public function __construct(user $user, driver_interface $db, config $config, language $language, log_interface $log, manager $notifications, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php index df1f4aa54a..c60a059251 100644 --- a/phpBB/phpbb/console/command/user/add.php +++ b/phpBB/phpbb/console/command/user/add.php @@ -13,28 +13,34 @@ namespace phpbb\console\command\user; +use phpbb\config\config; +use phpbb\console\command\command; +use phpbb\db\driver\driver_interface; use phpbb\exception\runtime_exception; +use phpbb\language\language; +use phpbb\passwords\manager; +use phpbb\user; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\SymfonyStyle; -class add extends \phpbb\console\command\command +class add extends command { /** @var array Array of interactively acquired options */ protected $data; - /** @var \phpbb\db\driver\driver_interface */ + /** @var driver_interface */ protected $db; - /** @var \phpbb\config\config */ + /** @var config */ protected $config; - /** @var \phpbb\language\language */ + /** @var language */ protected $language; - /** @var \phpbb\passwords\manager */ + /** @var manager */ protected $password_manager; /** @@ -54,15 +60,15 @@ class add extends \phpbb\console\command\command /** * Construct method * - * @param \phpbb\user $user - * @param \phpbb\db\driver\driver_interface $db - * @param \phpbb\config\config $config - * @param \phpbb\language\language $language - * @param \phpbb\passwords\manager $password_manager - * @param string $phpbb_root_path - * @param string $php_ext + * @param user $user + * @param driver_interface $db + * @param config $config + * @param language $language + * @param manager $password_manager + * @param string $phpbb_root_path + * @param string $php_ext */ - public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\language\language $language, \phpbb\passwords\manager $password_manager, $phpbb_root_path, $php_ext) + public function __construct(user $user, driver_interface $db, config $config, language $language, manager $password_manager, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; diff --git a/phpBB/phpbb/console/command/user/delete.php b/phpBB/phpbb/console/command/user/delete.php index 7251ecb3a5..93e75d365b 100644 --- a/phpBB/phpbb/console/command/user/delete.php +++ b/phpBB/phpbb/console/command/user/delete.php @@ -13,6 +13,11 @@ namespace phpbb\console\command\user; +use phpbb\console\command\command; +use phpbb\db\driver\driver_interface; +use phpbb\language\language; +use phpbb\log\log_interface; +use phpbb\user; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -20,15 +25,15 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Style\SymfonyStyle; -class delete extends \phpbb\console\command\command +class delete extends command { - /** @var \phpbb\db\driver\driver_interface */ + /** @var driver_interface */ protected $db; - /** @var \phpbb\language\language */ + /** @var language */ protected $language; - /** @var \phpbb\log\log_interface */ + /** @var log_interface */ protected $log; /** @@ -48,14 +53,14 @@ class delete extends \phpbb\console\command\command /** * Construct method * - * @param \phpbb\user $user - * @param \phpbb\db\driver\driver_interface $db - * @param \phpbb\language\language $language - * @param \phpbb\log\log_interface $log - * @param string $phpbb_root_path - * @param string $php_ext + * @param user $user + * @param driver_interface $db + * @param language $language + * @param log_interface $log + * @param string $phpbb_root_path + * @param string $php_ext */ - public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\language\language $language, \phpbb\log\log_interface $log, $phpbb_root_path, $php_ext) + public function __construct(user $user, driver_interface $db, language $language, log_interface $log, $phpbb_root_path, $php_ext) { $this->db = $db; $this->language = $language; diff --git a/phpBB/phpbb/console/command/user/reclean.php b/phpBB/phpbb/console/command/user/reclean.php index cd5fc60a05..e2f95c16d8 100644 --- a/phpBB/phpbb/console/command/user/reclean.php +++ b/phpBB/phpbb/console/command/user/reclean.php @@ -13,16 +13,20 @@ namespace phpbb\console\command\user; +use phpbb\console\command\command; +use phpbb\db\driver\driver_interface; +use phpbb\language\language; +use phpbb\user; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; -class reclean extends \phpbb\console\command\command +class reclean extends command { - /** @var \phpbb\db\driver\driver_interface */ + /** @var driver_interface */ protected $db; - /** @var \phpbb\language\language */ + /** @var language */ protected $language; /** @var int A count of the number of re-cleaned user names */ @@ -31,11 +35,11 @@ class reclean extends \phpbb\console\command\command /** * Construct method * - * @param \phpbb\user $user - * @param \phpbb\db\driver\driver_interface $db - * @param \phpbb\language\language $language + * @param user $user + * @param driver_interface $db + * @param language $language */ - public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\language\language $language) + public function __construct(user $user, driver_interface $db, language $language) { $this->db = $db; $this->language = $language; -- cgit v1.2.1 From ed0f151d863d7449d73336b3697e37259812215e Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 27 Mar 2016 09:47:45 -0700 Subject: [ticket/14561] Add extra help explaining reclean command PHPBB3-14561 --- phpBB/phpbb/console/command/user/reclean.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/reclean.php b/phpBB/phpbb/console/command/user/reclean.php index e2f95c16d8..ba8a638e7b 100644 --- a/phpBB/phpbb/console/command/user/reclean.php +++ b/phpBB/phpbb/console/command/user/reclean.php @@ -57,6 +57,7 @@ class reclean extends command $this ->setName('user:reclean') ->setDescription($this->language->lang('CLI_DESCRIPTION_USER_RECLEAN')) + ->setHelp($this->language->lang('CLI_HELP_USER_RECLEAN')) ; } -- cgit v1.2.1 From 4b789c041844396f3a5e6a51142c45c13d2edd59 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 27 Mar 2016 10:24:12 -0700 Subject: [ticket/14561] Use the user loader where appropriate PHPBB3-14561 --- phpBB/phpbb/console/command/user/activate.php | 31 ++++++++++----------------- phpBB/phpbb/console/command/user/delete.php | 31 ++++++++++----------------- 2 files changed, 22 insertions(+), 40 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/activate.php b/phpBB/phpbb/console/command/user/activate.php index 9eab06847c..5c36da6891 100644 --- a/phpBB/phpbb/console/command/user/activate.php +++ b/phpBB/phpbb/console/command/user/activate.php @@ -20,6 +20,7 @@ use phpbb\language\language; use phpbb\log\log_interface; use phpbb\notification\manager; use phpbb\user; +use phpbb\user_loader; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -43,6 +44,9 @@ class activate extends command /** @var manager */ protected $notifications; + /** @var user_loader */ + protected $user_loader; + /** * phpBB root path * @@ -66,16 +70,18 @@ class activate extends command * @param language $language * @param log_interface $log * @param manager $notifications + * @param user_loader $user_loader * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(user $user, driver_interface $db, config $config, language $language, log_interface $log, manager $notifications, $phpbb_root_path, $php_ext) + public function __construct(user $user, driver_interface $db, config $config, language $language, log_interface $log, manager $notifications, user_loader $user_loader, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; $this->language = $language; $this->log = $log; $this->notifications = $notifications; + $this->user_loader = $user_loader; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; @@ -132,7 +138,10 @@ class activate extends command $name = $input->getArgument('username'); $mode = ($input->getOption('deactivate')) ? 'deactivate' : 'activate'; - if (!$user_row = $this->get_user_data($name)) + $user_id = $this->user_loader->load_user_by_username($name); + $user_row = $this->user_loader->get_user($user_id); + + if ($user_row['user_id'] == ANONYMOUS) { $io->error($this->language->lang('NO_USER')); return 1; @@ -207,22 +216,4 @@ class activate extends command $messenger->send(NOTIFY_EMAIL); } } - - /** - * Get the user's data from the database - * - * @param string $name A user name - * @return mixed The user's data array if they exist, false otherwise. - */ - protected function get_user_data($name) - { - $sql = 'SELECT * - FROM ' . USERS_TABLE . " - WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($name)) . "'"; - $result = $this->db->sql_query_limit($sql, 1); - $user_row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - return $user_row; - } } diff --git a/phpBB/phpbb/console/command/user/delete.php b/phpBB/phpbb/console/command/user/delete.php index 93e75d365b..8593541c1a 100644 --- a/phpBB/phpbb/console/command/user/delete.php +++ b/phpBB/phpbb/console/command/user/delete.php @@ -18,6 +18,7 @@ use phpbb\db\driver\driver_interface; use phpbb\language\language; use phpbb\log\log_interface; use phpbb\user; +use phpbb\user_loader; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -36,6 +37,9 @@ class delete extends command /** @var log_interface */ protected $log; + /** @var user_loader */ + protected $user_loader; + /** * phpBB root path * @@ -57,14 +61,16 @@ class delete extends command * @param driver_interface $db * @param language $language * @param log_interface $log + * @param user_loader $user_loader * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(user $user, driver_interface $db, language $language, log_interface $log, $phpbb_root_path, $php_ext) + public function __construct(user $user, driver_interface $db, language $language, log_interface $log, user_loader $user_loader, $phpbb_root_path, $php_ext) { $this->db = $db; $this->language = $language; $this->log = $log; + $this->user_loader = $user_loader; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; @@ -116,7 +122,10 @@ class delete extends command { $io = new SymfonyStyle($input, $output); - if (!$user_row = $this->get_user_data($name)) + $user_id = $this->user_loader->load_user_by_username($name); + $user_row = $this->user_loader->get_user($user_id); + + if ($user_row['user_id'] == ANONYMOUS) { $io->error($this->language->lang('NO_USER')); return 1; @@ -158,22 +167,4 @@ class delete extends command $input->setArgument('username', false); } } - - /** - * Get the user's data from the database - * - * @param string $name A user name - * @return mixed The user's id and username if they exist, false otherwise. - */ - protected function get_user_data($name) - { - $sql = 'SELECT user_id, username - FROM ' . USERS_TABLE . " - WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($name)) . "'"; - $result = $this->db->sql_query_limit($sql, 1); - $user_row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - return $user_row; - } } -- cgit v1.2.1 From afb69d7cd280df65b22b1a338d3023aebf2e3f0c Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 27 Mar 2016 11:25:19 -0700 Subject: [ticket/14561] Add a progress bar to reclean command PHPBB3-14561 --- phpBB/phpbb/console/command/user/reclean.php | 76 +++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/reclean.php b/phpBB/phpbb/console/command/user/reclean.php index ba8a638e7b..20c2816be5 100644 --- a/phpBB/phpbb/console/command/user/reclean.php +++ b/phpBB/phpbb/console/command/user/reclean.php @@ -17,6 +17,7 @@ use phpbb\console\command\command; use phpbb\db\driver\driver_interface; use phpbb\language\language; use phpbb\user; +use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; @@ -32,6 +33,9 @@ class reclean extends command /** @var int A count of the number of re-cleaned user names */ protected $processed; + /** @var ProgressBar */ + protected $progress; + /** * Construct method * @@ -73,16 +77,27 @@ class reclean extends command */ protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + + $io->section($this->language->lang('CLI_USER_RECLEAN_START')); + $this->processed = 0; + $this->progress = $this->create_progress_bar($this->get_count(), $io, $output); + $this->progress->setMessage($this->language->lang('CLI_USER_RECLEAN_START')); + $this->progress->start(); + $stage = 0; while ($stage !== true) { $stage = $this->reclean_usernames($stage); } - $io = new SymfonyStyle($input, $output); - $io->success($this->language->lang('CLI_USER_RECLEAN_SUCCESS', $this->processed)); + $this->progress->finish(); + + $io->newLine(2); + $io->success($this->language->lang('CLI_USER_RECLEAN_DONE', $this->processed)); + return 0; } @@ -116,6 +131,8 @@ class reclean extends command $this->processed++; } + + $this->progress->advance(); } $this->db->sql_freeresult($result); @@ -123,4 +140,59 @@ class reclean extends command return ($i < $limit) ? true : $start + $i; } + + /** + * Create a styled progress bar + * + * @param integer $max Max value for the progress bar + * @param SymfonyStyle $io + * @param OutputInterface $output The output stream, used to print messages + * @return ProgressBar + */ + protected function create_progress_bar($max, SymfonyStyle $io, OutputInterface $output) + { + $progress = $io->createProgressBar($max); + if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE) + { + $progress->setFormat('[%percent:3s%%] %message%'); + $progress->setOverwrite(false); + } + else if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) + { + $progress->setFormat('[%current:s%/%max:s%][%elapsed%/%estimated%][%memory%] %message%'); + $progress->setOverwrite(false); + } + else + { + $io->newLine(2); + $progress->setFormat( + " %current:s%/%max:s% %bar% %percent:3s%%\n" . + " %message% %elapsed:6s%/%estimated:-6s% %memory:6s%\n"); + $progress->setBarWidth(60); + } + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) + { + $progress->setEmptyBarCharacter('â–‘'); // light shade character \u2591 + $progress->setProgressCharacter(''); + $progress->setBarCharacter('â–“'); // dark shade character \u2593 + } + + return $progress; + } + + /** + * Get the count of users in the database + * + * @return int + */ + protected function get_count() + { + $sql = 'SELECT COUNT(user_id) AS count FROM ' . USERS_TABLE; + $result = $this->db->sql_query($sql); + $count = (int) $this->db->sql_fetchfield('count'); + $this->db->sql_freeresult($result); + + return $count; + } } -- cgit v1.2.1 From e81bf76dea82c4bc98ab7214a656a093c67f25dd Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 27 Mar 2016 11:30:05 -0700 Subject: [ticket/14561] Fix function docblock in activate command PHPBB3-14561 --- phpBB/phpbb/console/command/user/activate.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/activate.php b/phpBB/phpbb/console/command/user/activate.php index 5c36da6891..9c85718b4c 100644 --- a/phpBB/phpbb/console/command/user/activate.php +++ b/phpBB/phpbb/console/command/user/activate.php @@ -123,8 +123,7 @@ class activate extends command /** * Executes the command user:activate * - * Deletes a user from the database. An option to delete the user's posts - * is available, by default posts will be retained. + * Activate (or deactivate) a user account * * @param InputInterface $input The input stream used to get the options * @param OutputInterface $output The output stream, used to print messages -- cgit v1.2.1 From 2b90591a317fd75c7c8c4cf690d7209935f3e810 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 28 Mar 2016 15:26:56 -0700 Subject: [ticket/14561] Small change to progress bar output PHPBB3-14561 --- phpBB/phpbb/console/command/user/reclean.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/user/reclean.php b/phpBB/phpbb/console/command/user/reclean.php index 20c2816be5..e298c285be 100644 --- a/phpBB/phpbb/console/command/user/reclean.php +++ b/phpBB/phpbb/console/command/user/reclean.php @@ -167,7 +167,7 @@ class reclean extends command $io->newLine(2); $progress->setFormat( " %current:s%/%max:s% %bar% %percent:3s%%\n" . - " %message% %elapsed:6s%/%estimated:-6s% %memory:6s%\n"); + " %elapsed:6s%/%estimated:-6s% %memory:6s%\n"); $progress->setBarWidth(60); } -- cgit v1.2.1 From ada90d3b0a10249d0bff73a71f81da9b3627dd75 Mon Sep 17 00:00:00 2001 From: RFD Date: Tue, 13 Jan 2015 15:12:25 -0500 Subject: [ticket/13502] Controller resolver should handle callable functions and objects PHPBB3-13502 --- phpBB/phpbb/controller/resolver.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/controller/resolver.php b/phpBB/phpbb/controller/resolver.php index 4f432c3323..233e2e94a4 100644 --- a/phpBB/phpbb/controller/resolver.php +++ b/phpBB/phpbb/controller/resolver.php @@ -126,9 +126,18 @@ class resolver implements ControllerResolverInterface */ public function getArguments(Request $request, $controller) { - // At this point, $controller contains the object and method name - list($object, $method) = $controller; - $mirror = new \ReflectionMethod($object, $method); + // At this point, $controller should be a callable + if (is_array($controller)) + { + list($object, $method) = $controller; + $mirror = new \ReflectionMethod($object, $method); + } else if (is_object($controller) && !$controller instanceof \Closure) + { + $mirror = new \ReflectionObject($controller); + $mirror = $mirror->getMethod('__invoke'); + } else { + $mirror = new \ReflectionFunction($controller); + } $arguments = array(); $parameters = $mirror->getParameters(); -- cgit v1.2.1 From 3f4cf728724528e2c37a3bad3f9c705c71225b26 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 30 Mar 2016 00:08:02 +0200 Subject: [ticket/13502] Fix coding style PHPBB3-13502 --- phpBB/phpbb/controller/resolver.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/controller/resolver.php b/phpBB/phpbb/controller/resolver.php index 233e2e94a4..f8dffc12de 100644 --- a/phpBB/phpbb/controller/resolver.php +++ b/phpBB/phpbb/controller/resolver.php @@ -131,11 +131,14 @@ class resolver implements ControllerResolverInterface { list($object, $method) = $controller; $mirror = new \ReflectionMethod($object, $method); - } else if (is_object($controller) && !$controller instanceof \Closure) + } + else if (is_object($controller) && !$controller instanceof \Closure) { $mirror = new \ReflectionObject($controller); $mirror = $mirror->getMethod('__invoke'); - } else { + } + else + { $mirror = new \ReflectionFunction($controller); } -- cgit v1.2.1 From 5cdbef860de6eccbf1ad62390668acc7fbccb46a Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 23 Mar 2016 11:26:30 +0100 Subject: [ticket/13616] Uses symfony/proxy-manager-bridge to lazy load twig lexer PHPBB3-13616 --- phpBB/phpbb/di/container_builder.php | 8 +++++++- phpBB/phpbb/di/extension/core.php | 6 +++--- phpBB/phpbb/template/twig/environment.php | 21 ++------------------- 3 files changed, 12 insertions(+), 23 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 7bfe1bbb87..0462fb60c2 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -14,6 +14,8 @@ namespace phpbb\di; use phpbb\filesystem\filesystem; +use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator; +use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -460,7 +462,10 @@ class container_builder { try { - $dumper = new PhpDumper($this->container); + $dumper = new PhpDumper($this->container); + $proxy_dumper = new ProxyDumper(); + $dumper->setProxyDumper($proxy_dumper); + $cached_container_dump = $dumper->dump(array( 'class' => 'phpbb_cache_container', 'base_class' => 'Symfony\\Component\\DependencyInjection\\ContainerBuilder', @@ -483,6 +488,7 @@ class container_builder protected function create_container(array $extensions) { $container = new ContainerBuilder(new ParameterBag($this->get_core_parameters())); + $container->setProxyInstantiator(new RuntimeInstantiator()); $extensions_alias = array(); diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index c48a80a558..2faeff3636 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -71,7 +71,7 @@ class core extends Extension // Set the Twig options if defined in the environment $definition = $container->getDefinition('template.twig.environment'); - $twig_environment_options = $definition->getArgument(7); + $twig_environment_options = $definition->getArgument(6); if ($config['twig']['debug']) { $twig_environment_options['debug'] = true; @@ -81,8 +81,8 @@ class core extends Extension $twig_environment_options['auto_reload'] = true; } - // Replace the 8th argument, the options passed to the environment - $definition->replaceArgument(7, $twig_environment_options); + // Replace the 7th argument, the options passed to the environment + $definition->replaceArgument(6, $twig_environment_options); if ($config['twig']['enable_debug_extension']) { diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 56c85c8d71..179412a2e3 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -50,20 +50,18 @@ class environment extends \Twig_Environment * @param \phpbb\config\config $phpbb_config The phpBB configuration * @param \phpbb\filesystem\filesystem $filesystem * @param \phpbb\path_helper $path_helper phpBB path helper - * @param \Symfony\Component\DependencyInjection\ContainerInterface $container The dependency injection container * @param string $cache_path The path to the cache directory * @param \phpbb\extension\manager $extension_manager phpBB extension manager * @param \Twig_LoaderInterface $loader Twig loader interface * @param array $options Array of options to pass to Twig */ - public function __construct(\phpbb\config\config $phpbb_config, \phpbb\filesystem\filesystem $filesystem, \phpbb\path_helper $path_helper, \Symfony\Component\DependencyInjection\ContainerInterface $container, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array()) + public function __construct(\phpbb\config\config $phpbb_config, \phpbb\filesystem\filesystem $filesystem, \phpbb\path_helper $path_helper, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array()) { $this->phpbb_config = $phpbb_config; $this->filesystem = $filesystem; $this->phpbb_path_helper = $path_helper; $this->extension_manager = $extension_manager; - $this->container = $container; $this->phpbb_root_path = $this->phpbb_path_helper->get_phpbb_root_path(); $this->web_root_path = $this->phpbb_path_helper->get_web_root_path(); @@ -77,24 +75,9 @@ class environment extends \Twig_Environment 'autoescape' => false, ), $options); - return parent::__construct($loader, $options); + parent::__construct($loader, $options); } - /** - * {@inheritdoc} - */ - public function getLexer() - { - if (null === $this->lexer) - { - $this->lexer = $this->container->get('template.twig.lexer'); - $this->lexer->set_environment($this); - } - - return $this->lexer; - } - - /** * Get the list of enabled phpBB extensions * -- cgit v1.2.1 From 6d2acb5ba3fbd22b345b312e704021eab1375941 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 24 Mar 2016 13:01:52 +0100 Subject: [ticket/13616] Fix UI tests PHPBB3-13616 --- phpBB/phpbb/install/helper/container_factory.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php index 5cf4f8a283..9e372fecde 100644 --- a/phpBB/phpbb/install/helper/container_factory.php +++ b/phpBB/phpbb/install/helper/container_factory.php @@ -183,6 +183,9 @@ class container_factory // Get compatibilty globals and constants $this->update_helper->include_file('includes/compatibility_globals.' . $this->php_ext); + + register_compatibility_globals(); + $this->update_helper->include_file('includes/constants.' . $this->php_ext); } } -- cgit v1.2.1 From 5754cbfec445919dd8b7f261de33d75cbdc78fdd Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 3 Apr 2016 16:14:50 +0200 Subject: [ticket/13616] Fix CS + constant in the core extension PHPBB3-13616 --- phpBB/phpbb/di/extension/core.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 2faeff3636..29c0b0e44e 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -24,6 +24,8 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; */ class core extends Extension { + const TWIG_OPTIONS_POSITION = 6; + /** * Config path * @var string @@ -71,7 +73,7 @@ class core extends Extension // Set the Twig options if defined in the environment $definition = $container->getDefinition('template.twig.environment'); - $twig_environment_options = $definition->getArgument(6); + $twig_environment_options = $definition->getArgument(static::TWIG_OPTIONS_POSITION); if ($config['twig']['debug']) { $twig_environment_options['debug'] = true; @@ -82,7 +84,7 @@ class core extends Extension } // Replace the 7th argument, the options passed to the environment - $definition->replaceArgument(6, $twig_environment_options); + $definition->replaceArgument(static::TWIG_OPTIONS_POSITION, $twig_environment_options); if ($config['twig']['enable_debug_extension']) { -- cgit v1.2.1 From d747ac146e374baf352a9d81d476727813a2eb0f Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 3 Apr 2016 16:25:54 +0200 Subject: [ticket/13683] Fix CS PHPBB3-13683 --- phpBB/phpbb/controller/helper.php | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index ce6bfba981..f71890b441 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -66,20 +66,19 @@ class helper protected $php_ext; /** - * Constructor - * - * @param \phpbb\template\template $template Template object - * @param \phpbb\user $user User object - * @param \phpbb\config\config $config Config object + * Constructor * + * @param \phpbb\template\template $template Template object + * @param \phpbb\user $user User object + * @param \phpbb\config\config $config Config object * @param \phpbb\controller\provider $provider Path provider - * @param \phpbb\extension\manager $manager Extension manager object - * @param \phpbb\symfony_request $symfony_request Symfony Request object - * @param \phpbb\request\request_interface $request phpBB request object - * @param \phpbb\filesystem $filesystem The filesystem object - * @param string $phpbb_root_path phpBB root path - * @param string $php_ext PHP file extension - */ + * @param \phpbb\extension\manager $manager Extension manager object + * @param \phpbb\symfony_request $symfony_request Symfony Request object + * @param \phpbb\request\request_interface $request phpBB request object + * @param \phpbb\filesystem $filesystem The filesystem object + * @param string $phpbb_root_path phpBB root path + * @param string $php_ext PHP file extension + */ public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext) { $this->template = $template; -- cgit v1.2.1 From 7bf8006b67f6a2f56317fb6c4ab25ca623757ba5 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 4 Apr 2016 21:32:46 +0200 Subject: [ticket/14198] Use the build option to calculate the container cache filename PHPBB3-14198 --- phpBB/phpbb/di/container_builder.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 7bfe1bbb87..b9284d04be 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -556,7 +556,13 @@ class container_builder */ protected function get_container_filename() { - return $this->get_cache_dir() . 'container_' . md5($this->phpbb_root_path) . '.' . $this->php_ext; + $container_params = [ + 'phpbb_root_path' => $this->phpbb_root_path, + 'use_extensions' => $this->use_extensions, + 'config_path' => $this->config_path, + ]; + + return $this->get_cache_dir() . 'container_' . md5(implode(',', $container_params)) . '.' . $this->php_ext; } /** @@ -566,7 +572,13 @@ class container_builder */ protected function get_autoload_filename() { - return $this->get_cache_dir() . 'autoload_' . md5($this->phpbb_root_path) . '.' . $this->php_ext; + $container_params = [ + 'phpbb_root_path' => $this->phpbb_root_path, + 'use_extensions' => $this->use_extensions, + 'config_path' => $this->config_path, + ]; + + return $this->get_cache_dir() . 'autoload_' . md5(implode(',', $container_params)) . '.' . $this->php_ext; } /** -- cgit v1.2.1 From 9163cc28647e9936fe9c9e390871f9130d2bf40b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Sun, 10 Apr 2016 10:30:15 +0200 Subject: [ticket/14589] Add error messages for failable installer requirements PHPBB3-14589 --- phpBB/phpbb/install/module/requirements/task/check_filesystem.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/requirements/task/check_filesystem.php b/phpBB/phpbb/install/module/requirements/task/check_filesystem.php index 2aec3915e0..868af39433 100644 --- a/phpBB/phpbb/install/module/requirements/task/check_filesystem.php +++ b/phpBB/phpbb/install/module/requirements/task/check_filesystem.php @@ -177,7 +177,9 @@ class check_filesystem extends \phpbb\install\task_base if (!($exists && $writable)) { $title = ($exists) ? 'FILE_NOT_WRITABLE' : 'FILE_NOT_EXISTS'; - $description = array($title . '_EXPLAIN', $file); + $lang_suffix = '_EXPLAIN'; + $lang_suffix .= ($failable) ? '_OPTIONAL' : ''; + $description = array($title . $lang_suffix, $file); if ($failable) { @@ -244,7 +246,9 @@ class check_filesystem extends \phpbb\install\task_base if (!($exists && $writable)) { $title = ($exists) ? 'DIRECTORY_NOT_WRITABLE' : 'DIRECTORY_NOT_EXISTS'; - $description = array($title . '_EXPLAIN', $dir); + $lang_suffix = '_EXPLAIN'; + $lang_suffix .= ($failable) ? '_OPTIONAL' : ''; + $description = array($title . $lang_suffix, $dir); if ($failable) { -- cgit v1.2.1 From f41c7bd2b16906293498b4eb4073407e57a3567f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Mon, 11 Apr 2016 18:18:09 +0200 Subject: [ticket/14590] Prevent refresh requests after the last tasks in modules PHPBB3-14590 --- phpBB/phpbb/install/module_base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module_base.php b/phpBB/phpbb/install/module_base.php index 527447b4a1..93c10bd656 100644 --- a/phpBB/phpbb/install/module_base.php +++ b/phpBB/phpbb/install/module_base.php @@ -172,7 +172,7 @@ abstract class module_base implements module_interface $this->iohandler->send_response(); // Stop execution if resource limit is reached - if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) + if ($iterator->valid() && ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0)) { throw new resource_limit_reached_exception(); } -- cgit v1.2.1 From d713ce94ff218c2464823cb23dae1007354c60f3 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Tue, 12 Apr 2016 10:56:23 -0700 Subject: [ticket/14569] Extract CLI progress bar creation to a method PHPBB3-14569 --- phpBB/phpbb/console/command/command.php | 45 ++++++++++++++++++++++ phpBB/phpbb/console/command/reparser/reparse.php | 40 +------------------ phpBB/phpbb/console/command/thumbnail/delete.php | 27 +------------ phpBB/phpbb/console/command/thumbnail/generate.php | 27 +------------ phpBB/phpbb/console/command/user/reclean.php | 40 ------------------- 5 files changed, 48 insertions(+), 131 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/command.php b/phpBB/phpbb/console/command/command.php index 638c989da2..0124c00d22 100644 --- a/phpBB/phpbb/console/command/command.php +++ b/phpBB/phpbb/console/command/command.php @@ -13,6 +13,10 @@ namespace phpbb\console\command; +use Symfony\Component\Console\Helper\ProgressBar; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; + abstract class command extends \Symfony\Component\Console\Command\Command { /** @var \phpbb\user */ @@ -28,4 +32,45 @@ abstract class command extends \Symfony\Component\Console\Command\Command $this->user = $user; parent::__construct(); } + + /** + * Create a styled progress bar + * + * @param int $max Max value for the progress bar + * @param SymfonyStyle $io Symfony style output decorator + * @param OutputInterface $output The output stream, used to print messages + * @param bool $message Should we display message output under the progress bar? + * @return ProgressBar + */ + public function create_progress_bar($max, SymfonyStyle $io, OutputInterface $output, $message = false) + { + $progress = $io->createProgressBar($max); + if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE) + { + $progress->setFormat('[%percent:3s%%] %message%'); + $progress->setOverwrite(false); + } + else if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) + { + $progress->setFormat('[%current:s%/%max:s%][%elapsed%/%estimated%][%memory%] %message%'); + $progress->setOverwrite(false); + } + else + { + $io->newLine(2); + $progress->setFormat( + " %current:s%/%max:s% %bar% %percent:3s%%\n" . + " " . ($message ? '%message%' : ' ') . " %elapsed:6s%/%estimated:-6s% %memory:6s%\n"); + $progress->setBarWidth(60); + } + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) + { + $progress->setEmptyBarCharacter('â–‘'); // light shade character \u2591 + $progress->setProgressCharacter(''); + $progress->setBarCharacter('â–“'); // dark shade character \u2593 + } + + return $progress; + } } diff --git a/phpBB/phpbb/console/command/reparser/reparse.php b/phpBB/phpbb/console/command/reparser/reparse.php index ddc97a1d1d..b10bd56a58 100644 --- a/phpBB/phpbb/console/command/reparser/reparse.php +++ b/phpBB/phpbb/console/command/reparser/reparse.php @@ -121,44 +121,6 @@ class reparse extends \phpbb\console\command\command ; } - /** - * Create a styled progress bar - * - * @param integer $max Max value for the progress bar - * @return \Symfony\Component\Console\Helper\ProgressBar - */ - protected function create_progress_bar($max) - { - $progress = $this->io->createProgressBar($max); - if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE) - { - $progress->setFormat('[%percent:3s%%] %message%'); - $progress->setOverwrite(false); - } - else if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) - { - $progress->setFormat('[%current:s%/%max:s%][%elapsed%/%estimated%][%memory%] %message%'); - $progress->setOverwrite(false); - } - else - { - $this->io->newLine(2); - $progress->setFormat( - " %current:s%/%max:s% %bar% %percent:3s%%\n" . - " %message% %elapsed:6s%/%estimated:-6s% %memory:6s%\n"); - $progress->setBarWidth(60); - } - - if (!defined('PHP_WINDOWS_VERSION_BUILD')) - { - $progress->setEmptyBarCharacter('â–‘'); // light shade character \u2591 - $progress->setProgressCharacter(''); - $progress->setBarCharacter('â–“'); // dark shade character \u2593 - } - - return $progress; - } - /** * Executes the command reparser:reparse * @@ -258,7 +220,7 @@ class reparse extends \phpbb\console\command\command $this->io->section($this->user->lang('CLI_REPARSER_REPARSE_REPARSING', preg_replace('(^text_reparser\\.)', '', $name), $min, $max)); - $progress = $this->create_progress_bar($max); + $progress = $this->create_progress_bar($max, $this->io, $this->output, true); $progress->setMessage($this->user->lang('CLI_REPARSER_REPARSE_REPARSING_START', preg_replace('(^text_reparser\\.)', '', $name))); $progress->start(); diff --git a/phpBB/phpbb/console/command/thumbnail/delete.php b/phpBB/phpbb/console/command/thumbnail/delete.php index e8e4cf568e..cfa9891fbc 100644 --- a/phpBB/phpbb/console/command/thumbnail/delete.php +++ b/phpBB/phpbb/console/command/thumbnail/delete.php @@ -91,32 +91,7 @@ class delete extends \phpbb\console\command\command WHERE thumbnail = 1'; $result = $this->db->sql_query($sql); - $progress = $io->createProgressBar($nb_missing_thumbnails); - if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE) - { - $progress->setFormat('[%percent:3s%%] %message%'); - $progress->setOverwrite(false); - } - else if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) - { - $progress->setFormat('[%current:s%/%max:s%][%elapsed%/%estimated%][%memory%] %message%'); - $progress->setOverwrite(false); - } - else - { - $io->newLine(2); - $progress->setFormat( - " %current:s%/%max:s% %bar% %percent:3s%%\n" . - " %elapsed:6s%/%estimated:-6s% %memory:6s%\n"); - $progress->setBarWidth(60); - } - - if (!defined('PHP_WINDOWS_VERSION_BUILD')) - { - $progress->setEmptyBarCharacter('â–‘'); // light shade character \u2591 - $progress->setProgressCharacter(''); - $progress->setBarCharacter('â–“'); // dark shade character \u2593 - } + $progress = $this->create_progress_bar($nb_missing_thumbnails, $io, $output); $progress->setMessage($this->user->lang('CLI_THUMBNAIL_DELETING')); diff --git a/phpBB/phpbb/console/command/thumbnail/generate.php b/phpBB/phpbb/console/command/thumbnail/generate.php index e677db3a97..64f7555336 100644 --- a/phpBB/phpbb/console/command/thumbnail/generate.php +++ b/phpBB/phpbb/console/command/thumbnail/generate.php @@ -115,32 +115,7 @@ class generate extends \phpbb\console\command\command require($this->phpbb_root_path . 'includes/functions_posting.' . $this->php_ext); } - $progress = $io->createProgressBar($nb_missing_thumbnails); - if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE) - { - $progress->setFormat('[%percent:3s%%] %message%'); - $progress->setOverwrite(false); - } - else if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) - { - $progress->setFormat('[%current:s%/%max:s%][%elapsed%/%estimated%][%memory%] %message%'); - $progress->setOverwrite(false); - } - else - { - $io->newLine(2); - $progress->setFormat( - " %current:s%/%max:s% %bar% %percent:3s%%\n" . - " %elapsed:6s%/%estimated:-6s% %memory:6s%\n"); - $progress->setBarWidth(60); - } - - if (!defined('PHP_WINDOWS_VERSION_BUILD')) - { - $progress->setEmptyBarCharacter('â–‘'); // light shade character \u2591 - $progress->setProgressCharacter(''); - $progress->setBarCharacter('â–“'); // dark shade character \u2593 - } + $progress = $this->create_progress_bar($nb_missing_thumbnails, $io, $output); $progress->setMessage($this->user->lang('CLI_THUMBNAIL_GENERATING')); diff --git a/phpBB/phpbb/console/command/user/reclean.php b/phpBB/phpbb/console/command/user/reclean.php index e298c285be..1a89f13382 100644 --- a/phpBB/phpbb/console/command/user/reclean.php +++ b/phpBB/phpbb/console/command/user/reclean.php @@ -141,46 +141,6 @@ class reclean extends command return ($i < $limit) ? true : $start + $i; } - /** - * Create a styled progress bar - * - * @param integer $max Max value for the progress bar - * @param SymfonyStyle $io - * @param OutputInterface $output The output stream, used to print messages - * @return ProgressBar - */ - protected function create_progress_bar($max, SymfonyStyle $io, OutputInterface $output) - { - $progress = $io->createProgressBar($max); - if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE) - { - $progress->setFormat('[%percent:3s%%] %message%'); - $progress->setOverwrite(false); - } - else if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) - { - $progress->setFormat('[%current:s%/%max:s%][%elapsed%/%estimated%][%memory%] %message%'); - $progress->setOverwrite(false); - } - else - { - $io->newLine(2); - $progress->setFormat( - " %current:s%/%max:s% %bar% %percent:3s%%\n" . - " %elapsed:6s%/%estimated:-6s% %memory:6s%\n"); - $progress->setBarWidth(60); - } - - if (!defined('PHP_WINDOWS_VERSION_BUILD')) - { - $progress->setEmptyBarCharacter('â–‘'); // light shade character \u2591 - $progress->setProgressCharacter(''); - $progress->setBarCharacter('â–“'); // dark shade character \u2593 - } - - return $progress; - } - /** * Get the count of users in the database * -- cgit v1.2.1 From 4614cc972f9a00b67bfc982c2da7b81dfed8c6a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Wed, 13 Apr 2016 19:02:43 +0200 Subject: [ticket/14589] Fix @var usage PHPBB3-14589 --- phpBB/phpbb/attachment/delete.php | 2 +- phpBB/phpbb/attachment/upload.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php index e093da8865..922f24b5dc 100644 --- a/phpBB/phpbb/attachment/delete.php +++ b/phpBB/phpbb/attachment/delete.php @@ -29,7 +29,7 @@ class delete /** @var driver_interface */ protected $db; - /** @var \phpbb\event\dispatcher */ + /** @var dispatcher */ protected $dispatcher; /** @var filesystem */ diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php index 957558768b..f9863b372c 100644 --- a/phpBB/phpbb/attachment/upload.php +++ b/phpBB/phpbb/attachment/upload.php @@ -39,7 +39,7 @@ class upload /** @var \phpbb\files\upload Upload class */ protected $files_upload; - /** @var \phpbb\language\language */ + /** @var language */ protected $language; /** @var guesser Mimetype guesser */ -- cgit v1.2.1 From 6eda942a7f3b605b41d3a8809939ff28abdc18b1 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 1 May 2016 17:29:10 +0200 Subject: [ticket/14607] Add missing auto_increment to report_id PHPBB3-14607 --- .../data/v320/report_id_auto_increment.php | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/report_id_auto_increment.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/report_id_auto_increment.php b/phpBB/phpbb/db/migration/data/v320/report_id_auto_increment.php new file mode 100644 index 0000000000..c40504051e --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/report_id_auto_increment.php @@ -0,0 +1,45 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class report_id_auto_increment extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\default_data_type_ids', + ); + } + + public function update_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'reports' => array( + 'report_id' => array('ULINT', null, 'auto_increment'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'reports' => array( + 'report_id' => array('ULINT', 0), 0), + ), + ); + } +} -- cgit v1.2.1 From 1629e6aaf36092241eaf6c745af5c3b38f8182b3 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 5 May 2016 17:05:17 +0200 Subject: [ticket/14628] Supports translatable error messages in the CLI installer PHPBB3-14628 --- phpBB/phpbb/install/helper/iohandler/cli_iohandler.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php index 94550d2db0..2a41cb10ba 100644 --- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -124,13 +124,14 @@ class cli_iohandler extends iohandler_base public function add_error_message($error_title, $error_description = false) { $this->io->newLine(); + $message = $this->translate_message($error_title, $error_description); + $message_string = $message['title'] . (!empty($message['description']) ? "\n" . $message['description'] : ''); - if (strpos($error_title, '
') !== false) + if (strpos($message_string, '
') !== false) { - $error_title = strip_tags(str_replace('
', "\n", $error_title)); + $message_string = strip_tags(str_replace('
', "\n", $message_string)); } - $message = $this->translate_message($error_title, $error_description); - $message_string = $message['title'] . (!empty($message['description']) ? "\n" . $message['description'] : ''); + $this->io->error($message_string); if ($this->progress_bar !== null) -- cgit v1.2.1 From bf37cdf878aeb9d2c1d5195de9390db623a98ef4 Mon Sep 17 00:00:00 2001 From: Derek Held Date: Sat, 14 May 2016 07:56:30 -0700 Subject: [ticket/14595] Added SMTP port to getConfigTreeBuilder PHPBB3-14595 --- phpBB/phpbb/install/installer_configuration.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/installer_configuration.php b/phpBB/phpbb/install/installer_configuration.php index ab02da8686..c660c99d0f 100644 --- a/phpBB/phpbb/install/installer_configuration.php +++ b/phpBB/phpbb/install/installer_configuration.php @@ -93,6 +93,9 @@ class installer_configuration implements ConfigurationInterface ->scalarNode('smtp_host') ->defaultValue(null) ->end() + ->scalarNode('smtp_port') + ->defaultValue(null) + ->end() ->scalarNode('smtp_auth') ->defaultValue(null) ->end() -- cgit v1.2.1 From 9c34594bc374eeeca5d79afe2d3fdffae0cd1553 Mon Sep 17 00:00:00 2001 From: Derek Held Date: Sat, 14 May 2016 09:19:26 -0700 Subject: [ticket/14595] Added smtp_port where places where smtp_host exists. PHPBB3-14595 --- phpBB/phpbb/install/console/command/install/install.php | 1 + .../install/module/install_database/task/add_config_settings.php | 4 ++++ phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php | 7 +++++++ 3 files changed, 12 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/console/command/install/install.php b/phpBB/phpbb/install/console/command/install/install.php index 50c23f6877..de3a2e2d61 100644 --- a/phpBB/phpbb/install/console/command/install/install.php +++ b/phpBB/phpbb/install/console/command/install/install.php @@ -190,6 +190,7 @@ class install extends \phpbb\console\command\command $iohandler->set_input('email_enable', $config['email']['enabled']); $iohandler->set_input('smtp_delivery', $config['email']['smtp_delivery']); $iohandler->set_input('smtp_host', $config['email']['smtp_host']); + $iohandler->set_input('smtp_port', $config['email']['smtp_port']); $iohandler->set_input('smtp_auth', $config['email']['smtp_auth']); $iohandler->set_input('smtp_user', $config['email']['smtp_user']); $iohandler->set_input('smtp_pass', $config['email']['smtp_pass']); diff --git a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php index 7a2df01de6..8002e3ed97 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php +++ b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php @@ -190,6 +190,10 @@ class add_config_settings extends \phpbb\install\task_base SET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_host')) . "' WHERE config_name = 'smtp_host'", + 'UPDATE ' . $this->config_table . " + SET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_port')) . "' + WHERE config_name = 'smtp_port'", + 'UPDATE ' . $this->config_table . " SET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_auth')) . "' WHERE config_name = 'smtp_auth_method'", diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php index 606e4a2ddd..1cb4f04297 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php @@ -51,6 +51,7 @@ class obtain_email_data extends \phpbb\install\task_base implements \phpbb\insta $email_enable = $this->io_handler->get_input('email_enable', true); $smtp_delivery = $this->io_handler->get_input('smtp_delivery', ''); $smtp_host = $this->io_handler->get_input('smtp_host', ''); + $smtp_port = $this->io_handler->get_input('smtp_port', ''); $smtp_auth = $this->io_handler->get_input('smtp_auth', ''); $smtp_user = $this->io_handler->get_input('smtp_user', ''); $smtp_passwd = $this->io_handler->get_input('smtp_pass', ''); @@ -63,6 +64,7 @@ class obtain_email_data extends \phpbb\install\task_base implements \phpbb\insta $this->install_config->set('email_enable', $email_enable); $this->install_config->set('smtp_delivery', $smtp_delivery); $this->install_config->set('smtp_host', $smtp_host); + $this->install_config->set('smtp_port', $smtp_port); $this->install_config->set('smtp_auth', $smtp_auth); $this->install_config->set('smtp_user', $smtp_user); $this->install_config->set('smtp_pass', $smtp_passwd); @@ -119,6 +121,11 @@ class obtain_email_data extends \phpbb\install\task_base implements \phpbb\insta 'type' => 'text', 'default' => $smtp_host, ), + 'smtp_port' => array( + 'label' => 'SMTP_PORT', + 'type' => 'text', + 'default' => $smtp_port, + ), 'smtp_auth' => array( 'label' => 'SMTP_AUTH_METHOD', 'description' => 'SMTP_AUTH_METHOD_EXPLAIN', -- cgit v1.2.1 From 3bafbc81ef11ee76c93eb4f21181d38b5e5c88ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Wed, 18 May 2016 14:53:52 -0400 Subject: [ticket/14591] Use the correct delimiter for MSSQL PHPBB3-14591 --- phpBB/phpbb/install/helper/database.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php index c4c90a01a4..b8422fc1ed 100644 --- a/phpBB/phpbb/install/helper/database.php +++ b/phpBB/phpbb/install/helper/database.php @@ -58,7 +58,7 @@ class database 'LABEL' => 'MS SQL Server 2000+', 'SCHEMA' => 'mssql', 'MODULE' => 'mssql', - 'DELIM' => 'GO', + 'DELIM' => ';', 'DRIVER' => 'phpbb\db\driver\mssql', 'AVAILABLE' => true, '2.0.x' => true, @@ -67,7 +67,7 @@ class database 'LABEL' => 'MS SQL Server [ ODBC ]', 'SCHEMA' => 'mssql', 'MODULE' => 'odbc', - 'DELIM' => 'GO', + 'DELIM' => ';', 'DRIVER' => 'phpbb\db\driver\mssql_odbc', 'AVAILABLE' => true, '2.0.x' => true, @@ -76,7 +76,7 @@ class database 'LABEL' => 'MS SQL Server 2005+ [ Native ]', 'SCHEMA' => 'mssql', 'MODULE' => 'sqlsrv', - 'DELIM' => 'GO', + 'DELIM' => ';', 'DRIVER' => 'phpbb\db\driver\mssqlnative', 'AVAILABLE' => true, '2.0.x' => false, -- cgit v1.2.1 From 1a6850417439b3b05b5971a9c21ebcffe04967ef Mon Sep 17 00:00:00 2001 From: Paul Sohier Date: Sat, 21 May 2016 19:50:12 +0200 Subject: [ticket/14645] Language pack not reconised when using a symlink Symfony finder does not follow symlinks by default. With this change it does, so a user is able to have the language pack outside the phpBB directory, and linked with a symlink into phpBB/language/ PHPBB3-14645 --- phpBB/phpbb/language/language_file_helper.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/language/language_file_helper.php b/phpBB/phpbb/language/language_file_helper.php index 18d7b62e21..85de034fb8 100644 --- a/phpBB/phpbb/language/language_file_helper.php +++ b/phpBB/phpbb/language/language_file_helper.php @@ -47,6 +47,7 @@ class language_file_helper $finder->files() ->name('iso.txt') ->depth('== 1') + ->followLinks() ->in($this->phpbb_root_path . 'language'); $available_languages = array(); -- cgit v1.2.1 From 25769935641aabee4e11141faf45a0040cb93fb7 Mon Sep 17 00:00:00 2001 From: Mark Shaw Date: Wed, 25 May 2016 14:30:04 -0400 Subject: [ticket/14648] Fix bug where default notifications stop working if another setting is set. When a new user signs up, they have an email preference set but no board notification preference set. The default board preference should work. Also when a user checks the email box for any notification preference, the default board preference should still work. PHPBB3-14648 --- phpBB/phpbb/notification/type/base.php | 39 +++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index 4aacb1c99e..8f05cfc80b 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -449,7 +449,7 @@ abstract class base implements \phpbb\notification\type\type_interface return array(); } - $rowset = $resulting_user_ids = array(); + $rowset = $output = array(); $sql = 'SELECT user_id, method, notify FROM ' . $this->user_notifications_table . ' @@ -460,9 +460,7 @@ abstract class base implements \phpbb\notification\type\type_interface while ($row = $this->db->sql_fetchrow($result)) { - $resulting_user_ids[] = $row['user_id']; - - if (!$row['notify'] || (isset($options['ignore_users'][$row['user_id']]) && in_array($row['method'], $options['ignore_users'][$row['user_id']]))) + if (isset($options['ignore_users'][$row['user_id']]) && in_array($row['method'], $options['ignore_users'][$row['user_id']])) { continue; } @@ -471,22 +469,47 @@ abstract class base implements \phpbb\notification\type\type_interface { $rowset[$row['user_id']] = array(); } + $rowset[$row['user_id']][$row['method']] = $row['notify']; - $rowset[$row['user_id']][] = $row['method']; + if (!isset($output[$row['user_id']])) + { + $output[$row['user_id']] = array(); + } + if ($row['notify']) + { + $output[$row['user_id']][] = $row['method']; + } } $this->db->sql_freeresult($result); + $default_methods = $this->notification_manager->get_default_methods(); + foreach ($user_ids as $user_id) { - if (!in_array($user_id, $resulting_user_ids) && !isset($options['ignore_users'][$user_id])) + if (isset($options['ignore_users'][$user_id])) + { + continue; + } + if (!array_key_exists($user_id, $rowset)) { // No rows at all for this user, use the default methods - $rowset[$user_id] = $this->notification_manager->get_default_methods(); + $output[$user_id] = $default_methods; + } + else + { + foreach ($default_methods as $default_method) + { + if (!array_key_exists($default_method, $rowset[$user_id])) + { + // No user preference for this type recorded, but it should be enabled by default. + $output[$user_id][] = $default_method; + } + } } } - return $rowset; + return $output; } /** -- cgit v1.2.1 From 548357e14c1b8e05759609d130f02acfd0647539 Mon Sep 17 00:00:00 2001 From: Mark Shaw Date: Wed, 25 May 2016 18:28:07 -0400 Subject: [ticket/14648] Remove whitespace at the end of a line PHPBB3-14648 --- phpBB/phpbb/notification/type/base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index 8f05cfc80b..77ed7f2b09 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -487,7 +487,7 @@ abstract class base implements \phpbb\notification\type\type_interface foreach ($user_ids as $user_id) { - if (isset($options['ignore_users'][$user_id])) + if (isset($options['ignore_users'][$user_id])) { continue; } -- cgit v1.2.1 From 33d1d19f9775242a260adbb33b0bfa4b5324dedf Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Sun, 22 May 2016 15:05:49 +0200 Subject: [ticket/14586] Add OAuth1 support PHPBB3-14586 --- phpBB/phpbb/auth/provider/oauth/oauth.php | 26 +++++- .../phpbb/auth/provider/oauth/service/twitter.php | 102 +++++++++++++++++++++ phpBB/phpbb/auth/provider/oauth/token_storage.php | 24 ++++- 3 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 phpBB/phpbb/auth/provider/oauth/service/twitter.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index dd7736db4e..04729d8453 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -201,7 +201,8 @@ class oauth extends \phpbb\auth\provider\base $query = 'mode=login&login=external&oauth_service=' . $service_name_original; $service = $this->get_service($service_name_original, $storage, $service_credentials, $query, $this->service_providers[$service_name]->get_auth_scope()); - if ($this->request->is_set('code', \phpbb\request\request_interface::GET)) + if (($service::OAUTH_VERSION === 2 && $this->request->is_set('code', \phpbb\request\request_interface::GET)) + || ($service::OAUTH_VERSION === 1 && $this->request->is_set('oauth_token', \phpbb\request\request_interface::GET))) { $this->service_providers[$service_name]->set_external_service_provider($service); $unique_id = $this->service_providers[$service_name]->perform_auth_login(); @@ -256,7 +257,15 @@ class oauth extends \phpbb\auth\provider\base } else { - $url = $service->getAuthorizationUri(); + if ($service::OAUTH_VERSION === 1) + { + $token = $service->requestRequestToken(); + $url = $service->getAuthorizationUri(array('oauth_token' => $token->getRequestToken())); + } + else + { + $url = $service->getAuthorizationUri(); + } header('Location: ' . $url); } } @@ -520,7 +529,8 @@ class oauth extends \phpbb\auth\provider\base $scopes = $this->service_providers[$service_name]->get_auth_scope(); $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $query, $scopes); - if ($this->request->is_set('code', \phpbb\request\request_interface::GET)) + if (($service::OAUTH_VERSION === 2 && $this->request->is_set('code', \phpbb\request\request_interface::GET)) + || ($service::OAUTH_VERSION === 1 && $this->request->is_set('oauth_token', \phpbb\request\request_interface::GET))) { $this->service_providers[$service_name]->set_external_service_provider($service); $unique_id = $this->service_providers[$service_name]->perform_auth_login(); @@ -536,7 +546,15 @@ class oauth extends \phpbb\auth\provider\base } else { - $url = $service->getAuthorizationUri(); + if ($service::OAUTH_VERSION === 1) + { + $token = $service->requestRequestToken(); + $url = $service->getAuthorizationUri(array('oauth_token' => $token->getRequestToken())); + } + else + { + $url = $service->getAuthorizationUri(); + } header('Location: ' . $url); } } diff --git a/phpBB/phpbb/auth/provider/oauth/service/twitter.php b/phpBB/phpbb/auth/provider/oauth/service/twitter.php new file mode 100644 index 0000000000..06beac51e2 --- /dev/null +++ b/phpBB/phpbb/auth/provider/oauth/service/twitter.php @@ -0,0 +1,102 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\auth\provider\oauth\service; + +/** +* Twitter OAuth service +*/ +class twitter extends \phpbb\auth\provider\oauth\service\base +{ + /** + * phpBB config + * + * @var \phpbb\config\config + */ + protected $config; + + /** + * phpBB request + * + * @var \phpbb\request\request_interface + */ + protected $request; + + /** + * Constructor + * + * @param \phpbb\config\config $config + * @param \phpbb\request\request_interface $request + */ + public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request) + { + $this->config = $config; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public function get_service_credentials() + { + return array( + 'key' => $this->config['auth_oauth_twitter_key'], + 'secret' => $this->config['auth_oauth_twitter_secret'], + ); + } + + /** + * {@inheritdoc} + */ + public function perform_auth_login() + { + if (!($this->service_provider instanceof \OAuth\OAuth1\Service\Twitter)) + { + throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE'); + } + + $storage = $this->service_provider->getStorage(); + $token = $storage->retrieveAccessToken('Twitter'); + $tokensecret = $token->getRequestTokenSecret(); + + // This was a callback request from twitter, get the token + $this->service_provider->requestAccessToken( + $this->request->variable('oauth_token', ''), + $this->request->variable('oauth_verifier', ''), + $tokensecret + ); + + // Send a request with it + $result = json_decode($this->service_provider->request('account/verify_credentials.json'), true); + + // Return the unique identifier returned from twitter + return $result['id']; + } + + /** + * {@inheritdoc} + */ + public function perform_token_auth() + { + if (!($this->service_provider instanceof \OAuth\OAuth1\Service\Twitter)) + { + throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE'); + } + + // Send a request with it + $result = json_decode($this->service_provider->request('account/verify_credentials.json'), true); + + // Return the unique identifier returned from twitter + return $result['id']; + } +} diff --git a/phpBB/phpbb/auth/provider/oauth/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php index e922342ef6..b0c2fd0d62 100644 --- a/phpBB/phpbb/auth/provider/oauth/token_storage.php +++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php @@ -113,16 +113,30 @@ class token_storage implements TokenStorageInterface $this->cachedToken = $token; $data = array( - 'user_id' => (int) $this->user->data['user_id'], - 'provider' => $service, 'oauth_token' => $this->json_encode_token($token), - 'session_id' => $this->user->data['session_id'], ); - $sql = 'INSERT INTO ' . $this->oauth_token_table . ' - ' . $this->db->sql_build_array('INSERT', $data); + $sql = 'UPDATE ' . $this->oauth_token_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $data) . ' + WHERE user_id = ' . (int) $this->user->data['user_id'] . ' + ' . ((int) $this->user->data['user_id'] === ANONYMOUS ? "AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'" : '') . " + AND provider = '" . $this->db->sql_escape($service) . "'"; $this->db->sql_query($sql); + if (!$this->db->sql_affectedrows()) + { + $data = array( + 'user_id' => (int) $this->user->data['user_id'], + 'provider' => $service, + 'oauth_token' => $this->json_encode_token($token), + 'session_id' => $this->user->data['session_id'], + ); + + $sql = 'INSERT INTO ' . $this->oauth_token_table . $this->db->sql_build_array('INSERT', $data); + + $this->db->sql_query($sql); + } + return $this; } -- cgit v1.2.1 From a90d8fa8d475010c45b1bca1fd9c279a9eb42fac Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 8 Jun 2016 08:38:55 +0200 Subject: [ticket/14665] Remove invalid syntax in report_id_auto_increment migration PHPBB3-14665 --- phpBB/phpbb/db/migration/data/v320/report_id_auto_increment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/report_id_auto_increment.php b/phpBB/phpbb/db/migration/data/v320/report_id_auto_increment.php index c40504051e..6e81baefb9 100644 --- a/phpBB/phpbb/db/migration/data/v320/report_id_auto_increment.php +++ b/phpBB/phpbb/db/migration/data/v320/report_id_auto_increment.php @@ -38,8 +38,9 @@ class report_id_auto_increment extends \phpbb\db\migration\migration return array( 'change_columns' => array( $this->table_prefix . 'reports' => array( - 'report_id' => array('ULINT', 0), 0), + 'report_id' => array('ULINT', 0), ), + ), ); } } -- cgit v1.2.1 From 7cbb049572de066a8d9214b78a8c523f50d7014c Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 29 Apr 2016 20:25:19 +0200 Subject: [prep-release-3.2.0-RC1] Add migration --- phpBB/phpbb/db/migration/data/v320/v320rc1.php | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/v320rc1.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/v320rc1.php b/phpBB/phpbb/db/migration/data/v320/v320rc1.php new file mode 100644 index 0000000000..a04a2abb19 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/v320rc1.php @@ -0,0 +1,40 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +use phpbb\db\migration\migration; + +class v320rc1 extends migration +{ + public function effectively_installed() + { + return version_compare($this->config['version'], '3.2.0-RC1', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v319', + '\phpbb\db\migration\data\v320\report_id_auto_increment', + '\phpbb\db\migration\data\v320\v320b2', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.0-RC1')), + ); + } +} -- cgit v1.2.1 From 24da2db987c895c474b1d0a59344a7094133f278 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 8 Jul 2016 07:46:53 +0200 Subject: [ticket/14706] Updated [list] BBCode to automatically create a list item Fixes issues with missing list items. Produces valid HTML. PHPBB3-14706 --- phpBB/phpbb/textformatter/s9e/factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 8c273c342e..8d1c0fabfe 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -82,7 +82,7 @@ class factory implements \phpbb\textformatter\cache_interface 'flash' => '[FLASH={NUMBER1},{NUMBER2} width={NUMBER1;postFilter=#flashwidth} height={NUMBER2;postFilter=#flashheight} url={URL;useContent} /]', 'i' => '[I]{TEXT}[/I]', 'img' => '[IMG src={IMAGEURL;useContent}]', - 'list' => '[LIST type={HASHMAP=1:decimal,a:lower-alpha,A:upper-alpha,i:lower-roman,I:upper-roman;optional;postFilter=#simpletext}]{TEXT}[/LIST]', + 'list' => '[LIST type={HASHMAP=1:decimal,a:lower-alpha,A:upper-alpha,i:lower-roman,I:upper-roman;optional;postFilter=#simpletext} #createChild=LI]{TEXT}[/LIST]', 'li' => '[* $tagName=LI]{TEXT}[/*]', 'quote' => "[QUOTE -- cgit v1.2.1 From 13a756bfb7f73bdbd89e178617345afa18210b69 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 21 Jul 2016 03:37:44 +0200 Subject: [ticket/14700] Prevent an exception on duplicate smilies in text_formatter PHPBB3-14700 --- phpBB/phpbb/textformatter/s9e/factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 8d1c0fabfe..916fdff909 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -309,7 +309,7 @@ class factory implements \phpbb\textformatter\cache_interface // Load smilies foreach ($this->data_access->get_smilies() as $row) { - $configurator->Emoticons->add( + $configurator->Emoticons->set( $row['code'], '{.}' ); -- cgit v1.2.1 From 61a147546def2aaee24e723d5a78cb7afbc31331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Sat, 30 Jul 2016 13:04:39 +0200 Subject: [ticket/14633] Check for XML extension support on install PHPBB3-14633 --- .../requirements/task/check_server_environment.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/requirements/task/check_server_environment.php b/phpBB/phpbb/install/module/requirements/task/check_server_environment.php index 62485a2097..29f9777747 100644 --- a/phpBB/phpbb/install/module/requirements/task/check_server_environment.php +++ b/phpBB/phpbb/install/module/requirements/task/check_server_environment.php @@ -71,6 +71,9 @@ class check_server_environment extends \phpbb\install\task_base // Check for JSON support $this->check_json(); + // XML extension support check + $this->check_xml(); + // Check for dbms support $this->check_available_dbms(); @@ -154,6 +157,22 @@ class check_server_environment extends \phpbb\install\task_base $this->set_test_passed(false); } + /** + * Checks whether or not the XML PHP extension is available (Required by the text formatter) + */ + protected function check_xml() + { + if (class_exists('DOMDocument')) + { + $this->set_test_passed(true); + return; + } + + $this->response_helper->add_error_message('PHP_XML_SUPPORT', 'PHP_XML_SUPPORT_EXPLAIN'); + + $this->set_test_passed(false); + } + /** * Check if any supported DBMS is available */ -- cgit v1.2.1 From c64b8102b7c5dc5bd0be9d8085d01a66e90dde73 Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Tue, 29 Mar 2016 21:21:35 +0200 Subject: [ticket/10809] Remove MSSQL support PHPBB3-10809 --- phpBB/phpbb/cache/service.php | 1 - phpBB/phpbb/db/driver/mssql.php | 494 --------------------- phpBB/phpbb/db/extractor/factory.php | 2 +- phpBB/phpbb/db/extractor/mssql_extractor.php | 111 +---- phpBB/phpbb/db/tools/factory.php | 2 +- phpBB/phpbb/db/tools/mssql.php | 1 - phpBB/phpbb/install/helper/database.php | 9 - .../install_database/task/add_default_data.php | 2 +- 8 files changed, 4 insertions(+), 618 deletions(-) delete mode 100644 phpBB/phpbb/db/driver/mssql.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/service.php b/phpBB/phpbb/cache/service.php index a022c00bc6..8a4366fed1 100644 --- a/phpBB/phpbb/cache/service.php +++ b/phpBB/phpbb/cache/service.php @@ -302,7 +302,6 @@ class service { switch ($this->db->get_sql_layer()) { - case 'mssql': case 'mssql_odbc': case 'mssqlnative': $sql = 'SELECT user_id, bot_agent, bot_ip diff --git a/phpBB/phpbb/db/driver/mssql.php b/phpBB/phpbb/db/driver/mssql.php deleted file mode 100644 index dfdbfe15e6..0000000000 --- a/phpBB/phpbb/db/driver/mssql.php +++ /dev/null @@ -1,494 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\db\driver; - -/** -* MSSQL Database Abstraction Layer -* Minimum Requirement is MSSQL 2000+ -*/ -class mssql extends \phpbb\db\driver\driver -{ - var $connect_error = ''; - - /** - * {@inheritDoc} - */ - function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) - { - if (!function_exists('mssql_connect')) - { - $this->connect_error = 'mssql_connect function does not exist, is mssql extension installed?'; - return $this->sql_error(''); - } - - $this->persistency = $persistency; - $this->user = $sqluser; - $this->dbname = $database; - - $port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' : ':'; - $this->server = $sqlserver . (($port) ? $port_delimiter . $port : ''); - - @ini_set('mssql.charset', 'UTF-8'); - @ini_set('mssql.textlimit', 2147483647); - @ini_set('mssql.textsize', 2147483647); - - $this->db_connect_id = ($this->persistency) ? @mssql_pconnect($this->server, $this->user, $sqlpassword, $new_link) : @mssql_connect($this->server, $this->user, $sqlpassword, $new_link); - - if ($this->db_connect_id && $this->dbname != '') - { - if (!@mssql_select_db($this->dbname, $this->db_connect_id)) - { - @mssql_close($this->db_connect_id); - return false; - } - } - - return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error(''); - } - - /** - * {@inheritDoc} - */ - function sql_server_info($raw = false, $use_cache = true) - { - global $cache; - - if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mssql_version')) === false) - { - $result_id = @mssql_query("SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY('productlevel'), SERVERPROPERTY('edition')", $this->db_connect_id); - - $row = false; - if ($result_id) - { - $row = mssql_fetch_assoc($result_id); - mssql_free_result($result_id); - } - - $this->sql_server_version = ($row) ? trim(implode(' ', $row)) : 0; - - if (!empty($cache) && $use_cache) - { - $cache->put('mssql_version', $this->sql_server_version); - } - } - - if ($raw) - { - return $this->sql_server_version; - } - - return ($this->sql_server_version) ? 'MSSQL
' . $this->sql_server_version : 'MSSQL'; - } - - /** - * {@inheritDoc} - */ - public function sql_concatenate($expr1, $expr2) - { - return $expr1 . ' + ' . $expr2; - } - - /** - * SQL Transaction - * @access private - */ - function _sql_transaction($status = 'begin') - { - switch ($status) - { - case 'begin': - return @mssql_query('BEGIN TRANSACTION', $this->db_connect_id); - break; - - case 'commit': - return @mssql_query('COMMIT TRANSACTION', $this->db_connect_id); - break; - - case 'rollback': - return @mssql_query('ROLLBACK TRANSACTION', $this->db_connect_id); - break; - } - - return true; - } - - /** - * {@inheritDoc} - */ - function sql_query($query = '', $cache_ttl = 0) - { - if ($query != '') - { - global $cache; - - // EXPLAIN only in extra debug mode - if (defined('DEBUG')) - { - $this->sql_report('start', $query); - } - else if (defined('PHPBB_DISPLAY_LOAD_TIME')) - { - $this->curtime = microtime(true); - } - - $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; - $this->sql_add_num_queries($this->query_result); - - if ($this->query_result === false) - { - if (($this->query_result = @mssql_query($query, $this->db_connect_id)) === false) - { - $this->sql_error($query); - } - - if (defined('DEBUG')) - { - $this->sql_report('stop', $query); - } - else if (defined('PHPBB_DISPLAY_LOAD_TIME')) - { - $this->sql_time += microtime(true) - $this->curtime; - } - - if (!$this->query_result) - { - return false; - } - - if ($cache && $cache_ttl) - { - $this->open_queries[(int) $this->query_result] = $this->query_result; - $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); - } - else if (strpos($query, 'SELECT') === 0 && $this->query_result !== true) - { - $this->open_queries[(int) $this->query_result] = $this->query_result; - } - } - else if (defined('DEBUG')) - { - $this->sql_report('fromcache', $query); - } - } - else - { - return false; - } - - return $this->query_result; - } - - /** - * Build LIMIT query - */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) - { - $this->query_result = false; - - // Since TOP is only returning a set number of rows we won't need it if total is set to 0 (return all rows) - if ($total) - { - // We need to grab the total number of rows + the offset number of rows to get the correct result - if (strpos($query, 'SELECT DISTINCT') === 0) - { - $query = 'SELECT DISTINCT TOP ' . ($total + $offset) . ' ' . substr($query, 15); - } - else - { - $query = 'SELECT TOP ' . ($total + $offset) . ' ' . substr($query, 6); - } - } - - $result = $this->sql_query($query, $cache_ttl); - - // Seek by $offset rows - if ($offset) - { - $this->sql_rowseek($offset, $result); - } - - return $result; - } - - /** - * {@inheritDoc} - */ - function sql_affectedrows() - { - return ($this->db_connect_id) ? @mssql_rows_affected($this->db_connect_id) : false; - } - - /** - * {@inheritDoc} - */ - function sql_fetchrow($query_id = false) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if ($cache && $cache->sql_exists($query_id)) - { - return $cache->sql_fetchrow($query_id); - } - - if (!$query_id || $query_id === true) - { - return false; - } - - $row = mssql_fetch_assoc($query_id); - - // I hope i am able to remove this later... hopefully only a PHP or MSSQL bug - if ($row) - { - foreach ($row as $key => $value) - { - $row[$key] = ($value === ' ' || $value === null) ? '' : $value; - } - } - - return $row; - } - - /** - * {@inheritDoc} - */ - function sql_rowseek($rownum, &$query_id) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if ($query_id === true) - { - return false; - } - - if ($cache && $cache->sql_exists($query_id)) - { - return $cache->sql_rowseek($rownum, $query_id); - } - - return ($query_id) ? @mssql_data_seek($query_id, $rownum) : false; - } - - /** - * {@inheritDoc} - */ - function sql_nextid() - { - $result_id = @mssql_query('SELECT SCOPE_IDENTITY()', $this->db_connect_id); - if ($result_id) - { - if ($row = mssql_fetch_assoc($result_id)) - { - mssql_free_result($result_id); - return $row['computed']; - } - mssql_free_result($result_id); - } - - return false; - } - - /** - * {@inheritDoc} - */ - function sql_freeresult($query_id = false) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if ($query_id === true) - { - return false; - } - - if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) - { - return $cache->sql_freeresult($query_id); - } - - if (isset($this->open_queries[(int) $query_id])) - { - unset($this->open_queries[(int) $query_id]); - return mssql_free_result($query_id); - } - - return false; - } - - /** - * {@inheritDoc} - */ - function sql_escape($msg) - { - return str_replace(array("'", "\0"), array("''", ''), $msg); - } - - /** - * {@inheritDoc} - */ - function sql_lower_text($column_name) - { - return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; - } - - /** - * Build LIKE expression - * @access private - */ - function _sql_like_expression($expression) - { - return $expression . " ESCAPE '\\'"; - } - - /** - * Build NOT LIKE expression - * @access private - */ - function _sql_not_like_expression($expression) - { - return $expression . " ESCAPE '\\'"; - } - - /** - * return sql error array - * @access private - */ - function _sql_error() - { - if (function_exists('mssql_get_last_message')) - { - $error = array( - 'message' => @mssql_get_last_message(), - 'code' => '', - ); - - // Get error code number - $result_id = @mssql_query('SELECT @@ERROR as code', $this->db_connect_id); - if ($result_id) - { - $row = mssql_fetch_assoc($result_id); - $error['code'] = $row['code']; - mssql_free_result($result_id); - } - - // Get full error message if possible - $sql = 'SELECT CAST(description as varchar(255)) as message - FROM master.dbo.sysmessages - WHERE error = ' . $error['code']; - $result_id = @mssql_query($sql); - - if ($result_id) - { - $row = mssql_fetch_assoc($result_id); - if (!empty($row['message'])) - { - $error['message'] .= '
' . $row['message']; - } - mssql_free_result($result_id); - } - } - else - { - $error = array( - 'message' => $this->connect_error, - 'code' => '', - ); - } - - return $error; - } - - /** - * Build db-specific query data - * @access private - */ - function _sql_custom_build($stage, $data) - { - return $data; - } - - /** - * Close sql connection - * @access private - */ - function _sql_close() - { - return @mssql_close($this->db_connect_id); - } - - /** - * Build db-specific report - * @access private - */ - function _sql_report($mode, $query = '') - { - switch ($mode) - { - case 'start': - $html_table = false; - @mssql_query('SET SHOWPLAN_TEXT ON;', $this->db_connect_id); - if ($result = @mssql_query($query, $this->db_connect_id)) - { - @mssql_next_result($result); - while ($row = mssql_fetch_row($result)) - { - $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); - } - } - @mssql_query('SET SHOWPLAN_TEXT OFF;', $this->db_connect_id); - mssql_free_result($result); - - if ($html_table) - { - $this->html_hold .= ''; - } - break; - - case 'fromcache': - $endtime = explode(' ', microtime()); - $endtime = $endtime[0] + $endtime[1]; - - $result = @mssql_query($query, $this->db_connect_id); - if ($result) - { - while ($void = mssql_fetch_assoc($result)) - { - // Take the time spent on parsing rows into account - } - mssql_free_result($result); - } - - $splittime = explode(' ', microtime()); - $splittime = $splittime[0] + $splittime[1]; - - $this->sql_report('record_fromcache', $query, $endtime, $splittime); - - break; - } - } -} diff --git a/phpBB/phpbb/db/extractor/factory.php b/phpBB/phpbb/db/extractor/factory.php index a1ffb65595..eed3661ae9 100644 --- a/phpBB/phpbb/db/extractor/factory.php +++ b/phpBB/phpbb/db/extractor/factory.php @@ -49,7 +49,7 @@ class factory public function get() { // Return the appropriate DB extractor - if ($this->db instanceof \phpbb\db\driver\mssql || $this->db instanceof \phpbb\db\driver\mssql_base) + if ($this->db instanceof \phpbb\db\driver\mssql_base) { return $this->container->get('dbal.extractor.extractors.mssql_extractor'); } diff --git a/phpBB/phpbb/db/extractor/mssql_extractor.php b/phpBB/phpbb/db/extractor/mssql_extractor.php index fc30f4789d..2817d3ebcc 100644 --- a/phpBB/phpbb/db/extractor/mssql_extractor.php +++ b/phpBB/phpbb/db/extractor/mssql_extractor.php @@ -180,11 +180,7 @@ class mssql_extractor extends base_extractor throw new extractor_not_initialized_exception(); } - if ($this->db->get_sql_layer() === 'mssql') - { - $this->write_data_mssql($table_name); - } - else if ($this->db->get_sql_layer() === 'mssqlnative') + if ($this->db->get_sql_layer() === 'mssqlnative') { $this->write_data_mssqlnative($table_name); } @@ -194,111 +190,6 @@ class mssql_extractor extends base_extractor } } - /** - * Extracts data from database table (for MSSQL driver) - * - * @param string $table_name name of the database table - * @return null - * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() - */ - protected function write_data_mssql($table_name) - { - if (!$this->is_initialized) - { - throw new extractor_not_initialized_exception(); - } - - $ary_type = $ary_name = array(); - $ident_set = false; - $sql_data = ''; - - // Grab all of the data from current table. - $sql = "SELECT * - FROM $table_name"; - $result = $this->db->sql_query($sql); - - $retrieved_data = mssql_num_rows($result); - - $i_num_fields = mssql_num_fields($result); - - for ($i = 0; $i < $i_num_fields; $i++) - { - $ary_type[$i] = mssql_field_type($result, $i); - $ary_name[$i] = mssql_field_name($result, $i); - } - - if ($retrieved_data) - { - $sql = "SELECT 1 as has_identity - FROM INFORMATION_SCHEMA.COLUMNS - WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1"; - $result2 = $this->db->sql_query($sql); - $row2 = $this->db->sql_fetchrow($result2); - if (!empty($row2['has_identity'])) - { - $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n"; - $ident_set = true; - } - $this->db->sql_freeresult($result2); - } - - while ($row = $this->db->sql_fetchrow($result)) - { - $schema_vals = $schema_fields = array(); - - // Build the SQL statement to recreate the data. - for ($i = 0; $i < $i_num_fields; $i++) - { - $str_val = $row[$ary_name[$i]]; - - if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i])) - { - $str_quote = ''; - $str_empty = "''"; - $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val)); - } - else if (preg_match('#date|timestamp#i', $ary_type[$i])) - { - if (empty($str_val)) - { - $str_quote = ''; - } - else - { - $str_quote = "'"; - } - } - else - { - $str_quote = ''; - $str_empty = 'NULL'; - } - - if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val))) - { - $str_val = $str_empty; - } - - $schema_vals[$i] = $str_quote . $str_val . $str_quote; - $schema_fields[$i] = $ary_name[$i]; - } - - // Take the ordered fields and their associated data and build it - // into a valid sql statement to recreate that field in the data. - $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n"; - - $this->flush($sql_data); - $sql_data = ''; - } - $this->db->sql_freeresult($result); - - if ($retrieved_data && $ident_set) - { - $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n"; - } - $this->flush($sql_data); - } - /** * Extracts data from database table (for MSSQL Native driver) * diff --git a/phpBB/phpbb/db/tools/factory.php b/phpBB/phpbb/db/tools/factory.php index d204451a63..96471c3408 100644 --- a/phpBB/phpbb/db/tools/factory.php +++ b/phpBB/phpbb/db/tools/factory.php @@ -25,7 +25,7 @@ class factory */ public function get($db_driver, $return_statements = false) { - if ($db_driver instanceof \phpbb\db\driver\mssql || $db_driver instanceof \phpbb\db\driver\mssql_base) + if ($db_driver instanceof \phpbb\db\driver\mssql_base) { return new \phpbb\db\tools\mssql($db_driver, $return_statements); } diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index 87719acd21..a132832005 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -110,7 +110,6 @@ class mssql extends tools // Determine mapping database type switch ($this->db->get_sql_layer()) { - case 'mssql': case 'mssql_odbc': $this->sql_layer = 'mssql'; break; diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php index b8422fc1ed..be0c953d28 100644 --- a/phpBB/phpbb/install/helper/database.php +++ b/phpBB/phpbb/install/helper/database.php @@ -54,15 +54,6 @@ class database 'AVAILABLE' => true, '2.0.x' => true, ), - 'mssql' => array( - 'LABEL' => 'MS SQL Server 2000+', - 'SCHEMA' => 'mssql', - 'MODULE' => 'mssql', - 'DELIM' => ';', - 'DRIVER' => 'phpbb\db\driver\mssql', - 'AVAILABLE' => true, - '2.0.x' => true, - ), 'mssql_odbc'=> array( 'LABEL' => 'MS SQL Server [ ODBC ]', 'SCHEMA' => 'mssql', diff --git a/phpBB/phpbb/install/module/install_database/task/add_default_data.php b/phpBB/phpbb/install/module/install_database/task/add_default_data.php index f5157637ee..e32101a3f7 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_default_data.php +++ b/phpBB/phpbb/install/module/install_database/task/add_default_data.php @@ -134,7 +134,7 @@ class add_default_data extends \phpbb\install\task_base */ protected function replace_dbms_specific_sql($query) { - if ($this->db instanceof \phpbb\db\driver\mssql_base || $this->db instanceof \phpbb\db\driver\mssql) + if ($this->db instanceof \phpbb\db\driver\mssql_base) { $query = preg_replace('#\# MSSQL IDENTITY (phpbb_[a-z_]+) (ON|OFF) \##s', 'SET IDENTITY_INSERT \1 \2;', $query); } -- cgit v1.2.1 From 8a9cf32b1d6c87367dbfe67d5e567e23fc7a5e66 Mon Sep 17 00:00:00 2001 From: Wesley Fok Date: Wed, 3 Aug 2016 13:42:36 -0400 Subject: [ticket/14729] Make reports take config base class Make the report controller and helper classes accept the more generic phpbb/config/config base class in their constructors, instead of the specific database implementation phpbb/config/db. PHPBB3-14729 --- phpBB/phpbb/report/controller/report.php | 4 ++-- phpBB/phpbb/report/report_handler.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/report/controller/report.php b/phpBB/phpbb/report/controller/report.php index f703d1cc60..e1c14afde0 100644 --- a/phpBB/phpbb/report/controller/report.php +++ b/phpBB/phpbb/report/controller/report.php @@ -19,7 +19,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse; class report { /** - * @var \phpbb\config\db + * @var \phpbb\config\config */ protected $config; @@ -68,7 +68,7 @@ class report */ protected $report_reason_provider; - public function __construct(\phpbb\config\db $config, \phpbb\user $user, \phpbb\template\template $template, \phpbb\controller\helper $helper, \phpbb\request\request_interface $request, \phpbb\captcha\factory $captcha_factory, \phpbb\report\handler_factory $report_factory, \phpbb\report\report_reason_list_provider $ui_provider, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\config\config $config, \phpbb\user $user, \phpbb\template\template $template, \phpbb\controller\helper $helper, \phpbb\request\request_interface $request, \phpbb\captcha\factory $captcha_factory, \phpbb\report\handler_factory $report_factory, \phpbb\report\report_reason_list_provider $ui_provider, $phpbb_root_path, $php_ext) { $this->config = $config; $this->user = $user; diff --git a/phpBB/phpbb/report/report_handler.php b/phpBB/phpbb/report/report_handler.php index 126a206dbf..854318c559 100644 --- a/phpBB/phpbb/report/report_handler.php +++ b/phpBB/phpbb/report/report_handler.php @@ -26,7 +26,7 @@ abstract class report_handler implements report_handler_interface protected $dispatcher; /** - * @var \phpbb\config\db + * @var \phpbb\config\config */ protected $config; @@ -60,7 +60,7 @@ abstract class report_handler implements report_handler_interface * @param \phpbb\user $user * @param \phpbb\notification\manager $notification */ - public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\db $config, \phpbb\auth\auth $auth, \phpbb\user $user, \phpbb\notification\manager $notification) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, \phpbb\auth\auth $auth, \phpbb\user $user, \phpbb\notification\manager $notification) { $this->db = $db; $this->dispatcher = $dispatcher; -- cgit v1.2.1 From 9225a0fdffdd5830e2f87ec964a90d26576b812b Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 5 Aug 2016 16:27:13 +0200 Subject: [ticket/14734] Use SVG emoji PHPBB3-14734 --- phpBB/phpbb/textformatter/s9e/factory.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 916fdff909..f62daefdd9 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -349,6 +349,7 @@ class factory implements \phpbb\textformatter\cache_interface // Load the Emoji plugin and modify its tag's template to obey viewsmilies $configurator->Emoji->setImageSize(18); + $configurator->Emoji->useSVG(); $tag = $configurator->Emoji->getTag(); $tag->template = '' . str_replace('class="emoji"', 'class="smilies"', $tag->template) . ''; -- cgit v1.2.1 From 3346609126893799169dc678da732d99d506fb9f Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Thu, 11 Aug 2016 01:25:45 +0200 Subject: [ticket/14742] Display message if reverting schema is in progress PHPBB3-14742 --- phpBB/phpbb/db/migrator.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 000859f418..030afe07ad 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -454,7 +454,7 @@ class migrator $this->set_migration_state($name, $state); $elapsed_time = microtime(true) - $elapsed_time; - if ($state['migration_data_done']) + if (!$state['migration_data_done']) { $this->output_handler->write(array('MIGRATION_REVERT_DATA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL); } @@ -474,6 +474,7 @@ class migrator $state['migration_data_state'] = ($result === true) ? '' : $result; $state['migration_schema_done'] = ($result === true) ? false : true; + $elapsed_time = microtime(true) - $elapsed_time; if (!$state['migration_schema_done']) { $sql = 'DELETE FROM ' . $this->migrations_table . " @@ -481,10 +482,13 @@ class migrator $this->db->sql_query($sql); unset($this->migration_state[$name]); - } - $elapsed_time = microtime(true) - $elapsed_time; - $this->output_handler->write(array('MIGRATION_REVERT_SCHEMA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL); + $this->output_handler->write(array('MIGRATION_REVERT_SCHEMA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL); + } + else + { + $this->output_handler->write(array('MIGRATION_REVERT_SCHEMA_IN_PROGRESS', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_VERY_VERBOSE); + } } return true; -- cgit v1.2.1 From 03be89ebd7bfd95e8586d0d13076a90afec243ee Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Thu, 11 Aug 2016 23:28:54 +0200 Subject: [ticket/14742] Fix progress bar in database updater Because of the new way, schema update steps are handled, the already misleading progress bar was even more misleading. This should fix it. PHPBB3-14742 --- phpBB/phpbb/db/migrator.php | 22 ++++++++++++++++++++++ .../install/module/update_database/task/update.php | 19 ++++++++++++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 89f05f7b40..9e76668655 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -204,6 +204,28 @@ class migrator return $this->migrations; } + /** + * Get the list of available and not installed migration class names + * + * @return array + */ + public function get_installable_migrations() + { + $unfinished_migrations = array(); + + 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']) + { + $unfinished_migrations[] = $name; + } + } + + return $unfinished_migrations; + } + /** * Runs a single update step from the next migration to be applied. * diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index 9fed2317e9..d167181125 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -140,7 +140,14 @@ class update extends task_base ->get_classes(); $this->migrator->set_migrations($migrations); - $migration_count = count($this->migrator->get_migrations()); + + $migration_count = $this->installer_config->get('database_update_migrations', -1); + if ($migration_count < 0) + { + $migration_count = count($this->migrator->get_installable_migrations()); + $this->installer_config->set('database_update_migrations', $migration_count); + } + $this->iohandler->set_task_count($migration_count, true); $this->installer_config->set_task_progress_count($migration_count); $progress_count = $this->installer_config->get('database_update_count', 0); @@ -150,8 +157,14 @@ class update extends task_base try { $this->migrator->update(); - $progress_count++; - $this->iohandler->set_progress('STAGE_UPDATE_DATABASE', $progress_count); + + $last_run_migration = $this->migrator->get_last_run_migration(); + + if ($last_run_migration['state']['migration_data_done']) + { + $progress_count++; + $this->iohandler->set_progress('STAGE_UPDATE_DATABASE', $progress_count); + } } catch (exception $e) { -- cgit v1.2.1 From 758fe20f4be7178fd4b9fd6ce48c5342cfcbce27 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Fri, 12 Aug 2016 03:45:56 +0200 Subject: [ticket/14742] Further improve progress bar in db updater PHPBB3-14742 --- .../install/module/update_database/task/update.php | 24 ++++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index d167181125..c69dafaa10 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -141,16 +141,17 @@ class update extends task_base $this->migrator->set_migrations($migrations); - $migration_count = $this->installer_config->get('database_update_migrations', -1); - if ($migration_count < 0) + $migration_step_count = $this->installer_config->get('database_update_migration_steps', -1); + if ($migration_step_count < 0) { - $migration_count = count($this->migrator->get_installable_migrations()); - $this->installer_config->set('database_update_migrations', $migration_count); + $migration_step_count = count($this->migrator->get_installable_migrations()) * 2; + $this->installer_config->set('database_update_migration_steps', $migration_step_count); } - $this->iohandler->set_task_count($migration_count, true); - $this->installer_config->set_task_progress_count($migration_count); $progress_count = $this->installer_config->get('database_update_count', 0); + $restart_progress_bar = ($progress_count === 0); // Only "restart" when the update runs for the first time + $this->iohandler->set_task_count($migration_step_count, $restart_progress_bar); + $this->installer_config->set_task_progress_count($migration_step_count); while (!$this->migrator->finished()) { @@ -159,12 +160,17 @@ class update extends task_base $this->migrator->update(); $last_run_migration = $this->migrator->get_last_run_migration(); - - if ($last_run_migration['state']['migration_data_done']) + if (isset($last_run_migration['effectively_installed']) && $last_run_migration['effectively_installed']) + { + $progress_count += 2; + } + else if (($last_run_migration['task'] === 'process_schema_step' && $last_run_migration['state']['migration_schema_done']) || + ($last_run_migration['task'] === 'process_data_step' && $last_run_migration['state']['migration_data_done'])) { $progress_count++; - $this->iohandler->set_progress('STAGE_UPDATE_DATABASE', $progress_count); } + + $this->iohandler->set_progress('STAGE_UPDATE_DATABASE', $progress_count); } catch (exception $e) { -- cgit v1.2.1 From a37f10ae0951f16b115f4a175cc546a515cf7937 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sat, 20 Aug 2016 22:40:37 +0200 Subject: [ticket/14742] Increase user feedback by improving progress bar We now count and display each step that was done by increasing the task count. PHPBB3-14742 --- phpBB/phpbb/install/helper/iohandler/cli_iohandler.php | 11 ++++++++++- phpBB/phpbb/install/module/update_database/task/update.php | 14 ++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php index 2a41cb10ba..196cdcdaab 100644 --- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -198,6 +198,16 @@ class cli_iohandler extends iohandler_base if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL) { + if ($this->progress_bar !== null) + { + // Symfony's ProgressBar is immutable regarding task_count, so delete the old and create a new one. + $this->progress_bar->clear(); + } + else + { + $this->io->newLine(2); + } + $this->progress_bar = $this->io->createProgressBar($task_count); $this->progress_bar->setFormat( " %current:3s%/%max:-3s% %bar% %percent:3s%%\n" . @@ -212,7 +222,6 @@ class cli_iohandler extends iohandler_base } $this->progress_bar->setMessage(''); - $this->io->newLine(2); $this->progress_bar->start(); } } diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index c69dafaa10..9d7ba2f919 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -158,18 +158,23 @@ class update extends task_base try { $this->migrator->update(); + $progress_count++; $last_run_migration = $this->migrator->get_last_run_migration(); if (isset($last_run_migration['effectively_installed']) && $last_run_migration['effectively_installed']) { - $progress_count += 2; + // We skipped two step, so increment $progress_count by another one + $progress_count++; } - else if (($last_run_migration['task'] === 'process_schema_step' && $last_run_migration['state']['migration_schema_done']) || - ($last_run_migration['task'] === 'process_data_step' && $last_run_migration['state']['migration_data_done'])) + else if (($last_run_migration['task'] === 'process_schema_step' && !$last_run_migration['state']['migration_schema_done']) || + ($last_run_migration['task'] === 'process_data_step' && !$last_run_migration['state']['migration_data_done'])) { - $progress_count++; + // We just run a step that wasn't counted yet so make it count + $migration_step_count++; } + $this->iohandler->set_task_count($migration_step_count); + $this->installer_config->set_task_progress_count($migration_step_count); $this->iohandler->set_progress('STAGE_UPDATE_DATABASE', $progress_count); } catch (exception $e) @@ -184,6 +189,7 @@ class update extends task_base if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0) { $this->installer_config->set('database_update_count', $progress_count); + $this->installer_config->set('database_update_migration_steps', $migration_step_count); throw new resource_limit_reached_exception(); } } -- cgit v1.2.1 From 4b6c2c8cde0b87d32f8df8af87239580ddc340c4 Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Sun, 29 May 2016 12:42:57 +0200 Subject: [ticket/10961] Send HTTP 403 when applicable PHPBB3-10961 --- phpBB/phpbb/feed/forum.php | 16 ++++++++++++++++ phpBB/phpbb/feed/topic.php | 24 ++++++++++++++++++++++++ phpBB/phpbb/message/topic_form.php | 8 ++++++++ 3 files changed, 48 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php index 6701c4d9e7..f522e91169 100644 --- a/phpBB/phpbb/feed/forum.php +++ b/phpBB/phpbb/feed/forum.php @@ -74,6 +74,14 @@ class forum extends post_base // Make sure we can read this forum if (!$this->auth->acl_get('f_read', $this->forum_id)) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } throw new unauthorized_forum_exception($this->forum_id); } @@ -84,6 +92,14 @@ class forum extends post_base if (isset($forum_ids_passworded[$this->forum_id])) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } throw new unauthorized_forum_exception($this->forum_id); } diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php index f029c2b00e..e5f2c41468 100644 --- a/phpBB/phpbb/feed/topic.php +++ b/phpBB/phpbb/feed/topic.php @@ -66,6 +66,14 @@ class topic extends post_base // Make sure topic is either approved or user authed if ($this->topic_data['topic_visibility'] != ITEM_APPROVED && !$this->auth->acl_get('m_approve', $this->forum_id)) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } throw new unauthorized_topic_exception($this->topic_id); } @@ -78,6 +86,14 @@ class topic extends post_base // Make sure we can read this forum if (!$this->auth->acl_get('f_read', $this->forum_id)) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } throw new unauthorized_forum_exception($this->forum_id); } @@ -88,6 +104,14 @@ class topic extends post_base if (isset($forum_ids_passworded[$this->forum_id])) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } throw new unauthorized_forum_exception($this->forum_id); } diff --git a/phpBB/phpbb/message/topic_form.php b/phpBB/phpbb/message/topic_form.php index 174643bb81..dbb883c142 100644 --- a/phpBB/phpbb/message/topic_form.php +++ b/phpBB/phpbb/message/topic_form.php @@ -71,6 +71,14 @@ class topic_form extends form if (!$this->auth->acl_get('f_read', $this->topic_row['forum_id'])) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } return 'SORRY_AUTH_READ'; } -- cgit v1.2.1 From 35c62d1e74adc445e65a21f3aa317925bd258893 Mon Sep 17 00:00:00 2001 From: rxu Date: Thu, 22 Sep 2016 22:29:18 +0700 Subject: [ticket/14793] Fix "A non-numeric value encountered" PHP warning on PHP 7.1+ PHPBB3-14793 --- phpBB/phpbb/db/migration/data/v310/timezone.php | 2 +- phpBB/phpbb/search/base.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v310/timezone.php b/phpBB/phpbb/db/migration/data/v310/timezone.php index 1f6b47ad50..03a8d1ab34 100644 --- a/phpBB/phpbb/db/migration/data/v310/timezone.php +++ b/phpBB/phpbb/db/migration/data/v310/timezone.php @@ -103,7 +103,7 @@ class timezone extends \phpbb\db\migration\migration */ public function convert_phpbb30_timezone($timezone, $dst) { - $offset = $timezone + $dst; + $offset = (float) $timezone + (int) $dst; switch ($timezone) { diff --git a/phpBB/phpbb/search/base.php b/phpBB/phpbb/search/base.php index d9313dddab..56de973b65 100644 --- a/phpBB/phpbb/search/base.php +++ b/phpBB/phpbb/search/base.php @@ -286,7 +286,7 @@ class base $sql = 'DELETE FROM ' . SEARCH_RESULTS_TABLE . ' - WHERE search_time < ' . (time() - $config['search_store_results']); + WHERE search_time < ' . (time() - (int) $config['search_store_results']); $db->sql_query($sql); } } -- cgit v1.2.1 From 5b32019ad6b19859f18fb263cb8034da18f15364 Mon Sep 17 00:00:00 2001 From: rxu Date: Sat, 1 Oct 2016 02:59:17 +0700 Subject: [ticket/14799] Remove accidentally added whitespaces into 3.2.x and master PHPBB3-14799 --- phpBB/phpbb/notification/manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index 8ec5ec4b32..6923d96392 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -922,7 +922,7 @@ class manager if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name])) { $this->db->sql_transaction('rollback'); - + throw new \phpbb\notification\exception('NOTIFICATION_TYPE_NOT_EXIST', array($notification_type_name)); } -- cgit v1.2.1 From 7a5fbd0257d7b15b8230fa6c60581cc197cb1a47 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 2 Oct 2016 19:24:45 +0200 Subject: [ticket/14807] Updates Twig PHPBB3-14807 --- phpBB/phpbb/template/twig/loader.php | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/loader.php b/phpBB/phpbb/template/twig/loader.php index 8b12188a77..b2261dd8cd 100644 --- a/phpBB/phpbb/template/twig/loader.php +++ b/phpBB/phpbb/template/twig/loader.php @@ -12,6 +12,7 @@ */ namespace phpbb\template\twig; +use Twig_Loader_Filesystem; /** * Twig Template loader @@ -100,6 +101,16 @@ class loader extends \Twig_Loader_Filesystem return; } + /** + * Adds a realpath call to fix a BC break in Twig 1.26 (https://github.com/twigphp/Twig/issues/2145) + * + * {@inheritdoc} + */ + public function addPath($path, $namespace = self::MAIN_NAMESPACE) + { + return parent::addPath($this->filesystem->realpath($path), $namespace); + } + /** * Find the template * -- cgit v1.2.1 From 1d40c0f43b366638de16a99a874ce1475249ade0 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 9 Aug 2016 21:07:49 +0200 Subject: [ticket/14733] Support increasing hashing cost factor PHPBB3-14733 --- phpBB/phpbb/passwords/driver/base.php | 8 ++++++ phpBB/phpbb/passwords/driver/bcrypt.php | 31 ++++++++++++++++++++++- phpBB/phpbb/passwords/driver/driver_interface.php | 8 ++++++ phpBB/phpbb/passwords/manager.php | 2 +- 4 files changed, 47 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/passwords/driver/base.php b/phpBB/phpbb/passwords/driver/base.php index fd07a61bf4..49b96af372 100644 --- a/phpBB/phpbb/passwords/driver/base.php +++ b/phpBB/phpbb/passwords/driver/base.php @@ -52,6 +52,14 @@ abstract class base implements driver_interface return false; } + /** + * {@inheritdoc} + */ + public function needs_rehash($hash) + { + return false; + } + /** * {@inheritdoc} */ diff --git a/phpBB/phpbb/passwords/driver/bcrypt.php b/phpBB/phpbb/passwords/driver/bcrypt.php index eab1c3d569..39fb5e5cf1 100644 --- a/phpBB/phpbb/passwords/driver/bcrypt.php +++ b/phpBB/phpbb/passwords/driver/bcrypt.php @@ -17,6 +17,23 @@ class bcrypt extends base { const PREFIX = '$2a$'; + /** @var int Hashing cost factor */ + protected $cost_factor; + + /** + * Constructor of passwords driver object + * + * @param \phpbb\config\config $config phpBB config + * @param \phpbb\passwords\driver\helper $helper Password driver helper + */ + public function __construct(\phpbb\config\config $config, helper $helper, $cost_factor) + { + parent::__construct($config, $helper); + + // Don't allow cost factor to be below default setting + $this->cost_factor = max(10, $cost_factor); + } + /** * {@inheritdoc} */ @@ -25,6 +42,18 @@ class bcrypt extends base return self::PREFIX; } + /** + * {@inheritdoc} + */ + public function needs_rehash($hash) + { + preg_match('/^' . preg_quote($this->get_prefix()) . '([0-9]+)\$/', $hash, $matches); + + list(, $cost_factor) = $matches; + + return empty($cost_factor) || $this->cost_factor !== intval($cost_factor); + } + /** * {@inheritdoc} */ @@ -46,7 +75,7 @@ class bcrypt extends base if ($salt == '') { - $salt = $prefix . '10$' . $this->get_random_salt(); + $salt = $prefix . $this->cost_factor . '$' . $this->get_random_salt(); } $hash = crypt($password, $salt); diff --git a/phpBB/phpbb/passwords/driver/driver_interface.php b/phpBB/phpbb/passwords/driver/driver_interface.php index 3974484f13..6a660b80ea 100644 --- a/phpBB/phpbb/passwords/driver/driver_interface.php +++ b/phpBB/phpbb/passwords/driver/driver_interface.php @@ -29,6 +29,14 @@ interface driver_interface */ public function is_legacy(); + /** + * Check if password needs to be rehashed + * + * @param string $hash Hash to check for rehash + * @return bool True if password needs to be rehashed, false if not + */ + public function needs_rehash($hash); + /** * Returns the hash prefix * diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php index b2caba81f2..38c12995b4 100644 --- a/phpBB/phpbb/passwords/manager.php +++ b/phpBB/phpbb/passwords/manager.php @@ -297,7 +297,7 @@ class manager } else { - $this->convert_flag = false; + $this->convert_flag = $stored_hash_type->needs_rehash($hash); } // Check all legacy hash types if prefix is $CP$ -- cgit v1.2.1 From 297376ee949f3afe6ad2bd6849be8b8115a1adbb Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 16 Aug 2016 21:08:00 +0200 Subject: [ticket/14733] Use default cost factor in bcrypt constructor PHPBB3-14733 --- phpBB/phpbb/passwords/driver/bcrypt.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/passwords/driver/bcrypt.php b/phpBB/phpbb/passwords/driver/bcrypt.php index 39fb5e5cf1..eb1aeeeb76 100644 --- a/phpBB/phpbb/passwords/driver/bcrypt.php +++ b/phpBB/phpbb/passwords/driver/bcrypt.php @@ -25,8 +25,9 @@ class bcrypt extends base * * @param \phpbb\config\config $config phpBB config * @param \phpbb\passwords\driver\helper $helper Password driver helper + * @param int $cost_factor Hashing cost factor (optional) */ - public function __construct(\phpbb\config\config $config, helper $helper, $cost_factor) + public function __construct(\phpbb\config\config $config, helper $helper, $cost_factor = 10) { parent::__construct($config, $helper); -- cgit v1.2.1 From d15269950d8f577a69f3359614d48087c84d4cec Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 25 Sep 2016 18:00:49 +0200 Subject: [ticket/14733] Use new interface to preserve backwards compatibility PHPBB3-14733 --- phpBB/phpbb/passwords/driver/base.php | 4 +- phpBB/phpbb/passwords/driver/driver_interface.php | 8 --- .../driver/rehashable_driver_interface.php | 77 ++++++++++++++++++++++ 3 files changed, 79 insertions(+), 10 deletions(-) create mode 100644 phpBB/phpbb/passwords/driver/rehashable_driver_interface.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/passwords/driver/base.php b/phpBB/phpbb/passwords/driver/base.php index 49b96af372..0997b5b700 100644 --- a/phpBB/phpbb/passwords/driver/base.php +++ b/phpBB/phpbb/passwords/driver/base.php @@ -13,7 +13,7 @@ namespace phpbb\passwords\driver; -abstract class base implements driver_interface +abstract class base implements rehashable_driver_interface { /** @var \phpbb\config\config */ protected $config; @@ -21,7 +21,7 @@ abstract class base implements driver_interface /** @var \phpbb\passwords\driver\helper */ protected $helper; - /** @var driver name */ + /** @var string Driver name */ protected $name; /** diff --git a/phpBB/phpbb/passwords/driver/driver_interface.php b/phpBB/phpbb/passwords/driver/driver_interface.php index 6a660b80ea..3974484f13 100644 --- a/phpBB/phpbb/passwords/driver/driver_interface.php +++ b/phpBB/phpbb/passwords/driver/driver_interface.php @@ -29,14 +29,6 @@ interface driver_interface */ public function is_legacy(); - /** - * Check if password needs to be rehashed - * - * @param string $hash Hash to check for rehash - * @return bool True if password needs to be rehashed, false if not - */ - public function needs_rehash($hash); - /** * Returns the hash prefix * diff --git a/phpBB/phpbb/passwords/driver/rehashable_driver_interface.php b/phpBB/phpbb/passwords/driver/rehashable_driver_interface.php new file mode 100644 index 0000000000..c22f41cf6b --- /dev/null +++ b/phpBB/phpbb/passwords/driver/rehashable_driver_interface.php @@ -0,0 +1,77 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\passwords\driver; + +interface rehashable_driver_interface +{ + /** + * Check if hash type is supported + * + * @return bool True if supported, false if not + */ + public function is_supported(); + + /** + * Check if hash type is a legacy hash type + * + * @return bool True if it's a legacy hash type, false if not + */ + public function is_legacy(); + + /** + * Check if password needs to be rehashed + * + * @param string $hash Hash to check for rehash + * @return bool True if password needs to be rehashed, false if not + */ + public function needs_rehash($hash); + + /** + * Returns the hash prefix + * + * @return string Hash prefix + */ + public function get_prefix(); + + /** + * Hash the password + * + * @param string $password The password that should be hashed + * + * @return bool|string Password hash or false if something went wrong + * during hashing + */ + public function hash($password); + + /** + * Check the password against the supplied hash + * + * @param string $password The password to check + * @param string $hash The password hash to check against + * @param array $user_row User's row in users table + * + * @return bool True if password is correct, else false + */ + public function check($password, $hash, $user_row = array()); + + /** + * Get only the settings of the specified hash + * + * @param string $hash Password hash + * @param bool $full Return full settings or only settings + * related to the salt + * @return string String containing the hash settings + */ + public function get_settings_only($hash, $full = false); +} -- cgit v1.2.1 From 722639a0e213e905cfb4a01aa54e638f7670ba63 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 25 Sep 2016 20:32:42 +0200 Subject: [ticket/14733] Extend passwords driver_interface in rehashable_driver_interface PHPBB3-14733 --- .../driver/rehashable_driver_interface.php | 54 +--------------------- phpBB/phpbb/passwords/manager.php | 9 +++- 2 files changed, 9 insertions(+), 54 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/passwords/driver/rehashable_driver_interface.php b/phpBB/phpbb/passwords/driver/rehashable_driver_interface.php index c22f41cf6b..ca30748502 100644 --- a/phpBB/phpbb/passwords/driver/rehashable_driver_interface.php +++ b/phpBB/phpbb/passwords/driver/rehashable_driver_interface.php @@ -13,22 +13,8 @@ namespace phpbb\passwords\driver; -interface rehashable_driver_interface +interface rehashable_driver_interface extends driver_interface { - /** - * Check if hash type is supported - * - * @return bool True if supported, false if not - */ - public function is_supported(); - - /** - * Check if hash type is a legacy hash type - * - * @return bool True if it's a legacy hash type, false if not - */ - public function is_legacy(); - /** * Check if password needs to be rehashed * @@ -36,42 +22,4 @@ interface rehashable_driver_interface * @return bool True if password needs to be rehashed, false if not */ public function needs_rehash($hash); - - /** - * Returns the hash prefix - * - * @return string Hash prefix - */ - public function get_prefix(); - - /** - * Hash the password - * - * @param string $password The password that should be hashed - * - * @return bool|string Password hash or false if something went wrong - * during hashing - */ - public function hash($password); - - /** - * Check the password against the supplied hash - * - * @param string $password The password to check - * @param string $hash The password hash to check against - * @param array $user_row User's row in users table - * - * @return bool True if password is correct, else false - */ - public function check($password, $hash, $user_row = array()); - - /** - * Get only the settings of the specified hash - * - * @param string $hash Password hash - * @param bool $full Return full settings or only settings - * related to the salt - * @return string String containing the hash settings - */ - public function get_settings_only($hash, $full = false); } diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php index 38c12995b4..6c3ef4c477 100644 --- a/phpBB/phpbb/passwords/manager.php +++ b/phpBB/phpbb/passwords/manager.php @@ -297,7 +297,14 @@ class manager } else { - $this->convert_flag = $stored_hash_type->needs_rehash($hash); + if ($stored_hash_type instanceof driver\rehashable_driver_interface) + { + $this->convert_flag = $stored_hash_type->needs_rehash($hash); + } + else + { + $this->convert_flag = false; + } } // Check all legacy hash types if prefix is $CP$ -- cgit v1.2.1 From 380be9f1fd713dbcee91f12f18060d6b3ff4819e Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 25 Sep 2016 20:33:10 +0200 Subject: [ticket/14733] Make sure detect_algorithm() works correctly and add tests detect_algorithm() returned array() if an algorithm prefix was more than 2 characters long. This might have been invalid for other prefixes. In order to correctly cope with other prefixes, another check for a backslash in the prefix definitino has been added. This was discovered while writing the tests for the newly added interface. PHPBB3-14733 --- phpBB/phpbb/passwords/manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php index 6c3ef4c477..fad76a9fe5 100644 --- a/phpBB/phpbb/passwords/manager.php +++ b/phpBB/phpbb/passwords/manager.php @@ -174,7 +174,7 @@ class manager // Be on the lookout for multiple hashing algorithms // 2 is correct: H\2a > 2, H\P > 2 - if (strlen($match[1]) > 2) + if (strlen($match[1]) > 2 && strpos($match[1], '\\') !== false) { $hash_types = explode('\\', $match[1]); $return_ary = array(); -- cgit v1.2.1 From b2711371f1267a1314ccf1de976d5432c03a2357 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 10 Oct 2016 09:14:24 +0200 Subject: [ticket/14807] s9e/textformatter 0.8.1 PHPBB3-14807 --- phpBB/phpbb/template/twig/loader.php | 1 - 1 file changed, 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/loader.php b/phpBB/phpbb/template/twig/loader.php index b2261dd8cd..d2b42852ce 100644 --- a/phpBB/phpbb/template/twig/loader.php +++ b/phpBB/phpbb/template/twig/loader.php @@ -12,7 +12,6 @@ */ namespace phpbb\template\twig; -use Twig_Loader_Filesystem; /** * Twig Template loader -- cgit v1.2.1 From d90afa67d866e1be44d3a69c97497c8412695f8d Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 9 Oct 2016 21:37:30 +0200 Subject: [ticket/14814] Fix reparser cron PHPBB3-14814 --- phpBB/phpbb/console/command/reparser/reparse.php | 2 +- phpBB/phpbb/cron/task/text_reparser/reparser.php | 8 ++++---- phpBB/phpbb/db/migration/data/v320/text_reparser.php | 20 +++++++++++++++++--- 3 files changed, 22 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/reparser/reparse.php b/phpBB/phpbb/console/command/reparser/reparse.php index b10bd56a58..cebeee0919 100644 --- a/phpBB/phpbb/console/command/reparser/reparse.php +++ b/phpBB/phpbb/console/command/reparser/reparse.php @@ -208,7 +208,7 @@ class reparse extends \phpbb\console\command\command $size = $this->get_option('range-size'); // range-max has no default value, it must be computed for each reparser - if ($max == null) + if ($max === null) { $max = $reparser->get_max_id(); } diff --git a/phpBB/phpbb/cron/task/text_reparser/reparser.php b/phpBB/phpbb/cron/task/text_reparser/reparser.php index aa644de827..7099128efd 100644 --- a/phpBB/phpbb/cron/task/text_reparser/reparser.php +++ b/phpBB/phpbb/cron/task/text_reparser/reparser.php @@ -99,7 +99,7 @@ class reparser extends \phpbb\cron\task\base $this->reparser_manager->get_resume_data($this->reparser_name); } - if (empty($this->resume_data['range-max']) || $this->resume_data['range-max'] >= $this->resume_data['range-min']) + if (!isset($this->resume_data['range-max']) || $this->resume_data['range-max'] >= $this->resume_data['range-min']) { return true; } @@ -147,9 +147,9 @@ class reparser extends \phpbb\cron\task\base */ $reparser = $this->reparsers[$this->reparser_name]; - $min = !empty($this->resume_data['range-min']) ? $this->resume_data['range-min'] : self::MIN; - $current = !empty($this->resume_data['range-max']) ? $this->resume_data['range-max'] : $reparser->get_max_id(); - $size = !empty($this->resume_data['range-size']) ? $this->resume_data['range-size'] : self::SIZE; + $min = isset($this->resume_data['range-min']) ? $this->resume_data['range-min'] : self::MIN; + $current = isset($this->resume_data['range-max']) ? $this->resume_data['range-max'] : $reparser->get_max_id(); + $size = isset($this->resume_data['range-size']) ? $this->resume_data['range-size'] : self::SIZE; if ($current >= $min) { diff --git a/phpBB/phpbb/db/migration/data/v320/text_reparser.php b/phpBB/phpbb/db/migration/data/v320/text_reparser.php index ea614feb40..03c5d39fe4 100644 --- a/phpBB/phpbb/db/migration/data/v320/text_reparser.php +++ b/phpBB/phpbb/db/migration/data/v320/text_reparser.php @@ -13,6 +13,9 @@ namespace phpbb\db\migration\data\v320; +use phpbb\textreparser\manager; +use phpbb\textreparser\reparser_interface; + class text_reparser extends \phpbb\db\migration\container_aware_migration { static public function depends_on() @@ -48,7 +51,19 @@ class text_reparser extends \phpbb\db\migration\container_aware_migration public function reparse($resume_data) { - // Somtimes a cron job is too much + /** @var manager $reparser_manager */ + $reparser_manager = $this->container->get('text_reparser.manager'); + + /** @var reparser_interface[] $reparsers */ + $reparsers = $this->container->get('text_reparser_collection'); + + // Initialize all reparsers + foreach ($reparsers as $name => $reparser) + { + $reparser_manager->update_resume_data($name, 1, $reparser->get_max_id(), 100); + } + + // Sometimes a cron job is too much $limit = 100; $fast_reparsers = array( 'text_reparser.contact_admin_info', @@ -65,7 +80,7 @@ class text_reparser extends \phpbb\db\migration\container_aware_migration ); } - $fast_reparsers_size = sizeof($fast_reparsers); + $fast_reparsers_size = count($fast_reparsers); $processed_records = 0; while ($processed_records < $limit && $resume_data['reparser'] < $fast_reparsers_size) { @@ -87,7 +102,6 @@ class text_reparser extends \phpbb\db\migration\container_aware_migration if ($start === 1) { // Prevent CLI command from running these reparsers again - $reparser_manager = $this->container->get('text_reparser.manager'); $reparser_manager->update_resume_data($fast_reparsers[$resume_data['reparser']], 1, 0, $limit); $resume_data['reparser']++; -- cgit v1.2.1 From 4d07f8a13423529d4559d6579f98305ee471ee84 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 3 Nov 2016 21:36:12 +0100 Subject: [ticket/14716] Update dependencies to latest versions This addresses some issues with symfony that resulted in issues when open_basedir restrictions were enabled, as well as issues with JPEG images in fast-image-size. The phpBB class extending the twig lexer also had to be modified to ensure compatibility after BC was broken by the PR https://github.com/twigphp/Twig/pull/2182 for twig 1.27. PHPBB3-14716 --- phpBB/phpbb/template/twig/lexer.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php index f1542109a4..de03aec04b 100644 --- a/phpBB/phpbb/template/twig/lexer.php +++ b/phpBB/phpbb/template/twig/lexer.php @@ -22,6 +22,11 @@ class lexer extends \Twig_Lexer public function tokenize($code, $filename = null) { + if ($code instanceof \Twig_Source) + { + $filename = $code->getName(); + $code = $code->getCode(); + } // Our phpBB tags // Commented out tokens are handled separately from the main replace $phpbb_tags = array( @@ -125,7 +130,7 @@ class lexer extends \Twig_Lexer // Appends any filters $code = preg_replace('#{([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ $1$2 }}', $code); - return parent::tokenize($code, $filename); + return parent::tokenize(new \Twig_Source($code, $filename)); } /** -- cgit v1.2.1 From 78c2e31ec2cab20f5fc0555706b27b63ad7d9437 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 13 Nov 2016 11:45:42 +0100 Subject: [ticket/security-181] Add .htaccess to 3.2.x migrations SECURITY-181 --- phpBB/phpbb/db/migration/data/v320/.htaccess | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/.htaccess (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/.htaccess b/phpBB/phpbb/db/migration/data/v320/.htaccess new file mode 100644 index 0000000000..44242b5418 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/.htaccess @@ -0,0 +1,33 @@ +# With Apache 2.4 the "Order, Deny" syntax has been deprecated and moved from +# module mod_authz_host to a new module called mod_access_compat (which may be +# disabled) and a new "Require" syntax has been introduced to mod_authz_host. +# We could just conditionally provide both versions, but unfortunately Apache +# does not explicitly tell us its version if the module mod_version is not +# available. In this case, we check for the availability of module +# mod_authz_core (which should be on 2.4 or higher only) as a best guess. + + + + Order Allow,Deny + Deny from All + + + = 2.4> + + Require all denied + + + + + + + Order Allow,Deny + Deny from All + + + + + Require all denied + + + -- cgit v1.2.1 From e974f338afb86c065e9b160363bc2e6156f8566d Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Sun, 13 Nov 2016 18:08:35 +0100 Subject: [ticket/14739] Remove SQLite 2.8.x database driver PHPBB3-14739 --- phpBB/phpbb/db/driver/sqlite.php | 384 -------------------------- phpBB/phpbb/db/extractor/factory.php | 4 - phpBB/phpbb/db/extractor/sqlite_extractor.php | 149 ---------- phpBB/phpbb/db/tools/tools.php | 116 +------- phpBB/phpbb/install/helper/database.php | 17 -- phpBB/phpbb/search/fulltext_native.php | 6 +- 6 files changed, 5 insertions(+), 671 deletions(-) delete mode 100644 phpBB/phpbb/db/driver/sqlite.php delete mode 100644 phpBB/phpbb/db/extractor/sqlite_extractor.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/driver/sqlite.php b/phpBB/phpbb/db/driver/sqlite.php deleted file mode 100644 index 8e205ebb81..0000000000 --- a/phpBB/phpbb/db/driver/sqlite.php +++ /dev/null @@ -1,384 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\db\driver; - -/** -* Sqlite Database Abstraction Layer -* Minimum Requirement: 2.8.2+ -*/ -class sqlite extends \phpbb\db\driver\driver -{ - var $connect_error = ''; - - /** - * {@inheritDoc} - */ - function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) - { - $this->persistency = $persistency; - $this->user = $sqluser; - $this->server = $sqlserver . (($port) ? ':' . $port : ''); - $this->dbname = $database; - - $error = ''; - if ($this->persistency) - { - if (!function_exists('sqlite_popen')) - { - $this->connect_error = 'sqlite_popen function does not exist, is sqlite extension installed?'; - return $this->sql_error(''); - } - $this->db_connect_id = @sqlite_popen($this->server, 0666, $error); - } - else - { - if (!function_exists('sqlite_open')) - { - $this->connect_error = 'sqlite_open function does not exist, is sqlite extension installed?'; - return $this->sql_error(''); - } - $this->db_connect_id = @sqlite_open($this->server, 0666, $error); - } - - if ($this->db_connect_id) - { - @sqlite_query('PRAGMA short_column_names = 1', $this->db_connect_id); -// @sqlite_query('PRAGMA encoding = "UTF-8"', $this->db_connect_id); - } - - return ($this->db_connect_id) ? true : array('message' => $error); - } - - /** - * {@inheritDoc} - */ - function sql_server_info($raw = false, $use_cache = true) - { - global $cache; - - if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite_version')) === false) - { - $result = @sqlite_query('SELECT sqlite_version() AS version', $this->db_connect_id); - if ($result) - { - $row = sqlite_fetch_array($result, SQLITE_ASSOC); - - $this->sql_server_version = (!empty($row['version'])) ? $row['version'] : 0; - - if (!empty($cache) && $use_cache) - { - $cache->put('sqlite_version', $this->sql_server_version); - } - } - } - - return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version; - } - - /** - * SQL Transaction - * @access private - */ - function _sql_transaction($status = 'begin') - { - switch ($status) - { - case 'begin': - return @sqlite_query('BEGIN', $this->db_connect_id); - break; - - case 'commit': - return @sqlite_query('COMMIT', $this->db_connect_id); - break; - - case 'rollback': - return @sqlite_query('ROLLBACK', $this->db_connect_id); - break; - } - - return true; - } - - /** - * {@inheritDoc} - */ - function sql_query($query = '', $cache_ttl = 0) - { - if ($query != '') - { - global $cache; - - // EXPLAIN only in extra debug mode - if (defined('DEBUG')) - { - $this->sql_report('start', $query); - } - else if (defined('PHPBB_DISPLAY_LOAD_TIME')) - { - $this->curtime = microtime(true); - } - - $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; - $this->sql_add_num_queries($this->query_result); - - if ($this->query_result === false) - { - if (($this->query_result = @sqlite_query($query, $this->db_connect_id)) === false) - { - $this->sql_error($query); - } - - if (defined('DEBUG')) - { - $this->sql_report('stop', $query); - } - else if (defined('PHPBB_DISPLAY_LOAD_TIME')) - { - $this->sql_time += microtime(true) - $this->curtime; - } - - if (!$this->query_result) - { - return false; - } - - if ($cache && $cache_ttl) - { - $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); - } - } - else if (defined('DEBUG')) - { - $this->sql_report('fromcache', $query); - } - } - else - { - return false; - } - - return $this->query_result; - } - - /** - * Build LIMIT query - */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) - { - $this->query_result = false; - - // if $total is set to 0 we do not want to limit the number of rows - if ($total == 0) - { - $total = -1; - } - - $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total); - - return $this->sql_query($query, $cache_ttl); - } - - /** - * {@inheritDoc} - */ - function sql_affectedrows() - { - return ($this->db_connect_id) ? @sqlite_changes($this->db_connect_id) : false; - } - - /** - * {@inheritDoc} - */ - function sql_fetchrow($query_id = false) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if ($cache && $cache->sql_exists($query_id)) - { - return $cache->sql_fetchrow($query_id); - } - - return ($query_id) ? sqlite_fetch_array($query_id, SQLITE_ASSOC) : false; - } - - /** - * {@inheritDoc} - */ - function sql_rowseek($rownum, &$query_id) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if ($cache && $cache->sql_exists($query_id)) - { - return $cache->sql_rowseek($rownum, $query_id); - } - - return ($query_id) ? @sqlite_seek($query_id, $rownum) : false; - } - - /** - * {@inheritDoc} - */ - function sql_nextid() - { - return ($this->db_connect_id) ? @sqlite_last_insert_rowid($this->db_connect_id) : false; - } - - /** - * {@inheritDoc} - */ - function sql_freeresult($query_id = false) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) - { - return $cache->sql_freeresult($query_id); - } - - return true; - } - - /** - * {@inheritDoc} - */ - function sql_escape($msg) - { - return @sqlite_escape_string($msg); - } - - /** - * {@inheritDoc} - * - * For SQLite an underscore is a not-known character... this may change with SQLite3 - */ - function sql_like_expression($expression) - { - // Unlike LIKE, GLOB is unfortunately case sensitive. - // We only catch * and ? here, not the character map possible on file globbing. - $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression); - - $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression); - $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression); - - return 'GLOB \'' . $this->sql_escape($expression) . '\''; - } - - /** - * {@inheritDoc} - * - * For SQLite an underscore is a not-known character... - */ - function sql_not_like_expression($expression) - { - // Unlike NOT LIKE, NOT GLOB is unfortunately case sensitive. - // We only catch * and ? here, not the character map possible on file globbing. - $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression); - - $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression); - $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression); - - return 'NOT GLOB \'' . $this->sql_escape($expression) . '\''; - } - - /** - * return sql error array - * @access private - */ - function _sql_error() - { - if (function_exists('sqlite_error_string')) - { - $error = array( - 'message' => @sqlite_error_string(@sqlite_last_error($this->db_connect_id)), - 'code' => @sqlite_last_error($this->db_connect_id), - ); - } - else - { - $error = array( - 'message' => $this->connect_error, - 'code' => '', - ); - } - - return $error; - } - - /** - * Build db-specific query data - * @access private - */ - function _sql_custom_build($stage, $data) - { - return $data; - } - - /** - * Close sql connection - * @access private - */ - function _sql_close() - { - return @sqlite_close($this->db_connect_id); - } - - /** - * Build db-specific report - * @access private - */ - function _sql_report($mode, $query = '') - { - switch ($mode) - { - case 'start': - break; - - case 'fromcache': - $endtime = explode(' ', microtime()); - $endtime = $endtime[0] + $endtime[1]; - - $result = @sqlite_query($query, $this->db_connect_id); - if ($result) - { - while ($void = sqlite_fetch_array($result, SQLITE_ASSOC)) - { - // Take the time spent on parsing rows into account - } - } - - $splittime = explode(' ', microtime()); - $splittime = $splittime[0] + $splittime[1]; - - $this->sql_report('record_fromcache', $query, $endtime, $splittime); - - break; - } - } -} diff --git a/phpBB/phpbb/db/extractor/factory.php b/phpBB/phpbb/db/extractor/factory.php index eed3661ae9..f27aae720f 100644 --- a/phpBB/phpbb/db/extractor/factory.php +++ b/phpBB/phpbb/db/extractor/factory.php @@ -65,10 +65,6 @@ class factory { return $this->container->get('dbal.extractor.extractors.postgres_extractor'); } - else if ($this->db instanceof \phpbb\db\driver\sqlite) - { - return $this->container->get('dbal.extractor.extractors.sqlite_extractor'); - } else if ($this->db instanceof \phpbb\db\driver\sqlite3) { return $this->container->get('dbal.extractor.extractors.sqlite3_extractor'); diff --git a/phpBB/phpbb/db/extractor/sqlite_extractor.php b/phpBB/phpbb/db/extractor/sqlite_extractor.php deleted file mode 100644 index 2734e23235..0000000000 --- a/phpBB/phpbb/db/extractor/sqlite_extractor.php +++ /dev/null @@ -1,149 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -namespace phpbb\db\extractor; - -use phpbb\db\extractor\exception\extractor_not_initialized_exception; - -class sqlite_extractor extends base_extractor -{ - /** - * {@inheritdoc} - */ - public function write_start($table_prefix) - { - if (!$this->is_initialized) - { - throw new extractor_not_initialized_exception(); - } - - $sql_data = "--\n"; - $sql_data .= "-- phpBB Backup Script\n"; - $sql_data .= "-- Dump of tables for $table_prefix\n"; - $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; - $sql_data .= "--\n"; - $sql_data .= "BEGIN TRANSACTION;\n"; - $this->flush($sql_data); - } - - /** - * {@inheritdoc} - */ - public function write_table($table_name) - { - if (!$this->is_initialized) - { - throw new extractor_not_initialized_exception(); - } - - $sql_data = '-- Table: ' . $table_name . "\n"; - $sql_data .= "DROP TABLE $table_name;\n"; - - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '" . $this->db->sql_escape($table_name) . "' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - // Create Table - $sql_data .= $row['sql'] . ";\n"; - - $result = $this->db->sql_query("PRAGMA index_list('" . $this->db->sql_escape($table_name) . "');"); - - $ar = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $ar[] = $row; - } - $this->db->sql_freeresult($result); - - foreach ($ar as $value) - { - if (strpos($value['name'], 'autoindex') !== false) - { - continue; - } - - $result = $this->db->sql_query("PRAGMA index_info('" . $this->db->sql_escape($value['name']) . "');"); - - $fields = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $fields[] = $row['name']; - } - $this->db->sql_freeresult($result); - - $sql_data .= 'CREATE ' . ($value['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $value['name'] . ' on ' . $table_name . ' (' . implode(', ', $fields) . ");\n"; - } - - $this->flush($sql_data . "\n"); - } - - /** - * {@inheritdoc} - */ - public function write_data($table_name) - { - if (!$this->is_initialized) - { - throw new extractor_not_initialized_exception(); - } - - $col_types = sqlite_fetch_column_types($this->db->get_db_connect_id(), $table_name); - - $sql = "SELECT * - FROM $table_name"; - $result = sqlite_unbuffered_query($this->db->get_db_connect_id(), $sql); - $rows = sqlite_fetch_all($result, SQLITE_ASSOC); - $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES ('; - foreach ($rows as $row) - { - foreach ($row as $column_name => $column_data) - { - if (is_null($column_data)) - { - $row[$column_name] = 'NULL'; - } - else if ($column_data == '') - { - $row[$column_name] = "''"; - } - else if (strpos($col_types[$column_name], 'text') !== false || strpos($col_types[$column_name], 'char') !== false || strpos($col_types[$column_name], 'blob') !== false) - { - $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data)); - } - } - $this->flush($sql_insert . implode(', ', $row) . ");\n"); - } - } - - /** - * Writes closing line(s) to database backup - * - * @return null - * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor() - */ - public function write_end() - { - if (!$this->is_initialized) - { - throw new extractor_not_initialized_exception(); - } - - $this->flush("COMMIT;\n"); - parent::write_end(); - } -} diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index 37ac0d0468..9273d69cd6 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -136,37 +136,6 @@ class tools implements tools_interface 'VARBINARY' => 'raw(255)', ), - 'sqlite' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'ULINT' => 'INTEGER UNSIGNED', // 'int(10) UNSIGNED', - 'UINT' => 'INTEGER UNSIGNED', // 'mediumint(8) UNSIGNED', - 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'INTEGER UNSIGNED', // 'mediumint(4) UNSIGNED', - 'BOOL' => 'INTEGER UNSIGNED', // 'tinyint(1) UNSIGNED', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'text(65535)', - 'STEXT' => 'text(65535)', - 'TEXT' => 'text(65535)', - 'MTEXT' => 'mediumtext(16777215)', - 'XSTEXT_UNI'=> 'text(65535)', - 'STEXT_UNI' => 'text(65535)', - 'TEXT_UNI' => 'text(65535)', - 'MTEXT_UNI' => 'mediumtext(16777215)', - 'TIMESTAMP' => 'INTEGER UNSIGNED', // 'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar(255)', - 'VARBINARY' => 'blob', - ), - 'sqlite3' => array( 'INT:' => 'INT(%d)', 'BINT' => 'BIGINT(20)', @@ -277,12 +246,6 @@ class tools implements tools_interface $sql = 'SHOW TABLES'; break; - case 'sqlite': - $sql = 'SELECT name - FROM sqlite_master - WHERE type = "table"'; - break; - case 'sqlite3': $sql = 'SELECT name FROM sqlite_master @@ -398,7 +361,6 @@ class tools implements tools_interface { case 'mysql_40': case 'mysql_41': - case 'sqlite': case 'sqlite3': $table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; break; @@ -420,7 +382,6 @@ class tools implements tools_interface break; case 'mysql_40': - case 'sqlite': case 'sqlite3': $table_sql .= "\n);"; $statements[] = $table_sql; @@ -497,7 +458,7 @@ class tools implements tools_interface $sqlite = false; // For SQLite we need to perform the schema changes in a much more different way - if (($this->db->get_sql_layer() == 'sqlite' || $this->db->get_sql_layer() == 'sqlite3') && $this->return_statements) + if ($this->db->get_sql_layer() == 'sqlite3' && $this->return_statements) { $sqlite_data = array(); $sqlite = true; @@ -884,7 +845,6 @@ class tools implements tools_interface WHERE LOWER(table_name) = '" . strtolower($table_name) . "'"; break; - case 'sqlite': case 'sqlite3': $sql = "SELECT sql FROM sqlite_master @@ -967,7 +927,6 @@ class tools implements tools_interface $col = 'index_name'; break; - case 'sqlite': case 'sqlite3': $sql = "PRAGMA index_list('" . $table_name . "');"; $col = 'name'; @@ -986,7 +945,6 @@ class tools implements tools_interface switch ($this->sql_layer) { case 'oracle': - case 'sqlite': case 'sqlite3': $row[$col] = substr($row[$col], strlen($table_name) + 1); break; @@ -1026,7 +984,6 @@ class tools implements tools_interface $col = 'index_name'; break; - case 'sqlite': case 'sqlite3': $sql = "PRAGMA index_list('" . $table_name . "');"; $col = 'name'; @@ -1041,7 +998,7 @@ class tools implements tools_interface continue; } - if (($this->sql_layer == 'sqlite' || $this->sql_layer == 'sqlite3') && !$row['unique']) + if ($this->sql_layer == 'sqlite3' && !$row['unique']) { continue; } @@ -1061,7 +1018,6 @@ class tools implements tools_interface } break; - case 'sqlite': case 'sqlite3': $row[$col] = substr($row[$col], strlen($table_name) + 1); break; @@ -1193,18 +1149,12 @@ class tools implements tools_interface break; - case 'sqlite': case 'sqlite3': $return_array['primary_key_set'] = false; if (isset($column_data[2]) && $column_data[2] == 'auto_increment') { - $sql .= ' INTEGER PRIMARY KEY'; + $sql .= ' INTEGER PRIMARY KEY AUTOINCREMENT'; $return_array['primary_key_set'] = true; - - if ($this->sql_layer === 'sqlite3') - { - $sql .= ' AUTOINCREMENT'; - } } else { @@ -1306,57 +1256,6 @@ class tools implements tools_interface $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; break; - case 'sqlite': - if ($inline && $this->return_statements) - { - return $column_name . ' ' . $column_data['column_type_sql']; - } - - $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name); - if (empty($recreate_queries)) - { - break; - } - - $statements[] = 'begin'; - - $sql_create_table = array_shift($recreate_queries); - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $sql_create_table, $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - $column_list[] = $entities[0]; - } - - $columns = implode(',', $column_list); - - $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols; - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; - $statements = array_merge($statements, $recreate_queries); - - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - break; - case 'sqlite3': if ($inline && $this->return_statements) { @@ -1388,7 +1287,6 @@ class tools implements tools_interface $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name; break; - case 'sqlite': case 'sqlite3': if ($inline && $this->return_statements) @@ -1465,7 +1363,6 @@ class tools implements tools_interface break; case 'oracle': - case 'sqlite': case 'sqlite3': $statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name; break; @@ -1529,7 +1426,6 @@ class tools implements tools_interface $statements[] = 'ALTER TABLE ' . $table_name . ' add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; break; - case 'sqlite': case 'sqlite3': if ($inline && $this->return_statements) @@ -1596,7 +1492,6 @@ class tools implements tools_interface switch ($this->sql_layer) { case 'oracle': - case 'sqlite': case 'sqlite3': $statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; break; @@ -1628,7 +1523,6 @@ class tools implements tools_interface switch ($this->sql_layer) { case 'oracle': - case 'sqlite': case 'sqlite3': $statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; break; @@ -1693,7 +1587,6 @@ class tools implements tools_interface $col = 'index_name'; break; - case 'sqlite': case 'sqlite3': $sql = "PRAGMA index_info('" . $table_name . "');"; $col = 'name'; @@ -1711,7 +1604,6 @@ class tools implements tools_interface switch ($this->sql_layer) { case 'oracle': - case 'sqlite': case 'sqlite3': $row[$col] = substr($row[$col], strlen($table_name) + 1); break; @@ -1818,7 +1710,6 @@ class tools implements tools_interface $this->return_statements = $old_return_statements; break; - case 'sqlite': case 'sqlite3': if ($inline && $this->return_statements) @@ -1899,7 +1790,6 @@ class tools implements tools_interface { case 'mysql_40': case 'mysql_41': - case 'sqlite': case 'sqlite3': // Not supported throw new \Exception('DBMS is not supported'); diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php index be0c953d28..192f0a3654 100644 --- a/phpBB/phpbb/install/helper/database.php +++ b/phpBB/phpbb/install/helper/database.php @@ -90,15 +90,6 @@ class database 'AVAILABLE' => true, '2.0.x' => true, ), - 'sqlite' => array( - 'LABEL' => 'SQLite', - 'SCHEMA' => 'sqlite', - 'MODULE' => 'sqlite', - 'DELIM' => ';', - 'DRIVER' => 'phpbb\db\driver\sqlite', - 'AVAILABLE' => true, - '2.0.x' => false, - ), 'sqlite3' => array( 'LABEL' => 'SQLite3', 'SCHEMA' => 'sqlite', @@ -390,14 +381,6 @@ class database ); } break; - case 'sqlite': - if (version_compare($db->sql_server_info(true), '2.8.2', '<')) - { - $errors[] = array( - 'title' => 'INST_ERR_DB_NO_SQLITE', - ); - } - break; case 'sqlite3': if (version_compare($db->sql_server_info(true), '3.6.15', '<')) { diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 580d9b6878..2071a973e5 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -878,7 +878,6 @@ class fulltext_native extends \phpbb\search\base break; - case 'sqlite': case 'sqlite3': $sql_array_count['SELECT'] = ($type == 'posts') ? 'DISTINCT p.post_id' : 'DISTINCT p.topic_id'; $sql = 'SELECT COUNT(' . (($type == 'posts') ? 'post_id' : 'topic_id') . ') as total_results @@ -1185,7 +1184,7 @@ class fulltext_native extends \phpbb\search\base } else { - if ($this->db->get_sql_layer() == 'sqlite' || $this->db->get_sql_layer() == 'sqlite3') + if ($this->db->get_sql_layer() == 'sqlite3') { $sql = 'SELECT COUNT(topic_id) as total_results FROM (SELECT DISTINCT t.topic_id'; @@ -1202,7 +1201,7 @@ class fulltext_native extends \phpbb\search\base $post_visibility $sql_fora AND t.topic_id = p.topic_id - $sql_time" . (($this->db->get_sql_layer() == 'sqlite' || $this->db->get_sql_layer() == 'sqlite3') ? ')' : ''); + $sql_time" . ($this->db->get_sql_layer() == 'sqlite3' ? ')' : ''); } $result = $this->db->sql_query($sql); @@ -1667,7 +1666,6 @@ class fulltext_native extends \phpbb\search\base { switch ($this->db->get_sql_layer()) { - case 'sqlite': case 'sqlite3': $this->db->sql_query('DELETE FROM ' . SEARCH_WORDLIST_TABLE); $this->db->sql_query('DELETE FROM ' . SEARCH_WORDMATCH_TABLE); -- cgit v1.2.1 From a96fc3d87fdb6558397debd26992877677816d34 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 16 Nov 2016 21:39:29 +0100 Subject: [ticket/14867] Revert back to twig 1.26.* and update dependencies The revert of twig back to 1.26.* is necessary due to a breaking change in the way the Filesystem loader returns the paths to template files. PHPBB3-14867 --- phpBB/phpbb/template/twig/lexer.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php index de03aec04b..f1542109a4 100644 --- a/phpBB/phpbb/template/twig/lexer.php +++ b/phpBB/phpbb/template/twig/lexer.php @@ -22,11 +22,6 @@ class lexer extends \Twig_Lexer public function tokenize($code, $filename = null) { - if ($code instanceof \Twig_Source) - { - $filename = $code->getName(); - $code = $code->getCode(); - } // Our phpBB tags // Commented out tokens are handled separately from the main replace $phpbb_tags = array( @@ -130,7 +125,7 @@ class lexer extends \Twig_Lexer // Appends any filters $code = preg_replace('#{([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ $1$2 }}', $code); - return parent::tokenize(new \Twig_Source($code, $filename)); + return parent::tokenize($code, $filename); } /** -- cgit v1.2.1 From 23f5b6debdd24cc1caefd3bb8cd6da96a88abe9a Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 24 Nov 2016 22:22:38 +0100 Subject: [ticket/14875] Add method for untrimmed input to ajax iohandler Due to the pre-encoded input and the escaping of the input, the string has to be decoded twice for the password. PHPBB3-14875 --- phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php | 16 ++++++++++++++++ .../module/obtain_data/task/obtain_database_data.php | 11 ++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php index c168d26425..591a19b7c1 100644 --- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -120,6 +120,22 @@ class ajax_iohandler extends iohandler_base return $this->request->variable($name, $default, $multibyte); } + /** + * Returns untrimmed input variable + * + * @param string $name Name of the input variable to obtain + * @param mixed $default A default value that is returned if the variable was not set. + * This function will always return a value of the same type as the default. + * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters + * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks + * + * @return mixed Value of the untrimmed input variable + */ + public function get_untrimmed_input($name, $default, $multibyte = false) + { + return $this->request->untrimmed_variable($name, $default, $multibyte); + } + /** * {@inheritdoc} */ diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php index ce720dbf76..9019cf4332 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php @@ -79,10 +79,19 @@ class obtain_database_data extends \phpbb\install\task_base implements \phpbb\in $dbhost = $this->io_handler->get_input('dbhost', '', true); $dbport = $this->io_handler->get_input('dbport', ''); $dbuser = $this->io_handler->get_input('dbuser', ''); - $dbpasswd = $this->io_handler->get_input('dbpasswd', '', true); $dbname = $this->io_handler->get_input('dbname', ''); $table_prefix = $this->io_handler->get_input('table_prefix', ''); + // Need to get untrimmed password when using ajax IO handler + if ($this->io_handler instanceof \phpbb\install\helper\iohandler\ajax_iohandler) + { + $dbpasswd = htmlspecialchars_decode(htmlspecialchars_decode($this->io_handler->get_untrimmed_input('dbpasswd', '', true))); + } + else + { + $dbpasswd = $this->io_handler->get_input('dbpasswd', '', true); + } + // Check database data $user_data_vaild = $this->check_database_data($dbms, $dbhost, $dbport, $dbuser, $dbpasswd, $dbname, $table_prefix); -- cgit v1.2.1 From 9aa017d0f7ce13a11114cbae24b694e935931342 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 25 Nov 2016 22:15:13 +0100 Subject: [ticket/14875] Add method for raw input to request and add to installer A method for retrieving raw input has been added to the request class. This will be used in the installer to retrieve the datatabase password while also allowing utf8 characters. Not escaping the input is ok in this case as it won't be put anywhere in this raw form and only be used to populate the entry for the password field in config.php. PHPBB3-14875 --- .../install/helper/iohandler/ajax_iohandler.php | 20 +++---- .../install/helper/iohandler/cli_iohandler.php | 14 +++++ .../helper/iohandler/iohandler_interface.php | 11 ++++ .../obtain_data/task/obtain_database_data.php | 11 +--- phpBB/phpbb/request/request.php | 62 ++++++++++++++++++++++ 5 files changed, 94 insertions(+), 24 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php index 591a19b7c1..2db6750f3f 100644 --- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -27,7 +27,7 @@ class ajax_iohandler extends iohandler_base protected $path_helper; /** - * @var \phpbb\request\request_interface + * @var \phpbb\request\request */ protected $request; @@ -90,12 +90,12 @@ class ajax_iohandler extends iohandler_base * Constructor * * @param path_helper $path_helper - * @param \phpbb\request\request_interface $request HTTP request interface + * @param \phpbb\request\request $request HTTP request interface * @param \phpbb\template\template $template Template engine * @param router $router Router * @param string $root_path Path to phpBB's root */ - public function __construct(path_helper $path_helper, \phpbb\request\request_interface $request, \phpbb\template\template $template, router $router, $root_path) + public function __construct(path_helper $path_helper, \phpbb\request\request $request, \phpbb\template\template $template, router $router, $root_path) { $this->path_helper = $path_helper; $this->request = $request; @@ -121,19 +121,11 @@ class ajax_iohandler extends iohandler_base } /** - * Returns untrimmed input variable - * - * @param string $name Name of the input variable to obtain - * @param mixed $default A default value that is returned if the variable was not set. - * This function will always return a value of the same type as the default. - * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters - * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks - * - * @return mixed Value of the untrimmed input variable + * {@inheritdoc} */ - public function get_untrimmed_input($name, $default, $multibyte = false) + public function get_raw_input($name, $default) { - return $this->request->untrimmed_variable($name, $default, $multibyte); + return $this->request->raw_variable($name, $default); } /** diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php index 196cdcdaab..4117a3dfd3 100644 --- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -74,6 +74,20 @@ class cli_iohandler extends iohandler_base return $result; } + /** + * {@inheritdoc} + */ + public function get_raw_input($name, $default) + { + return $this->get_input($name, $default, true); + } + + /** + * Set input variable + * + * @param string $name Name of input variable + * @param mixed $value Value of input variable + */ public function set_input($name, $value) { $this->input_values[$name] = $value; diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php index f22f33d9cb..f0e0e99bbb 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php @@ -38,6 +38,17 @@ interface iohandler_interface */ public function get_input($name, $default, $multibyte = false); + /** + * Returns raw input variable + * + * @param string $name Name of the input variable to obtain + * @param mixed $default A default value that is returned if the variable was not set. + * This function will always return a value of the same type as the default. + * + * @return mixed Value of the raw input variable + */ + public function get_raw_input($name, $default); + /** * Returns server variable * diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php index 9019cf4332..dc7b060746 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php @@ -79,19 +79,10 @@ class obtain_database_data extends \phpbb\install\task_base implements \phpbb\in $dbhost = $this->io_handler->get_input('dbhost', '', true); $dbport = $this->io_handler->get_input('dbport', ''); $dbuser = $this->io_handler->get_input('dbuser', ''); + $dbpasswd = $this->io_handler->get_raw_input('dbpasswd', ''); $dbname = $this->io_handler->get_input('dbname', ''); $table_prefix = $this->io_handler->get_input('table_prefix', ''); - // Need to get untrimmed password when using ajax IO handler - if ($this->io_handler instanceof \phpbb\install\helper\iohandler\ajax_iohandler) - { - $dbpasswd = htmlspecialchars_decode(htmlspecialchars_decode($this->io_handler->get_untrimmed_input('dbpasswd', '', true))); - } - else - { - $dbpasswd = $this->io_handler->get_input('dbpasswd', '', true); - } - // Check database data $user_data_vaild = $this->check_database_data($dbms, $dbhost, $dbport, $dbuser, $dbpasswd, $dbname, $table_prefix); diff --git a/phpBB/phpbb/request/request.php b/phpBB/phpbb/request/request.php index 4cac6fbaea..318d9f66f9 100644 --- a/phpBB/phpbb/request/request.php +++ b/phpBB/phpbb/request/request.php @@ -224,6 +224,68 @@ class request implements \phpbb\request\request_interface return $this->_variable($var_name, $default, $multibyte, $super_global, false); } + /** + * Get a variable without trimming strings and without escaping. + * This method MUST NOT be used with queries. + * Same functionality as variable(), except does not run trim() on strings + * and does not escape input. + * This method should only be used when the raw input is needed without + * any escaping, i.e. for database password during the installation. + * + * @param string|array $var_name The form variable's name from which data shall be retrieved. + * If the value is an array this may be an array of indizes which will give + * direct access to a value at any depth. E.g. if the value of "var" is array(1 => "a") + * then specifying array("var", 1) as the name will return "a". + * @param mixed $default A default value that is returned if the variable was not set. + * This function will always return a value of the same type as the default. + * @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global + * Specifies which super global should be used + * + * @return mixed The value of $_REQUEST[$var_name] run through {@link set_var set_var} to ensure that the type is the + * the same as that of $default. If the variable is not set $default is returned. + */ + public function raw_variable($var_name, $default, $super_global = \phpbb\request\request_interface::REQUEST) + { + $path = false; + + // deep direct access to multi dimensional arrays + if (is_array($var_name)) + { + $path = $var_name; + // make sure at least the variable name is specified + if (empty($path)) + { + return (is_array($default)) ? array() : $default; + } + // the variable name is the first element on the path + $var_name = array_shift($path); + } + + if (!isset($this->input[$super_global][$var_name])) + { + return (is_array($default)) ? array() : $default; + } + $var = $this->input[$super_global][$var_name]; + + if ($path) + { + // walk through the array structure and find the element we are looking for + foreach ($path as $key) + { + if (is_array($var) && isset($var[$key])) + { + $var = $var[$key]; + } + else + { + return (is_array($default)) ? array() : $default; + } + } + } + + return $var; + } + /** * Shortcut method to retrieve SERVER variables. * -- cgit v1.2.1 From 08bf8812d3bc7c22671e7e0dc88a0e99fcf403d7 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 25 Nov 2016 22:51:29 +0100 Subject: [ticket/14875] Use raw_variable() method in _variable() to get raw data The raw_variable() method uses the same exact code the _variable method has been using until now. PHPBB3-14875 --- phpBB/phpbb/request/request.php | 39 ++++++--------------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/request/request.php b/phpBB/phpbb/request/request.php index 318d9f66f9..0d9ffa1780 100644 --- a/phpBB/phpbb/request/request.php +++ b/phpBB/phpbb/request/request.php @@ -431,41 +431,14 @@ class request implements \phpbb\request\request_interface */ protected function _variable($var_name, $default, $multibyte = false, $super_global = \phpbb\request\request_interface::REQUEST, $trim = true) { - $path = false; - - // deep direct access to multi dimensional arrays - if (is_array($var_name)) - { - $path = $var_name; - // make sure at least the variable name is specified - if (empty($path)) - { - return (is_array($default)) ? array() : $default; - } - // the variable name is the first element on the path - $var_name = array_shift($path); - } - - if (!isset($this->input[$super_global][$var_name])) - { - return (is_array($default)) ? array() : $default; - } - $var = $this->input[$super_global][$var_name]; + $var = $this->raw_variable($var_name, $default, $super_global); - if ($path) + // Return prematurely if raw variable is empty array or the same as + // the default. Using strict comparison to ensure that one can't + // prevent proper type checking on any input variable + if ($var === array() || $var === $default) { - // walk through the array structure and find the element we are looking for - foreach ($path as $key) - { - if (is_array($var) && isset($var[$key])) - { - $var = $var[$key]; - } - else - { - return (is_array($default)) ? array() : $default; - } - } + return $var; } $this->type_cast_helper->recursive_set_var($var, $default, $multibyte, $trim); -- cgit v1.2.1 From 88c921be23a2cddbfb3ac7272eb14305664b6542 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 27 Nov 2016 13:30:15 +0100 Subject: [ticket/14873] Added width/height attributes to smilies PHPBB3-14873 --- phpBB/phpbb/textformatter/s9e/factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index f62daefdd9..a310c67359 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -311,7 +311,7 @@ class factory implements \phpbb\textformatter\cache_interface { $configurator->Emoticons->set( $row['code'], - '{.}' + '{.}' ); } -- cgit v1.2.1 From 9bdd002f584de78475362067b777749486504172 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 2 Dec 2016 11:36:07 +0100 Subject: [ticket/14875] Move raw_variable() method to request_interface PHPBB3-14875 --- .../install/helper/iohandler/ajax_iohandler.php | 6 +++--- .../helper/iohandler/iohandler_interface.php | 4 ++-- phpBB/phpbb/request/request.php | 19 +------------------ phpBB/phpbb/request/request_interface.php | 22 ++++++++++++++++++++++ 4 files changed, 28 insertions(+), 23 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php index 2db6750f3f..a40d457466 100644 --- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -27,7 +27,7 @@ class ajax_iohandler extends iohandler_base protected $path_helper; /** - * @var \phpbb\request\request + * @var \phpbb\request\request_interface */ protected $request; @@ -90,12 +90,12 @@ class ajax_iohandler extends iohandler_base * Constructor * * @param path_helper $path_helper - * @param \phpbb\request\request $request HTTP request interface + * @param \phpbb\request\request_interface $request HTTP request interface * @param \phpbb\template\template $template Template engine * @param router $router Router * @param string $root_path Path to phpBB's root */ - public function __construct(path_helper $path_helper, \phpbb\request\request $request, \phpbb\template\template $template, router $router, $root_path) + public function __construct(path_helper $path_helper, \phpbb\request\request_interface $request, \phpbb\template\template $template, router $router, $root_path) { $this->path_helper = $path_helper; $this->request = $request; diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php index f0e0e99bbb..440748901c 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php @@ -52,7 +52,7 @@ interface iohandler_interface /** * Returns server variable * - * This function should work the same as request_interterface::server(). + * This function should work the same as request_interface::server(). * * @param string $name Name of the server variable * @param mixed $default Default value to return when the requested variable does not exist @@ -62,7 +62,7 @@ interface iohandler_interface public function get_server_variable($name, $default = ''); /** - * Wrapper function for request_interterface::header() + * Wrapper function for request_interface::header() * * @param string $name Name of the request header variable * @param mixed $default Default value to return when the requested variable does not exist diff --git a/phpBB/phpbb/request/request.php b/phpBB/phpbb/request/request.php index 0d9ffa1780..92d4213180 100644 --- a/phpBB/phpbb/request/request.php +++ b/phpBB/phpbb/request/request.php @@ -225,24 +225,7 @@ class request implements \phpbb\request\request_interface } /** - * Get a variable without trimming strings and without escaping. - * This method MUST NOT be used with queries. - * Same functionality as variable(), except does not run trim() on strings - * and does not escape input. - * This method should only be used when the raw input is needed without - * any escaping, i.e. for database password during the installation. - * - * @param string|array $var_name The form variable's name from which data shall be retrieved. - * If the value is an array this may be an array of indizes which will give - * direct access to a value at any depth. E.g. if the value of "var" is array(1 => "a") - * then specifying array("var", 1) as the name will return "a". - * @param mixed $default A default value that is returned if the variable was not set. - * This function will always return a value of the same type as the default. - * @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global - * Specifies which super global should be used - * - * @return mixed The value of $_REQUEST[$var_name] run through {@link set_var set_var} to ensure that the type is the - * the same as that of $default. If the variable is not set $default is returned. + * {@inheritdoc} */ public function raw_variable($var_name, $default, $super_global = \phpbb\request\request_interface::REQUEST) { diff --git a/phpBB/phpbb/request/request_interface.php b/phpBB/phpbb/request/request_interface.php index 47b3b3a4ed..3bfa8bb424 100644 --- a/phpBB/phpbb/request/request_interface.php +++ b/phpBB/phpbb/request/request_interface.php @@ -64,6 +64,28 @@ interface request_interface */ public function variable($var_name, $default, $multibyte = false, $super_global = \phpbb\request\request_interface::REQUEST); + /** + * Get a variable without trimming strings and without escaping. + * This method MUST NOT be used with queries. + * Same functionality as variable(), except does not run trim() on strings + * and does not escape input. + * This method should only be used when the raw input is needed without + * any escaping, i.e. for database password during the installation. + * + * @param string|array $var_name The form variable's name from which data shall be retrieved. + * If the value is an array this may be an array of indizes which will give + * direct access to a value at any depth. E.g. if the value of "var" is array(1 => "a") + * then specifying array("var", 1) as the name will return "a". + * @param mixed $default A default value that is returned if the variable was not set. + * This function will always return a value of the same type as the default. + * @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global + * Specifies which super global should be used + * + * @return mixed The value of $_REQUEST[$var_name] run through {@link set_var set_var} to ensure that the type is the + * the same as that of $default. If the variable is not set $default is returned. + */ + public function raw_variable($var_name, $default, $super_global = \phpbb\request\request_interface::REQUEST); + /** * Shortcut method to retrieve SERVER variables. * -- cgit v1.2.1 From a99cb31a5290883bba532e8c340e6ef7bca802fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Fri, 2 Dec 2016 14:23:44 +0100 Subject: [ticket/14885] Add a line break when writing to the migrator output file --- phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php index 20991746ac..d28c195baa 100644 --- a/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php +++ b/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php @@ -94,7 +94,7 @@ class log_wrapper_migrator_output_handler implements migrator_output_handler_int $translated_message = '[DEBUG] ' . $translated_message; } - fwrite($this->file_handle, $translated_message); + fwrite($this->file_handle, $translated_message . "\r"); fflush($this->file_handle); } } -- cgit v1.2.1 From c3caa3d9dc156ed796c96810e88d4e98711d8d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Fri, 2 Dec 2016 16:50:55 +0100 Subject: [ticket/14885] Use \n instead of \r for output_handler messages --- phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php index d28c195baa..e4bd3ac8e0 100644 --- a/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php +++ b/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php @@ -94,7 +94,7 @@ class log_wrapper_migrator_output_handler implements migrator_output_handler_int $translated_message = '[DEBUG] ' . $translated_message; } - fwrite($this->file_handle, $translated_message . "\r"); + fwrite($this->file_handle, $translated_message . "\n"); fflush($this->file_handle); } } -- cgit v1.2.1 From c30394ff4a1034e5e6e7a0862e9101b5a80d8587 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 7 Dec 2015 09:59:47 +0100 Subject: [ticket/14492] Add basic task for installing viglink extension PHPBB3-14492 --- .../module/install_finish/task/install_viglink.php | 119 +++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 phpBB/phpbb/install/module/install_finish/task/install_viglink.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_viglink.php b/phpBB/phpbb/install/module/install_finish/task/install_viglink.php new file mode 100644 index 0000000000..1facb1eaf4 --- /dev/null +++ b/phpBB/phpbb/install/module/install_finish/task/install_viglink.php @@ -0,0 +1,119 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\install_finish\task; + +/** + * Installs viglink extension with default config + */ +class install_viglink extends \phpbb\install\task_base +{ + /** + * @var \phpbb\install\helper\config + */ + protected $install_config; + + /** + * @var \phpbb\install\helper\iohandler\iohandler_interface + */ + protected $iohandler; + + /** + * @var \phpbb\config\db + */ + protected $config; + + /** + * @var \phpbb\log\log_interface + */ + protected $log; + + /** + * @var \phpbb\user + */ + protected $user; + + /** @var \phpbb\extension\manager */ + protected $extension_manager; + + /** + * Constructor + * + * @param \phpbb\install\helper\container_factory $container + * @param \phpbb\install\helper\config $install_config + * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler + */ + public function __construct(\phpbb\install\helper\container_factory $container, \phpbb\install\helper\config $install_config, \phpbb\install\helper\iohandler\iohandler_interface $iohandler) + { + $this->install_config = $install_config; + $this->iohandler = $iohandler; + + $this->log = $container->get('log'); + $this->user = $container->get('user'); + $this->extension_manager = $container->get('ext.manager'); + $this->config = $container->get('config'); + + // Make sure asset version exists in config. Otherwise we might try to + // insert the assets_version setting into the database and cause a + // duplicate entry error. + if (!isset($this->config['assets_version'])) + { + $this->config['assets_version'] = 0; + } + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->user->session_begin(); + $this->user->setup(array('common', 'acp/common', 'cli')); + $name = 'phpbb/viglink'; + + // Should be available by default but make sure it is + if ($this->extension_manager->is_available($name)) + { + $this->extension_manager->enable($name); + $this->extension_manager->load_extensions(); + + if (!$this->extension_manager->is_enabled($name)) + { + // Create log + $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($name)); + } + } + else + { + $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array('phpbb/viglink')); + } + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_INSTALL_VIGLINK'; + } +} -- cgit v1.2.1 From 36460ebdf679f3cecb11afdc6e43e64195cc1d27 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 28 Jan 2016 20:24:51 +0100 Subject: [ticket/14492] Do not copy viglink on update if it was deleted PHPBB3-14492 --- phpBB/phpbb/install/module/update_filesystem/task/file_check.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php index f4b3870148..e4e0be0531 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -138,6 +138,15 @@ class file_check extends task_base $progress_count++; $this->iohandler->set_progress('UPDATE_CHECK_FILES', $progress_count); + // Do not copy viglink again if the previous version was packaged + // with it but it does not exist (e.g. deleted by admin) + if (strpos($file, $this->phpbb_root_path . 'ext/phpbb/viglink') !== false && + $this->update_helper->phpbb_version_compare($update_info['version']['from'], '3.2.0', '>=') && + !$this->filesystem->exists($this->phpbb_root_path . 'ext/phpbb/viglink')) + { + continue; + } + if (!$this->filesystem->exists($file)) { $file_update_info['new'][] = $filename; -- cgit v1.2.1 From 8fb2347cfa89ef9768311e92f11da4b090b94f7b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 28 Jan 2016 23:13:36 +0100 Subject: [ticket/14492] Install all packaged extensions by default PHPBB3-14492 --- .../install_finish/task/install_extensions.php | 135 +++++++++++++++++++++ .../module/install_finish/task/install_viglink.php | 119 ------------------ 2 files changed, 135 insertions(+), 119 deletions(-) create mode 100644 phpBB/phpbb/install/module/install_finish/task/install_extensions.php delete mode 100644 phpBB/phpbb/install/module/install_finish/task/install_viglink.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php new file mode 100644 index 0000000000..6b2881aa2f --- /dev/null +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -0,0 +1,135 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\install_finish\task; + +/** + * Installs extensions that exist in ext folder upon install + */ +class install_extensions extends \phpbb\install\task_base +{ + /** + * @var \phpbb\install\helper\config + */ + protected $install_config; + + /** + * @var \phpbb\install\helper\iohandler\iohandler_interface + */ + protected $iohandler; + + /** + * @var \phpbb\config\db + */ + protected $config; + + /** + * @var \phpbb\log\log_interface + */ + protected $log; + + /** + * @var \phpbb\user + */ + protected $user; + + /** @var \phpbb\extension\manager */ + protected $extension_manager; + + /** @var \Symfony\Component\Finder\Finder */ + protected $finder; + + /** + * Constructor + * + * @param \phpbb\install\helper\container_factory $container + * @param \phpbb\install\helper\config $install_config + * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler + * @param string $phpbb_root_path phpBB root path + */ + public function __construct(\phpbb\install\helper\container_factory $container, \phpbb\install\helper\config $install_config, \phpbb\install\helper\iohandler\iohandler_interface $iohandler, $phpbb_root_path) + { + $this->install_config = $install_config; + $this->iohandler = $iohandler; + + $this->log = $container->get('log'); + $this->user = $container->get('user'); + $this->extension_manager = $container->get('ext.manager'); + $this->config = $container->get('config'); + $this->finder = new \Symfony\Component\Finder\Finder(); + $this->finder->in($phpbb_root_path . 'ext/') + ->ignoreUnreadableDirs() + ->depth('< 3') + ->files() + ->name('composer.json'); + + // Make sure asset version exists in config. Otherwise we might try to + // insert the assets_version setting into the database and cause a + // duplicate entry error. + if (!isset($this->config['assets_version'])) + { + $this->config['assets_version'] = 0; + } + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->user->session_begin(); + $this->user->setup(array('common', 'acp/common', 'cli')); + $name = 'phpbb/viglink'; + + // Find available extensions + foreach ($this->finder as $file) + { + /** @var \SplFileInfo $file */ + $ext_name = preg_replace('#(.+ext[\\/\\\])#', '', dirname($file->getRealPath())); + + if ($this->extension_manager->is_available($ext_name)) + { + $this->extension_manager->enable($ext_name); + $this->extension_manager->load_extensions(); + + if (!$this->extension_manager->is_enabled($ext_name)) + { + // Create log + $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); + } + } + else + { + $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); + } + } + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_INSTALL_EXTENSIONS'; + } +} diff --git a/phpBB/phpbb/install/module/install_finish/task/install_viglink.php b/phpBB/phpbb/install/module/install_finish/task/install_viglink.php deleted file mode 100644 index 1facb1eaf4..0000000000 --- a/phpBB/phpbb/install/module/install_finish/task/install_viglink.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -namespace phpbb\install\module\install_finish\task; - -/** - * Installs viglink extension with default config - */ -class install_viglink extends \phpbb\install\task_base -{ - /** - * @var \phpbb\install\helper\config - */ - protected $install_config; - - /** - * @var \phpbb\install\helper\iohandler\iohandler_interface - */ - protected $iohandler; - - /** - * @var \phpbb\config\db - */ - protected $config; - - /** - * @var \phpbb\log\log_interface - */ - protected $log; - - /** - * @var \phpbb\user - */ - protected $user; - - /** @var \phpbb\extension\manager */ - protected $extension_manager; - - /** - * Constructor - * - * @param \phpbb\install\helper\container_factory $container - * @param \phpbb\install\helper\config $install_config - * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler - */ - public function __construct(\phpbb\install\helper\container_factory $container, \phpbb\install\helper\config $install_config, \phpbb\install\helper\iohandler\iohandler_interface $iohandler) - { - $this->install_config = $install_config; - $this->iohandler = $iohandler; - - $this->log = $container->get('log'); - $this->user = $container->get('user'); - $this->extension_manager = $container->get('ext.manager'); - $this->config = $container->get('config'); - - // Make sure asset version exists in config. Otherwise we might try to - // insert the assets_version setting into the database and cause a - // duplicate entry error. - if (!isset($this->config['assets_version'])) - { - $this->config['assets_version'] = 0; - } - - parent::__construct(true); - } - - /** - * {@inheritdoc} - */ - public function run() - { - $this->user->session_begin(); - $this->user->setup(array('common', 'acp/common', 'cli')); - $name = 'phpbb/viglink'; - - // Should be available by default but make sure it is - if ($this->extension_manager->is_available($name)) - { - $this->extension_manager->enable($name); - $this->extension_manager->load_extensions(); - - if (!$this->extension_manager->is_enabled($name)) - { - // Create log - $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($name)); - } - } - else - { - $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array('phpbb/viglink')); - } - } - - /** - * {@inheritdoc} - */ - static public function get_step_count() - { - return 1; - } - - /** - * {@inheritdoc} - */ - public function get_task_lang_name() - { - return 'TASK_INSTALL_VIGLINK'; - } -} -- cgit v1.2.1 From 267d1b15c4884dd67a299b2428251e68cd55327b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 29 Jan 2016 10:13:06 +0100 Subject: [ticket/14492] Re-enable extensions if updated during update PHPBB3-14492 --- .../install_finish/task/install_extensions.php | 3 +- .../update_database/task/update_extensions.php | 162 +++++++++++++++++++++ 2 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 phpBB/phpbb/install/module/update_database/task/update_extensions.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index 6b2881aa2f..28911b36c5 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -91,7 +91,6 @@ class install_extensions extends \phpbb\install\task_base { $this->user->session_begin(); $this->user->setup(array('common', 'acp/common', 'cli')); - $name = 'phpbb/viglink'; // Find available extensions foreach ($this->finder as $file) @@ -122,7 +121,7 @@ class install_extensions extends \phpbb\install\task_base */ static public function get_step_count() { - return 1; + return 0; } /** diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php new file mode 100644 index 0000000000..c7437d4746 --- /dev/null +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -0,0 +1,162 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\update_database\task; + +use phpbb\install\helper\container_factory; +use phpbb\install\helper\config; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\install\helper\update_helper; +use phpbb\install\task_base; +use Symfony\Component\Finder\Finder; + +/** + * Installs extensions that exist in ext folder upon install + */ +class enable_extensions extends task_base +{ + /** + * @var config + */ + protected $install_config; + + /** + * @var iohandler_interface + */ + protected $iohandler; + + /** @var update_helper */ + protected $update_helper; + + /** + * @var \phpbb\config\db + */ + protected $config; + + /** + * @var \phpbb\log\log_interface + */ + protected $log; + + /** + * @var \phpbb\user + */ + protected $user; + + /** @var \phpbb\extension\manager */ + protected $extension_manager; + + /** @var Finder */ + protected $finder; + + /** + * Constructor + * + * @param container_factory $container + * @param config $install_config + * @param iohandler_interface $iohandler + * @param $update_helper $update_helper + * @param string $phpbb_root_path phpBB root path + */ + public function __construct(container_factory $container, config $install_config, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path) + { + $this->install_config = $install_config; + $this->iohandler = $iohandler; + + $this->log = $container->get('log'); + $this->user = $container->get('user'); + $this->extension_manager = $container->get('ext.manager'); + $this->config = $container->get('config'); + $this->finder = new Finder(); + $this->finder->in($phpbb_root_path . 'ext/') + ->ignoreUnreadableDirs() + ->depth('< 3') + ->files() + ->name('composer.json'); + + // Make sure asset version exists in config. Otherwise we might try to + // insert the assets_version setting into the database and cause a + // duplicate entry error. + if (!isset($this->config['assets_version'])) + { + $this->config['assets_version'] = 0; + } + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->user->session_begin(); + $this->user->setup(array('common', 'acp/common', 'cli')); + + $update_info = $this->install_config->get('update_info_unprocessed', array()); + + if (!empty($update_info)) + { + // Find available extensions + foreach ($this->finder as $file) + { + /** @var \SplFileInfo $file */ + $ext_name = preg_replace('#(.+ext[\\/\\\])#', '', dirname($file->getRealPath())); + + // Skip extensions that were not added or updated during update + if (!count(preg_grep('#ext/' . $ext_name . '#', $update_info['files']))) + { + continue; + } + + // Disable enabled extensions in order to run migrations if needed + if ($this->extension_manager->is_enabled($ext_name)) + { + $this->extension_manager->disable($ext_name); + } + + if ($this->extension_manager->is_available($ext_name)) + { + $this->extension_manager->enable($ext_name); + $this->extension_manager->load_extensions(); + + if (!$this->extension_manager->is_enabled($ext_name)) + { + // Create log + $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); + } + } + else + { + $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); + } + } + } + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_UPDATE_EXTENSIONS'; + } +} -- cgit v1.2.1 From 430ec6f61d5da5b278ee2cadda535fcf9dcaed22 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 30 Jan 2016 16:12:44 +0100 Subject: [ticket/14492] Do not install extensions in installer if in test env PHPBB3-14492 --- .../phpbb/install/module/install_finish/task/install_extensions.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index 28911b36c5..d5086e7b82 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -89,6 +89,11 @@ class install_extensions extends \phpbb\install\task_base */ public function run() { + if (defined('PHPBB_ENVIRONMENT') && PHPBB_ENVIRONMENT === 'test') + { + return; + } + $this->user->session_begin(); $this->user->setup(array('common', 'acp/common', 'cli')); -- cgit v1.2.1 From c1035c98e455548fe14fbf5443bb98137d4e3d5d Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 31 Jan 2016 23:49:17 +0100 Subject: [ticket/14492] Rename files to help_phpbb and fix css tabbing PHPBB3-14492 --- .../db/migration/data/v320/add_help_phpbb.php | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php b/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php new file mode 100644 index 0000000000..4274f53520 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php @@ -0,0 +1,49 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class add_help_phpbb extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320a2', + ); + } + + public function effectively_installed() + { + return isset($this->config['help_send_statistics']); + } + + public function update_data() + { + return array( + array('config.add', array('help_send_statistics', true)), + array('module.remove', array( + 'acp', + false, + 'ACP_SEND_STATISTICS', + )), + array('module.add', array( + 'acp', + 'ACP_SERVER_CONFIGURATION', + array( + 'module_basename' => 'acp_help_phpbb', + 'modes' => array('help_phpbb'), + ), + )), + ); + } +} -- cgit v1.2.1 From 90a5e22eb51fa20c94d576ffc5cdb49fb31dab3a Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 4 Feb 2016 09:45:32 +0100 Subject: [ticket/14492] Correctly check if extension was enabled during install Also fixed some incorrectly generated log messages and improved the regex. PHPBB3-14492 --- .../install_finish/task/install_extensions.php | 42 +++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index d5086e7b82..c9a35a309a 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -49,6 +49,12 @@ class install_extensions extends \phpbb\install\task_base /** @var \Symfony\Component\Finder\Finder */ protected $finder; + /** @var string Extension table */ + protected $extension_table; + + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + /** * Constructor * @@ -61,11 +67,13 @@ class install_extensions extends \phpbb\install\task_base { $this->install_config = $install_config; $this->iohandler = $iohandler; + $this->extension_table = $container->get_parameter('tables.ext'); $this->log = $container->get('log'); $this->user = $container->get('user'); $this->extension_manager = $container->get('ext.manager'); $this->config = $container->get('config'); + $this->db = $container->get('dbal.conn'); $this->finder = new \Symfony\Component\Finder\Finder(); $this->finder->in($phpbb_root_path . 'ext/') ->ignoreUnreadableDirs() @@ -101,14 +109,14 @@ class install_extensions extends \phpbb\install\task_base foreach ($this->finder as $file) { /** @var \SplFileInfo $file */ - $ext_name = preg_replace('#(.+ext[\\/\\\])#', '', dirname($file->getRealPath())); + $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])([^\\/\\\]+)[\\/\\\]([^\\/\\\]+)#', '$2/$3', dirname($file->getRealPath())); if ($this->extension_manager->is_available($ext_name)) { $this->extension_manager->enable($ext_name); - $this->extension_manager->load_extensions(); + $extensions = $this->get_extensions(); - if (!$this->extension_manager->is_enabled($ext_name)) + if (isset($extensions[$ext_name]) && $extensions[$ext_name]['ext_active']) { // Create log $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); @@ -116,7 +124,7 @@ class install_extensions extends \phpbb\install\task_base } else { - $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); + $this->iohandler->add_log_message(array('CLI_EXTENSION_ENABLE_FAILURE', $ext_name)); } } } @@ -136,4 +144,30 @@ class install_extensions extends \phpbb\install\task_base { return 'TASK_INSTALL_EXTENSIONS'; } + + /** + * Get extensions from database + * + * @return array List of extensions + */ + private function get_extensions() + { + $sql = 'SELECT * + FROM ' . $this->extension_table; + + $result = $this->db->sql_query($sql); + $extensions_row = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + $extensions = array(); + + foreach ($extensions_row as $extension) + { + $extensions[$extension['ext_name']] = $extension; + } + + ksort($extensions); + + return $extensions; + } } -- cgit v1.2.1 From 4451db9f225d7a0e8a12503f0ff2f1393ee42467 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 4 Feb 2016 11:43:29 +0100 Subject: [ticket/14492] Apply fixes to update extensions task The regex was also simplified. PHPBB3-14492 --- .../install_finish/task/install_extensions.php | 2 +- .../update_database/task/update_extensions.php | 40 ++++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index c9a35a309a..d92f420202 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -109,7 +109,7 @@ class install_extensions extends \phpbb\install\task_base foreach ($this->finder as $file) { /** @var \SplFileInfo $file */ - $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])([^\\/\\\]+)[\\/\\\]([^\\/\\\]+)#', '$2/$3', dirname($file->getRealPath())); + $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])(\w+)[\\/\\\](\w+)#', '$2/$3', dirname($file->getRealPath())); if ($this->extension_manager->is_available($ext_name)) { diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index c7437d4746..a6648084a6 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -59,6 +59,12 @@ class enable_extensions extends task_base /** @var Finder */ protected $finder; + /** @var string Extension table */ + protected $extension_table; + + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + /** * Constructor * @@ -72,11 +78,13 @@ class enable_extensions extends task_base { $this->install_config = $install_config; $this->iohandler = $iohandler; + $this->extension_table = $container->get_parameter('tables.ext'); $this->log = $container->get('log'); $this->user = $container->get('user'); $this->extension_manager = $container->get('ext.manager'); $this->config = $container->get('config'); + $this->db = $container->get('dbal.conn'); $this->finder = new Finder(); $this->finder->in($phpbb_root_path . 'ext/') ->ignoreUnreadableDirs() @@ -111,7 +119,7 @@ class enable_extensions extends task_base foreach ($this->finder as $file) { /** @var \SplFileInfo $file */ - $ext_name = preg_replace('#(.+ext[\\/\\\])#', '', dirname($file->getRealPath())); + $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])(\w+)[\\/\\\](\w+)#', '$2/$3', dirname($file->getRealPath())); // Skip extensions that were not added or updated during update if (!count(preg_grep('#ext/' . $ext_name . '#', $update_info['files']))) @@ -128,9 +136,9 @@ class enable_extensions extends task_base if ($this->extension_manager->is_available($ext_name)) { $this->extension_manager->enable($ext_name); - $this->extension_manager->load_extensions(); + $extensions = $this->get_extensions(); - if (!$this->extension_manager->is_enabled($ext_name)) + if (isset($extensions[$ext_name]) && $extensions[$ext_name]['ext_active']) { // Create log $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); @@ -159,4 +167,30 @@ class enable_extensions extends task_base { return 'TASK_UPDATE_EXTENSIONS'; } + + /** + * Get extensions from database + * + * @return array List of extensions + */ + private function get_extensions() + { + $sql = 'SELECT * + FROM ' . $this->extension_table; + + $result = $this->db->sql_query($sql); + $extensions_row = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + $extensions = array(); + + foreach ($extensions_row as $extension) + { + $extensions[$extension['ext_name']] = $extension; + } + + ksort($extensions); + + return $extensions; + } } -- cgit v1.2.1 From 89fef2ce13a183c7b963032274f455a09a05f325 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 21 Feb 2016 22:14:58 +0100 Subject: [ticket/14492] Send statistics via ajax request Flooding ajax requests will try to be prevented and sending stats without JS will also properly work. PHPBB3-14492 --- phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php b/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php index 4274f53520..2634cee643 100644 --- a/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php +++ b/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php @@ -31,6 +31,7 @@ class add_help_phpbb extends \phpbb\db\migration\migration { return array( array('config.add', array('help_send_statistics', true)), + array('config.add', array('help_send_statistics_time', 0)), array('module.remove', array( 'acp', false, -- cgit v1.2.1 From eb1ade67681ee7c88845978eade07ad3ac96357a Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 24 Feb 2016 13:49:20 +0100 Subject: [ticket/14492] Set install extensions to synthetic and fix step count PHPBB3-14492 --- .../install/module/install_finish/task/install_extensions.php | 7 +------ .../install/module/update_database/task/update_extensions.php | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index d92f420202..bc13795188 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -97,11 +97,6 @@ class install_extensions extends \phpbb\install\task_base */ public function run() { - if (defined('PHPBB_ENVIRONMENT') && PHPBB_ENVIRONMENT === 'test') - { - return; - } - $this->user->session_begin(); $this->user->setup(array('common', 'acp/common', 'cli')); @@ -134,7 +129,7 @@ class install_extensions extends \phpbb\install\task_base */ static public function get_step_count() { - return 0; + return 1; } /** diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index a6648084a6..a73fa9b854 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -157,7 +157,7 @@ class enable_extensions extends task_base */ static public function get_step_count() { - return 0; + return 1; } /** -- cgit v1.2.1 From 65d6e338a99baa2f100d6bd4dea5cd76ac146ac3 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 24 Feb 2016 15:05:01 +0100 Subject: [ticket/14492] Allow specifying extensions to update & install PHPBB3-14492 --- .../phpbb/install/console/command/install/install.php | 18 ++++++++++++++++++ .../module/install_finish/task/install_extensions.php | 9 +++++++++ .../module/update_database/task/update_extensions.php | 7 ++++++- 3 files changed, 33 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/console/command/install/install.php b/phpBB/phpbb/install/console/command/install/install.php index de3a2e2d61..3378f5fdac 100644 --- a/phpBB/phpbb/install/console/command/install/install.php +++ b/phpBB/phpbb/install/console/command/install/install.php @@ -80,6 +80,10 @@ class install extends \phpbb\console\command\command 'config-file', InputArgument::REQUIRED, $this->language->lang('CLI_CONFIG_FILE')) + ->addArgument( + 'install-extensions', + InputArgument::OPTIONAL, + $this->language->lang('CLI_INSTALL_EXTENSIONS')) ->setDescription($this->language->lang('CLI_INSTALL_BOARD')) ; } @@ -147,6 +151,7 @@ class install extends \phpbb\console\command\command } $this->register_configuration($iohandler, $config); + $this->register_install_extensions($iohandler, $input); try { @@ -204,4 +209,17 @@ class install extends \phpbb\console\command\command $iohandler->set_input('script_path', $config['server']['script_path']); $iohandler->set_input('submit_server', 'submit'); } + + /** + * Register extensions to install during installation + * + * @param cli_iohandler $iohandler + * @param InputInterface $input + */ + private function register_install_extensions(cli_iohandler $iohandler, InputInterface $input) + { + $install_extensions = $input->getArgument('install-extensions'); + $install_extensions = !empty($install_extensions) ? explode(',', $install_extensions) : array(); + $iohandler->set_input('install-extensions', $install_extensions); + } } diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index bc13795188..c42d17fc18 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -13,6 +13,8 @@ namespace phpbb\install\module\install_finish\task; +use Symfony\Component\Console\Input\ArgvInput; + /** * Installs extensions that exist in ext folder upon install */ @@ -100,12 +102,19 @@ class install_extensions extends \phpbb\install\task_base $this->user->session_begin(); $this->user->setup(array('common', 'acp/common', 'cli')); + $install_extensions = $this->iohandler->get_input('install-extensions', array()); + // Find available extensions foreach ($this->finder as $file) { /** @var \SplFileInfo $file */ $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])(\w+)[\\/\\\](\w+)#', '$2/$3', dirname($file->getRealPath())); + if (!empty($install_extensions) && !in_array($ext_name, $install_extensions)) + { + continue; + } + if ($this->extension_manager->is_available($ext_name)) { $this->extension_manager->enable($ext_name); diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index a73fa9b854..7a65ff1803 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -18,6 +18,7 @@ use phpbb\install\helper\config; use phpbb\install\helper\iohandler\iohandler_interface; use phpbb\install\helper\update_helper; use phpbb\install\task_base; +use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Finder\Finder; /** @@ -111,6 +112,9 @@ class enable_extensions extends task_base $this->user->session_begin(); $this->user->setup(array('common', 'acp/common', 'cli')); + $input = new ArgvInput(); + $update_extensions = explode(',', $input->getArgument('update-extensions')); + $update_info = $this->install_config->get('update_info_unprocessed', array()); if (!empty($update_info)) @@ -122,7 +126,8 @@ class enable_extensions extends task_base $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])(\w+)[\\/\\\](\w+)#', '$2/$3', dirname($file->getRealPath())); // Skip extensions that were not added or updated during update - if (!count(preg_grep('#ext/' . $ext_name . '#', $update_info['files']))) + if (!count(preg_grep('#ext/' . $ext_name . '#', $update_info['files'])) && + !in_array($ext_name, $update_extensions) && $ext_name !== 'phpbb/viglink') { continue; } -- cgit v1.2.1 From e519b21b2e563f9d751aa8f9157ccc489b660ec8 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 29 Feb 2016 11:31:33 +0100 Subject: [ticket/14492] Only show fail of extension install if it's available PHPBB3-14492 --- .../install/module/install_finish/task/install_extensions.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index c42d17fc18..cef2abe0cb 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -125,10 +125,10 @@ class install_extensions extends \phpbb\install\task_base // Create log $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); } - } - else - { - $this->iohandler->add_log_message(array('CLI_EXTENSION_ENABLE_FAILURE', $ext_name)); + else + { + $this->iohandler->add_log_message(array('CLI_EXTENSION_ENABLE_FAILURE', $ext_name)); + } } } } -- cgit v1.2.1 From 69dece6197d6289199a713e7db57cc80574aae69 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 29 Feb 2016 15:04:55 +0100 Subject: [ticket/14492] Removed unused use statement PHPBB3-14492 --- phpBB/phpbb/install/module/install_finish/task/install_extensions.php | 2 -- 1 file changed, 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index cef2abe0cb..9db922b7f4 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -13,8 +13,6 @@ namespace phpbb\install\module\install_finish\task; -use Symfony\Component\Console\Input\ArgvInput; - /** * Installs extensions that exist in ext folder upon install */ -- cgit v1.2.1 From ffe900c72d358ba0337c607f2ed76f893715f686 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 2 Mar 2016 11:53:20 +0100 Subject: [ticket/14492] Define extensions to install in config not via cli argument PHPBB3-14492 --- .../phpbb/install/console/command/install/install.php | 19 ++----------------- phpBB/phpbb/install/console/command/update/update.php | 3 +++ phpBB/phpbb/install/installer_configuration.php | 4 ++++ phpBB/phpbb/install/updater_configuration.php | 4 ++++ 4 files changed, 13 insertions(+), 17 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/console/command/install/install.php b/phpBB/phpbb/install/console/command/install/install.php index 3378f5fdac..52a348fe44 100644 --- a/phpBB/phpbb/install/console/command/install/install.php +++ b/phpBB/phpbb/install/console/command/install/install.php @@ -80,10 +80,6 @@ class install extends \phpbb\console\command\command 'config-file', InputArgument::REQUIRED, $this->language->lang('CLI_CONFIG_FILE')) - ->addArgument( - 'install-extensions', - InputArgument::OPTIONAL, - $this->language->lang('CLI_INSTALL_EXTENSIONS')) ->setDescription($this->language->lang('CLI_INSTALL_BOARD')) ; } @@ -151,11 +147,11 @@ class install extends \phpbb\console\command\command } $this->register_configuration($iohandler, $config); - $this->register_install_extensions($iohandler, $input); try { $this->installer->run(); + return 0; } catch (installer_exception $e) { @@ -208,18 +204,7 @@ class install extends \phpbb\console\command\command $iohandler->set_input('server_port', $config['server']['server_port']); $iohandler->set_input('script_path', $config['server']['script_path']); $iohandler->set_input('submit_server', 'submit'); - } - /** - * Register extensions to install during installation - * - * @param cli_iohandler $iohandler - * @param InputInterface $input - */ - private function register_install_extensions(cli_iohandler $iohandler, InputInterface $input) - { - $install_extensions = $input->getArgument('install-extensions'); - $install_extensions = !empty($install_extensions) ? explode(',', $install_extensions) : array(); - $iohandler->set_input('install-extensions', $install_extensions); + $iohandler->set_input('install-extensions', $config['extensions']); } } diff --git a/phpBB/phpbb/install/console/command/update/update.php b/phpBB/phpbb/install/console/command/update/update.php index 116f42f758..e827761d1c 100644 --- a/phpBB/phpbb/install/console/command/update/update.php +++ b/phpBB/phpbb/install/console/command/update/update.php @@ -151,6 +151,7 @@ class update extends \phpbb\console\command\command try { $this->installer->run(); + return 0; } catch (installer_exception $e) { @@ -175,5 +176,7 @@ class update extends \phpbb\console\command\command $iohandler->set_input('submit_update_file', 'submit'); $iohandler->set_input('submit_continue_file_update', 'submit'); + + $iohandler->set_input('update-extensions', $config['extensions']); } } diff --git a/phpBB/phpbb/install/installer_configuration.php b/phpBB/phpbb/install/installer_configuration.php index c660c99d0f..805140338c 100644 --- a/phpBB/phpbb/install/installer_configuration.php +++ b/phpBB/phpbb/install/installer_configuration.php @@ -136,6 +136,10 @@ class installer_configuration implements ConfigurationInterface ->end() ->end() ->end() + ->arrayNode('extensions') + ->prototype('scalar')->end() + ->defaultValue([]) + ->end() ->end() ; return $treeBuilder; diff --git a/phpBB/phpbb/install/updater_configuration.php b/phpBB/phpbb/install/updater_configuration.php index e992356290..5c1c29f1da 100644 --- a/phpBB/phpbb/install/updater_configuration.php +++ b/phpBB/phpbb/install/updater_configuration.php @@ -32,6 +32,10 @@ class updater_configuration implements ConfigurationInterface ->addDefaultsIfNotSet() ->children() ->enumNode('type')->values(['all','db_only'])->defaultValue('all')->end() + ->arrayNode('extensions') + ->prototype('scalar')->end() + ->defaultValue([]) + ->end() ->end() ; -- cgit v1.2.1 From 930b02342e4f27f1c72fe0590f7153298331c3a6 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 2 Mar 2016 13:02:44 +0100 Subject: [ticket/14492] Check if composer.json exists in viglink folder on file_check PHPBB3-14492 --- phpBB/phpbb/install/module/update_filesystem/task/file_check.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php index e4e0be0531..8777b747de 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -142,7 +142,7 @@ class file_check extends task_base // with it but it does not exist (e.g. deleted by admin) if (strpos($file, $this->phpbb_root_path . 'ext/phpbb/viglink') !== false && $this->update_helper->phpbb_version_compare($update_info['version']['from'], '3.2.0', '>=') && - !$this->filesystem->exists($this->phpbb_root_path . 'ext/phpbb/viglink')) + !$this->filesystem->exists($this->phpbb_root_path . 'ext/phpbb/viglink/composer.json')) { continue; } -- cgit v1.2.1 From f604e1ab5d5d780ff4bed1e39fa83cc264a8af71 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 2 Mar 2016 13:54:02 +0100 Subject: [ticket/14492] Rework logic for selecting which extensions to update PHPBB3-14492 --- .../update_database/task/update_extensions.php | 81 ++++++++++++++-------- 1 file changed, 54 insertions(+), 27 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index 7a65ff1803..f3a977a013 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -24,7 +24,7 @@ use Symfony\Component\Finder\Finder; /** * Installs extensions that exist in ext folder upon install */ -class enable_extensions extends task_base +class update_extensions extends task_base { /** * @var config @@ -66,6 +66,14 @@ class enable_extensions extends task_base /** @var \phpbb\db\driver\driver_interface */ protected $db; + /** + * @var array List of default extensions to update, grouped by version + * they were added + */ + private $default_update = [ + '3.2.0-b2' => ['phpbb/viglink'] + ]; + /** * Constructor * @@ -112,47 +120,66 @@ class enable_extensions extends task_base $this->user->session_begin(); $this->user->setup(array('common', 'acp/common', 'cli')); - $input = new ArgvInput(); - $update_extensions = explode(',', $input->getArgument('update-extensions')); + $update_info = $this->install_config->get('update_info_unprocessed', []); - $update_info = $this->install_config->get('update_info_unprocessed', array()); + if (empty($update_info)) + { + return; + } - if (!empty($update_info)) + $update_extensions = $this->iohandler->get_input('update-extensions', []); + + // Create list of default extensions that need to be enabled in update + $default_update_extensions = []; + foreach ($this->default_update as $version => $extensions) { - // Find available extensions - foreach ($this->finder as $file) + if ($this->update_helper->phpbb_version_compare($update_info['version']['from'], $version, '<')) { - /** @var \SplFileInfo $file */ - $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])(\w+)[\\/\\\](\w+)#', '$2/$3', dirname($file->getRealPath())); - - // Skip extensions that were not added or updated during update - if (!count(preg_grep('#ext/' . $ext_name . '#', $update_info['files'])) && - !in_array($ext_name, $update_extensions) && $ext_name !== 'phpbb/viglink') - { - continue; - } + $default_update_extensions = array_merge($default_update_extensions, $extensions); + } + } - // Disable enabled extensions in order to run migrations if needed - if ($this->extension_manager->is_enabled($ext_name)) + // Find available extensions + foreach ($this->finder as $file) + { + /** @var \SplFileInfo $file */ + $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])(\w+)[\\/\\\](\w+)#', '$2/$3', dirname($file->getRealPath())); + + // Update extensions if: + // 1) Extension is currently enabled + // 2) Extension was implicitly defined as needing an update + // 3) Extension was newly added as default phpBB extension in + // this update and should be enabled by default. + if ($this->extension_manager->is_available($ext_name) && + ( + $this->extension_manager->is_enabled($ext_name) || + in_array($ext_name, $update_extensions) || + in_array($ext_name, $default_update_extensions) + )) + { + $extension_enabled = $this->extension_manager->is_enabled($ext_name); + if ($extension_enabled) { $this->extension_manager->disable($ext_name); } + $this->extension_manager->enable($ext_name); + $extensions = $this->get_extensions(); - if ($this->extension_manager->is_available($ext_name)) + if (isset($extensions[$ext_name]) && $extensions[$ext_name]['ext_active']) { - $this->extension_manager->enable($ext_name); - $extensions = $this->get_extensions(); - - if (isset($extensions[$ext_name]) && $extensions[$ext_name]['ext_active']) - { - // Create log - $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); - } + // Create log + $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); } else { $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); } + + // Disable extensions if it was disabled by the admin before + if (!$extension_enabled && !in_array($ext_name, $default_update_extensions)) + { + $this->extension_manager->disable($ext_name); + } } } } -- cgit v1.2.1 From 64f0d74489515ad76d0caf6cfdf100ef92e16328 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 2 Mar 2016 16:35:18 +0100 Subject: [ticket/14492] Properly retrieve version updating from PHPBB3-14492 --- .../install/module/update_database/task/update.php | 2 - .../update_database/task/update_extensions.php | 112 ++++++++++++--------- 2 files changed, 62 insertions(+), 52 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index 9d7ba2f919..fb9eb44e6a 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -211,8 +211,6 @@ class update extends task_base $this->iohandler->add_success_message('INLINE_UPDATE_SUCCESSFUL'); - $this->config->delete('version_update_from'); - $this->cache->purge(); $this->config->increment('assets_version', 1); diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index f3a977a013..cb5cd90952 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -26,6 +26,11 @@ use Symfony\Component\Finder\Finder; */ class update_extensions extends task_base { + /** + * @var \phpbb\cache\driver\driver_interface + */ + protected $cache; + /** * @var config */ @@ -92,8 +97,10 @@ class update_extensions extends task_base $this->log = $container->get('log'); $this->user = $container->get('user'); $this->extension_manager = $container->get('ext.manager'); + $this->cache = $container->get('cache.driver'); $this->config = $container->get('config'); $this->db = $container->get('dbal.conn'); + $this->update_helper = $update_helper; $this->finder = new Finder(); $this->finder->in($phpbb_root_path . 'ext/') ->ignoreUnreadableDirs() @@ -121,67 +128,72 @@ class update_extensions extends task_base $this->user->setup(array('common', 'acp/common', 'cli')); $update_info = $this->install_config->get('update_info_unprocessed', []); + $version_from = !empty($update_info) ? $update_info['version']['from'] : $this->config['version_update_from']; - if (empty($update_info)) + if (!empty($version_from)) { - return; - } - - $update_extensions = $this->iohandler->get_input('update-extensions', []); + $update_extensions = $this->iohandler->get_input('update-extensions', []); - // Create list of default extensions that need to be enabled in update - $default_update_extensions = []; - foreach ($this->default_update as $version => $extensions) - { - if ($this->update_helper->phpbb_version_compare($update_info['version']['from'], $version, '<')) - { - $default_update_extensions = array_merge($default_update_extensions, $extensions); - } - } - - // Find available extensions - foreach ($this->finder as $file) - { - /** @var \SplFileInfo $file */ - $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])(\w+)[\\/\\\](\w+)#', '$2/$3', dirname($file->getRealPath())); - - // Update extensions if: - // 1) Extension is currently enabled - // 2) Extension was implicitly defined as needing an update - // 3) Extension was newly added as default phpBB extension in - // this update and should be enabled by default. - if ($this->extension_manager->is_available($ext_name) && - ( - $this->extension_manager->is_enabled($ext_name) || - in_array($ext_name, $update_extensions) || - in_array($ext_name, $default_update_extensions) - )) + // Create list of default extensions that need to be enabled in update + $default_update_extensions = []; + foreach ($this->default_update as $version => $extensions) { - $extension_enabled = $this->extension_manager->is_enabled($ext_name); - if ($extension_enabled) + if ($this->update_helper->phpbb_version_compare($version_from, $version, '<')) { - $this->extension_manager->disable($ext_name); - } - $this->extension_manager->enable($ext_name); - $extensions = $this->get_extensions(); - - if (isset($extensions[$ext_name]) && $extensions[$ext_name]['ext_active']) - { - // Create log - $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); - } - else - { - $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); + $default_update_extensions = array_merge($default_update_extensions, $extensions); } + } - // Disable extensions if it was disabled by the admin before - if (!$extension_enabled && !in_array($ext_name, $default_update_extensions)) + // Find available extensions + foreach ($this->finder as $file) + { + /** @var \SplFileInfo $file */ + $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])(\w+)[\\/\\\](\w+)#', '$2/$3', dirname($file->getRealPath())); + + // Update extensions if: + // 1) Extension is currently enabled + // 2) Extension was implicitly defined as needing an update + // 3) Extension was newly added as default phpBB extension in + // this update and should be enabled by default. + if ($this->extension_manager->is_available($ext_name) && + ( + $this->extension_manager->is_enabled($ext_name) || + in_array($ext_name, $update_extensions) || + in_array($ext_name, $default_update_extensions) + ) + ) { - $this->extension_manager->disable($ext_name); + $extension_enabled = $this->extension_manager->is_enabled($ext_name); + if ($extension_enabled) + { + $this->extension_manager->disable($ext_name); + } + $this->extension_manager->enable($ext_name); + $extensions = $this->get_extensions(); + + if (isset($extensions[$ext_name]) && $extensions[$ext_name]['ext_active']) + { + // Create log + $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); + } else + { + $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); + } + + // Disable extensions if it was disabled by the admin before + if (!$extension_enabled && !in_array($ext_name, $default_update_extensions)) + { + $this->extension_manager->disable($ext_name); + } } } } + + $this->config->delete('version_update_from'); + + $this->cache->purge(); + + $this->config->increment('assets_version', 1); } /** -- cgit v1.2.1 From d62d35ad46baf9a7563a9f58038b16272cdf7c2d Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 2 Mar 2016 21:56:22 +0100 Subject: [ticket/14492] Redirect to help phpBB page after installation PHPBB3-14492 --- phpBB/phpbb/install/installer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index 240423ae78..b8eef34a1d 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -244,7 +244,7 @@ class installer else { global $SID; - $acp_url = $this->web_root . 'adm/index.php' . $SID; + $acp_url = $this->web_root . 'adm/index.php' . $SID . '&i=acp_help_phpbb&mode=help_phpbb'; $this->iohandler->add_success_message('INSTALLER_FINISHED', array( 'ACP_LINK', $acp_url, -- cgit v1.2.1 From fd37919ecb8e6e6618145aafae9de864fe16ded8 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 2 Mar 2016 22:00:08 +0100 Subject: [ticket/14492] Remove unused use statement PHPBB3-14492 --- phpBB/phpbb/install/module/update_database/task/update_extensions.php | 1 - 1 file changed, 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index cb5cd90952..0a339f11e8 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -18,7 +18,6 @@ use phpbb\install\helper\config; use phpbb\install\helper\iohandler\iohandler_interface; use phpbb\install\helper\update_helper; use phpbb\install\task_base; -use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Finder\Finder; /** -- cgit v1.2.1 From e308093d7507258855c14dcfb7214e81beac187e Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 3 Mar 2016 22:26:29 +0100 Subject: [ticket/14492] Use extension manager instead of finder and add try/catch PHPBB3-14492 --- .../install_finish/task/install_extensions.php | 17 +++--- .../update_database/task/update_extensions.php | 61 ++++++++++++---------- 2 files changed, 44 insertions(+), 34 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index 9db922b7f4..eb44bb780b 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -102,18 +102,17 @@ class install_extensions extends \phpbb\install\task_base $install_extensions = $this->iohandler->get_input('install-extensions', array()); - // Find available extensions - foreach ($this->finder as $file) - { - /** @var \SplFileInfo $file */ - $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])(\w+)[\\/\\\](\w+)#', '$2/$3', dirname($file->getRealPath())); + $available_extensions = $this->extension_manager->all_available(); + // Install extensions + foreach ($available_extensions as $ext_name => $ext_path) + { if (!empty($install_extensions) && !in_array($ext_name, $install_extensions)) { continue; } - if ($this->extension_manager->is_available($ext_name)) + try { $this->extension_manager->enable($ext_name); $extensions = $this->get_extensions(); @@ -122,12 +121,18 @@ class install_extensions extends \phpbb\install\task_base { // Create log $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); + $this->iohandler->add_success_message(array('CLI_EXTENSION_ENABLE_SUCCESS', $ext_name)); } else { $this->iohandler->add_log_message(array('CLI_EXTENSION_ENABLE_FAILURE', $ext_name)); } } + catch (\Exception $e) + { + // Add fail log and continue + $this->iohandler->add_log_message(array('CLI_EXTENSION_ENABLE_FAILURE', $ext_name)); + } } } diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index 0a339f11e8..e8b73db25a 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -143,47 +143,52 @@ class update_extensions extends task_base } } - // Find available extensions - foreach ($this->finder as $file) - { - /** @var \SplFileInfo $file */ - $ext_name = preg_replace('#(.+[\\/\\\]ext[\\/\\\])(\w+)[\\/\\\](\w+)#', '$2/$3', dirname($file->getRealPath())); + $available_extensions = $this->extension_manager->all_available(); + // Update available extensions + foreach ($available_extensions as $ext_name => $ext_path) + { // Update extensions if: // 1) Extension is currently enabled // 2) Extension was implicitly defined as needing an update // 3) Extension was newly added as default phpBB extension in // this update and should be enabled by default. - if ($this->extension_manager->is_available($ext_name) && - ( - $this->extension_manager->is_enabled($ext_name) || - in_array($ext_name, $update_extensions) || - in_array($ext_name, $default_update_extensions) - ) + if ($this->extension_manager->is_enabled($ext_name) || + in_array($ext_name, $update_extensions) || + in_array($ext_name, $default_update_extensions) ) { - $extension_enabled = $this->extension_manager->is_enabled($ext_name); - if ($extension_enabled) + try { - $this->extension_manager->disable($ext_name); + $extension_enabled = $this->extension_manager->is_enabled($ext_name); + if ($extension_enabled) + { + $this->extension_manager->disable($ext_name); + } + $this->extension_manager->enable($ext_name); + $extensions = $this->get_extensions(); + + if (isset($extensions[$ext_name]) && $extensions[$ext_name]['ext_active']) + { + // Create log + $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); + $this->iohandler->add_success_message(array('CLI_EXTENSION_ENABLE_SUCCESS', $ext_name)); + } else + { + $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); + } + + // Disable extensions if it was disabled by the admin before + if (!$extension_enabled && !in_array($ext_name, $default_update_extensions)) + { + $this->extension_manager->disable($ext_name); + } } - $this->extension_manager->enable($ext_name); - $extensions = $this->get_extensions(); - - if (isset($extensions[$ext_name]) && $extensions[$ext_name]['ext_active']) - { - // Create log - $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); - } else + catch (\Exception $e) { + // Add fail log and continue $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); } - - // Disable extensions if it was disabled by the admin before - if (!$extension_enabled && !in_array($ext_name, $default_update_extensions)) - { - $this->extension_manager->disable($ext_name); - } } } } -- cgit v1.2.1 From 2fa23c9b3f55e024f6a35c268cd7878e68ad08c2 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 3 Mar 2016 22:28:51 +0100 Subject: [ticket/14492] Unify version check for installing default extensions PHPBB3-14492 --- phpBB/phpbb/install/module/update_database/task/update_extensions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index e8b73db25a..6d0016ddb3 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -75,7 +75,7 @@ class update_extensions extends task_base * they were added */ private $default_update = [ - '3.2.0-b2' => ['phpbb/viglink'] + '3.2.0-b3' => ['phpbb/viglink'] ]; /** @@ -137,7 +137,7 @@ class update_extensions extends task_base $default_update_extensions = []; foreach ($this->default_update as $version => $extensions) { - if ($this->update_helper->phpbb_version_compare($version_from, $version, '<')) + if ($this->update_helper->phpbb_version_compare($version_from, $version, '<=')) { $default_update_extensions = array_merge($default_update_extensions, $extensions); } -- cgit v1.2.1 From edfc4f3efc742342a37a5d510909aece6ae4c95d Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 4 Mar 2016 00:24:04 +0100 Subject: [ticket/14492] Use same list for checking if extension should be updated PHPBB3-14492 --- .../update_database/task/update_extensions.php | 4 +-- .../module/update_filesystem/task/file_check.php | 35 ++++++++++++++++++---- 2 files changed, 31 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index 6d0016ddb3..64215e2f30 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -74,7 +74,7 @@ class update_extensions extends task_base * @var array List of default extensions to update, grouped by version * they were added */ - private $default_update = [ + static public $default_extensions_update = [ '3.2.0-b3' => ['phpbb/viglink'] ]; @@ -135,7 +135,7 @@ class update_extensions extends task_base // Create list of default extensions that need to be enabled in update $default_update_extensions = []; - foreach ($this->default_update as $version => $extensions) + foreach (self::$default_extensions_update as $version => $extensions) { if ($this->update_helper->phpbb_version_compare($version_from, $version, '<=')) { diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php index 8777b747de..5b48350e73 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -118,6 +118,17 @@ class file_check extends task_base $this->iohandler->set_task_count($task_count); $this->iohandler->set_progress('UPDATE_CHECK_FILES', 0); + // Create list of default extensions that should have been added prior + // to this update + $default_update_extensions = []; + foreach (\phpbb\install\module\update_database\task\update_extensions::$default_extensions_update as $version => $extensions) + { + if ($this->update_helper->phpbb_version_compare($update_info['version']['from'], $version, '>')) + { + $default_update_extensions = array_merge($default_update_extensions, $extensions); + } + } + foreach ($update_info['files'] as $key => $filename) { $old_file = $old_path . $filename; @@ -138,13 +149,25 @@ class file_check extends task_base $progress_count++; $this->iohandler->set_progress('UPDATE_CHECK_FILES', $progress_count); - // Do not copy viglink again if the previous version was packaged - // with it but it does not exist (e.g. deleted by admin) - if (strpos($file, $this->phpbb_root_path . 'ext/phpbb/viglink') !== false && - $this->update_helper->phpbb_version_compare($update_info['version']['from'], '3.2.0', '>=') && - !$this->filesystem->exists($this->phpbb_root_path . 'ext/phpbb/viglink/composer.json')) + // Do not copy default extension again if the previous version was + // packaged with it but it does not exist (e.g. deleted by admin) + if (strpos($file, $this->phpbb_root_path . 'ext/') !== false) { - continue; + $skip_file = false; + foreach ($default_update_extensions as $ext_name) + { + if (strpos($file, $this->phpbb_root_path . 'ext/' . $ext_name) !== false && + !$this->filesystem->exists($this->phpbb_root_path . 'ext/' . $ext_name . '/composer.json')) + { + $skip_file = true; + break; + } + } + + if ($skip_file) + { + continue; + } } if (!$this->filesystem->exists($file)) -- cgit v1.2.1 From b1596fda7f88bc0e2817a1143be6ff94ef3aae2a Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 4 Mar 2016 17:27:27 +0100 Subject: [ticket/14492] Prevent timeouts in install & update extensions tasks PHPBB3-14492 --- .../install_finish/task/install_extensions.php | 21 ++++++++++++++++++++- .../update_database/task/update_extensions.php | 20 +++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index eb44bb780b..b8a04685f6 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -13,6 +13,8 @@ namespace phpbb\install\module\install_finish\task; +use phpbb\install\exception\resource_limit_reached_exception; + /** * Installs extensions that exist in ext folder upon install */ @@ -102,7 +104,9 @@ class install_extensions extends \phpbb\install\task_base $install_extensions = $this->iohandler->get_input('install-extensions', array()); - $available_extensions = $this->extension_manager->all_available(); + $all_available_extensions = $this->extension_manager->all_available(); + $i = $this->install_config->get('install_extensions_index', 0); + $available_extensions = array_slice($all_available_extensions, $i); // Install extensions foreach ($available_extensions as $ext_name => $ext_path) @@ -133,6 +137,21 @@ class install_extensions extends \phpbb\install\task_base // Add fail log and continue $this->iohandler->add_log_message(array('CLI_EXTENSION_ENABLE_FAILURE', $ext_name)); } + + $i++; + + // Stop execution if resource limit is reached + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) + { + break; + } + } + + $this->install_config->set('install_extensions_index', $i); + + if ($i < sizeof($all_available_extensions)) + { + throw new resource_limit_reached_exception(); } } diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index 64215e2f30..24b72f7b42 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -13,6 +13,7 @@ namespace phpbb\install\module\update_database\task; +use phpbb\install\exception\resource_limit_reached_exception; use phpbb\install\helper\container_factory; use phpbb\install\helper\config; use phpbb\install\helper\iohandler\iohandler_interface; @@ -143,7 +144,9 @@ class update_extensions extends task_base } } - $available_extensions = $this->extension_manager->all_available(); + $all_available_extensions = $this->extension_manager->all_available(); + $i = $this->install_config->get('update_extensions_index', 0); + $available_extensions = array_slice($all_available_extensions, $i); // Update available extensions foreach ($available_extensions as $ext_name => $ext_path) @@ -190,6 +193,21 @@ class update_extensions extends task_base $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); } } + + $i++; + + // Stop execution if resource limit is reached + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) + { + break; + } + } + + $this->install_config->set('update_extensions_index', $i); + + if ($i < sizeof($all_available_extensions)) + { + throw new resource_limit_reached_exception(); } } -- cgit v1.2.1 From dee5e6e07636db7e35a82919a723907e734fbcd1 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 4 Mar 2016 17:32:25 +0100 Subject: [ticket/14492] Add language variables for updating extensions PHPBB3-14492 --- .../install/module/update_database/task/update_extensions.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index 24b72f7b42..76904f80f1 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -174,11 +174,11 @@ class update_extensions extends task_base if (isset($extensions[$ext_name]) && $extensions[$ext_name]['ext_active']) { // Create log - $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name)); - $this->iohandler->add_success_message(array('CLI_EXTENSION_ENABLE_SUCCESS', $ext_name)); + $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_UPDATE', time(), array($ext_name)); + $this->iohandler->add_success_message(array('CLI_EXTENSION_UPDATE_SUCCESS', $ext_name)); } else { - $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); + $this->iohandler->add_log_message('CLI_EXTENSION_UPDATE_FAILURE', array($ext_name)); } // Disable extensions if it was disabled by the admin before @@ -190,7 +190,7 @@ class update_extensions extends task_base catch (\Exception $e) { // Add fail log and continue - $this->iohandler->add_log_message('CLI_EXTENSION_ENABLE_FAILURE', array($ext_name)); + $this->iohandler->add_log_message('CLI_EXTENSION_UPDATE_FAILURE', array($ext_name)); } } -- cgit v1.2.1 From 1f270972084cd228e135481b766ada9941582155 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 6 Mar 2016 14:59:34 +0100 Subject: [ticket/14492] Install all extensions if 'all' is specified for extensions PHPBB3-14492 --- phpBB/phpbb/install/module/install_finish/task/install_extensions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index b8a04685f6..553a30ea28 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -111,7 +111,7 @@ class install_extensions extends \phpbb\install\task_base // Install extensions foreach ($available_extensions as $ext_name => $ext_path) { - if (!empty($install_extensions) && !in_array($ext_name, $install_extensions)) + if (!empty($install_extensions) && $install_extensions !== ['all'] && !in_array($ext_name, $install_extensions)) { continue; } -- cgit v1.2.1 From b9c284d85be82e2a8f50c20e147d1ca2352453d4 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 22 Aug 2016 20:59:57 +0200 Subject: [ticket/14492] Update phpBB version and fix miscellaneous code issues PHPBB3-14492 --- phpBB/phpbb/install/module/update_database/task/update_extensions.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index 76904f80f1..01b88344e8 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -176,7 +176,8 @@ class update_extensions extends task_base // Create log $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_UPDATE', time(), array($ext_name)); $this->iohandler->add_success_message(array('CLI_EXTENSION_UPDATE_SUCCESS', $ext_name)); - } else + } + else { $this->iohandler->add_log_message('CLI_EXTENSION_UPDATE_FAILURE', array($ext_name)); } -- cgit v1.2.1 From c54838b25f50dca71a2f516175621a7ccd39a071 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 9 Sep 2016 22:59:58 +0200 Subject: [ticket/14492] Update versions in files PHPBB3-14492 --- phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php | 2 +- phpBB/phpbb/install/module/update_database/task/update_extensions.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php b/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php index 2634cee643..afa67fbc58 100644 --- a/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php +++ b/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php @@ -18,7 +18,7 @@ class add_help_phpbb extends \phpbb\db\migration\migration static public function depends_on() { return array( - '\phpbb\db\migration\data\v320\v320a2', + '\phpbb\db\migration\data\v320\v320rc1', ); } diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index 01b88344e8..13c1591dcd 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -76,7 +76,7 @@ class update_extensions extends task_base * they were added */ static public $default_extensions_update = [ - '3.2.0-b3' => ['phpbb/viglink'] + '3.2.0-RC2' => ['phpbb/viglink'] ]; /** -- cgit v1.2.1 From 8ded30bbbe1e12ed301c2deb43d52da5a22d5b05 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 22 Nov 2016 18:39:01 +0100 Subject: [ticket/14492] Fix redirection to help phpBB page PHPBB3-14492 --- phpBB/phpbb/install/installer.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index b8eef34a1d..abdb172cf3 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -59,6 +59,11 @@ class installer */ protected $web_root; + /** + * @var \phpbb\user + */ + protected $user; + /** * Stores the number of steps that a given module has * @@ -87,6 +92,7 @@ class installer $this->installer_modules = null; $this->web_root = $path_helper->get_web_root_path(); $this->purge_cache_before = false; + $this->user = $container->get('user'); } /** @@ -243,8 +249,14 @@ class installer } else { - global $SID; - $acp_url = $this->web_root . 'adm/index.php' . $SID . '&i=acp_help_phpbb&mode=help_phpbb'; + // Start session and try to apply session id + $auth = $this->container_factory->get('auth'); + $this->user->session_begin(); + $auth->acl($this->user->data); + $this->user->setup(); + $phpbb_root_path = $this->container_factory->get_parameter('core.root_path'); + + $acp_url = append_sid($phpbb_root_path . 'adm/index.php', 'i=acp_help_phpbb&mode=help_phpbb', true, $this->user->session_id); $this->iohandler->add_success_message('INSTALLER_FINISHED', array( 'ACP_LINK', $acp_url, -- cgit v1.2.1 From 5895f56de05b637765a6583b8c51c1db3daabe91 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 24 Nov 2016 20:38:29 +0100 Subject: [ticket/14492] Add user service to installer & only instantiate if needed PHPBB3-14492 --- phpBB/phpbb/install/installer.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index abdb172cf3..a7d3b99dcb 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -59,11 +59,6 @@ class installer */ protected $web_root; - /** - * @var \phpbb\user - */ - protected $user; - /** * Stores the number of steps that a given module has * @@ -92,7 +87,6 @@ class installer $this->installer_modules = null; $this->web_root = $path_helper->get_web_root_path(); $this->purge_cache_before = false; - $this->user = $container->get('user'); } /** @@ -251,12 +245,13 @@ class installer { // Start session and try to apply session id $auth = $this->container_factory->get('auth'); - $this->user->session_begin(); - $auth->acl($this->user->data); - $this->user->setup(); + $user = $this->container_factory->get('user'); + $user->session_begin(); + $auth->acl($user->data); + $user->setup(); $phpbb_root_path = $this->container_factory->get_parameter('core.root_path'); - $acp_url = append_sid($phpbb_root_path . 'adm/index.php', 'i=acp_help_phpbb&mode=help_phpbb', true, $this->user->session_id); + $acp_url = append_sid($phpbb_root_path . 'adm/index.php', 'i=acp_help_phpbb&mode=help_phpbb', true, $user->session_id); $this->iohandler->add_success_message('INSTALLER_FINISHED', array( 'ACP_LINK', $acp_url, -- cgit v1.2.1 From 346f31a03156839d1b1931d2fc69cd2ab5656bc0 Mon Sep 17 00:00:00 2001 From: Etienne Baroux Date: Mon, 2 Jun 2014 10:12:18 +0200 Subject: [ticket/12610] Add command to check if the board is up to date. PHPBB3-12610 --- phpBB/phpbb/console/command/update/check.php | 302 +++++++++++++++++++++++++++ phpBB/phpbb/extension/manager.php | 38 +++- phpBB/phpbb/extension/metadata_manager.php | 18 +- phpBB/phpbb/finder.php | 4 +- 4 files changed, 342 insertions(+), 20 deletions(-) create mode 100644 phpBB/phpbb/console/command/update/check.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php new file mode 100644 index 0000000000..0ef3c970ac --- /dev/null +++ b/phpBB/phpbb/console/command/update/check.php @@ -0,0 +1,302 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\console\command\update; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class check extends \phpbb\console\command\command +{ + /** @var \phpbb\config\config */ + protected $config; + + /** @var \Symfony\Component\DependencyInjection\ContainerBuilder */ + protected $phpbb_container; + + /** + * Construct method + */ + public function __construct(\phpbb\user $user, \phpbb\config\config $config, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container) + { + parent::__construct($user); + + $this->config = $config; + $this->phpbb_container = $phpbb_container; + $this->user->add_lang(array('acp/common', 'acp/extensions')); + } + + /** + * Configures the service. + * + * Sets the name and description of the command. + * + * @return null + */ + protected function configure() + { + $this + ->setName('update:check') + ->setDescription($this->user->lang('CLI_DESCRIPTION_UPDATE_CHECK')) + ->addArgument('ext-name', InputArgument::OPTIONAL, $this->user->lang('CLI_DESCRIPTION_UPDATE_CHECK_ARGUMENT_1')) + ->addOption('stability', null, InputOption::VALUE_REQUIRED, 'CLI_DESCRIPTION_CRON_RUN_OPTION_STABILITY') + ->addOption('cache', 'c', InputOption::VALUE_NONE, 'CLI_DESCRIPTION_CRON_RUN_OPTION_CACHE') + ; + } + + /** + * Executes the command. + * + * Checks if an update is available. + * If at least one is available, a message is printed and if verbose mode is set the list of possible updates is printed. + * If their is none, nothing is printed unless verbose mode is set. + * + * @param InputInterface $input Input stream, used to get the options. + * @param OutputInterface $output Output stream, used to print messages. + * @return int 0 if the board is up to date, 1 if it is not and 2 if an error occured. + * @throws \RuntimeException + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $recheck = true; + if ($input->getOption('cache')) + { + $recheck = false; + } + + $stability = null; + if ($input->getOption('stability')) + { + $stability = $input->getOption('stability'); + if (!($stability == 'stable') && !($stability == 'unstable')) + { + throw new \RuntimeException($this->user->lang('CLI_ERROR_INVALID_STABILITY', $stability)); + } + } + + $ext_name = $input->getArgument('ext-name'); + if ($ext_name != null) + { + if ($ext_name == 'all') + { + return $this->check_all_ext($input, $output, $stability, $recheck); + } + else + { + return $this->check_ext($input, $output, $stability, $recheck, $ext_name); + } + } + else + { + return $this->check_core($input, $output, $stability, $recheck); + } + } + + /** + * Check if a given extension is up to date + * + * @param InputInterface $input Input stream, used to get the options. + * @param OutputInterface $output Output stream, used to print messages. + * @param OutputInterface $stability Force a given stability + * @param bool $recheck Disallow the use of the cache + * @param string $ext_name The extension name + * @return int + */ + protected function check_ext(InputInterface $input, OutputInterface $output, $stability, $recheck, $ext_name) + { + try + { + $ext_manager = $this->phpbb_container->get('ext.manager'); + $md_manager = $ext_manager->create_extension_metadata_manager($ext_name, null); + $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); + } + catch (\RuntimeException $e) + { + $output->writeln('' . $e->getMessage() . ''); + + return 2; + } + + $metadata = $md_manager->get_metadata('all'); + if ($input->getOption('verbose')) + { + $output->writeln('' . $md_manager->get_metadata('display-name') . ''); + $output->writeln(''); + + $output->writeln('' . $this->user->lang('CURRENT_VERSION') . $this->user->lang('COLON') . ' ' . $metadata['version']); + } + + if (!empty($updates_available)) + { + $output->writeln(''); + $output->writeln('' . $this->user->lang('NOT_UP_TO_DATE', $metadata['name']) . ''); + + if ($input->getOption('verbose')) + { + $this->display_versions($output, $updates_available); + } + + return 1; + } + else + { + $output->writeln(''); + $output->writeln('' . $this->user->lang('NOT_UP_TO_DATE', $metadata['name']) . ''); + + if ($input->getOption('verbose')) + { + $output->writeln('' . $this->user->lang('UPDATE_NOT_NEEDED') . ''); + } + + return 0; + } + } + + /** + * Check if the core is up to date + * + * @param InputInterface $input Input stream, used to get the options. + * @param OutputInterface $output Output stream, used to print messages. + * @param OutputInterface $stability Force a given stability + * @param bool $recheck Disallow the use of the cache + * @return int + */ + protected function check_core(InputInterface $input, OutputInterface $output, $stability, $recheck) + { + $version_helper = $this->phpbb_container->get('version_helper'); + $version_helper->force_stability($stability); + + try + { + $updates_available = $version_helper->get_suggested_updates($recheck); + } + catch (\RuntimeException $e) + { + $output->writeln('' . $this->user->lang('VERSIONCHECK_FAIL') . ''); + + return 2; + } + + if ($input->getOption('verbose')) + { + $output->writeln('phpBB core'); + $output->writeln(''); + + $output->writeln('' . $this->user->lang('CURRENT_VERSION') . $this->user->lang('COLON') . ' ' . $this->config['version']); + } + + if (!empty($updates_available)) + { + $output->writeln(''); + $output->writeln('' . $this->user->lang('UPDATE_NEEDED') . ''); + + if ($input->getOption('verbose')) + { + $this->display_versions($output, $updates_available); + } + + return 1; + } + else + { + if ($input->getOption('verbose')) + { + $output->writeln(''); + $output->writeln('' . $this->user->lang('UPDATE_NOT_NEEDED') . ''); + } + + return 0; + } + } + + /** + * Check if all the available extensions are up to date + * + * @param InputInterface $input Input stream, used to get the options. + * @param OutputInterface $output Output stream, used to print messages. + * @param OutputInterface $stability Force a given stability + * @param bool $recheck Disallow the use of the cache + * @return int + */ + protected function check_all_ext(InputInterface $input, OutputInterface $output, $stability, $recheck) + { + $ext_manager = $this->phpbb_container->get('ext.manager'); + + $ext_name_length = max(30, strlen($this->user->lang('EXTENSION_NAME'))); + $current_version_length = max(15, strlen($this->user->lang('CURRENT_VERSION'))); + $latest_version_length = max(15, strlen($this->user->lang('LATEST_VERSION'))); + + $output->writeln(sprintf("%-{$ext_name_length}s | %-{$current_version_length}s | %s", $this->user->lang('EXTENSION_NAME'), $this->user->lang('CURRENT_VERSION'), $this->user->lang('LATEST_VERSION'))); + $output->writeln(sprintf("%'-{$ext_name_length}s-+-%'-{$current_version_length}s-+-%'-{$latest_version_length}s", '', '', '')); + foreach ($ext_manager->all_available() as $ext_name => $ext_path) + { + $message = sprintf("%-{$ext_name_length}s", $ext_name); + $md_manager = $ext_manager->create_extension_metadata_manager($ext_name, null); + try + { + $metadata = $md_manager->get_metadata('all'); + $message .= sprintf(" | %-{$current_version_length}s", $metadata['version']); + try + { + $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); + $message .= sprintf(" | %s", implode(', ', array_keys($updates_available))); + } + catch (\RuntimeException $e) + { + $message .= ' | '; + } + } + catch (\RuntimeException $e) + { + $message .= ('' . $e->getMessage() . ''); + } + + $output->writeln($message); + } + + return 0; + } + + /** + * Display the details of the available updates + * + * @param OutputInterface $output Output stream, used to print messages. + * @param array $updates_available The list of the available updates + */ + protected function display_versions(OutputInterface $output, $updates_available) + { + $output->writeln(''); + $output->writeln('' . $this->user->lang('UPDATES_AVAILABLE') . ''); + foreach ($updates_available as $version_data) + { + $messages = array(); + $messages[] = sprintf("\t%-30s| %s", $this->user->lang('VERSION'), $version_data['current']); + + if (isset($version_data['announcement'])) + { + $messages[] = sprintf("\t%-30s| %s", $this->user->lang('ANNOUNCEMENT_TOPIC'), $version_data['announcement']); + } + + if (isset($version_data['download'])) + { + $messages[] = sprintf("\t%-30s| %s", $this->user->lang('DOWNLOAD_LATEST'), $version_data['download']); + } + + $messages[] = ''; + + $output->writeln(implode("\n", $messages)); + } + } +} diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 98d2d27278..6cdc8c0cc7 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -42,10 +42,10 @@ class manager * @param string $extension_table The name of the table holding extensions * @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $php_ext php file extension, defaults to php - * @param \phpbb\cache\driver\driver_interface $cache A cache instance or null + * @param \phpbb\cache\service $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\service $cache = null, $cache_name = '_ext') { $this->cache = $cache; $this->cache_name = $cache_name; @@ -146,12 +146,11 @@ class manager * Instantiates the metadata manager for the extension with the given name * * @param string $name The extension name - * @param \phpbb\template\template $template The template manager * @return \phpbb\extension\metadata_manager Instance of the metadata manager */ - public function create_extension_metadata_manager($name, \phpbb\template\template $template) + public function create_extension_metadata_manager($name) { - return new \phpbb\extension\metadata_manager($name, $this->config, $this, $template, $this->phpbb_root_path); + return new \phpbb\extension\metadata_manager($name, $this->config, $this, $this->phpbb_root_path); } /** @@ -565,6 +564,35 @@ class manager return isset($this->extensions[$name]); } + /** + * Check the version and return the available updates (for an extension). + * + * @param \phpbb\extension\metadata_manager $md_manager The metadata manager for the version to check. + * @param bool $force_update Ignores cached data. Defaults to false. + * @param bool $force_cache Force the use of the cache. Override $force_update. + * @param string $stability Force the stability (null by default). + * @return string + * @throws \RuntimeException + */ + public function version_check(\phpbb\extension\metadata_manager $md_manager, $force_update = false, $force_cache = false, $stability = null) + { + $meta = $md_manager->get_metadata('all'); + + if (!isset($meta['extra']['version-check'])) + { + throw new \RuntimeException($this->user->lang('NO_VERSIONCHECK'), 1); + } + + $version_check = $meta['extra']['version-check']; + + $version_helper = new \phpbb\version_helper($this->cache, $this->config, $this->user); + $version_helper->set_current_version($meta['version']); + $version_helper->set_file_location($version_check ['host'], $version_check ['directory'], $version_check ['filename']); + $version_helper->force_stability($stability); + + return $updates = $version_helper->get_suggested_updates($force_update, $force_cache); + } + /** * Check to see if a given extension is purged * diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index 4f080647c8..fe64c92ee1 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -30,12 +30,6 @@ class metadata_manager */ protected $extension_manager; - /** - * phpBB Template instance - * @var \phpbb\template\template - */ - protected $template; - /** * phpBB root path * @var string @@ -66,14 +60,12 @@ class metadata_manager * @param string $ext_name Name (including vendor) of the extension * @param \phpbb\config\config $config phpBB Config instance * @param \phpbb\extension\manager $extension_manager An instance of the phpBB extension manager - * @param \phpbb\template\template $template phpBB Template instance * @param string $phpbb_root_path Path to the phpbb includes directory. */ - public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, $phpbb_root_path) + public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, $phpbb_root_path) { $this->config = $config; $this->extension_manager = $extension_manager; - $this->template = $template; $this->phpbb_root_path = $phpbb_root_path; $this->ext_name = $ext_name; @@ -336,11 +328,11 @@ class metadata_manager /** * Outputs the metadata into the template * - * @return null + * @param \phpbb\template\template $template phpBB Template instance */ - public function output_template_data() + public function output_template_data(\phpbb\template\template $template) { - $this->template->assign_vars(array( + $template->assign_vars(array( 'META_NAME' => $this->metadata['name'], 'META_TYPE' => $this->metadata['type'], 'META_DESCRIPTION' => (isset($this->metadata['description'])) ? $this->metadata['description'] : '', @@ -360,7 +352,7 @@ class metadata_manager foreach ($this->metadata['authors'] as $author) { - $this->template->assign_block_vars('meta_authors', array( + $template->assign_block_vars('meta_authors', array( 'AUTHOR_NAME' => $author['name'], 'AUTHOR_EMAIL' => (isset($author['email'])) ? $author['email'] : '', 'AUTHOR_HOMEPAGE' => (isset($author['homepage'])) ? $author['homepage'] : '', diff --git a/phpBB/phpbb/finder.php b/phpBB/phpbb/finder.php index 58bc27084e..1f1d931880 100644 --- a/phpBB/phpbb/finder.php +++ b/phpBB/phpbb/finder.php @@ -50,12 +50,12 @@ class finder * * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem instance * @param string $phpbb_root_path Path to the phpbb root directory - * @param \phpbb\cache\driver\driver_interface $cache A cache instance or null + * @param \phpbb\cache\service $cache A cache instance or null * @param string $php_ext php file extension * @param string $cache_name The name of the cache variable, defaults to * _ext_finder */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path = '', \phpbb\cache\driver\driver_interface $cache = null, $php_ext = 'php', $cache_name = '_ext_finder') + public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path = '', \phpbb\cache\service $cache = null, $php_ext = 'php', $cache_name = '_ext_finder') { $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; -- cgit v1.2.1 From 8481bd4e1831e3f9911263957637f4095fb088b0 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 24 Aug 2015 12:33:32 +0200 Subject: [ticket/12610] Use exception_interface PHPBB3-12610 --- phpBB/phpbb/console/command/update/check.php | 32 +++++++++------------------ phpBB/phpbb/extension/manager.php | 8 ++++--- phpBB/phpbb/version_helper.php | 33 +++++++++------------------- 3 files changed, 25 insertions(+), 48 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php index 0ef3c970ac..982c86bf8c 100644 --- a/phpBB/phpbb/console/command/update/check.php +++ b/phpBB/phpbb/console/command/update/check.php @@ -13,6 +13,7 @@ namespace phpbb\console\command\update; +use phpbb\exception\exception_interface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; @@ -116,18 +117,9 @@ class check extends \phpbb\console\command\command */ protected function check_ext(InputInterface $input, OutputInterface $output, $stability, $recheck, $ext_name) { - try - { - $ext_manager = $this->phpbb_container->get('ext.manager'); - $md_manager = $ext_manager->create_extension_metadata_manager($ext_name, null); - $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); - } - catch (\RuntimeException $e) - { - $output->writeln('' . $e->getMessage() . ''); - - return 2; - } + $ext_manager = $this->phpbb_container->get('ext.manager'); + $md_manager = $ext_manager->create_extension_metadata_manager($ext_name, null); + $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); $metadata = $md_manager->get_metadata('all'); if ($input->getOption('verbose')) @@ -178,16 +170,7 @@ class check extends \phpbb\console\command\command $version_helper = $this->phpbb_container->get('version_helper'); $version_helper->force_stability($stability); - try - { - $updates_available = $version_helper->get_suggested_updates($recheck); - } - catch (\RuntimeException $e) - { - $output->writeln('' . $this->user->lang('VERSIONCHECK_FAIL') . ''); - - return 2; - } + $updates_available = $version_helper->get_suggested_updates($recheck); if ($input->getOption('verbose')) { @@ -258,6 +241,11 @@ class check extends \phpbb\console\command\command $message .= ' | '; } } + catch (exception_interface $e) + { + $exception_message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters())); + $message .= ('' . $exception_message . ''); + } catch (\RuntimeException $e) { $message .= ('' . $e->getMessage() . ''); diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 6cdc8c0cc7..da1f06c885 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -13,6 +13,8 @@ namespace phpbb\extension; +use phpbb\exception\runtime_exception; +use phpbb\file_downloader; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -572,7 +574,7 @@ class manager * @param bool $force_cache Force the use of the cache. Override $force_update. * @param string $stability Force the stability (null by default). * @return string - * @throws \RuntimeException + * @throws runtime_exception */ public function version_check(\phpbb\extension\metadata_manager $md_manager, $force_update = false, $force_cache = false, $stability = null) { @@ -580,12 +582,12 @@ class manager if (!isset($meta['extra']['version-check'])) { - throw new \RuntimeException($this->user->lang('NO_VERSIONCHECK'), 1); + throw new runtime_exception('NO_VERSIONCHECK'); } $version_check = $meta['extra']['version-check']; - $version_helper = new \phpbb\version_helper($this->cache, $this->config, $this->user); + $version_helper = new \phpbb\version_helper($this->cache, $this->config, new file_downloader()); $version_helper->set_current_version($meta['version']); $version_helper->set_file_location($version_check ['host'], $version_check ['directory'], $version_check ['filename']); $version_helper->force_stability($stability); diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index a1e66ba8fe..227bb72403 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -12,6 +12,7 @@ */ namespace phpbb; +use phpbb\exception\runtime_exception; /** * Class to handle version checking and comparison @@ -58,23 +59,18 @@ class version_helper /** @var \phpbb\file_downloader */ protected $file_downloader; - /** @var \phpbb\user */ - protected $user; - /** * Constructor * * @param \phpbb\cache\service $cache * @param \phpbb\config\config $config * @param \phpbb\file_downloader $file_downloader - * @param \phpbb\user $user */ - public function __construct(\phpbb\cache\service $cache, \phpbb\config\config $config, \phpbb\file_downloader $file_downloader, \phpbb\user $user) + public function __construct(\phpbb\cache\service $cache, \phpbb\config\config $config, \phpbb\file_downloader $file_downloader) { $this->cache = $cache; $this->config = $config; $this->file_downloader = $file_downloader; - $this->user = $user; if (defined('PHPBB_QA')) { @@ -175,7 +171,7 @@ class version_helper * @param bool $force_update Ignores cached data. Defaults to false. * @param bool $force_cache Force the use of the cache. Override $force_update. * @return string - * @throws \RuntimeException + * @throws runtime_exception */ public function get_latest_on_current_branch($force_update = false, $force_cache = false) { @@ -206,7 +202,7 @@ class version_helper * @param bool $force_update Ignores cached data. Defaults to false. * @param bool $force_cache Force the use of the cache. Override $force_update. * @return string - * @throws \RuntimeException + * @throws runtime_exception */ public function get_suggested_updates($force_update = false, $force_cache = false) { @@ -227,7 +223,7 @@ class version_helper * @param bool $force_update Ignores cached data. Defaults to false. * @param bool $force_cache Force the use of the cache. Override $force_update. * @return string Version info - * @throws \RuntimeException + * @throws runtime_exception */ public function get_versions_matching_stability($force_update = false, $force_cache = false) { @@ -247,7 +243,7 @@ class version_helper * @param bool $force_update Ignores cached data. Defaults to false. * @param bool $force_cache Force the use of the cache. Override $force_update. * @return string Version info, includes stable and unstable data - * @throws \RuntimeException + * @throws runtime_exception */ public function get_versions($force_update = false, $force_cache = false) { @@ -257,23 +253,16 @@ class version_helper if ($info === false && $force_cache) { - throw new \RuntimeException($this->user->lang('VERSIONCHECK_FAIL')); + throw new runtime_exception('VERSIONCHECK_FAIL'); } else if ($info === false || $force_update) { - try { - $info = $this->file_downloader->get($this->host, $this->path, $this->file, $this->use_ssl ? 443 : 80); - } - catch (\phpbb\exception\runtime_exception $exception) - { - $prepare_parameters = array_merge(array($exception->getMessage()), $exception->get_parameters()); - throw new \RuntimeException(call_user_func_array(array($this->user, 'lang'), $prepare_parameters)); - } + $info = $this->file_downloader->get($this->host, $this->path, $this->file, $this->use_ssl ? 443 : 80); $error_string = $this->file_downloader->get_error_string(); if (!empty($error_string)) { - throw new \RuntimeException($error_string); + throw new runtime_exception($error_string); } $info = json_decode($info, true); @@ -290,9 +279,7 @@ class version_helper if (empty($info['stable']) && empty($info['unstable'])) { - $this->user->add_lang('acp/common'); - - throw new \RuntimeException($this->user->lang('VERSIONCHECK_FAIL')); + throw new runtime_exception('VERSIONCHECK_FAIL'); } $info['stable'] = (empty($info['stable'])) ? array() : $info['stable']; -- cgit v1.2.1 From 45dda53310bb618dce0813d61a85948cb334e4a9 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 26 Aug 2015 12:06:56 +0200 Subject: [ticket/12610] Improve output PHPBB3-12610 --- phpBB/phpbb/console/command/update/check.php | 32 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php index 982c86bf8c..03dd313291 100644 --- a/phpBB/phpbb/console/command/update/check.php +++ b/phpBB/phpbb/console/command/update/check.php @@ -52,8 +52,8 @@ class check extends \phpbb\console\command\command ->setName('update:check') ->setDescription($this->user->lang('CLI_DESCRIPTION_UPDATE_CHECK')) ->addArgument('ext-name', InputArgument::OPTIONAL, $this->user->lang('CLI_DESCRIPTION_UPDATE_CHECK_ARGUMENT_1')) - ->addOption('stability', null, InputOption::VALUE_REQUIRED, 'CLI_DESCRIPTION_CRON_RUN_OPTION_STABILITY') - ->addOption('cache', 'c', InputOption::VALUE_NONE, 'CLI_DESCRIPTION_CRON_RUN_OPTION_CACHE') + ->addOption('stability', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_UPDATE_CHECK_OPTION_STABILITY')) + ->addOption('cache', 'c', InputOption::VALUE_NONE, $this->user->lang('CLI_DESCRIPTION_UPDATE_CHECK_OPTION_CACHE')) ; } @@ -215,6 +215,7 @@ class check extends \phpbb\console\command\command */ protected function check_all_ext(InputInterface $input, OutputInterface $output, $stability, $recheck) { + /** @var \phpbb\extension\manager $ext_manager */ $ext_manager = $this->phpbb_container->get('ext.manager'); $ext_name_length = max(30, strlen($this->user->lang('EXTENSION_NAME'))); @@ -230,15 +231,30 @@ class check extends \phpbb\console\command\command try { $metadata = $md_manager->get_metadata('all'); - $message .= sprintf(" | %-{$current_version_length}s", $metadata['version']); - try + if (isset($metadata['extra']['version-check'])) { - $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); - $message .= sprintf(" | %s", implode(', ', array_keys($updates_available))); + try { + $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); + if (!empty($updates_available)) + { + $message .= sprintf(" | %-{$current_version_length}s | %s", + $metadata['version'], + implode(', ', array_keys($updates_available)) + ); + } + else + { + $message .= sprintf(" | %-{$current_version_length}s | ", + $metadata['version'] + ); + } + } catch (\RuntimeException $e) { + $message .= ' | '; + } } - catch (\RuntimeException $e) + else { - $message .= ' | '; + $message .= sprintf(" | %-{$current_version_length}s | ", $metadata['version']); } } catch (exception_interface $e) -- cgit v1.2.1 From 0256c69191db7b2102d5fb338401ab3f58b118c6 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Wed, 26 Aug 2015 13:33:38 +0200 Subject: [ticket/12610] CS PHPBB3-12610 --- phpBB/phpbb/extension/manager.php | 2 +- phpBB/phpbb/version_helper.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index da1f06c885..b2b60aaa9b 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -589,7 +589,7 @@ class manager $version_helper = new \phpbb\version_helper($this->cache, $this->config, new file_downloader()); $version_helper->set_current_version($meta['version']); - $version_helper->set_file_location($version_check ['host'], $version_check ['directory'], $version_check ['filename']); + $version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename']); $version_helper->force_stability($stability); return $updates = $version_helper->get_suggested_updates($force_update, $force_cache); diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index 227bb72403..b1dcdf10d9 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -12,6 +12,7 @@ */ namespace phpbb; + use phpbb\exception\runtime_exception; /** -- cgit v1.2.1 From c9e493a911d8296ce1ccca5de8ec4c9f84e1983d Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 18 Feb 2016 22:33:39 +0100 Subject: [ticket/12610] Display the latest version and not the branch name in CLI PHPBB3-12610 --- phpBB/phpbb/console/command/update/check.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php index 03dd313291..7c1e52c955 100644 --- a/phpBB/phpbb/console/command/update/check.php +++ b/phpBB/phpbb/console/command/update/check.php @@ -237,9 +237,14 @@ class check extends \phpbb\console\command\command $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); if (!empty($updates_available)) { + $versions = array_map(function($entry) + { + return $entry['current']; + }, $updates_available); + $message .= sprintf(" | %-{$current_version_length}s | %s", $metadata['version'], - implode(', ', array_keys($updates_available)) + implode(', ', $versions) ); } else -- cgit v1.2.1 From 57915a8aaa842064d42fee419c9e0eaf7288140a Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Thu, 1 Sep 2016 16:12:04 +0200 Subject: [ticket/12610] Correctly handle empty cache PHPBB3-12610 --- phpBB/phpbb/exception/version_check_exception.php | 21 +++++++++++++++++++++ phpBB/phpbb/version_helper.php | 16 ++++++++-------- 2 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 phpBB/phpbb/exception/version_check_exception.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/exception/version_check_exception.php b/phpBB/phpbb/exception/version_check_exception.php new file mode 100644 index 0000000000..0810263ade --- /dev/null +++ b/phpBB/phpbb/exception/version_check_exception.php @@ -0,0 +1,21 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\exception; + +/** + * Define an exception related to the version checker. + */ +class version_check_exception extends runtime_exception +{ +} diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index b1dcdf10d9..17caaa4a60 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -13,7 +13,7 @@ namespace phpbb; -use phpbb\exception\runtime_exception; +use phpbb\exception\version_check_exception; /** * Class to handle version checking and comparison @@ -172,7 +172,7 @@ class version_helper * @param bool $force_update Ignores cached data. Defaults to false. * @param bool $force_cache Force the use of the cache. Override $force_update. * @return string - * @throws runtime_exception + * @throws version_check_exception */ public function get_latest_on_current_branch($force_update = false, $force_cache = false) { @@ -203,7 +203,7 @@ class version_helper * @param bool $force_update Ignores cached data. Defaults to false. * @param bool $force_cache Force the use of the cache. Override $force_update. * @return string - * @throws runtime_exception + * @throws version_check_exception */ public function get_suggested_updates($force_update = false, $force_cache = false) { @@ -224,7 +224,7 @@ class version_helper * @param bool $force_update Ignores cached data. Defaults to false. * @param bool $force_cache Force the use of the cache. Override $force_update. * @return string Version info - * @throws runtime_exception + * @throws version_check_exception */ public function get_versions_matching_stability($force_update = false, $force_cache = false) { @@ -244,7 +244,7 @@ class version_helper * @param bool $force_update Ignores cached data. Defaults to false. * @param bool $force_cache Force the use of the cache. Override $force_update. * @return string Version info, includes stable and unstable data - * @throws runtime_exception + * @throws version_check_exception */ public function get_versions($force_update = false, $force_cache = false) { @@ -254,7 +254,7 @@ class version_helper if ($info === false && $force_cache) { - throw new runtime_exception('VERSIONCHECK_FAIL'); + throw new version_check_exception('VERSIONCHECK_FAIL'); } else if ($info === false || $force_update) { @@ -263,7 +263,7 @@ class version_helper if (!empty($error_string)) { - throw new runtime_exception($error_string); + throw new version_check_exception($error_string); } $info = json_decode($info, true); @@ -280,7 +280,7 @@ class version_helper if (empty($info['stable']) && empty($info['unstable'])) { - throw new runtime_exception('VERSIONCHECK_FAIL'); + throw new version_check_exception('VERSIONCHECK_FAIL'); } $info['stable'] = (empty($info['stable'])) ? array() : $info['stable']; -- cgit v1.2.1 From 6c35ca80edd76906638326468b15aa9f355b477b Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 4 Dec 2016 10:37:17 +0100 Subject: [ticket/12610] Add a better error message when an extension is missing PHPBB3-12610 --- phpBB/phpbb/console/command/update/check.php | 107 ++++++++++++++++----------- 1 file changed, 63 insertions(+), 44 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php index 7c1e52c955..19da2318ca 100644 --- a/phpBB/phpbb/console/command/update/check.php +++ b/phpBB/phpbb/console/command/update/check.php @@ -13,11 +13,15 @@ namespace phpbb\console\command\update; +use phpbb\config\config; use phpbb\exception\exception_interface; +use phpbb\language\language; +use phpbb\user; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; class check extends \phpbb\console\command\command { @@ -26,17 +30,23 @@ class check extends \phpbb\console\command\command /** @var \Symfony\Component\DependencyInjection\ContainerBuilder */ protected $phpbb_container; + /** + * @var language + */ + private $language; /** * Construct method */ - public function __construct(\phpbb\user $user, \phpbb\config\config $config, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container) + public function __construct(user $user, config $config, ContainerInterface $phpbb_container, language $language) { parent::__construct($user); $this->config = $config; $this->phpbb_container = $phpbb_container; - $this->user->add_lang(array('acp/common', 'acp/extensions')); + $this->language = $language; + + $this->language->add_lang(array('acp/common', 'acp/extensions')); } /** @@ -50,10 +60,10 @@ class check extends \phpbb\console\command\command { $this ->setName('update:check') - ->setDescription($this->user->lang('CLI_DESCRIPTION_UPDATE_CHECK')) - ->addArgument('ext-name', InputArgument::OPTIONAL, $this->user->lang('CLI_DESCRIPTION_UPDATE_CHECK_ARGUMENT_1')) - ->addOption('stability', null, InputOption::VALUE_REQUIRED, $this->user->lang('CLI_DESCRIPTION_UPDATE_CHECK_OPTION_STABILITY')) - ->addOption('cache', 'c', InputOption::VALUE_NONE, $this->user->lang('CLI_DESCRIPTION_UPDATE_CHECK_OPTION_CACHE')) + ->setDescription($this->language->lang('CLI_DESCRIPTION_UPDATE_CHECK')) + ->addArgument('ext-name', InputArgument::OPTIONAL, $this->language->lang('CLI_DESCRIPTION_UPDATE_CHECK_ARGUMENT_1')) + ->addOption('stability', null, InputOption::VALUE_REQUIRED, $this->language->lang('CLI_DESCRIPTION_UPDATE_CHECK_OPTION_STABILITY')) + ->addOption('cache', 'c', InputOption::VALUE_NONE, $this->language->lang('CLI_DESCRIPTION_UPDATE_CHECK_OPTION_CACHE')) ; } @@ -83,7 +93,7 @@ class check extends \phpbb\console\command\command $stability = $input->getOption('stability'); if (!($stability == 'stable') && !($stability == 'unstable')) { - throw new \RuntimeException($this->user->lang('CLI_ERROR_INVALID_STABILITY', $stability)); + throw new \RuntimeException($this->language->lang('CLI_ERROR_INVALID_STABILITY', $stability)); } } @@ -117,42 +127,51 @@ class check extends \phpbb\console\command\command */ protected function check_ext(InputInterface $input, OutputInterface $output, $stability, $recheck, $ext_name) { - $ext_manager = $this->phpbb_container->get('ext.manager'); - $md_manager = $ext_manager->create_extension_metadata_manager($ext_name, null); - $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); - - $metadata = $md_manager->get_metadata('all'); - if ($input->getOption('verbose')) + try { - $output->writeln('' . $md_manager->get_metadata('display-name') . ''); - $output->writeln(''); - - $output->writeln('' . $this->user->lang('CURRENT_VERSION') . $this->user->lang('COLON') . ' ' . $metadata['version']); - } - - if (!empty($updates_available)) - { - $output->writeln(''); - $output->writeln('' . $this->user->lang('NOT_UP_TO_DATE', $metadata['name']) . ''); + $ext_manager = $this->phpbb_container->get('ext.manager'); + $md_manager = $ext_manager->create_extension_metadata_manager($ext_name, null); + $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); + $metadata = $md_manager->get_metadata('all'); if ($input->getOption('verbose')) { - $this->display_versions($output, $updates_available); + $output->writeln('' . $md_manager->get_metadata('display-name') . ''); + $output->writeln(''); + + $output->writeln('' . $this->language->lang('CURRENT_VERSION') . $this->language->lang('COLON') . ' ' . $metadata['version']); } - return 1; - } - else - { - $output->writeln(''); - $output->writeln('' . $this->user->lang('NOT_UP_TO_DATE', $metadata['name']) . ''); + if (!empty($updates_available)) + { + $output->writeln(''); + $output->writeln('' . $this->language->lang('NOT_UP_TO_DATE', $metadata['name']) . ''); - if ($input->getOption('verbose')) + if ($input->getOption('verbose')) + { + $this->display_versions($output, $updates_available); + } + + return 1; + } + else { - $output->writeln('' . $this->user->lang('UPDATE_NOT_NEEDED') . ''); + $output->writeln(''); + $output->writeln('' . $this->language->lang('NOT_UP_TO_DATE', $metadata['name']) . ''); + + if ($input->getOption('verbose')) + { + $output->writeln('' . $this->language->lang('UPDATE_NOT_NEEDED') . ''); + } + + return 0; } + } + catch (\RuntimeException $e) + { + $output->writeln(''.$this->language->lang('EXTENSION_NOT_INSTALLED', $ext_name).''); - return 0; + return 1; } } @@ -177,13 +196,13 @@ class check extends \phpbb\console\command\command $output->writeln('phpBB core'); $output->writeln(''); - $output->writeln('' . $this->user->lang('CURRENT_VERSION') . $this->user->lang('COLON') . ' ' . $this->config['version']); + $output->writeln('' . $this->language->lang('CURRENT_VERSION') . $this->language->lang('COLON') . ' ' . $this->config['version']); } if (!empty($updates_available)) { $output->writeln(''); - $output->writeln('' . $this->user->lang('UPDATE_NEEDED') . ''); + $output->writeln('' . $this->language->lang('UPDATE_NEEDED') . ''); if ($input->getOption('verbose')) { @@ -197,7 +216,7 @@ class check extends \phpbb\console\command\command if ($input->getOption('verbose')) { $output->writeln(''); - $output->writeln('' . $this->user->lang('UPDATE_NOT_NEEDED') . ''); + $output->writeln('' . $this->language->lang('UPDATE_NOT_NEEDED') . ''); } return 0; @@ -218,11 +237,11 @@ class check extends \phpbb\console\command\command /** @var \phpbb\extension\manager $ext_manager */ $ext_manager = $this->phpbb_container->get('ext.manager'); - $ext_name_length = max(30, strlen($this->user->lang('EXTENSION_NAME'))); - $current_version_length = max(15, strlen($this->user->lang('CURRENT_VERSION'))); - $latest_version_length = max(15, strlen($this->user->lang('LATEST_VERSION'))); + $ext_name_length = max(30, strlen($this->language->lang('EXTENSION_NAME'))); + $current_version_length = max(15, strlen($this->language->lang('CURRENT_VERSION'))); + $latest_version_length = max(15, strlen($this->language->lang('LATEST_VERSION'))); - $output->writeln(sprintf("%-{$ext_name_length}s | %-{$current_version_length}s | %s", $this->user->lang('EXTENSION_NAME'), $this->user->lang('CURRENT_VERSION'), $this->user->lang('LATEST_VERSION'))); + $output->writeln(sprintf("%-{$ext_name_length}s | %-{$current_version_length}s | %s", $this->language->lang('EXTENSION_NAME'), $this->language->lang('CURRENT_VERSION'), $this->language->lang('LATEST_VERSION'))); $output->writeln(sprintf("%'-{$ext_name_length}s-+-%'-{$current_version_length}s-+-%'-{$latest_version_length}s", '', '', '')); foreach ($ext_manager->all_available() as $ext_name => $ext_path) { @@ -287,20 +306,20 @@ class check extends \phpbb\console\command\command protected function display_versions(OutputInterface $output, $updates_available) { $output->writeln(''); - $output->writeln('' . $this->user->lang('UPDATES_AVAILABLE') . ''); + $output->writeln('' . $this->language->lang('UPDATES_AVAILABLE') . ''); foreach ($updates_available as $version_data) { $messages = array(); - $messages[] = sprintf("\t%-30s| %s", $this->user->lang('VERSION'), $version_data['current']); + $messages[] = sprintf("\t%-30s| %s", $this->language->lang('VERSION'), $version_data['current']); if (isset($version_data['announcement'])) { - $messages[] = sprintf("\t%-30s| %s", $this->user->lang('ANNOUNCEMENT_TOPIC'), $version_data['announcement']); + $messages[] = sprintf("\t%-30s| %s", $this->language->lang('ANNOUNCEMENT_TOPIC'), $version_data['announcement']); } if (isset($version_data['download'])) { - $messages[] = sprintf("\t%-30s| %s", $this->user->lang('DOWNLOAD_LATEST'), $version_data['download']); + $messages[] = sprintf("\t%-30s| %s", $this->language->lang('DOWNLOAD_LATEST'), $version_data['download']); } $messages[] = ''; -- cgit v1.2.1 From 32aa0596f3750ff19f3da799d649e7b2a3429c47 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 4 Dec 2016 17:43:51 +0100 Subject: [ticket/12610] Use Symfony style guide PHPBB3-12610 --- phpBB/phpbb/console/command/update/check.php | 173 +++++++++++++-------------- 1 file changed, 86 insertions(+), 87 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php index 19da2318ca..aaccfa4983 100644 --- a/phpBB/phpbb/console/command/update/check.php +++ b/phpBB/phpbb/console/command/update/check.php @@ -21,6 +21,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\DependencyInjection\ContainerInterface; class check extends \phpbb\console\command\command @@ -40,13 +41,13 @@ class check extends \phpbb\console\command\command */ public function __construct(user $user, config $config, ContainerInterface $phpbb_container, language $language) { - parent::__construct($user); - $this->config = $config; $this->phpbb_container = $phpbb_container; $this->language = $language; $this->language->add_lang(array('acp/common', 'acp/extensions')); + + parent::__construct($user); } /** @@ -81,6 +82,8 @@ class check extends \phpbb\console\command\command */ protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $recheck = true; if ($input->getOption('cache')) { @@ -93,7 +96,8 @@ class check extends \phpbb\console\command\command $stability = $input->getOption('stability'); if (!($stability == 'stable') && !($stability == 'unstable')) { - throw new \RuntimeException($this->language->lang('CLI_ERROR_INVALID_STABILITY', $stability)); + $io->error($this->language->lang('CLI_ERROR_INVALID_STABILITY', $stability)); + return 3; } } @@ -102,30 +106,29 @@ class check extends \phpbb\console\command\command { if ($ext_name == 'all') { - return $this->check_all_ext($input, $output, $stability, $recheck); + return $this->check_all_ext($io, $stability, $recheck); } else { - return $this->check_ext($input, $output, $stability, $recheck, $ext_name); + return $this->check_ext($io, $stability, $recheck, $ext_name); } } else { - return $this->check_core($input, $output, $stability, $recheck); + return $this->check_core($io,$stability, $recheck); } } /** - * Check if a given extension is up to date - * - * @param InputInterface $input Input stream, used to get the options. - * @param OutputInterface $output Output stream, used to print messages. - * @param OutputInterface $stability Force a given stability - * @param bool $recheck Disallow the use of the cache - * @param string $ext_name The extension name - * @return int - */ - protected function check_ext(InputInterface $input, OutputInterface $output, $stability, $recheck, $ext_name) + * Check if a given extension is up to date + * + * @param SymfonyStyle $io IO handler, for formatted and unified IO + * @param string $stability Force a given stability + * @param bool $recheck Disallow the use of the cache + * @param string $ext_name The extension name + * @return int + */ + protected function check_ext(SymfonyStyle $io, $stability, $recheck, $ext_name) { try { @@ -134,34 +137,29 @@ class check extends \phpbb\console\command\command $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); $metadata = $md_manager->get_metadata('all'); - if ($input->getOption('verbose')) + if ($io->isVerbose()) { - $output->writeln('' . $md_manager->get_metadata('display-name') . ''); - $output->writeln(''); + $io->title($md_manager->get_metadata('display-name')); - $output->writeln('' . $this->language->lang('CURRENT_VERSION') . $this->language->lang('COLON') . ' ' . $metadata['version']); + $io->note($this->language->lang('CURRENT_VERSION') . $this->language->lang('COLON') . ' ' . $metadata['version']); } if (!empty($updates_available)) { - $output->writeln(''); - $output->writeln('' . $this->language->lang('NOT_UP_TO_DATE', $metadata['name']) . ''); - - if ($input->getOption('verbose')) + if ($io->isVerbose()) { - $this->display_versions($output, $updates_available); + $io->caution($this->language->lang('NOT_UP_TO_DATE', $metadata['name'])); + + $this->display_versions($io, $updates_available); } return 1; } else { - $output->writeln(''); - $output->writeln('' . $this->language->lang('NOT_UP_TO_DATE', $metadata['name']) . ''); - - if ($input->getOption('verbose')) + if ($io->isVerbose()) { - $output->writeln('' . $this->language->lang('UPDATE_NOT_NEEDED') . ''); + $io->success($this->language->lang('UPDATE_NOT_NEEDED')); } return 0; @@ -169,54 +167,50 @@ class check extends \phpbb\console\command\command } catch (\RuntimeException $e) { - $output->writeln(''.$this->language->lang('EXTENSION_NOT_INSTALLED', $ext_name).''); + $io->error($this->language->lang('EXTENSION_NOT_INSTALLED', $ext_name)); return 1; } } /** - * Check if the core is up to date - * - * @param InputInterface $input Input stream, used to get the options. - * @param OutputInterface $output Output stream, used to print messages. - * @param OutputInterface $stability Force a given stability - * @param bool $recheck Disallow the use of the cache - * @return int - */ - protected function check_core(InputInterface $input, OutputInterface $output, $stability, $recheck) + * Check if the core is up to date + * + * @param SymfonyStyle $io IO handler, for formatted and unified IO + * @param string $stability Force a given stability + * @param bool $recheck Disallow the use of the cache + * @return int + */ + protected function check_core(SymfonyStyle $io, $stability, $recheck) { $version_helper = $this->phpbb_container->get('version_helper'); $version_helper->force_stability($stability); $updates_available = $version_helper->get_suggested_updates($recheck); - if ($input->getOption('verbose')) + if ($io->isVerbose()) { - $output->writeln('phpBB core'); - $output->writeln(''); + $io->title('phpBB core'); - $output->writeln('' . $this->language->lang('CURRENT_VERSION') . $this->language->lang('COLON') . ' ' . $this->config['version']); + $io->note( $this->language->lang('CURRENT_VERSION') . $this->language->lang('COLON') . ' ' . $this->config['version']); } if (!empty($updates_available)) { - $output->writeln(''); - $output->writeln('' . $this->language->lang('UPDATE_NEEDED') . ''); + $io->caution($this->language->lang('UPDATE_NEEDED')); - if ($input->getOption('verbose')) + if ($io->isVerbose()) { - $this->display_versions($output, $updates_available); + $this->display_versions($io, $updates_available); } return 1; } else { - if ($input->getOption('verbose')) + if ($io->isVerbose()) { - $output->writeln(''); - $output->writeln('' . $this->language->lang('UPDATE_NOT_NEEDED') . ''); + $io->success($this->language->lang('UPDATE_NOT_NEEDED')); } return 0; @@ -226,27 +220,22 @@ class check extends \phpbb\console\command\command /** * Check if all the available extensions are up to date * - * @param InputInterface $input Input stream, used to get the options. - * @param OutputInterface $output Output stream, used to print messages. - * @param OutputInterface $stability Force a given stability - * @param bool $recheck Disallow the use of the cache + * @param SymfonyStyle $io IO handler, for formatted and unified IO + * @param bool $recheck Disallow the use of the cache * @return int */ - protected function check_all_ext(InputInterface $input, OutputInterface $output, $stability, $recheck) + protected function check_all_ext(SymfonyStyle $io, $stability, $recheck) { /** @var \phpbb\extension\manager $ext_manager */ $ext_manager = $this->phpbb_container->get('ext.manager'); - $ext_name_length = max(30, strlen($this->language->lang('EXTENSION_NAME'))); - $current_version_length = max(15, strlen($this->language->lang('CURRENT_VERSION'))); - $latest_version_length = max(15, strlen($this->language->lang('LATEST_VERSION'))); + $rows = []; - $output->writeln(sprintf("%-{$ext_name_length}s | %-{$current_version_length}s | %s", $this->language->lang('EXTENSION_NAME'), $this->language->lang('CURRENT_VERSION'), $this->language->lang('LATEST_VERSION'))); - $output->writeln(sprintf("%'-{$ext_name_length}s-+-%'-{$current_version_length}s-+-%'-{$latest_version_length}s", '', '', '')); foreach ($ext_manager->all_available() as $ext_name => $ext_path) { - $message = sprintf("%-{$ext_name_length}s", $ext_name); - $md_manager = $ext_manager->create_extension_metadata_manager($ext_name, null); + $row = []; + $row[] = sprintf("%s", $ext_name); + $md_manager = $ext_manager->create_extension_metadata_manager($ext_name); try { $metadata = $md_manager->get_metadata('all'); @@ -261,70 +250,80 @@ class check extends \phpbb\console\command\command return $entry['current']; }, $updates_available); - $message .= sprintf(" | %-{$current_version_length}s | %s", - $metadata['version'], - implode(', ', $versions) - ); + $row[] = sprintf("%s", $metadata['version']); + $row[] = implode(', ', $versions); } else { - $message .= sprintf(" | %-{$current_version_length}s | ", - $metadata['version'] - ); + $row[] = sprintf("%s", $metadata['version']); + $row[] = ''; } } catch (\RuntimeException $e) { - $message .= ' | '; + $row[] = $metadata['version']; + $row[] = ''; } } else { - $message .= sprintf(" | %-{$current_version_length}s | ", $metadata['version']); + $row[] = $metadata['version']; + $row[] = ''; } } catch (exception_interface $e) { $exception_message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters())); - $message .= ('' . $exception_message . ''); + $row[] = '' . $exception_message . ''; } catch (\RuntimeException $e) { - $message .= ('' . $e->getMessage() . ''); + $row[] = '' . $e->getMessage() . ''; } - $output->writeln($message); + $rows[] = $row; } + $io->table([ + $this->language->lang('EXTENSION_NAME'), + $this->language->lang('CURRENT_VERSION'), + $this->language->lang('LATEST_VERSION'), + ], $rows); + return 0; } /** * Display the details of the available updates * - * @param OutputInterface $output Output stream, used to print messages. - * @param array $updates_available The list of the available updates + * @param SymfonyStyle $io IO handler, for formatted and unified IO + * @param array $updates_available The list of the available updates */ - protected function display_versions(OutputInterface $output, $updates_available) + protected function display_versions(SymfonyStyle $io, $updates_available) { - $output->writeln(''); - $output->writeln('' . $this->language->lang('UPDATES_AVAILABLE') . ''); + $io->section($this->language->lang('UPDATES_AVAILABLE')); + + $rows = []; foreach ($updates_available as $version_data) { - $messages = array(); - $messages[] = sprintf("\t%-30s| %s", $this->language->lang('VERSION'), $version_data['current']); + $row = ['', '', '']; + $row[0] = $version_data['current']; if (isset($version_data['announcement'])) { - $messages[] = sprintf("\t%-30s| %s", $this->language->lang('ANNOUNCEMENT_TOPIC'), $version_data['announcement']); + $row[1] = $version_data['announcement']; } if (isset($version_data['download'])) { - $messages[] = sprintf("\t%-30s| %s", $this->language->lang('DOWNLOAD_LATEST'), $version_data['download']); + $row[2] = $version_data['download']; } - $messages[] = ''; - - $output->writeln(implode("\n", $messages)); + $rows[] = $row; } + + $io->table([ + $this->language->lang('VERSION'), + $this->language->lang('ANNOUNCEMENT_TOPIC'), + $this->language->lang('DOWNLOAD_LATEST'), + ], $rows); } } -- cgit v1.2.1 From 103d344cd4476b452e42cd7ba0007b5a85caeaaf Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 5 Dec 2016 15:46:05 +0100 Subject: [ticket/12610] Fix tests and use getOption() for console PHPBB3-12610 --- phpBB/phpbb/console/command/update/check.php | 38 +++++++++++++++------------- 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php index aaccfa4983..1f1cfa25d2 100644 --- a/phpBB/phpbb/console/command/update/check.php +++ b/phpBB/phpbb/console/command/update/check.php @@ -110,25 +110,26 @@ class check extends \phpbb\console\command\command } else { - return $this->check_ext($io, $stability, $recheck, $ext_name); + return $this->check_ext($input, $io, $stability, $recheck, $ext_name); } } else { - return $this->check_core($io,$stability, $recheck); + return $this->check_core($input, $io, $stability, $recheck); } } /** * Check if a given extension is up to date * - * @param SymfonyStyle $io IO handler, for formatted and unified IO - * @param string $stability Force a given stability - * @param bool $recheck Disallow the use of the cache - * @param string $ext_name The extension name + * @param InputInterface $input Input stream, used to get the options. + * @param SymfonyStyle $io IO handler, for formatted and unified IO + * @param string $stability Force a given stability + * @param bool $recheck Disallow the use of the cache + * @param string $ext_name The extension name * @return int */ - protected function check_ext(SymfonyStyle $io, $stability, $recheck, $ext_name) + protected function check_ext(InputInterface $input, SymfonyStyle $io, $stability, $recheck, $ext_name) { try { @@ -137,7 +138,7 @@ class check extends \phpbb\console\command\command $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); $metadata = $md_manager->get_metadata('all'); - if ($io->isVerbose()) + if ($input->getOption('verbose')) { $io->title($md_manager->get_metadata('display-name')); @@ -146,7 +147,7 @@ class check extends \phpbb\console\command\command if (!empty($updates_available)) { - if ($io->isVerbose()) + if ($input->getOption('verbose')) { $io->caution($this->language->lang('NOT_UP_TO_DATE', $metadata['name'])); @@ -157,7 +158,7 @@ class check extends \phpbb\console\command\command } else { - if ($io->isVerbose()) + if ($input->getOption('verbose')) { $io->success($this->language->lang('UPDATE_NOT_NEEDED')); } @@ -176,19 +177,20 @@ class check extends \phpbb\console\command\command /** * Check if the core is up to date * - * @param SymfonyStyle $io IO handler, for formatted and unified IO - * @param string $stability Force a given stability - * @param bool $recheck Disallow the use of the cache + * @param InputInterface $input Input stream, used to get the options. + * @param SymfonyStyle $io IO handler, for formatted and unified IO + * @param string $stability Force a given stability + * @param bool $recheck Disallow the use of the cache * @return int */ - protected function check_core(SymfonyStyle $io, $stability, $recheck) + protected function check_core(InputInterface $input, SymfonyStyle $io, $stability, $recheck) { $version_helper = $this->phpbb_container->get('version_helper'); $version_helper->force_stability($stability); $updates_available = $version_helper->get_suggested_updates($recheck); - if ($io->isVerbose()) + if ($input->getOption('verbose')) { $io->title('phpBB core'); @@ -199,7 +201,7 @@ class check extends \phpbb\console\command\command { $io->caution($this->language->lang('UPDATE_NEEDED')); - if ($io->isVerbose()) + if ($input->getOption('verbose')) { $this->display_versions($io, $updates_available); } @@ -208,7 +210,7 @@ class check extends \phpbb\console\command\command } else { - if ($io->isVerbose()) + if ($input->getOption('verbose')) { $io->success($this->language->lang('UPDATE_NOT_NEEDED')); } @@ -220,7 +222,7 @@ class check extends \phpbb\console\command\command /** * Check if all the available extensions are up to date * - * @param SymfonyStyle $io IO handler, for formatted and unified IO + * @param SymfonyStyle $io IO handler, for formatted and unified IO * @param bool $recheck Disallow the use of the cache * @return int */ -- cgit v1.2.1 From fd95da909aff360c7c41c04ff2cadedb9ab2e222 Mon Sep 17 00:00:00 2001 From: rxu Date: Tue, 6 Dec 2016 23:42:49 +0700 Subject: [ticket/14893] Fix undefined variable on reporting PM notification PHPBB3-14893 --- phpBB/phpbb/notification/type/report_pm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php index 239805204c..7e53ffb3ca 100644 --- a/phpBB/phpbb/notification/type/report_pm.php +++ b/phpBB/phpbb/notification/type/report_pm.php @@ -142,7 +142,7 @@ class report_pm extends \phpbb\notification\type\pm */ public function get_email_template_variables() { - $user_data = $this->user_loader->get_username($this->get_data('reporter_id'), 'no_profile'); + $user_data = $this->user_loader->get_user($this->get_data('reporter_id')); return array( 'AUTHOR_NAME' => htmlspecialchars_decode($user_data['username']), -- cgit v1.2.1 From 74cd513a8892285032a248322e3ce52b19645075 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 7 Dec 2016 10:13:09 -0800 Subject: [ticket/14895] CLI reparser:list should display proper list PHPBB3-14895 --- phpBB/phpbb/console/command/reparser/list_all.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/reparser/list_all.php b/phpBB/phpbb/console/command/reparser/list_all.php index e42c3ac782..7dd0571975 100644 --- a/phpBB/phpbb/console/command/reparser/list_all.php +++ b/phpBB/phpbb/console/command/reparser/list_all.php @@ -54,7 +54,7 @@ class list_all extends \phpbb\console\command\command } /** - * Executes the command reparser:reparse + * Executes the command reparser:list * * @param InputInterface $input * @param OutputInterface $output @@ -62,7 +62,11 @@ class list_all extends \phpbb\console\command\command */ protected function execute(InputInterface $input, OutputInterface $output) { - $output->writeln('' . implode(', ', $this->reparser_names) . ''); + $output->writeln('' . $this->user->lang('CLI_DESCRIPTION_REPARSER_AVAILABLE') . ''); + foreach ($this->reparser_names as $reparser_name) + { + $output->writeln($reparser_name); + } return 0; } -- cgit v1.2.1 From 829e1475044f1a72f68958923a0900ed4e62f78e Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 7 Dec 2016 17:55:57 +0100 Subject: [ticket/14896] Do not overwrite login when finishing install Otherwise the user will be "logged in" again as guest user which will prevent any redirectiong to the ACP after the installation. PHPBB3-14896 --- phpBB/phpbb/install/installer.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index a7d3b99dcb..e04e233a76 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -243,12 +243,18 @@ class installer } else { - // Start session and try to apply session id - $auth = $this->container_factory->get('auth'); + // Start session if not installing and get user object + // to allow redirecting to ACP $user = $this->container_factory->get('user'); - $user->session_begin(); - $auth->acl($user->data); - $user->setup(); + if (!isset($module) || !($module instanceof \phpbb\install\module\install_finish\module)) + { + $auth = $this->container_factory->get('auth'); + + $user->session_begin(); + $auth->acl($user->data); + $user->setup(); + } + $phpbb_root_path = $this->container_factory->get_parameter('core.root_path'); $acp_url = append_sid($phpbb_root_path . 'adm/index.php', 'i=acp_help_phpbb&mode=help_phpbb', true, $user->session_id); -- cgit v1.2.1 From f2fde5e7a32943017f7f22b070c974f161d14d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Wed, 7 Dec 2016 21:01:47 +0100 Subject: [ticket/14897] Add $restart_progress_bar to iohandler base PHPBB3-14897 --- phpBB/phpbb/install/helper/iohandler/iohandler_base.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php index fed4bc101f..1797a6c9ad 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php @@ -70,6 +70,11 @@ abstract class iohandler_base implements iohandler_interface */ protected $current_task_name; + /** + * @var bool + */ + protected $restart_progress_bar; + /** * Constructor */ -- cgit v1.2.1 From d275fefc69bae24f547802d824607c9a054ff6d2 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 7 Dec 2016 23:49:54 -0800 Subject: [ticket/14895] Use SymfonyIO styling PHPBB3-14895 --- phpBB/phpbb/console/command/reparser/list_all.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/reparser/list_all.php b/phpBB/phpbb/console/command/reparser/list_all.php index 7dd0571975..028468649d 100644 --- a/phpBB/phpbb/console/command/reparser/list_all.php +++ b/phpBB/phpbb/console/command/reparser/list_all.php @@ -15,6 +15,7 @@ namespace phpbb\console\command\reparser; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class list_all extends \phpbb\console\command\command { @@ -62,11 +63,9 @@ class list_all extends \phpbb\console\command\command */ protected function execute(InputInterface $input, OutputInterface $output) { - $output->writeln('' . $this->user->lang('CLI_DESCRIPTION_REPARSER_AVAILABLE') . ''); - foreach ($this->reparser_names as $reparser_name) - { - $output->writeln($reparser_name); - } + $io = new SymfonyStyle($input, $output); + $io->section($this->user->lang('CLI_DESCRIPTION_REPARSER_AVAILABLE')); + $io->listing($this->reparser_names); return 0; } -- cgit v1.2.1 From b17fa7dfa588fc191f4ed268b88dcaec40294acb Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 8 Dec 2016 14:24:02 -0800 Subject: [ticket/14895] Use SymfonyStyle in all CLI PHPBB3-14895 --- phpBB/phpbb/console/command/cache/purge.php | 4 ++- phpBB/phpbb/console/command/config/delete.php | 7 ++-- phpBB/phpbb/console/command/config/get.php | 5 ++- phpBB/phpbb/console/command/config/increment.php | 5 ++- phpBB/phpbb/console/command/config/set.php | 5 ++- phpBB/phpbb/console/command/config/set_atomic.php | 7 ++-- phpBB/phpbb/console/command/cron/cron_list.php | 39 ++++++---------------- phpBB/phpbb/console/command/db/list_command.php | 30 +++++++++++------ phpBB/phpbb/console/command/db/migrate.php | 7 ++-- phpBB/phpbb/console/command/db/revert.php | 10 ++++-- phpBB/phpbb/console/command/extension/disable.php | 7 ++-- phpBB/phpbb/console/command/extension/enable.php | 7 ++-- phpBB/phpbb/console/command/extension/purge.php | 7 ++-- phpBB/phpbb/console/command/extension/show.php | 28 ++++++---------- .../command/fixup/recalculate_email_hash.php | 15 +++++---- 15 files changed, 100 insertions(+), 83 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/cache/purge.php b/phpBB/phpbb/console/command/cache/purge.php index d0c2ef6f72..1da97624f5 100644 --- a/phpBB/phpbb/console/command/cache/purge.php +++ b/phpBB/phpbb/console/command/cache/purge.php @@ -14,6 +14,7 @@ namespace phpbb\console\command\cache; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class purge extends \phpbb\console\command\command { @@ -84,6 +85,7 @@ class purge extends \phpbb\console\command\command $this->log->add('admin', ANONYMOUS, '', 'LOG_PURGE_CACHE', time(), array()); - $output->writeln($this->user->lang('PURGE_CACHE_SUCCESS')); + $io = new SymfonyStyle($input, $output); + $io->success($this->user->lang('PURGE_CACHE_SUCCESS')); } } diff --git a/phpBB/phpbb/console/command/config/delete.php b/phpBB/phpbb/console/command/config/delete.php index efd276d7e3..a1ccefe286 100644 --- a/phpBB/phpbb/console/command/config/delete.php +++ b/phpBB/phpbb/console/command/config/delete.php @@ -15,6 +15,7 @@ namespace phpbb\console\command\config; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class delete extends command { @@ -47,17 +48,19 @@ class delete extends command */ protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $key = $input->getArgument('key'); if (isset($this->config[$key])) { $this->config->delete($key); - $output->writeln('' . $this->user->lang('CLI_CONFIG_DELETE_SUCCESS', $key) . ''); + $io->success($this->user->lang('CLI_CONFIG_DELETE_SUCCESS', $key)); } else { - $output->writeln('' . $this->user->lang('CLI_CONFIG_NOT_EXISTS', $key) . ''); + $io->error($this->user->lang('CLI_CONFIG_NOT_EXISTS', $key)); } } } diff --git a/phpBB/phpbb/console/command/config/get.php b/phpBB/phpbb/console/command/config/get.php index 9c03b49a3d..b2b824dd12 100644 --- a/phpBB/phpbb/console/command/config/get.php +++ b/phpBB/phpbb/console/command/config/get.php @@ -16,6 +16,7 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class get extends command { @@ -54,6 +55,8 @@ class get extends command */ protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $key = $input->getArgument('key'); if (isset($this->config[$key]) && $input->getOption('no-newline')) @@ -66,7 +69,7 @@ class get extends command } else { - $output->writeln('' . $this->user->lang('CLI_CONFIG_NOT_EXISTS', $key) . ''); + $io->error($this->user->lang('CLI_CONFIG_NOT_EXISTS', $key)); } } } diff --git a/phpBB/phpbb/console/command/config/increment.php b/phpBB/phpbb/console/command/config/increment.php index b4d7438b66..8b3acc1620 100644 --- a/phpBB/phpbb/console/command/config/increment.php +++ b/phpBB/phpbb/console/command/config/increment.php @@ -16,6 +16,7 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class increment extends command { @@ -59,12 +60,14 @@ class increment extends command */ protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $key = $input->getArgument('key'); $increment = $input->getArgument('increment'); $use_cache = !$input->getOption('dynamic'); $this->config->increment($key, $increment, $use_cache); - $output->writeln('' . $this->user->lang('CLI_CONFIG_INCREMENT_SUCCESS', $key) . ''); + $io->success($this->user->lang('CLI_CONFIG_INCREMENT_SUCCESS', $key)); } } diff --git a/phpBB/phpbb/console/command/config/set.php b/phpBB/phpbb/console/command/config/set.php index 695de31013..889fb630c6 100644 --- a/phpBB/phpbb/console/command/config/set.php +++ b/phpBB/phpbb/console/command/config/set.php @@ -16,6 +16,7 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class set extends command { @@ -59,12 +60,14 @@ class set extends command */ protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $key = $input->getArgument('key'); $value = $input->getArgument('value'); $use_cache = !$input->getOption('dynamic'); $this->config->set($key, $value, $use_cache); - $output->writeln('' . $this->user->lang('CLI_CONFIG_SET_SUCCESS', $key) . ''); + $io->success($this->user->lang('CLI_CONFIG_SET_SUCCESS', $key)); } } diff --git a/phpBB/phpbb/console/command/config/set_atomic.php b/phpBB/phpbb/console/command/config/set_atomic.php index e8c69a0885..475d8a9271 100644 --- a/phpBB/phpbb/console/command/config/set_atomic.php +++ b/phpBB/phpbb/console/command/config/set_atomic.php @@ -16,6 +16,7 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class set_atomic extends command { @@ -65,6 +66,8 @@ class set_atomic extends command */ protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $key = $input->getArgument('key'); $old_value = $input->getArgument('old'); $new_value = $input->getArgument('new'); @@ -72,12 +75,12 @@ class set_atomic extends command if ($this->config->set_atomic($key, $old_value, $new_value, $use_cache)) { - $output->writeln('' . $this->user->lang('CLI_CONFIG_SET_SUCCESS', $key) . ''); + $io->success($this->user->lang('CLI_CONFIG_SET_SUCCESS', $key)); return 0; } else { - $output->writeln('' . $this->user->lang('CLI_CONFIG_SET_FAILURE', $key) . ''); + $io->error($this->user->lang('CLI_CONFIG_SET_FAILURE', $key)); return 1; } } diff --git a/phpBB/phpbb/console/command/cron/cron_list.php b/phpBB/phpbb/console/command/cron/cron_list.php index c515fd9e80..0618cee4db 100644 --- a/phpBB/phpbb/console/command/cron/cron_list.php +++ b/phpBB/phpbb/console/command/cron/cron_list.php @@ -14,6 +14,7 @@ namespace phpbb\console\command\cron; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class cron_list extends \phpbb\console\command\command { @@ -55,57 +56,39 @@ class cron_list extends \phpbb\console\command\command */ protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $tasks = $this->cron_manager->get_tasks(); if (empty($tasks)) { - $output->writeln($this->user->lang('CRON_NO_TASKS')); + $io->error($this->user->lang('CRON_NO_TASKS')); return; } - $ready_tasks = array(); - $not_ready_tasks = array(); + $ready_tasks = $not_ready_tasks = array(); foreach ($tasks as $task) { if ($task->is_ready()) { - $ready_tasks[] = $task; + $ready_tasks[] = $task->get_name(); } else { - $not_ready_tasks[] = $task; + $not_ready_tasks[] = $task->get_name(); } } if (!empty($ready_tasks)) { - $output->writeln('' . $this->user->lang('TASKS_READY') . ''); - $this->print_tasks_names($ready_tasks, $output); - } - - if (!empty($ready_tasks) && !empty($not_ready_tasks)) - { - $output->writeln(''); + $io->section($this->user->lang('TASKS_READY')); + $io->listing($ready_tasks); } if (!empty($not_ready_tasks)) { - $output->writeln('' . $this->user->lang('TASKS_NOT_READY') . ''); - $this->print_tasks_names($not_ready_tasks, $output); - } - } - - /** - * Print a list of cron jobs - * - * @param array $tasks A list of task to display - * @param OutputInterface $output An OutputInterface instance - */ - protected function print_tasks_names(array $tasks, OutputInterface $output) - { - foreach ($tasks as $task) - { - $output->writeln($task->get_name()); + $io->section($this->user->lang('TASKS_NOT_READY')); + $io->listing($not_ready_tasks); } } } diff --git a/phpBB/phpbb/console/command/db/list_command.php b/phpBB/phpbb/console/command/db/list_command.php index 708107b592..77f26dd786 100644 --- a/phpBB/phpbb/console/command/db/list_command.php +++ b/phpBB/phpbb/console/command/db/list_command.php @@ -15,6 +15,7 @@ namespace phpbb\console\command\db; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class list_command extends \phpbb\console\command\db\migration_command { @@ -34,6 +35,8 @@ class list_command extends \phpbb\console\command\db\migration_command protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $show_installed = !$input->getOption('available'); $installed = $available = array(); @@ -51,23 +54,28 @@ class list_command extends \phpbb\console\command\db\migration_command if ($show_installed) { - $output->writeln('' . $this->user->lang('CLI_MIGRATIONS_INSTALLED') . $this->user->lang('COLON') . ''); - $output->writeln($installed); + $io->section($this->user->lang('CLI_MIGRATIONS_INSTALLED')); - if (empty($installed)) + if (!empty($installed)) { - $output->writeln($this->user->lang('CLI_MIGRATIONS_EMPTY')); + $io->listing($installed); + } + else + { + $io->text($this->user->lang('CLI_MIGRATIONS_EMPTY')); + $io->newLine(); } - - $output->writeln(''); } - $output->writeln('' . $this->user->lang('CLI_MIGRATIONS_AVAILABLE') . $this->user->lang('COLON') . ''); - $output->writeln($available); - - if (empty($available)) + $io->section($this->user->lang('CLI_MIGRATIONS_AVAILABLE')); + if (!empty($available)) + { + $io->listing($available); + } + else { - $output->writeln($this->user->lang('CLI_MIGRATIONS_EMPTY')); + $io->text($this->user->lang('CLI_MIGRATIONS_EMPTY')); + $io->newLine(); } } } diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php index ae4211f7be..f2cc9142a6 100644 --- a/phpBB/phpbb/console/command/db/migrate.php +++ b/phpBB/phpbb/console/command/db/migrate.php @@ -15,6 +15,7 @@ namespace phpbb\console\command\db; use phpbb\db\output_handler\log_wrapper_migrator_output_handler; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class migrate extends \phpbb\console\command\db\migration_command { @@ -50,6 +51,8 @@ class migrate extends \phpbb\console\command\db\migration_command protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $this->migrator->set_output_handler(new log_wrapper_migrator_output_handler($this->language, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem)); $this->migrator->create_migrations_table(); @@ -66,7 +69,7 @@ class migrate extends \phpbb\console\command\db\migration_command } catch (\phpbb\db\migration\exception $e) { - $output->writeln('' . $e->getLocalisedMessage($this->user) . ''); + $io->error($e->getLocalisedMessage($this->user)); $this->finalise_update(); return 1; } @@ -78,6 +81,6 @@ class migrate extends \phpbb\console\command\db\migration_command } $this->finalise_update(); - $output->writeln($this->user->lang['DATABASE_UPDATE_COMPLETE']); + $io->success($this->language->lang('INLINE_UPDATE_SUCCESSFUL')); } } diff --git a/phpBB/phpbb/console/command/db/revert.php b/phpBB/phpbb/console/command/db/revert.php index 3fa2e17515..7977afc319 100644 --- a/phpBB/phpbb/console/command/db/revert.php +++ b/phpBB/phpbb/console/command/db/revert.php @@ -16,6 +16,7 @@ use phpbb\db\output_handler\log_wrapper_migrator_output_handler; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class revert extends \phpbb\console\command\db\migration_command { @@ -52,6 +53,8 @@ class revert extends \phpbb\console\command\db\migration_command protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $name = str_replace('/', '\\', $input->getArgument('name')); $this->migrator->set_output_handler(new log_wrapper_migrator_output_handler($this->language, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem)); @@ -60,12 +63,12 @@ class revert extends \phpbb\console\command\db\migration_command if (!in_array($name, $this->load_migrations())) { - $output->writeln('' . $this->user->lang('MIGRATION_NOT_VALID', $name) . ''); + $io->error($this->language->lang('MIGRATION_NOT_VALID', $name)); return 1; } else if ($this->migrator->migration_state($name) === false) { - $output->writeln('' . $this->user->lang('MIGRATION_NOT_INSTALLED', $name) . ''); + $io->error($this->language->lang('MIGRATION_NOT_INSTALLED', $name)); return 1; } @@ -78,11 +81,12 @@ class revert extends \phpbb\console\command\db\migration_command } catch (\phpbb\db\migration\exception $e) { - $output->writeln('' . $e->getLocalisedMessage($this->user) . ''); + $io->error($e->getLocalisedMessage($this->user)); $this->finalise_update(); return 1; } $this->finalise_update(); + $io->success($this->language->lang('INLINE_UPDATE_SUCCESSFUL')); } } diff --git a/phpBB/phpbb/console/command/extension/disable.php b/phpBB/phpbb/console/command/extension/disable.php index 1eee16cbd9..d022755753 100644 --- a/phpBB/phpbb/console/command/extension/disable.php +++ b/phpBB/phpbb/console/command/extension/disable.php @@ -15,6 +15,7 @@ namespace phpbb\console\command\extension; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class disable extends command { @@ -33,19 +34,21 @@ class disable extends command protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $name = $input->getArgument('extension-name'); $this->manager->disable($name); $this->manager->load_extensions(); if ($this->manager->is_enabled($name)) { - $output->writeln('' . $this->user->lang('CLI_EXTENSION_DISABLE_FAILURE', $name) . ''); + $io->error($this->user->lang('CLI_EXTENSION_DISABLE_FAILURE', $name)); return 1; } else { $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_DISABLE', time(), array($name)); - $output->writeln('' . $this->user->lang('CLI_EXTENSION_DISABLE_SUCCESS', $name) . ''); + $io->success($this->user->lang('CLI_EXTENSION_DISABLE_SUCCESS', $name)); return 0; } } diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index 59ff11e9b7..14077d688b 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -15,6 +15,7 @@ namespace phpbb\console\command\extension; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class enable extends command { @@ -33,6 +34,8 @@ class enable extends command protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $name = $input->getArgument('extension-name'); $this->manager->enable($name); $this->manager->load_extensions(); @@ -40,12 +43,12 @@ class enable extends command if ($this->manager->is_enabled($name)) { $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($name)); - $output->writeln('' . $this->user->lang('CLI_EXTENSION_ENABLE_SUCCESS', $name) . ''); + $io->success($this->user->lang('CLI_EXTENSION_ENABLE_SUCCESS', $name)); return 0; } else { - $output->writeln('' . $this->user->lang('CLI_EXTENSION_ENABLE_FAILURE', $name) . ''); + $io->error($this->user->lang('CLI_EXTENSION_ENABLE_FAILURE', $name)); return 1; } } diff --git a/phpBB/phpbb/console/command/extension/purge.php b/phpBB/phpbb/console/command/extension/purge.php index 517e9a74c9..25bde503f7 100644 --- a/phpBB/phpbb/console/command/extension/purge.php +++ b/phpBB/phpbb/console/command/extension/purge.php @@ -15,6 +15,7 @@ namespace phpbb\console\command\extension; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class purge extends command { @@ -33,19 +34,21 @@ class purge extends command protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $name = $input->getArgument('extension-name'); $this->manager->purge($name); $this->manager->load_extensions(); if ($this->manager->is_enabled($name)) { - $output->writeln('' . $this->user->lang('CLI_EXTENSION_PURGE_FAILURE', $name) . ''); + $io->error($this->user->lang('CLI_EXTENSION_PURGE_FAILURE', $name)); return 1; } else { $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_PURGE', time(), array($name)); - $output->writeln('' . $this->user->lang('CLI_EXTENSION_PURGE_SUCCESS', $name) . ''); + $io->success($this->user->lang('CLI_EXTENSION_PURGE_SUCCESS', $name)); return 0; } } diff --git a/phpBB/phpbb/console/command/extension/show.php b/phpBB/phpbb/console/command/extension/show.php index f9322034d7..7bad0c0a5a 100644 --- a/phpBB/phpbb/console/command/extension/show.php +++ b/phpBB/phpbb/console/command/extension/show.php @@ -14,6 +14,7 @@ namespace phpbb\console\command\extension; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class show extends command { @@ -27,36 +28,27 @@ class show extends command protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $this->manager->load_extensions(); $all = array_keys($this->manager->all_available()); if (empty($all)) { - $output->writeln('' . $this->user->lang('CLI_EXTENSION_NOT_FOUND') . ''); + $io->note($this->user->lang('CLI_EXTENSION_NOT_FOUND')); return 3; } $enabled = array_keys($this->manager->all_enabled()); - $this->print_extension_list($output, $this->user->lang('CLI_EXTENSIONS_ENABLED') . $this->user->lang('COLON'), $enabled); - - $output->writeln(''); + $io->section($this->user->lang('CLI_EXTENSIONS_ENABLED')); + $io->listing($enabled); $disabled = array_keys($this->manager->all_disabled()); - $this->print_extension_list($output, $this->user->lang('CLI_EXTENSIONS_DISABLED') . $this->user->lang('COLON'), $disabled); - - $output->writeln(''); + $io->section($this->user->lang('CLI_EXTENSIONS_DISABLED')); + $io->listing($disabled); $purged = array_diff($all, $enabled, $disabled); - $this->print_extension_list($output, $this->user->lang('CLI_EXTENSIONS_AVAILABLE') . $this->user->lang('COLON'), $purged); - } - - protected function print_extension_list(OutputInterface $output, $type, array $extensions) - { - $output->writeln("$type"); - - foreach ($extensions as $extension) - { - $output->writeln(" - $extension"); - } + $io->section($this->user->lang('CLI_EXTENSIONS_AVAILABLE')); + $io->listing($purged); } } diff --git a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php index ec4e1b0ee7..043f181e72 100644 --- a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php +++ b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php @@ -14,6 +14,7 @@ namespace phpbb\console\command\fixup; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; class recalculate_email_hash extends \phpbb\console\command\command { @@ -37,6 +38,8 @@ class recalculate_email_hash extends \phpbb\console\command\command protected function execute(InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $sql = 'SELECT user_id, user_email, user_email_hash FROM ' . USERS_TABLE . ' WHERE user_type <> ' . USER_IGNORE . " @@ -59,17 +62,15 @@ class recalculate_email_hash extends \phpbb\console\command\command if ($output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG) { - $output->writeln(sprintf( - 'user_id %d, email %s => %s', - $row['user_id'], - $row['user_email'], - $user_email_hash - )); + $io->table( + array('user_id', 'user_email', 'user_email_hash'), + array(array($row['user_id'], $row['user_email'], $user_email_hash)) + ); } } } $this->db->sql_freeresult($result); - $output->writeln('' . $this->user->lang('CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS') . ''); + $io->success($this->user->lang('CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS')); } } -- cgit v1.2.1 From cbf6d71f6859fd6c036967ed19082f3e54efc328 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 8 Dec 2016 14:25:09 -0800 Subject: [ticket/14895] Fix issues in CLI classes PHPBB3-14895 --- phpBB/phpbb/console/command/cache/purge.php | 4 ++-- phpBB/phpbb/console/command/config/command.php | 2 +- phpBB/phpbb/console/command/config/delete.php | 2 +- phpBB/phpbb/console/command/config/get.php | 2 +- phpBB/phpbb/console/command/config/increment.php | 2 +- phpBB/phpbb/console/command/config/set.php | 2 +- phpBB/phpbb/console/command/cron/cron_list.php | 2 +- phpBB/phpbb/console/command/db/migrate.php | 6 +++--- .../phpbb/console/command/db/migration_command.php | 2 +- phpBB/phpbb/console/command/db/revert.php | 24 +++------------------- phpBB/phpbb/console/command/dev/migration_tips.php | 2 +- .../command/fixup/recalculate_email_hash.php | 2 +- 12 files changed, 17 insertions(+), 35 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/cache/purge.php b/phpBB/phpbb/console/command/cache/purge.php index 1da97624f5..b7a51b2bb4 100644 --- a/phpBB/phpbb/console/command/cache/purge.php +++ b/phpBB/phpbb/console/command/cache/purge.php @@ -40,7 +40,7 @@ class purge extends \phpbb\console\command\command * @param \phpbb\cache\driver\driver_interface $cache Cache instance * @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\auth\auth $auth Auth instance - * @param \phpbb\log\log $log Logger instance + * @param \phpbb\log\log_interface $log Logger instance * @param \phpbb\config\config $config Config instance */ public function __construct(\phpbb\user $user, \phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\auth\auth $auth, \phpbb\log\log_interface $log, \phpbb\config\config $config) @@ -72,7 +72,7 @@ class purge extends \phpbb\console\command\command * @param InputInterface $input An InputInterface instance * @param OutputInterface $output An OutputInterface instance * - * @return null + * @return void */ protected function execute(InputInterface $input, OutputInterface $output) { diff --git a/phpBB/phpbb/console/command/config/command.php b/phpBB/phpbb/console/command/config/command.php index f0ad5d4d19..19f67d3b6c 100644 --- a/phpBB/phpbb/console/command/config/command.php +++ b/phpBB/phpbb/console/command/config/command.php @@ -17,7 +17,7 @@ abstract class command extends \phpbb\console\command\command /** @var \phpbb\config\config */ protected $config; - function __construct(\phpbb\user $user, \phpbb\config\config $config) + public function __construct(\phpbb\user $user, \phpbb\config\config $config) { $this->config = $config; diff --git a/phpBB/phpbb/console/command/config/delete.php b/phpBB/phpbb/console/command/config/delete.php index a1ccefe286..2da0801337 100644 --- a/phpBB/phpbb/console/command/config/delete.php +++ b/phpBB/phpbb/console/command/config/delete.php @@ -43,7 +43,7 @@ class delete extends command * @param InputInterface $input An InputInterface instance * @param OutputInterface $output An OutputInterface instance * - * @return null + * @return void * @see \phpbb\config\config::delete() */ protected function execute(InputInterface $input, OutputInterface $output) diff --git a/phpBB/phpbb/console/command/config/get.php b/phpBB/phpbb/console/command/config/get.php index b2b824dd12..f065787110 100644 --- a/phpBB/phpbb/console/command/config/get.php +++ b/phpBB/phpbb/console/command/config/get.php @@ -50,7 +50,7 @@ class get extends command * @param InputInterface $input An InputInterface instance * @param OutputInterface $output An OutputInterface instance * - * @return null + * @return void * @see \phpbb\config\config::offsetGet() */ protected function execute(InputInterface $input, OutputInterface $output) diff --git a/phpBB/phpbb/console/command/config/increment.php b/phpBB/phpbb/console/command/config/increment.php index 8b3acc1620..647380a0bf 100644 --- a/phpBB/phpbb/console/command/config/increment.php +++ b/phpBB/phpbb/console/command/config/increment.php @@ -55,7 +55,7 @@ class increment extends command * @param InputInterface $input An InputInterface instance * @param OutputInterface $output An OutputInterface instance * - * @return null + * @return void * @see \phpbb\config\config::increment() */ protected function execute(InputInterface $input, OutputInterface $output) diff --git a/phpBB/phpbb/console/command/config/set.php b/phpBB/phpbb/console/command/config/set.php index 889fb630c6..e9f7f8f91e 100644 --- a/phpBB/phpbb/console/command/config/set.php +++ b/phpBB/phpbb/console/command/config/set.php @@ -55,7 +55,7 @@ class set extends command * @param InputInterface $input An InputInterface instance * @param OutputInterface $output An OutputInterface instance * - * @return null + * @return void * @see \phpbb\config\config::set() */ protected function execute(InputInterface $input, OutputInterface $output) diff --git a/phpBB/phpbb/console/command/cron/cron_list.php b/phpBB/phpbb/console/command/cron/cron_list.php index 0618cee4db..8f9d63eda2 100644 --- a/phpBB/phpbb/console/command/cron/cron_list.php +++ b/phpBB/phpbb/console/command/cron/cron_list.php @@ -52,7 +52,7 @@ class cron_list extends \phpbb\console\command\command * @param InputInterface $input An InputInterface instance * @param OutputInterface $output An OutputInterface instance * - * @return null + * @return void */ protected function execute(InputInterface $input, OutputInterface $output) { diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php index f2cc9142a6..4270e2d703 100644 --- a/phpBB/phpbb/console/command/db/migrate.php +++ b/phpBB/phpbb/console/command/db/migrate.php @@ -31,21 +31,21 @@ class migrate extends \phpbb\console\command\db\migration_command /** @var \phpbb\language\language */ protected $language; - function __construct(\phpbb\user $user, \phpbb\language\language $language, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) + public function __construct(\phpbb\user $user, \phpbb\language\language $language, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) { $this->language = $language; $this->log = $log; $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; parent::__construct($user, $migrator, $extension_manager, $config, $cache); - $this->user->add_lang(array('common', 'install', 'migrator')); + $this->language->add_lang(array('common', 'install', 'migrator')); } protected function configure() { $this ->setName('db:migrate') - ->setDescription($this->user->lang('CLI_DESCRIPTION_DB_MIGRATE')) + ->setDescription($this->language->lang('CLI_DESCRIPTION_DB_MIGRATE')) ; } diff --git a/phpBB/phpbb/console/command/db/migration_command.php b/phpBB/phpbb/console/command/db/migration_command.php index b951560588..851f404fab 100644 --- a/phpBB/phpbb/console/command/db/migration_command.php +++ b/phpBB/phpbb/console/command/db/migration_command.php @@ -26,7 +26,7 @@ abstract class migration_command extends \phpbb\console\command\command /** @var \phpbb\cache\service */ protected $cache; - function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache) + public function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache) { $this->migrator = $migrator; $this->extension_manager = $extension_manager; diff --git a/phpBB/phpbb/console/command/db/revert.php b/phpBB/phpbb/console/command/db/revert.php index 7977afc319..3c79d8c554 100644 --- a/phpBB/phpbb/console/command/db/revert.php +++ b/phpBB/phpbb/console/command/db/revert.php @@ -18,35 +18,17 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; -class revert extends \phpbb\console\command\db\migration_command +class revert extends \phpbb\console\command\db\migrate { - /** @var string phpBB root path */ - protected $phpbb_root_path; - - /** @var \phpbb\filesystem\filesystem_interface */ - protected $filesystem; - - /** @var \phpbb\language\language */ - protected $language; - - function __construct(\phpbb\user $user, \phpbb\language\language $language, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) - { - $this->filesystem = $filesystem; - $this->language = $language; - $this->phpbb_root_path = $phpbb_root_path; - parent::__construct($user, $migrator, $extension_manager, $config, $cache); - $this->user->add_lang(array('common', 'migrator')); - } - protected function configure() { $this ->setName('db:revert') - ->setDescription($this->user->lang('CLI_DESCRIPTION_DB_REVERT')) + ->setDescription($this->language->lang('CLI_DESCRIPTION_DB_REVERT')) ->addArgument( 'name', InputArgument::REQUIRED, - $this->user->lang('CLI_MIGRATION_NAME') + $this->language->lang('CLI_MIGRATION_NAME') ) ; } diff --git a/phpBB/phpbb/console/command/dev/migration_tips.php b/phpBB/phpbb/console/command/dev/migration_tips.php index f9047bdac8..2ca0ddde2f 100644 --- a/phpBB/phpbb/console/command/dev/migration_tips.php +++ b/phpBB/phpbb/console/command/dev/migration_tips.php @@ -20,7 +20,7 @@ class migration_tips extends \phpbb\console\command\command /** @var \phpbb\extension\manager */ protected $extension_manager; - function __construct(\phpbb\user $user, \phpbb\extension\manager $extension_manager) + public function __construct(\phpbb\user $user, \phpbb\extension\manager $extension_manager) { $this->extension_manager = $extension_manager; parent::__construct($user); diff --git a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php index 043f181e72..6f7096296d 100644 --- a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php +++ b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php @@ -21,7 +21,7 @@ class recalculate_email_hash extends \phpbb\console\command\command /** @var \phpbb\db\driver\driver_interface */ protected $db; - function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db) + public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db) { $this->db = $db; -- cgit v1.2.1 From 6a5b99b12b1812202843613994480cc6caf93354 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 8 Dec 2016 16:49:50 -0800 Subject: [ticket/14895] Fix broken tests PHPBB3-14895 --- phpBB/phpbb/console/command/cron/cron_list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/cron/cron_list.php b/phpBB/phpbb/console/command/cron/cron_list.php index 8f9d63eda2..ea61e45235 100644 --- a/phpBB/phpbb/console/command/cron/cron_list.php +++ b/phpBB/phpbb/console/command/cron/cron_list.php @@ -81,13 +81,13 @@ class cron_list extends \phpbb\console\command\command if (!empty($ready_tasks)) { - $io->section($this->user->lang('TASKS_READY')); + $io->title($this->user->lang('TASKS_READY')); $io->listing($ready_tasks); } if (!empty($not_ready_tasks)) { - $io->section($this->user->lang('TASKS_NOT_READY')); + $io->title($this->user->lang('TASKS_NOT_READY')); $io->listing($not_ready_tasks); } } -- cgit v1.2.1 From 7fedc19cc422a00ad460f7f9dc41e916c67073ef Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 9 Dec 2016 08:17:51 +0100 Subject: [ticket/14891] Use own proxy instantiator for open_basedir compatibility Also reverted random_compat lib to 1.4.x. PHPBB3-14891 --- phpBB/phpbb/di/container_builder.php | 2 +- phpBB/phpbb/di/proxy_instantiator.php | 74 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 phpBB/phpbb/di/proxy_instantiator.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index b6854673c2..6412ccea46 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -488,7 +488,7 @@ class container_builder protected function create_container(array $extensions) { $container = new ContainerBuilder(new ParameterBag($this->get_core_parameters())); - $container->setProxyInstantiator(new RuntimeInstantiator()); + $container->setProxyInstantiator(new proxy_instantiator($this->get_cache_dir())); $extensions_alias = array(); diff --git a/phpBB/phpbb/di/proxy_instantiator.php b/phpBB/phpbb/di/proxy_instantiator.php new file mode 100644 index 0000000000..28d9972cd7 --- /dev/null +++ b/phpBB/phpbb/di/proxy_instantiator.php @@ -0,0 +1,74 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\di; + +use \bantu\IniGetWrapper\IniGetWrapper; +use ProxyManager\Configuration; +use ProxyManager\Factory\LazyLoadingValueHolderFactory; +use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; +use ProxyManager\Proxy\LazyLoadingInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface; + +/** + * Runtime lazy loading proxy generator extended for allowing use while using + * open_basedir restrictions + * + * Original author: Marco Pivetta + */ +class proxy_instantiator implements InstantiatorInterface +{ + /** + * @var LazyLoadingValueHolderFactory + */ + private $factory; + + /** + * proxy_instantiator constructor + * @param string $cache_dir Cache dir for fall back when using open_basedir + */ + public function __construct($cache_dir) + { + $config = new Configuration(); + + // Prevent trying to write to system temp dir in case of open_basedir + // restrictions being in effect + $ini_wrapper = new IniGetWrapper(); + if ($ini_wrapper->getString('open_basedir') || !file_exists(sys_get_temp_dir())) + { + $config->setProxiesTargetDir($cache_dir); + } + $config->setGeneratorStrategy(new EvaluatingGeneratorStrategy()); + + $this->factory = new LazyLoadingValueHolderFactory($config); + } + + /** + * {@inheritdoc} + */ + public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator) + { + return $this->factory->createProxy( + $definition->getClass(), + function (&$wrappedInstance, LazyLoadingInterface $proxy) use ($realInstantiator) { + $wrappedInstance = call_user_func($realInstantiator); + + $proxy->setProxyInitializer(null); + + return true; + } + ); + } +} -- cgit v1.2.1 From 5f56e9025b276419578507ddbab933183649b47d Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 9 Dec 2016 08:56:16 +0100 Subject: [ticket/14891] Remove unused use statements PHPBB3-14891 --- phpBB/phpbb/di/container_builder.php | 1 - phpBB/phpbb/di/proxy_instantiator.php | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 6412ccea46..4d5f189f12 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -14,7 +14,6 @@ namespace phpbb\di; use phpbb\filesystem\filesystem; -use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator; use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\FileLocator; diff --git a/phpBB/phpbb/di/proxy_instantiator.php b/phpBB/phpbb/di/proxy_instantiator.php index 28d9972cd7..1f51100493 100644 --- a/phpBB/phpbb/di/proxy_instantiator.php +++ b/phpBB/phpbb/di/proxy_instantiator.php @@ -17,7 +17,6 @@ use \bantu\IniGetWrapper\IniGetWrapper; use ProxyManager\Configuration; use ProxyManager\Factory\LazyLoadingValueHolderFactory; use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; -use ProxyManager\Proxy\LazyLoadingInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface; @@ -62,7 +61,7 @@ class proxy_instantiator implements InstantiatorInterface { return $this->factory->createProxy( $definition->getClass(), - function (&$wrappedInstance, LazyLoadingInterface $proxy) use ($realInstantiator) { + function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($realInstantiator) { $wrappedInstance = call_user_func($realInstantiator); $proxy->setProxyInitializer(null); -- cgit v1.2.1 From 6a568719d031544553a9e236e4128c5bfbd42600 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 9 Dec 2016 11:10:28 +0100 Subject: [ticket/14891] Use filesystem classes for checking on tmp dir The cache dir will now also only be used if tmp dir does not exist or if it's not writable. PHPBB3-14891 --- phpBB/phpbb/di/proxy_instantiator.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/proxy_instantiator.php b/phpBB/phpbb/di/proxy_instantiator.php index 1f51100493..47cc7b69c4 100644 --- a/phpBB/phpbb/di/proxy_instantiator.php +++ b/phpBB/phpbb/di/proxy_instantiator.php @@ -13,7 +13,8 @@ namespace phpbb\di; -use \bantu\IniGetWrapper\IniGetWrapper; +use bantu\IniGetWrapper\IniGetWrapper; +use phpbb\filesystem\filesystem; use ProxyManager\Configuration; use ProxyManager\Factory\LazyLoadingValueHolderFactory; use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; @@ -45,7 +46,10 @@ class proxy_instantiator implements InstantiatorInterface // Prevent trying to write to system temp dir in case of open_basedir // restrictions being in effect $ini_wrapper = new IniGetWrapper(); - if ($ini_wrapper->getString('open_basedir') || !file_exists(sys_get_temp_dir())) + $filesystem = new filesystem(); + $tmp_dir = sys_get_temp_dir(); + if ($ini_wrapper->getString('open_basedir') && + (!$filesystem->exists($tmp_dir) || !$filesystem->is_writable($tmp_dir))) { $config->setProxiesTargetDir($cache_dir); } -- cgit v1.2.1 From 90b59bb547844f6913cb459c21d249aec4226d56 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 9 Dec 2016 11:32:13 +0100 Subject: [ticket/14891] Don't rely on sys_get_temp_dir() being available Or actually returning a path. It might also return an empty string or null. PHPBB3-14891 --- phpBB/phpbb/di/proxy_instantiator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/proxy_instantiator.php b/phpBB/phpbb/di/proxy_instantiator.php index 47cc7b69c4..a388e82c0e 100644 --- a/phpBB/phpbb/di/proxy_instantiator.php +++ b/phpBB/phpbb/di/proxy_instantiator.php @@ -47,8 +47,8 @@ class proxy_instantiator implements InstantiatorInterface // restrictions being in effect $ini_wrapper = new IniGetWrapper(); $filesystem = new filesystem(); - $tmp_dir = sys_get_temp_dir(); - if ($ini_wrapper->getString('open_basedir') && + $tmp_dir = (function_exists('sys_get_temp_dir')) ? sys_get_temp_dir() : ''; + if (empty($tmp_dir) || $ini_wrapper->getString('open_basedir') && (!$filesystem->exists($tmp_dir) || !$filesystem->is_writable($tmp_dir))) { $config->setProxiesTargetDir($cache_dir); -- cgit v1.2.1 From 37a3bd131bf82becc436c72a4e01975f4381d4f6 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 9 Dec 2016 19:54:58 +0100 Subject: [ticket/14894] Use correct config name for conflicts archive extension PHPBB3-14894 --- phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php index 7f18950cf6..cf1e4cf4ac 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php @@ -92,7 +92,7 @@ class show_file_status extends task_base // Create archive for merge conflicts if (!empty($merge_conflicts)) { - $compression_method = $this->installer_config->get('compression_method', ''); + $compression_method = $this->installer_config->get('file_update_compression', ''); $conflict_archive = $this->file_updater->init($compression_method); $this->installer_config->set('update_file_conflict_archive', $conflict_archive); -- cgit v1.2.1 From a35c8a924ee824a10468e75df375c870b550d550 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 6 Dec 2016 15:41:58 +0100 Subject: [prep-release-3.2.0-RC2] Add migration file for 3.2.0-RC2 --- phpBB/phpbb/db/migration/data/v320/v320rc2.php | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/v320rc2.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/v320rc2.php b/phpBB/phpbb/db/migration/data/v320/v320rc2.php new file mode 100644 index 0000000000..ec9bb62732 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/v320rc2.php @@ -0,0 +1,40 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +use phpbb\db\migration\migration; + +class v320rc2 extends migration +{ + public function effectively_installed() + { + return version_compare($this->config['version'], '3.2.0-RC2', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\remove_duplicate_migrations', + '\phpbb\db\migration\data\v31x\add_log_time_index', + '\phpbb\db\migration\data\v320\add_help_phpbb', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.0-RC2')), + ); + } +} -- cgit v1.2.1 From 1846b90a33daa1f73586b17a871b28fa349983ee Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 17 Dec 2016 23:20:28 +0100 Subject: [ticket/14920] Force installer to only populate core migrations PHPBB3-14920 --- phpBB/phpbb/install/module/install_finish/task/populate_migrations.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php b/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php index 34541c361e..cebf0f425f 100644 --- a/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php +++ b/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php @@ -70,6 +70,7 @@ class populate_migrations extends \phpbb\install\task_base $migrations = $finder ->core_path('phpbb/db/migration/data/') + ->set_extensions(array()) ->get_classes(); $this->migrator->populate_migrations($migrations); } -- cgit v1.2.1 From b4748a5d1ee31084da7e78f8ffaf5b036f2e5314 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 18 Dec 2016 01:28:51 -0800 Subject: [ticket/14925] Set reparser names in service definitions PHPBB3-14925 --- phpBB/phpbb/console/command/reparser/list_all.php | 4 ++-- phpBB/phpbb/console/command/reparser/reparse.php | 16 +++++--------- phpBB/phpbb/cron/task/text_reparser/reparser.php | 2 +- phpBB/phpbb/textreparser/base.php | 27 ++++++++++++++++++++++- phpBB/phpbb/textreparser/manager.php | 20 +++++++++++++++++ phpBB/phpbb/textreparser/reparser_interface.php | 14 ++++++++++++ 6 files changed, 69 insertions(+), 14 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/reparser/list_all.php b/phpBB/phpbb/console/command/reparser/list_all.php index 028468649d..a79578abf0 100644 --- a/phpBB/phpbb/console/command/reparser/list_all.php +++ b/phpBB/phpbb/console/command/reparser/list_all.php @@ -34,10 +34,10 @@ class list_all extends \phpbb\console\command\command { parent::__construct($user); $this->reparser_names = array(); - foreach ($reparsers as $name => $reparser) + foreach ($reparsers as $reparser) { // Store the names without the "text_reparser." prefix - $this->reparser_names[] = preg_replace('(^text_reparser\\.)', '', $name); + $this->reparser_names[] = $reparser->get_name(); } } diff --git a/phpBB/phpbb/console/command/reparser/reparse.php b/phpBB/phpbb/console/command/reparser/reparse.php index cebeee0919..f285977ea2 100644 --- a/phpBB/phpbb/console/command/reparser/reparse.php +++ b/phpBB/phpbb/console/command/reparser/reparse.php @@ -140,13 +140,9 @@ class reparse extends \phpbb\console\command\command } $name = $input->getArgument('reparser-name'); - if (isset($name)) + if ($name) { - // Allow "post_text" to be an alias for "text_reparser.post_text" - if (!isset($this->reparsers[$name])) - { - $name = 'text_reparser.' . $name; - } + $name = $this->reparser_manager->find_reparser($name); $this->reparse($name); } else @@ -187,7 +183,7 @@ class reparse extends \phpbb\console\command\command /** * Reparse all text handled by given reparser within given range * - * @param string $name Reparser name + * @param string $name Reparser service name */ protected function reparse($name) { @@ -218,10 +214,10 @@ class reparse extends \phpbb\console\command\command return; } - $this->io->section($this->user->lang('CLI_REPARSER_REPARSE_REPARSING', preg_replace('(^text_reparser\\.)', '', $name), $min, $max)); + $this->io->section($this->user->lang('CLI_REPARSER_REPARSE_REPARSING', $reparser->get_name(), $min, $max)); $progress = $this->create_progress_bar($max, $this->io, $this->output, true); - $progress->setMessage($this->user->lang('CLI_REPARSER_REPARSE_REPARSING_START', preg_replace('(^text_reparser\\.)', '', $name))); + $progress->setMessage($this->user->lang('CLI_REPARSER_REPARSE_REPARSING_START', $reparser->get_name())); $progress->start(); // Start from $max and decrement $current by $size until we reach $min @@ -231,7 +227,7 @@ class reparse extends \phpbb\console\command\command $start = max($min, $current + 1 - $size); $end = max($min, $current); - $progress->setMessage($this->user->lang('CLI_REPARSER_REPARSE_REPARSING', preg_replace('(^text_reparser\\.)', '', $name), $start, $end)); + $progress->setMessage($this->user->lang('CLI_REPARSER_REPARSE_REPARSING', $reparser->get_name(), $start, $end)); $reparser->reparse_range($start, $end); $current = $start - 1; diff --git a/phpBB/phpbb/cron/task/text_reparser/reparser.php b/phpBB/phpbb/cron/task/text_reparser/reparser.php index 7099128efd..69392f5ac9 100644 --- a/phpBB/phpbb/cron/task/text_reparser/reparser.php +++ b/phpBB/phpbb/cron/task/text_reparser/reparser.php @@ -81,7 +81,7 @@ class reparser extends \phpbb\cron\task\base */ public function set_reparser($reparser) { - $this->reparser_name = (!isset($this->reparsers[$reparser]) ? 'text_reparser.' : '') . $reparser; + $this->reparser_name = !isset($this->reparsers[$reparser]) ? $this->reparser_manager->find_reparser($reparser) : $reparser; if ($this->resume_data === null) { diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php index afa5ccacad..ef97bc90d5 100644 --- a/phpBB/phpbb/textreparser/base.php +++ b/phpBB/phpbb/textreparser/base.php @@ -15,6 +15,11 @@ namespace phpbb\textreparser; abstract class base implements reparser_interface { + /** + * @var string The reparser name + */ + protected $name; + /** * @var bool Whether to save changes to the database */ @@ -89,6 +94,26 @@ abstract class base implements reparser_interface return $record; } + /** + * Returns the name of the reparser + * + * @return string Name of reparser + */ + public function get_name() + { + return $this->name; + } + + /** + * Sets the name of the reparser + * + * @param string $name The reparser name + */ + public function set_name($name) + { + $this->name = $name; + } + /** * Disable saving changes to the database */ @@ -231,7 +256,7 @@ abstract class base implements reparser_interface $unparsed['enable_flash_bbcode'], $unparsed['enable_quote_bbcode'], $unparsed['enable_url_bbcode'], - 'reparse' + $this->get_name() ); // Save the new text if it has changed and it's not a dry run diff --git a/phpBB/phpbb/textreparser/manager.php b/phpBB/phpbb/textreparser/manager.php index fddd867923..7ca65d708d 100644 --- a/phpBB/phpbb/textreparser/manager.php +++ b/phpBB/phpbb/textreparser/manager.php @@ -125,4 +125,24 @@ class manager $this->schedule($reparser, $interval); } } + + /** + * Finds a reparser by name. + * + * If there is no reparser with the specified name, null is returned. + * + * @param string $name Name of the reparser to look up. + * @return string A reparser service name, or null. + */ + public function find_reparser($name) + { + foreach ($this->reparsers as $service => $reparser) + { + if ($reparser->get_name() == $name) + { + return $service; + } + } + return null; + } } diff --git a/phpBB/phpbb/textreparser/reparser_interface.php b/phpBB/phpbb/textreparser/reparser_interface.php index 9ea1732870..912de10058 100644 --- a/phpBB/phpbb/textreparser/reparser_interface.php +++ b/phpBB/phpbb/textreparser/reparser_interface.php @@ -22,6 +22,20 @@ interface reparser_interface */ public function get_max_id(); + /** + * Returns the name of the reparser + * + * @return string Name of reparser + */ + public function get_name(); + + /** + * Sets the name of the reparser + * + * @param string $name The reparser name + */ + public function set_name($name); + /** * Reparse all records in given range * -- cgit v1.2.1 From 76e9f4dd2d45e8f128e59e1378dfd6778eec9d48 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 18 Dec 2016 09:12:26 -0800 Subject: [ticket/14925] Prefix modes from reparser with text_reparser PHPBB3-14925 --- phpBB/phpbb/textreparser/base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php index ef97bc90d5..27d7bc1f27 100644 --- a/phpBB/phpbb/textreparser/base.php +++ b/phpBB/phpbb/textreparser/base.php @@ -256,7 +256,7 @@ abstract class base implements reparser_interface $unparsed['enable_flash_bbcode'], $unparsed['enable_quote_bbcode'], $unparsed['enable_url_bbcode'], - $this->get_name() + 'text_reparser.' . $this->get_name() ); // Save the new text if it has changed and it's not a dry run -- cgit v1.2.1 From c6aa4a319dd2cfb76a5919fc295ab782529c6646 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 25 Dec 2016 15:04:48 +0100 Subject: [ticket/14934] Use bare PHP functions for checking for tmp dir The symfony methods will cause PHP warnings being thrown. PHPBB3-14934 --- phpBB/phpbb/di/proxy_instantiator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/proxy_instantiator.php b/phpBB/phpbb/di/proxy_instantiator.php index a388e82c0e..f8ef39535b 100644 --- a/phpBB/phpbb/di/proxy_instantiator.php +++ b/phpBB/phpbb/di/proxy_instantiator.php @@ -49,7 +49,7 @@ class proxy_instantiator implements InstantiatorInterface $filesystem = new filesystem(); $tmp_dir = (function_exists('sys_get_temp_dir')) ? sys_get_temp_dir() : ''; if (empty($tmp_dir) || $ini_wrapper->getString('open_basedir') && - (!$filesystem->exists($tmp_dir) || !$filesystem->is_writable($tmp_dir))) + (!@file_exists($tmp_dir) || !@is_writable($tmp_dir))) { $config->setProxiesTargetDir($cache_dir); } -- cgit v1.2.1 From 97b834c3ef6051f11b0f74e60fe445976fb7d681 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 25 Dec 2016 22:19:03 +0100 Subject: [ticket/14934] Do not rely on open basedir being properly set PHPBB3-14934 --- phpBB/phpbb/di/proxy_instantiator.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/proxy_instantiator.php b/phpBB/phpbb/di/proxy_instantiator.php index f8ef39535b..70295a3dec 100644 --- a/phpBB/phpbb/di/proxy_instantiator.php +++ b/phpBB/phpbb/di/proxy_instantiator.php @@ -13,8 +13,6 @@ namespace phpbb\di; -use bantu\IniGetWrapper\IniGetWrapper; -use phpbb\filesystem\filesystem; use ProxyManager\Configuration; use ProxyManager\Factory\LazyLoadingValueHolderFactory; use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; @@ -45,11 +43,8 @@ class proxy_instantiator implements InstantiatorInterface // Prevent trying to write to system temp dir in case of open_basedir // restrictions being in effect - $ini_wrapper = new IniGetWrapper(); - $filesystem = new filesystem(); $tmp_dir = (function_exists('sys_get_temp_dir')) ? sys_get_temp_dir() : ''; - if (empty($tmp_dir) || $ini_wrapper->getString('open_basedir') && - (!@file_exists($tmp_dir) || !@is_writable($tmp_dir))) + if (empty($tmp_dir) || !@file_exists($tmp_dir) || !@is_writable($tmp_dir)) { $config->setProxiesTargetDir($cache_dir); } -- cgit v1.2.1 From 60251cd62367aa8b50e7f717479eea5170b03e98 Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Sun, 20 Nov 2016 19:06:23 +0100 Subject: [ticket/14557] Simplify updating overloaded events for extensions PHPBB3-14557 --- phpBB/phpbb/event/data.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/event/data.php b/phpBB/phpbb/event/data.php index c7365aee35..42080e96d5 100644 --- a/phpBB/phpbb/event/data.php +++ b/phpBB/phpbb/event/data.php @@ -63,4 +63,17 @@ class data extends Event implements \ArrayAccess { unset($this->data[$offset]); } + + /** + * Returns data with updated key in specified offset. + * + * @param string $offset Data array offset + * @param string $key Offset key + * @param mixed $value Value to update + * @return mixed Value of $value + */ + public function update_subarray($offset, $key, $value) + { + return $this->data[$offset][$key] = $value; + } } -- cgit v1.2.1 From f111e70fc3959d979e61e8134fcaefb670b32603 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 27 Dec 2016 21:48:01 +0100 Subject: [ticket/14914] Made emoji scale in size with text PHPBB3-14914 --- phpBB/phpbb/textformatter/s9e/factory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index a310c67359..55149b8e63 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -348,10 +348,10 @@ class factory implements \phpbb\textformatter\cache_interface $configurator->registeredVars['max_img_width'] = 0; // Load the Emoji plugin and modify its tag's template to obey viewsmilies - $configurator->Emoji->setImageSize(18); + $configurator->Emoji->omitImageSize(); $configurator->Emoji->useSVG(); $tag = $configurator->Emoji->getTag(); - $tag->template = '' . str_replace('class="emoji"', 'class="smilies"', $tag->template) . ''; + $tag->template = '' . str_replace('class="emoji"', 'class="emoji smilies"', $tag->template) . ''; /** * Modify the s9e\TextFormatter configurator after the default settings are set -- cgit v1.2.1 From 1eb451d0d49af102ef80e5617765f01c07eebeea Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Tue, 27 Dec 2016 22:28:34 +0100 Subject: [ticket/14557] Don't return $value PHPBB3-14557 --- phpBB/phpbb/event/data.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/event/data.php b/phpBB/phpbb/event/data.php index 42080e96d5..00ebbcefdd 100644 --- a/phpBB/phpbb/event/data.php +++ b/phpBB/phpbb/event/data.php @@ -70,10 +70,9 @@ class data extends Event implements \ArrayAccess * @param string $offset Data array offset * @param string $key Offset key * @param mixed $value Value to update - * @return mixed Value of $value */ public function update_subarray($offset, $key, $value) { - return $this->data[$offset][$key] = $value; + $this->data[$offset][$key] = $value; } } -- cgit v1.2.1 From aa888fab3404ba8544bbcc84ef96b1003979a200 Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Tue, 27 Dec 2016 22:30:47 +0100 Subject: [ticket/14557] Rename $offset to $subarray PHPBB3-14557 --- phpBB/phpbb/event/data.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/event/data.php b/phpBB/phpbb/event/data.php index 00ebbcefdd..276ab027f2 100644 --- a/phpBB/phpbb/event/data.php +++ b/phpBB/phpbb/event/data.php @@ -67,12 +67,12 @@ class data extends Event implements \ArrayAccess /** * Returns data with updated key in specified offset. * - * @param string $offset Data array offset - * @param string $key Offset key - * @param mixed $value Value to update + * @param string $subarray Data array subarray + * @param string $key Subarray key + * @param mixed $value Value to update */ - public function update_subarray($offset, $key, $value) + public function update_subarray($subarray, $key, $value) { - $this->data[$offset][$key] = $value; + $this->data[$subarray][$key] = $value; } } -- cgit v1.2.1 From a4d67c55d97598f29c1f5a1e6a8dec4b1e58df6d Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 3 Jan 2017 22:53:18 +0100 Subject: [ticket/14957] Make sure config_php_file is set before injecting PHPBB3-14957 --- phpBB/phpbb/di/container_builder.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index a314def0f3..ac1a1a1733 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -525,6 +525,11 @@ class container_builder */ protected function inject_dbal_driver() { + if (empty($this->config_php_file)) + { + return; + } + $config_data = $this->config_php_file->get_all(); if (!empty($config_data)) { -- cgit v1.2.1 From 92708b290500d6b8e81b3b9bae2829958486f615 Mon Sep 17 00:00:00 2001 From: javiexin Date: Wed, 4 Jan 2017 00:36:23 +0100 Subject: [ticket/14950] Add possibility to delete a template block Adds a new mode to alter_block_array to allow for the deletion of a certain block of template variables. The selection method is the same as for the other modes for alter_block_array. The passed in vararray is ignored, and an out of bounds index is considered an error. PHPBB3-14944 --- phpBB/phpbb/template/context.php | 42 ++++++++++++++++++++++++++++++++++++++- phpBB/phpbb/template/template.php | 3 ++- 2 files changed, 43 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 4ee48205c8..ce0fef37fc 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -280,10 +280,11 @@ class context * If key is false the position is set to 0 * If key is true the position is set to the last entry * - * @param string $mode Mode to execute (valid modes are 'insert' and 'change') + * @param string $mode Mode to execute (valid modes are 'insert', 'change' and 'delete') * * If insert, the vararray is inserted at the given position (position counting from zero). * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new \value). + * If delete, the vararray is ignored, and the block at the given position (counting from zero) is removed. * * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) @@ -408,6 +409,45 @@ class context return true; } + // Delete Block + if ($mode == 'delete') + { + // If we are exceeding last iteration, do not delete anything + if ($key > sizeof($block)) + { + return false; + } + + // If we are positioned at the end, we remove the last element + if ($key == sizeof($block)) + { + $key--; + } + + // We are deleting the last element in the block, so remove the block + if (sizeof($block) === 1) + { + $block = null; // unset($block); does not work on references + return true; + } + + // Re-position template blocks + for ($i = $key; $i < sizeof($block)-1; $i++) + { + $block[$i] = $block[$i+1]; + $block[$i]['S_ROW_COUNT'] = $block[$i]['S_ROW_NUM'] = $i; + } + + // Remove the last element + unset($block[$i]); + + // Set first and last elements again, in case they were removed + $block[0]['S_FIRST_ROW'] = true; + $block[sizeof($block)-1]['S_LAST_ROW'] = true; + + return true; + } + return false; } diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php index 041ecb12e4..3d8505e204 100644 --- a/phpBB/phpbb/template/template.php +++ b/phpBB/phpbb/template/template.php @@ -160,10 +160,11 @@ interface template * If key is false the position is set to 0 * If key is true the position is set to the last entry * - * @param string $mode Mode to execute (valid modes are 'insert' and 'change') + * @param string $mode Mode to execute (valid modes are 'insert', 'change' and 'delete') * * If insert, the vararray is inserted at the given position (position counting from zero). * If change, the current block gets merged with the vararray (resulting in new \key/value pairs be added and existing keys be replaced by the new \value). + * If delete, the vararray is ignored, and the block at the given position (counting from zero) is removed. * * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) -- cgit v1.2.1 From c6746ab3cd02b4c8a05895c334a3f812a5a5c5b1 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 4 Jan 2017 21:40:46 +0100 Subject: [ticket/14946] Make sure to pass integers to max() PHPBB3-14946 --- phpBB/phpbb/session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index cbe2f02851..cc200b1adc 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -838,7 +838,7 @@ class session $sql = 'SELECT COUNT(session_id) AS sessions FROM ' . SESSIONS_TABLE . ' WHERE session_user_id = ' . (int) $this->data['user_id'] . ' - AND session_time >= ' . (int) ($this->time_now - (max($config['session_length'], $config['form_token_lifetime']))); + AND session_time >= ' . (int) ($this->time_now - (max((int) $config['session_length'], (int) $config['form_token_lifetime']))); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); -- cgit v1.2.1 From 0a68593dd2ac015749e22aae015e5b22ba460c82 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 5 Jan 2017 23:39:30 +0100 Subject: [ticket/14949] Pass full notification array and post data for updating PHPBB3-14949 --- phpBB/phpbb/notification/type/post.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index b9afc6d70a..03221e7c7a 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -456,6 +456,12 @@ class post extends \phpbb\notification\type\base return array(); } - return array('notification_data' => $serialized_data); + $data_array = array_merge(array( + 'post_time' => $post['post_time'], + 'post_id' => $post['post_id'], + 'topic_id' => $post['topic_id'] + ), $this->get_data(false)); + + return $data_array; } } -- cgit v1.2.1 From e0eeea800cb51217e4511c3bcfcba6406d89f314 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 6 Jan 2017 00:57:12 +0100 Subject: [ticket/14961] Add cookie notice as enablable feature Uses Insites cookieconsent v3.0.3: https://cookieconsent.insites.com PHPBB3-14961 --- .../phpbb/db/migration/data/v320/cookie_notice.php | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/cookie_notice.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/cookie_notice.php b/phpBB/phpbb/db/migration/data/v320/cookie_notice.php new file mode 100644 index 0000000000..75cb03b3ef --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/cookie_notice.php @@ -0,0 +1,31 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class cookie_notice extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320rc2', + ); + } + + public function update_data() + { + return array( + array('config.add', array('cookie_notice', false)), + ); + } +} -- cgit v1.2.1 From f82299b8e445cccfc8bad8cbe6505f3fb50d0f8f Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 6 Jan 2017 19:52:17 +0100 Subject: [ticket/14962] Introduces a new helper to check emptyness of bbcode texts PHPBB3-14962 --- phpBB/phpbb/textformatter/s9e/utils.php | 13 +++++++++++++ phpBB/phpbb/textformatter/utils_interface.php | 18 +++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index b317fe4a8d..a9a6d4b892 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -136,4 +136,17 @@ class utils implements \phpbb\textformatter\utils_interface { return \s9e\TextFormatter\Unparser::unparse($xml); } + + /** + * {@inheritdoc} + */ + public function is_empty($text) + { + if ($text === null || $text === '') + { + return true; + } + + return trim($this->unparse($text)) === ''; + } } diff --git a/phpBB/phpbb/textformatter/utils_interface.php b/phpBB/phpbb/textformatter/utils_interface.php index 4810453cd1..4b7392976a 100644 --- a/phpBB/phpbb/textformatter/utils_interface.php +++ b/phpBB/phpbb/textformatter/utils_interface.php @@ -62,10 +62,18 @@ interface utils_interface public function remove_bbcode($text, $bbcode_name, $depth = 0); /** - * Return a parsed text to its original form - * - * @param string $text Parsed text - * @return string Original plain text - */ + * Return a parsed text to its original form + * + * @param string $text Parsed text + * @return string Original plain text + */ public function unparse($text); + + /** + * Return whether or not a parsed text represent an empty text. + * + * @param string $text Parsed text + * @return bool Tue if the original text is empty + */ + public function is_empty($text); } -- cgit v1.2.1 From da8ec61ab2dba1c8bb770932a6983cddbbb1251c Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 7 Jan 2017 11:48:15 +0100 Subject: [prep-release-3.2.0] Update version numbers and add 3.2.0 migration --- phpBB/phpbb/db/migration/data/v320/v320.php | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v320/v320.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/v320.php b/phpBB/phpbb/db/migration/data/v320/v320.php new file mode 100644 index 0000000000..20e741cb8b --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/v320.php @@ -0,0 +1,40 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +use phpbb\db\migration\migration; + +class v320 extends migration +{ + public function effectively_installed() + { + return version_compare($this->config['version'], '3.2.0', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\increase_size_of_emotion', + '\phpbb\db\migration\data\v320\cookie_notice', + ); + + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.0')), + ); + } +} -- cgit v1.2.1 From 9bbd034a4e818fbfef657e04c2a87c889af640af Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 7 Jan 2017 14:44:04 +0100 Subject: [prep-release-3.2.0] Correctly compare extensions version --- phpBB/phpbb/install/module/update_database/task/update_extensions.php | 2 +- phpBB/phpbb/install/module/update_filesystem/task/file_check.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index 13c1591dcd..b66847b243 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -138,7 +138,7 @@ class update_extensions extends task_base $default_update_extensions = []; foreach (self::$default_extensions_update as $version => $extensions) { - if ($this->update_helper->phpbb_version_compare($version_from, $version, '<=')) + if ($this->update_helper->phpbb_version_compare($version_from, $version, '<')) { $default_update_extensions = array_merge($default_update_extensions, $extensions); } diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php index 5b48350e73..47a71eb844 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -123,7 +123,7 @@ class file_check extends task_base $default_update_extensions = []; foreach (\phpbb\install\module\update_database\task\update_extensions::$default_extensions_update as $version => $extensions) { - if ($this->update_helper->phpbb_version_compare($update_info['version']['from'], $version, '>')) + if ($this->update_helper->phpbb_version_compare($update_info['version']['from'], $version, '>=')) { $default_update_extensions = array_merge($default_update_extensions, $extensions); } -- cgit v1.2.1 From 40985de245d7eb5426f8379d93283331d1eab65a Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 8 Jan 2017 10:48:30 +0100 Subject: [ticket/14967] Add cookie notice migration fixing invalid previous one PHPBB3-14967 --- .../db/migration/data/v32x/cookie_notice_p2.php | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v32x/cookie_notice_p2.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/cookie_notice_p2.php b/phpBB/phpbb/db/migration/data/v32x/cookie_notice_p2.php new file mode 100644 index 0000000000..1a83175705 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/cookie_notice_p2.php @@ -0,0 +1,36 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v32x; + +class cookie_notice_p2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320', + ); + } + + public function effectively_installed() + { + return isset($this->config['cookie_notice']); + } + + public function update_data() + { + return array( + array('config.add', array('cookie_notice', '0')), + ); + } +} -- cgit v1.2.1 From c98193a799067896e61b0df615fe49bc48814048 Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 8 Jan 2017 22:16:40 +0700 Subject: [ticket/14971] Fix pagination PHP warning on PHP 7.1 PHPBB3-14971 --- phpBB/phpbb/pagination.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/pagination.php b/phpBB/phpbb/pagination.php index 7a81c25ad2..a5a95b096d 100644 --- a/phpBB/phpbb/pagination.php +++ b/phpBB/phpbb/pagination.php @@ -284,7 +284,7 @@ class pagination */ public function get_on_page($per_page, $start) { - return floor($start / $per_page) + 1; + return floor((int) $start / (int) $per_page) + 1; } /** -- cgit v1.2.1 From 42cf311b2ff513a7d90b903f601157a7a65ba4cf Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 8 Jan 2017 18:31:10 +0100 Subject: =?UTF-8?q?[ticket/14973]=C2=A0Add=20BC=20layer=20for=20\phpbb\db\?= =?UTF-8?q?tools?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHPBB3-14973 --- phpBB/phpbb/db/tools.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 phpBB/phpbb/db/tools.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php new file mode 100644 index 0000000000..4d1b91f7b4 --- /dev/null +++ b/phpBB/phpbb/db/tools.php @@ -0,0 +1,21 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db; + +/** + * @deprecated 3.2.0-dev (To be removed 3.3.0) use \phpbb\db\tools\tools instead + */ +class tools extends \phpbb\db\tools\tools +{ +} -- cgit v1.2.1 From ef215f573e7540bd7f26d936de4108057f9b3225 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 10 Jan 2017 18:04:16 +0100 Subject: [ticket/14985] Decode HTML special chars in plain text columns PHPBB3-14985 --- phpBB/phpbb/textformatter/data_access.php | 50 +++++++++++++++++++++++-------- phpBB/phpbb/textformatter/s9e/factory.php | 3 +- 2 files changed, 38 insertions(+), 15 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/data_access.php b/phpBB/phpbb/textformatter/data_access.php index 2103bf8e60..0d37e62c87 100644 --- a/phpBB/phpbb/textformatter/data_access.php +++ b/phpBB/phpbb/textformatter/data_access.php @@ -81,11 +81,8 @@ class data_access public function get_bbcodes() { $sql = 'SELECT bbcode_match, bbcode_tpl FROM ' . $this->bbcodes_table; - $result = $this->db->sql_query($sql); - $rows = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - return $rows; + return $this->fetch_decoded_rowset($sql, ['bbcode_match']); } /** @@ -101,11 +98,8 @@ class data_access $sql = 'SELECT code, emotion, smiley_url, smiley_width, smiley_height FROM ' . $this->smilies_table . ' ORDER BY display_on_posting DESC'; - $result = $this->db->sql_query($sql); - $rows = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - return $rows; + return $this->fetch_decoded_rowset($sql, ['code', 'emotion', 'smiley_url']); } /** @@ -116,11 +110,8 @@ class data_access protected function get_styles() { $sql = 'SELECT style_id, style_path, style_parent_id, bbcode_bitfield FROM ' . $this->styles_table; - $result = $this->db->sql_query($sql); - $rows = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - return $rows; + return $this->fetch_decoded_rowset($sql); } /** @@ -219,10 +210,43 @@ class data_access public function get_censored_words() { $sql = 'SELECT word, replacement FROM ' . $this->words_table; + + return $this->fetch_decoded_rowset($sql, ['word', 'replacement']); + } + + /** + * Decode HTML special chars in given rowset + * + * @param array $rows Original rowset + * @param array $columns List of columns to decode + * @return array Decoded rowset + */ + protected function decode_rowset(array $rows, array $columns) + { + foreach ($rows as &$row) + { + foreach ($columns as $column) + { + $row[$column] = htmlspecialchars_decode($row[$column]); + } + } + + return $rows; + } + + /** + * Fetch all rows for given query and decode plain text columns + * + * @param string $sql SELECT query + * @param array $columns List of columns to decode + * @return array + */ + protected function fetch_decoded_rowset($sql, array $columns = []) + { $result = $this->db->sql_query($sql); $rows = $this->db->sql_fetchrowset($result); $this->db->sql_freeresult($result); - return $rows; + return $this->decode_rowset($rows, $columns); } } diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 55149b8e63..5cbf2712f7 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -333,8 +333,7 @@ class factory implements \phpbb\textformatter\cache_interface $configurator->plugins->load('Censor', array('tagName' => 'censor:tag')); foreach ($censor as $row) { - // NOTE: words are stored as HTML, we need to decode them to plain text - $configurator->Censor->add(htmlspecialchars_decode($row['word']), htmlspecialchars_decode($row['replacement'])); + $configurator->Censor->add($row['word'], $row['replacement']); } } -- cgit v1.2.1 From 136c74bd1c3d2ef1f22055d9bb14e6f524d41433 Mon Sep 17 00:00:00 2001 From: javiexin Date: Thu, 12 Jan 2017 21:28:58 +0100 Subject: [ticket/14950] Add possibility to delete a template block Adds a new mode to alter_block_array to allow for the deletion of a certain block of template variables. The selection method is the same as for the other modes for alter_block_array. The passed in vararray is ignored, and an out of bounds index is considered an error. Added tests for the new function, fixed. PHPBB3-14950 --- phpBB/phpbb/template/context.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index ce0fef37fc..b909b248aa 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -413,7 +413,7 @@ class context if ($mode == 'delete') { // If we are exceeding last iteration, do not delete anything - if ($key > sizeof($block)) + if ($key > sizeof($block) || $key < 0) { return false; } -- cgit v1.2.1 From 15315ac87a68834e2d560acf62756f628a26da45 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sat, 14 Jan 2017 14:27:38 +0100 Subject: [ticket/15008] Disable emoji when smilies are disabled Will effectively disable emoji shortname and won't replace emoji with images but will not prevent a browser or OS from displaying emoji as images. PHPBB3-15008 --- phpBB/phpbb/textformatter/s9e/parser.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index e2653d60f0..05ddfffa11 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -142,6 +142,7 @@ class parser implements \phpbb\textformatter\parser_interface public function disable_smilies() { $this->parser->disablePlugin('Emoticons'); + $this->parser->disablePlugin('Emoji'); } /** @@ -183,6 +184,7 @@ class parser implements \phpbb\textformatter\parser_interface public function enable_smilies() { $this->parser->enablePlugin('Emoticons'); + $this->parser->enablePlugin('Emoji'); } /** -- cgit v1.2.1 From 02b5873442de90b1d38eced87ecc7f9d780794d2 Mon Sep 17 00:00:00 2001 From: Richard McGirr Date: Sat, 14 Jan 2017 09:18:55 -0500 Subject: [ticket/15010] Fix incorrect use of request https://tracker.phpbb.com/browse/PHPBB3-15010 PHPBB3-15010 --- phpBB/phpbb/profilefields/type/type_date.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/profilefields/type/type_date.php b/phpBB/phpbb/profilefields/type/type_date.php index 414484920b..139ceabeec 100644 --- a/phpBB/phpbb/profilefields/type/type_date.php +++ b/phpBB/phpbb/profilefields/type/type_date.php @@ -72,7 +72,7 @@ class type_date extends type_base 'lang_options' => $field_data['lang_options'], ); - $always_now = $request->variable('always_now', -1); + $always_now = $this->request->variable('always_now', -1); if ($always_now == -1) { $s_checked = ($field_data['field_default_value'] == 'now') ? true : false; -- cgit v1.2.1 From abf7a4f6636d51f02ee9de0a359c5e784465a4ac Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 14 Jan 2017 22:48:24 +0100 Subject: [ticket/15012] Use valid constructor in ftp_file_updater PHPBB3-15012 --- phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php b/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php index 258a035768..5cdc331cbc 100644 --- a/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php +++ b/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php @@ -47,7 +47,7 @@ class ftp_file_updater implements file_updater_interface * @param string $phpbb_root_path * @param string $php_ext */ - public function __constructor(update_helper $update_helper, $phpbb_root_path, $php_ext) + public function __construct(update_helper $update_helper, $phpbb_root_path, $php_ext) { $this->transfer = null; $this->update_helper = $update_helper; -- cgit v1.2.1 From d6e42ec63b54c54b488d3e4112f4cd83062731ba Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Sun, 15 Jan 2017 12:00:36 +0100 Subject: [ticket/15011] Fix 3.2.x merge PHPBB3-15011 --- phpBB/phpbb/extension/metadata_manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index 9ea3c7e541..348b3c2cdf 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -216,7 +216,7 @@ class metadata_manager if (!$this->validate_enable()) { - throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', $name)); + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array($name)); } break; -- cgit v1.2.1 From 0238d850ddf708e54992ae5b11bfc4e20748c171 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 22 Jan 2017 19:36:19 +0100 Subject: [ticket/15015] Use correct explain string for enable email settings PHPBB3-15015 --- phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php index 1cb4f04297..e8a9c971b7 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php @@ -84,7 +84,7 @@ class obtain_email_data extends \phpbb\install\task_base implements \phpbb\insta $email_form = array( 'email_enable' => array( 'label' => 'ENABLE_EMAIL', - 'description' => 'COOKIE_SECURE_EXPLAIN', + 'description' => 'ENABLE_EMAIL_EXPLAIN', 'type' => 'radio', 'options' => array( array( -- cgit v1.2.1 From 9df6ef5735a32fe9c46be3891c6a4ed2308a1d27 Mon Sep 17 00:00:00 2001 From: tas2580 Date: Mon, 16 Jan 2017 19:08:25 +0100 Subject: Use SSL in version check for extension PHPBB3-15025 --- phpBB/phpbb/extension/manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index b2b60aaa9b..ca0ff31d5d 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -589,7 +589,7 @@ class manager $version_helper = new \phpbb\version_helper($this->cache, $this->config, new file_downloader()); $version_helper->set_current_version($meta['version']); - $version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename']); + $version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename'], isset($version_check['ssl']) ? $version_check['ssl'] : false); $version_helper->force_stability($stability); return $updates = $version_helper->get_suggested_updates($force_update, $force_cache); -- cgit v1.2.1 From a03047da5b0f640d4428a74012453df3dfa4f070 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 24 Jan 2017 21:47:20 +0100 Subject: [ticket/15044] Add module task for creating search index during install PHPBB3-15044 --- .../install_data/task/create_search_index.php | 134 +++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 phpBB/phpbb/install/module/install_data/task/create_search_index.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_data/task/create_search_index.php b/phpBB/phpbb/install/module/install_data/task/create_search_index.php new file mode 100644 index 0000000000..8a2f6aa1de --- /dev/null +++ b/phpBB/phpbb/install/module/install_data/task/create_search_index.php @@ -0,0 +1,134 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\module\install_data\task; + +use phpbb\auth\auth; +use phpbb\db\driver\driver_interface; +use phpbb\event\dispatcher; +use phpbb\config\config; +use phpbb\install\helper\container_factory; +use phpbb\language\language; +use phpbb\search\fulltext_native; +use phpbb\user; + +class create_search_index extends \phpbb\install\task_base +{ + /** + * @var auth + */ + protected $auth; + + /** + * @var config + */ + protected $config; + + /** + * @var driver_interface + */ + protected $db; + + /** + * @var dispatcher + */ + protected $phpbb_dispatcher; + + /** + * @var language + */ + protected $language; + + /** + * @var user + */ + protected $user; + + /** + * @var string phpBB root path + */ + protected $phpbb_root_path; + + /** + * @var string PHP file extension + */ + protected $php_ext; + + /** + * Constructor + * + * @param config $config phpBB config + * @param container_factory $container Installer's DI container + * @param string $phpbb_root_path phpBB root path + * @param string $php_ext PHP file extension + */ + public function __construct(config $config, container_factory $container, + $phpbb_root_path, $php_ext) + { + $this->auth = $container->get('auth'); + $this->config = $config; + $this->db = $container->get('dbal.conn'); + $this->language = $container->get('language'); + $this->phpbb_dispatcher = $container->get('dispatcher'); + $this->user = $container->get('user'); + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Make sure fulltext native load update is set + $this->config->set('fulltext_native_load_upd', 1); + + $error = false; + $search = new fulltext_native( + $error, + $this->phpbb_root_path, + $this->php_ext, + $this->auth, + $this->config, + $this->db, + $this->user, + $this->phpbb_dispatcher + ); + + $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id + FROM ' . POSTS_TABLE; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']); + } + $this->db->sql_freeresult($result); + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_CREATE_SEARCH_INDEX'; + } +} -- cgit v1.2.1 From 10dee52c18286524e62b10499120f7f8a4ca99e4 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 24 Jan 2017 21:47:37 +0100 Subject: [ticket/15044] Make sure fulltext native min and max are numbers PHPBB3-15044 --- phpBB/phpbb/search/fulltext_native.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 2071a973e5..73dcfce9a5 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -120,7 +120,7 @@ class fulltext_native extends \phpbb\search\base $this->phpbb_dispatcher = $phpbb_dispatcher; $this->user = $user; - $this->word_length = array('min' => $this->config['fulltext_native_min_chars'], 'max' => $this->config['fulltext_native_max_chars']); + $this->word_length = array('min' => (int) $this->config['fulltext_native_min_chars'], 'max' => (int) $this->config['fulltext_native_max_chars']); /** * Load the UTF tools -- cgit v1.2.1 From f66594bf93ca2604be73ef094555af571a55ea9b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 25 Jan 2017 22:18:29 +0100 Subject: [ticket/15050] Use new file when new file already exists Instead of trying to diff the new file against a pre-existing file, we're just going to use the new file. It's impossible to know whether the pre-existing file is newer or older than the new file. As the system will rely on the files being in the "new" state it's better to simply use the file in "new" state. PHPBB3-15050 --- .../module/update_filesystem/task/diff_files.php | 71 ++++++++++++++-------- 1 file changed, 46 insertions(+), 25 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php index e3e6db6263..0c3658bd44 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php @@ -132,41 +132,62 @@ class diff_files extends task_base $file_contents = array(); // Handle the special case when user created a file with the filename that is now new in the core - $file_contents[0] = (file_exists($old_path . $filename)) ? file_get_contents($old_path . $filename) : ''; + if (file_exists($old_path . $filename)) + { + $file_contents[0] = file_get_contents($old_path . $filename); - $filenames = array( - $this->phpbb_root_path . $filename, - $new_path . $filename - ); + $filenames = array( + $this->phpbb_root_path . $filename, + $new_path . $filename + ); - foreach ($filenames as $file_to_diff) - { - $file_contents[] = file_get_contents($file_to_diff); + foreach ($filenames as $file_to_diff) + { + $file_contents[] = file_get_contents($file_to_diff); + + if ($file_contents[sizeof($file_contents) - 1] === false) + { + $this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); + unset($file_contents); + throw new user_interaction_required_exception(); + } + } - if ($file_contents[sizeof($file_contents) - 1] === false) + $diff = new \diff3($file_contents[0], $file_contents[1], $file_contents[2]); + unset($file_contents); + + // Handle conflicts + if ($diff->get_num_conflicts() !== 0) { - $this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); - unset($file_contents); - throw new user_interaction_required_exception(); + $merge_conflicts[] = $filename; } - } - $diff = new \diff3($file_contents[0], $file_contents[1], $file_contents[2]); - unset($file_contents); + // Save merged output + $this->cache->put( + '_file_' . md5($filename), + base64_encode(implode("\n", $diff->merged_output())) + ); - // Handle conflicts - if ($diff->get_num_conflicts() !== 0) - { - $merge_conflicts[] = $filename; + unset($diff); } + else + { + $new_file_content = file_get_contents($new_path . $filename); - // Save merged output - $this->cache->put( - '_file_' . md5($filename), - base64_encode(implode("\n", $diff->merged_output())) - ); + if ($new_file_content === false) + { + $this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); + unset($new_file_content ); + throw new user_interaction_required_exception(); + } - unset($diff); + // Save new file content to cache + $this->cache->put( + '_file_' . md5($filename), + base64_encode($new_file_content) + ); + unset($new_file_content); + } $progress_count++; $this->iohandler->set_progress('UPDATE_FILE_DIFF', $progress_count); -- cgit v1.2.1 From 66b0fe3b5d982220e593e945a71e95b3283ac4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Wed, 25 Jan 2017 15:48:39 -0500 Subject: [ticket/15047] No index name length check for mssql --- phpBB/phpbb/db/tools/mssql.php | 4 ---- 1 file changed, 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index a132832005..254599444d 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -524,8 +524,6 @@ class mssql extends tools { $statements = array(); - $this->check_index_name_length($table_name, $index_name); - $statements[] = 'CREATE UNIQUE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; return $this->_sql_run_sql($statements); @@ -538,8 +536,6 @@ class mssql extends tools { $statements = array(); - $this->check_index_name_length($table_name, $index_name); - // remove index length $column = preg_replace('#:.*$#', '', $column); -- cgit v1.2.1 From b52ee87df8add5666b6fbe7b30bbe9ede9a30371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Wed, 25 Jan 2017 16:23:59 -0500 Subject: [ticket/15047] Don't attempt to drop primary keys --- phpBB/phpbb/db/tools/mssql.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index 254599444d..d4128f6bcd 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -713,6 +713,7 @@ class mssql extends tools AND cols.object_id = ix.object_id WHERE ix.object_id = object_id('{$table_name}') AND cols.name = '{$column_name}' + AND ix.is_primary_key = 0 AND ix.is_unique = " . ($unique ? '1' : '0'); } -- cgit v1.2.1 From c53054f2b7bb83a5b3ec39f310c8ea37bffa95ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Wed, 25 Jan 2017 16:27:59 -0500 Subject: [ticket/15047] Use brackets due to keyword usage --- phpBB/phpbb/db/tools/mssql.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index d4128f6bcd..3518fb416b 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -477,7 +477,7 @@ class mssql extends tools { $statements = array(); - $statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name; + $statements[] = 'DROP INDEX [' . $table_name . '].[' . $index_name . ']'; return $this->_sql_run_sql($statements); } -- cgit v1.2.1 From fae78b4c011de598e4e05e26ff3129610ae087a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Wed, 25 Jan 2017 16:45:04 -0500 Subject: [ticket/15047] Do not set default for identity cols --- phpBB/phpbb/db/tools/mssql.php | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index 3518fb416b..81e7424136 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -597,7 +597,7 @@ class mssql extends tools // Change the column $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; - if (!empty($column_data['default'])) + if (!empty($column_data['default']) && !$this->mssql_is_column_identity($table_name, $column_name)) { // Add new default value constraint $statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $column_data['default'] . ' FOR [' . $column_name . ']'; @@ -674,6 +674,37 @@ class mssql extends tools return $statements; } + /** + * Checks to see if column is an identity column + * + * Identity columns cannot have defaults set for them. + * + * @param string $table_name + * @param string $column_name + * @return bool true if identity, false if not + */ + protected function mssql_is_column_identity($table_name, $column_name) + { + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT COLUMNPROPERTY(object_id('{$table_name}'), '{$column_name}', 'IsIdentity') AS is_identity"; + } + else + { + $sql = "SELECT is_identity FROM sys.columns + WHERE object_id = object_id('{$table_name}') + AND name = '{$column_name}'"; + } + + $result = $this->db->sql_query($sql); + $is_identity = $this->db->sql_fetchfield('is_identity'); + $this->db->sql_freeresult($result); + + return (bool)$is_identity; + } + /** * Get a list with existing indexes for the column * -- cgit v1.2.1 From 2416a743f51dd5b995bb2bf1d6316f347fa0000e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Thu, 26 Jan 2017 18:44:18 -0500 Subject: [ticket/15047] Reinstate length check for MSSQL 2000 --- phpBB/phpbb/db/tools/mssql.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index 81e7424136..d31aa2ba0b 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -524,6 +524,11 @@ class mssql extends tools { $statements = array(); + if ($this->is_sql_server_2000()) + { + $this->check_index_name_length($table_name, $index_name); + } + $statements[] = 'CREATE UNIQUE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; return $this->_sql_run_sql($statements); @@ -536,6 +541,11 @@ class mssql extends tools { $statements = array(); + if ($this->is_sql_server_2000()) + { + $this->check_index_name_length($table_name, $index_name); + } + // remove index length $column = preg_replace('#:.*$#', '', $column); @@ -702,7 +712,7 @@ class mssql extends tools $is_identity = $this->db->sql_fetchfield('is_identity'); $this->db->sql_freeresult($result); - return (bool)$is_identity; + return (bool) $is_identity; } /** -- cgit v1.2.1 From b5ed02d03c2a28e01e68c9f52fc9044fae2de05c Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 27 Jan 2017 08:40:35 +0100 Subject: [ticket/15050] Remove extra whitespace PHPBB3-15050 --- phpBB/phpbb/install/module/update_filesystem/task/diff_files.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php index 0c3658bd44..1792a3b723 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php @@ -172,9 +172,9 @@ class diff_files extends task_base } else { - $new_file_content = file_get_contents($new_path . $filename); + $new_file_content = file_get_contents($new_path . $filename); - if ($new_file_content === false) + if ($new_file_content === false) { $this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); unset($new_file_content ); -- cgit v1.2.1 From f23d9bf2e0886498a3d9d5bb0a800d663b795e61 Mon Sep 17 00:00:00 2001 From: javiexin Date: Sun, 5 Feb 2017 21:47:31 +0100 Subject: [ticket/15068] Add template vars retrieval from the template object PHPBB3-15068 --- phpBB/phpbb/template/base.php | 29 ++++++++++++++++++++ phpBB/phpbb/template/context.php | 57 +++++++++++++++++++++++++++++++++++++++ phpBB/phpbb/template/template.php | 24 +++++++++++++++++ 3 files changed, 110 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/base.php b/phpBB/phpbb/template/base.php index 9a40702ba8..e84aef6abe 100644 --- a/phpBB/phpbb/template/base.php +++ b/phpBB/phpbb/template/base.php @@ -104,6 +104,27 @@ abstract class base implements template return $this; } + /** + * {@inheritdoc} + */ + public function retrieve_vars(array $vararray) + { + $result = array(); + foreach ($vararray as $varname) + { + $result[$varname] = $this->retrieve_var($varname); + } + return $result; + } + + /** + * {@inheritdoc} + */ + public function retrieve_var($varname) + { + return $this->context->retrieve_var($varname); + } + /** * {@inheritdoc} */ @@ -124,6 +145,14 @@ abstract class base implements template return $this; } + /** + * {@inheritdoc} + */ + public function retrieve_block_vars($blockname, array $vararray) + { + return $this->context->retrieve_block_vars($blockname, $vararray); + } + /** * {@inheritdoc} */ diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 4ee48205c8..0e5f3287aa 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -86,6 +86,17 @@ class context return true; } + /** + * Retreive a single scalar value from a single key. + * + * @param string $varname Variable name + * @return mixed Variable value, or null if not set + */ + public function retrieve_var($varname) + { + return isset($this->rootref[$varname]) ? $this->rootref[$varname] : null; + } + /** * Returns a reference to template data array. * @@ -263,6 +274,52 @@ class context return true; } + /** + * Retrieve key variable pairs from the specified block + * + * @param string $blockname Name of block to retrieve $vararray from + * @param array $vararray An array of variable names + * @return array of hashes with variable name as key and retrieved value or null as value + */ + public function retrieve_block_vars($blockname, array $vararray) + { + // For nested block, $blockcount > 0, for top-level block, $blockcount == 0 + $blocks = explode('.', $blockname); + $blockcount = sizeof($blocks) - 1; + + $block = $this->tpldata; + for ($i = 0; $i <= $blockcount; $i++) + { + if (($pos = strpos($blocks[$i], '[')) !== false) + { + $name = substr($blocks[$i], 0, $pos); + + if (strpos($blocks[$i], '[]') === $pos) + { + $index = sizeof($block[$name]) - 1; + } + else + { + $index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1); + } + } + else + { + $name = $blocks[$i]; + $index = sizeof($block[$name]) - 1; + } + $block = $block[$name]; + $block = $block[$index]; + } + + $result = array(); + foreach ($vararray as $varname) + { + $result[$varname] = isset($block[$varname]) ? $block[$varname] : null; + } + return $result; + } + /** * Change already assigned key variable pair (one-dimensional - single loop entry) * diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php index 041ecb12e4..183999d5f4 100644 --- a/phpBB/phpbb/template/template.php +++ b/phpBB/phpbb/template/template.php @@ -127,6 +127,22 @@ interface template */ public function append_var($varname, $varval); + /** + * Retrieve multiple template values + * + * @param array $vararray An array with variable names + * @return array A hash of variable name => value pairs (value is null if not set) + */ + public function retrieve_vars(array $vararray); + + /** + * Retreive a single scalar value from a single key. + * + * @param string $varname Variable name + * @return mixed Variable value, or null if not set + */ + public function retrieve_var($varname); + /** * Assign key variable pairs from an array to a specified block * @param string $blockname Name of block to assign $vararray to @@ -143,6 +159,14 @@ interface template */ public function assign_block_vars_array($blockname, array $block_vars_array); + /** + * Retrieve variable values from an specified block + * @param string $blockname Name of block to retrieve $vararray from + * @param array $vararray An array with variable names + * @return array A hash of variable name => value pairs (value is null if not set) + */ + public function retrieve_block_vars($blockname, array $vararray); + /** * Change already assigned key variable pair (one-dimensional - single loop entry) * -- cgit v1.2.1 From 5266821e1b5b271e69b00d717b9e9b1f77b65b9f Mon Sep 17 00:00:00 2001 From: javiexin Date: Sun, 12 Feb 2017 14:10:58 +0100 Subject: [ticket/15087] Optimize creation of metadata objects by caching Code for [ticket/14938] Inconsistency in ext_mgr all_available vs is_available for phpbb 3.2. PHPBB3-15087 --- phpBB/phpbb/extension/manager.php | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index b2b60aaa9b..22522d0785 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -431,25 +431,11 @@ class manager if ($file_info->isFile() && $file_info->getFilename() == 'composer.json') { $ext_name = $iterator->getInnerIterator()->getSubPath(); - $composer_file = $iterator->getPath() . '/composer.json'; - - // Ignore the extension if there is no composer.json. - if (!is_readable($composer_file) || !($ext_info = file_get_contents($composer_file))) - { - continue; - } - - $ext_info = json_decode($ext_info, true); $ext_name = str_replace(DIRECTORY_SEPARATOR, '/', $ext_name); - - // Ignore the extension if directory depth is not correct or if the directory structure - // does not match the name value specified in composer.json. - if (substr_count($ext_name, '/') !== 1 || !isset($ext_info['name']) || $ext_name != $ext_info['name']) + if ($this->is_available($ext_name)) { - continue; + $available[$ext_name] = $this->get_extension_path($ext_name, true); } - - $available[$ext_name] = $this->phpbb_root_path . 'ext/' . $ext_name . '/'; } } ksort($available); @@ -527,7 +513,15 @@ class manager */ public function is_available($name) { - return file_exists($this->get_extension_path($name, true)); + $md_manager = $this->create_extension_metadata_manager($name); + try + { + return $md_manager->get_metadata('all') && $md_manager->validate_enable(); + } + catch (\phpbb\extension\exception $e) + { + return false; + } } /** -- cgit v1.2.1 From d3a687df270268b4cbbe3ae0d10e8c4e2ae29235 Mon Sep 17 00:00:00 2001 From: javiexin Date: Sun, 12 Feb 2017 14:39:26 +0100 Subject: [ticket/15087] Optimize creation of metadata objects by caching Code for [ticket/15080] Save unneeded file loads for extension metadata for phpbb 3.2. PHPBB3-15087 --- phpBB/phpbb/extension/metadata_manager.php | 64 ++++++++---------------------- 1 file changed, 16 insertions(+), 48 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index 348b3c2cdf..089f9a7a32 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -81,13 +81,11 @@ class metadata_manager */ public function get_metadata($element = 'all') { - $this->set_metadata_file(); - - // Fetch the metadata - $this->fetch_metadata(); - - // Clean the metadata - $this->clean_metadata_array(); + // Fetch and clean the metadata if not done yet + if ($this->metadata === array()) + { + $this->fetch_metadata_from_file(); + } switch ($element) { @@ -121,52 +119,32 @@ class metadata_manager } /** - * Sets the filepath of the metadata file + * Sets the path of the metadata file, gets its contents and cleans loaded file * * @throws \phpbb\extension\exception */ - private function set_metadata_file() + private function fetch_metadata_from_file() { $ext_filepath = $this->extension_manager->get_extension_path($this->ext_name); - $metadata_filepath = $this->phpbb_root_path . $ext_filepath . 'composer.json'; - - $this->metadata_file = $metadata_filepath; + $this->metadata_file = $this->phpbb_root_path . $ext_filepath . 'composer.json'; if (!file_exists($this->metadata_file)) { throw new \phpbb\extension\exception('FILE_NOT_FOUND', array($this->metadata_file)); } - } - /** - * Gets the contents of the composer.json file - * - * @return bool True if success, throws an exception on failure - * @throws \phpbb\extension\exception - */ - private function fetch_metadata() - { - if (!file_exists($this->metadata_file)) + if (!($file_contents = file_get_contents($this->metadata_file))) { - throw new \phpbb\extension\exception('FILE_NOT_FOUND', array($this->metadata_file)); + throw new \phpbb\extension\exception('FILE_CONTENT_ERR', array($this->metadata_file)); } - else - { - if (!($file_contents = file_get_contents($this->metadata_file))) - { - throw new \phpbb\extension\exception('FILE_CONTENT_ERR', array($this->metadata_file)); - } - if (($metadata = json_decode($file_contents, true)) === null) - { - throw new \phpbb\extension\exception('FILE_JSON_DECODE_ERR', array($this->metadata_file)); - } - - array_walk_recursive($metadata, array($this, 'sanitize_json')); - $this->metadata = $metadata; - - return true; + if (($metadata = json_decode($file_contents, true)) === null) + { + throw new \phpbb\extension\exception('FILE_JSON_DECODE_ERR', array($this->metadata_file)); } + + array_walk_recursive($metadata, array($this, 'sanitize_json')); + $this->metadata = $metadata; } /** @@ -180,16 +158,6 @@ class metadata_manager $value = htmlspecialchars($value); } - /** - * This array handles the cleaning of the array - * - * @return array Contains the cleaned metadata array - */ - private function clean_metadata_array() - { - return $this->metadata; - } - /** * Validate fields * -- cgit v1.2.1 From 2e3d90e05b7b08f6df89b9e3a98b1716d52cf340 Mon Sep 17 00:00:00 2001 From: javiexin Date: Sun, 12 Feb 2017 18:33:06 +0100 Subject: [ticket/15087] Optimize creation of metadata objects by caching Caching is done in ext_manager, and metadata_manager is further simplified by reducing the number of parameters needed. Also, move template output function from metadata_manager to acp_extensions, where it belongs. PHPBB3-15087 --- phpBB/phpbb/console/command/update/check.php | 2 +- phpBB/phpbb/extension/manager.php | 33 +++++++---- phpBB/phpbb/extension/metadata_manager.php | 85 ++++++---------------------- 3 files changed, 38 insertions(+), 82 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php index 1f1cfa25d2..ed8ad79eea 100644 --- a/phpBB/phpbb/console/command/update/check.php +++ b/phpBB/phpbb/console/command/update/check.php @@ -134,7 +134,7 @@ class check extends \phpbb\console\command\command try { $ext_manager = $this->phpbb_container->get('ext.manager'); - $md_manager = $ext_manager->create_extension_metadata_manager($ext_name, null); + $md_manager = $ext_manager->create_extension_metadata_manager($ext_name); $updates_available = $ext_manager->version_check($md_manager, $recheck, false, $stability); $metadata = $md_manager->get_metadata('all'); diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 22522d0785..5cafd9319a 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -152,7 +152,12 @@ class manager */ public function create_extension_metadata_manager($name) { - return new \phpbb\extension\metadata_manager($name, $this->config, $this, $this->phpbb_root_path); + if (!isset($this->extensions[$name]['metadata'])) + { + $metadata = new \phpbb\extension\metadata_manager($name, $this->get_extension_path($name, true)); + $this->extensions[$name]['metadata'] = $metadata; + } + return $this->extensions[$name]['metadata']; } /** @@ -168,7 +173,7 @@ class manager public function enable_step($name) { // ignore extensions that are already enabled - if (isset($this->extensions[$name]) && $this->extensions[$name]['ext_active']) + if ($this->is_enabled($name)) { return false; } @@ -258,7 +263,7 @@ class manager public function disable_step($name) { // ignore extensions that are already disabled - if (!isset($this->extensions[$name]) || !$this->extensions[$name]['ext_active']) + if ($this->is_disabled($name)) { return false; } @@ -336,8 +341,8 @@ class manager */ public function purge_step($name) { - // ignore extensions that do not exist - if (!isset($this->extensions[$name])) + // ignore extensions that are not configured + if (!$this->is_configured($name)) { return false; } @@ -458,8 +463,12 @@ class manager $configured = array(); foreach ($this->extensions as $name => $data) { - $data['ext_path'] = ($phpbb_relative ? $this->phpbb_root_path : '') . $data['ext_path']; - $configured[$name] = $data; + if ($this->is_configured($name)) + { + unset($data['metadata']); + $data['ext_path'] = ($phpbb_relative ? $this->phpbb_root_path : '') . $data['ext_path']; + $configured[$name] = $data; + } } return $configured; } @@ -476,7 +485,7 @@ class manager $enabled = array(); foreach ($this->extensions as $name => $data) { - if ($data['ext_active']) + if ($this->is_enabled($name)) { $enabled[$name] = ($phpbb_relative ? $this->phpbb_root_path : '') . $data['ext_path']; } @@ -497,7 +506,7 @@ class manager $disabled = array(); foreach ($this->extensions as $name => $data) { - if (!$data['ext_active']) + if ($this->is_disabled($name)) { $disabled[$name] = ($phpbb_relative ? $this->phpbb_root_path : '') . $data['ext_path']; } @@ -532,7 +541,7 @@ class manager */ public function is_enabled($name) { - return isset($this->extensions[$name]) && $this->extensions[$name]['ext_active']; + return isset($this->extensions[$name]['ext_active']) && $this->extensions[$name]['ext_active']; } /** @@ -543,7 +552,7 @@ class manager */ public function is_disabled($name) { - return isset($this->extensions[$name]) && !$this->extensions[$name]['ext_active']; + return isset($this->extensions[$name]['ext_active']) && !$this->extensions[$name]['ext_active']; } /** @@ -557,7 +566,7 @@ class manager */ public function is_configured($name) { - return isset($this->extensions[$name]); + return isset($this->extensions[$name]['ext_active']); } /** diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index 089f9a7a32..2dec6944b7 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -18,24 +18,6 @@ namespace phpbb\extension; */ class metadata_manager { - /** - * phpBB Config instance - * @var \phpbb\config\config - */ - protected $config; - - /** - * phpBB Extension Manager - * @var \phpbb\extension\manager - */ - protected $extension_manager; - - /** - * phpBB root path - * @var string - */ - protected $phpbb_root_path; - /** * Name (including vendor) of the extension * @var string @@ -58,19 +40,13 @@ class metadata_manager * Creates the metadata manager * * @param string $ext_name Name (including vendor) of the extension - * @param \phpbb\config\config $config phpBB Config instance - * @param \phpbb\extension\manager $extension_manager An instance of the phpBB extension manager - * @param string $phpbb_root_path Path to the phpbb includes directory. + * @param string $ext_path Path to the extension directory including root path */ - public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, $phpbb_root_path) + public function __construct($ext_name, $ext_path) { - $this->config = $config; - $this->extension_manager = $extension_manager; - $this->phpbb_root_path = $phpbb_root_path; - $this->ext_name = $ext_name; $this->metadata = array(); - $this->metadata_file = ''; + $this->metadata_file = $ext_path . 'composer.json'; } /** @@ -119,15 +95,12 @@ class metadata_manager } /** - * Sets the path of the metadata file, gets its contents and cleans loaded file + * Gets the metadata file contents and cleans loaded file * * @throws \phpbb\extension\exception */ private function fetch_metadata_from_file() { - $ext_filepath = $this->extension_manager->get_extension_path($this->ext_name); - $this->metadata_file = $this->phpbb_root_path . $ext_filepath . 'composer.json'; - if (!file_exists($this->metadata_file)) { throw new \phpbb\extension\exception('FILE_NOT_FOUND', array($this->metadata_file)); @@ -182,9 +155,19 @@ class metadata_manager case 'all': $this->validate('display'); - if (!$this->validate_enable()) + if (!$this->validate_dir()) { - throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array($name)); + throw new \phpbb\extension\exception('EXTENSION_DIR_INVALID'); + } + + if (!$this->validate_require_phpbb()) + { + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('soft-require')); + } + + if (!$this->validate_require_php()) + { + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('require php')); } break; @@ -296,40 +279,4 @@ class metadata_manager return true; } - - /** - * Outputs the metadata into the template - * - * @param \phpbb\template\template $template phpBB Template instance - */ - public function output_template_data(\phpbb\template\template $template) - { - $template->assign_vars(array( - 'META_NAME' => $this->metadata['name'], - 'META_TYPE' => $this->metadata['type'], - 'META_DESCRIPTION' => (isset($this->metadata['description'])) ? $this->metadata['description'] : '', - 'META_HOMEPAGE' => (isset($this->metadata['homepage'])) ? $this->metadata['homepage'] : '', - 'META_VERSION' => (isset($this->metadata['version'])) ? $this->metadata['version'] : '', - 'META_TIME' => (isset($this->metadata['time'])) ? $this->metadata['time'] : '', - 'META_LICENSE' => $this->metadata['license'], - - 'META_REQUIRE_PHP' => (isset($this->metadata['require']['php'])) ? $this->metadata['require']['php'] : '', - 'META_REQUIRE_PHP_FAIL' => !$this->validate_require_php(), - - 'META_REQUIRE_PHPBB' => (isset($this->metadata['extra']['soft-require']['phpbb/phpbb'])) ? $this->metadata['extra']['soft-require']['phpbb/phpbb'] : '', - 'META_REQUIRE_PHPBB_FAIL' => !$this->validate_require_phpbb(), - - 'META_DISPLAY_NAME' => (isset($this->metadata['extra']['display-name'])) ? $this->metadata['extra']['display-name'] : '', - )); - - foreach ($this->metadata['authors'] as $author) - { - $template->assign_block_vars('meta_authors', array( - 'AUTHOR_NAME' => $author['name'], - 'AUTHOR_EMAIL' => (isset($author['email'])) ? $author['email'] : '', - 'AUTHOR_HOMEPAGE' => (isset($author['homepage'])) ? $author['homepage'] : '', - 'AUTHOR_ROLE' => (isset($author['role'])) ? $author['role'] : '', - )); - } - } } -- cgit v1.2.1 From e5eb7025141238a3486a0395c42c55411dafb259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Mon, 13 Feb 2017 14:03:54 -0500 Subject: [ticket/14992] Add indexes to user_notifications table [ticket/14992] Change how index length is checked [ticket/14992] Remove duplicates from user_notifications table [ticket/14992] Add unique index to user_notifications table [ticket/14992] Shorten unique index name [ticket/14992] Shorten another index for user notifications --- .../data/v32x/user_notifications_table_indexes.php | 50 ++++++++++++++++++++ .../user_notifications_table_remove_duplicates.php | 55 ++++++++++++++++++++++ .../v32x/user_notifications_table_unique_index.php | 46 ++++++++++++++++++ phpBB/phpbb/db/tools/tools.php | 14 +++--- 4 files changed, 157 insertions(+), 8 deletions(-) create mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_indexes.php create mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php create mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_indexes.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_indexes.php new file mode 100644 index 0000000000..86a3891b46 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_indexes.php @@ -0,0 +1,50 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v32x; + +class user_notifications_table_indexes extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\cookie_notice_p2', + ); + } + + public function update_schema() + { + return array( + 'add_index' => array( + $this->table_prefix . 'user_notifications' => array( + 'user_id' => array('user_id'), + 'user_id_item_id' => array('user_id', 'item_id'), + 'user_itm_type_id' => array('user_id', 'item_type', 'item_id'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_keys' => array( + $this->table_prefix . 'user_notifications' => array( + 'user_id', + 'user_id_item_id', + 'user_itm_type_id', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php new file mode 100644 index 0000000000..f5f0305fda --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php @@ -0,0 +1,55 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v32x; + +class user_notifications_table_remove_duplicates extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\user_notifications_table_indexes', + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'remove_duplicates'))), + ); + } + + public function remove_duplicates() + { + $insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, $this->table_prefix . 'user_notifications'); + + $sql = "SELECT item_type, item_id, user_id, method, MAX(notify) AS notify + FROM {$this->table_prefix}user_notifications + GROUP BY item_type, item_id, user_id, method + HAVING COUNT(item_type) > 1"; + + $result = $this->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Delete the duplicate entries + $this->sql_query("DELETE FROM {$this->table_prefix}user_notifications + WHERE user_id = {$row['user_id']} + AND item_type = '{$row['item_type']}' + AND method = '{$row['method']}'"); + + // And re-insert as a single one + $insert_buffer->insert($row); + } + $this->db->sql_freeresult($result); + } +} diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php new file mode 100644 index 0000000000..925197a02b --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php @@ -0,0 +1,46 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v32x; + +class user_notifications_table_unique_index extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\user_notifications_table_remove_duplicates', + ); + } + + public function update_schema() + { + return array( + 'add_unique_index' => array( + $this->table_prefix . 'user_notifications' => array( + 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id', 'method'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_keys' => array( + $this->table_prefix . 'user_notifications' => array( + 'itm_usr_mthd', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index 9273d69cd6..4218addb8e 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -1487,17 +1487,17 @@ class tools implements tools_interface { $statements = array(); - $this->check_index_name_length($table_name, $index_name); - switch ($this->sql_layer) { case 'oracle': case 'sqlite3': + $this->check_index_name_length($table_name, $table_name . '_' . $index_name); $statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; break; case 'mysql_40': case 'mysql_41': + $this->check_index_name_length($table_name, $index_name); $statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; break; } @@ -1512,8 +1512,6 @@ class tools implements tools_interface { $statements = array(); - $this->check_index_name_length($table_name, $index_name); - // remove index length unless MySQL4 if ('mysql_40' != $this->sql_layer) { @@ -1524,6 +1522,7 @@ class tools implements tools_interface { case 'oracle': case 'sqlite3': + $this->check_index_name_length($table_name, $table_name . '_' . $index_name); $statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; break; @@ -1539,6 +1538,7 @@ class tools implements tools_interface } // no break case 'mysql_41': + $this->check_index_name_length($table_name, $index_name); $statements[] = 'ALTER TABLE ' . $table_name . ' ADD INDEX ' . $index_name . ' (' . implode(', ', $column) . ')'; break; } @@ -1554,11 +1554,9 @@ class tools implements tools_interface */ protected function check_index_name_length($table_name, $index_name) { - $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) - if (strlen($table_name . $index_name) - strlen($table_prefix) > 24) + if (strlen($index_name) > 30) { - $max_length = strlen($table_prefix) + 24; - trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); + trigger_error("Index name '$index_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); } } -- cgit v1.2.1 From 59ac4a71b6dc53f2edf8bb5c669b14df9ce5544a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Wed, 1 Mar 2017 22:55:13 -0500 Subject: [ticket/14992] Check index name length in a more proper way [ticket/14992] Add indexes to user_notifications table --- .../v32x/user_notifications_table_index_p1.php | 46 ++++++++++++++++++++ .../v32x/user_notifications_table_index_p2.php | 46 ++++++++++++++++++++ .../v32x/user_notifications_table_index_p3.php | 46 ++++++++++++++++++++ .../data/v32x/user_notifications_table_indexes.php | 50 ---------------------- .../user_notifications_table_remove_duplicates.php | 2 +- .../v32x/user_notifications_table_temp_index.php | 46 ++++++++++++++++++++ .../v32x/user_notifications_table_unique_index.php | 7 ++- phpBB/phpbb/db/tools/tools.php | 45 ++++++++++++++----- 8 files changed, 226 insertions(+), 62 deletions(-) create mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p1.php create mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p2.php create mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p3.php delete mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_indexes.php create mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p1.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p1.php new file mode 100644 index 0000000000..93ff31ec6c --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p1.php @@ -0,0 +1,46 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v32x; + +class user_notifications_table_index_p1 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\cookie_notice_p2', + ); + } + + public function update_schema() + { + return array( + 'add_index' => array( + $this->table_prefix . 'user_notifications' => array( + 'user_id' => array('user_id'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_keys' => array( + $this->table_prefix . 'user_notifications' => array( + 'user_id', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p2.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p2.php new file mode 100644 index 0000000000..e492b4e1f8 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p2.php @@ -0,0 +1,46 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v32x; + +class user_notifications_table_index_p2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\user_notifications_table_index_p1', + ); + } + + public function update_schema() + { + return array( + 'add_index' => array( + $this->table_prefix . 'user_notifications' => array( + 'usr_id_itm_id' => array('user_id', 'item_id'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_keys' => array( + $this->table_prefix . 'user_notifications' => array( + 'usr_id_itm_id', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p3.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p3.php new file mode 100644 index 0000000000..1636b3024a --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p3.php @@ -0,0 +1,46 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v32x; + +class user_notifications_table_index_p3 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\user_notifications_table_index_p2', + ); + } + + public function update_schema() + { + return array( + 'add_index' => array( + $this->table_prefix . 'user_notifications' => array( + 'usr_itm_tpe' => array('user_id', 'item_type', 'item_id'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_keys' => array( + $this->table_prefix . 'user_notifications' => array( + 'usr_itm_tpe', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_indexes.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_indexes.php deleted file mode 100644 index 86a3891b46..0000000000 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_indexes.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -namespace phpbb\db\migration\data\v32x; - -class user_notifications_table_indexes extends \phpbb\db\migration\migration -{ - static public function depends_on() - { - return array( - '\phpbb\db\migration\data\v32x\cookie_notice_p2', - ); - } - - public function update_schema() - { - return array( - 'add_index' => array( - $this->table_prefix . 'user_notifications' => array( - 'user_id' => array('user_id'), - 'user_id_item_id' => array('user_id', 'item_id'), - 'user_itm_type_id' => array('user_id', 'item_type', 'item_id'), - ), - ), - ); - } - - public function revert_schema() - { - return array( - 'drop_keys' => array( - $this->table_prefix . 'user_notifications' => array( - 'user_id', - 'user_id_item_id', - 'user_itm_type_id', - ), - ), - ); - } -} diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php index f5f0305fda..50d0642056 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php @@ -18,7 +18,7 @@ class user_notifications_table_remove_duplicates extends \phpbb\db\migration\mig static public function depends_on() { return array( - '\phpbb\db\migration\data\v32x\user_notifications_table_indexes', + '\phpbb\db\migration\data\v32x\user_notifications_table_temp_index', ); } diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php new file mode 100644 index 0000000000..eea44e168c --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php @@ -0,0 +1,46 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v32x; + +class user_notifications_table_temp_index extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\user_notifications_table_index_p3', + ); + } + + public function update_schema() + { + return array( + 'add_index' => array( + $this->table_prefix . 'user_notifications' => array( + 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id', 'method'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_keys' => array( + $this->table_prefix . 'user_notifications' => array( + 'itm_usr_mthd', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php index 925197a02b..51cf90c8a0 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php @@ -25,7 +25,12 @@ class user_notifications_table_unique_index extends \phpbb\db\migration\migratio public function update_schema() { return array( - 'add_unique_index' => array( + 'drop_keys' => array( + $this->table_prefix . 'user_notifications' => array( + 'itm_usr_mthd', + ), + ), + 'add_unique_index' => array( $this->table_prefix . 'user_notifications' => array( 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id', 'method'), ), diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index 4218addb8e..112438fcdd 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -946,7 +946,8 @@ class tools implements tools_interface { case 'oracle': case 'sqlite3': - $row[$col] = substr($row[$col], strlen($table_name) + 1); + $index_name = $this->check_index_name_length($table_name, $table_name . '_' . $index_name, false); + $row[$col] = strpos($row[$col], $table_name) === 0 ? substr($row[$col], strlen($table_name) + 1) : $row[$col]; break; } @@ -1359,12 +1360,14 @@ class tools implements tools_interface { case 'mysql_40': case 'mysql_41': + $index_name = $this->check_index_name_length($table_name, $index_name, false); $statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name; break; case 'oracle': case 'sqlite3': - $statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name; + $index_name = $this->check_index_name_length($table_name, $table_name . '_' . $index_name, false); + $statements[] = 'DROP INDEX ' . $index_name; break; } @@ -1491,13 +1494,13 @@ class tools implements tools_interface { case 'oracle': case 'sqlite3': - $this->check_index_name_length($table_name, $table_name . '_' . $index_name); - $statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; + $index_name = $this->check_index_name_length($table_name, $table_name . '_' . $index_name); + $statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; break; case 'mysql_40': case 'mysql_41': - $this->check_index_name_length($table_name, $index_name); + $index_name = $this->check_index_name_length($table_name, $index_name); $statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; break; } @@ -1522,8 +1525,8 @@ class tools implements tools_interface { case 'oracle': case 'sqlite3': - $this->check_index_name_length($table_name, $table_name . '_' . $index_name); - $statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; + $index_name = $this->check_index_name_length($table_name, $table_name . '_' . $index_name); + $statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; break; case 'mysql_40': @@ -1538,7 +1541,7 @@ class tools implements tools_interface } // no break case 'mysql_41': - $this->check_index_name_length($table_name, $index_name); + $index_name = $this->check_index_name_length($table_name, $index_name); $statements[] = 'ALTER TABLE ' . $table_name . ' ADD INDEX ' . $index_name . ' (' . implode(', ', $column) . ')'; break; } @@ -1551,13 +1554,35 @@ class tools implements tools_interface * * @param string $table_name * @param string $index_name + * @param bool $throw_error + * @return string The index name, shortened if too long */ - protected function check_index_name_length($table_name, $index_name) + protected function check_index_name_length($table_name, $index_name, $throw_error = true) { if (strlen($index_name) > 30) { - trigger_error("Index name '$index_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); + // Try removing the table prefix if it's at the beginning + $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) + if (strpos($index_name, $table_prefix) === 0) + { + $index_name = substr($index_name, strlen($table_prefix) + 1); + return $this->check_index_name_length($table_name, $index_name); + } + + // Try removing the table name then + if (strpos($index_name, $table_name) === 0) + { + $index_name = substr($index_name, strlen($table_name) + 1); + return $this->check_index_name_length($table_name, $index_name); + } + + if ($throw_error) + { + trigger_error("Index name '$index_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); + } } + + return $index_name; } /** -- cgit v1.2.1 From 96a90d3f81c1fcce3834ee72b7d1b9f76aa9354c Mon Sep 17 00:00:00 2001 From: javiexin Date: Thu, 9 Mar 2017 16:05:39 +0100 Subject: [ticket/15068] Add template vars retrieval from the template object Add possibility to retrieve full block of vars PHPBB3-15068 --- phpBB/phpbb/template/context.php | 22 +++++++++++++++++++--- phpBB/phpbb/template/template.php | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 0e5f3287aa..6975409ce3 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -278,7 +278,7 @@ class context * Retrieve key variable pairs from the specified block * * @param string $blockname Name of block to retrieve $vararray from - * @param array $vararray An array of variable names + * @param array $vararray An array of variable names, empty array retrieves all vars * @return array of hashes with variable name as key and retrieved value or null as value */ public function retrieve_block_vars($blockname, array $vararray) @@ -313,9 +313,25 @@ class context } $result = array(); - foreach ($vararray as $varname) + if ($vararray === array()) { - $result[$varname] = isset($block[$varname]) ? $block[$varname] : null; + // The calculated vars that depend on the block position are excluded from the complete block returned results + $excluded_vars = array('S_FIRST_ROW', 'S_LAST_ROW', 'S_BLOCK_NAME', 'S_NUM_ROWS', 'S_ROW_COUNT', 'S_ROW_NUM'); + + foreach ($block as $varname => $varvalue) + { + if ($varname === strtoupper($varname) && !is_array($varvalue) && !in_array($varname, $excluded_vars)) + { + $result[$varname] = $varvalue; + } + } + } + else + { + foreach ($vararray as $varname) + { + $result[$varname] = isset($block[$varname]) ? $block[$varname] : null; + } } return $result; } diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php index 183999d5f4..dbb85dc110 100644 --- a/phpBB/phpbb/template/template.php +++ b/phpBB/phpbb/template/template.php @@ -162,7 +162,7 @@ interface template /** * Retrieve variable values from an specified block * @param string $blockname Name of block to retrieve $vararray from - * @param array $vararray An array with variable names + * @param array $vararray An array with variable names, empty array gets all vars * @return array A hash of variable name => value pairs (value is null if not set) */ public function retrieve_block_vars($blockname, array $vararray); -- cgit v1.2.1 From 891aab05935e9ebc237a83cef0b248998cb5fccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Sat, 11 Mar 2017 20:34:40 +0100 Subject: [ticket/15123] add check before enable or disable extension PHPBB3-15123 --- phpBB/phpbb/console/command/extension/disable.php | 7 +++++++ phpBB/phpbb/console/command/extension/enable.php | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/extension/disable.php b/phpBB/phpbb/console/command/extension/disable.php index d022755753..be5c77a9a0 100644 --- a/phpBB/phpbb/console/command/extension/disable.php +++ b/phpBB/phpbb/console/command/extension/disable.php @@ -37,6 +37,13 @@ class disable extends command $io = new SymfonyStyle($input, $output); $name = $input->getArgument('extension-name'); + + if (!$this->manager->is_enabled($name)) + { + $io->error($this->user->lang('CLI_EXTENSION_ALREADY_DISABLED', $name)); + return 1; + } + $this->manager->disable($name); $this->manager->load_extensions(); diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index 14077d688b..2de7498c71 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -37,6 +37,13 @@ class enable extends command $io = new SymfonyStyle($input, $output); $name = $input->getArgument('extension-name'); + + if ($this->manager->is_enabled($name)) + { + $io->error($this->user->lang('CLI_EXTENSION_ALREADY_ENABLED', $name)); + return 1; + } + $this->manager->enable($name); $this->manager->load_extensions(); -- cgit v1.2.1 From 68c167fe7a5f0c86d97c9c3dda30f66d9df5b032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Sat, 11 Mar 2017 20:39:16 +0100 Subject: [ticket/15123] removed blank spaces PHPBB3-15123 --- phpBB/phpbb/console/command/extension/disable.php | 2 +- phpBB/phpbb/console/command/extension/enable.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/extension/disable.php b/phpBB/phpbb/console/command/extension/disable.php index be5c77a9a0..323f9b6d83 100644 --- a/phpBB/phpbb/console/command/extension/disable.php +++ b/phpBB/phpbb/console/command/extension/disable.php @@ -43,7 +43,7 @@ class disable extends command $io->error($this->user->lang('CLI_EXTENSION_ALREADY_DISABLED', $name)); return 1; } - + $this->manager->disable($name); $this->manager->load_extensions(); diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index 2de7498c71..e6b5f66c7f 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -43,7 +43,7 @@ class enable extends command $io->error($this->user->lang('CLI_EXTENSION_ALREADY_ENABLED', $name)); return 1; } - + $this->manager->enable($name); $this->manager->load_extensions(); -- cgit v1.2.1 From 8994295f2b7d5b2beece7bbd8f7a2861fa15625d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Sat, 11 Mar 2017 23:03:31 +0100 Subject: [ticket/15123] modified language string PHPBB3-15123 --- phpBB/phpbb/console/command/extension/disable.php | 2 +- phpBB/phpbb/console/command/extension/enable.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/extension/disable.php b/phpBB/phpbb/console/command/extension/disable.php index 323f9b6d83..05f7ce9704 100644 --- a/phpBB/phpbb/console/command/extension/disable.php +++ b/phpBB/phpbb/console/command/extension/disable.php @@ -40,7 +40,7 @@ class disable extends command if (!$this->manager->is_enabled($name)) { - $io->error($this->user->lang('CLI_EXTENSION_ALREADY_DISABLED', $name)); + $io->error($this->user->lang('CLI_EXTENSION_DISABLE_DISABLED', $name)); return 1; } diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index e6b5f66c7f..c7c336cdc9 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -40,7 +40,7 @@ class enable extends command if ($this->manager->is_enabled($name)) { - $io->error($this->user->lang('CLI_EXTENSION_ALREADY_ENABLED', $name)); + $io->error($this->user->lang('CLI_EXTENSION_ENABLE_ENABLED', $name)); return 1; } -- cgit v1.2.1 From 9b3609d6f60af328e6681146014453da0af4ee01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Sun, 12 Mar 2017 22:44:18 +0100 Subject: [ticket/15123] modified language strings PHPBB3-15123 --- phpBB/phpbb/console/command/extension/disable.php | 2 +- phpBB/phpbb/console/command/extension/enable.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/extension/disable.php b/phpBB/phpbb/console/command/extension/disable.php index 05f7ce9704..12674c16cb 100644 --- a/phpBB/phpbb/console/command/extension/disable.php +++ b/phpBB/phpbb/console/command/extension/disable.php @@ -40,7 +40,7 @@ class disable extends command if (!$this->manager->is_enabled($name)) { - $io->error($this->user->lang('CLI_EXTENSION_DISABLE_DISABLED', $name)); + $io->error($this->user->lang('CLI_EXTENSION_DISABLED', $name)); return 1; } diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index c7c336cdc9..079e4ce1f6 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -40,7 +40,7 @@ class enable extends command if ($this->manager->is_enabled($name)) { - $io->error($this->user->lang('CLI_EXTENSION_ENABLE_ENABLED', $name)); + $io->error($this->user->lang('CLI_EXTENSION_ENABLED', $name)); return 1; } -- cgit v1.2.1 From 45f0adcd0a4e6c7e43183fe641fa03ef2d90d45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Sun, 12 Mar 2017 22:45:33 +0100 Subject: [ticket/15123] modified return error codes PHPBB3-15123 --- phpBB/phpbb/console/command/extension/disable.php | 2 +- phpBB/phpbb/console/command/extension/enable.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/extension/disable.php b/phpBB/phpbb/console/command/extension/disable.php index 12674c16cb..b2e10fb960 100644 --- a/phpBB/phpbb/console/command/extension/disable.php +++ b/phpBB/phpbb/console/command/extension/disable.php @@ -41,7 +41,7 @@ class disable extends command if (!$this->manager->is_enabled($name)) { $io->error($this->user->lang('CLI_EXTENSION_DISABLED', $name)); - return 1; + return 2; } $this->manager->disable($name); diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index 079e4ce1f6..a8312d5c15 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -41,7 +41,7 @@ class enable extends command if ($this->manager->is_enabled($name)) { $io->error($this->user->lang('CLI_EXTENSION_ENABLED', $name)); - return 1; + return 2; } $this->manager->enable($name); -- cgit v1.2.1 From 568ce32ca85cbf30f510ce7f87ad05c423d48158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Fri, 10 Feb 2017 23:22:14 +0100 Subject: [ticket/15084] fix wrong order of breadcrumbs on module management PHPBB3-15084 --- phpBB/phpbb/module/module_manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/module/module_manager.php b/phpBB/phpbb/module/module_manager.php index 7ae16cdb61..67bac5b33e 100644 --- a/phpBB/phpbb/module/module_manager.php +++ b/phpBB/phpbb/module/module_manager.php @@ -208,7 +208,7 @@ class module_manager WHERE m1.module_class = '" . $this->db->sql_escape($module_class) . "' AND m2.module_class = '" . $this->db->sql_escape($module_class) . "' AND m1.module_id = $module_id - ORDER BY m2.left_id DESC"; + ORDER BY m2.left_id"; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) -- cgit v1.2.1 From d3eb85dd5d04463f78f77d371eddc89ac3985659 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Wed, 15 Mar 2017 02:36:20 +0100 Subject: [ticket/15126] Disable HTML entities in quote helper PHPBB3-15126 --- phpBB/phpbb/textformatter/s9e/quote_helper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/quote_helper.php b/phpBB/phpbb/textformatter/s9e/quote_helper.php index 24109ac8cc..86c33c7591 100644 --- a/phpBB/phpbb/textformatter/s9e/quote_helper.php +++ b/phpBB/phpbb/textformatter/s9e/quote_helper.php @@ -39,8 +39,8 @@ class quote_helper */ public function __construct(\phpbb\user $user, $root_path, $php_ext) { - $this->post_url = append_sid($root_path . 'viewtopic.' . $php_ext, 'p={POST_ID}#p{POST_ID}'); - $this->profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=viewprofile&u={USER_ID}'); + $this->post_url = append_sid($root_path . 'viewtopic.' . $php_ext, 'p={POST_ID}#p{POST_ID}', false); + $this->profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=viewprofile&u={USER_ID}', false); $this->user = $user; } -- cgit v1.2.1 From 018528b0623dab807c478e2bd3345606faa95ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Sun, 19 Mar 2017 17:29:11 +0100 Subject: [ticket/15134] Replace php native functions for filesystem service methods PHPBB3-15134 --- phpBB/phpbb/avatar/driver/upload.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index 2640e1ad1e..93b2353098 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -281,9 +281,13 @@ class upload extends \phpbb\avatar\driver\driver ); extract($this->dispatcher->trigger_event('core.avatar_driver_upload_delete_before', compact($vars))); - if (!sizeof($error) && file_exists($filename)) + if (!sizeof($error) && $this->filesystem->exists($filename)) { - @unlink($filename); + try + { + $this->filesystem->remove($filename); + } + catch(\phpbb\filesystem\exception\filesystem_exception $e) {} } return true; @@ -304,6 +308,6 @@ class upload extends \phpbb\avatar\driver\driver */ protected function can_upload() { - return (file_exists($this->phpbb_root_path . $this->config['avatar_path']) && $this->filesystem->is_writable($this->phpbb_root_path . $this->config['avatar_path']) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')); + return ($this->filesystem->exists($this->phpbb_root_path . $this->config['avatar_path']) && $this->filesystem->is_writable($this->phpbb_root_path . $this->config['avatar_path']) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')); } } -- cgit v1.2.1 From 29ce6e63527e395f086aff7936c8c4f32086956c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Sun, 19 Mar 2017 19:26:08 +0100 Subject: [ticket/15134] Follow coding guideliness PHPBB3-15134 --- phpBB/phpbb/avatar/driver/upload.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index 93b2353098..607db9067c 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -287,7 +287,10 @@ class upload extends \phpbb\avatar\driver\driver { $this->filesystem->remove($filename); } - catch(\phpbb\filesystem\exception\filesystem_exception $e) {} + catch (\phpbb\filesystem\exception\filesystem_exception $e) + { + // Do nothing + } } return true; -- cgit v1.2.1 From 6f1de69bbe8c876ce3c69f7f23d3dcdf65a890b2 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 19 Mar 2017 22:37:19 +0100 Subject: [ticket/15135] Parse language files in acp_extensions instead of md manager PHPBB3-15135 --- phpBB/phpbb/extension/metadata_manager.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index f929433bff..3dc6cdaee6 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -278,7 +278,7 @@ class metadata_manager { if (substr_count($this->ext_name, '/') !== 1 || $this->ext_name != $this->get_metadata('name')) { - throw new \phpbb\extension\exception($this->user->lang('EXTENSION_DIR_INVALID')); + throw new \phpbb\extension\exception('EXTENSION_DIR_INVALID'); } return true; @@ -295,7 +295,7 @@ class metadata_manager { if (!isset($this->metadata['extra']['soft-require']['phpbb/phpbb'])) { - throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'soft-require')); + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', 'soft-require'); } return true; @@ -311,7 +311,7 @@ class metadata_manager { if (!isset($this->metadata['require']['php'])) { - throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'require php')); + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', 'require php'); } return true; -- cgit v1.2.1 From 27ab639fbea160af2a003cb6ce3b2394195da297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Mon, 20 Mar 2017 11:49:34 +0100 Subject: [ticket/15134] Return false if error PHPBB3-15134 --- phpBB/phpbb/avatar/driver/upload.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index 607db9067c..4effa4c410 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -286,14 +286,15 @@ class upload extends \phpbb\avatar\driver\driver try { $this->filesystem->remove($filename); + return true; } catch (\phpbb\filesystem\exception\filesystem_exception $e) { - // Do nothing + // Fail is covered by return statement below } } - return true; + return false; } /** -- cgit v1.2.1 From a975a3573435d56b837c78b9df5ef92dc2b6dba6 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 23 Mar 2017 21:52:35 +0100 Subject: [ticket/15135] Correctly pass exception arguments and add back link again PHPBB3-15135 --- phpBB/phpbb/extension/metadata_manager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index 3dc6cdaee6..6fc6dc9891 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -295,7 +295,7 @@ class metadata_manager { if (!isset($this->metadata['extra']['soft-require']['phpbb/phpbb'])) { - throw new \phpbb\extension\exception('META_FIELD_NOT_SET', 'soft-require'); + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('soft-require')); } return true; @@ -311,7 +311,7 @@ class metadata_manager { if (!isset($this->metadata['require']['php'])) { - throw new \phpbb\extension\exception('META_FIELD_NOT_SET', 'require php'); + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('require php')); } return true; -- cgit v1.2.1 From e7dfdbffb50d8f88d9a5a4c064a853f50d92acf0 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 15 Apr 2017 12:06:03 +0200 Subject: [ticket/15090] Ensure send stats module exists before removing PHPBB3-15090 --- phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php b/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php index afa67fbc58..8fadb4bde4 100644 --- a/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php +++ b/phpBB/phpbb/db/migration/data/v320/add_help_phpbb.php @@ -32,10 +32,9 @@ class add_help_phpbb extends \phpbb\db\migration\migration return array( array('config.add', array('help_send_statistics', true)), array('config.add', array('help_send_statistics_time', 0)), - array('module.remove', array( - 'acp', - false, - 'ACP_SEND_STATISTICS', + array('if', array( + array('module.exists', array('acp', false, 'ACP_SEND_STATISTICS')), + array('module.remove', array('acp', false, 'ACP_SEND_STATISTICS')), )), array('module.add', array( 'acp', -- cgit v1.2.1 From aa37e9b7fc60bd443c6abbcdc3adbf28ae010f32 Mon Sep 17 00:00:00 2001 From: lr94 Date: Sun, 16 Apr 2017 16:28:38 +0200 Subject: [ticket/15176] Add setting for user activity display limit. Up to phpBB 3.2 the maximum number of posts a user must have to have his activity shown is 5000. This limit is hardcoded in functions_display.php. It would be useful if board administrators could choose to disable the limit or to set an higher value. PHPBB3-15176 --- .../data/v32x/load_user_activity_limit.php | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v32x/load_user_activity_limit.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/load_user_activity_limit.php b/phpBB/phpbb/db/migration/data/v32x/load_user_activity_limit.php new file mode 100644 index 0000000000..71bb6c00bf --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/load_user_activity_limit.php @@ -0,0 +1,36 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v32x; + +class load_user_activity_limit extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320', + ); + } + + public function effectively_installed() + { + return isset($this->config['load_user_activity_limit']); + } + + public function update_data() + { + return array( + array('config.add', array('load_user_activity_limit', '5000')), + ); + } +} -- cgit v1.2.1 From 633bbc9c6d42785233ea10165a081c7c32795d1c Mon Sep 17 00:00:00 2001 From: rxu Date: Wed, 11 Jan 2017 22:50:50 +0700 Subject: [ticket/14990] Add core events to the Twig environment PHPBB3-14990 --- phpBB/phpbb/template/twig/environment.php | 32 ++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 179412a2e3..b2b4f990dd 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -32,6 +32,11 @@ class environment extends \Twig_Environment /** @var \phpbb\extension\manager */ protected $extension_manager; + /** + * @var \phpbb\event\dispatcher_interface + */ + protected $phpbb_dispatcher; + /** @var string */ protected $phpbb_root_path; @@ -54,14 +59,16 @@ class environment extends \Twig_Environment * @param \phpbb\extension\manager $extension_manager phpBB extension manager * @param \Twig_LoaderInterface $loader Twig loader interface * @param array $options Array of options to pass to Twig + * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object */ - public function __construct(\phpbb\config\config $phpbb_config, \phpbb\filesystem\filesystem $filesystem, \phpbb\path_helper $path_helper, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array()) + public function __construct(\phpbb\config\config $phpbb_config, \phpbb\filesystem\filesystem $filesystem, \phpbb\path_helper $path_helper, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array(), \phpbb\event\dispatcher_interface $phpbb_dispatcher = null) { $this->phpbb_config = $phpbb_config; $this->filesystem = $filesystem; $this->phpbb_path_helper = $path_helper; $this->extension_manager = $extension_manager; + $this->phpbb_dispatcher = $phpbb_dispatcher; $this->phpbb_root_path = $this->phpbb_path_helper->get_phpbb_root_path(); $this->web_root_path = $this->phpbb_path_helper->get_web_root_path(); @@ -202,8 +209,31 @@ class environment extends \Twig_Environment $context['definition']->set('STYLESHEETS', '__STYLESHEETS_' . $placeholder_salt . '__'); } + /** + * Allow changing the template output stream before rendering + * + * @event core.twig_environment_render_template_before + * @var array $context Array with template variables + * @var string $name The template name + * @since 3.2.1-RC1 + */ + $vars = array('context', 'name'); + extract($this->phpbb_dispatcher->trigger_event('core.twig_environment_render_template_before', compact($vars))); + $output = parent::render($name, $context); + /** + * Allow changing the template output stream after rendering + * + * @event core.twig_environment_render_template_before + * @var array $context Array with template variables + * @var string $name The template name + * @var string $output Rendered template output stream + * @since 3.2.1-RC1 + */ + $vars = array('context', 'name', 'output'); + extract($this->phpbb_dispatcher->trigger_event('core.twig_environment_render_template_after', compact($vars))); + return $this->inject_assets($output, $placeholder_salt); } -- cgit v1.2.1 From 1ea114ca20bd4613420284d7bfc4c92ab0a817b4 Mon Sep 17 00:00:00 2001 From: rxu Date: Wed, 11 Jan 2017 23:53:12 +0700 Subject: [ticket/14990] Fix event name, email parsing, installer and dispatcher calls PHPBB3-14990 --- phpBB/phpbb/template/twig/environment.php | 32 +++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index b2b4f990dd..d9e84b042e 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -32,9 +32,7 @@ class environment extends \Twig_Environment /** @var \phpbb\extension\manager */ protected $extension_manager; - /** - * @var \phpbb\event\dispatcher_interface - */ + /** @var \phpbb\event\dispatcher_interface */ protected $phpbb_dispatcher; /** @var string */ @@ -61,7 +59,7 @@ class environment extends \Twig_Environment * @param array $options Array of options to pass to Twig * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object */ - public function __construct(\phpbb\config\config $phpbb_config, \phpbb\filesystem\filesystem $filesystem, \phpbb\path_helper $path_helper, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array(), \phpbb\event\dispatcher_interface $phpbb_dispatcher = null) + public function __construct(\phpbb\config\config $phpbb_config, \phpbb\filesystem\filesystem $filesystem, \phpbb\path_helper $path_helper, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array(), \phpbb\event\dispatcher_interface $phpbb_dispatcher = null) { $this->phpbb_config = $phpbb_config; @@ -213,26 +211,32 @@ class environment extends \Twig_Environment * Allow changing the template output stream before rendering * * @event core.twig_environment_render_template_before - * @var array $context Array with template variables - * @var string $name The template name + * @var array context Array with template variables + * @var string name The template name * @since 3.2.1-RC1 */ - $vars = array('context', 'name'); - extract($this->phpbb_dispatcher->trigger_event('core.twig_environment_render_template_before', compact($vars))); + if ($this->phpbb_dispatcher) + { + $vars = array('context', 'name'); + extract($this->phpbb_dispatcher->trigger_event('core.twig_environment_render_template_before', compact($vars))); + } $output = parent::render($name, $context); /** * Allow changing the template output stream after rendering * - * @event core.twig_environment_render_template_before - * @var array $context Array with template variables - * @var string $name The template name - * @var string $output Rendered template output stream + * @event core.twig_environment_render_template_after + * @var array context Array with template variables + * @var string name The template name + * @var string output Rendered template output stream * @since 3.2.1-RC1 */ - $vars = array('context', 'name', 'output'); - extract($this->phpbb_dispatcher->trigger_event('core.twig_environment_render_template_after', compact($vars))); + if ($this->phpbb_dispatcher) + { + $vars = array('context', 'name', 'output'); + extract($this->phpbb_dispatcher->trigger_event('core.twig_environment_render_template_after', compact($vars))); + } return $this->inject_assets($output, $placeholder_salt); } -- cgit v1.2.1 From fcc8e155ec309669bebbf6e0370cecfe64c95193 Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 16 Apr 2017 20:53:59 +0700 Subject: [ticket/14990] Move dispatcher object to the front of the options array PHPBB3-14990 --- phpBB/phpbb/template/twig/environment.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index d9e84b042e..ac4b16e457 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -56,10 +56,10 @@ class environment extends \Twig_Environment * @param string $cache_path The path to the cache directory * @param \phpbb\extension\manager $extension_manager phpBB extension manager * @param \Twig_LoaderInterface $loader Twig loader interface - * @param array $options Array of options to pass to Twig * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object + * @param array $options Array of options to pass to Twig */ - public function __construct(\phpbb\config\config $phpbb_config, \phpbb\filesystem\filesystem $filesystem, \phpbb\path_helper $path_helper, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array(), \phpbb\event\dispatcher_interface $phpbb_dispatcher = null) + public function __construct(\phpbb\config\config $phpbb_config, \phpbb\filesystem\filesystem $filesystem, \phpbb\path_helper $path_helper, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, \phpbb\event\dispatcher_interface $phpbb_dispatcher = null, $options = array()) { $this->phpbb_config = $phpbb_config; -- cgit v1.2.1 From e0d13da5f47321c9be16e93e9e1eb98d09626eed Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Mon, 17 Apr 2017 23:06:25 +0200 Subject: [ticket/15180] Adjust \phpbb\di\extension\core::TWIG_OPTIONS_POSITION PHPBB3-15180 --- phpBB/phpbb/di/extension/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 29c0b0e44e..67150f0103 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -24,7 +24,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; */ class core extends Extension { - const TWIG_OPTIONS_POSITION = 6; + const TWIG_OPTIONS_POSITION = 7; /** * Config path -- cgit v1.2.1 From ddcd0f243791ea64373b53f077689df0c46c713a Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Fri, 7 Apr 2017 08:49:56 +0200 Subject: [ticket/15163] Escape curly braces in smilies HTML attributes PHPBB3-15163 --- phpBB/phpbb/textformatter/s9e/factory.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 5cbf2712f7..7719ce5afa 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -311,7 +311,7 @@ class factory implements \phpbb\textformatter\cache_interface { $configurator->Emoticons->set( $row['code'], - '{.}' + '{.}' ); } @@ -441,6 +441,20 @@ class factory implements \phpbb\textformatter\cache_interface ->addParameterByName('parser'); } + /** + * Escape a literal to be used in an HTML attribute in an XSL template + * + * Escapes "HTML special chars" for obvious reasons and curly braces to avoid them + * being interpreted as an attribute value template + * + * @param string $value Original string + * @return string Escaped string + */ + protected function escape_html_attribute($value) + { + return htmlspecialchars(strtr($value, ['{' => '{{', '}' => '}}']), ENT_COMPAT | ENT_XML1, 'UTF-8'); + } + /** * Return the default BBCodes configuration * -- cgit v1.2.1 From 3114e5399c015e4679572102202eee7c99e6d2b5 Mon Sep 17 00:00:00 2001 From: rxu Date: Thu, 27 Apr 2017 15:16:55 +0700 Subject: [ticket/15200] Allow extensions using custom templates for help/faq controllers PHPBB3-15200 --- phpBB/phpbb/help/controller/help.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/help/controller/help.php b/phpBB/phpbb/help/controller/help.php index 9cc3b0c8b4..3bf6fe3098 100644 --- a/phpBB/phpbb/help/controller/help.php +++ b/phpBB/phpbb/help/controller/help.php @@ -64,6 +64,7 @@ class help */ public function handle($mode) { + $template_file = 'faq_body.html'; switch ($mode) { case 'faq': @@ -85,13 +86,16 @@ class help * @var string lang_file Language file containing the help data * @var string ext_name Vendor and extension name where the help * language file can be loaded from + * @var string template_file Template file name * @since 3.1.4-RC1 + * @changed 3.1.11-RC1 Added template_file var */ $vars = array( 'page_title', 'mode', 'lang_file', 'ext_name', + 'template_file', ); extract($this->dispatcher->trigger_event('core.faq_mode_validation', compact($vars))); @@ -113,7 +117,7 @@ class help $this->assign_to_template($this->user->help); make_jumpbox(append_sid("{$this->root_path}viewforum.{$this->php_ext}")); - return $this->helper->render('faq_body.html', $page_title); + return $this->helper->render($template_file, $page_title); } /** -- cgit v1.2.1 From 1e8f4679642627cca3d678611ea72e3837739274 Mon Sep 17 00:00:00 2001 From: javiexin Date: Fri, 28 Apr 2017 23:47:51 +0200 Subject: [ticket/15202] To disable, an extension must be enabled PHPBB3-15202 --- phpBB/phpbb/extension/manager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 00aa2c6826..4b4109bd85 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -262,8 +262,8 @@ class manager */ public function disable_step($name) { - // ignore extensions that are already disabled - if ($this->is_disabled($name)) + // ignore extensions that are not enabled + if (!$this->is_enabled($name)) { return false; } -- cgit v1.2.1 From 1d5f5ccffcfd30a652734485b51066950bbb8a76 Mon Sep 17 00:00:00 2001 From: javiexin Date: Sun, 21 May 2017 12:58:05 +0200 Subject: [ticket/15227] Remove STRIP, as always false PHPBB3-15227 --- phpBB/phpbb/files/filespec.php | 2 +- phpBB/phpbb/passwords/driver/md5_phpbb2.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php index 2ff2a92c83..f1a32ef4a8 100644 --- a/phpBB/phpbb/files/filespec.php +++ b/phpBB/phpbb/files/filespec.php @@ -129,7 +129,7 @@ class filespec $this->class_initialized = true; $this->filename = $upload_ary['tmp_name']; $this->filesize = $upload_ary['size']; - $name = (STRIP) ? stripslashes($upload_ary['name']) : $upload_ary['name']; + $name = $upload_ary['name']; $name = trim(utf8_basename($name)); $this->realname = $this->uploadname = $name; $this->mimetype = $upload_ary['type']; diff --git a/phpBB/phpbb/passwords/driver/md5_phpbb2.php b/phpBB/phpbb/passwords/driver/md5_phpbb2.php index bd8cc51e5a..b38b041d6c 100644 --- a/phpBB/phpbb/passwords/driver/md5_phpbb2.php +++ b/phpBB/phpbb/passwords/driver/md5_phpbb2.php @@ -95,7 +95,7 @@ class md5_phpbb2 extends base // in phpBB2 passwords were used exactly as they were sent, with addslashes applied $password_old_format = isset($_REQUEST['password']) ? (string) $_REQUEST['password'] : ''; - $password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format; + $password_old_format = addslashes($password_old_format); $password_new_format = $this->request->variable('password', '', true); if ($super_globals_disabled) -- cgit v1.2.1 From 11f968e774fed238030f851c4ad90facf86e583f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 21 May 2017 14:18:10 +0200 Subject: [ticket/14992] Shorten index name for user_id and item_id PHPBB3-14992 --- .../db/migration/data/v32x/user_notifications_table_index_p2.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p2.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p2.php index e492b4e1f8..0a471766a0 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p2.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_index_p2.php @@ -27,7 +27,7 @@ class user_notifications_table_index_p2 extends \phpbb\db\migration\migration return array( 'add_index' => array( $this->table_prefix . 'user_notifications' => array( - 'usr_id_itm_id' => array('user_id', 'item_id'), + 'uid_itm_id' => array('user_id', 'item_id'), ), ), ); @@ -38,7 +38,7 @@ class user_notifications_table_index_p2 extends \phpbb\db\migration\migration return array( 'drop_keys' => array( $this->table_prefix . 'user_notifications' => array( - 'usr_id_itm_id', + 'uid_itm_id', ), ), ); -- cgit v1.2.1 From bcc85ab679f6f100d169597990a8ab4138dd3158 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 21 May 2017 15:59:59 +0200 Subject: [ticket/14992] Correctly remove table name and prefix from keys PHPBB3-14992 --- phpBB/phpbb/db/tools/tools.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index 112438fcdd..76036554d2 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -947,7 +947,19 @@ class tools implements tools_interface case 'oracle': case 'sqlite3': $index_name = $this->check_index_name_length($table_name, $table_name . '_' . $index_name, false); - $row[$col] = strpos($row[$col], $table_name) === 0 ? substr($row[$col], strlen($table_name) + 1) : $row[$col]; + $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) + + if (strpos($index_name , $table_name) === false) + { + if (strpos($index_name, $table_prefix) !== false) + { + $row[$col] = substr($row[$col], strlen($table_prefix) + 1); + } + else + { + $row[$col] = substr($row[$col], strlen($table_name) + 1); + } + } break; } -- cgit v1.2.1 From f3c782b3584c1c006e5d3da602ff953381f3e6b9 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 21 May 2017 16:14:11 +0200 Subject: [ticket/14992] Make unit tests run more verbose PHPBB3-14992 --- .../db/migration/data/v32x/user_notifications_table_temp_index.php | 2 +- .../db/migration/data/v32x/user_notifications_table_unique_index.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php index eea44e168c..a6a321dbde 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php @@ -27,7 +27,7 @@ class user_notifications_table_temp_index extends \phpbb\db\migration\migration return array( 'add_index' => array( $this->table_prefix . 'user_notifications' => array( - 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id', 'method'), + 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id'), ), ), ); diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php index 51cf90c8a0..d279af7fec 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php @@ -32,7 +32,7 @@ class user_notifications_table_unique_index extends \phpbb\db\migration\migratio ), 'add_unique_index' => array( $this->table_prefix . 'user_notifications' => array( - 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id', 'method'), + 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id'), ), ), ); -- cgit v1.2.1 From c2711fb6c46b47a4004319b6887d07487baef0dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Tue, 23 May 2017 13:57:28 -0400 Subject: [ticket/14992] Remove temp index migration --- .../user_notifications_table_remove_duplicates.php | 2 +- .../v32x/user_notifications_table_temp_index.php | 46 ---------------------- .../v32x/user_notifications_table_unique_index.php | 5 --- 3 files changed, 1 insertion(+), 52 deletions(-) delete mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php index 50d0642056..371cdf9b3a 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php @@ -18,7 +18,7 @@ class user_notifications_table_remove_duplicates extends \phpbb\db\migration\mig static public function depends_on() { return array( - '\phpbb\db\migration\data\v32x\user_notifications_table_temp_index', + '\phpbb\db\migration\data\v32x\user_notifications_table_index_p3', ); } diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php deleted file mode 100644 index a6a321dbde..0000000000 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -namespace phpbb\db\migration\data\v32x; - -class user_notifications_table_temp_index extends \phpbb\db\migration\migration -{ - static public function depends_on() - { - return array( - '\phpbb\db\migration\data\v32x\user_notifications_table_index_p3', - ); - } - - public function update_schema() - { - return array( - 'add_index' => array( - $this->table_prefix . 'user_notifications' => array( - 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id'), - ), - ), - ); - } - - public function revert_schema() - { - return array( - 'drop_keys' => array( - $this->table_prefix . 'user_notifications' => array( - 'itm_usr_mthd', - ), - ), - ); - } -} diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php index d279af7fec..3145b634c8 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php @@ -25,11 +25,6 @@ class user_notifications_table_unique_index extends \phpbb\db\migration\migratio public function update_schema() { return array( - 'drop_keys' => array( - $this->table_prefix . 'user_notifications' => array( - 'itm_usr_mthd', - ), - ), 'add_unique_index' => array( $this->table_prefix . 'user_notifications' => array( 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id'), -- cgit v1.2.1 From 4c67f65d5db539ffc94259549d1cbf270703d7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Wed, 24 May 2017 16:56:24 -0400 Subject: [ticket/14992] 'method' is needed for the unique index --- .../db/migration/data/v32x/user_notifications_table_unique_index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php index 3145b634c8..157a12472b 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php @@ -27,7 +27,7 @@ class user_notifications_table_unique_index extends \phpbb\db\migration\migratio return array( 'add_unique_index' => array( $this->table_prefix . 'user_notifications' => array( - 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id'), + 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id', 'method'), ), ), ); -- cgit v1.2.1 From a6317dc52dded6eeb3adb174b5d843673b7dbc15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Wed, 24 May 2017 17:34:17 -0400 Subject: [ticket/14992] Reduce notification table col sizes --- ...ser_notifications_table_reduce_column_sizes.php | 48 ++++++++++++++++++++++ .../v32x/user_notifications_table_unique_index.php | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_reduce_column_sizes.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_reduce_column_sizes.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_reduce_column_sizes.php new file mode 100644 index 0000000000..c2efb8fd4f --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_reduce_column_sizes.php @@ -0,0 +1,48 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v32x; + +class user_notifications_table_reduce_column_sizes extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\user_notifications_table_remove_duplicates', + ); + } + + public function update_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'user_notifications' => array( + 'item_type' => array('VCHAR:165', ''), + 'method' => array('VCHAR:165', ''), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'user_notifications' => array( + 'item_type' => array('VCHAR:255', ''), + 'method' => array('VCHAR:255', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php index 157a12472b..e46c231b7b 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php @@ -18,7 +18,7 @@ class user_notifications_table_unique_index extends \phpbb\db\migration\migratio static public function depends_on() { return array( - '\phpbb\db\migration\data\v32x\user_notifications_table_remove_duplicates', + '\phpbb\db\migration\data\v32x\user_notifications_table_reduce_column_sizes', ); } -- cgit v1.2.1 From 9029a925aaf56427748cd119749f97ac77932b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Col=C3=B3n?= Date: Thu, 25 May 2017 14:06:10 -0400 Subject: [ticket/14992] Add temp index migration for removing duplicates --- ...ser_notifications_table_reduce_column_sizes.php | 2 +- .../user_notifications_table_remove_duplicates.php | 2 +- .../v32x/user_notifications_table_temp_index.php | 46 ++++++++++++++++++++++ .../v32x/user_notifications_table_unique_index.php | 7 +++- 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_reduce_column_sizes.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_reduce_column_sizes.php index c2efb8fd4f..e0a107782e 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_reduce_column_sizes.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_reduce_column_sizes.php @@ -18,7 +18,7 @@ class user_notifications_table_reduce_column_sizes extends \phpbb\db\migration\m static public function depends_on() { return array( - '\phpbb\db\migration\data\v32x\user_notifications_table_remove_duplicates', + '\phpbb\db\migration\data\v32x\user_notifications_table_index_p3', ); } diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php index 371cdf9b3a..50d0642056 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_remove_duplicates.php @@ -18,7 +18,7 @@ class user_notifications_table_remove_duplicates extends \phpbb\db\migration\mig static public function depends_on() { return array( - '\phpbb\db\migration\data\v32x\user_notifications_table_index_p3', + '\phpbb\db\migration\data\v32x\user_notifications_table_temp_index', ); } diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php new file mode 100644 index 0000000000..80256a0e0a --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_temp_index.php @@ -0,0 +1,46 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v32x; + +class user_notifications_table_temp_index extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\user_notifications_table_reduce_column_sizes', + ); + } + + public function update_schema() + { + return array( + 'add_index' => array( + $this->table_prefix . 'user_notifications' => array( + 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id', 'method'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_keys' => array( + $this->table_prefix . 'user_notifications' => array( + 'itm_usr_mthd', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php index e46c231b7b..51cf90c8a0 100644 --- a/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php +++ b/phpBB/phpbb/db/migration/data/v32x/user_notifications_table_unique_index.php @@ -18,13 +18,18 @@ class user_notifications_table_unique_index extends \phpbb\db\migration\migratio static public function depends_on() { return array( - '\phpbb\db\migration\data\v32x\user_notifications_table_reduce_column_sizes', + '\phpbb\db\migration\data\v32x\user_notifications_table_remove_duplicates', ); } public function update_schema() { return array( + 'drop_keys' => array( + $this->table_prefix . 'user_notifications' => array( + 'itm_usr_mthd', + ), + ), 'add_unique_index' => array( $this->table_prefix . 'user_notifications' => array( 'itm_usr_mthd' => array('item_type', 'item_id', 'user_id', 'method'), -- cgit v1.2.1 From e2c0356f34bed706ca1dcf8fc0844109d764b935 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 3 Jun 2017 10:01:28 +0200 Subject: [ticket/15179] Replace spaces with a tab PHPBB3-15179 --- phpBB/phpbb/console/command/update/check.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php index ed8ad79eea..9ced651e8b 100644 --- a/phpBB/phpbb/console/command/update/check.php +++ b/phpBB/phpbb/console/command/update/check.php @@ -325,7 +325,7 @@ class check extends \phpbb\console\command\command $io->table([ $this->language->lang('VERSION'), $this->language->lang('ANNOUNCEMENT_TOPIC'), - $this->language->lang('DOWNLOAD_LATEST'), + $this->language->lang('DOWNLOAD_LATEST'), ], $rows); } } -- cgit v1.2.1 From 27b2d91713dfbad1e87ae83336559d22ac9ec399 Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Thu, 4 May 2017 17:27:41 +0200 Subject: [ticket/15217] Add core.user_format_date_override event PHPBB3-15217 --- phpBB/phpbb/user.php | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index 305510851c..d4097f53ee 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -588,6 +588,7 @@ class user extends \phpbb\session */ function format_date($gmepoch, $format = false, $forcedate = false) { + global $phpbb_dispatcher; static $utc; if (!isset($utc)) @@ -595,10 +596,34 @@ class user extends \phpbb\session $utc = new \DateTimeZone('UTC'); } - $time = new $this->datetime($this, '@' . (int) $gmepoch, $utc); - $time->setTimezone($this->timezone); + $format_date_override = false; + $function_arguments = func_get_args(); + /** + * Execute code and/or override format_date() + * + * To override the format_date() function generated value + * set $format_date_override to new return value + * + * @event core.user_format_date_override + * @var DateTimeZone utc Is DateTimeZone in UTC + * @var array function_arguments is array comprising a function's argument list + * @var string format_date_override Shall we return custom format (string) or not (false) + * @since 3.2.1-RC1 + */ + $vars = array('utc', 'function_arguments', 'format_date_override'); + extract($phpbb_dispatcher->trigger_event('core.user_format_date_override', compact($vars))); - return $time->format($format, $forcedate); + if (!$format_date_override) + { + $time = new $this->datetime($this, '@' . (int) $gmepoch, $utc); + $time->setTimezone($this->timezone); + + return $time->format($format, $forcedate); + } + else + { + return $format_date_override; + } } /** -- cgit v1.2.1 From e6bdba7da1069c71e9b3c148266d0cd90b6cf1a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Thu, 15 Jun 2017 16:56:19 +0200 Subject: [ticket/15243] Check permissions before installing with SQLite PHPBB3-15243 --- phpBB/phpbb/install/helper/database.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php index 192f0a3654..59b86a8ca7 100644 --- a/phpBB/phpbb/install/helper/database.php +++ b/phpBB/phpbb/install/helper/database.php @@ -336,6 +336,15 @@ class database ); } + // Check if SQLite database is writable + if ($dbms_info['SCHEMA'] === 'sqlite' + && (!$this->filesystem->is_writable($dbhost) || !$this->filesystem->is_writable(pathinfo($dbhost, PATHINFO_DIRNAME)))) + { + $errors[] = array( + 'title' =>'INST_ERR_DB_NO_WRITABLE', + ); + } + // Try to connect to db if (is_array($db->sql_connect($dbhost, $dbuser, $dbpass, $dbname, $dbport, false, true))) { -- cgit v1.2.1 From 8a8d435ed4c065084fc35e48e8926b5e0ffb2ccc Mon Sep 17 00:00:00 2001 From: rxu Date: Fri, 26 May 2017 20:36:32 +0700 Subject: [ticket/15238] Add console command to fix forums/modules left/right IDs PHPBB3-15238 --- .../console/command/fixup/fix_left_right_ids.php | 108 +++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 phpBB/phpbb/console/command/fixup/fix_left_right_ids.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php b/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php new file mode 100644 index 0000000000..7b932fa179 --- /dev/null +++ b/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php @@ -0,0 +1,108 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ +namespace phpbb\console\command\fixup; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; + +class fix_left_right_ids extends \phpbb\console\command\command +{ + /** @var \phpbb\user */ + protected $user; + + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\cache\driver\driver_interface */ + protected $cache; + + public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache) + { + $this->user = $user; + $this->db = $db; + $this->cache = $cache; + + parent::__construct($user); + } + + protected function configure() + { + $this + ->setName('fixup:fix-left-right-ids') + ->setDescription($this->user->lang('CLI_DESCRIPTION_FIX_LEFT_RIGHT_IDS')) + ; + } + + /** + * The code is mainly borrowed from Support toolkit for phpBB Olympus + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + + $changes_made = false; + + // Fix Left/Right IDs for the modules table + $result = $this->db->sql_query('SELECT DISTINCT(module_class) FROM ' . MODULES_TABLE); + while ($row = $this->db->sql_fetchrow($result)) + { + $i = 1; + $where = array('module_class = \'' . $row['module_class'] .'\''); + $changes_made = (($this->fixem($i, 'module_id', MODULES_TABLE, 0, $where)) || $changes_made) ? true : false; + } + $this->db->sql_freeresult($result); + + // Fix the Left/Right IDs for the forums table + $i = 1; + $changes_made = (($this->fixem($i, 'forum_id', FORUMS_TABLE)) || $changes_made) ? true : false; + + $this->cache->purge(); + + $io->success($this->user->lang('CLI_FIXUP_FIX_LEFT_RIGHT_IDS_SUCCESS')); + } + + function fixem(&$i, $pkey, $table, $parent_id = 0, $where = array()) + { + $changes_made = false; + $sql = 'SELECT * FROM ' . $table . ' + WHERE parent_id = ' . (int) $parent_id . + ((!empty($where)) ? ' AND ' . implode(' AND ', $where) : '') . ' + ORDER BY left_id ASC'; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Update the left_id for this module + if ($row['left_id'] != $i) + { + $this->db->sql_query('UPDATE ' . $table . ' SET ' . $this->db->sql_build_array('UPDATE', array('left_id' => $i)) . " WHERE $pkey = {$row[$pkey]}"); + $changes_made = true; + } + $i++; + + // Go through children and update their left/right IDs + $changes_made = (($this->fixem($i, $pkey, $table, $row[$pkey], $where)) || $changes_made) ? true : false; + + // Update the right_id for the module + if ($row['right_id'] != $i) + { + $this->db->sql_query('UPDATE ' . $table . ' SET ' . $this->db->sql_build_array('UPDATE', array('right_id' => $i)) . " WHERE $pkey = {$row[$pkey]}"); + $changes_made = true; + } + $i++; + } + $this->db->sql_freeresult($result); + + return $changes_made; + } +} -- cgit v1.2.1 From b0ed1f2388be4246ceddb2f9ec4c10963a18c073 Mon Sep 17 00:00:00 2001 From: rxu Date: Tue, 6 Jun 2017 00:42:05 +0700 Subject: [ticket/15238] Code cleanup, add docblocks PHPBB3-15238 --- .../console/command/fixup/fix_left_right_ids.php | 50 +++++++++++++++++----- 1 file changed, 39 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php b/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php index 7b932fa179..601a27118b 100644 --- a/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php +++ b/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php @@ -27,6 +27,13 @@ class fix_left_right_ids extends \phpbb\console\command\command /** @var \phpbb\cache\driver\driver_interface */ protected $cache; + /** + * Constructor + * + * @param \phpbb\user $user User instance + * @param \phpbb\db\driver\driver_interface $db Database connection + * @param \phpbb\cache\driver\driver_interface $cache Cache instance + */ public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache) { $this->user = $user; @@ -36,6 +43,9 @@ class fix_left_right_ids extends \phpbb\console\command\command parent::__construct($user); } + /** + * {@inheritdoc} + */ protected function configure() { $this @@ -45,34 +55,52 @@ class fix_left_right_ids extends \phpbb\console\command\command } /** + * Executes the command fixup:fix-left-right-ids. + * + * Repairs the tree structure of the forums and modules. * The code is mainly borrowed from Support toolkit for phpBB Olympus + * + * @param InputInterface $input An InputInterface instance + * @param OutputInterface $output An OutputInterface instance + * + * @return void */ protected function execute(InputInterface $input, OutputInterface $output) { $io = new SymfonyStyle($input, $output); - $changes_made = false; - // Fix Left/Right IDs for the modules table $result = $this->db->sql_query('SELECT DISTINCT(module_class) FROM ' . MODULES_TABLE); while ($row = $this->db->sql_fetchrow($result)) { $i = 1; - $where = array('module_class = \'' . $row['module_class'] .'\''); - $changes_made = (($this->fixem($i, 'module_id', MODULES_TABLE, 0, $where)) || $changes_made) ? true : false; + $where = array("module_class = '" . $this->db->sql_escape($row['module_class']) . "'"); + $this->fix_ids_tree($i, 'module_id', MODULES_TABLE, 0, $where); } $this->db->sql_freeresult($result); // Fix the Left/Right IDs for the forums table $i = 1; - $changes_made = (($this->fixem($i, 'forum_id', FORUMS_TABLE)) || $changes_made) ? true : false; + $this->fix_ids_tree($i, 'forum_id', FORUMS_TABLE); $this->cache->purge(); $io->success($this->user->lang('CLI_FIXUP_FIX_LEFT_RIGHT_IDS_SUCCESS')); } - function fixem(&$i, $pkey, $table, $parent_id = 0, $where = array()) + /** + * Item's tree structure rebuild helper + * The item is either forum or ACP/MCP/UCP module + * + * @param int $i Item id offset index + * @param string $field The key field to fix, forum_id|module_id + * @param string $table The table name to perform, FORUMS_TABLE|MODULES_TABLE + * @param int $parent_id Parent item id + * @param string $where Additional WHERE clause condition + * + * @return bool True on rebuild success, false otherwise + */ + function fix_ids_tree(&$i, $field, $table, $parent_id = 0, $where = array()) { $changes_made = false; $sql = 'SELECT * FROM ' . $table . ' @@ -82,21 +110,21 @@ class fix_left_right_ids extends \phpbb\console\command\command $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - // Update the left_id for this module + // Update the left_id for the item if ($row['left_id'] != $i) { - $this->db->sql_query('UPDATE ' . $table . ' SET ' . $this->db->sql_build_array('UPDATE', array('left_id' => $i)) . " WHERE $pkey = {$row[$pkey]}"); + $this->db->sql_query('UPDATE ' . $table . ' SET ' . $this->db->sql_build_array('UPDATE', array('left_id' => $i)) . " WHERE $field = " . (int) $row[$field]); $changes_made = true; } $i++; // Go through children and update their left/right IDs - $changes_made = (($this->fixem($i, $pkey, $table, $row[$pkey], $where)) || $changes_made) ? true : false; + $changes_made = (($this->fix_ids_tree($i, $field, $table, $row[$field], $where)) || $changes_made) ? true : false; - // Update the right_id for the module + // Update the right_id for the item if ($row['right_id'] != $i) { - $this->db->sql_query('UPDATE ' . $table . ' SET ' . $this->db->sql_build_array('UPDATE', array('right_id' => $i)) . " WHERE $pkey = {$row[$pkey]}"); + $this->db->sql_query('UPDATE ' . $table . ' SET ' . $this->db->sql_build_array('UPDATE', array('right_id' => $i)) . " WHERE $field = " . (int) $row[$field]); $changes_made = true; } $i++; -- cgit v1.2.1 From 7f08d46aa4888cba48317bf0a8175b399039aff6 Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 18 Jun 2017 22:00:18 +0700 Subject: [ticket/15238] More code cleanup PHPBB3-15238 --- phpBB/phpbb/console/command/fixup/fix_left_right_ids.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php b/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php index 601a27118b..656011e4a6 100644 --- a/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php +++ b/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php @@ -10,6 +10,7 @@ * the docs/CREDITS.txt file. * */ + namespace phpbb\console\command\fixup; use Symfony\Component\Console\Input\InputInterface; @@ -96,7 +97,7 @@ class fix_left_right_ids extends \phpbb\console\command\command * @param string $field The key field to fix, forum_id|module_id * @param string $table The table name to perform, FORUMS_TABLE|MODULES_TABLE * @param int $parent_id Parent item id - * @param string $where Additional WHERE clause condition + * @param array $where Additional WHERE clause condition * * @return bool True on rebuild success, false otherwise */ -- cgit v1.2.1 From f3403fb10d7225d9aed121f17d1355b04fb0899e Mon Sep 17 00:00:00 2001 From: rxu Date: Tue, 20 Jun 2017 21:07:11 +0700 Subject: [ticket/15238] Add missing protected keyword PHPBB3-15238 --- phpBB/phpbb/console/command/fixup/fix_left_right_ids.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php b/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php index 656011e4a6..271b099a6c 100644 --- a/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php +++ b/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php @@ -101,7 +101,7 @@ class fix_left_right_ids extends \phpbb\console\command\command * * @return bool True on rebuild success, false otherwise */ - function fix_ids_tree(&$i, $field, $table, $parent_id = 0, $where = array()) + protected function fix_ids_tree(&$i, $field, $table, $parent_id = 0, $where = array()) { $changes_made = false; $sql = 'SELECT * FROM ' . $table . ' -- cgit v1.2.1 From ba5a2bcb73c8914a3c2a8f2dba11f1afd810aeb2 Mon Sep 17 00:00:00 2001 From: Agris Date: Tue, 20 Jun 2017 22:38:21 +0300 Subject: [ticket/15251] Use dispatcher_interface in help manager Allow TraceableEventDispatcher for webprofiler PHPBB3-15251 --- phpBB/phpbb/help/manager.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/help/manager.php b/phpBB/phpbb/help/manager.php index 39f52d343b..1637c58a61 100644 --- a/phpBB/phpbb/help/manager.php +++ b/phpBB/phpbb/help/manager.php @@ -18,7 +18,7 @@ namespace phpbb\help; */ class manager { - /** @var \phpbb\event\dispatcher */ + /** @var \phpbb\event\dispatcher_interface */ protected $dispatcher; /** @var \phpbb\language\language */ @@ -33,11 +33,11 @@ class manager /** * Constructor * - * @param \phpbb\event\dispatcher $dispatcher + * @param \phpbb\event\dispatcher_interface $dispatcher * @param \phpbb\language\language $language * @param \phpbb\template\template $template */ - public function __construct(\phpbb\event\dispatcher $dispatcher, \phpbb\language\language $language, \phpbb\template\template $template) + public function __construct(\phpbb\event\dispatcher_interface $dispatcher, \phpbb\language\language $language, \phpbb\template\template $template) { $this->dispatcher = $dispatcher; $this->language = $language; -- cgit v1.2.1 From 03cd4658d08caa062509fdf0e6ee7d6d296b67c0 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 25 Jun 2017 21:59:14 +0200 Subject: [prep-release-3.2.1] Add migration for 3.2.1-RC1 --- phpBB/phpbb/db/migration/data/v32x/v321rc1.php | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v32x/v321rc1.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/v321rc1.php b/phpBB/phpbb/db/migration/data/v32x/v321rc1.php new file mode 100644 index 0000000000..653a16f327 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/v321rc1.php @@ -0,0 +1,39 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v32x; + +class v321rc1 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.2.1-RC1', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320', + '\phpbb\db\migration\data\v31x\v3111rc1', + '\phpbb\db\migration\data\v32x\load_user_activity_limit', + '\phpbb\db\migration\data\v32x\user_notifications_table_unique_index', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.1-RC1')), + ); + } +} -- cgit v1.2.1 From 7f408e4b4184e4c850156090e648fc120985c975 Mon Sep 17 00:00:00 2001 From: v12mike Date: Mon, 26 Jun 2017 12:43:23 +0100 Subject: [PHPBB3-15247] Add support for php v7 APCu cache API Add new cache driver apcu.php (based closely on existing APC cache driver) Add new unit test apcu_driver_test.php for the new driver Update RUNNING_TESTS.md to clarify requirements for apc, apcu and apc_bc extensions and add a couple of general hints to RUNNING_TESTS.md PHPBB3-15247 --- phpBB/phpbb/cache/driver/apcu.php | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 phpBB/phpbb/cache/driver/apcu.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/apcu.php b/phpBB/phpbb/cache/driver/apcu.php new file mode 100644 index 0000000000..40192e4026 --- /dev/null +++ b/phpBB/phpbb/cache/driver/apcu.php @@ -0,0 +1,70 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\cache\driver; + +/** +* ACM for APCU +*/ +class apcu extends \phpbb\cache\driver\memory +{ + var $extension = 'apcu'; + + /** + * {@inheritDoc} + */ + function purge() + { + apcu_clear_cache(); + + parent::purge(); + } + + /** + * Fetch an item from the cache + * + * @access protected + * @param string $var Cache key + * @return mixed Cached data + */ + function _read($var) + { + return apcu_fetch($this->key_prefix . $var); + } + + /** + * Store data in the cache + * + * @access protected + * @param string $var Cache key + * @param mixed $data Data to store + * @param int $ttl Time-to-live of cached data + * @return bool True if the operation succeeded + */ + function _write($var, $data, $ttl = 2592000) + { + return apcu_store($this->key_prefix . $var, $data, $ttl); + } + + /** + * Remove an item from the cache + * + * @access protected + * @param string $var Cache key + * @return bool True if the operation succeeded + */ + function _delete($var) + { + return apcu_delete($this->key_prefix . $var); + } +} -- cgit v1.2.1 From b7ce395fbe6e2087a400487cb2431dc9ea66b8a9 Mon Sep 17 00:00:00 2001 From: lavigor Date: Sat, 1 Jul 2017 22:59:25 +0300 Subject: [ticket/15259] Fatal error on SQLite/Oracle database update PHPBB3-15259 --- phpBB/phpbb/db/tools/tools.php | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index 76036554d2..2f891e43d5 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -941,29 +941,19 @@ class tools implements tools_interface continue; } - // These DBMS prefix index name with the table name switch ($this->sql_layer) { + // These DBMS prefix index name with the table name case 'oracle': case 'sqlite3': - $index_name = $this->check_index_name_length($table_name, $table_name . '_' . $index_name, false); - $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) - - if (strpos($index_name , $table_name) === false) - { - if (strpos($index_name, $table_prefix) !== false) - { - $row[$col] = substr($row[$col], strlen($table_prefix) + 1); - } - else - { - $row[$col] = substr($row[$col], strlen($table_name) + 1); - } - } + $new_index_name = $this->check_index_name_length($table_name, $table_name . '_' . $index_name, false); + break; + default: + $new_index_name = $this->check_index_name_length($table_name, $index_name, false); break; } - if (strtolower($row[$col]) == strtolower($index_name)) + if (strtolower($row[$col]) == strtolower($new_index_name)) { $this->db->sql_freeresult($result); return true; @@ -1577,15 +1567,17 @@ class tools implements tools_interface $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) if (strpos($index_name, $table_prefix) === 0) { - $index_name = substr($index_name, strlen($table_prefix) + 1); - return $this->check_index_name_length($table_name, $index_name); + $index_name = substr($index_name, strlen($table_prefix)); + return $this->check_index_name_length($table_name, $index_name, $throw_error); } - // Try removing the table name then - if (strpos($index_name, $table_name) === 0) + // Try removing the remaining suffix part of table name then + $table_suffix = substr($table_name, strlen($table_prefix)); + if (strpos($index_name, $table_suffix) === 0) { - $index_name = substr($index_name, strlen($table_name) + 1); - return $this->check_index_name_length($table_name, $index_name); + // Remove the suffix and underscore separator between table_name and index_name + $index_name = substr($index_name, strlen($table_suffix) + 1); + return $this->check_index_name_length($table_name, $index_name, $throw_error); } if ($throw_error) -- cgit v1.2.1 From 329e5c5e052588b0f22c9046b9fbc19c9e551c81 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 3 Jul 2017 16:06:50 +0200 Subject: [ticket/15261] Fix censoring HTML tags PHPBB3-15261 --- phpBB/phpbb/textformatter/s9e/renderer.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 9be20b7f53..6fcd2b0a98 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -247,14 +247,12 @@ class renderer implements \phpbb\textformatter\renderer_interface $vars = array('renderer', 'xml'); extract($this->dispatcher->trigger_event('core.text_formatter_s9e_render_before', compact($vars))); + $html = $this->renderer->render($xml); if (isset($this->censor) && $this->viewcensors) { - // NOTE: censorHtml() is XML-safe - $xml = $this->censor->censorHtml($xml, true); + $html = $this->censor->censorHtml($html, true); } - $html = $this->renderer->render($xml); - /** * Modify a rendered text * -- cgit v1.2.1 From 4b733426698760801ff2b8ce3ce077c16732d4ef Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 16 Jul 2017 17:12:01 +0200 Subject: [prep-release-3.2.1] Add migration for 3.2.1 --- phpBB/phpbb/db/migration/data/v32x/v321.php | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v32x/v321.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/v321.php b/phpBB/phpbb/db/migration/data/v32x/v321.php new file mode 100644 index 0000000000..268f978b4b --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/v321.php @@ -0,0 +1,37 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v32x; + +class v321 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.2.1', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\v321rc1', + ); + + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.1')), + ); + } +} -- cgit v1.2.1 From 5216bf44838f8395d27b3df4ec1641a6407cb466 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 16 Jul 2017 20:07:13 +0200 Subject: [prep-release-3.2.1] Add missing .htaccess file --- phpBB/phpbb/db/migration/data/v32x/.htaccess | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v32x/.htaccess (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v32x/.htaccess b/phpBB/phpbb/db/migration/data/v32x/.htaccess new file mode 100644 index 0000000000..44242b5418 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/.htaccess @@ -0,0 +1,33 @@ +# With Apache 2.4 the "Order, Deny" syntax has been deprecated and moved from +# module mod_authz_host to a new module called mod_access_compat (which may be +# disabled) and a new "Require" syntax has been introduced to mod_authz_host. +# We could just conditionally provide both versions, but unfortunately Apache +# does not explicitly tell us its version if the module mod_version is not +# available. In this case, we check for the availability of module +# mod_authz_core (which should be on 2.4 or higher only) as a best guess. + + + + Order Allow,Deny + Deny from All + + + = 2.4> + + Require all denied + + + + + + + Order Allow,Deny + Deny from All + + + + + Require all denied + + + -- cgit v1.2.1 From 7f45062466b201e607db93e7f523f2a6d7057649 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sat, 22 Jul 2017 08:36:48 +0200 Subject: [ticket/15290] Add core.text_formatter_s9e_configure_finalize event PHPBB3-15290 --- phpBB/phpbb/textformatter/s9e/factory.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 7719ce5afa..71d39b6819 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -382,7 +382,18 @@ class factory implements \phpbb\textformatter\cache_interface unset($configurator->tags['censor:tag']); } - $objects = $configurator->finalize(); + $objects = $configurator->finalize(); + + /** + * Access the objects returned by finalize() before they are saved to cache + * + * @event core.text_formatter_s9e_configure_finalize + * @var array objects Array containing a "parser" object, a "renderer" object and optionally a "js" string + * @since 3.2.2-RC1 + */ + $vars = array('objects'); + extract($this->dispatcher->trigger_event('core.text_formatter_s9e_configure_finalize', compact($vars))); + $parser = $objects['parser']; $renderer = $objects['renderer']; -- cgit v1.2.1 From 80d0bf4566c098364790473d6b1c63aa3167922b Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sat, 22 Jul 2017 08:43:10 +0200 Subject: [ticket/15291] Allow short array notation in event declarations PHPBB3-15291 --- phpBB/phpbb/event/php_exporter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/event/php_exporter.php b/phpBB/phpbb/event/php_exporter.php index ae3553c558..26d7e2b426 100644 --- a/phpBB/phpbb/event/php_exporter.php +++ b/phpBB/phpbb/event/php_exporter.php @@ -392,7 +392,7 @@ class php_exporter public function get_vars_from_single_line_array($line, $throw_multiline = true) { $match = array(); - preg_match('#^\$vars = array\(\'([a-zA-Z0-9_\' ,]+)\'\);$#', $line, $match); + preg_match('#^\$vars = (?:\[|array\()\'([a-zA-Z0-9_\' ,]+)\'[\)\]];$#', $line, $match); if (isset($match[1])) { -- cgit v1.2.1 From d84834db88ea54bc33a323457236943a56399747 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 23 Jul 2017 21:09:30 +0200 Subject: [ticket/15293] Prevent continuing to database update on incomplete file update PHPBB3-15293 --- .../install/helper/iohandler/ajax_iohandler.php | 6 +++++ .../task/download_updated_files.php | 24 ++++++++++++------ .../module/update_filesystem/task/file_check.php | 29 ++++++++++++++++++++++ .../update_filesystem/task/show_file_status.php | 6 ++--- 4 files changed, 54 insertions(+), 11 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php index a40d457466..bce0149890 100644 --- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -186,6 +186,7 @@ class ajax_iohandler extends iohandler_base $tpl_ary['TITLE'] = $this->language->lang($input_options['label']); $tpl_ary['KEY'] = $input_name; $tpl_ary['S_EXPLAIN'] = false; + $tpl_ary['DISABLED'] = isset($input_options['disabled']) ? $input_options['disabled'] : false; if (isset($input_options['default'])) { @@ -219,6 +220,11 @@ class ajax_iohandler extends iohandler_base $this->template->assign_var('S_NOT_ONLY_BUTTON_FORM', $not_button_form); + if (!$not_button_form) + { + $this->template->destroy_block_vars('options'); + } + $this->template->set_filenames(array( 'form_install' => 'installer_form.html', )); diff --git a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php index f911b7ac62..21aa93b7ea 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php @@ -78,16 +78,23 @@ class download_updated_files extends task_base } else if ($this->iohandler->get_input('update_recheck_files_submit', false)) { + $this->installer_config->set('file_updater_elem_progress', ''); + $this->installer_config->set('update_files', array()); throw new jump_to_restart_point_exception('check_update_files'); } else { - // Render download box - $this->iohandler->add_download_link( - 'phpbb_installer_update_file_download', - 'DOWNLOAD_UPDATE_METHOD', - 'DOWNLOAD_UPDATE_METHOD_EXPLAIN' - ); + $file_update_info = $this->installer_config->get('update_files', array()); + + if (count($file_update_info) > 0) + { + // Render download box + $this->iohandler->add_download_link( + 'phpbb_installer_update_file_download', + 'DOWNLOAD_UPDATE_METHOD', + 'DOWNLOAD_UPDATE_METHOD_EXPLAIN' + ); + } // Add form to continue update $this->iohandler->add_user_form_group('UPDATE_CONTINUE_UPDATE_PROCESS', array( @@ -96,8 +103,9 @@ class download_updated_files extends task_base 'type' => 'submit', ), 'database_update_submit' => array( - 'label' => 'UPDATE_CONTINUE_UPDATE_PROCESS', - 'type' => 'submit', + 'label' => 'UPDATE_CONTINUE_UPDATE_PROCESS', + 'type' => 'submit', + 'disabled' => count($file_update_info) > 0, ), )); diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php index 47a71eb844..9daa8530c6 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -103,6 +103,29 @@ class file_check extends task_base $file_update_info = array(); $file_update_info['update_without_diff'] = array_diff($update_info['binary'], $update_info['deleted']); + foreach ($file_update_info['update_without_diff'] as $key => $binary_file) + { + $new_file = $new_path . $binary_file; + $file = $this->phpbb_root_path . $binary_file; + + if (!$this->filesystem->exists($file)) + { + continue; + } + + if (md5_file($file) === md5_file($new_file)) + { + // File already up to date + unset($file_update_info['update_without_diff'][$key]); + } + } + + // Remove update without diff info if empty + if (count($file_update_info['update_without_diff']) < 1) + { + unset($file_update_info['update_without_diff']); + } + // Filter out files that are already deleted $file_update_info['delete'] = array_filter( $update_info['deleted'], @@ -111,6 +134,12 @@ class file_check extends task_base return file_exists($root_path . $filename); } ); + + // Remove files to delete list if empty + if (count($file_update_info['delete']) < 1) + { + unset($file_update_info['delete']); + } } $progress_count = $this->installer_config->get('file_check_progress_count', 0); diff --git a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php index cf1e4cf4ac..0e82f91553 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php @@ -129,9 +129,9 @@ class show_file_status extends task_base // Add form to continue update $this->iohandler->add_user_form_group('UPDATE_CONTINUE_FILE_UPDATE', array( - 'submit_continue_file_update' => array( - 'label' => 'UPDATE_CONTINUE_FILE_UPDATE', - 'type' => 'submit', + 'submit_continue_file_update' => array( + 'label' => 'UPDATE_CONTINUE_FILE_UPDATE', + 'type' => 'submit', ), )); -- cgit v1.2.1 From ef404d0f95a3fd47c936239c1f6392b5851440b9 Mon Sep 17 00:00:00 2001 From: abyssmedia <30393121+abyssmedia@users.noreply.github.com> Date: Mon, 24 Jul 2017 00:04:43 +0400 Subject: [ticket/15303] Correctly refer to $memcached and not $memcache PHPBB3-15303 --- phpBB/phpbb/cache/driver/memcached.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/memcached.php b/phpBB/phpbb/cache/driver/memcached.php index a7da22d7e8..808e15afe8 100644 --- a/phpBB/phpbb/cache/driver/memcached.php +++ b/phpBB/phpbb/cache/driver/memcached.php @@ -68,7 +68,7 @@ class memcached extends \phpbb\cache\driver\memory foreach (explode(',', PHPBB_ACM_MEMCACHE) as $u) { preg_match('#(.*)/(\d+)#', $u, $parts); - $this->memcache->addServer(trim($parts[1]), (int) trim($parts[2])); + $this->memcached->addServer(trim($parts[1]), (int) trim($parts[2])); } } -- cgit v1.2.1 From 3aac61cfa74c0ca6816ddebed7e955519c11b9e2 Mon Sep 17 00:00:00 2001 From: Serge Skripchuk Date: Sun, 13 Aug 2017 15:33:04 +0300 Subject: [ticket/15319] Add IF EXISTS to Postgres DROP SEQUENCE query --- phpBB/phpbb/db/extractor/postgres_extractor.php | 2 +- phpBB/phpbb/db/tools/postgres.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/extractor/postgres_extractor.php b/phpBB/phpbb/db/extractor/postgres_extractor.php index a98e39621c..0219d2ac8d 100644 --- a/phpBB/phpbb/db/extractor/postgres_extractor.php +++ b/phpBB/phpbb/db/extractor/postgres_extractor.php @@ -85,7 +85,7 @@ class postgres_extractor extends base_extractor // We don't even care about storing the results. We already know the answer if we get rows back. if ($this->db->sql_fetchrow($result)) { - $sql_data .= "DROP SEQUENCE {$table_name}_seq;\n"; + $sql_data .= "DROP SEQUENCE IF EXISTS {$table_name}_seq;\n"; $sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n"; } $this->db->sql_freeresult($result); diff --git a/phpBB/phpbb/db/tools/postgres.php b/phpBB/phpbb/db/tools/postgres.php index e2a4e668a6..077d6e06f9 100644 --- a/phpBB/phpbb/db/tools/postgres.php +++ b/phpBB/phpbb/db/tools/postgres.php @@ -448,7 +448,7 @@ class postgres extends tools // We don't even care about storing the results. We already know the answer if we get rows back. if ($this->db->sql_fetchrow($result)) { - $statements[] = "DROP SEQUENCE {$table_name}_seq;\n"; + $statements[] = "DROP SEQUENCE IF EXISTS {$table_name}_seq;\n"; } $this->db->sql_freeresult($result); -- cgit v1.2.1 From a6c9119dfa1cf812292fffe1131f3b9f3bfebfc7 Mon Sep 17 00:00:00 2001 From: Jagoba Los Arcos Date: Sun, 13 Aug 2017 22:49:24 +0200 Subject: [ticket/15320] Redis cache does not save keys withouth expiration In some functions like sql_save in cache/memory.php, code try to save a key/value in cache with ttl = 0 so key should never expire. In current redis.php cache driver, it fails so key never get cached. This cause for example that when you create a subforum, it not appear in the forum box in the admincp. To solve, if ttl is 0, we use redis->set instead of setex --- phpBB/phpbb/cache/driver/redis.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/redis.php b/phpBB/phpbb/cache/driver/redis.php index eda774491c..8c9cd933a5 100644 --- a/phpBB/phpbb/cache/driver/redis.php +++ b/phpBB/phpbb/cache/driver/redis.php @@ -137,6 +137,10 @@ class redis extends \phpbb\cache\driver\memory */ function _write($var, $data, $ttl = 2592000) { + if($ttl == 0) + { + return $this->redis->set($var, $data); + } return $this->redis->setex($var, $ttl, $data); } -- cgit v1.2.1 From 4e5fd9a6e925487fe424538f4a2e6905f00da43d Mon Sep 17 00:00:00 2001 From: Jagoba Los Arcos Date: Mon, 14 Aug 2017 13:00:54 +0200 Subject: [ticket/15320] Fix to accomplish coding guidelines --- phpBB/phpbb/cache/driver/redis.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/cache/driver/redis.php b/phpBB/phpbb/cache/driver/redis.php index 8c9cd933a5..eaeb529918 100644 --- a/phpBB/phpbb/cache/driver/redis.php +++ b/phpBB/phpbb/cache/driver/redis.php @@ -137,7 +137,7 @@ class redis extends \phpbb\cache\driver\memory */ function _write($var, $data, $ttl = 2592000) { - if($ttl == 0) + if ($ttl == 0) { return $this->redis->set($var, $data); } -- cgit v1.2.1 From aabb9d2e488e465d48d9910f98a861ab96f55f74 Mon Sep 17 00:00:00 2001 From: rxu Date: Tue, 15 Aug 2017 15:41:56 +0700 Subject: [ticket/15323] Allow Twig syntax in bbcode.html PHPBB3-15323 --- phpBB/phpbb/textformatter/s9e/factory.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 7719ce5afa..13bfc7b5e9 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -518,7 +518,9 @@ class factory implements \phpbb\textformatter\cache_interface protected function extract_templates($template) { // Capture the template fragments - preg_match_all('#(.*?)#s', $template, $matches, PREG_SET_ORDER); + // Allow either phpBB template or the Twig syntax + preg_match_all('#(.*?)#s', $template, $matches, PREG_SET_ORDER) ?: + preg_match_all('#{% for (.*?) in .*? %}(.*?){% endfor %}#s', $template, $matches, PREG_SET_ORDER); $fragments = array(); foreach ($matches as $match) -- cgit v1.2.1 From 79093c11459d0a95116b1d6f6c3cf70084f099ea Mon Sep 17 00:00:00 2001 From: rxu Date: Thu, 17 Aug 2017 00:45:28 +0700 Subject: [ticket/15327] Add post anchor to the log postlink PHPBB3-15327 --- phpBB/phpbb/log/log.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php index cf3db365a4..5aad7ee326 100644 --- a/phpBB/phpbb/log/log.php +++ b/phpBB/phpbb/log/log.php @@ -747,7 +747,7 @@ class log implements \phpbb\log\log_interface foreach ($log as $key => $row) { $log[$key]['viewtopic'] = (isset($topic_auth['f_read'][$row['topic_id']])) ? append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 'f=' . $topic_auth['f_read'][$row['topic_id']] . '&t=' . $row['topic_id']) : false; - $log[$key]['viewpost'] = (isset($topic_auth['f_read'][$row['topic_id']]) && $row['post_id']) ? append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 'f=' . $topic_auth['f_read'][$row['topic_id']] . '&t=' . $row['topic_id'] . '&p=' . $row['post_id']) : false; + $log[$key]['viewpost'] = (isset($topic_auth['f_read'][$row['topic_id']]) && $row['post_id']) ? append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 'f=' . $topic_auth['f_read'][$row['topic_id']] . '&t=' . $row['topic_id'] . '&p=' . $row['post_id'] . '#p' . $row['post_id']) : false; $log[$key]['viewlogs'] = (isset($topic_auth['m_'][$row['topic_id']])) ? append_sid("{$this->phpbb_root_path}mcp.{$this->php_ext}", 'i=logs&mode=topic_logs&t=' . $row['topic_id'], true, $this->user->session_id) : false; } } -- cgit v1.2.1 From ec2d983ab1864affc6fd5718fc2faede488301dd Mon Sep 17 00:00:00 2001 From: kasimi Date: Thu, 24 Aug 2017 10:36:54 +0200 Subject: [ticket/15328] Disable checkbox if notification method isn't supported PHPBB3-15328 --- phpBB/phpbb/notification/manager.php | 8 +++++--- phpBB/phpbb/notification/method/email.php | 8 ++++++-- phpBB/phpbb/notification/method/jabber.php | 8 ++++++-- phpBB/phpbb/notification/method/messenger_base.php | 13 +++++++++++++ 4 files changed, 30 insertions(+), 7 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index 6923d96392..1cd7e5bc9a 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -475,9 +475,10 @@ class manager if ($type instanceof \phpbb\notification\type\type_interface && $type->is_available()) { $options = array_merge(array( - 'id' => $type->get_type(), - 'lang' => 'NOTIFICATION_TYPE_' . strtoupper($type->get_type()), - 'group' => 'NOTIFICATION_GROUP_MISCELLANEOUS', + 'type' => $type, + 'id' => $type->get_type(), + 'lang' => 'NOTIFICATION_TYPE_' . strtoupper($type->get_type()), + 'group' => 'NOTIFICATION_GROUP_MISCELLANEOUS', ), (($type::$notification_option !== false) ? $type::$notification_option : array())); $this->subscription_types[$options['group']][$options['id']] = $options; @@ -509,6 +510,7 @@ class manager foreach ($this->get_available_subscription_methods() as $method_name => $method) { $subscription_methods[$method_name] = array( + 'method' => $method, 'id' => $method->get_type(), 'lang' => str_replace('.', '_', strtoupper($method->get_type())), ); diff --git a/phpBB/phpbb/notification/method/email.php b/phpBB/phpbb/notification/method/email.php index 21a6559012..b330aa9da8 100644 --- a/phpBB/phpbb/notification/method/email.php +++ b/phpBB/phpbb/notification/method/email.php @@ -56,10 +56,14 @@ class email extends \phpbb\notification\method\messenger_base /** * Is this method available for the user? * This is checked on the notifications options + * + * @param \phpbb\notification\type\type_interface $notification_type An optional instance of a notification type. If provided, this + * method additionally checks if the type provides an email template. + * @return bool */ - public function is_available() + public function is_available(\phpbb\notification\type\type_interface $notification_type = null) { - return $this->config['email_enable'] && $this->user->data['user_email']; + return parent::is_available($notification_type) && $this->config['email_enable'] && $this->user->data['user_email']; } /** diff --git a/phpBB/phpbb/notification/method/jabber.php b/phpBB/phpbb/notification/method/jabber.php index 509c6b432c..4b461a5da3 100644 --- a/phpBB/phpbb/notification/method/jabber.php +++ b/phpBB/phpbb/notification/method/jabber.php @@ -56,10 +56,14 @@ class jabber extends \phpbb\notification\method\messenger_base /** * Is this method available for the user? * This is checked on the notifications options + * + * @param \phpbb\notification\type\type_interface $notification_type An optional instance of a notification type. If provided, this + * method additionally checks if the type provides an email template. + * @return bool */ - public function is_available() + public function is_available(\phpbb\notification\type\type_interface $notification_type = null) { - return ($this->global_available() && $this->user->data['user_jabber']); + return parent::is_available($notification_type) && $this->global_available() && $this->user->data['user_jabber']; } /** diff --git a/phpBB/phpbb/notification/method/messenger_base.php b/phpBB/phpbb/notification/method/messenger_base.php index 1f5525accc..7c99085a95 100644 --- a/phpBB/phpbb/notification/method/messenger_base.php +++ b/phpBB/phpbb/notification/method/messenger_base.php @@ -42,6 +42,19 @@ abstract class messenger_base extends \phpbb\notification\method\base $this->php_ext = $php_ext; } + /** + * Is this method available for the user? + * This is checked on the notifications options + * + * @param \phpbb\notification\type\type_interface $notification_type An optional instance of a notification type. This method returns false + * only if the type is provided and if it doesn't provide an email template. + * @return bool + */ + public function is_available(\phpbb\notification\type\type_interface $notification_type = null) + { + return $notification_type === null || $notification_type->get_email_template() !== false; + } + /** * Notify using phpBB messenger * -- cgit v1.2.1 From e1e94683bdc57430b2205ae4b1f1b32e7d0c66e2 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Thu, 24 Aug 2017 14:17:42 +0200 Subject: [ticket/15301] Remove quote limits when creating a parser PHPBB3-15301 --- phpBB/phpbb/textformatter/s9e/factory.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 7719ce5afa..81afeafd56 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -273,6 +273,11 @@ class factory implements \phpbb\textformatter\cache_interface { $configurator->BBCodes->addCustom($bbcode['usage'], $bbcode['template']); } + if (isset($configurator->tags['QUOTE'])) + { + // Remove the nesting limit and let other services remove quotes at parsing time + $configurator->tags['QUOTE']->nestingLimit = PHP_INT_MAX; + } // Modify the template to disable images/flash depending on user's settings foreach (array('FLASH', 'IMG') as $name) -- cgit v1.2.1 From e854e5b71f90910075fbac2b4f0dadac4fd39588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Sun, 3 Sep 2017 17:50:40 +0200 Subject: [ticket/15346] Check if extension is enableable during install PHPBB3-15346 --- .../install/module/install_finish/task/install_extensions.php | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index 553a30ea28..db28ad8fe3 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -118,6 +118,13 @@ class install_extensions extends \phpbb\install\task_base try { + $extension = $this->extension_manager->get_extension($ext_name); + + if (!$extension->is_enableable()) + { + continue; + } + $this->extension_manager->enable($ext_name); $extensions = $this->get_extensions(); -- cgit v1.2.1 From d99dbf1f0ea08e69be4fd61df2a45bbf1f0b1340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Tue, 5 Sep 2017 17:50:44 +0200 Subject: [ticket/15346] Add log message if extension is not enableable PHPBB3-15346 --- phpBB/phpbb/install/module/install_finish/task/install_extensions.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php index db28ad8fe3..eee13a6581 100644 --- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php +++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php @@ -122,6 +122,7 @@ class install_extensions extends \phpbb\install\task_base if (!$extension->is_enableable()) { + $this->iohandler->add_log_message(array('CLI_EXTENSION_NOT_ENABLEABLE', $ext_name)); continue; } -- cgit v1.2.1 From 837dc9b3a737e68d12eef033572894a81a2c0de7 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Wed, 6 Sep 2017 03:35:26 +0200 Subject: [ticket/15348] Ignore smilies that are immediately followed by a word PHPBB3-15348 --- phpBB/phpbb/textformatter/s9e/factory.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 7719ce5afa..3f2e0ab8cb 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -323,6 +323,9 @@ class factory implements \phpbb\textformatter\cache_interface // Only parse emoticons at the beginning of the text or if they're preceded by any // one of: a new line, a space, a dot, or a right square bracket $configurator->Emoticons->notAfter = '[^\\n .\\]]'; + + // Ignore emoticons that are immediately followed by a "word" character + $configurator->Emoticons->notBefore = '\\w'; } // Load the censored words -- cgit v1.2.1 From aa23af38d4d3a13918e859005277955debd76acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Thu, 7 Sep 2017 12:53:44 +0200 Subject: [ticket/15349] Check if extension is enableable before enable PHPBB3-15346 --- phpBB/phpbb/console/command/extension/enable.php | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index a8312d5c15..b35fb9c4c6 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -37,6 +37,13 @@ class enable extends command $io = new SymfonyStyle($input, $output); $name = $input->getArgument('extension-name'); + $extension = $this->manager->get_extension($name); + + if (!$extension->is_enableable()) + { + $io->error($this->user->lang('CLI_EXTENSION_NOT_ENABLEABLE', $name)); + return 1; + } if ($this->manager->is_enabled($name)) { -- cgit v1.2.1 From bf289de26f137bfe50608b6f9c549b306ede5b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Thu, 7 Sep 2017 12:54:13 +0200 Subject: [ticket/15349] Return 1 instead of 2 in case of error PHPBB3-15346 --- phpBB/phpbb/console/command/extension/enable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index b35fb9c4c6..f92de0069c 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -48,7 +48,7 @@ class enable extends command if ($this->manager->is_enabled($name)) { $io->error($this->user->lang('CLI_EXTENSION_ENABLED', $name)); - return 2; + return 1; } $this->manager->enable($name); -- cgit v1.2.1 From edd1ce74436c399f407e667b0b81b329a57a6f15 Mon Sep 17 00:00:00 2001 From: kasimi Date: Thu, 7 Sep 2017 13:30:39 +0200 Subject: [ticket/15328] Use type_interface PHPBB3-15328 --- phpBB/phpbb/notification/method/email.php | 8 +++++--- phpBB/phpbb/notification/method/jabber.php | 8 +++++--- phpBB/phpbb/notification/method/messenger_base.php | 8 +++++--- 3 files changed, 15 insertions(+), 9 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/notification/method/email.php b/phpBB/phpbb/notification/method/email.php index b330aa9da8..56dd1e9367 100644 --- a/phpBB/phpbb/notification/method/email.php +++ b/phpBB/phpbb/notification/method/email.php @@ -13,6 +13,8 @@ namespace phpbb\notification\method; +use phpbb\notification\type\type_interface; + /** * Email notification method class * This class handles sending emails for notifications @@ -57,11 +59,11 @@ class email extends \phpbb\notification\method\messenger_base * Is this method available for the user? * This is checked on the notifications options * - * @param \phpbb\notification\type\type_interface $notification_type An optional instance of a notification type. If provided, this - * method additionally checks if the type provides an email template. + * @param type_interface $notification_type An optional instance of a notification type. If provided, this + * method additionally checks if the type provides an email template. * @return bool */ - public function is_available(\phpbb\notification\type\type_interface $notification_type = null) + public function is_available(type_interface $notification_type = null) { return parent::is_available($notification_type) && $this->config['email_enable'] && $this->user->data['user_email']; } diff --git a/phpBB/phpbb/notification/method/jabber.php b/phpBB/phpbb/notification/method/jabber.php index 4b461a5da3..81fdb378e2 100644 --- a/phpBB/phpbb/notification/method/jabber.php +++ b/phpBB/phpbb/notification/method/jabber.php @@ -13,6 +13,8 @@ namespace phpbb\notification\method; +use phpbb\notification\type\type_interface; + /** * Jabber notification method class * This class handles sending Jabber messages for notifications @@ -57,11 +59,11 @@ class jabber extends \phpbb\notification\method\messenger_base * Is this method available for the user? * This is checked on the notifications options * - * @param \phpbb\notification\type\type_interface $notification_type An optional instance of a notification type. If provided, this - * method additionally checks if the type provides an email template. + * @param type_interface $notification_type An optional instance of a notification type. If provided, this + * method additionally checks if the type provides an email template. * @return bool */ - public function is_available(\phpbb\notification\type\type_interface $notification_type = null) + public function is_available(type_interface $notification_type = null) { return parent::is_available($notification_type) && $this->global_available() && $this->user->data['user_jabber']; } diff --git a/phpBB/phpbb/notification/method/messenger_base.php b/phpBB/phpbb/notification/method/messenger_base.php index 7c99085a95..32e79aa936 100644 --- a/phpBB/phpbb/notification/method/messenger_base.php +++ b/phpBB/phpbb/notification/method/messenger_base.php @@ -13,6 +13,8 @@ namespace phpbb\notification\method; +use phpbb\notification\type\type_interface; + /** * Abstract notification method handling email and jabber notifications * using the phpBB messenger. @@ -46,11 +48,11 @@ abstract class messenger_base extends \phpbb\notification\method\base * Is this method available for the user? * This is checked on the notifications options * - * @param \phpbb\notification\type\type_interface $notification_type An optional instance of a notification type. This method returns false - * only if the type is provided and if it doesn't provide an email template. + * @param type_interface $notification_type An optional instance of a notification type. This method returns false + * only if the type is provided and if it doesn't provide an email template. * @return bool */ - public function is_available(\phpbb\notification\type\type_interface $notification_type = null) + public function is_available(type_interface $notification_type = null) { return $notification_type === null || $notification_type->get_email_template() !== false; } -- cgit v1.2.1 From c368d170cf09d06ff63249d4405323e6108d90bb Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Fri, 8 Sep 2017 10:45:22 +0200 Subject: [ticket/15351] Makes confirm_works in a router context (app.php) PHPBB3-15351 --- phpBB/phpbb/path_helper.php | 13 +++++++++++++ phpBB/phpbb/session.php | 15 ++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php index 154361ef64..5b6db35f23 100644 --- a/phpBB/phpbb/path_helper.php +++ b/phpBB/phpbb/path_helper.php @@ -496,4 +496,17 @@ class path_helper return $page; } + + /** + * Tells if the router is currently in use (if the current page is a route or not) + * + * @return bool + */ + public function is_router_used() + { + // Script name URI (e.g. phpBB/app.php) + $script_name = $this->symfony_request->getScriptName(); + + return basename($script_name) === 'app.' . $this->php_ext; + } } diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index c5b50c2b07..6b5b8f2625 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -91,9 +91,18 @@ class session $page_name .= str_replace('%2F', '/', urlencode($symfony_request_path)); } - // current directory within the phpBB root (for example: adm) - $root_dirs = explode('/', str_replace('\\', '/', $phpbb_filesystem->realpath($root_path))); - $page_dirs = explode('/', str_replace('\\', '/', $phpbb_filesystem->realpath('./'))); + if (substr($root_path, 0, 2) === './' && strpos($root_path, '..') === false) + { + $root_dirs = explode('/', str_replace('\\', '/', rtrim($root_path, '/'))); + $page_dirs = explode('/', str_replace('\\', '/', '.')); + } + else + { + // current directory within the phpBB root (for example: adm) + $root_dirs = explode('/', str_replace('\\', '/', $phpbb_filesystem->realpath($root_path))); + $page_dirs = explode('/', str_replace('\\', '/', $phpbb_filesystem->realpath('./'))); + } + $intersection = array_intersect_assoc($root_dirs, $page_dirs); $root_dirs = array_diff_assoc($root_dirs, $intersection); -- cgit v1.2.1 From a29048abd6ea13ec00449c4c1c751c035cf5ed1c Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sat, 9 Sep 2017 17:08:27 +0200 Subject: [ticket/14933] Make "route not found" more user-friendly PHPBB3-14933 --- phpBB/phpbb/event/kernel_exception_subscriber.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/event/kernel_exception_subscriber.php b/phpBB/phpbb/event/kernel_exception_subscriber.php index b7a54f2608..f7582c5d90 100644 --- a/phpBB/phpbb/event/kernel_exception_subscriber.php +++ b/phpBB/phpbb/event/kernel_exception_subscriber.php @@ -16,12 +16,20 @@ namespace phpbb\event; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Response; class kernel_exception_subscriber implements EventSubscriberInterface { + /** + * Set to true to show full exception messages + * + * @var bool + */ + protected $debug; + /** * Template object * @@ -45,8 +53,9 @@ class kernel_exception_subscriber implements EventSubscriberInterface * @param \phpbb\template\template $template Template object * @param \phpbb\language\language $language Language object */ - public function __construct(\phpbb\template\template $template, \phpbb\language\language $language) + public function __construct(\phpbb\template\template $template, \phpbb\language\language $language, $debug = false) { + $this->debug = $debug || defined('DEBUG'); $this->template = $template; $this->language = $language; $this->type_caster = new \phpbb\request\type_cast_helper(); @@ -69,6 +78,10 @@ class kernel_exception_subscriber implements EventSubscriberInterface { $message = $this->language->lang_array($message, $exception->get_parameters()); } + else if (!$this->debug && $exception instanceof NotFoundHttpException) + { + $message = $this->language->lang('PAGE_NOT_FOUND'); + } // Show text in bold $message = preg_replace('#<(/?strong)>#i', '<$1>', $message); @@ -99,7 +112,7 @@ class kernel_exception_subscriber implements EventSubscriberInterface $data['message'] = $message; } - if (defined('DEBUG')) + if ($this->debug) { $data['trace'] = $exception->getTrace(); } -- cgit v1.2.1 From 4b39b99d566a81a1a0a1e5c8e793f3380db21c85 Mon Sep 17 00:00:00 2001 From: Oliver Schramm Date: Sun, 10 Sep 2017 11:08:59 +0200 Subject: [ticket/14933] Fix docblock for kernel_exception_subscriber PHPBB3-14933 --- phpBB/phpbb/event/kernel_exception_subscriber.php | 1 + 1 file changed, 1 insertion(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/event/kernel_exception_subscriber.php b/phpBB/phpbb/event/kernel_exception_subscriber.php index f7582c5d90..373e59b0c8 100644 --- a/phpBB/phpbb/event/kernel_exception_subscriber.php +++ b/phpBB/phpbb/event/kernel_exception_subscriber.php @@ -52,6 +52,7 @@ class kernel_exception_subscriber implements EventSubscriberInterface * * @param \phpbb\template\template $template Template object * @param \phpbb\language\language $language Language object + * @param bool $debug Set to true to show full exception messages */ public function __construct(\phpbb\template\template $template, \phpbb\language\language $language, $debug = false) { -- cgit v1.2.1 From ca5678cc1c2a1f723d39127e0c066eba6c9a3336 Mon Sep 17 00:00:00 2001 From: rxu Date: Sat, 16 Sep 2017 23:51:39 +0700 Subject: [ticket/15367] Escape special characters in Sphinx search backend PHPBB3-15367 --- phpBB/phpbb/search/fulltext_sphinx.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index 89c615e087..59c3d55076 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -648,7 +648,7 @@ class fulltext_sphinx $this->sphinx->SetFilter('deleted', array(0)); $this->sphinx->SetLimits($start, (int) $per_page, SPHINX_MAX_MATCHES); - $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); + $result = $this->sphinx->Query($search_query_prefix . $this->sphinx->EscapeString(str_replace('"', '"', $this->search_query)), $this->indexes); // Could be connection to localhost:9312 failed (errno=111, // msg=Connection refused) during rotate, retry if so @@ -656,7 +656,7 @@ class fulltext_sphinx while (!$result && (strpos($this->sphinx->GetLastError(), "errno=111,") !== false) && $retries--) { usleep(SPHINX_CONNECT_WAIT_TIME); - $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); + $result = $this->sphinx->Query($search_query_prefix . $this->sphinx->EscapeString(str_replace('"', '"', $this->search_query)), $this->indexes); } if ($this->sphinx->GetLastError()) @@ -679,7 +679,7 @@ class fulltext_sphinx $start = floor(($result_count - 1) / $per_page) * $per_page; $this->sphinx->SetLimits((int) $start, (int) $per_page, SPHINX_MAX_MATCHES); - $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); + $result = $this->sphinx->Query($search_query_prefix . $this->sphinx->EscapeString(str_replace('"', '"', $this->search_query)), $this->indexes); // Could be connection to localhost:9312 failed (errno=111, // msg=Connection refused) during rotate, retry if so @@ -687,7 +687,7 @@ class fulltext_sphinx while (!$result && (strpos($this->sphinx->GetLastError(), "errno=111,") !== false) && $retries--) { usleep(SPHINX_CONNECT_WAIT_TIME); - $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); + $result = $this->sphinx->Query($search_query_prefix . $this->sphinx->EscapeString(str_replace('"', '"', $this->search_query)), $this->indexes); } } -- cgit v1.2.1