diff options
133 files changed, 2761 insertions, 383 deletions
diff --git a/.travis.yml b/.travis.yml index 2e0b68c3de..b7b17f2f19 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,8 @@ matrix: env: DB=postgres - php: 5.4 env: DB=sqlite3 + - php: 5.4 + env: DB=mysqli;SLOWTESTS=1 - php: 5.5 env: DB=mysqli - php: 5.6 @@ -41,6 +43,7 @@ script: - travis/check-sami-parse-errors.sh $DB $TRAVIS_PHP_VERSION - travis/check-image-icc-profiles.sh $DB $TRAVIS_PHP_VERSION - travis/check-executable-files.sh $DB $TRAVIS_PHP_VERSION ./ - - phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml + - sh -c "if [ '$SLOWTESTS' != '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml; fi" + - sh -c "if [ '$SLOWTESTS' = '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --group slow; fi" - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.3.3' -a '$DB' = 'mysqli' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..FETCH_HEAD; fi" diff --git a/build/build.xml b/build/build.xml index dd7bb3d014..b0a9190898 100644 --- a/build/build.xml +++ b/build/build.xml @@ -2,9 +2,9 @@ <project name="phpBB" description="The phpBB forum software" default="all" basedir="../"> <!-- a few settings for the build --> - <property name="newversion" value="3.1.3-RC1-dev" /> - <property name="prevversion" value="3.1.2" /> - <property name="olderversions" value="3.0.12, 3.1.0-a1, 3.1.0-a2, 3.1.0-a3, 3.1.0-b1, 3.1.0-b2, 3.1.0-b3, 3.1.0-b4, 3.1.0-RC1, 3.1.0-RC2, 3.1.0-RC3, 3.1.0-RC4, 3.1.0-RC5, 3.1.0-RC6, 3.1.0, 3.1.1, 3.1.2-RC1" /> + <property name="newversion" value="3.1.4-dev" /> + <property name="prevversion" value="3.1.3" /> + <property name="olderversions" value="3.0.12, 3.0.13, 3.0.13-PL1, 3.1.0, 3.1.1, 3.1.2" /> <!-- no configuration should be needed beyond this point --> <property name="oldversions" value="${olderversions}, ${prevversion}" /> diff --git a/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php b/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php index f81ec46579..18cb8ba82e 100644 --- a/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php +++ b/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php @@ -24,6 +24,23 @@ class phpbb_Sniffs_Namespaces_UnusedUseSniff implements PHP_CodeSniffer_Sniff return array(T_USE); } + protected function check($phpcsFile, $found_name, $full_name, $short_name, $line) + { + + if ($found_name === $full_name) + { + $error = 'Either use statement or full name must be used.'; + $phpcsFile->addError($error, $line, 'FullName'); + } + + if ($found_name === $short_name) + { + return true; + } + + return false; + } + /** * {@inheritdoc} */ @@ -74,16 +91,7 @@ class phpbb_Sniffs_Namespaces_UnusedUseSniff implements PHP_CodeSniffer_Sniff $simple_class_name = trim($phpcsFile->getTokensAsString($simple_class_name_start, ($simple_class_name_end - $simple_class_name_start))); - if ($simple_class_name === $class_name_full) - { - $error = 'Either use statement or full name must be used.'; - $phpcsFile->addError($error, $simple_statement, 'FullName'); - } - - if ($simple_class_name === $class_name_short) - { - $ok = true; - } + $ok = $this->check($phpcsFile, $simple_class_name, $class_name_full, $class_name_short, $simple_statement) ? true : $ok; } } @@ -98,16 +106,7 @@ class phpbb_Sniffs_Namespaces_UnusedUseSniff implements PHP_CodeSniffer_Sniff $paamayim_nekudotayim_class_name = trim($phpcsFile->getTokensAsString($paamayim_nekudotayim_class_name_start + 1, ($paamayim_nekudotayim_class_name_end - $paamayim_nekudotayim_class_name_start))); - if ($paamayim_nekudotayim_class_name === $class_name_full) - { - $error = 'Either use statement or full name must be used.'; - $phpcsFile->addError($error, $paamayim_nekudotayim, 'FullName'); - } - - if ($paamayim_nekudotayim_class_name === $class_name_short) - { - $ok = true; - } + $ok = $this->check($phpcsFile, $paamayim_nekudotayim_class_name, $class_name_full, $class_name_short, $paamayim_nekudotayim) ? true : $ok; } // Checks in implements @@ -126,16 +125,7 @@ class phpbb_Sniffs_Namespaces_UnusedUseSniff implements PHP_CodeSniffer_Sniff $implements_class_name = trim($phpcsFile->getTokensAsString($implements_class_name_start, ($implements_class_name_end - $implements_class_name_start))); - if ($implements_class_name === $class_name_full) - { - $error = 'Either use statement or full name must be used.'; - $phpcsFile->addError($error, $implements, 'FullName'); - } - - if ($implements_class_name === $class_name_short) - { - $ok = true; - } + $ok = $this->check($phpcsFile, $implements_class_name, $class_name_full, $class_name_short, $implements) ? true : $ok; } } @@ -145,34 +135,64 @@ class phpbb_Sniffs_Namespaces_UnusedUseSniff implements PHP_CodeSniffer_Sniff { $old_function_declaration = $function_declaration; - $end_function = $phpcsFile->findNext(array(T_CLOSE_PARENTHESIS), ($function_declaration + 1)); - $old_argument = $function_declaration; - while (($argument = $phpcsFile->findNext(T_VARIABLE, ($old_argument + 1), $end_function)) !== false) + // Check docblocks + $find = array( + T_COMMENT, + T_DOC_COMMENT, + T_CLASS, + T_FUNCTION, + T_OPEN_TAG, + ); + + $comment_end = $phpcsFile->findPrevious($find, ($function_declaration - 1)); + if ($comment_end !== false) { - $old_argument = $argument; - - $start_argument = $phpcsFile->findPrevious(array(T_OPEN_PARENTHESIS, T_COMMA), $argument); - $argument_class_name_start = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING), ($start_argument + 1), $argument); - - // Skip the parameter if no type is defined. - if ($argument_class_name_start !== false) + if (!$tokens[$comment_end]['code'] !== T_DOC_COMMENT) { - $argument_class_name_end = $phpcsFile->findNext($find, ($argument_class_name_start + 1), null, true); - - $argument_class_name = $phpcsFile->getTokensAsString($argument_class_name_start, ($argument_class_name_end - $argument_class_name_start - 1)); + $comment_start = ($phpcsFile->findPrevious(T_DOC_COMMENT, ($comment_end - 1), null, true) + 1); + $comment = $phpcsFile->getTokensAsString($comment_start, ($comment_end - $comment_start + 1)); - if ($argument_class_name === $class_name_full) + try { - $error = 'Either use statement or full name must be used.'; - $phpcsFile->addError($error, $function_declaration, 'FullName'); + $comment_parser = new PHP_CodeSniffer_CommentParser_FunctionCommentParser($comment, $phpcsFile); + $comment_parser->parse(); + + // Check @param + foreach ($comment_parser->getParams() as $param) { + $type = $param->getType(); + $types = explode('|', str_replace('[]', '', $type)); + foreach ($types as $type) + { + $ok = $this->check($phpcsFile, $type, $class_name_full, $class_name_short, $param->getLine() + $comment_start) ? true : $ok; + } + } + + // Check @return + $return = $comment_parser->getReturn(); + if ($return !== null) + { + $type = $return->getValue(); + $types = explode('|', str_replace('[]', '', $type)); + foreach ($types as $type) + { + $ok = $this->check($phpcsFile, $type, $class_name_full, $class_name_short, $return->getLine() + $comment_start) ? true : $ok; + } + } } - - if ($argument_class_name === $class_name_short) + catch (PHP_CodeSniffer_CommentParser_ParserException $e) { - $ok = true; + $line = ($e->getLineWithinComment() + $comment_start); + $phpcsFile->addError($e->getMessage(), $line, 'FailedParse'); } } } + + // Check type hint + $params = $phpcsFile->getMethodParameters($function_declaration); + foreach ($params as $param) + { + $ok = $this->check($phpcsFile, $param['type_hint'], $class_name_full, $class_name_short, $function_declaration) ? true : $ok; + } } if (!$ok) diff --git a/build/package.php b/build/package.php index c0db0c4011..d168957ca5 100755 --- a/build/package.php +++ b/build/package.php @@ -394,6 +394,7 @@ if (sizeof($package->old_packages)) $package->run_command('mkdir ' . $package->get('files_directory') . '/release'); $package->run_command('cp -Rp ' . $package->get('dest_dir') . '/docs ' . $package->get('files_directory') . '/release'); $package->run_command('cp -Rp ' . $package->get('dest_dir') . '/install ' . $package->get('files_directory') . '/release'); + $package->run_command('cp -Rp ' . $package->get('dest_dir') . '/vendor ' . $package->get('files_directory') . '/release'); $package->run_command('rm -v ' . $package->get('files_directory') . '/release/install/install_install.php'); $package->run_command('rm -v ' . $package->get('files_directory') . '/release/install/install_update.php'); diff --git a/phpBB/config/content.yml b/phpBB/config/content.yml index f0985f0292..4d9ee31335 100644 --- a/phpBB/config/content.yml +++ b/phpBB/config/content.yml @@ -4,6 +4,7 @@ services: arguments: - @auth - @config + - @dispatcher - @dbal.conn - @user - %core.root_path% diff --git a/phpBB/config/db.yml b/phpBB/config/db.yml index b3f1b485ea..d11669d8a3 100644 --- a/phpBB/config/db.yml +++ b/phpBB/config/db.yml @@ -18,6 +18,7 @@ services: migrator: class: phpbb\db\migrator arguments: + - @service_container - @config - @dbal.conn - @dbal.tools diff --git a/phpBB/config/notification.yml b/phpBB/config/notification.yml index add577be2c..b17a172fb5 100644 --- a/phpBB/config/notification.yml +++ b/phpBB/config/notification.yml @@ -7,6 +7,7 @@ services: - @service_container - @user_loader - @config + - @dispatcher - @dbal.conn - @cache - @user diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 7ef86ad7fc..60ffe04330 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -51,7 +51,6 @@ $classes = $finder->core_path('phpbb/') $db = new \phpbb\db\driver\sqlite(); $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, new \phpbb\db\tools($db, true), $phpbb_root_path, $phpEx, $table_prefix); $schema_data = $schema_generator->get_schema(); -$dbms_type_map = phpbb\db\tools::get_dbms_type_map(); $fp = fopen($schema_path . 'schema.json', 'wb'); fwrite($fp, json_encode($schema_data, JSON_PRETTY_PRINT)); diff --git a/phpBB/develop/mysql_upgrader.php b/phpBB/develop/mysql_upgrader.php index 5c558f0b8e..698be9d303 100644 --- a/phpBB/develop/mysql_upgrader.php +++ b/phpBB/develop/mysql_upgrader.php @@ -62,10 +62,14 @@ echo "USE $dbname;$newline$newline"; @set_time_limit(0); -require($phpbb_root_path . 'includes/db/schema_data.' . $phpEx); -require($phpbb_root_path . 'phpbb/db/tools.' . $phpEx); - -$dbms_type_map = phpbb\db\tools::get_dbms_type_map(); +$finder = new \phpbb\finder(new \phpbb\filesystem(), $phpbb_root_path); +$classes = $finder->core_path('phpbb/') + ->directory('/db/migration/data') + ->get_classes(); + +$schema_generator = new \phpbb\db\migration\schema_generator($classes, $config, $db, new \phpbb\db\tools($db, true), $phpbb_root_path, $phpEx, $table_prefix); +$schema_data = $schema_generator->get_schema(); +$dbms_type_map = \phpbb\db\tools::get_dbms_type_map(); foreach ($schema_data as $table_name => $table_data) { diff --git a/phpBB/develop/regex_idn.php b/phpBB/develop/regex_idn.php new file mode 100644 index 0000000000..d871695c50 --- /dev/null +++ b/phpBB/develop/regex_idn.php @@ -0,0 +1,151 @@ +<?php +// +// Security message: +// +// This script is potentially dangerous. +// Remove or comment the next line (die(".... ) to enable this script. +// Do NOT FORGET to either remove this script or disable it after you have used it. +// +die("Please read the first lines of this script for instructions on how to enable it"); + +// IP regular expressions + +$dec_octet = '(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])'; +$h16 = '[\dA-F]{1,4}'; +$ipv4 = "(?:$dec_octet\.){3}$dec_octet"; +$ls32 = "(?:$h16:$h16|$ipv4)"; + +$ipv6_construct = array( + array(false, '', '{6}', $ls32), + array(false, '::', '{0,5}', "(?:$h16(?::$h16)?|$ipv4)"), + array('', ':', '{4}', $ls32), + array('{1,2}', ':', '{3}', $ls32), + array('{1,3}', ':', '{2}', $ls32), + array('{1,4}', ':', '', $ls32), + array('{1,5}', ':', false, $ls32), + array('{1,6}', ':', false, $h16), + array('{1,7}', ':', false, ''), + array(false, '::', false, '') +); + +$ipv6 = '(?:'; +foreach ($ipv6_construct as $ip_type) +{ + $ipv6 .= '(?:'; + if ($ip_type[0] !== false) + { + $ipv6 .= "(?:$h16:)" . $ip_type[0]; + } + $ipv6 .= $ip_type[1]; + if ($ip_type[2] !== false) + { + $ipv6 .= "(?:$h16:)" . $ip_type[2]; + } + $ipv6 .= $ip_type[3] . ')|'; +} +$ipv6 = substr($ipv6, 0, -1) . ')'; + +echo 'IPv4: ' . $ipv4 . "<br /><br />\n\nIPv6: " . $ipv6 . "<br /><br />\n\n"; + +// URL regular expressions + +/* IDN2008 characters derivation +** http://unicode.org/faq/idn.html#33 - IDN FAQ: derivation of valid characters in terms of Unicode properties +** http://unicode.org/reports/tr46/ - Unicode Technical Standard #46. Unicode IDNA Compatibility Processing +** http://www.unicode.org/Public/UNIDATA/DerivedNormalizationProps.txt - Unicode Character Database +*/ +/* +** Remove Control Characters and Whitespace (as in IDNA2003) +*/ +$no_cc = '\p{C}\p{Z}'; +/* +** Remove Symbols, Punctuation, non-decimal Numbers, and Enclosing Marks +*/ +$no_symbol = '\p{S}\p{P}\p{Nl}\p{No}\p{Me}'; +/* +** Remove characters used for archaic Hangul (Korean) - \p{HST=L} and \p{HST=V} +** as per http://unicode.org/Public/UNIDATA/HangulSyllableType.txt +*/ +$no_hangul = '\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}'; +/* +** Remove three blocks of technical or archaic symbols. +*/ +$no_cdm = '\x{20D0}-\x{20FF}'; // \p{block=Combining_Diacritical_Marks_For_Symbols} +$no_musical = '\x{1D100}-\x{1D1FF}'; // \p{block=Musical_Symbols} +$no_ancient_greek_musical = '\x{1D200}-\x{1D24F}'; // \p{block=Ancient_Greek_Musical_Notation} +/* Remove certain exceptions: +** U+0640 ARABIC TATWEEL +** U+07FA NKO LAJANYALAN +** U+302E HANGUL SINGLE DOT TONE MARK +** U+302F HANGUL DOUBLE DOT TONE MARK +** U+3031 VERTICAL KANA REPEAT MARK +** U+3032 VERTICAL KANA REPEAT WITH VOICED SOUND MARK +** .. +** U+3035 VERTICAL KANA REPEAT MARK LOWER HALF +** U+303B VERTICAL IDEOGRAPHIC ITERATION MARK +*/ +$no_certain_exceptions = '\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}'; +/* Add certain exceptions: +** U+00B7 MIDDLE DOT +** U+0375 GREEK LOWER NUMERAL SIGN +** U+05F3 HEBREW PUNCTUATION GERESH +** U+05F4 HEBREW PUNCTUATION GERSHAYIM +** U+30FB KATAKANA MIDDLE DOT +** U+002D HYPHEN-MINUS +** U+06FD ARABIC SIGN SINDHI AMPERSAND +** U+06FE ARABIC SIGN SINDHI POSTPOSITION MEN +** U+0F0B TIBETAN MARK INTERSYLLABIC TSHEG +** U+3007 IDEOGRAPHIC NUMBER ZERO +*/ +$add_certain_exceptions = '\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}'; +/* Add special exceptions (Deviations): +** U+00DF LATIN SMALL LETTER SHARP S +** U+03C2 GREEK SMALL LETTER FINAL SIGMA +** U+200C ZERO WIDTH NON-JOINER +** U+200D ZERO WIDTH JOINER +*/ +$add_deviations = '\x{00DF}\x{03C2}\x{200C}\x{200D}'; + +// Concatenate remove/add regexes respectively +$remove_chars = "$no_cc$no_symbol$no_hangul$no_cdm$no_musical$no_ancient_greek_musical$no_certain_exceptions"; +$add_chars = "$add_certain_exceptions$add_deviations"; + +// Initialize inline mode +$inline = false; + +do +{ + $inline = !$inline; + + $pct_encoded = "%[\dA-F]{2}"; + $unreserved = "$add_chars\pL0-9\-._~"; + $sub_delims = ($inline) ? '!$&\'(*+,;=' : '!$&\'()*+,;='; + $scheme = ($inline) ? '[a-z][a-z\d+]*': '[a-z][a-z\d+\-.]*' ; // avoid automatic parsing of "word" in "last word.http://..." + $pchar = "(?:[^$remove_chars]*[$unreserved$sub_delims:@|]+|$pct_encoded)"; // rfc: no "|" + + $reg_name = "(?:[^$remove_chars]*[$unreserved$sub_delims:@|]+|$pct_encoded)+"; // rfc: * instead of + and no "|" and no "@" and no ":" (included instead of userinfo) + //$userinfo = "(?:(?:[$unreserved$sub_delims:]+|$pct_encoded))*"; + $ipv4_simple = '[0-9.]+'; + $ipv6_simple = '\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\]'; + $host = "(?:$reg_name|$ipv4_simple|$ipv6_simple)"; + $port = '\d*'; + //$authority = "(?:$userinfo@)?$host(?::$port)?"; + $authority = "$host(?::$port)?"; + $segment = "$pchar*"; + $path_abempty = "(?:/$segment)*"; + $hier_part = "/{2}$authority$path_abempty"; + $query = "(?:[^$remove_chars]*[$unreserved$sub_delims:@/?|]+|$pct_encoded)*"; // pchar | "/" | "?", rfc: no "|" + $fragment = $query; + + $url = "$scheme:$hier_part(?:\?$query)?(?:\#$fragment)?"; + echo (($inline) ? 'URL inline: ' : 'URL: ') . $url . "<br /><br />\n\n"; + + // no scheme, shortened authority, but host has to start with www. + $www_url = "www\.$reg_name(?::$port)?$path_abempty(?:\?$query)?(?:\#$fragment)?"; + echo (($inline) ? 'www.URL_inline: ' : 'www.URL: ') . $www_url . "<br /><br />\n\n"; + + // no schema and no authority + $relative_url = "$segment$path_abempty(?:\?$query)?(?:\#$fragment)?"; + echo (($inline) ? 'relative URL inline: ' : 'relative URL: ') . $relative_url . "<br /><br />\n\n"; +} +while ($inline); diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index 5cf98e20fc..acf5a318be 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -45,7 +45,9 @@ <ol> <li><a href="#changelog">Changelog</a> - <ol style="list-style-type: lower-roman;"> + <ul> + <li><a href="#v312">Changes since 3.1.3-RC1</a></li> + <li><a href="#v312">Changes since 3.1.2</a></li> <li><a href="#v311">Changes since 3.1.1</a></li> <li><a href="#v310">Changes since 3.1.0</a></li> <li><a href="#v310RC6">Changes since 3.1.0-RC6</a></li> @@ -62,6 +64,8 @@ <li><a href="#v310a2">Changes since 3.1.0-a2</a></li> <li><a href="#v310a1">Changes since 3.1.0-a1</a></li> <li><a href="#v30x">Changes since 3.0.x</a></li> + <li><a href="#v3013">Changes since 3.0.13</a></li> + <li><a href="#v3012">Changes since 3.0.12</a></li> <li><a href="#v3011">Changes since 3.0.11</a></li> <li><a href="#v3010">Changes since 3.0.10</a></li> <li><a href="#v309">Changes since 3.0.9</a></li> @@ -83,7 +87,7 @@ <li><a href="#v30rc3">Changes since RC-3</a></li> <li><a href="#v30rc2">Changes since RC-2</a></li> <li><a href="#v30rc1">Changes since RC-1</a></li> - </ol> + </ul> </li> <li><a href="#disclaimer">Copyright and disclaimer</a></li> </ol> @@ -102,7 +106,119 @@ <div class="content"> - <a name="v311"></a><h3>1.i. Changes since 3.1.1</h3> + <a name="v313rc1"></a><h3>Changes since 3.1.3-RC1</h3> + + <h4>Bug</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12933">PHPBB3-12933</a>] - The search operator for partial matches does not work</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13544">PHPBB3-13544</a>] - Migrations' "permission.permission_unset" deletes all permissions instead of just the one stated</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13556">PHPBB3-13556</a>] - Translated exceptions from file_downloader are handled incorrectly</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13557">PHPBB3-13557</a>] - Migrations for 3.0.13 and PL1 are missing</li> + </ul> + <h4>Task</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13553">PHPBB3-13553</a>] - Controller helper needs a message handler to replace error handler</li> + </ul> + + <a name="v312"></a><h3>Changes since 3.1.2</h3> + + <h4>Security</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13519">PHPBB3-13519</a>] - Correctly validate imagick path as path and not string</li> + </ul> + <h4>Bug</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9100">PHPBB3-9100</a>] - Inline attachments are not being inserted at the cursor</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11613">PHPBB3-11613</a>] - Cookies do not work for netbios domain</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12089">PHPBB3-12089</a>] - Make HTTP status code error messages more informative</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12642">PHPBB3-12642</a>] - Custom profile field isn't displayed</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12698">PHPBB3-12698</a>] - Replace all instances of magic numbers with constants in javascript</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12866">PHPBB3-12866</a>] - Wrong profile field validation options</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13098">PHPBB3-13098</a>] - Repair Yahoo contact field</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13192">PHPBB3-13192</a>] - confirm_box() action contains app.php when enable_mod_rewrite is set</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13238">PHPBB3-13238</a>] - \phpbb\db\migration\data\v310\mysql_fulltext_drop tries to drop non existent indexes</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13272">PHPBB3-13272</a>] - Changed Files packages do not include vendor directory</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13282">PHPBB3-13282</a>] - PostgreSQL error when creating boolean/dropdown custom profile fields</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13302">PHPBB3-13302</a>] - ACP links to docs need to be updated to 3.1 URLs</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13307">PHPBB3-13307</a>] - develop/mysql_upgrader.php does not work anymore</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13319">PHPBB3-13319</a>] - Icons/smilies table improperly formed when no images present</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13346">PHPBB3-13346</a>] - Missing space in posting_editor.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13357">PHPBB3-13357</a>] - LOG_MOVED_TOPIC Language var missing</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13358">PHPBB3-13358</a>] - Add class for retrieving remote file data</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13362">PHPBB3-13362</a>] - The whole cache dir (excluding the .htaccess and index.html files) should be ignored by git</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13366">PHPBB3-13366</a>] - Dynamic config for "plupload_last_gc" is static</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13381">PHPBB3-13381</a>] - Code Sniffer complains about 3.1.2 migration</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13385">PHPBB3-13385</a>] - Add free result after running update query in $config->set_atomic()</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13391">PHPBB3-13391</a>] - subsilver2 poll options must have a setting of 1 when editing a post</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13393">PHPBB3-13393</a>] - Invalid parameters passed to call_user_func_array in version_helper.php</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13396">PHPBB3-13396</a>] - Multibyte chars cause attachment upload to fail</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13400">PHPBB3-13400</a>] - Add a new message for high server loads during search</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13405">PHPBB3-13405</a>] - A typo in style_update_p1.php migration may prevent updating in some circumstances</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13406">PHPBB3-13406</a>] - ADD INDEX syntax may cause an error in earlier MySQL versions</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13420">PHPBB3-13420</a>] - Prune users bug - filter all with 0 posts</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13427">PHPBB3-13427</a>] - Add template events to MCP front before/after each list</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13431">PHPBB3-13431</a>] - Wrong margin-left for RTL sites in Internet Explorer mobile view</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13432">PHPBB3-13432</a>] - Migrator module tool does not add the needed module language file</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13441">PHPBB3-13441</a>] - functions_convert fails to set global moderators default group</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13442">PHPBB3-13442</a>] - UTF-8 symbols for database host</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13448">PHPBB3-13448</a>] - \phpbb\messenger->template can't find email templates in extensions</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13453">PHPBB3-13453</a>] - Sort params in Canonical URL</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13470">PHPBB3-13470</a>] - Mass email says "user doesn't exist" when all users is selected</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13486">PHPBB3-13486</a>] - Call to undefined method phpbb\db\driver\factory::sql_escpape() on database update</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13489">PHPBB3-13489</a>] - Allow the migrations to use the DI container</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13490">PHPBB3-13490</a>] - Unicode chars are broken in edit message after preview</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13492">PHPBB3-13492</a>] - Custom BBCode URL tokens do not support IDN</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13504">PHPBB3-13504</a>] - "Array" is displayed when searching, or when unanswered posts or active topics are selected</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13507">PHPBB3-13507</a>] - Large images in posts can cause horizontal scrollbars</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13511">PHPBB3-13511</a>] - The "Unused Use" Sniff is broken</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13530">PHPBB3-13530</a>] - Fix undefined variables in migrations and tests</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13534">PHPBB3-13534</a>] - Non-existent path in attachment settings causes travis failure</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13543">PHPBB3-13543</a>] - Slow tests fail on 3.1 and 3.2</li> + </ul> + <h4>Improvement</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11033">PHPBB3-11033</a>] - FULLTEXT_SPHINX_NO_CONFIG_DATA references unrequired field</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12567">PHPBB3-12567</a>] - [proSilver] - viewtopic_body.html: Change 'back2top' anchor in to '#top'</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12926">PHPBB3-12926</a>] - Support for IDN (IRI)</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13266">PHPBB3-13266</a>] - Enabling twig dump function if DEBUG is defined</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13306">PHPBB3-13306</a>] - Add error level to the error collector</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13312">PHPBB3-13312</a>] - [event] - Add core event to the mass email form</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13368">PHPBB3-13368</a>] - Add the forum_data var to the core.viewforum_get_topic_ids_data event</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13370">PHPBB3-13370</a>] - Add ability to call class methods more easily in the convertor framework</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13389">PHPBB3-13389</a>] - Replace pattern with path in routing.yml</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13402">PHPBB3-13402</a>] - Code Sniffer, unused use, check the function doc blocks</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13409">PHPBB3-13409</a>] - Add event to modify search parameters before searching</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13419">PHPBB3-13419</a>] - Add template event at the end of the file</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13422">PHPBB3-13422</a>] - Add new events in save custom cookies and set custom ban type</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13428">PHPBB3-13428</a>] - Add core events to memberlist.php for teampage</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13430">PHPBB3-13430</a>] - Add event for modifying prune SQL</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13435">PHPBB3-13435</a>] - Add core event to modify submit_post() sql data</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13437">PHPBB3-13437</a>] - [Template] - viewtopic_body_post_author_before/after</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13439">PHPBB3-13439</a>] - [event] - Add event to run code at beginning of ACP users overview</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13440">PHPBB3-13440</a>] - [event] - Add event to process when a user fails a login attempt</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13449">PHPBB3-13449</a>] - Add viewforum.php core event after the topic data has been assigned to template </li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13466">PHPBB3-13466</a>] - Add bbcode_uid and bitfield to event core.message_parser_check_message</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13478">PHPBB3-13478</a>] - Add core event core.bbcode_cache_init_end</li> + </ul> + <h4>Sub-task</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13141">PHPBB3-13141</a>] - Add an event to allow applying additional permissions to MCP access besides f_read</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13146">PHPBB3-13146</a>] - Add an event to allow changing the result of calling get_forums_visibility_sql()</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13147">PHPBB3-13147</a>] - Add an event to change get_global_visibility_sql()'s results</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13148">PHPBB3-13148</a>] - Add an event to creating a final way to modify edit logs output</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13154">PHPBB3-13154</a>] - Add an event to edit user list for notifications</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13158">PHPBB3-13158</a>] - Add an event to allow adding extra auth checks when the user is posting</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13159">PHPBB3-13159</a>] - Add an event to allow extra auth checks when reporting posts</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13160">PHPBB3-13160</a>] - Add an event to viewtopic before viewing permissions</li> + </ul> + <h4>Task</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12924">PHPBB3-12924</a>] - Meta tags should be self-closing</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13528">PHPBB3-13528</a>] - Boolean checkbox profile fields display "1" instead of selected value</li> + </ul> + + + <a name="v311"></a><h3>Changes since 3.1.1</h3> <h4>Security</h4> <ul> @@ -183,7 +299,7 @@ </ul> - <a name="v310"></a><h3>1.ii. Changes since 3.1.0</h3> + <a name="v310"></a><h3>Changes since 3.1.0</h3> <h4>Security</h4> <ul> @@ -201,7 +317,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13262">PHPBB3-13262</a>] - Add note to docs about htaccess file when upgrading 3.0 to 3.1</li> </ul> - <a name="v310RC6"></a><h3>1.iii. Changes since 3.1.0-RC6</h3> + <a name="v310RC6"></a><h3>Changes since 3.1.0-RC6</h3> <h4>Bug</h4> <ul> @@ -229,7 +345,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13215">PHPBB3-13215</a>] - Update Symfony Components to 2.3.21</li> </ul> - <a name="v310RC5"></a><h3>1.iv. Changes since 3.1.0-RC5</h3> + <a name="v310RC5"></a><h3>Changes since 3.1.0-RC5</h3> <h4>Bug</h4> <ul> @@ -270,7 +386,7 @@ </ul> - <a name="v310RC4"></a><h3>1.v. Changes since 3.1.0-RC4</h3> + <a name="v310RC4"></a><h3>Changes since 3.1.0-RC4</h3> <h4>Bug</h4> <ul> @@ -337,7 +453,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13123">PHPBB3-13123</a>] - Add events to allow post blocking and post pre/past processing</li> </ul> - <a name="v310RC3"></a><h3>1.vi. Changes since 3.1.0-RC3</h3> + <a name="v310RC3"></a><h3>Changes since 3.1.0-RC3</h3> <h4>Bug</h4> <ul> @@ -427,7 +543,7 @@ </ul> - <a name="v310RC2"></a><h3>1.vii. Changes since 3.1.0-RC2</h3> + <a name="v310RC2"></a><h3>Changes since 3.1.0-RC2</h3> <h4>Bug</h4> <ul> @@ -551,7 +667,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12948">PHPBB3-12948</a>] - Remove Travis CI "broken opcache on PHP 5.5.7 and 5.5.8" workaround.</li> </ul> - <a name="v310RC1"></a><h3>1.viii. Changes since 3.1.0-RC1</h3> + <a name="v310RC1"></a><h3>Changes since 3.1.0-RC1</h3> <h4>Bug</h4> <ul> @@ -622,7 +738,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12829">PHPBB3-12829</a>] - Remove check for pgsql 8.3/8.2</li> </ul> - <a name="v310b4"></a><h3>1.ix. Changes since 3.1.0-b4</h3> + <a name="v310b4"></a><h3>Changes since 3.1.0-b4</h3> <h4>Bug</h4> <ul> @@ -742,7 +858,7 @@ </ul> - <a name="v310b3"></a><h3>1.x. Changes since 3.1.0-b3</h3> + <a name="v310b3"></a><h3>Changes since 3.1.0-b3</h3> <h4>Bug</h4> <ul> @@ -849,7 +965,7 @@ </ul> - <a name="v310b2"></a><h3>1.xi. Changes since 3.1.0-b2</h3> + <a name="v310b2"></a><h3>Changes since 3.1.0-b2</h3> <h4>Bug</h4> <ul> @@ -1014,7 +1130,7 @@ </ul> - <a name="v310b1"></a><h3>1.xii. Changes since 3.1.0-b1</h3> + <a name="v310b1"></a><h3>Changes since 3.1.0-b1</h3> <h4>Bug</h4> <ul> @@ -1082,7 +1198,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12302">PHPBB3-12302</a>] - Upgrade composer.phar to 1.0.0-alpha8</li> </ul> - <a name="v310a3"></a><h3>1.xiii. Changes since 3.1.0-a3</h3> + <a name="v310a3"></a><h3>Changes since 3.1.0-a3</h3> <h4>Bug</h4> <ul> @@ -1229,7 +1345,7 @@ </ul> - <a name="v310a2"></a><h3>1.xiv. Changes since 3.1.0-a2</h3> + <a name="v310a2"></a><h3>Changes since 3.1.0-a2</h3> <h4>Bug</h4> <ul> @@ -1337,7 +1453,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12147">PHPBB3-12147</a>] - Remove Travis CI notification configuration</li> </ul> - <a name="v310a1"></a><h3>1.xv. Changes since 3.1.0-a1</h3> + <a name="v310a1"></a><h3>Changes since 3.1.0-a1</h3> <h4>Bug</h4> <ul> @@ -1413,7 +1529,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11998">PHPBB3-11998</a>] - Add console / command line client environment </li> </ul> - <a name="v30x"></a><h3>1.xvi. Changes since 3.0.x</h3> + <a name="v30x"></a><h3>Changes since 3.0.x</h3> <h4>Bug</h4> <ul> @@ -2094,7 +2210,152 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11913">PHPBB3-11913</a>] - Apply reorganisation of download.phpbb.com to build_announcement.php</li> </ul> - <a name="v3011"></a><h3>1.xvii. Changes since 3.0.11</h3> + <a name="v3013"></a><h3>Changes since 3.0.13</h3> + +<h4>Bug</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12933">PHPBB3-12933</a>] - The search operator for partial matches does not work</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13549">PHPBB3-13549</a>] - Compare ORIG_PATH_INFO with SCRIPT_NAME for checking trailing paths</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13554">PHPBB3-13554</a>] - Advertisement of feature release in red indicates a problem</li> +</ul> + + <a name="v3012"></a><h3>Changes since 3.0.12</h3> + +<h4>Security</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13531">PHPBB3-13531</a>] - Disallow trailing paths (e.g. using the PATH_INFO feature) to prevent path-relative CSS injection</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13526">PHPBB3-13526</a>] - Correctly validate ucp_pm_options form key</li> +</ul> +<h4>Bug</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-6703">PHPBB3-6703</a>] - Problem with russian letter while converting from 2.0.x</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8960">PHPBB3-8960</a>] - Allow changing allow_avatar_remote when images/avatars/upload is not writable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9420">PHPBB3-9420</a>] - BBCode - Unable to use a proper URI token</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9724">PHPBB3-9724</a>] - Wrong return "Return to ACP"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9725">PHPBB3-9725</a>] - MSSQL Schema is not azure compatible</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10023">PHPBB3-10023</a>] - Password change requirement notification in UCP is not noticable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10423">PHPBB3-10423</a>] - Searching for the term "test *" will highlight nearly every word and displays htmlspecialchars as htmlentities.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10442">PHPBB3-10442</a>] - XHTML is invalid when a forum link without redirect counter is present</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10687">PHPBB3-10687</a>] - UNABLE_GET_IMAGE_SIZE text misleading for remote avatars</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10729">PHPBB3-10729</a>] - Post editor information is not updated when user being deleted with posts</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10776">PHPBB3-10776</a>] - Grammar errors in docs/README.html</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10796">PHPBB3-10796</a>] - SQL Azure does not allow SELECT FROM sysfiles</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10851">PHPBB3-10851</a>] - HTML files containing certain tags being rejected as possible attack vectors with "Check attachment file" set to "No"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10863">PHPBB3-10863</a>] - Permission mask does not accurately show some forum permissions if user has MOD parmissions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10917">PHPBB3-10917</a>] - Updater notice "Update files are out of date..." when updating to unreleased version</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10985">PHPBB3-10985</a>] - Error bbcode.html not found when updating with custom style inheriting from prosilver</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11062">PHPBB3-11062</a>] - In Automatic Update, new language strings from install.php are only loaded from English</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11224">PHPBB3-11224</a>] - SQL cache destroy does not destroy queries to tables joined</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11288">PHPBB3-11288</a>] - "Fulltext native" search fooled by hyphens</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11480">PHPBB3-11480</a>] - Prevent Private Message system from returning "Unknown folder" when inbox folder is full</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11613">PHPBB3-11613</a>] - Cookies do not work for netbios domain</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11686">PHPBB3-11686</a>] - Not checking for phpBB Debug errors on functional tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11699">PHPBB3-11699</a>] - PHP Lint Test should exclude selected subdirectories of the build directory.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11726">PHPBB3-11726</a>] - Don't run lint tests on Travis on postgres</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11762">PHPBB3-11762</a>] - generate_text_for_display() treats "0" as an empty string</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11789">PHPBB3-11789</a>] - Inline css with color value in subsilver2</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11794">PHPBB3-11794</a>] - Coding Guidelines document says to place a comma after every array element, but fails to do so itself</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11799">PHPBB3-11799</a>] - Anti Abuse Headers missing for sendpassword</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11811">PHPBB3-11811</a>] - Chrome 30 adds outline to focused elements</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11821">PHPBB3-11821</a>] - Wrong comma usage "You are receiving this notification"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11823">PHPBB3-11823</a>] - Travis-CI webserver not matching PHP files with anything after the .php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11829">PHPBB3-11829</a>] - Closed reports may seem open in detailed view</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11860">PHPBB3-11860</a>] - .htaccess not working for Apache 2.4</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11864">PHPBB3-11864</a>] - Do not call exit after display_progress_bar in acp_forums</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11879">PHPBB3-11879</a>] - Compatibility error in forum_fn.js: .live should be replaced with .on</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11968">PHPBB3-11968</a>] - Travis Image are broken due to repository rename</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12037">PHPBB3-12037</a>] - acp_inactive.html has hard-coded text</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12048">PHPBB3-12048</a>] - Custom BBCodes Fail to Render Language Strings with a Number</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12061">PHPBB3-12061</a>] - Keyboard shortcut alt+h doesn't work properly in firefox</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12072">PHPBB3-12072</a>] - Missing word "send" in comment in schema_data.sql</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12093">PHPBB3-12093</a>] - IE 11 javascript selection is no longer supported</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12118">PHPBB3-12118</a>] - Add noindex meta tag to subsilver2 pm/topic view-print template</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12119">PHPBB3-12119</a>] - Remove keywords and description meta tags from prosilver view-print templates</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12120">PHPBB3-12120</a>] - Update docs/AUTHORS for 3.0.13-RC1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12140">PHPBB3-12140</a>] - Avoid endless loop in build script</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12161">PHPBB3-12161</a>] - build/save directories are no longer created</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12162">PHPBB3-12162</a>] - Binary files missing from update packages</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12176">PHPBB3-12176</a>] - No error shown when attempting to delete a founder</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12186">PHPBB3-12186</a>] - MCP should open "Reported posts" instead of PM Reports</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12188">PHPBB3-12188</a>] - Add php 5.6 to travis tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12202">PHPBB3-12202</a>] - Variables read from style.cfg etc. should be htmlspecialchared</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12205">PHPBB3-12205</a>] - Custom Profile Field display bug</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12210">PHPBB3-12210</a>] - dbtools::sql_create_table incorrectly throws error related to auto-increment length on non auto-increment fields</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12310">PHPBB3-12310</a>] - SMTP username and password should not autocomplete during install</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12316">PHPBB3-12316</a>] - develop-ascraeus build status missing from "Automated Testing" section in README.md</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12353">PHPBB3-12353</a>] - User attachments in ACP are not displaying every attachment</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12359">PHPBB3-12359</a>] - Day and Month of Birthday Misaligned When Editing</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12381">PHPBB3-12381</a>] - Broken error message when selecting invalid DB driver</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12397">PHPBB3-12397</a>] - db_tools::sql_unique_index_exists() has wrong doc block</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12429">PHPBB3-12429</a>] - Update phpunit to 3.8+</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12467">PHPBB3-12467</a>] - Add config_*.php and tests_config_*.php to .gitignore</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12472">PHPBB3-12472</a>] - Set fast finish for .travis.yml</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12485">PHPBB3-12485</a>] - Broken tests due to absolute exclude</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12492">PHPBB3-12492</a>] - DB_TEST: Special chars are not supported.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12540">PHPBB3-12540</a>] - WRONG_FILESIZE contains broken placeholders</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12660">PHPBB3-12660</a>] - Undefined offset error when phpinfo() disabled and debug enabled</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12695">PHPBB3-12695</a>] - Undefined index: MISSING_INLINE_ATTACHMENT notice given when viewing post details</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12720">PHPBB3-12720</a>] - Git commit hook should not require commit message to start with a capital letter</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12741">PHPBB3-12741</a>] - Functional tests on Travis fail since php update last night</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12755">PHPBB3-12755</a>] - Remote upload stuck in infinite loop if server sends keep-alive</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13086">PHPBB3-13086</a>] - Update ACP_MASS_EMAIL_EXPLAIN language key</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13096">PHPBB3-13096</a>] - ldap_escape() added to PHP 5.6.0</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13138">PHPBB3-13138</a>] - Banned users cause infinite recursion</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13168">PHPBB3-13168</a>] - Warning displayed in PHP 5.6 for mbstring.http_input</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13234">PHPBB3-13234</a>] - Remember me cookie gets unset by admin reauthentication</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13341">PHPBB3-13341</a>] - Tests fail when generating coverage report</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13376">PHPBB3-13376</a>] - deregister_globals() does not work correctly when $_COOKIE['GLOBALS'] - is specified</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13519">PHPBB3-13519</a>] - Correctly validate imagick path as path and not string</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13523">PHPBB3-13523</a>] - PHP 5.2 Unit Tests no longer work due to deprecated PHPUnit PEAR channel</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13527">PHPBB3-13527</a>] - Escape information received from version server</li> +</ul> +<h4>Improvement</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10037">PHPBB3-10037</a>] - Add Smiley Buttons in Signature Editor</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10174">PHPBB3-10174</a>] - Rename "Ban usernames" to "Ban users" in ACP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10549">PHPBB3-10549</a>] - Languages variables should be used, not hardcoded</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10555">PHPBB3-10555</a>] - Copyright notice in overall_header.html is not translatable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10945">PHPBB3-10945</a>] - Show entered search query in the search box when no results are found.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11254">PHPBB3-11254</a>] - Check CRLF line endings in the test suite</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11295">PHPBB3-11295</a>] - Drop tables for postgres in the test suite</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11297">PHPBB3-11297</a>] - Running tests doc should mention dbunit dependency</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11704">PHPBB3-11704</a>] - phing build script does not include vendor folder, even if there are dependencies</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11766">PHPBB3-11766</a>] - Remove Quote and Edit button when topic is lock</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11801">PHPBB3-11801</a>] - missing semi colons in css</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11814">PHPBB3-11814</a>] - Topic reply notification email text change</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12035">PHPBB3-12035</a>] - Add a link to user's posts in the ACP user overview page</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12106">PHPBB3-12106</a>] - Document exceptions to "Disable Board" in ACP.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12146">PHPBB3-12146</a>] - Add color demo when editing a group from the UCP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12247">PHPBB3-12247</a>] - include poster's username in email notifications of posts that get approved by moderators</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12259">PHPBB3-12259</a>] - Too many redundant tests are run on Travis</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12468">PHPBB3-12468</a>] - Allow mbstring.http_input='' besides 'pass' for PHP 5.6 compatibility</li> +</ul> +<h4>Task</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10839">PHPBB3-10839</a>] - Remove phpunit.xml.functional and always include functional tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11509">PHPBB3-11509</a>] - Travis should check commit message format</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11876">PHPBB3-11876</a>] - Upgrade package checksums from MD5 to SHA256</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11877">PHPBB3-11877</a>] - Create package download links and checksums for announcement via script</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11920">PHPBB3-11920</a>] - Add MariaDB tests to Travis-CI</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11951">PHPBB3-11951</a>] - Add MariaDB to supported RDBMS list</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11970">PHPBB3-11970</a>] - Use 'set -x' in Travis CI setup scripts</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12046">PHPBB3-12046</a>] - Use PHP_BINARY environment variable in lint unit test</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12056">PHPBB3-12056</a>] - Make sure each unit test runs on its own</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12147">PHPBB3-12147</a>] - Remove Travis CI notification configuration</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12302">PHPBB3-12302</a>] - Upgrade composer.phar to 1.0.0-alpha8</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12318">PHPBB3-12318</a>] - Correctly setup HHVM functional tests on Travis CI</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12319">PHPBB3-12319</a>] - Backport Travis CI HHVM environment enabling to develop-olympus.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12320">PHPBB3-12320</a>] - No longer allow Travis CI HHVM environment to fail</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12341">PHPBB3-12341</a>] - Add tests for get_username_string()</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12384">PHPBB3-12384</a>] - Run Travis CI HHVM tests against MySQLi instead of MySQL</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12417">PHPBB3-12417</a>] - hhvm-nightly 2014.04.16~precise breaks tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12495">PHPBB3-12495</a>] - Add Sami to composer dependencies and build script</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12582">PHPBB3-12582</a>] - Strip away copyrighted ICC profile from images</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12917">PHPBB3-12917</a>] - Move commit check and file executable checks to 5.3.3 build on travis</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13324">PHPBB3-13324</a>] - Composer no longer downloads sami/sami and fabpot/goutte</li> +</ul> + + <a name="v3011"></a><h3>Changes since 3.0.11</h3> <h4>Bug</h4> <ul> @@ -2249,7 +2510,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11753">PHPBB3-11753</a>] - Upgrade mysql_upgrader.php schema data.</li> </ul> - <a name="v3010"></a><h3>1.xviii. Changes since 3.0.10</h3> + <a name="v3010"></a><h3>Changes since 3.0.10</h3> <h4>Bug</h4> <ul> @@ -2374,7 +2635,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10909">PHPBB3-10909</a>] - Update Travis Test Configuration: Travis no longer supports PHP 5.3.2</li> </ul> - <a name="v309"></a><h3>1.xix. Changes since 3.0.9</h3> + <a name="v309"></a><h3>Changes since 3.0.9</h3> <h4>Bug</h4> <ul> @@ -2510,7 +2771,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10480">PHPBB3-10480</a>] - Automate changelog building</li> </ul> - <a name="v308"></a><h3>1.xx. Changes since 3.0.8</h3> + <a name="v308"></a><h3>Changes since 3.0.8</h3> <h4> Bug </h4> @@ -2575,7 +2836,7 @@ </li> <li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9924'>PHPBB3-9924</a>] - $template->display hook does not pass $template instance </li> -<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9925'>PHPBB3-9925</a>] - prosilver logo margin bug in IE 6-7-8 +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9925'>PHPBB3-9925</a>] - prosilver logo margin bug in IE 6-7-8 </li> <li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9928'>PHPBB3-9928</a>] - Do not link "login to your board" to the "send statistics" page after completed update. </li> @@ -2583,7 +2844,7 @@ </li> <li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9932'>PHPBB3-9932</a>] - The Bing bot is not added when converting. </li> -<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9933'>PHPBB3-9933</a>] - Wrong handling of consecutive multiple asterisks in word censor +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9933'>PHPBB3-9933</a>] - Wrong handling of consecutive multiple asterisks in word censor </li> <li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9934'>PHPBB3-9934</a>] - Mass Mail missing under the system tab on a fresh install </li> @@ -2595,7 +2856,7 @@ </li> <li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9948'>PHPBB3-9948</a>] - Inline quicktime files won't display </li> -<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9949'>PHPBB3-9949</a>] - $user->lang() is not handling arguments as per documentation +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9949'>PHPBB3-9949</a>] - $user->lang() is not handling arguments as per documentation </li> <li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9950'>PHPBB3-9950</a>] - Problem with localized button images after uprading from 3.0.7-PL1 to 3.0.8 </li> @@ -2758,7 +3019,7 @@ <li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10250'>PHPBB3-10250</a>] - phpBB Logo needs the Registered Trademark Symbol </li> </ul> - + <h4> Improvement </h4> <ul> @@ -2815,7 +3076,7 @@ <li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10186'>PHPBB3-10186</a>] - UCP signature panel displays when not authed for signatures </li> </ul> - + <h4> New Feature </h4> <ul> @@ -2826,7 +3087,7 @@ <li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10110'>PHPBB3-10110</a>] - Redis caching module </li> </ul> - + <h4> Task </h4> <ul> @@ -2865,7 +3126,7 @@ <li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10107'>PHPBB3-10107</a>] - Improve docs for non-apache webserver configuration </li> </ul> - + <h4> Sub-task </h4> <ul> @@ -2877,8 +3138,8 @@ </li> </ul> + <a name="v307-PL1"></a><h3>Changes since 3.0.7-PL1</h3> - <a name="v307-PL1"></a><h3>1.xxi. Changes since 3.0.7-PL1</h3> <h4> Security </h4> <ul> @@ -3335,14 +3596,13 @@ </li> </ul> - - <a name="v307"></a><h3>1.xxii. Changes since 3.0.7</h3> + <a name="v307"></a><h3>Changes since 3.0.7</h3> <ul> <li>[Sec] Do not expose forum content of forums with ACL entries but no actual permission in ATOM Feeds. (Bug #58595)</li> </ul> - <a name="v306"></a><h3>1.xxiii. Changes since 3.0.6</h3> + <a name="v306"></a><h3>Changes since 3.0.6</h3> <ul> <li>[Fix] Allow ban reason and length to be selected and copied in ACP and subsilver2 MCP. (Bug #51095)</li> @@ -3446,7 +3706,7 @@ </ul> - <a name="v305"></a><h3>1.xxiv. Changes since 3.0.5</h3> + <a name="v305"></a><h3>Changes since 3.0.5</h3> <ul> <li>[Fix] Allow whitespaces in avatar gallery names. (Bug #44955)</li> @@ -3668,7 +3928,7 @@ <li>[Feature] Send anonymous statistical information to phpBB on installation and update (optional).</li> </ul> - <a name="v304"></a><h3>1.xxv. Changes since 3.0.4</h3> + <a name="v304"></a><h3>Changes since 3.0.4</h3> <ul> <li>[Fix] Delete user entry from ban list table upon user deletion (Bug #40015 - Patch by TerraFrost)</li> @@ -3757,7 +4017,7 @@ <li>[Sec] Only use forum id supplied for posting if global announcement detected. (Reported by nickvergessen)</li> </ul> - <a name="v303"></a><h3>1.xxvi. Changes since 3.0.3</h3> + <a name="v303"></a><h3>Changes since 3.0.3</h3> <ul> <li>[Fix] Allow mixed-case template directories to be inherited (Bug #36725)</li> @@ -3789,7 +4049,7 @@ <li>[Sec] Ask for forum password if post within passworded forum quoted in private message. (Reported by nickvergessen)</li> </ul> - <a name="v302"></a><h3>1.xxvii. Changes since 3.0.2</h3> + <a name="v302"></a><h3>Changes since 3.0.2</h3> <ul> <li>[Fix] Correctly set topic starter if first post in topic removed (Bug #30575 - Patch by blueray2048)</li> @@ -3888,7 +4148,7 @@ <li>[Sec Precaution] Stricter validation of the HTTP_HOST header (Thanks to Techie-Micheal et al for pointing out possible issues in derived code)</li> </ul> - <a name="v301"></a><h3>1.xxviii. Changes since 3.0.1</h3> + <a name="v301"></a><h3>Changes since 3.0.1</h3> <ul> <li>[Fix] Ability to set permissions on non-mysql dbms (Bug #24955)</li> @@ -3936,7 +4196,7 @@ <li>[Sec] Only allow urls gone through redirect() being used within login_box(). (thanks nookieman)</li> </ul> - <a name="v300"></a><h3>1.xxix. Changes since 3.0.0</h3> + <a name="v300"></a><h3>Changes since 3.0.0</h3> <ul> <li>[Change] Validate birthdays (Bug #15004)</li> @@ -4007,7 +4267,7 @@ <li>[Fix] Find and display colliding usernames correctly when converting from one database to another (Bug #23925)</li> </ul> - <a name="v30rc8"></a><h3>1.xxx. Changes since 3.0.RC8</h3> + <a name="v30rc8"></a><h3>Changes since 3.0.RC8</h3> <ul> <li>[Fix] Cleaned usernames contain only single spaces, so "a_name" and "a__name" are treated as the same name (Bug #15634)</li> @@ -4016,7 +4276,7 @@ <li>[Fix] Call garbage_collection() within database updater to correctly close connections (affects Oracle for example)</li> </ul> - <a name="v30rc7"></a><h3>1.xxxi. Changes since 3.0.RC7</h3> + <a name="v30rc7"></a><h3>Changes since 3.0.RC7</h3> <ul> <li>[Fix] Fixed MSSQL related bug in the update system</li> @@ -4051,7 +4311,7 @@ <li>[Fix] No duplication of active topics (Bug #15474)</li> </ul> - <a name="v30rc6"></a><h3>1.xxxii. Changes since 3.0.RC6</h3> + <a name="v30rc6"></a><h3>Changes since 3.0.RC6</h3> <ul> <li>[Fix] Submitting language changes using acp_language (Bug #14736)</li> @@ -4061,7 +4321,7 @@ <li>[Fix] Able to request new password (Bug #14743)</li> </ul> - <a name="v30rc5"></a><h3>1.xxxiii. Changes since 3.0.RC5</h3> + <a name="v30rc5"></a><h3>Changes since 3.0.RC5</h3> <ul> <li>[Feature] Removing constant PHPBB_EMBEDDED in favor of using an exit_handler(); the constant was meant to achive this more or less.</li> @@ -4124,7 +4384,7 @@ <li>[Sec] New password hashing mechanism for storing passwords (#i42)</li> </ul> - <a name="v30rc4"></a><h3>1.xxxiv. Changes since 3.0.RC4</h3> + <a name="v30rc4"></a><h3>Changes since 3.0.RC4</h3> <ul> <li>[Fix] MySQL, PostgreSQL and SQLite related database fixes (Bug #13862)</li> @@ -4175,7 +4435,7 @@ <li>[Fix] odbc_autocommit causing existing result sets to be dropped (Bug #14182)</li> </ul> - <a name="v30rc3"></a><h3>1.xxxv. Changes since 3.0.RC3</h3> + <a name="v30rc3"></a><h3>Changes since 3.0.RC3</h3> <ul> <li>[Fix] Fixing some subsilver2 and prosilver style issues</li> @@ -4284,7 +4544,7 @@ </ul> - <a name="v30rc2"></a><h3>1.xxxvi. Changes since 3.0.RC2</h3> + <a name="v30rc2"></a><h3>Changes since 3.0.RC2</h3> <ul> <li>[Fix] Re-allow searching within the memberlist</li> @@ -4330,7 +4590,7 @@ </ul> - <a name="v30rc1"></a><h3>1.xxxvii. Changes since 3.0.RC1</h3> + <a name="v30rc1"></a><h3>Changes since 3.0.RC1</h3> <ul> <li>[Fix] (X)HTML issues within the templates (Bug #11255, #11255)</li> diff --git a/phpBB/docs/FAQ.html b/phpBB/docs/FAQ.html index d9ba651032..cd1ec4ae14 100644 --- a/phpBB/docs/FAQ.html +++ b/phpBB/docs/FAQ.html @@ -243,7 +243,7 @@ I want to sue you because i think you host an illegal board!</h2> <div class="content"> -<p>Please read the paragraph about permissions in our extensive <a href="https://www.phpbb.com/support/documentation/3.0/">online documentation</a>.</p> +<p>Please read the paragraph about permissions in our extensive <a href="https://www.phpbb.com/support/docs/en/3.1/ug/">online documentation</a>.</p> </div> @@ -299,7 +299,7 @@ I want to sue you because i think you host an illegal board!</h2> <div class="content"> -<p>Please read our <a href="https://www.phpbb.com/support/documentation/3.0/">extensive user documentation</a> first, it may just explain what you want to know.</p> +<p>Please read our <a href="https://www.phpbb.com/support/docs/en/3.1/ug/">extensive user documentation</a> first, it may just explain what you want to know.</p> <p>Feel free to search our community forum for the information you require. <strong>PLEASE DO NOT</strong> post your question without having first used search, chances are someone has already asked and answered your question. You can find our board here:</p> diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html index 80e09f1bf9..df863917e2 100644 --- a/phpBB/docs/INSTALL.html +++ b/phpBB/docs/INSTALL.html @@ -39,7 +39,7 @@ <p>This document will walk you through the basics on installing, updating and converting the forum software.</p> -<p>A basic overview of running phpBB can be found in the accompanying <a href="README.html">README</a> file. Please ensure you read that document in addition to this! For more detailed information on using, installing, updating and converting phpBB you should read <a href="https://www.phpbb.com/support/documentation/3.0/">the documentation</a> available online.</p> +<p>A basic overview of running phpBB can be found in the accompanying <a href="README.html">README</a> file. Please ensure you read that document in addition to this! For more detailed information on using, installing, updating and converting phpBB you should read <a href="https://www.phpbb.com/support/docs/en/3.1/ug/">the documentation</a> available online.</p> <h1>Install</h1> @@ -297,7 +297,7 @@ <p>This update method is the recommended method for updating. This package detects changed files automatically and merges in changes if needed.</p> - <p>The automatic update package will update the board from a given version to the latest version. A number of automatic update files are available, and you should choose the one that corresponds to the version of the board that you are currently running. For example, if your current version is <strong>3.0.10</strong>, you need the <code>phpBB-3.0.10_to_3.0.11.zip/tar.bz2</code> file.</p> + <p>The automatic update package will update the board from a given version to the latest version. A number of automatic update files are available, and you should choose the one that corresponds to the version of the board that you are currently running. For example, if your current version is <strong>3.0.12</strong>, you need the <code>phpBB-3.0.12_to_3.0.13.zip/tar.bz2</code> file.</p> <p>To perform the update, either follow the instructions from the <strong>Administration Control Panel->System</strong> Tab - this should point out that you are running an outdated version and will guide you through the update - or follow the instructions listed below.</p> diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index 77d5d33115..b66f47178e 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -134,7 +134,7 @@ <p>Installation of these packages is straightforward: simply download the required language pack, uncompress (unzip) it and via FTP transfer the included <code>language</code> and <code>styles</code> folders to the root of your board installation. The language can then be installed via the Administration Control Panel of your board: <code>Customise tab -> Language management -> Language packs</code>. A more detailed description of the process is in the Knowledge Base article, <a href="https://www.phpbb.com/kb/article/how-to-install-a-language-pack/">How to Install a Language Pack</a>.</p> - <p>If your language is not available, please visit our <a href="https://www.phpbb.com/community/viewforum.php?f=66">[3.0.x] Translations</a> forum where you will find topics on translations in progress. Should you wish to volunteer to translate a language not currently available or assist in maintaining an existing language pack, you can <a href="https://www.phpbb.com/languages/apply.php">Apply to become a translator</a>.</p> + <p>If your language is not available, please visit our <a href="https://www.phpbb.com/community/viewforum.php?f=491">[3.1.x] Translations</a> forum where you will find topics on translations in progress. Should you wish to volunteer to translate a language not currently available or assist in maintaining an existing language pack, you can <a href="https://www.phpbb.com/languages/apply.php">Apply to become a translator</a>.</p> <a name="styles"></a><h3>2.ii. Styles</h3> @@ -150,7 +150,7 @@ <a name="extensions"></a><h3>2.iii. Extensions</h3> - <p>We are proud to have a thriving extensions community. These third party extensions to the standard phpBB software, extend its capabilities still further. You can browse through many of the extensions in the <a href="https://www.phpbb.com/customise/db/extensions-27/">Extensions</a> section of our <a href="https://www.phpbb.com/customise/db/">Customisation Database</a>.</p> + <p>We are proud to have a thriving extensions community. These third party extensions to the standard phpBB software, extend its capabilities still further. You can browse through many of the extensions in the <a href="https://www.phpbb.com/customise/db/extensions-36">Extensions</a> section of our <a href="https://www.phpbb.com/customise/db/">Customisation Database</a>.</p> <p>For more information about extensions, please see: <a href="https://www.phpbb.com/extensions">https://www.phpbb.com/extensions</a></p> @@ -180,7 +180,7 @@ <p>Comprehensive documentation is now available on the phpBB website:</p> - <p><a href="https://www.phpbb.com/support/documentation/3.0/">https://www.phpbb.com/support/documentation/3.0/</a></p> + <p><a href="https://www.phpbb.com/support/docs/en/3.1/ug/">https://www.phpbb.com/support/docs/en/3.1/ug/</a></p> <p>This covers everything from installation to setting permissions and managing users.</p> diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index 7863814daa..8086bc9f43 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -456,6 +456,46 @@ mcp_ban_unban_before * Since: 3.1.0-RC3 * Purpose: Add additional fields to the unban form in MCP +mcp_front_latest_logs_after +=== +* Locations: + + styles/prosilver/template/mcp_front.html + + styles/subsilver2/template/mcp_front.html +* Since: 3.1.3-RC1 +* Purpose: Add content after latest logs list + +mcp_front_latest_logs_before +=== +* Locations: + + styles/prosilver/template/mcp_front.html + + styles/subsilver2/template/mcp_front.html +* Since: 3.1.3-RC1 +* Purpose: Add content before latest logs list + +mcp_front_latest_reported_before +=== +* Locations: + + styles/prosilver/template/mcp_front.html + + styles/subsilver2/template/mcp_front.html +* Since: 3.1.3-RC1 +* Purpose: Add content before latest reported posts list + +mcp_front_latest_reported_pms_before +=== +* Locations: + + styles/prosilver/template/mcp_front.html + + styles/subsilver2/template/mcp_front.html +* Since: 3.1.3-RC1 +* Purpose: Add content before latest reported private messages list + +mcp_front_latest_unapproved_before +=== +* Locations: + + styles/prosilver/template/mcp_front.html + + styles/subsilver2/template/mcp_front.html +* Since: 3.1.3-RC1 +* Purpose: Add content before latest unapproved posts list + memberlist_body_username_append === * Locations: @@ -635,6 +675,14 @@ overall_footer_after * Since: 3.1.0-a1 * Purpose: Add content at the end of the file, directly prior to the `</body>` tag +overall_footer_body_after +=== +* Locations: + + styles/prosilver/template/overall_footer.html + + styles/subsilver2/template/overall_footer.html +* Since: 3.1.3-RC1 +* Purpose: Add content before the `</body>` tag but after the $SCRIPTS var, i.e. after the js scripts have been loaded + overall_footer_breadcrumb_append === * Locations: @@ -1407,6 +1455,22 @@ viewtopic_body_poll_question_prepend * Since: 3.1.0-b3 * Purpose: Add content directly before the poll question on the View topic screen +viewtopic_body_post_author_after +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.3-RC1 +* Purpose: Add content directly after the post author on the view topic screen + +viewtopic_body_post_author_before +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.3-RC1 +* Purpose: Add content directly before the post author on the view topic screen + viewtopic_body_post_buttons_after === * Locations: @@ -1467,6 +1531,22 @@ viewtopic_body_postrow_post_content_footer * Since: 3.1.0-RC4 * Purpose: Add data at the end of the posts. +viewtopic_body_postrow_post_details_after +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.4-RC1 +* Purpose: Add content after the post details + +viewtopic_body_postrow_post_details_before +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.4-RC1 +* Purpose: Add content before the post details + viewtopic_body_postrow_post_notices_after === * Locations: diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 2372c1f73c..2873b48fa4 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -153,7 +153,7 @@ class acp_attachments 'img_create_thumbnail' => array('lang' => 'CREATE_THUMBNAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'img_max_thumb_width' => array('lang' => 'MAX_THUMB_WIDTH', 'validate' => 'int:0:999999999999999', 'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'img_min_thumb_filesize' => array('lang' => 'MIN_THUMB_FILESIZE', 'validate' => 'int:0:999999999999999', 'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), - 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'string', 'type' => 'text:20:200', 'explain' => true, 'append' => ' <span>[ <a href="' . $this->u_action . '&action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'), + 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'path', 'type' => 'text:20:200', 'explain' => true, 'append' => ' <span>[ <a href="' . $this->u_action . '&action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'), 'img_max' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'img_link' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), ) diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php index 130a3ef542..e245eea069 100644 --- a/phpBB/includes/acp/acp_bbcodes.php +++ b/phpBB/includes/acp/acp_bbcodes.php @@ -409,7 +409,9 @@ class acp_bbcodes { $bbcode_match = trim($bbcode_match); $bbcode_tpl = trim($bbcode_tpl); - $utf8 = strpos($bbcode_match, 'INTTEXT') !== false; + + // Allow unicode characters for URL|LOCAL_URL|RELATIVE_URL|INTTEXT tokens + $utf8 = preg_match('/(URL|LOCAL_URL|RELATIVE_URL|INTTEXT)/', $bbcode_match); $utf8_pcre_properties = phpbb_pcre_utf8_support(); diff --git a/phpBB/includes/acp/acp_email.php b/phpBB/includes/acp/acp_email.php index 4fefd6bec3..fda9d50779 100644 --- a/phpBB/includes/acp/acp_email.php +++ b/phpBB/includes/acp/acp_email.php @@ -40,6 +40,7 @@ class acp_email $error = array(); $usernames = request_var('usernames', '', true); + $usernames = (!empty($usernames)) ? explode("\n", $usernames) : array(); $group_id = request_var('g', 0); $subject = utf8_normalize_nfc(request_var('subject', '', true)); $message = utf8_normalize_nfc(request_var('message', '', true)); @@ -69,7 +70,7 @@ class acp_email if (!sizeof($error)) { - if ($usernames) + if (!empty($usernames)) { // If giving usernames the admin is able to email inactive users too... $sql_ary = array( @@ -77,7 +78,7 @@ class acp_email 'FROM' => array( USERS_TABLE => '', ), - 'WHERE' => $db->sql_in_set('username_clean', array_map('utf8_clean_string', explode("\n", $usernames))) . ' + 'WHERE' => $db->sql_in_set('username_clean', array_map('utf8_clean_string', $usernames)) . ' AND user_allow_massemail = 1', 'ORDER_BY' => 'user_lang, user_notify_type', ); @@ -194,6 +195,39 @@ class acp_email $errored = false; + $email_template = 'admin_send_email'; + $template_data = array( + 'CONTACT_EMAIL' => phpbb_get_board_contact($config, $phpEx), + 'MESSAGE' => htmlspecialchars_decode($message), + ); + $generate_log_entry = true; + + /** + * Modify email template data before the emails are sent + * + * @event core.acp_email_send_before + * @var string email_template The template to be used for sending the email + * @var string subject The subject of the email + * @var array template_data Array with template data assigned to email template + * @var bool generate_log_entry If false, no log entry will be created + * @var array usernames Usernames which will be displayed in log entry, if it will be created + * @var int group_id The group this email will be sent to + * @var bool use_queue If true, email queue will be used for sending + * @var int priority Priority of sent emails + * @since 3.1.3-RC1 + */ + $vars = array( + 'email_template', + 'subject', + 'template_data', + 'generate_log_entry', + 'usernames', + 'group_id', + 'use_queue', + 'priority', + ); + extract($phpbb_dispatcher->trigger_event('core.acp_email_send_before', compact($vars))); + for ($i = 0, $size = sizeof($email_list); $i < $size; $i++) { $used_lang = $email_list[$i][0]['lang']; @@ -207,17 +241,14 @@ class acp_email $messenger->im($email_row['jabber'], $email_row['name']); } - $messenger->template('admin_send_email', $used_lang); + $messenger->template($email_template, $used_lang); $messenger->anti_abuse_headers($config, $user); $messenger->subject(htmlspecialchars_decode($subject)); $messenger->set_mail_priority($priority); - $messenger->assign_vars(array( - 'CONTACT_EMAIL' => phpbb_get_board_contact($config, $phpEx), - 'MESSAGE' => htmlspecialchars_decode($message)) - ); + $messenger->assign_vars($template_data); if (!($messenger->send($used_method))) { @@ -228,24 +259,26 @@ class acp_email $messenger->save_queue(); - if ($usernames) - { - $usernames = explode("\n", $usernames); - add_log('admin', 'LOG_MASS_EMAIL', implode(', ', utf8_normalize_nfc($usernames))); - } - else + if ($generate_log_entry) { - if ($group_id) + if (!empty($usernames)) { - $group_name = get_group_name($group_id); + add_log('admin', 'LOG_MASS_EMAIL', implode(', ', utf8_normalize_nfc($usernames))); } else { - // Not great but the logging routine doesn't cope well with localising on the fly - $group_name = $user->lang['ALL_USERS']; - } + if ($group_id) + { + $group_name = get_group_name($group_id); + } + else + { + // Not great but the logging routine doesn't cope well with localising on the fly + $group_name = $user->lang['ALL_USERS']; + } - add_log('admin', 'LOG_MASS_EMAIL', $group_name); + add_log('admin', 'LOG_MASS_EMAIL', $group_name); + } } if (!$errored) @@ -281,17 +314,31 @@ class acp_email $s_priority_options .= '<option value="' . MAIL_NORMAL_PRIORITY . '" selected="selected">' . $user->lang['MAIL_NORMAL_PRIORITY'] . '</option>'; $s_priority_options .= '<option value="' . MAIL_HIGH_PRIORITY . '">' . $user->lang['MAIL_HIGH_PRIORITY'] . '</option>'; - $template->assign_vars(array( + $template_data = array( 'S_WARNING' => (sizeof($error)) ? true : false, 'WARNING_MSG' => (sizeof($error)) ? implode('<br />', $error) : '', 'U_ACTION' => $this->u_action, 'S_GROUP_OPTIONS' => $select_list, - 'USERNAMES' => $usernames, + 'USERNAMES' => implode("\n", $usernames), 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_email&field=usernames'), 'SUBJECT' => $subject, 'MESSAGE' => $message, - 'S_PRIORITY_OPTIONS' => $s_priority_options) + 'S_PRIORITY_OPTIONS' => $s_priority_options, ); + /** + * Modify custom email template data before we display the form + * + * @event core.acp_email_display + * @var array template_data Array with template data assigned to email template + * @var array exclude Array with groups which are excluded from group selection + * @var array usernames Usernames which will be displayed in form + * + * @since 3.1.4-RC1 + */ + $vars = array('template_data', 'exclude', 'usernames'); + extract($phpbb_dispatcher->trigger_event('core.acp_email_display', compact($vars))); + + $template->assign_vars($template_data); } } diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index a10b248324..59f15c4890 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -397,7 +397,7 @@ class acp_prune $joined_after = request_var('joined_after', ''); $active = request_var('active', ''); - $count = request_var('count', 0); + $count = ($request->variable('count', '') === '') ? false : $request->variable('count', 0); $active = ($active) ? explode('-', $active) : array(); $joined_before = ($joined_before) ? explode('-', $joined_before) : array(); @@ -439,7 +439,7 @@ class acp_prune $where_sql .= ($username) ? ' AND username_clean ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), utf8_clean_string($username))) : ''; $where_sql .= ($email) ? ' AND user_email ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), $email)) . ' ' : ''; $where_sql .= $joined_sql; - $where_sql .= ($count) ? " AND user_posts " . $key_match[$count_select] . ' ' . (int) $count . ' ' : ''; + $where_sql .= ($count !== false) ? " AND user_posts " . $key_match[$count_select] . ' ' . (int) $count . ' ' : ''; // First handle pruning of users who never logged in, last active date is 0000-00-00 if (sizeof($active) && (int) $active[0] == 0 && (int) $active[1] == 0 && (int) $active[2] == 0) diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 31b033604d..881e50dd5a 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -173,6 +173,21 @@ class acp_users $delete_type = request_var('delete_type', ''); $ip = request_var('ip', 'ip'); + /** + * Run code at beginning of ACP users overview + * + * @event core.acp_users_overview_before + * @var array user_row Current user data + * @var string mode Active module + * @var string action Module that should be run + * @var bool submit Do we display the form only + * or did the user press submit + * @var array error Array holding error messages + * @since 3.1.3-RC1 + */ + $vars = array('user_row', 'mode', 'action', 'submit', 'error'); + extract($phpbb_dispatcher->trigger_event('core.acp_users_overview_before', compact($vars))); + if ($submit) { if ($delete) diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index 3460db4882..5f6dcde448 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -129,7 +129,7 @@ class bbcode */ function bbcode_cache_init() { - global $phpbb_root_path, $phpEx, $config, $user, $phpbb_extension_manager, $phpbb_path_helper; + global $phpbb_root_path, $phpEx, $config, $user, $phpbb_dispatcher, $phpbb_extension_manager, $phpbb_path_helper; if (empty($this->template_filename)) { @@ -388,6 +388,26 @@ class bbcode break; } } + + $bbcode_cache = $this->bbcode_cache; + $bbcode_bitfield = $this->bbcode_bitfield; + $bbcode_uid = $this->bbcode_uid; + + /** + * Use this event to modify the bbcode_cache + * + * @event core.bbcode_cache_init_end + * @var array bbcode_cache The array of cached search and replace patterns of bbcodes + * @var string bbcode_bitfield The bbcode bitfield + * @var string bbcode_uid The bbcode uid + * @since 3.1.3-RC1 + */ + $vars = array('bbcode_cache', 'bbcode_bitfield', 'bbcode_uid'); + extract($phpbb_dispatcher->trigger_event('core.bbcode_cache_init_end', compact($vars))); + + $this->bbcode_cache = $bbcode_cache; + $this->bbcode_bitfield = $bbcode_bitfield; + $this->bbcode_uid = $bbcode_uid; } /** diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 0ac9208aa4..321a87b4b0 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -28,7 +28,7 @@ if (!defined('IN_PHPBB')) */ // phpBB Version -define('PHPBB_VERSION', '3.1.3-RC1-dev'); +define('PHPBB_VERSION', '3.1.4-dev'); // QA-related // define('PHPBB_QA', 1); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 5408f7e281..940484a0ea 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1150,10 +1150,43 @@ function phpbb_timezone_select($template, $user, $default = '', $truncate = fals function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $user_id = 0) { global $db, $user, $config; - global $request, $phpbb_container; + global $request, $phpbb_container, $phpbb_dispatcher; $post_time = ($post_time === 0 || $post_time > time()) ? time() : (int) $post_time; + $should_markread = true; + + /** + * This event is used for performing actions directly before marking forums, + * topics or posts as read. + * + * It is also possible to prevent the marking. For that, the $should_markread parameter + * should be set to FALSE. + * + * @event core.markread_before + * @var string mode Variable containing marking mode value + * @var mixed forum_id Variable containing forum id, or false + * @var mixed topic_id Variable containing topic id, or false + * @var int post_time Variable containing post time + * @var int user_id Variable containing the user id + * @var bool should_markread Flag indicating if the markread should be done or not. + * @since 3.1.4-RC1 + */ + $vars = array( + 'mode', + 'forum_id', + 'topic_id', + 'post_time', + 'user_id', + 'should_markread', + ); + extract($phpbb_dispatcher->trigger_event('core.markread_before', compact($vars))); + + if (!$should_markread) + { + return; + } + if ($mode == 'all') { if ($forum_id === false || !sizeof($forum_id)) @@ -2415,26 +2448,7 @@ function build_url($strip_vars = false) { global $config, $user, $phpbb_path_helper; - $php_ext = $phpbb_path_helper->get_php_ext(); - $page = $user->page['page']; - - // We need to be cautious here. - // On some situations, the redirect path is an absolute URL, sometimes a relative path - // For a relative path, let's prefix it with $phpbb_root_path to point to the correct location, - // else we use the URL directly. - $url_parts = parse_url($page); - - // URL - if ($url_parts === false || empty($url_parts['scheme']) || empty($url_parts['host'])) - { - // Remove 'app.php/' from the page, when rewrite is enabled - if ($config['enable_mod_rewrite'] && strpos($page, 'app.' . $php_ext . '/') === 0) - { - $page = substr($page, strlen('app.' . $php_ext . '/')); - } - - $page = $phpbb_path_helper->get_phpbb_root_path() . $page; - } + $page = $phpbb_path_helper->get_valid_page($user->page['page'], $config['enable_mod_rewrite']); // Append SID $redirect = append_sid($page, false, false); @@ -2676,7 +2690,7 @@ function check_form_key($form_name, $timespan = false) function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_body.html', $u_action = '') { global $user, $template, $db, $request; - global $phpEx, $phpbb_root_path, $request; + global $config, $phpbb_path_helper; if (isset($_POST['cancel'])) { @@ -2738,8 +2752,8 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo } // re-add sid / transform & to & for user->page (user->page is always using &) - $use_page = ($u_action) ? $phpbb_root_path . $u_action : $phpbb_root_path . str_replace('&', '&', $user->page['page']); - $u_action = reapply_sid($use_page); + $use_page = ($u_action) ? $u_action : str_replace('&', '&', $user->page['page']); + $u_action = reapply_sid($phpbb_path_helper->get_valid_page($use_page, $config['enable_mod_rewrite'])); $u_action .= ((strpos($u_action, '?') === false) ? '?' : '&') . 'confirm_key=' . $confirm_key; $template->assign_vars(array( @@ -2941,6 +2955,19 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa break; } + + /** + * This event allows an extension to process when a user fails a login attempt + * + * @event core.login_box_failed + * @var array result Login result data + * @var string username User name used to login + * @var string password Password used to login + * @var string err Error message + * @since 3.1.3-RC1 + */ + $vars = array('result', 'username', 'password', 'err'); + extract($phpbb_dispatcher->trigger_event('core.login_box_failed', compact($vars))); } // Assign credential for username/password pair @@ -3346,23 +3373,33 @@ function get_preg_expression($mode) break; case 'url': + // generated with regex_idn.php file in the develop folder + return "[a-z][a-z\d+\-.]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?"; + break; + case 'url_inline': - $inline = ($mode == 'url') ? ')' : ''; - $scheme = ($mode == 'url') ? '[a-z\d+\-.]' : '[a-z\d+]'; // avoid automatic parsing of "word" in "last word.http://..." - // generated with regex generation file in the develop folder - return "[a-z]$scheme*:/{2}(?:(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?"; + // generated with regex_idn.php file in the develop folder + return "[a-z][a-z\d+]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?"; break; case 'www_url': + // generated with regex_idn.php file in the develop folder + return "www\.(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?"; + break; + case 'www_url_inline': - $inline = ($mode == 'www_url') ? ')' : ''; - return "www\.(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?"; + // generated with regex_idn.php file in the develop folder + return "www\.(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?"; break; case 'relative_url': + // generated with regex_idn.php file in the develop folder + return "(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?"; + break; + case 'relative_url_inline': - $inline = ($mode == 'relative_url') ? ')' : ''; - return "(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?"; + // generated with regex_idn.php file in the develop folder + return "(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?"; break; case 'table_prefix': diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 0b9ea23fe7..b016659541 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2311,7 +2311,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, */ function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync = true) { - global $db; + global $db, $phpbb_dispatcher; if (!is_array($forum_id)) { @@ -2351,6 +2351,21 @@ function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync $sql_and .= ' AND topic_status = ' . ITEM_MOVED . " AND topic_last_post_time < $prune_date"; } + /** + * Use this event to modify the SQL that selects topics to be pruned + * + * @event core.prune_sql + * @var string forum_id The forum id + * @var string prune_mode The prune mode + * @var string prune_date The prune date + * @var int prune_flags The prune flags + * @var bool auto_sync Whether or not to perform auto sync + * @var string sql_and SQL text appended to where clause + * @since 3.1.3-RC1 + */ + $vars = array('forum_id', 'prune_mode', 'prune_date', 'prune_flags', 'auto_sync', 'sql_and'); + extract($phpbb_dispatcher->trigger_event('core.prune_sql', compact($vars))); + $sql = 'SELECT topic_id FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_id) . " diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php index 9d480692e9..61ab4721c4 100644 --- a/phpBB/includes/functions_convert.php +++ b/phpBB/includes/functions_convert.php @@ -2148,6 +2148,7 @@ function fix_empty_primary_groups() } $sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . ' WHERE group_id = ' . get_group_id('global_moderators'); + $result = $db->sql_query($sql); $user_ids = array(); while ($row = $db->sql_fetchrow($result)) diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index fbeae50f55..254e65ae3d 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -210,11 +210,6 @@ function send_file_to_browser($attachment, $upload_dir, $category) } } - if ($size) - { - header("Content-Length: $size"); - } - // Close the db connection before sending the file etc. file_gc(false); @@ -238,6 +233,11 @@ function send_file_to_browser($attachment, $upload_dir, $category) exit; } + if ($size) + { + header("Content-Length: $size"); + } + // Try to deliver in chunks @set_time_limit(0); diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index af44f6270e..22ade15b48 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -1825,6 +1825,30 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u break; } + /** + * Modify sql query data for post submitting + * + * @event core.submit_post_modify_sql_data + * @var array data Array with the data for the post + * @var array poll Array with the poll data for the post + * @var string post_mode Variable containing posting mode value + * @var bool sql_data Array with the data for the posting SQL query + * @var string subject Variable containing post subject value + * @var int topic_type Variable containing topic type value + * @var string username Variable containing post author name + * @since 3.1.3-RC1 + */ + $vars = array( + 'data', + 'poll', + 'post_mode', + 'sql_data', + 'subject', + 'topic_type', + 'username', + ); + extract($phpbb_dispatcher->trigger_event('core.submit_post_modify_sql_data', compact($vars))); + // Submit new topic if ($post_mode == 'post') { diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index 12ef94c07a..04a2726d22 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -313,7 +313,7 @@ class bbcode_firstpass extends bbcode $in = str_replace(' ', '%20', $in); // Checking urls - if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) && !preg_match('#^' . get_preg_expression('www_url') . '$#iu', $in)) + if (!preg_match('#^' . get_preg_expression('url') . '$#iu', $in) && !preg_match('#^' . get_preg_expression('www_url') . '$#iu', $in)) { return '[img]' . $in . '[/img]'; } @@ -1172,13 +1172,18 @@ class parse_message extends bbcode_firstpass * @var bool update_this_message Do we alter the parsed message * @var string mode Posting mode * @var string message The message text to parse + * @var string bbcode_bitfield The bbcode_bitfield before parsing + * @var string bbcode_uid The bbcode_uid before parsing * @var bool return Do we return after the event is triggered if $warn_msg is not empty * @var array warn_msg Array of the warning messages * @since 3.1.2-RC1 + * @change 3.1.3-RC1 Added vars $bbcode_bitfield and $bbcode_uid */ $message = $this->message; $warn_msg = $this->warn_msg; $return = false; + $bbcode_bitfield = $this->bbcode_bitfield; + $bbcode_uid = $this->bbcode_uid; $vars = array( 'allow_bbcode', 'allow_magic_url', @@ -1190,12 +1195,16 @@ class parse_message extends bbcode_firstpass 'update_this_message', 'mode', 'message', + 'bbcode_bitfield', + 'bbcode_uid', 'return', 'warn_msg', ); extract($phpbb_dispatcher->trigger_event('core.message_parser_check_message', compact($vars))); $this->message = $message; $this->warn_msg = $warn_msg; + $this->bbcode_bitfield = $bbcode_bitfield; + $this->bbcode_uid = $bbcode_uid; if ($return && !empty($this->warn_msg)) { return (!$update_this_message) ? $return_message : $this->warn_msg; diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index 2195500b57..1d3fb19f67 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -67,9 +67,11 @@ class ucp_prefs * @var bool submit Do we display the form only * or did the user press submit * @var array data Array with current ucp options data + * @var array error Array with list of errors * @since 3.1.0-a1 + * @changed 3.1.4-rc1 Added error variable to the event */ - $vars = array('submit', 'data'); + $vars = array('submit', 'data', 'error'); extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_personal_data', compact($vars))); if ($submit) @@ -83,11 +85,11 @@ class ucp_prefs $data['user_style'] = (int) $user->data['user_style']; } - $error = validate_data($data, array( + $error = array_merge(validate_data($data, array( 'dateformat' => array('string', false, 1, 30), 'lang' => array('language_iso_name'), 'tz' => array('timezone'), - )); + )), $error); if (!check_form_key('ucp_prefs_personal')) { diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index da53d2c143..511f850679 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -38,7 +38,7 @@ $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms); $convertor_data = array( 'forum_name' => 'phpBB 2.0.x', 'version' => '1.0.3', - 'phpbb_version' => '3.1.2', + 'phpbb_version' => '3.1.3', 'author' => '<a href="https://www.phpbb.com/">phpBB Limited</a>', 'dbms' => $dbms, 'dbhost' => $dbhost, diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php index 17161b5eae..6a892a7373 100644 --- a/phpBB/install/install_convert.php +++ b/phpBB/install/install_convert.php @@ -2014,7 +2014,7 @@ class install_convert extends module { $value = $fields[1][$firstkey]; } - else if (is_array($fields[2])) + else if (is_array($fields[2]) && !is_callable($fields[2])) { // Execute complex function/eval/typecast $value = $fields[1]; diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index 103262b516..3bcf5c4f94 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -2083,7 +2083,7 @@ class install_install extends module return array( 'language' => basename(request_var('language', '')), 'dbms' => request_var('dbms', ''), - 'dbhost' => request_var('dbhost', ''), + 'dbhost' => request_var('dbhost', '', true), 'dbport' => request_var('dbport', ''), 'dbuser' => request_var('dbuser', ''), 'dbpasswd' => request_var('dbpasswd', '', true), diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index ea51e5df76..a39bb365d6 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -273,7 +273,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0 INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.1.3-RC1-dev'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.1.4-dev'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400'); @@ -805,7 +805,7 @@ INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_len INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_aol', 'profilefields.type.string', 'phpbb_aol', '40', '5', '255', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 5, 1, '', ''); INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_icq', 'profilefields.type.string', 'phpbb_icq', '20', '3', '15', '', '', '[0-9]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 6, 1, 'SEND_ICQ_MESSAGE', 'https://www.icq.com/people/%s/'); INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_wlm', 'profilefields.type.string', 'phpbb_wlm', '40', '5', '255', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 7, 1, '', ''); -INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_yahoo', 'profilefields.type.string', 'phpbb_yahoo', '40', '5', '255', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 8, 1, 'SEND_YIM_MESSAGE', 'http://edit.yahoo.com/config/send_webmesg?.target=%s&.src=pg'); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_yahoo', 'profilefields.type.string', 'phpbb_yahoo', '40', '5', '255', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 8, 1, 'SEND_YIM_MESSAGE', 'ymsgr:sendim?%s'); INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_facebook', 'profilefields.type.string', 'phpbb_facebook', '20', '5', '50', '', '', '[\w.]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 9, 1, 'VIEW_FACEBOOK_PROFILE', 'http://facebook.com/%s/'); INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_twitter', 'profilefields.type.string', 'phpbb_twitter', '20', '1', '15', '', '', '[\w_]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 10, 1, 'VIEW_TWITTER_PROFILE', 'http://twitter.com/%s'); INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_skype', 'profilefields.type.string', 'phpbb_skype', '20', '6', '32', '', '', '[a-zA-Z][\w\.,\-_]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 11, 1, 'VIEW_SKYPE_PROFILE', 'skype:%s?userinfo'); diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index 91fc1215fc..fdbc4aebd0 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -558,6 +558,7 @@ $lang = array_merge($lang, array( 'LOG_LOCK_POST' => '<strong>Locked post</strong><br />» %s', 'LOG_MERGE' => '<strong>Merged posts</strong> into topic<br />» %s', 'LOG_MOVE' => '<strong>Moved topic</strong><br />» from %1$s to %2$s', + 'LOG_MOVED_TOPIC' => '<strong>Moved topic</strong><br />» %s', 'LOG_PM_REPORT_CLOSED' => '<strong>Closed PM report</strong><br />» %s', 'LOG_PM_REPORT_DELETED' => '<strong>Deleted PM report</strong><br />» %s', 'LOG_POST_APPROVED' => '<strong>Approved post</strong><br />» %s', diff --git a/phpBB/language/en/acp/permissions.php b/phpBB/language/en/acp/permissions.php index 8654a9e88c..1ade2d6eb8 100644 --- a/phpBB/language/en/acp/permissions.php +++ b/phpBB/language/en/acp/permissions.php @@ -54,7 +54,7 @@ $lang = array_merge($lang, array( <br /> - <p>For further information on setting up and managing permissions on your phpBB3 board, please see <a href="https://www.phpbb.com/support/documentation/3.0/quickstart/quick_permissions.html">Chapter 1.5 of our Quick Start Guide</a>.</p> + <p>For further information on setting up and managing permissions on your phpBB3 board, please see the section on <a href="https://www.phpbb.com/support/docs/en/3.1/ug/quickstart/permissions/">Setting permissions of our Quick Start Guide</a>.</p> ', 'ACL_NEVER' => 'Never', diff --git a/phpBB/language/en/acp/search.php b/phpBB/language/en/acp/search.php index 98412cb050..bda965b615 100644 --- a/phpBB/language/en/acp/search.php +++ b/phpBB/language/en/acp/search.php @@ -84,7 +84,7 @@ $lang = array_merge($lang, array( 'FULLTEXT_SPHINX_WRONG_DATABASE' => 'The sphinx search for phpBB supports MySQL and PostgreSQL only.', 'FULLTEXT_SPHINX_CONFIG_FILE' => 'Sphinx config file', 'FULLTEXT_SPHINX_CONFIG_FILE_EXPLAIN' => 'The generated content of the sphinx config file. This data needs to be pasted into the sphinx.conf which is used by sphinx search daemon. Replace the [dbuser] and [dbpassword] placeholders with your database credentials.', - 'FULLTEXT_SPHINX_NO_CONFIG_DATA' => 'The sphinx data and config directory paths are not defined. Please define them to generate the config file.', + 'FULLTEXT_SPHINX_NO_CONFIG_DATA' => 'The sphinx data directory path is not defined. Please define the path and submit to generate the config file.', 'GENERAL_SEARCH_SETTINGS' => 'General search settings', 'GO_TO_SEARCH_INDEX' => 'Go to search index page', diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php index 107de9c64f..dd22e84fcb 100644 --- a/phpBB/language/en/install.php +++ b/phpBB/language/en/install.php @@ -80,7 +80,7 @@ $lang = array_merge($lang, array( 'CONTINUE_OLD_CONVERSION' => 'Continue previously started conversion', 'CONVERT' => 'Convert', 'CONVERT_COMPLETE' => 'Conversion completed', - 'CONVERT_COMPLETE_EXPLAIN' => 'You have now successfully converted your board to phpBB 3.1. You can now login and <a href="../">access your board</a>. Please ensure that the settings were transferred correctly before enabling your board by deleting the install directory. Remember that help on using phpBB is available online via the <a href="https://www.phpbb.com/support/documentation/3.0/">Documentation</a> and the <a href="https://www.phpbb.com/community/viewforum.php?f=46">support forums</a>.', + 'CONVERT_COMPLETE_EXPLAIN' => 'You have now successfully converted your board to phpBB 3.1. You can now login and <a href="../">access your board</a>. Please ensure that the settings were transferred correctly before enabling your board by deleting the install directory. Remember that help on using phpBB is available online via the <a href="https://www.phpbb.com/support/docs/en/3.1/ug/">Documentation</a> and the <a href="https://www.phpbb.com/community/viewforum.php?f=466">support forums</a>.', 'CONVERT_INTRO' => 'Welcome to the phpBB Unified Convertor Framework', 'CONVERT_INTRO_BODY' => 'From here, you are able to import data from other (installed) board systems. The list below shows all the conversion modules currently available. If there is no convertor shown in this list for the board software you wish to convert from, please check our website where further conversion modules may be available for download.', 'CONVERT_NEW_CONVERSION' => 'New conversion', @@ -192,7 +192,7 @@ $lang = array_merge($lang, array( <h2>Convert an existing board to phpBB3</h2> <p>The phpBB Unified Convertor Framework supports the conversion of phpBB 2.0.x and other board systems to phpBB3. If you have an existing board that you wish to convert, please <a href="%2$s">proceed to the convertor</a>.</p> <h2>Go live with your phpBB3!</h2> - <p>Clicking the button below will take you to a form for submitting statistical data to phpBB in your Administration Control Panel (ACP). We would appreciate it if you could help us by sending that information. Afterwards you should take some time to examine the options available to you. Remember that help is available online via the <a href="https://www.phpbb.com/support/documentation/3.0/">Documentation</a>, <a href="%3$s">README</a> and the <a href="https://www.phpbb.com/community/viewforum.php?f=46">Support Forums</a>.</p><p><strong>Please delete, move or rename the install directory before using your board. While this directory exists, only the Administration Control Panel (ACP) will be accessible.</strong>', + <p>Clicking the button below will take you to a form for submitting statistical data to phpBB in your Administration Control Panel (ACP). We would appreciate it if you could help us by sending that information. Afterwards you should take some time to examine the options available to you. Remember that help is available online via the <a href="https://www.phpbb.com/support/docs/en/3.1/ug/">Documentation</a>, <a href="%3$s">README</a> and the <a href="https://www.phpbb.com/community/viewforum.php?f=466">Support Forums</a>.</p><p><strong>Please delete, move or rename the install directory before using your board. While this directory exists, only the Administration Control Panel (ACP) will be accessible.</strong>', 'INSTALL_INTRO' => 'Welcome to Installation', 'INSTALL_INTRO_BODY' => 'With this option, it is possible to install phpBB3 onto your server.</p><p>In order to proceed, you will need your database settings. If you do not know your database settings, please contact your host and ask for them. You will not be able to continue without them. You need:</p> @@ -274,7 +274,7 @@ $lang = array_merge($lang, array( 'MAKE_FOLDER_WRITABLE' => 'Please make sure that this folder exists and is writable by the webserver then try again:<br />»<strong>%s</strong>.', 'MAKE_FOLDERS_WRITABLE' => 'Please make sure that these folders exist and are writable by the webserver then try again:<br />»<strong>%s</strong>.', - 'MYSQL_SCHEMA_UPDATE_REQUIRED' => 'Your MySQL database schema for phpBB is outdated. phpBB detected a schema for MySQL 3.x/4.x, but the server runs on MySQL %2$s.<br /><strong>Before you proceed the update, you need to upgrade the schema.</strong><br /><br />Please refer to the <a href="https://www.phpbb.com/kb/article/doesnt-have-a-default-value-errors/">Knowledge Base article about upgrading the MySQL schema</a>. If you encounter problems, please use <a href="https://www.phpbb.com/community/viewforum.php?f=46">our support forums</a>.', + 'MYSQL_SCHEMA_UPDATE_REQUIRED' => 'Your MySQL database schema for phpBB is outdated. phpBB detected a schema for MySQL 3.x/4.x, but the server runs on MySQL %2$s.<br /><strong>Before you proceed the update, you need to upgrade the schema.</strong><br /><br />Please refer to the <a href="https://www.phpbb.com/kb/article/doesnt-have-a-default-value-errors/">Knowledge Base article about upgrading the MySQL schema</a>. If you encounter problems, please use <a href="https://www.phpbb.com/community/viewforum.php?f=466">our support forums</a>.', 'NAMING_CONFLICT' => 'Naming conflict: %s and %s are both aliases<br /><br />%s', 'NEXT_STEP' => 'Proceed to next step', @@ -345,7 +345,7 @@ $lang = array_merge($lang, array( 'SUB_LICENSE' => 'License', 'SUB_SUPPORT' => 'Support', 'SUCCESSFUL_CONNECT' => 'Successful connection', - 'SUPPORT_BODY' => 'Full support will be provided for the current stable release of phpBB3, free of charge. This includes:</p><ul><li>installation</li><li>configuration</li><li>technical questions</li><li>problems relating to potential bugs in the software</li><li>updating from Release Candidate (RC) versions to the latest stable version</li><li>converting from phpBB 2.0.x to phpBB3</li><li>converting from other discussion board software to phpBB3 (please see the <a href="https://www.phpbb.com/community/viewforum.php?f=486">Convertors Forum</a>)</li></ul><p>We encourage users still running beta versions of phpBB3 to replace their installation with a fresh copy of the latest version.</p><h2>Extensions / Styles</h2><p>For issues relating to Extensions, please post in the appropriate <a href="https://www.phpbb.com/community/viewforum.php?f=451">Extensions Forum</a>.<br />For issues relating to styles, templates and themes, please post in the appropriate <a href="https://www.phpbb.com/community/viewforum.php?f=471">Styles Forum</a>.<br /><br />If your question relates to a specific package, please post directly in the topic dedicated to the package.</p><h2>Obtaining Support</h2><p><a href="https://www.phpbb.com/community/viewtopic.php?f=14&t=571070">The phpBB Welcome Package</a><br /><a href="https://www.phpbb.com/support/">Support Section</a><br /><a href="https://www.phpbb.com/support/documentation/3.1/quickstart/">Quick Start Guide</a><br /><br />To ensure you stay up to date with the latest news and releases, why not <a href="https://www.phpbb.com/support/">subscribe to our mailing list</a>?<br /><br />', + 'SUPPORT_BODY' => 'Full support will be provided for the current stable release of phpBB3, free of charge. This includes:</p><ul><li>installation</li><li>configuration</li><li>technical questions</li><li>problems relating to potential bugs in the software</li><li>updating from Release Candidate (RC) versions to the latest stable version</li><li>converting from phpBB 2.0.x to phpBB3</li><li>converting from other discussion board software to phpBB3 (please see the <a href="https://www.phpbb.com/community/viewforum.php?f=486">Convertors Forum</a>)</li></ul><p>We encourage users still running beta versions of phpBB3 to replace their installation with a fresh copy of the latest version.</p><h2>Extensions / Styles</h2><p>For issues relating to Extensions, please post in the appropriate <a href="https://www.phpbb.com/community/viewforum.php?f=451">Extensions Forum</a>.<br />For issues relating to styles, templates and themes, please post in the appropriate <a href="https://www.phpbb.com/community/viewforum.php?f=471">Styles Forum</a>.<br /><br />If your question relates to a specific package, please post directly in the topic dedicated to the package.</p><h2>Obtaining Support</h2><p><a href="https://www.phpbb.com/community/viewtopic.php?f=14&t=571070">The phpBB Welcome Package</a><br /><a href="https://www.phpbb.com/support/">Support Section</a><br /><a href="https://www.phpbb.com/support/docs/en/3.1/ug/quickstart/">Quick Start Guide</a><br /><br />To ensure you stay up to date with the latest news and releases, why not <a href="https://www.phpbb.com/support/">subscribe to our mailing list</a>?<br /><br />', 'SYNC_FORUMS' => 'Starting to synchronise forums', 'SYNC_POST_COUNT' => 'Synchronising post_counts', 'SYNC_POST_COUNT_ID' => 'Synchronising post_counts from <var>entry</var> %1$s to %2$s.', diff --git a/phpBB/mcp.php b/phpBB/mcp.php index 25765b1af7..f9d46db528 100644 --- a/phpBB/mcp.php +++ b/phpBB/mcp.php @@ -137,6 +137,28 @@ if ($forum_id && !$auth->acl_get('f_read', $forum_id)) trigger_error('NOT_AUTHORISED'); } +/** +* Allow applying additional permissions to MCP access besides f_read +* +* @event core.mcp_global_f_read_auth_after +* @var string action The action the user tried to execute +* @var int forum_id The forum the user tried to access +* @var string mode The MCP module the user is trying to access +* @var p_master module Module system class +* @var bool quickmod True if the user is accessing using quickmod tools +* @var int topic_id The topic the user tried to access +* @since 3.1.3-RC1 +*/ +$vars = array( + 'action', + 'forum_id', + 'mode', + 'module', + 'quickmod', + 'topic_id', +); +extract($phpbb_dispatcher->trigger_event('core.mcp_global_f_read_auth_after', compact($vars))); + if ($forum_id) { $module->acl_forum_id = $forum_id; diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 5a5be6f761..e64dab635b 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -173,6 +173,22 @@ switch ($mode) 'ORDER_BY' => 'u.username_clean ASC', ); + /** + * Modify the query used to get the users for the team page + * + * @event core.memberlist_team_modify_query + * @var array sql_ary Array containing the query + * @var array group_ids Array of group ids + * @var array teampage_data The teampage data + * @since 3.1.3-RC1 + */ + $vars = array( + 'sql_ary', + 'group_ids', + 'teampage_data', + ); + extract($phpbb_dispatcher->trigger_event('core.memberlist_team_modify_query', compact($vars))); + $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary)); $user_ary = $user_ids = $group_users = array(); @@ -285,7 +301,7 @@ switch ($mode) $user_rank_data = phpbb_get_user_rank($row, (($row['user_id'] == ANONYMOUS) ? false : $row['user_posts'])); - $template->assign_block_vars('group.user', array( + $template_vars = array( 'USER_ID' => $row['user_id'], 'FORUMS' => $row['forums'], 'FORUM_OPTIONS' => (isset($row['forums_options'])) ? true : false, @@ -304,7 +320,25 @@ switch ($mode) 'USERNAME' => get_username_string('username', $row['user_id'], $row['username'], $row['user_colour']), 'USER_COLOR' => get_username_string('colour', $row['user_id'], $row['username'], $row['user_colour']), 'U_VIEW_PROFILE' => get_username_string('profile', $row['user_id'], $row['username'], $row['user_colour']), - )); + ); + + /** + * Modify the template vars for displaying the user in the groups on the teampage + * + * @event core.memberlist_team_modify_template_vars + * @var array template_vars Array containing the query + * @var array row Array containing the action user row + * @var array groups_ary Array of groups with all users that should be displayed + * @since 3.1.3-RC1 + */ + $vars = array( + 'template_vars', + 'row', + 'groups_ary', + ); + extract($phpbb_dispatcher->trigger_event('core.memberlist_team_modify_template_vars', compact($vars))); + + $template->assign_block_vars('group.user', $template_vars); if ($config['teampage_memberships'] != 2) { diff --git a/phpBB/phpbb/config/db.php b/phpBB/phpbb/config/db.php index ef20ebf62a..26489bdd34 100644 --- a/phpBB/phpbb/config/db.php +++ b/phpBB/phpbb/config/db.php @@ -145,9 +145,9 @@ class db extends \phpbb\config\config $sql .= " AND config_value = '" . $this->db->sql_escape($old_value) . "'"; } - $result = $this->db->sql_query($sql); + $this->db->sql_query($sql); - if (!$this->db->sql_affectedrows($result) && isset($this->config[$key])) + if (!$this->db->sql_affectedrows() && isset($this->config[$key])) { return false; } diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php index 8bd537586e..c8516d6c85 100644 --- a/phpBB/phpbb/content_visibility.php +++ b/phpBB/phpbb/content_visibility.php @@ -44,6 +44,12 @@ class content_visibility protected $config; /** + * Event dispatcher object + * @var \phpbb\event\dispatcher + */ + protected $phpbb_dispatcher; + + /** * phpBB root path * @var string */ @@ -60,6 +66,7 @@ class content_visibility * * @param \phpbb\auth\auth $auth Auth object * @param \phpbb\config\config $config Config object + * @param \phpbb\event\dispatcher $phpbb_dispatcher Event dispatcher object * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\user $user User object * @param string $phpbb_root_path Root path @@ -69,10 +76,11 @@ class content_visibility * @param string $topics_table Topics table name * @param string $users_table Users table name */ - public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table) + public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\event\dispatcher $phpbb_dispatcher, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table) { $this->auth = $auth; $this->config = $config; + $this->phpbb_dispatcher = $phpbb_dispatcher; $this->db = $db; $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; @@ -160,6 +168,36 @@ class content_visibility $approve_forums = array_intersect($forum_ids, array_keys($this->auth->acl_getf('m_approve', true))); + $get_forums_visibility_sql_overwrite = false; + /** + * Allow changing the result of calling get_forums_visibility_sql + * + * @event core.phpbb_content_visibility_get_forums_visibility_before + * @var string where_sql The action the user tried to execute + * @var string mode Either "topic" or "post" depending on the query this is being used in + * @var array forum_ids Array of forum ids which the posts/topics are limited to + * @var string table_alias Table alias to prefix in SQL queries + * @var array approve_forums Array of forums where the user has m_approve permissions + * @var mixed get_forums_visibility_sql_overwrite If a string, forces the function to return get_forums_visibility_sql_overwrite after executing the event + * If false, get_forums_visibility_sql continues normally + * It must be either boolean or string + * @since 3.1.3-RC1 + */ + $vars = array( + 'where_sql', + 'mode', + 'forum_ids', + 'table_alias', + 'approve_forums', + 'get_forums_visibility_sql_overwrite', + ); + extract($this->phpbb_dispatcher->trigger_event('core.phpbb_content_visibility_get_forums_visibility_before', compact($vars))); + + if ($get_forums_visibility_sql_overwrite !== false) + { + return $get_forums_visibility_sql_overwrite; + } + if (sizeof($approve_forums)) { // Remove moderator forums from the rest @@ -206,6 +244,35 @@ class content_visibility $approve_forums = array_diff(array_keys($this->auth->acl_getf('m_approve', true)), $exclude_forum_ids); + $visibility_sql_overwrite = null; + + /** + * Allow changing the result of calling get_global_visibility_sql + * + * @event core.phpbb_content_visibility_get_global_visibility_before + * @var array where_sqls The action the user tried to execute + * @var string mode Either "topic" or "post" depending on the query this is being used in + * @var array forum_ids Array of forum ids which the posts/topics are limited to + * @var string table_alias Table alias to prefix in SQL queries + * @var array approve_forums Array of forums where the user has m_approve permissions + * @var string visibility_sql_overwrite Forces the function to return an implosion of where_sqls (joined by "OR") + * @since 3.1.3-RC1 + */ + $vars = array( + 'where_sqls', + 'mode', + 'forum_ids', + 'table_alias', + 'approve_forums', + 'visibility_sql_overwrite', + ); + extract($this->phpbb_dispatcher->trigger_event('core.phpbb_content_visibility_get_global_visibility_before', compact($vars))); + + if ($visibility_sql_overwrite) + { + return $visibility_sql_overwrite; + } + if (sizeof($exclude_forum_ids)) { $where_sqls[] = '(' . $this->db->sql_in_set($table_alias . 'forum_id', $exclude_forum_ids, true) . ' diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index 52e6947c2c..c6c470e91b 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -184,15 +184,34 @@ class helper * @param string $message The error message * @param int $code The error code (e.g. 404, 500, 503, etc.) * @return Response A Response instance + * + * @deprecated 3.1.3 (To be removed: 3.3.0) Use exceptions instead. */ public function error($message, $code = 500) { + return $this->message($message, array(), 'INFORMATION', $code); + } + + /** + * Output a message + * + * In case of an error, please throw an exception instead + * + * @param string $message The message to display (must be a language variable) + * @param array $parameters The parameters to use with the language var + * @param string $title Title for the message (must be a language variable) + * @param int $code The HTTP status code (e.g. 404, 500, 503, etc.) + * @return Response A Response instance + */ + public function message($message, array $parameters = array(), $title = 'INFORMATION', $code = 200) + { + array_unshift($parameters, $message); $this->template->assign_vars(array( - 'MESSAGE_TEXT' => $message, - 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'), + 'MESSAGE_TEXT' => call_user_func_array(array($this->user, 'lang'), $parameters), + 'MESSAGE_TITLE' => $this->user->lang($title), )); - return $this->render('message_body.html', $this->user->lang('INFORMATION'), $code); + return $this->render('message_body.html', $this->user->lang($title), $code); } /** diff --git a/phpBB/phpbb/db/migration/container_aware_migration.php b/phpBB/phpbb/db/migration/container_aware_migration.php new file mode 100644 index 0000000000..3b4b49b04b --- /dev/null +++ b/phpBB/phpbb/db/migration/container_aware_migration.php @@ -0,0 +1,36 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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; + +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** +* Abstract base class for container aware database migrations. +*/ +abstract class container_aware_migration extends migration implements ContainerAwareInterface +{ + /** + * @var ContainerInterface + */ + protected $container; + + /** + * {@inheritdoc} + */ + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } +} diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_13.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_13.php new file mode 100644 index 0000000000..310fcc70fc --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_13.php @@ -0,0 +1,37 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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\v30x; + +class release_3_0_13 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.0.13', '>=') && phpbb_version_compare($this->config['version'], '3.1.0-dev', '<'); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v30x\release_3_0_13_rc1'); + } + + public function update_data() + { + return array( + array('if', array( + phpbb_version_compare($this->config['version'], '3.0.13', '<'), + array('config.update', array('version', '3.0.13')), + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_13_pl1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_13_pl1.php new file mode 100644 index 0000000000..b12a96a7fb --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_13_pl1.php @@ -0,0 +1,37 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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\v30x; + +class release_3_0_13_pl1 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.0.13-PL1', '>=') && phpbb_version_compare($this->config['version'], '3.1.0-dev', '<'); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v30x\release_3_0_13'); + } + + public function update_data() + { + return array( + array('if', array( + phpbb_version_compare($this->config['version'], '3.0.13-PL1', '<'), + array('config.update', array('version', '3.0.13-PL1')), + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_13_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_13_rc1.php new file mode 100644 index 0000000000..9ea68fa862 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_13_rc1.php @@ -0,0 +1,37 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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\v30x; + +class release_3_0_13_rc1 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.0.13-RC1', '>=') && phpbb_version_compare($this->config['version'], '3.1.0-dev', '<'); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v30x\release_3_0_12'); + } + + public function update_data() + { + return array( + array('if', array( + phpbb_version_compare($this->config['version'], '3.0.13-RC1', '<'), + array('config.update', array('version', '3.0.13-RC1')), + )), + ); + } +} 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..003ccf8f18 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 @@ -13,7 +13,9 @@ namespace phpbb\db\migration\data\v30x; -class release_3_0_5_rc1 extends \phpbb\db\migration\migration +use phpbb\db\migration\container_aware_migration; + +class release_3_0_5_rc1 extends container_aware_migration { public function effectively_installed() { @@ -55,9 +57,7 @@ class release_3_0_5_rc1 extends \phpbb\db\migration\migration public function hash_old_passwords() { - global $phpbb_container; - - $passwords_manager = $phpbb_container->get('passwords.manager'); + $passwords_manager = $this->container->get('passwords.manager'); $sql = 'SELECT user_id, user_password FROM ' . $this->table_prefix . 'users WHERE user_pass_convert = 1'; @@ -110,7 +110,7 @@ class release_3_0_5_rc1 extends \phpbb\db\migration\migration // Select auth_option_ids... the largest id will be preserved $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . " - WHERE auth_option = '" . $db->sql_escape($option) . "' + WHERE auth_option = '" . $this->db->sql_escape($option) . "' ORDER BY auth_option_id DESC"; // sql_query_limit not possible here, due to bug in postgresql layer $result = $this->db->sql_query($sql); diff --git a/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php b/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php index 4530ebe285..e04a705c91 100644 --- a/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php +++ b/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php @@ -15,10 +15,18 @@ namespace phpbb\db\migration\data\v310; class mysql_fulltext_drop extends \phpbb\db\migration\migration { + protected $indexes; + public function effectively_installed() { // This migration is irrelevant for all non-MySQL DBMSes. - return strpos($this->db->get_sql_layer(), 'mysql') === false; + if (strpos($this->db->get_sql_layer(), 'mysql') === false) + { + return true; + } + + $this->find_indexes_to_drop(); + return empty($this->indexes); } static public function depends_on() @@ -30,6 +38,11 @@ class mysql_fulltext_drop extends \phpbb\db\migration\migration public function update_schema() { + if (empty($this->indexes)) + { + return array(); + } + /* * Drop FULLTEXT indexes related to MySQL fulltext search. * Doing so is equivalent to dropping the search index from the ACP. @@ -40,12 +53,28 @@ class mysql_fulltext_drop extends \phpbb\db\migration\migration */ return array( 'drop_keys' => array( - $this->table_prefix . 'posts' => array( - 'post_subject', - 'post_text', - 'post_content', - ), + $this->table_prefix . 'posts' => $this->indexes, ), ); } + + public function find_indexes_to_drop() + { + if ($this->indexes !== null) + { + return $this->indexes; + } + + $this->indexes = array(); + $potential_keys = array('post_subject', 'post_text', 'post_content'); + foreach ($potential_keys as $key) + { + if ($this->db_tools->sql_index_exists($this->table_prefix . 'posts', $key)) + { + $this->indexes[] = $key; + } + } + + return $this->indexes; + } } diff --git a/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php b/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php index ea442dfb1b..3457c19478 100644 --- a/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php +++ b/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php @@ -15,10 +15,18 @@ namespace phpbb\db\migration\data\v310; class postgres_fulltext_drop extends \phpbb\db\migration\migration { + protected $indexes; + public function effectively_installed() { // This migration is irrelevant for all non-PostgreSQL DBMSes. - return strpos($this->db->get_sql_layer(), 'postgres') === false; + if (strpos($this->db->get_sql_layer(), 'postgres') === false) + { + return true; + } + + $this->find_indexes_to_drop(); + return empty($this->indexes); } static public function depends_on() @@ -30,6 +38,11 @@ class postgres_fulltext_drop extends \phpbb\db\migration\migration public function update_schema() { + if (empty($this->indexes)) + { + return array(); + } + /* * Drop FULLTEXT indexes related to PostgreSQL fulltext search. * Doing so is equivalent to dropping the search index from the ACP. @@ -40,12 +53,28 @@ class postgres_fulltext_drop extends \phpbb\db\migration\migration */ return array( 'drop_keys' => array( - $this->table_prefix . 'posts' => array( - 'post_subject', - 'post_text', - 'post_content', - ), + $this->table_prefix . 'posts' => $this->indexes, ), ); } + + public function find_indexes_to_drop() + { + if ($this->indexes !== null) + { + return $this->indexes; + } + + $this->indexes = array(); + $potential_keys = array('post_subject', 'post_text', 'post_content'); + foreach ($potential_keys as $key) + { + if ($this->db_tools->sql_index_exists($this->table_prefix . 'posts', $key)) + { + $this->indexes[] = $key; + } + } + + return $this->indexes; + } } diff --git a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php index 58845b88ec..85b90da5fa 100644 --- a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php +++ b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php @@ -13,12 +13,14 @@ namespace phpbb\db\migration\data\v310; +use phpbb\db\migration\container_aware_migration; + /** * Migration to convert the Soft Delete MOD for 3.0 * * https://www.phpbb.com/customise/db/mod/soft_delete/ */ -class soft_delete_mod_convert extends \phpbb\db\migration\migration +class soft_delete_mod_convert extends container_aware_migration { static public function depends_on() { @@ -115,19 +117,11 @@ class soft_delete_mod_convert extends \phpbb\db\migration\migration } } + /** + * @return \phpbb\content_visibility + */ protected function get_content_visibility() { - return new \phpbb\content_visibility( - new \phpbb\auth\auth(), - $this->config, - $this->db, - new \phpbb\user('\phpbb\datetime'), - $this->phpbb_root_path, - $this->php_ext, - $this->table_prefix . 'forums', - $this->table_prefix . 'posts', - $this->table_prefix . 'topics', - $this->table_prefix . 'users' - ); + return $this->container->get('content.visibility'); } } diff --git a/phpBB/phpbb/db/migration/data/v31x/plupload_last_gc_dynamic.php b/phpBB/phpbb/db/migration/data/v31x/plupload_last_gc_dynamic.php new file mode 100644 index 0000000000..0783d707c5 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/plupload_last_gc_dynamic.php @@ -0,0 +1,31 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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\v31x; + +class plupload_last_gc_dynamic extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v31x\v312'); + } + + public function update_data() + { + return array( + // Make plupload_last_gc dynamic. + array('config.remove', array('plupload_last_gc')), + array('config.add', array('plupload_last_gc', 0, 1)), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/profilefield_remove_underscore_from_alpha.php b/phpBB/phpbb/db/migration/data/v31x/profilefield_remove_underscore_from_alpha.php new file mode 100644 index 0000000000..60491f8de8 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/profilefield_remove_underscore_from_alpha.php @@ -0,0 +1,47 @@ +<?php + +/** + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited <https://www.phpbb.com> + * @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\v31x; + +class profilefield_remove_underscore_from_alpha extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v31x\v311'); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'remove_underscore_from_alpha_validations'))), + ); + } + + public function remove_underscore_from_alpha_validations() + { + $this->update_validation_rule('[\w]+', '[a-zA-Z0-9]+'); + $this->update_validation_rule('[\w_]+', '[\w]+'); + $this->update_validation_rule('[\w.]+', '[a-zA-Z0-9.]+'); + $this->update_validation_rule('[\w\x20_+\-\[\]]+', '[\w\x20+\-\[\]]+'); + $this->update_validation_rule('[a-zA-Z][\w\.,\-_]+', '[a-zA-Z][\w\.,\-]+'); + } + + public function update_validation_rule($old_validation, $new_validation) + { + $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " + SET field_validation = '" . $this->db->sql_escape($new_validation) . "' + WHERE field_validation = '" . $this->db->sql_escape($old_validation) . "'"; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/profilefield_yahoo_update_url.php b/phpBB/phpbb/db/migration/data/v31x/profilefield_yahoo_update_url.php new file mode 100644 index 0000000000..4df9083bdf --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/profilefield_yahoo_update_url.php @@ -0,0 +1,38 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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\v31x; + +class profilefield_yahoo_update_url extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v31x\v312'); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'update_contact_url'))), + ); + } + + public function update_contact_url() + { + $sql = 'UPDATE ' . $this->table_prefix . "profile_fields + SET field_contact_url = 'ymsgr:sendim?%s' + WHERE field_name = 'phpbb_yahoo' + AND field_contact_url = 'http://edit.yahoo.com/config/send_webmesg?.target=%s&.src=pg'"; + $this->sql_query($sql); + } +} 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 new file mode 100644 index 0000000000..854ed1f568 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/update_custom_bbcodes_with_idn.php @@ -0,0 +1,70 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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\v31x; + +class update_custom_bbcodes_with_idn extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v312', + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'update_bbcodes_table'))), + ); + } + + public function update_bbcodes_table() + { + if (!class_exists('acp_bbcodes')) + { + include($this->phpbb_root_path . 'includes/acp/acp_bbcodes.' . $this->php_ext); + } + + $bbcodes = new \acp_bbcodes(); + + $sql = 'SELECT bbcode_id, bbcode_match, bbcode_tpl + FROM ' . BBCODES_TABLE; + $result = $this->sql_query($sql); + + $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']); + $sql_ary[$row['bbcode_id']] = array( + 'first_pass_match' => $data['first_pass_match'], + 'first_pass_replace' => $data['first_pass_replace'], + 'second_pass_match' => $data['second_pass_match'], + 'second_pass_replace' => $data['second_pass_replace'] + ); + } + } + $this->db->sql_freeresult($result); + + foreach ($sql_ary as $bbcode_id => $bbcode_data) + { + $sql = 'UPDATE ' . BBCODES_TABLE . ' + SET ' . $this->db->sql_build_array('UPDATE', $bbcode_data) . ' + WHERE bbcode_id = ' . (int) $bbcode_id; + $this->sql_query($sql); + } + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/v313.php b/phpBB/phpbb/db/migration/data/v31x/v313.php new file mode 100644 index 0000000000..5a4e21a9b7 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v313.php @@ -0,0 +1,31 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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\v31x; + +class v313 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v313rc2', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.3')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/v313rc1.php b/phpBB/phpbb/db/migration/data/v31x/v313rc1.php new file mode 100644 index 0000000000..e50754f805 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v313rc1.php @@ -0,0 +1,35 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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\v31x; + +class v313rc1 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v30x\release_3_0_13_rc1', + '\phpbb\db\migration\data\v31x\plupload_last_gc_dynamic', + '\phpbb\db\migration\data\v31x\profilefield_remove_underscore_from_alpha', + '\phpbb\db\migration\data\v31x\profilefield_yahoo_update_url', + '\phpbb\db\migration\data\v31x\update_custom_bbcodes_with_idn', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.3-RC1')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/v313rc2.php b/phpBB/phpbb/db/migration/data/v31x/v313rc2.php new file mode 100644 index 0000000000..d832d6f502 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v313rc2.php @@ -0,0 +1,32 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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\v31x; + +class v313rc2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v30x\release_3_0_13_pl1', + '\phpbb\db\migration\data\v31x\v313rc1', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.3-RC2')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/profilefield_base_migration.php b/phpBB/phpbb/db/migration/profilefield_base_migration.php index 9000949a7d..da1a38e2fa 100644 --- a/phpBB/phpbb/db/migration/profilefield_base_migration.php +++ b/phpBB/phpbb/db/migration/profilefield_base_migration.php @@ -13,7 +13,7 @@ namespace phpbb\db\migration; -abstract class profilefield_base_migration extends \phpbb\db\migration\migration +abstract class profilefield_base_migration extends container_aware_migration { protected $profilefield_name; @@ -237,8 +237,7 @@ abstract class profilefield_base_migration extends \phpbb\db\migration\migration if ($profile_row === null) { - global $phpbb_container; - $manager = $phpbb_container->get('profilefields.manager'); + $manager = $this->container->get('profilefields.manager'); $profile_row = $manager->build_insert_sql_array(array()); } diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index db43046a95..035625b095 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -475,6 +475,7 @@ class module implements \phpbb\db\migration\tool\tool_interface if (!class_exists('acp_modules')) { include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext); + $this->user->add_lang('acp/modules'); } $acp_modules = new \acp_modules(); $module = $acp_modules->get_module_infos($basename, $class, true); diff --git a/phpBB/phpbb/db/migration/tool/permission.php b/phpBB/phpbb/db/migration/tool/permission.php index 5cfbc5ca00..1a91127d2d 100644 --- a/phpBB/phpbb/db/migration/tool/permission.php +++ b/phpBB/phpbb/db/migration/tool/permission.php @@ -537,7 +537,8 @@ class permission implements \phpbb\db\migration\tool\tool_interface } $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' - WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); + WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove) . ' + AND role_id = ' . (int) $role_id; $this->db->sql_query($sql); break; diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index d03496eae3..7fc3e787e2 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -13,11 +13,19 @@ namespace phpbb\db; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + /** * The migrator is responsible for applying new migrations in the correct order. */ class migrator { + /** + * @var ContainerInterface + */ + protected $container; + /** @var \phpbb\config\config */ protected $config; @@ -77,15 +85,16 @@ class migrator /** * The output handler. A null handler is configured by default. * - * @var migrator_output_handler + * @var migrator_output_handler_interface */ public $output_handler; /** * 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(ContainerInterface $container, \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) { + $this->container = $container; $this->config = $config; $this->db = $db; $this->db_tools = $db_tools; @@ -172,6 +181,18 @@ class migrator */ public function update() { + $this->container->get('dispatcher')->disable(); + $this->update_do(); + $this->container->get('dispatcher')->enable(); + } + + /** + * Effectively runs a single update step from the next migration to be applied. + * + * @return null + */ + protected function update_do() + { foreach ($this->migrations as $name) { if (!isset($this->migration_state[$name]) || @@ -317,7 +338,7 @@ class migrator catch (\phpbb\db\migration\exception $e) { // Revert the schema changes - $this->revert($name); + $this->revert_do($name); // Rethrow exception throw $e; @@ -337,10 +358,22 @@ class migrator * check if revert() needs to be called again use the migration_state() method. * * @param string $migration String migration name to revert (including any that depend on this migration) - * @return null */ public function revert($migration) { + $this->container->get('dispatcher')->disable(); + $this->revert_do($migration); + $this->container->get('dispatcher')->enable(); + } + + /** + * Effectively runs a single revert step from the last migration installed + * + * @param string $migration String migration name to revert (including any that depend on this migration) + * @return null + */ + protected function revert_do($migration) + { if (!isset($this->migration_state[$migration])) { // Not installed @@ -351,7 +384,7 @@ class migrator { if (!empty($state['migration_depends_on']) && in_array($migration, $state['migration_depends_on'])) { - $this->revert($name); + $this->revert_do($name); } } @@ -742,7 +775,14 @@ class migrator */ protected function get_migration($name) { - return new $name($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix); + $migration = new $name($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix); + + if ($migration instanceof ContainerAwareInterface) + { + $migration->setContainer($this->container); + } + + return $migration; } /** diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index c8d25f23a2..775deccc30 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -1574,7 +1574,15 @@ class tools } else { - $default_val = "'" . $column_data[1] . "'"; + // 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 '; } @@ -2175,7 +2183,7 @@ class tools } // no break case 'mysql_41': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD INDEX ' . $index_name . ' (' . implode(', ', $column) . ')'; break; case 'mssql': diff --git a/phpBB/phpbb/error_collector.php b/phpBB/phpbb/error_collector.php index 7141f83174..bf8efd1065 100644 --- a/phpBB/phpbb/error_collector.php +++ b/phpBB/phpbb/error_collector.php @@ -16,15 +16,28 @@ namespace phpbb; class error_collector { var $errors; + var $error_types; - function __construct() + /** + * Constructor. + * + * The variable $error_types may be set to a mask of PHP error types that + * the collector should keep, e.g. `E_ALL`. If unset, the current value of + * the error_reporting() function will be used to determine which errors + * the collector will keep. + * + * @see PHPBB3-13306 + * @param int|null $error_types + */ + function __construct($error_types = null) { $this->errors = array(); + $this->error_types = $error_types; } function install() { - set_error_handler(array(&$this, 'error_handler')); + set_error_handler(array(&$this, 'error_handler'), ($this->error_types !== null) ? $this->error_types : error_reporting()); } function uninstall() diff --git a/phpBB/phpbb/event/dispatcher.php b/phpBB/phpbb/event/dispatcher.php index 9a786022c2..1c4abeb108 100644 --- a/phpBB/phpbb/event/dispatcher.php +++ b/phpBB/phpbb/event/dispatcher.php @@ -14,6 +14,7 @@ namespace phpbb\event; use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; +use Symfony\Component\EventDispatcher\Event; /** * Extension of the Symfony2 EventDispatcher @@ -32,6 +33,11 @@ use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; class dispatcher extends ContainerAwareEventDispatcher implements dispatcher_interface { /** + * @var bool + */ + protected $disabled = false; + + /** * {@inheritdoc} */ public function trigger_event($eventName, $data = array()) @@ -40,4 +46,33 @@ class dispatcher extends ContainerAwareEventDispatcher implements dispatcher_int $this->dispatch($eventName, $event); return $event->get_data_filtered(array_keys($data)); } + + /** + * {@inheritdoc} + */ + public function dispatch($eventName, Event $event = null) + { + if ($this->disabled) + { + return $event; + } + + return parent::dispatch($eventName, $event); + } + + /** + * {@inheritdoc} + */ + public function disable() + { + $this->disabled = true; + } + + /** + * {@inheritdoc} + */ + public function enable() + { + $this->disabled = false; + } } diff --git a/phpBB/phpbb/event/dispatcher_interface.php b/phpBB/phpbb/event/dispatcher_interface.php index 50a3ef9101..c66aa98260 100644 --- a/phpBB/phpbb/event/dispatcher_interface.php +++ b/phpBB/phpbb/event/dispatcher_interface.php @@ -37,4 +37,14 @@ interface dispatcher_interface extends \Symfony\Component\EventDispatcher\EventD * @return mixed */ public function trigger_event($eventName, $data = array()); + + /** + * Disable the event dispatcher. + */ + public function disable(); + + /** + * Enable the event dispatcher. + */ + public function enable(); } diff --git a/phpBB/phpbb/event/kernel_exception_subscriber.php b/phpBB/phpbb/event/kernel_exception_subscriber.php index 44e87507f9..eb7831ad34 100644 --- a/phpBB/phpbb/event/kernel_exception_subscriber.php +++ b/phpBB/phpbb/event/kernel_exception_subscriber.php @@ -14,9 +14,10 @@ namespace phpbb\event; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; -use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpFoundation\Response; class kernel_exception_subscriber implements EventSubscriberInterface @@ -53,23 +54,55 @@ class kernel_exception_subscriber implements EventSubscriberInterface */ public function on_kernel_exception(GetResponseForExceptionEvent $event) { - page_header($this->user->lang('INFORMATION')); - $exception = $event->getException(); - $this->template->assign_vars(array( - 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'), - 'MESSAGE_TEXT' => $exception->getMessage(), - )); + $message = $exception->getMessage(); + + if ($exception instanceof \phpbb\exception\exception_interface) + { + $message = call_user_func_array(array($this->user, 'lang'), array_merge(array($message), $exception->get_parameters())); + } + + if (!$event->getRequest()->isXmlHttpRequest()) + { + page_header($this->user->lang('INFORMATION')); + + $this->template->assign_vars(array( + 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'), + 'MESSAGE_TEXT' => $message, + )); + + $this->template->set_filenames(array( + 'body' => 'message_body.html', + )); + + page_footer(true, false, false); + + $response = new Response($this->template->assign_display('body'), 500); + } + else + { + $data = array(); + + if (!empty($message)) + { + $data['message'] = $message; + } + + if (defined('DEBUG')) + { + $data['trace'] = $exception->getTrace(); + } - $this->template->set_filenames(array( - 'body' => 'message_body.html', - )); + $response = new JsonResponse($data, 500); + } - page_footer(true, false, false); + if ($exception instanceof HttpExceptionInterface) + { + $response->setStatusCode($exception->getStatusCode()); + $response->headers->add($exception->getHeaders()); + } - $status_code = $exception instanceof HttpException ? $exception->getStatusCode() : 500; - $response = new Response($this->template->assign_display('body'), $status_code); $event->setResponse($response); } diff --git a/phpBB/phpbb/exception/exception_interface.php b/phpBB/phpbb/exception/exception_interface.php new file mode 100644 index 0000000000..e8526a35f5 --- /dev/null +++ b/phpBB/phpbb/exception/exception_interface.php @@ -0,0 +1,29 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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; + +/** + * Interface exception_interface + * + * Define an exception which support a language var as message. + */ +interface exception_interface +{ + /** + * Return the arguments associated with the message if it's a language var. + * + * @return array + */ + public function get_parameters(); +} diff --git a/phpBB/phpbb/exception/http_exception.php b/phpBB/phpbb/exception/http_exception.php new file mode 100644 index 0000000000..0e6ffe4f59 --- /dev/null +++ b/phpBB/phpbb/exception/http_exception.php @@ -0,0 +1,70 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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; + +use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; + +/** + * Class http_exception + */ +class http_exception extends runtime_exception implements HttpExceptionInterface +{ + /** + * Http status code. + * + * @var integer + */ + private $status_code; + + /** + * Additional headers to set in the response. + * + * @var array + */ + private $headers; + + /** + * Constructor + * + * @param integer $status_code The http status code. + * @param string $message The Exception message to throw (must be a language variable). + * @param array $parameters The parameters to use with the language var. + * @param \Exception $previous The previous exception used for the exception chaining. + * @param array $headers Additional headers to set in the response. + * @param integer $code The Exception code. + */ + public function __construct($status_code, $message = "", array $parameters = array(), \Exception $previous = null, array $headers = array(), $code = 0) + { + $this->status_code = $status_code; + $this->headers = $headers; + + parent::__construct($message, $parameters, $previous, $code); + } + + /** + * {@inheritdoc} + */ + public function getStatusCode() + { + return $this->status_code; + } + + /** + * {@inheritdoc} + */ + public function getHeaders() + { + return $this->headers; + } +} diff --git a/phpBB/phpbb/exception/runtime_exception.php b/phpBB/phpbb/exception/runtime_exception.php new file mode 100644 index 0000000000..6568bbf86f --- /dev/null +++ b/phpBB/phpbb/exception/runtime_exception.php @@ -0,0 +1,52 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @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; + +/** + * Class runtime_exception + * + * Define an exception which support a language var as message. + */ +class runtime_exception extends \RuntimeException implements exception_interface +{ + /** + * Parameters to use with the language var. + * + * @var array + */ + private $parameters; + + /** + * Constructor + * + * @param string $message The Exception message to throw (must be a language variable). + * @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 = "", array $parameters = array(), \Exception $previous = null, $code = 0) + { + $this->parameters = $parameters; + + parent::__construct($message, $code, $previous); + } + + /** + * {@inheritdoc} + */ + public function get_parameters() + { + return $this->parameters; + } +} diff --git a/phpBB/phpbb/file_downloader.php b/phpBB/phpbb/file_downloader.php index d717b394d5..ca8b1f4534 100644 --- a/phpBB/phpbb/file_downloader.php +++ b/phpBB/phpbb/file_downloader.php @@ -33,7 +33,7 @@ class file_downloader * @return mixed File data as string if file can be read and there is no * timeout, false if there were errors or the connection timed out * - * @throws \RuntimeException If data can't be retrieved and no error + * @throws \phpbb\exception\runtime_exception If data can't be retrieved and no error * message is returned */ public function get($host, $directory, $filename, $port = 80, $timeout = 6) @@ -69,7 +69,7 @@ class file_downloader } else if (stripos($line, '404 not found') !== false) { - throw new \RuntimeException(array('FILE_NOT_FOUND', $filename)); + throw new \phpbb\exception\runtime_exception('FILE_NOT_FOUND', array($filename)); } } @@ -77,7 +77,7 @@ class file_downloader if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) { - throw new \RuntimeException('FSOCK_TIMEOUT'); + throw new \phpbb\exception\runtime_exception('FSOCK_TIMEOUT'); } } @fclose($socket); diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php index 2af8b50b54..0c5205530b 100644 --- a/phpBB/phpbb/log/log.php +++ b/phpBB/phpbb/log/log.php @@ -708,6 +708,50 @@ class log implements \phpbb\log\log_interface } } + /** + * Allow modifying or execute extra final filter on log entries + * + * @event core.get_logs_after + * @var array log Array with all our log entries + * @var array topic_id_list Array of topic ids, for which we + * get the permission data + * @var array reportee_id_list Array of additional user IDs we + * get the username strings for + * @var string mode Mode of the entries we display + * @var bool count_logs Do we count all matching entries? + * @var int limit Limit the number of entries + * @var int offset Offset when fetching the entries + * @var mixed forum_id Limit entries to the forum_id, + * can also be an array of forum_ids + * @var int topic_id Limit entries to the topic_id + * @var int user_id Limit entries to the user_id + * @var int log_time Limit maximum age of log entries + * @var string sort_by SQL order option + * @var string keywords Will only return entries that have the + * keywords in log_operation or log_data + * @var string profile_url URL to the users profile + * @var int log_type The type of logs it was filtered + * @since 3.1.3-RC1 + */ + $vars = array( + 'log', + 'topic_id_list', + 'reportee_id_list', + 'mode', + 'count_logs', + 'limit', + 'offset', + 'forum_id', + 'topic_id', + 'user_id', + 'log_time', + 'sort_by', + 'keywords', + 'profile_url', + 'log_type', + ); + extract($this->dispatcher->trigger_event('core.get_logs_after', compact($vars))); + return $log; } diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index dd611e1dd1..aa52eb61d0 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -38,6 +38,9 @@ class manager /** @var \phpbb\config\config */ protected $config; + /** @var \phpbb\event\dispatcher */ + protected $phpbb_dispatcher; + /** @var \phpbb\db\driver\driver_interface */ protected $db; @@ -70,6 +73,7 @@ class manager * @param ContainerInterface $phpbb_container * @param \phpbb\user_loader $user_loader * @param \phpbb\config\config $config + * @param \phpbb\event\dispatcher $phpbb_dispatcher * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\cache\service $cache * @param \phpbb\user $user @@ -81,7 +85,7 @@ class manager * * @return \phpbb\notification\manager */ - public function __construct($notification_types, $notification_methods, ContainerInterface $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) + public function __construct($notification_types, $notification_methods, ContainerInterface $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\config\config $config, \phpbb\event\dispatcher $phpbb_dispatcher, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) { $this->notification_types = $notification_types; $this->notification_methods = $notification_methods; @@ -89,6 +93,7 @@ class manager $this->user_loader = $user_loader; $this->config = $config; + $this->phpbb_dispatcher = $phpbb_dispatcher; $this->db = $db; $this->cache = $cache; $this->user = $user; @@ -350,6 +355,26 @@ class manager // 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); + /** + * Allow filtering the notify_users array for a notification that is about to be sent. + * Here, $notify_users is already filtered by f_read and the ignored list included in the options variable + * + * @event core.notification_manager_add_notifications + * @var string notification_type_name The forum id from where the topic belongs + * @var array data Data specific for the notification_type_name used will be inserted + * @var array notify_users The array of userid that are going to be notified for this notification. Set to array() to cancel. + * @var array options The options that were used when this method was called (read only) + * + * @since 3.1.3-RC1 + */ + $vars = array( + 'notification_type_name', + 'data', + 'notify_users', + 'options', + ); + extract($this->phpbb_dispatcher->trigger_event('core.notification_manager_add_notifications', compact($vars))); + $this->add_notifications_for_users($notification_type_name, $data, $notify_users); return $notify_users; diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php index b49d8d13c2..5400c1c5a6 100644 --- a/phpBB/phpbb/path_helper.php +++ b/phpBB/phpbb/path_helper.php @@ -455,4 +455,38 @@ class path_helper return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : ''); } + + /** + * Get a valid page + * + * @param string $page The page to verify + * @param bool $mod_rewrite Whether mod_rewrite is enabled, default: false + * + * @return string A valid page based on given page and mod_rewrite + */ + public function get_valid_page($page, $mod_rewrite = false) + { + // We need to be cautious here. + // On some situations, the redirect path is an absolute URL, sometimes a relative path + // For a relative path, let's prefix it with $phpbb_root_path to point to the correct location, + // else we use the URL directly. + $url_parts = parse_url($page); + + // URL + if ($url_parts === false || empty($url_parts['scheme']) || empty($url_parts['host'])) + { + // Remove 'app.php/' from the page, when rewrite is enabled. + // Treat app.php as a reserved file name and remove on mod rewrite + // even if it might not be in the phpBB root. + if ($mod_rewrite && ($app_position = strpos($page, 'app.' . $this->php_ext . '/')) !== false) + { + $page = substr($page, 0, $app_position) . substr($page, $app_position + strlen('app.' . $this->php_ext . '/')); + } + + // Remove preceding slashes from page name and prepend root path + $page = $this->get_phpbb_root_path() . ltrim($page, '/\\'); + } + + return $page; + } } diff --git a/phpBB/phpbb/profilefields/type/type_bool.php b/phpBB/phpbb/profilefields/type/type_bool.php index 75934e3be7..f6f3f17a6c 100644 --- a/phpBB/phpbb/profilefields/type/type_bool.php +++ b/phpBB/phpbb/profilefields/type/type_bool.php @@ -173,7 +173,7 @@ class type_bool extends type_base } else { - return $this->lang_helper->is_set($field_id, $lang_id, $field_value + 1); + return $this->lang_helper->is_set($field_id, $lang_id, $field_value + 1) ? $this->lang_helper->get($field_id, $lang_id, $field_value + 1) : null; } } @@ -367,29 +367,29 @@ class type_bool extends type_base */ public function prepare_hidden_fields($step, $key, $action, &$field_data) { - if ($key == 'l_lang_options' && $this->request->is_set('l_lang_options')) + if ($key == 'field_default_value') { - return $this->request->variable($key, array(array('')), true); - } - else if ($key == 'field_default_value') - { - return $this->request->variable($key, $field_data[$key]); - } - else - { - if (!$this->request->is_set($key)) - { - return false; - } - else if ($key == 'field_ident' && isset($field_data[$key])) - { - return $field_data[$key]; - } - else + $field_length = $this->request->variable('field_length', 0); + + // Do a simple is set check if using checkbox. + if ($field_length == 2) { - return ($key == 'lang_options') ? $this->request->variable($key, array(''), true) : $this->request->variable($key, '', true); + return $this->request->is_set($key); } + return $this->request->variable($key, $field_data[$key], true); + } + + $default_lang_options = array( + 'l_lang_options' => array(0 => array('')), + 'lang_options' => array(0 => ''), + ); + + if (isset($default_lang_options[$key]) && $this->request->is_set($key)) + { + return $this->request->variable($key, $default_lang_options[$key], true); } + + return parent::prepare_hidden_fields($step, $key, $action, $field_data); } /** diff --git a/phpBB/phpbb/profilefields/type/type_string_common.php b/phpBB/phpbb/profilefields/type/type_string_common.php index ff33a7b49c..f5e1992044 100644 --- a/phpBB/phpbb/profilefields/type/type_string_common.php +++ b/phpBB/phpbb/profilefields/type/type_string_common.php @@ -18,11 +18,11 @@ abstract class type_string_common extends type_base protected $validation_options = array( 'CHARS_ANY' => '.*', 'NUMBERS_ONLY' => '[0-9]+', - 'ALPHA_ONLY' => '[\w]+', - 'ALPHA_UNDERSCORE' => '[\w_]+', - 'ALPHA_DOTS' => '[\w.]+', - 'ALPHA_SPACERS' => '[\w\x20_+\-\[\]]+', - 'ALPHA_PUNCTUATION' => '[a-zA-Z][\w\.,\-_]+', + 'ALPHA_ONLY' => '[a-zA-Z0-9]+', + 'ALPHA_UNDERSCORE' => '[\w]+', + 'ALPHA_DOTS' => '[a-zA-Z0-9.]+', + 'ALPHA_SPACERS' => '[\w\x20+\-\[\]]+', + 'ALPHA_PUNCTUATION' => '[a-zA-Z][\w\.,\-]+', 'LETTER_NUM_ONLY' => '[\p{Lu}\p{Ll}0-9]+', 'LETTER_NUM_UNDERSCORE' => '[\p{Lu}\p{Ll}0-9_]+', 'LETTER_NUM_DOTS' => '[\p{Lu}\p{Ll}0-9.]+', diff --git a/phpBB/phpbb/profilefields/type/type_url.php b/phpBB/phpbb/profilefields/type/type_url.php index bc8ac869d0..fe0bffd582 100644 --- a/phpBB/phpbb/profilefields/type/type_url.php +++ b/phpBB/phpbb/profilefields/type/type_url.php @@ -64,7 +64,7 @@ class type_url extends type_string return false; } - if (!preg_match('#^' . get_preg_expression('url') . '$#i', $field_value)) + if (!preg_match('#^' . get_preg_expression('url') . '$#iu', $field_value)) { return $this->user->lang('FIELD_INVALID_URL', $this->get_field_name($field_data['lang_name'])); } diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 48b0f077c7..93ea46ca60 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -300,7 +300,7 @@ class fulltext_native extends \phpbb\search\base $this->search_query = $keywords; $exact_words = array(); - preg_match_all('#([^\\s+\\-|*()]+)(?:$|[\\s+\\-|()])#u', $keywords, $exact_words); + preg_match_all('#([^\\s+\\-|()]+)(?:$|[\\s+\\-|()])#u', $keywords, $exact_words); $exact_words = $exact_words[1]; $common_ids = $words = array(); @@ -434,7 +434,7 @@ class fulltext_native extends \phpbb\search\base // throw an error if we shall not ignore unexistant words else if (!$ignore_no_id && sizeof($non_common_words)) { - trigger_error(sprintf($user->lang['WORDS_IN_NO_POST'], implode($user->lang['COMMA_SEPARATOR'], $non_common_words))); + trigger_error(sprintf($this->user->lang['WORDS_IN_NO_POST'], implode($this->user->lang['COMMA_SEPARATOR'], $non_common_words))); } unset($non_common_words); } diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 691d0d5bef..0a6a18ffbe 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -1082,7 +1082,7 @@ class session */ function check_ban($user_id = false, $user_ips = false, $user_email = false, $return = false) { - global $config, $db; + global $config, $db, $phpbb_dispatcher; if (defined('IN_CHECK_BAN') || defined('SKIP_CHECK_BAN')) { @@ -1196,6 +1196,20 @@ class session } $db->sql_freeresult($result); + /** + * Event to set custom ban type + * + * @event core.session_set_custom_ban + * @var bool return If $return is false this routine does not return on finding a banned user, it outputs a relevant message and stops execution + * @var bool banned Check if user already banned + * @var array|false ban_row Ban data + * @var string ban_triggered_by Method that caused ban, can be your custom method + * @since 3.1.3-RC1 + */ + $ban_row = isset($ban_row) ? $ban_row : false; + $vars = array('return', 'banned', 'ban_row', 'ban_triggered_by'); + extract($phpbb_dispatcher->trigger_event('core.session_set_custom_ban', compact($vars))); + if ($banned && !$return) { global $template, $phpbb_root_path, $phpEx; diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php index 5b71bb5e8a..bd754d9bbd 100644 --- a/phpBB/phpbb/template/twig/twig.php +++ b/phpBB/phpbb/template/twig/twig.php @@ -115,6 +115,11 @@ class twig extends \phpbb\template\base ) ); + if (defined('DEBUG')) + { + $this->twig->addExtension(new \Twig_Extension_Debug()); + } + $lexer = new \phpbb\template\twig\lexer($this->twig); $this->twig->setLexer($lexer); @@ -280,19 +285,19 @@ class twig extends \phpbb\template\base $ext_style_theme_path = $ext_style_path . 'theme/'; } - $ok = false; + $is_valid_dir = false; if (is_dir($ext_style_template_path)) { - $ok = true; + $is_valid_dir = true; $paths[] = $ext_style_template_path; } if (is_dir($ext_style_theme_path)) { - $ok = true; + $is_valid_dir = true; $paths[] = $ext_style_theme_path; } - if ($ok) + if ($is_valid_dir) { // Add the base style directory as a safe directory $this->twig->getLoader()->addSafeDirectory($ext_style_path); diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index dc62f06fb2..e4f68f5aab 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -257,9 +257,10 @@ class version_helper try { $info = $this->file_downloader->get($this->host, $this->path, $this->file); } - catch (\RuntimeException $exception) + catch (\phpbb\exception\runtime_exception $exception) { - throw new \RuntimeException($this->user->lang($exception->getMessage())); + $prepare_parameters = array_merge(array($exception->getMessage()), $exception->get_parameters()); + throw new \RuntimeException(call_user_func_array(array($this->user, 'lang'), $prepare_parameters)); } $error_string = $this->file_downloader->get_error_string(); diff --git a/phpBB/posting.php b/phpBB/posting.php index dda7455845..ac412c0c73 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -344,6 +344,48 @@ switch ($mode) } break; } +/** +* This event allows you to do extra auth checks and verify if the user +* has the required permissions +* +* Extensions should only change the error and is_authed variables. +* +* @event core.modify_posting_auth +* @var int post_id ID of the post +* @var int topic_id ID of the topic +* @var int forum_id ID of the forum +* @var int draft_id ID of the draft +* @var int lastclick Timestamp of when the form was last loaded +* @var bool submit Whether or not the form has been submitted +* @var bool preview Whether or not the post is being previewed +* @var bool save Whether or not a draft is being saved +* @var bool load Whether or not a draft is being loaded +* @var bool refresh Whether or not to retain previously submitted data +* @var string mode What action to take if the form has been submitted +* post|reply|quote|edit|delete|bump|smilies|popup +* @var array error Any error strings; a non-empty array aborts +* form submission. +* NOTE: Should be actual language strings, NOT +* language keys. +* @var bool is_authed Does the user have the required permissions? +* @since 3.1.3-RC1 +*/ +$vars = array( + 'post_id', + 'topic_id', + 'forum_id', + 'draft_id', + 'lastclick', + 'submit', + 'preview', + 'save', + 'load', + 'refresh', + 'mode', + 'error', + 'is_authed', +); +extract($phpbb_dispatcher->trigger_event('core.modify_posting_auth', compact($vars))); if (!$is_authed) { @@ -1694,7 +1736,7 @@ $page_data = array( 'POST_DATE' => ($post_data['post_time']) ? $user->format_date($post_data['post_time']) : '', 'ERROR' => (sizeof($error)) ? implode('<br />', $error) : '', 'TOPIC_TIME_LIMIT' => (int) $post_data['topic_time_limit'], - 'EDIT_REASON' => $request->variable('edit_reason', ''), + 'EDIT_REASON' => $request->variable('edit_reason', '', true), 'SHOW_PANEL' => $request->variable('show_panel', ''), 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id"), 'U_VIEW_TOPIC' => ($mode != 'post') ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id") : '', diff --git a/phpBB/report.php b/phpBB/report.php index 1b5d3c9d46..3ea6bb40c5 100644 --- a/phpBB/report.php +++ b/phpBB/report.php @@ -99,6 +99,24 @@ if ($post_id) // Check required permissions $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($phpbb_dispatcher->trigger_event('core.report_post_auth', compact($vars))); + foreach ($acl_check_ary as $acl => $error) { if (!$auth->acl_get($acl, $forum_id)) diff --git a/phpBB/search.php b/phpBB/search.php index 2598e407cc..164d834ff2 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -311,6 +311,26 @@ if ($keywords || $author || $author_id || $search_id || $submit) // define some variables needed for retrieving post_id/topic_id information $sort_by_sql = array('a' => 'u.username_clean', 't' => (($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time'), 'f' => 'f.forum_id', 'i' => 't.topic_title', 's' => (($show_results == 'posts') ? 'p.post_subject' : 't.topic_title')); + /** + * Event to modify the SQL parameters before pre-made searches + * + * @event core.search_modify_param_before + * @var string keywords String of the specified keywords + * @var array sort_by_sql Array of SQL sorting instructions + * @var array ex_fid_ary Array of excluded forum ids + * @var array author_id_ary Array of exclusive author ids + * @var string search_id The id of the search request + * @since 3.1.3-RC1 + */ + $vars = array( + 'keywords', + 'sort_by_sql', + 'ex_fid_ary', + 'author_id_ary', + 'search_id', + ); + extract($phpbb_dispatcher->trigger_event('core.search_modify_param_before', compact($vars))); + // pre-made searches $sql = $field = $l_search_title = ''; if ($search_id) diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg index 41e0d68714..34a7618f86 100644 --- a/phpBB/styles/prosilver/style.cfg +++ b/phpBB/styles/prosilver/style.cfg @@ -21,8 +21,8 @@ # General Information about this style name = prosilver copyright = © phpBB Limited, 2007 -style_version = 3.1.2 -phpbb_version = 3.1.2 +style_version = 3.1.3 +phpbb_version = 3.1.3 # Defining a different template bitfield # template_bitfield = lNg= diff --git a/phpBB/styles/prosilver/template/mcp_front.html b/phpBB/styles/prosilver/template/mcp_front.html index 44295611cf..8fe7dfdf65 100644 --- a/phpBB/styles/prosilver/template/mcp_front.html +++ b/phpBB/styles/prosilver/template/mcp_front.html @@ -2,6 +2,8 @@ <h2>{PAGE_TITLE}</h2> +<!-- EVENT mcp_front_latest_unapproved_before --> + <!-- IF S_SHOW_UNAPPROVED --> <form id="mcp_queue" method="post" action="{S_MCP_QUEUE_ACTION}"> @@ -59,6 +61,8 @@ </form> <!-- ENDIF --> +<!-- EVENT mcp_front_latest_reported_before --> + <!-- IF S_SHOW_REPORTS --> <div class="panel"> <div class="inner"> @@ -100,6 +104,8 @@ </div> <!-- ENDIF --> +<!-- EVENT mcp_front_latest_reported_pms_before --> + <!-- IF S_SHOW_PM_REPORTS --> <div class="panel"> <div class="inner"> @@ -141,6 +147,8 @@ </div> <!-- ENDIF --> +<!-- EVENT mcp_front_latest_logs_before --> + <!-- IF S_SHOW_LOGS --> <div class="panel"> <div class="inner"> @@ -180,4 +188,6 @@ </div> <!-- ENDIF --> +<!-- EVENT mcp_front_latest_logs_after --> + <!-- INCLUDE mcp_footer.html --> diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 275859ac97..6f35d0e80b 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -48,5 +48,7 @@ <!-- IF S_PLUPLOAD --><!-- INCLUDE plupload.html --><!-- ENDIF --> {$SCRIPTS} +<!-- EVENT overall_footer_body_after --> + </body> </html> diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html index ad08c1220b..121094f6e0 100644 --- a/phpBB/styles/prosilver/template/overall_header.html +++ b/phpBB/styles/prosilver/template/overall_header.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta charset="utf-8"> +<meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> {META} <title><!-- IF UNREAD_NOTIFICATIONS_COUNT -->({UNREAD_NOTIFICATIONS_COUNT}) <!-- ENDIF --><!-- IF not S_VIEWTOPIC and not S_VIEWFORUM -->{SITENAME} - <!-- ENDIF --><!-- IF S_IN_MCP -->{L_MCP} - <!-- ELSEIF S_IN_UCP -->{L_UCP} - <!-- ENDIF -->{PAGE_TITLE}<!-- IF S_VIEWTOPIC or S_VIEWFORUM --> - {SITENAME}<!-- ENDIF --></title> diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html index 333e61008e..e68e6a97e5 100644 --- a/phpBB/styles/prosilver/template/posting_editor.html +++ b/phpBB/styles/prosilver/template/posting_editor.html @@ -1,5 +1,5 @@ <fieldset class="fields1"> -<!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF --> + <!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF --> <!-- IF S_SHOW_TOPIC_ICONS or S_SHOW_PM_ICONS --> <dl> @@ -42,7 +42,7 @@ <a href="#" onclick="insert_text('{smiley.A_SMILEY_CODE}', true); return false;"><img src="{smiley.SMILEY_IMG}" width="{smiley.SMILEY_WIDTH}" height="{smiley.SMILEY_HEIGHT}" alt="{smiley.SMILEY_CODE}" title="{smiley.SMILEY_DESC}" /></a> <!-- END smiley --> <!-- ENDIF --> - <!-- IF S_SHOW_SMILEY_LINK and S_SMILIES_ALLOWED--> + <!-- IF S_SHOW_SMILEY_LINK and S_SMILIES_ALLOWED --> <br /><a href="{U_MORE_SMILIES}" onclick="popup(this.href, 750, 350, '_phpbbsmilies'); return false;">{L_MORE_SMILIES}</a> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html index 6d22a074be..a0c7bc68bb 100644 --- a/phpBB/styles/prosilver/template/simple_header.html +++ b/phpBB/styles/prosilver/template/simple_header.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta charset="utf-8"> +<meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> {META} <title>{SITENAME} • <!-- IF S_IN_MCP -->{L_MCP} • <!-- ELSEIF S_IN_UCP -->{L_UCP} • <!-- ENDIF -->{PAGE_TITLE}</title> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html index ce0f4941a5..7fe0d67077 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta charset="utf-8"> +<meta charset="utf-8" /> <meta name="robots" content="noindex" /> {META} <title>{SITENAME} • {PAGE_TITLE}</title> diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 48bcc2e922..3b2c0a9c65 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -137,7 +137,9 @@ <!-- ENDIF --> <!-- EVENT viewtopic_body_avatar_after --> </div> + <!-- EVENT viewtopic_body_post_author_before --> <!-- IF not postrow.U_POST_AUTHOR --><strong>{postrow.POST_AUTHOR_FULL}</strong><!-- ELSE -->{postrow.POST_AUTHOR_FULL}<!-- ENDIF --> + <!-- EVENT viewtopic_body_post_author_after --> </dt> <!-- IF postrow.RANK_TITLE or postrow.RANK_IMG --><dd class="profile-rank">{postrow.RANK_TITLE}<!-- IF postrow.RANK_TITLE and postrow.RANK_IMG --><br /><!-- ENDIF -->{postrow.RANK_IMG}</dd><!-- ENDIF --> @@ -247,7 +249,9 @@ <!-- ENDIF --> <!-- ENDIF --> + <!-- EVENT viewtopic_body_postrow_post_details_before --> <p class="author"><!-- IF S_IS_BOT -->{postrow.MINI_POST_IMG}<!-- ELSE --><a href="{postrow.U_MINI_POST}">{postrow.MINI_POST_IMG}</a><!-- ENDIF --><span class="responsive-hide">{L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong> » </span>{postrow.POST_DATE} </p> + <!-- EVENT viewtopic_body_postrow_post_details_after --> <!-- IF postrow.S_POST_UNAPPROVED --> <form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}"> diff --git a/phpBB/styles/prosilver/template/viewtopic_print.html b/phpBB/styles/prosilver/template/viewtopic_print.html index 5c44f58adb..66199295bb 100644 --- a/phpBB/styles/prosilver/template/viewtopic_print.html +++ b/phpBB/styles/prosilver/template/viewtopic_print.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta charset="utf-8"> +<meta charset="utf-8" /> <meta name="robots" content="noindex" /> {META} <title>{SITENAME} • {PAGE_TITLE}</title> diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css index 2d79a78ccb..889110e3fc 100644 --- a/phpBB/styles/prosilver/theme/bidi.css +++ b/phpBB/styles/prosilver/theme/bidi.css @@ -1061,17 +1061,6 @@ li.breadcrumbs span:first-child > a { text-align: right; } - @media only screen and (max-width: 550px), only screen and (max-device-width: 550px) - { - .rtl ul.topiclist.forums dt { - margin-left: 0; - } - - .rtl ul.topiclist.forums dt .list-inner { - margin-left: 0; - } - } - .rtl table.responsive.show-header thead, .rtl table.responsive.show-header th:first-child { text-align: right !important; } @@ -1086,19 +1075,6 @@ li.breadcrumbs span:first-child > a { float: none; } - @media only screen and (max-width: 500px), only screen and (max-device-width: 500px) - { - .rtl dl.details dt, .rtl dl.details dd { - float: none; - text-align: right; - } - - .rtl dl.details dd { - margin-left: 0; - margin-right: 20px; - } - } - /* Post ----------------------------------------*/ .rtl .postprofile, .rtl .postbody, .rtl .search .postbody { @@ -1131,10 +1107,34 @@ li.breadcrumbs span:first-child > a { .rtl fieldset dd, .rtl fieldset.fields1 dd, .rtl fieldset.fields2 dd { margin-right: 20px; } +} + +@media only screen and (max-width: 550px), only screen and (max-device-width: 550px) +{ + /* .topiclist lists + ----------------------------------------*/ + .rtl ul.topiclist.forums dt { + margin-left: 0; + } - @media only screen and (max-width: 500px), only screen and (max-device-width: 500px) { - .captcha-panel dd.captcha { - margin-right: 0; - } + .rtl ul.topiclist.forums dt .list-inner { + margin-left: 0; + } +} + +@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) +{ + .rtl dl.details dt, .rtl dl.details dd { + float: none; + text-align: right; + } + + .rtl dl.details dd { + margin-left: 0; + margin-right: 20px; + } + + .captcha-panel dd.captcha { + margin-right: 0; } } diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index 4768309c29..e73f8c9d54 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -276,6 +276,9 @@ dd.option { .postbody img.postimage { max-width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } .search .postbody { diff --git a/phpBB/styles/subsilver2/style.cfg b/phpBB/styles/subsilver2/style.cfg index 6014b89e66..8f3f55ec87 100644 --- a/phpBB/styles/subsilver2/style.cfg +++ b/phpBB/styles/subsilver2/style.cfg @@ -21,8 +21,8 @@ # General Information about this style name = subsilver2 copyright = © 2005 phpBB Limited -style_version = 3.1.2 -phpbb_version = 3.1.2 +style_version = 3.1.3 +phpbb_version = 3.1.3 # Defining a different template bitfield # template_bitfield = lNg= diff --git a/phpBB/styles/subsilver2/template/index.htm b/phpBB/styles/subsilver2/template/index.htm index 4763c05f0e..a1356823e2 100644 --- a/phpBB/styles/subsilver2/template/index.htm +++ b/phpBB/styles/subsilver2/template/index.htm @@ -1,7 +1,7 @@ <html> <head> <title>subSilver created by subBlue Design</title> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> <body bgcolor="#FFFFFF" text="#000000"> diff --git a/phpBB/styles/subsilver2/template/mcp_front.html b/phpBB/styles/subsilver2/template/mcp_front.html index 7c17e13c52..55adb3b550 100644 --- a/phpBB/styles/subsilver2/template/mcp_front.html +++ b/phpBB/styles/subsilver2/template/mcp_front.html @@ -1,5 +1,7 @@ <!-- INCLUDE mcp_header.html --> +<!-- EVENT mcp_front_latest_unapproved_before --> + <!-- IF S_SHOW_UNAPPROVED --> <form name="mcp_queue" method="post" action="{S_MCP_QUEUE_ACTION}"> @@ -44,6 +46,8 @@ <br clear="all" /><br /> <!-- ENDIF --> +<!-- EVENT mcp_front_latest_reported_before --> + <!-- IF S_SHOW_REPORTS --> <table class="tablebg" width="100%" cellspacing="1"> <tr> @@ -73,6 +77,8 @@ <br clear="all" /><br /> <!-- ENDIF --> +<!-- EVENT mcp_front_latest_reported_pms_before --> + <!-- IF S_SHOW_PM_REPORTS --> <table class="tablebg" width="100%" cellspacing="1"> <tr> @@ -104,6 +110,8 @@ <br clear="all" /><br /> <!-- ENDIF --> +<!-- EVENT mcp_front_latest_logs_before --> + <!-- IF S_SHOW_LOGS --> <table class="tablebg" width="100%" cellspacing="1" cellpadding="4" border="0" align="{S_CONTENT_FLOW_END}"> <tr> @@ -134,4 +142,6 @@ <br clear="all" /> <!-- ENDIF --> +<!-- EVENT mcp_front_latest_logs_after --> + <!-- INCLUDE mcp_footer.html --> diff --git a/phpBB/styles/subsilver2/template/overall_footer.html b/phpBB/styles/subsilver2/template/overall_footer.html index 42ee17f2ed..176110c58d 100644 --- a/phpBB/styles/subsilver2/template/overall_footer.html +++ b/phpBB/styles/subsilver2/template/overall_footer.html @@ -23,5 +23,7 @@ {$SCRIPTS} +<!-- EVENT overall_footer_body_after --> + </body> </html> diff --git a/phpBB/styles/subsilver2/template/overall_header.html b/phpBB/styles/subsilver2/template/overall_header.html index 4741154889..225a7d85ff 100644 --- a/phpBB/styles/subsilver2/template/overall_header.html +++ b/phpBB/styles/subsilver2/template/overall_header.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta charset="utf-8"> +<meta charset="utf-8" /> {META} <title><!-- IF UNREAD_NOTIFICATIONS_COUNT -->({UNREAD_NOTIFICATIONS_COUNT}) <!-- ENDIF --><!-- IF not S_VIEWTOPIC and not S_VIEWFORUM -->{SITENAME} - <!-- ENDIF --><!-- IF S_IN_MCP -->{L_MCP} - <!-- ELSEIF S_IN_UCP -->{L_UCP} - <!-- ENDIF -->{PAGE_TITLE}<!-- IF S_VIEWTOPIC or S_VIEWFORUM --> - {SITENAME}<!-- ENDIF --></title> diff --git a/phpBB/styles/subsilver2/template/simple_header.html b/phpBB/styles/subsilver2/template/simple_header.html index d292c4594a..3abf89719f 100644 --- a/phpBB/styles/subsilver2/template/simple_header.html +++ b/phpBB/styles/subsilver2/template/simple_header.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta charset="utf-8"> +<meta charset="utf-8" /> {META} <title>{SITENAME} • <!-- IF S_IN_MCP -->{L_MCP} • <!-- ELSEIF S_IN_UCP -->{L_UCP} • <!-- ENDIF -->{PAGE_TITLE}</title> diff --git a/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html b/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html index f70f39f9d8..fd5e390d83 100644 --- a/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html +++ b/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta charset="utf-8"> +<meta charset="utf-8" /> <meta name="robots" content="noindex" /> <title>{SITENAME} :: {PAGE_TITLE}</title> @@ -78,7 +78,7 @@ hr.sep { <td width="10%" nowrap="nowrap">{L_PM_FROM}{L_COLON} </td> <td><b>{MESSAGE_AUTHOR}</b> [ {SENT_DATE} ]</td> </tr> - + <!-- IF S_TO_RECIPIENT --> <tr> <td width="10%" nowrap="nowrap">{L_TO}{L_COLON}</td> diff --git a/phpBB/styles/subsilver2/template/viewtopic_body.html b/phpBB/styles/subsilver2/template/viewtopic_body.html index 24a8c12be0..ff39515876 100644 --- a/phpBB/styles/subsilver2/template/viewtopic_body.html +++ b/phpBB/styles/subsilver2/template/viewtopic_body.html @@ -163,8 +163,11 @@ <a id="unread" class="anchor"<!-- IF S_UNREAD_VIEW --> data-url="{postrow.U_MINI_POST}"<!-- ENDIF -->></a> <!-- ENDIF --> <a name="p{postrow.POST_ID}" class="anchor"></a> + <!-- EVENT viewtopic_body_post_author_before --> <b class="postauthor"<!-- IF postrow.POST_AUTHOR_COLOUR --> style="color: {postrow.POST_AUTHOR_COLOUR}"<!-- ENDIF -->>{postrow.POST_AUTHOR}</b> + <!-- EVENT viewtopic_body_post_author_after --> </td> + <!-- EVENT viewtopic_body_postrow_post_details_before --> <td width="100%" height="25"> <table width="100%" cellspacing="0"> <tr> @@ -175,6 +178,7 @@ </tr> </table> </td> + <!-- EVENT viewtopic_body_postrow_post_details_after --> </tr> <!-- IF postrow.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/viewtopic_print.html b/phpBB/styles/subsilver2/template/viewtopic_print.html index a99d807cf2..9497fda121 100644 --- a/phpBB/styles/subsilver2/template/viewtopic_print.html +++ b/phpBB/styles/subsilver2/template/viewtopic_print.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta charset="utf-8"> +<meta charset="utf-8" /> <meta name="robots" content="noindex" /> <title>{SITENAME} :: {PAGE_TITLE}</title> @@ -23,7 +23,7 @@ td { line-height: 150%; } -.code, .codecontent, +.code, .codecontent, .quote, .quotecontent { margin: 0 5px 0 5px; padding: 5px; diff --git a/phpBB/styles/subsilver2/theme/images/index.htm b/phpBB/styles/subsilver2/theme/images/index.htm index 29531416fe..957f68a803 100644 --- a/phpBB/styles/subsilver2/theme/images/index.htm +++ b/phpBB/styles/subsilver2/theme/images/index.htm @@ -1,7 +1,7 @@ <html> <head> <title>subSilver created by subBlue Design</title> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> <body bgcolor="#FFFFFF" text="#000000"> diff --git a/phpBB/ucp.php b/phpBB/ucp.php index 182bc2e285..8c74ca1f3c 100644 --- a/phpBB/ucp.php +++ b/phpBB/ucp.php @@ -164,6 +164,22 @@ switch ($mode) $cookie_name = str_replace($config['cookie_name'] . '_', '', $cookie_name); + /** + * Event to save custom cookies from deletion + * + * @event core.ucp_delete_cookies + * @var string cookie_name Cookie name to checking + * @var bool retain_cookie Do we retain our cookie or not, true if retain + * @since 3.1.3-RC1 + */ + $retain_cookie = false; + $vars = array('cookie_name', 'retain_cookie'); + extract($phpbb_dispatcher->trigger_event('core.ucp_delete_cookies', compact($vars))); + if ($retain_cookie) + { + continue; + } + // Polls are stored as {cookie_name}_poll_{topic_id}, cookie_name_ got removed, therefore checking for poll_ if (strpos($cookie_name, 'poll_') !== 0) { diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index 1f455494f7..92ac9171cb 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -370,7 +370,7 @@ $template->assign_vars(array( 'U_MCP' => ($auth->acl_get('m_', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "f=$forum_id&i=main&mode=forum_view", true, $user->session_id) : '', 'U_POST_NEW_TOPIC' => ($auth->acl_get('f_post', $forum_id) || $user->data['user_id'] == ANONYMOUS) ? append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=post&f=' . $forum_id) : '', 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '') . (($start == 0) ? '' : "&start=$start")), - 'U_CANONICAL' => generate_board_url() . '/' . append_sid("viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '') . (($start) ? "&start=$start" : ''), true, ''), + 'U_CANONICAL' => generate_board_url() . '/' . append_sid("viewforum.$phpEx", "f=$forum_id" . (($start) ? "&start=$start" : ''), true, ''), 'U_MARK_TOPICS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . "&f=$forum_id&mark=topics&mark_time=" . time()) : '', )); @@ -395,7 +395,7 @@ $sql_array = array( * @var array forum_data Array with forum data * @var array sql_array The SQL array to get the data of all topics * @since 3.1.0-a1 -* @change 3.1.0-RC4 Added forum_data var +* @change 3.1.0-RC4 Added forum_data var */ $vars = array( 'forum_data', @@ -554,6 +554,7 @@ $sql_ary = array( * Event to modify the SQL query before the topic ids data is retrieved * * @event core.viewforum_get_topic_ids_data +* @var array forum_data Data about the forum * @var array sql_ary SQL query array to get the topic ids data * @var string sql_approved Topic visibility SQL string * @var int sql_limit Number of records to select @@ -564,8 +565,11 @@ $sql_ary = array( * @var bool store_reverse Flag indicating if we select from the late pages * * @since 3.1.0-RC4 +* +* @changed 3.1.3 Added forum_data */ $vars = array( + 'forum_data', 'sql_ary', 'sql_approved', 'sql_limit', @@ -883,6 +887,28 @@ if (sizeof($topic_list)) $s_type_switch = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0; + /** + * Event after the topic data has been assigned to the template + * + * @event core.viewforum_topic_row_after + * @var array row Array with the topic data + * @var array rowset Array with topics data (in topic_id => topic_data format) + * @var bool s_type_switch Flag indicating if the topic type is [global] announcement + * @var int topic_id The topic ID + * @var array topic_list Array with current viewforum page topic ids + * @var array topic_row Template array with topic data + * @since 3.1.3-RC1 + */ + $vars = array( + 'row', + 'rowset', + 's_type_switch', + 'topic_id', + 'topic_list', + 'topic_row', + ); + extract($phpbb_dispatcher->trigger_event('core.viewforum_topic_row_after', compact($vars))); + if ($unread_topic) { $mark_forum_read = false; diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index a44169d3f1..981941cea0 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -336,8 +336,41 @@ if (($topic_data['topic_type'] == POST_STICKY || $topic_data['topic_type'] == PO // Setup look and feel $user->setup('viewtopic', $topic_data['forum_style']); +$overrides_f_read_check = false; +$overrides_forum_password_check = false; +$topic_tracking_info = isset($topic_tracking_info) ? $topic_tracking_info : null; + +/** +* Event to apply extra permissions and to override original phpBB's f_read permission and forum password check +* on viewtopic access +* +* @event core.viewtopic_before_f_read_check +* @var int forum_id The forum id from where the topic belongs +* @var int topic_id The id of the topic the user tries to access +* @var int post_id The id of the post the user tries to start viewing at. +* It may be 0 for none given. +* @var array topic_data All the information from the topic and forum tables for this topic +* It includes posts information if post_id is not 0 +* @var bool overrides_f_read_check Set true to remove f_read check afterwards +* @var bool overrides_forum_password_check Set true to remove forum_password check afterwards +* @var array topic_tracking_info Information upon calling get_topic_tracking() +* Set it to NULL to allow auto-filling later. +* Set it to an array to override original data. +* @since 3.1.3-RC1 +*/ +$vars = array( + 'forum_id', + 'topic_id', + 'post_id', + 'topic_data', + 'overrides_f_read_check', + 'overrides_forum_password_check', + 'topic_tracking_info', +); +extract($phpbb_dispatcher->trigger_event('core.viewtopic_before_f_read_check', compact($vars))); + // Start auth check -if (!$auth->acl_get('f_read', $forum_id)) +if (!$overrides_f_read_check && !$auth->acl_get('f_read', $forum_id)) { if ($user->data['user_id'] != ANONYMOUS) { @@ -349,7 +382,7 @@ if (!$auth->acl_get('f_read', $forum_id)) // Forum is passworded ... check whether access has been granted to this // user this session, if not show login box -if ($topic_data['forum_password']) +if (!$overrides_forum_password_check && $topic_data['forum_password']) { login_forum_box($topic_data); } @@ -692,7 +725,7 @@ $template->assign_vars(array( 'U_TOPIC' => "{$server_path}viewtopic.$phpEx?f=$forum_id&t=$topic_id", 'U_FORUM' => $server_path, 'U_VIEW_TOPIC' => $viewtopic_url, - 'U_CANONICAL' => generate_board_url() . '/' . append_sid("viewtopic.$phpEx", "t=$topic_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '') . (($start) ? "&start=$start" : ''), true, ''), + 'U_CANONICAL' => generate_board_url() . '/' . append_sid("viewtopic.$phpEx", "t=$topic_id" . (($start) ? "&start=$start" : ''), true, ''), 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id), 'U_VIEW_OLDER_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id&view=previous"), 'U_VIEW_NEWER_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id&view=next"), diff --git a/tests/content_visibility/delete_post_test.php b/tests/content_visibility/delete_post_test.php index 65dda3ce48..6ad6351a0c 100644 --- a/tests/content_visibility/delete_post_test.php +++ b/tests/content_visibility/delete_post_test.php @@ -296,6 +296,7 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case $cache = new phpbb_mock_cache; $db = $this->new_dbal(); $phpbb_config = new \phpbb\config\config(array('num_posts' => 3, 'num_topics' => 1)); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); set_config_count(null, null, null, $phpbb_config); // Create auth mock @@ -312,7 +313,7 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case $phpbb_container = new phpbb_mock_container_builder(); $phpbb_container->set('notification_manager', new phpbb_mock_notification_manager()); - $phpbb_container->set('content.visibility', new \phpbb\content_visibility($auth, $phpbb_config, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE)); + $phpbb_container->set('content.visibility', new \phpbb\content_visibility($auth, $phpbb_config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE)); delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $reason); diff --git a/tests/content_visibility/get_forums_visibility_sql_test.php b/tests/content_visibility/get_forums_visibility_sql_test.php index fe7ab36436..28e463ecb5 100644 --- a/tests/content_visibility/get_forums_visibility_sql_test.php +++ b/tests/content_visibility/get_forums_visibility_sql_test.php @@ -136,7 +136,8 @@ class phpbb_content_visibility_get_forums_visibility_sql_test extends phpbb_data ->will($this->returnValueMap($permissions)); $user = new \phpbb\user('\phpbb\datetime'); $config = new phpbb\config\config(array()); - $content_visibility = new \phpbb\content_visibility($auth, $config, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $content_visibility = new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); $result = $db->sql_query('SELECT ' . $mode . '_id FROM ' . $table . ' diff --git a/tests/content_visibility/get_global_visibility_sql_test.php b/tests/content_visibility/get_global_visibility_sql_test.php index 43a80c792b..586bae8668 100644 --- a/tests/content_visibility/get_global_visibility_sql_test.php +++ b/tests/content_visibility/get_global_visibility_sql_test.php @@ -136,7 +136,8 @@ class phpbb_content_visibility_get_global_visibility_sql_test extends phpbb_data ->will($this->returnValueMap($permissions)); $user = new \phpbb\user('\phpbb\datetime'); $config = new phpbb\config\config(array()); - $content_visibility = new \phpbb\content_visibility($auth, $config, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $content_visibility = new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); $result = $db->sql_query('SELECT ' . $mode . '_id FROM ' . $table . ' diff --git a/tests/content_visibility/get_visibility_sql_test.php b/tests/content_visibility/get_visibility_sql_test.php index f718e6c29a..9ae2d2fdc4 100644 --- a/tests/content_visibility/get_visibility_sql_test.php +++ b/tests/content_visibility/get_visibility_sql_test.php @@ -83,7 +83,8 @@ class phpbb_content_visibility_get_visibility_sql_test extends phpbb_database_te ->will($this->returnValueMap($permissions)); $user = new \phpbb\user('\phpbb\datetime'); $config = new phpbb\config\config(array()); - $content_visibility = new \phpbb\content_visibility($auth, $config, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $content_visibility = new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); $result = $db->sql_query('SELECT ' . $mode . '_id FROM ' . $table . ' diff --git a/tests/content_visibility/set_post_visibility_test.php b/tests/content_visibility/set_post_visibility_test.php index ab79fbc2ee..36ebf58374 100644 --- a/tests/content_visibility/set_post_visibility_test.php +++ b/tests/content_visibility/set_post_visibility_test.php @@ -126,7 +126,8 @@ class phpbb_content_visibility_set_post_visibility_test extends phpbb_database_t $auth = $this->getMock('\phpbb\auth\auth'); $user = new \phpbb\user('\phpbb\datetime'); $config = new phpbb\config\config(array()); - $content_visibility = new \phpbb\content_visibility($auth, $config, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $content_visibility = new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); $content_visibility->set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest); @@ -176,7 +177,8 @@ class phpbb_content_visibility_set_post_visibility_test extends phpbb_database_t $auth = $this->getMock('\phpbb\auth\auth'); $user = new \phpbb\user('\phpbb\datetime'); $config = new phpbb\config\config(array()); - $content_visibility = new \phpbb\content_visibility($auth, $config, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $content_visibility = new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); $content_visibility->set_post_visibility(ITEM_DELETED, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest); diff --git a/tests/content_visibility/set_topic_visibility_test.php b/tests/content_visibility/set_topic_visibility_test.php index 4d02a55490..6c34f42167 100644 --- a/tests/content_visibility/set_topic_visibility_test.php +++ b/tests/content_visibility/set_topic_visibility_test.php @@ -90,7 +90,8 @@ class phpbb_content_visibility_set_topic_visibility_test extends phpbb_database_ $auth = $this->getMock('\phpbb\auth\auth'); $user = new \phpbb\user('\phpbb\datetime'); $config = new phpbb\config\config(array()); - $content_visibility = new \phpbb\content_visibility($auth, $config, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $content_visibility = new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); $content_visibility->set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all); diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index 51f9daacfb..5832b966d8 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -415,4 +415,11 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case $this->tools->sql_create_unique_index('prefix_table_name', 'i_uniq_ts_id', array('c_timestamp', 'c_id')); $this->assertTrue($this->tools->sql_unique_index_exists('prefix_table_name', 'i_uniq_ts_id')); } + + public function test_create_int_default_null() + { + $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_13282')); + $this->assertTrue($this->tools->sql_column_add('prefix_table_name', 'c_bug_13282', array('TINT:2'))); + $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_13282')); + } } diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index 10a9444d63..4c4306888c 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -46,7 +46,10 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case new \phpbb\db\migration\tool\config($this->config), ); + $container = new phpbb_mock_container_builder(); + $this->migrator = new \phpbb\db\migrator( + $container, $this->config, $this->db, $this->db_tools, @@ -57,9 +60,8 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $tools, new \phpbb\db\migration\helper() ); - - $container = new phpbb_mock_container_builder(); - $container->set('migrator', $migrator); + $container->set('migrator', $this->migrator); + $container->set('dispatcher', new phpbb_mock_event_dispatcher()); $user = new \phpbb\user('\phpbb\datetime'); $this->extension_manager = new \phpbb\extension\manager( diff --git a/tests/error_collector_test.php b/tests/error_collector_test.php index 1d8ef367f5..b92c4fa6bb 100644 --- a/tests/error_collector_test.php +++ b/tests/error_collector_test.php @@ -17,7 +17,7 @@ class phpbb_error_collector_test extends phpbb_test_case { public function test_collection() { - $collector = new \phpbb\error_collector; + $collector = new \phpbb\error_collector(E_ALL | E_STRICT); // php set_error_handler() default $collector->install(); // Cause a warning @@ -35,4 +35,32 @@ class phpbb_error_collector_test extends phpbb_test_case $this->assertStringStartsWith('Errno 2: Division by zero at ', $error_contents); $this->assertStringEndsWith(" line $line", $error_contents); } + + public function test_collection_with_mask() + { + $collector = new \phpbb\error_collector(E_ALL & ~E_NOTICE); // not collecting notices + $collector->install(); + + // Cause a warning + 1/0; $line = __LINE__; + + // Cause a notice + $array = array('ITEM' => 'value'); + $value = $array[ITEM]; $line2 = __LINE__; + + $collector->uninstall(); + + // The notice should not be collected + $this->assertEmpty($collector->errors[1]); + + list($errno, $msg_text, $errfile, $errline) = $collector->errors[0]; + $error_contents = $collector->format_errors(); + + $this->assertEquals($errno, 2); + + // Unfortunately $error_contents will contain the full path here, + // because the tests directory is outside of phpbb root path. + $this->assertStringStartsWith('Errno 2: Division by zero at ', $error_contents); + $this->assertStringEndsWith(" line $line", $error_contents); + } } diff --git a/tests/event/exception_listener_test.php b/tests/event/exception_listener_test.php new file mode 100644 index 0000000000..4d3453cd83 --- /dev/null +++ b/tests/event/exception_listener_test.php @@ -0,0 +1,100 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class exception_listener extends phpbb_test_case +{ + public function phpbb_exception_data() + { + return array( + array( + true, + new \Exception(), + array( + 'status_code' => 500, + ), + ), + array( + true, + new \Exception('AJAX_ERROR_TEXT'), + array( + 'status_code' => 500, + 'content' => 'AJAX_ERROR_TEXT', + ), + ), + array( + true, + new \phpbb\exception\runtime_exception('AJAX_ERROR_TEXT'), + array( + 'status_code' => 500, + 'content' => 'Something went wrong when processing your request.', + ), + ), + array( + true, + new \Symfony\Component\HttpKernel\Exception\HttpException(404, 'AJAX_ERROR_TEXT'), + array( + 'status_code' => 404, + 'content' => 'AJAX_ERROR_TEXT', + ), + ), + array( + true, + new \phpbb\exception\http_exception(404, 'AJAX_ERROR_TEXT'), + array( + 'status_code' => 404, + 'content' => 'Something went wrong when processing your request.', + ), + ), + array( + true, + new \phpbb\exception\http_exception(404, 'CURRENT_TIME', array('today')), + array( + 'status_code' => 404, + 'content' => 'It is currently today', + ), + ), + ); + } + + /** + * @dataProvider phpbb_exception_data + */ + public function test_phpbb_exception($is_ajax, $exception, $expected) + { + $request = \Symfony\Component\HttpFoundation\Request::create('test.php', 'GET', array(), array(), array(), $is_ajax ? array('HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest') : array()); + + $template = $this->getMockBuilder('\phpbb\template\twig\twig') + ->disableOriginalConstructor() + ->getMock(); + + $user = new \phpbb\user('\phpbb\datetime'); + $user->add_lang('common'); + + $exception_listener = new \phpbb\event\kernel_exception_subscriber($template, $user); + + $event = new \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent($this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), $request, \Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST, $exception); + $exception_listener->on_kernel_exception($event); + + $response = $event->getResponse(); + + $this->assertEquals($expected['status_code'], $response->getStatusCode()); + $this->assertEquals($is_ajax, $response instanceof \Symfony\Component\HttpFoundation\JsonResponse); + + if (isset($expected['content'])) + { + $this->assertContains($expected['content'], $response->getContent()); + } + } +} diff --git a/tests/extension/manager_test.php b/tests/extension/manager_test.php index 5c7cad89f6..0eeb060936 100644 --- a/tests/extension/manager_test.php +++ b/tests/extension/manager_test.php @@ -156,7 +156,10 @@ class phpbb_extension_manager_test extends phpbb_database_test_case $table_prefix = 'phpbb_'; $user = new \phpbb\user('\phpbb\user'); + $container = new phpbb_mock_container_builder(); + $migrator = new \phpbb\db\migrator( + $container, $config, $db, $db_tools, @@ -167,7 +170,6 @@ class phpbb_extension_manager_test extends phpbb_database_test_case array(), new \phpbb\db\migration\helper() ); - $container = new phpbb_mock_container_builder(); $container->set('migrator', $migrator); return new \phpbb\extension\manager( diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index fab1d3af3a..2a746d3792 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -62,7 +62,10 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case new \phpbb\template\context() ); + $container = new phpbb_mock_container_builder(); + $this->migrator = new \phpbb\db\migrator( + $container, $this->config, $this->db, $this->db_tools, @@ -73,7 +76,6 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case array(), new \phpbb\db\migration\helper() ); - $container = new phpbb_mock_container_builder(); $container->set('migrator', $this->migrator); $this->extension_manager = new \phpbb\extension\manager( diff --git a/tests/functional/acp_profile_field_test.php b/tests/functional/acp_profile_field_test.php new file mode 100644 index 0000000000..88df782faa --- /dev/null +++ b/tests/functional/acp_profile_field_test.php @@ -0,0 +1,71 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_acp_profile_field_test extends phpbb_functional_test_case +{ + public function setUp() + { + parent::setUp(); + + $this->login(); + $this->admin_login(); + $this->add_lang('acp/profile'); + } + + public function data_add_profile_field() + { + return array( + array('bool', 'profilefields.type.bool', + array( + 'lang_options[0]' => 'foo', + 'lang_options[1]' => 'bar', + ), + array(), + ), + array('dropdown', 'profilefields.type.dropdown', + array( + 'lang_options' => "foo\nbar\nbar\nfoo", + ), + array(), + ), + ); + } + + /** + * @dataProvider data_add_profile_field + */ + public function test_add_profile_field($name, $type, $page1_settings, $page2_settings) + { + // Custom profile fields page + $crawler = self::request('GET', 'adm/index.php?i=acp_profile&mode=profile&sid=' . $this->sid); + // these language strings are html + $form = $crawler->selectButton('Create new field')->form(array( + 'field_ident' => $name, + 'field_type' => $type, + )); + $crawler = self::submit($form); + + // Fill form for profile field options + $form = $crawler->selectButton('Profile type specific options')->form($page1_settings); + $crawler = self::submit($form); + + // Fill form for profile field specific options + $form = $crawler->selectButton('Save')->form($page2_settings); + $crawler= self::submit($form); + + $this->assertContainsLang('ADDED_PROFILE_FIELD', $crawler->text()); + } +} diff --git a/tests/functional/fileupload_form_test.php b/tests/functional/fileupload_form_test.php index b8c48389e0..d381fa1ae2 100644 --- a/tests/functional/fileupload_form_test.php +++ b/tests/functional/fileupload_form_test.php @@ -93,23 +93,32 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case $this->login(); $this->admin_login(); $this->add_lang('ucp'); - $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_attachments&mode=attach'); - $form = $crawler->selectButton('Submit')->form(); - $values = $form->getValues(); + // Make sure check_attachment_content is set to false + $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_attachments&mode=attach'); - $values["config[check_attachment_content]"] = 0; - $form->setValues($values); - $crawler = self::submit($form); + $form = $crawler->selectButton('Submit')->form(array( + 'config[check_attachment_content]' => 0, + 'config[img_imagick]' => '', + )); + self::submit($form); // Request index for correct URL - $crawler = self::request('GET', 'index.php?sid=' . $this->sid); + self::request('GET', 'index.php?sid=' . $this->sid); $crawler = $this->upload_file('disallowed.jpg', 'image/jpeg'); // Hitting the UNABLE_GET_IMAGE_SIZE error means we passed the // DISALLOWED_CONTENT check $this->assertContainsLang('UNABLE_GET_IMAGE_SIZE', $crawler->text()); + + // Reset check_attachment_content to default (enabled) + $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_attachments&mode=attach'); + + $form = $crawler->selectButton('Submit')->form(array( + 'config[check_attachment_content]' => 1, + )); + self::submit($form); } public function test_too_large() diff --git a/tests/functional/prune_shadow_topic_test.php b/tests/functional/prune_shadow_topic_test.php index f00303060d..c014119b98 100644 --- a/tests/functional/prune_shadow_topic_test.php +++ b/tests/functional/prune_shadow_topic_test.php @@ -62,7 +62,7 @@ class phpbb_functional_prune_shadow_topic_test extends phpbb_functional_test_cas $crawler = self::request('GET', "viewtopic.php?t={$this->post['topic_id']}&sid={$this->sid}"); $this->assertContains('Prune Shadow #1', $crawler->filter('html')->text()); - $this->data['topics']['Prune Shadow #1'] = (int) $post['topic_id']; + $this->data['topics']['Prune Shadow #1'] = (int) $this->post['topic_id']; $this->data['posts']['Prune Shadow #1'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); $this->assert_forum_details($this->data['forums']['Prune Shadow'], array( diff --git a/tests/functions/get_remote_file_test.php b/tests/functions/get_remote_file_test.php index d412dce164..612d82273e 100644 --- a/tests/functions/get_remote_file_test.php +++ b/tests/functions/get_remote_file_test.php @@ -21,6 +21,10 @@ class phpbb_functions_get_remote_file extends phpbb_test_case { public function test_version_phpbb_com() { + global $phpbb_container; + $phpbb_container = new phpbb_mock_container_builder(); + $phpbb_container->set('file_downloader', new \phpbb\file_downloader()); + $hostname = 'version.phpbb.com'; if (!phpbb_checkdnsrr($hostname, 'A')) diff --git a/tests/functions/make_clickable_test.php b/tests/functions/make_clickable_test.php index e61cb2c30e..63beeb06b2 100644 --- a/tests/functions/make_clickable_test.php +++ b/tests/functions/make_clickable_test.php @@ -74,13 +74,77 @@ class phpbb_functions_make_clickable_test extends phpbb_test_case 'http://www.phpbb.com/community/path/to/long/url/file.ext#section', '<!-- m --><a class="postlink" href="http://www.phpbb.com/community/path/to/long/url/file.ext#section">http://www.phpbb.com/community/path/to/ ... xt#section</a><!-- m -->' ), + ); + } - // IDN is not parsed and returned as is - array('http://домен.рф', 'http://домен.рф'), + public function data_test_make_clickable_url_idn() + { + return array( + array( + 'http://www.täst.de/community/', + '<!-- m --><a class="postlink" href="http://www.täst.de/community/">http://www.täst.de/community/</a><!-- m -->' + ), + array( + 'http://www.täst.de/path/file.ext#section', + '<!-- m --><a class="postlink" href="http://www.täst.de/path/file.ext#section">http://www.täst.de/path/file.ext#section</a><!-- m -->' + ), + array( + 'ftp://ftp.täst.de/', + '<!-- m --><a class="postlink" href="ftp://ftp.täst.de/">ftp://ftp.täst.de/</a><!-- m -->' + ), + array( + 'sip://bantu@täst.de', + '<!-- m --><a class="postlink" href="sip://bantu@täst.de">sip://bantu@täst.de</a><!-- m -->' + ), + array( + 'www.täst.de/community/', + '<!-- w --><a class="postlink" href="http://www.täst.de/community/">www.täst.de/community/</a><!-- w -->' + ), + // Test appending punctuation mark to the URL + array( + 'http://домен.рф/viewtopic.php?t=1!', + '<!-- m --><a class="postlink" href="http://домен.рф/viewtopic.php?t=1">http://домен.рф/viewtopic.php?t=1</a><!-- m -->!' + ), + array( + 'www.домен.рф/сообщество/?', + '<!-- w --><a class="postlink" href="http://www.домен.рф/сообщество/">www.домен.рф/сообщество/</a><!-- w -->?' + ), + // Test shortened text for URL > 55 characters long + // URL text should be turned into: first 39 chars + ' ... ' + last 10 chars + array( + 'http://www.домен.рф/сообщество/путь/по/длинной/ссылке/file.ext#section', + '<!-- m --><a class="postlink" href="http://www.домен.рф/сообщество/путь/по/длинной/ссылке/file.ext#section">http://www.домен.рф/сообщество/путь/по/ ... xt#section</a><!-- m -->' + ), + + // IDN with invalid characters shouldn't be parsed correctly (only 'valid' part) + array( + 'http://www.täst╫.de', + '<!-- m --><a class="postlink" href="http://www.täst">http://www.täst</a><!-- m -->╫.de' + ), + // IDN in emails is unsupported yet array('почта@домен.рф', 'почта@домен.рф'), ); } + public function data_test_make_clickable_local_url_idn() + { + return array( + array( + 'http://www.домен.рф/viewtopic.php?t=1', + '<!-- l --><a class="postlink-local" href="http://www.домен.рф/viewtopic.php?t=1">viewtopic.php?t=1</a><!-- l -->' + ), + // Test appending punctuation mark to the URL + array( + 'http://www.домен.рф/viewtopic.php?t=1!', + '<!-- l --><a class="postlink-local" href="http://www.домен.рф/viewtopic.php?t=1">viewtopic.php?t=1</a><!-- l -->!' + ), + array( + 'http://www.домен.рф/сообщество/?', + '<!-- l --><a class="postlink-local" href="http://www.домен.рф/сообщество/">сообщество/</a><!-- l -->?' + ), + ); + } + protected function setUp() { parent::setUp(); @@ -97,4 +161,20 @@ class phpbb_functions_make_clickable_test extends phpbb_test_case { $this->assertSame($expected, make_clickable($url)); } + + /** + * @dataProvider data_test_make_clickable_url_idn + */ + public function test_urls_matching_idn($url, $expected) + { + $this->assertSame($expected, make_clickable($url)); + } + + /** + * @dataProvider data_test_make_clickable_local_url_idn + */ + public function test_local_urls_matching_idn($url, $expected) + { + $this->assertSame($expected, make_clickable($url, "http://www.домен.рф")); + } } diff --git a/tests/notification/base.php b/tests/notification/base.php index c97b7c24e2..162feae557 100644 --- a/tests/notification/base.php +++ b/tests/notification/base.php @@ -66,6 +66,8 @@ abstract class phpbb_tests_notification_base extends phpbb_database_test_case $phpbb_root_path, $phpEx ); + + $this->phpbb_dispatcher = new phpbb_mock_event_dispatcher(); $phpbb_container = $this->container = new phpbb_mock_container_builder(); @@ -75,6 +77,7 @@ abstract class phpbb_tests_notification_base extends phpbb_database_test_case $this->container, $this->user_loader, $this->config, + $this->phpbb_dispatcher, $this->db, $this->cache, $this->user, diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php index 684dd99280..5e770f71c9 100644 --- a/tests/notification/submit_post_base.php +++ b/tests/notification/submit_post_base.php @@ -100,7 +100,8 @@ abstract class phpbb_notification_submit_post_base extends phpbb_database_test_c // Container $phpbb_container = new phpbb_mock_container_builder(); - $phpbb_container->set('content.visibility', new \phpbb\content_visibility($auth, $config, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE)); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $phpbb_container->set('content.visibility', new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE)); $user_loader = new \phpbb\user_loader($db, $phpbb_root_path, $phpEx, USERS_TABLE); @@ -122,7 +123,7 @@ abstract class phpbb_notification_submit_post_base extends phpbb_database_test_c // Notification Manager $phpbb_notifications = new \phpbb\notification\manager($notification_types_array, array(), - $phpbb_container, $user_loader, $config, $db, $cache, $user, + $phpbb_container, $user_loader, $config, $phpbb_dispatcher, $db, $cache, $user, $phpbb_root_path, $phpEx, NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE); $phpbb_container->set('notification_manager', $phpbb_notifications); diff --git a/tests/path_helper/path_helper_test.php b/tests/path_helper/path_helper_test.php index bb68f8b3bc..73f0e6bafc 100644 --- a/tests/path_helper/path_helper_test.php +++ b/tests/path_helper/path_helper_test.php @@ -436,4 +436,29 @@ class phpbb_path_helper_test extends phpbb_test_case { $this->assertEquals($this->phpbb_root_path . $expected, $this->path_helper->get_web_root_path_from_ajax_referer($referer_url, $board_url)); } + + public function data_get_valid_page() + { + return array( + // array( current page , mod_rewrite setting , expected output ) + array('index', true, 'index'), + array('index', false, 'index'), + array('foo/index', true, 'foo/index'), + array('foo/index', false, 'foo/index'), + array('app.php/foo', true, 'foo'), + array('app.php/foo', false, 'app.php/foo'), + array('/../app.php/foo', true, '../foo'), + array('/../app.php/foo', false, '../app.php/foo'), + array('/../example/app.php/foo/bar', true, '../example/foo/bar'), + array('/../example/app.php/foo/bar', false, '../example/app.php/foo/bar'), + ); + } + + /** + * @dataProvider data_get_valid_page + */ + public function test_get_valid_page($page, $mod_rewrite, $expected) + { + $this->assertEquals($this->phpbb_root_path . $expected, $this->path_helper->get_valid_page($page, $mod_rewrite)); + } } diff --git a/tests/profilefields/type_string_test.php b/tests/profilefields/type_string_test.php index a7be087fb5..0417afbfab 100644 --- a/tests/profilefields/type_string_test.php +++ b/tests/profilefields/type_string_test.php @@ -133,37 +133,49 @@ class phpbb_profilefield_type_string_test extends phpbb_test_case ), array( 'ö äö äö ä', - array('field_validation' => '[\w]+'), + array('field_validation' => '[a-zA-Z0-9]+'), 'FIELD_INVALID_CHARS_ALPHA_ONLY-field', 'Required field should reject UTF-8 in alpha only field', ), array( + 'a_abc', + array('field_validation' => '[a-zA-Z0-9]+'), + 'FIELD_INVALID_CHARS_ALPHA_ONLY-field', + 'Required field should reject underscore in alpha only field', + ), + array( 'Hello', - array('field_validation' => '[\w]+'), + array('field_validation' => '[a-zA-Z0-9]+'), false, 'Required field should accept a characters only field', ), array( 'Valid.Username123', - array('field_validation' => '[\w.]+'), + array('field_validation' => '[a-zA-Z0-9.]+'), false, 'Required field should accept a alphanumeric field with dots', ), array( 'Invalid.,username123', - array('field_validation' => '[\w.]+'), + array('field_validation' => '[a-zA-Z0-9.]+'), 'FIELD_INVALID_CHARS_ALPHA_DOTS-field', 'Required field should reject field with comma', ), array( + 'Invalid._username123', + array('field_validation' => '[a-zA-Z0-9.]+'), + 'FIELD_INVALID_CHARS_ALPHA_DOTS-field', + 'Required field should reject field with underscore', + ), + array( 'skype.test.name,_this', - array('field_validation' => '[a-zA-Z][\w\.,\-_]+'), + array('field_validation' => '[a-zA-Z][\w\.,\-]+'), false, 'Required field should accept alphanumeric field with punctuations', ), array( '1skype.this.should.faila', - array('field_validation' => '[a-zA-Z][\w\.,\-_]+'), + array('field_validation' => '[a-zA-Z][\w\.,\-]+'), 'FIELD_INVALID_CHARS_ALPHA_PUNCTUATION-field', 'Required field should reject field having invalid input for the given validation', ), diff --git a/tests/profilefields/type_url_test.php b/tests/profilefields/type_url_test.php index 372c07418f..cc37f04f30 100644 --- a/tests/profilefields/type_url_test.php +++ b/tests/profilefields/type_url_test.php @@ -89,6 +89,32 @@ class phpbb_profilefield_type_url_test extends phpbb_test_case 'FIELD_INVALID_URL-field', 'Field should reject invalid URL having multi value parameters', ), + + // IDN url type profilefields + array( + 'http://www.täst.de', + array(), + false, + 'Field should accept valid IDN', + ), + array( + 'http://täst.de/index.html?param1=test¶m2=awesome', + array(), + false, + 'Field should accept valid IDN URL with params', + ), + array( + 'http://домен.рф/index.html/тест/path?document=get', + array(), + false, + 'Field should accept valid IDN URL', + ), + array( + 'http://домен.рф/index.html/тест/path?document[]=DocType%20test&document[]=AnotherDoc', + array(), + 'FIELD_INVALID_URL-field', + 'Field should reject invalid IDN URL having multi value parameters', + ), ); } @@ -119,6 +145,20 @@ class phpbb_profilefield_type_url_test extends phpbb_test_case 'http://example.com', 'Field should return correct raw value', ), + + // IDN tests + array( + 'http://täst.de', + array('field_show_novalue' => true), + 'http://täst.de', + 'Field should return the correct raw value', + ), + array( + 'http://домен.рф', + array('field_show_novalue' => false), + 'http://домен.рф', + 'Field should return correct raw value', + ), ); } diff --git a/tests/regex/url_test.php b/tests/regex/url_test.php index d3487a9c16..e5d7c3256a 100644 --- a/tests/regex/url_test.php +++ b/tests/regex/url_test.php @@ -32,6 +32,6 @@ class phpbb_regex_url_test extends phpbb_test_case */ public function test_url($url, $expected) { - $this->assertEquals($expected, preg_match('#^' . get_preg_expression('url') . '$#i', $url)); + $this->assertEquals($expected, preg_match('#^' . get_preg_expression('url') . '$#iu', $url)); } } diff --git a/tests/search/fixtures/posts.xml b/tests/search/fixtures/posts.xml index 7b249ee303..16232b8f39 100644 --- a/tests/search/fixtures/posts.xml +++ b/tests/search/fixtures/posts.xml @@ -19,6 +19,11 @@ <value>commonword</value> <value>commonword</value> </row> + <row> + <value>baaz</value> + <value>baaz</value> + <value>baaz</value> + </row> </table> <table name="phpbb_search_wordlist"> <column>word_id</column> @@ -39,5 +44,10 @@ <value>commonword</value> <value>1</value> </row> + <row> + <value>4</value> + <value>baaz</value> + <value>0</value> + </row> </table> </dataset> diff --git a/tests/search/native_test.php b/tests/search/native_test.php index f681a62fce..61fde7d098 100644 --- a/tests/search/native_test.php +++ b/tests/search/native_test.php @@ -35,6 +35,8 @@ class phpbb_search_native_test extends phpbb_search_test_case $this->db = $this->new_dbal(); $error = null; $class = self::get_search_wrapper('\phpbb\search\fulltext_native'); + $config['fulltext_native_min_chars'] = 2; + $config['fulltext_native_max_chars'] = 14; $this->search = new $class($error, $phpbb_root_path, $phpEx, null, $config, $this->db, $user); } @@ -56,6 +58,54 @@ class phpbb_search_native_test extends phpbb_search_test_case array(), ), array( + 'baaz*', + 'all', + true, + array('\'baaz%\''), + array(), + array(), + ), + array( + 'ba*az', + 'all', + true, + array('\'ba%az\''), + array(), + array(), + ), + array( + 'ba*z', + 'all', + true, + array('\'ba%z\''), + array(), + array(), + ), + array( + 'baa* baaz*', + 'all', + true, + array('\'baa%\'', '\'baaz%\''), + array(), + array(), + ), + array( + 'ba*z baa*', + 'all', + true, + array('\'ba%z\'', '\'baa%\''), + array(), + array(), + ), + array( + 'baaz* commonword', + 'all', + true, + array('\'baaz%\''), + array(), + array('commonword'), + ), + array( 'foo bar', 'all', true, diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 51bae7a723..b6769f08d0 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -227,7 +227,9 @@ class phpbb_functional_test_case extends phpbb_test_case $db = $this->get_db(); $db_tools = new \phpbb\db\tools($db); + $container = new phpbb_mock_container_builder(); $migrator = new \phpbb\db\migrator( + $container, $config, $db, $db_tools, @@ -238,8 +240,8 @@ class phpbb_functional_test_case extends phpbb_test_case array(), new \phpbb\db\migration\helper() ); - $container = new phpbb_mock_container_builder(); $container->set('migrator', $migrator); + $container->set('dispatcher', new phpbb_mock_event_dispatcher()); $user = new \phpbb\user('\phpbb\datetime'); $extension_manager = new \phpbb\extension\manager( @@ -883,7 +885,7 @@ class phpbb_functional_test_case extends phpbb_test_case */ static public function assert_response_status_code($status_code = 200) { - self::assertEquals($status_code, self::$client->getResponse()->getStatus()); + self::assertEquals($status_code, self::$client->getResponse()->getStatus(), 'HTTP status code does not match'); } public function assert_filter($crawler, $expr, $msg = null) |