diff options
234 files changed, 3305 insertions, 2040 deletions
diff --git a/.travis.yml b/.travis.yml index fe91fe78c8..cbba07b16d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,7 +37,9 @@ before_script: script: - travis/phing-sniff.sh $DB $TRAVIS_PHP_VERSION + - 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 [ '$TRAVIS_PHP_VERSION' = '5.5' -a '$DB' = 'mysqli' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..FETCH_HEAD; 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 3c1a3e4db4..ca71aae924 100644 --- a/build/build.xml +++ b/build/build.xml @@ -259,7 +259,7 @@ command="git archive ${revision} composer.phar | tar -xf - -C ${dir}" checkreturn="true" /> <exec dir="${dir}" - command="php composer.phar install --no-dev" + command="php composer.phar install --no-dev --optimize-autoloader" checkreturn="true" passthru="true" /> <delete file="${dir}/composer.phar" /> diff --git a/build/sami.conf.php b/build/sami.conf.php index febd0276d4..78d532631c 100644 --- a/build/sami.conf.php +++ b/build/sami.conf.php @@ -45,7 +45,7 @@ $versions = Sami\Version\GitVersionCollection::create(__DIR__ . '/../') ->add('develop-ascraeus') ; -return new Sami\Sami($iterator, array( +$config = array( 'theme' => 'enhanced', 'versions' => $versions, 'title' => 'phpBB API Documentation', @@ -54,4 +54,6 @@ return new Sami\Sami($iterator, array( 'default_opened_level' => 2, // Do not use JsonStore. See https://github.com/fabpot/Sami/issues/79 'store' => new PhpbbArrayStore, -)); +); + +return new Sami\Sami($iterator, $config); diff --git a/phpBB/adm/style/acp_ban.html b/phpBB/adm/style/acp_ban.html index 71c737de70..9e9f05120a 100644 --- a/phpBB/adm/style/acp_ban.html +++ b/phpBB/adm/style/acp_ban.html @@ -13,27 +13,34 @@ var ban_length = new Array(); ban_length[-1] = ''; - <!-- BEGIN ban_length --> - ban_length['{ban_length.BAN_ID}'] = '{ban_length.A_LENGTH}'; - <!-- END ban_length --> - var ban_reason = new Array(); ban_reason[-1] = ''; - <!-- BEGIN ban_reason --> - ban_reason['{ban_reason.BAN_ID}'] = '{ban_reason.A_REASON}'; - <!-- END ban_reason --> - var ban_give_reason = new Array(); ban_give_reason[-1] = ''; - <!-- BEGIN ban_give_reason --> - ban_give_reason['{ban_give_reason.BAN_ID}'] = '{ban_give_reason.A_REASON}'; - <!-- END ban_give_reason --> + + <!-- BEGIN bans --> + ban_length['{bans.BAN_ID}'] = '{bans.A_LENGTH}'; + <!-- IF bans.A_REASON --> + ban_reason['{bans.BAN_ID}'] = '{bans.A_REASON}'; + <!-- ENDIF --> + <!-- IF bans.A_GIVE_REASON --> + ban_give_reason['{bans.BAN_ID}'] = '{bans.A_GIVE_REASON}'; + <!-- ENDIF --> + <!-- END bans --> function display_details(option) { - document.getElementById('acp_unban').unbangivereason.innerHTML = ban_give_reason[option]; - document.getElementById('acp_unban').unbanreason.innerHTML = ban_reason[option]; - document.getElementById('acp_unban').unbanlength.value = ban_length[option]; + document.getElementById('unbanlength').value = ban_length[option]; + if (option in ban_reason) { + document.getElementById('unbanreason').innerHTML = ban_reason[option]; + } else { + document.getElementById('unbanreason').innerHTML = ''; + } + if (option in ban_give_reason) { + document.getElementById('unbangivereason').innerHTML = ban_give_reason[option]; + } else { + document.getElementById('unbangivereason').innerHTML = ''; + } } // ]]> diff --git a/phpBB/adm/style/acp_ranks.html b/phpBB/adm/style/acp_ranks.html index dd2d07a837..fa06513b98 100644 --- a/phpBB/adm/style/acp_ranks.html +++ b/phpBB/adm/style/acp_ranks.html @@ -24,6 +24,9 @@ <fieldset> <legend>{L_ACP_RANKS}</legend> + + <!-- EVENT acp_ranks_edit_before --> + <dl> <dt><label for="title">{L_RANK_TITLE}{L_COLON}</label></dt> <dd><input name="title" type="text" id="title" value="{RANK_TITLE}" maxlength="255" /></dd> @@ -38,13 +41,15 @@ <dd><label><input onclick="phpbb.toggleDisplay('posts', -1)" type="radio" class="radio" name="special_rank" value="1" id="special_rank"<!-- IF S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> /> {L_YES}</label> <label><input onclick="phpbb.toggleDisplay('posts', 1)" type="radio" class="radio" name="special_rank" value="0"<!-- IF not S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> </dl> - <!-- IF S_SPECIAL_RANK --><div id="posts" style="display: none;"><!-- ELSE --><div id="posts"><!-- ENDIF --> + <div id="posts"<!-- IF S_SPECIAL_RANK --> style="display: none;"<!-- ENDIF -->> <dl> <dt><label for="min_posts">{L_RANK_MINIMUM}{L_COLON}</label></dt> <dd><input name="min_posts" type="number" id="min_posts" maxlength="10" value="{MIN_POSTS}" /></dd> </dl> </div> + <!-- EVENT acp_ranks_edit_after --> + <p class="submit-buttons"> <input type="hidden" name="action" value="save" /> @@ -68,18 +73,22 @@ <table class="table1 zebra-table"> <thead> <tr> + <!-- EVENT acp_ranks_list_header_before --> <th>{L_RANK_IMAGE}</th> <th>{L_RANK_TITLE}</th> <th>{L_RANK_MINIMUM}</th> + <!-- EVENT acp_ranks_list_header_after --> <th>{L_ACTION}</th> </tr> </thead> <tbody> <!-- BEGIN ranks --> <tr> + <!-- EVENT acp_ranks_list_column_before --> <td style="text-align: center;"><!-- IF ranks.S_RANK_IMAGE --><img src="{ranks.RANK_IMAGE}" alt="{ranks.RANK_TITLE}" title="{ranks.RANK_TITLE}" /><!-- ELSE --> - <!-- ENDIF --></td> <td style="text-align: center;">{ranks.RANK_TITLE}</td> <td style="text-align: center;"><!-- IF ranks.S_SPECIAL_RANK --> - <!-- ELSE -->{ranks.MIN_POSTS}<!-- ENDIF --></td> + <!-- EVENT acp_ranks_list_column_after --> <td style="text-align: center;"><a href="{ranks.U_EDIT}">{ICON_EDIT}</a> <a href="{ranks.U_DELETE}" data-ajax="row_delete">{ICON_DELETE}</a></td> </tr> <!-- END ranks --> diff --git a/phpBB/adm/style/auth_provider_ldap.html b/phpBB/adm/style/auth_provider_ldap.html index 9e0567dfed..97684db396 100644 --- a/phpBB/adm/style/auth_provider_ldap.html +++ b/phpBB/adm/style/auth_provider_ldap.html @@ -22,7 +22,7 @@ </dl> <dl> <dt><label for="ldap_email">{L_LDAP_EMAIL}{L_COLON}</label><br /><span>{L_LDAP_EMAIL_EXPLAIN}</span></dt> - <dd><input type="email" id="ldap_email" size="40" name="config[ldap_email]" value="{AUTH_LDAP_EMAIL}" /></dd> + <dd><input type="text" id="ldap_email" size="40" name="config[ldap_email]" value="{AUTH_LDAP_EMAIL}" /></dd> </dl> <dl> <dt><label for="ldap_user">{L_LDAP_USER}{L_COLON}</label><br /><span>{L_LDAP_USER_EXPLAIN}</span></dt> diff --git a/phpBB/adm/style/overall_header.html b/phpBB/adm/style/overall_header.html index afd2b94924..f1f7eee282 100644 --- a/phpBB/adm/style/overall_header.html +++ b/phpBB/adm/style/overall_header.html @@ -89,6 +89,8 @@ function popup(url, width, height, name) {$STYLESHEETS} +<!-- EVENT acp_overall_header_stylesheets_after --> + </head> <body class="{S_CONTENT_DIRECTION} {BODY_CLASS} nojs"> diff --git a/phpBB/adm/style/simple_header.html b/phpBB/adm/style/simple_header.html index bf8f41cd7a..d0b9bf62ed 100644 --- a/phpBB/adm/style/simple_header.html +++ b/phpBB/adm/style/simple_header.html @@ -84,6 +84,7 @@ function find_username(url) </script> <!-- EVENT acp_simple_header_head_append --> {$STYLESHEETS} +<!-- EVENT acp_simple_header_stylesheets_after --> </head> <body class="{S_CONTENT_DIRECTION} {BODY_CLASS}"> diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 2c35875dca..388f31698f 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -48,6 +48,18 @@ phpbb.clearLoadingTimeout = function() { } }; + +/** +* Close popup alert after a specified delay +* +* @param int Delay in ms until darkenwrapper's click event is triggered +*/ +phpbb.closeDarkenWrapper = function(delay) { + phpbbAlertTimer = setTimeout(function() { + $('#darkenwrapper').trigger('click'); + }, delay); +}; + /** * Display a simple alert similar to JSs native alert(). * @@ -272,7 +284,7 @@ phpbb.ajaxify = function(options) { * Handler for AJAX errors */ function errorHandler(jqXHR, textStatus, errorThrown) { - if (console && console.log) { + if (typeof console !== 'undefined' && console.log) { console.log('AJAX error. status: ' + textStatus + ', message: ' + errorThrown); } phpbb.clearLoadingTimeout(); diff --git a/phpBB/bin/phpbbcli.php b/phpBB/bin/phpbbcli.php index c8098094a2..ca425ad0c4 100755 --- a/phpBB/bin/phpbbcli.php +++ b/phpBB/bin/phpbbcli.php @@ -12,6 +12,8 @@ * */ +use Symfony\Component\Console\Input\ArgvInput; + if (php_sapi_name() != 'cli') { echo 'This program must be run from the command line.' . PHP_EOL; @@ -35,20 +37,31 @@ require($phpbb_root_path . 'includes/functions.' . $phpEx); require($phpbb_root_path . 'includes/functions_admin.' . $phpEx); require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); -$phpbb_class_loader_ext = new \phpbb\class_loader('\\', "{$phpbb_root_path}ext/", $phpEx); -$phpbb_class_loader_ext->register(); - $phpbb_container_builder = new \phpbb\di\container_builder($phpbb_config_php_file, $phpbb_root_path, $phpEx); -$phpbb_container_builder->set_use_extensions(false); $phpbb_container_builder->set_dump_container(false); +$input = new ArgvInput(); + +if ($input->hasParameterOption(array('--safe-mode'))) +{ + $phpbb_container_builder->set_use_extensions(false); + $phpbb_container_builder->set_dump_container(false); +} +else +{ + $phpbb_class_loader_ext = new \phpbb\class_loader('\\', "{$phpbb_root_path}ext/", $phpEx); + $phpbb_class_loader_ext->register(); + phpbb_load_extensions_autoloaders($phpbb_root_path); +} + $phpbb_container = $phpbb_container_builder->get_container(); $phpbb_container->get('request')->enable_super_globals(); require($phpbb_root_path . 'includes/compatibility_globals.' . $phpEx); $user = $phpbb_container->get('user'); $user->add_lang('acp/common'); +$user->add_lang('cli'); $application = new \phpbb\console\application('phpBB Console', PHPBB_VERSION, $user); -$application->register_container_commands($phpbb_container); -$application->run(); +$application->register_container_commands($phpbb_container->get('console.command_collection')); +$application->run($input); diff --git a/phpBB/composer.json b/phpBB/composer.json index 9b473a3bb7..e74dd120f0 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -1,9 +1,31 @@ { - "_readme": [ - "You MUST update the clean-vendor-dir target in build/build.xml", - "accordingly when adding or upgrading dependencies." + "name": "phpbb/phpbb", + "description": "phpBB Forum Software application", + "type": "project", + "keywords": ["phpbb", "forum"], + "homepage": "https://www.phpbb.com", + "license": "GPL-2.0", + "authors": [ + { + "name": "phpBB Limited", + "email": "operations@phpbb.com", + "homepage": "https://www.phpbb.com/go/authors" + } ], + "support": { + "issues": "https://tracker.phpbb.com", + "forum": "https://www.phpbb.com/community/", + "wiki": "https://wiki.phpbb.com", + "irc": "irc://irc.freenode.org/phpbb" + }, + "scripts": { + "post-update-cmd": "echo 'You MUST manually modify the clean-vendor-dir target in build/build.xml when adding or upgrading dependencies.'" + }, + "replace": { + "phpbb/phpbb-core": "self.version" + }, "require": { + "php": ">=5.3.3", "lusitanian/oauth": "0.2.*", "symfony/config": "2.3.*", "symfony/console": "2.3.*", @@ -15,8 +37,6 @@ "twig/twig": "1.13.*" }, "require-dev": { - "behat/mink": "1.4.*", - "behat/mink-goutte-driver": "1.0.*", "fabpot/goutte": "1.0.*", "phpunit/dbunit": "1.3.*", "phpunit/phpunit": "4.1.*", diff --git a/phpBB/composer.lock b/phpBB/composer.lock index 751cd0695f..671daa70e1 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "dcd46c1373cfc4dacd2e1f8a79da0b91", + "hash": "27d5da149e0b5d76b76f43210306b666", "packages": [ { "name": "lusitanian/oauth", @@ -721,167 +721,6 @@ ], "packages-dev": [ { - "name": "behat/mink", - "version": "v1.4.3", - "source": { - "type": "git", - "url": "https://github.com/Behat/Mink.git", - "reference": "0817070a6e2ec9f475fad9bfb81a962c462eb934" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Mink/zipball/0817070a6e2ec9f475fad9bfb81a962c462eb934", - "reference": "0817070a6e2ec9f475fad9bfb81a962c462eb934", - "shasum": "" - }, - "require": { - "php": ">=5.3.1", - "symfony/css-selector": ">=2.0,<2.4-dev" - }, - "suggest": { - "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)", - "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation", - "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)", - "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-develop": "1.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\Mink": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Web acceptance testing framework for PHP 5.3", - "homepage": "http://mink.behat.org/", - "keywords": [ - "browser", - "testing", - "web" - ], - "time": "2013-03-02 15:53:18" - }, - { - "name": "behat/mink-browserkit-driver", - "version": "v1.0.5", - "source": { - "type": "git", - "url": "https://github.com/Behat/MinkBrowserKitDriver.git", - "reference": "f2771b5fc4dbc233859addf37a7d150852f78418" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/MinkBrowserKitDriver/zipball/f2771b5fc4dbc233859addf37a7d150852f78418", - "reference": "f2771b5fc4dbc233859addf37a7d150852f78418", - "shasum": "" - }, - "require": { - "behat/mink": "~1.4.3", - "php": ">=5.3.1", - "symfony/browser-kit": "~2.0", - "symfony/dom-crawler": "~2.0" - }, - "require-dev": { - "silex/silex": "@dev" - }, - "type": "mink-driver", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\Mink\\Driver": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Symfony2 BrowserKit driver for Mink framework", - "homepage": "http://mink.behat.org/", - "keywords": [ - "Mink", - "Symfony2", - "browser", - "testing" - ], - "time": "2013-04-13 12:17:15" - }, - { - "name": "behat/mink-goutte-driver", - "version": "v1.0.9", - "source": { - "type": "git", - "url": "https://github.com/Behat/MinkGoutteDriver.git", - "reference": "fa1b073b48761464feb0b05e6825da44b20118d8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/MinkGoutteDriver/zipball/fa1b073b48761464feb0b05e6825da44b20118d8", - "reference": "fa1b073b48761464feb0b05e6825da44b20118d8", - "shasum": "" - }, - "require": { - "behat/mink-browserkit-driver": ">=1.0.5,<1.2.0", - "fabpot/goutte": "~1.0.1", - "php": ">=5.3.1" - }, - "type": "mink-driver", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\Mink\\Driver": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Goutte driver for Mink framework", - "homepage": "http://mink.behat.org/", - "keywords": [ - "browser", - "goutte", - "headless", - "testing" - ], - "time": "2013-07-03 18:43:54" - }, - { "name": "fabpot/goutte", "version": "v1.0.3", "source": { @@ -2437,9 +2276,9 @@ "stability-flags": [ ], - "platform": [ - - ], + "platform": { + "php": ">=5.3.3" + }, "platform-dev": [ ] diff --git a/phpBB/config/avatars.yml b/phpBB/config/avatars.yml index d22a5db2ae..8e5b1fdbfe 100644 --- a/phpBB/config/avatars.yml +++ b/phpBB/config/avatars.yml @@ -45,6 +45,7 @@ services: - %core.root_path% - %core.php_ext% - @path_helper + - @mimetype.guesser - @cache.driver calls: - [set_name, [avatar.driver.upload]] diff --git a/phpBB/config/console.yml b/phpBB/config/console.yml index 00b8f9cec0..540908164a 100644 --- a/phpBB/config/console.yml +++ b/phpBB/config/console.yml @@ -1,12 +1,19 @@ services: + console.command_collection: + class: phpbb\di\service_collection + arguments: + - @service_container + tags: + - { name: service_collection, tag: console.command } + console.command.cache.purge: class: phpbb\console\command\cache\purge arguments: + - @user - @cache.driver - @dbal.conn - @auth - @log - - @user - @config tags: - { name: console.command } @@ -14,6 +21,7 @@ services: console.command.config.delete: class: phpbb\console\command\config\delete arguments: + - @user - @config tags: - { name: console.command } @@ -21,6 +29,7 @@ services: console.command.config.increment: class: phpbb\console\command\config\increment arguments: + - @user - @config tags: - { name: console.command } @@ -28,6 +37,7 @@ services: console.command.config.get: class: phpbb\console\command\config\get arguments: + - @user - @config tags: - { name: console.command } @@ -35,6 +45,7 @@ services: console.command.config.set: class: phpbb\console\command\config\set arguments: + - @user - @config tags: - { name: console.command } @@ -42,6 +53,7 @@ services: console.command.config.set_atomic: class: phpbb\console\command\config\set_atomic arguments: + - @user - @config tags: - { name: console.command } @@ -49,35 +61,36 @@ services: console.command.cron.list: class: phpbb\console\command\cron\cron_list arguments: - - @cron.manager - @user + - @cron.manager tags: - { name: console.command } console.command.cron.run: class: phpbb\console\command\cron\run arguments: + - @user - @cron.manager - @cron.lock_db - - @user tags: - { name: console.command } console.command.db.migrate: class: phpbb\console\command\db\migrate arguments: + - @user - @migrator - @ext.manager - @config - @cache - @log - - @user tags: - { name: console.command } console.command.dev.migration_tips: class: phpbb\console\command\dev\migration_tips arguments: + - @user - @ext.manager tags: - { name: console.command } @@ -85,6 +98,7 @@ services: console.command.extension.disable: class: phpbb\console\command\extension\disable arguments: + - @user - @ext.manager - @log tags: @@ -93,6 +107,7 @@ services: console.command.extension.enable: class: phpbb\console\command\extension\enable arguments: + - @user - @ext.manager - @log tags: @@ -101,6 +116,7 @@ services: console.command.extension.purge: class: phpbb\console\command\extension\purge arguments: + - @user - @ext.manager - @log tags: @@ -109,6 +125,7 @@ services: console.command.extension.show: class: phpbb\console\command\extension\show arguments: + - @user - @ext.manager - @log tags: @@ -117,6 +134,7 @@ services: console.command.fixup.recalculate_email_hash: class: phpbb\console\command\fixup\recalculate_email_hash arguments: + - @user - @dbal.conn tags: - { name: console.command } diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index b4e387bd73..a9f9f5ed19 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -79,6 +79,7 @@ services: class: phpbb\content_visibility arguments: - @auth + - @config - @dbal.conn - @user - %core.root_path% diff --git a/phpBB/cron.php b/phpBB/cron.php index 8bb49bd5d2..3f022b1db8 100644 --- a/phpBB/cron.php +++ b/phpBB/cron.php @@ -62,8 +62,9 @@ if ($cron_lock->acquire()) if ($task->is_ready()) { $task->run(); - garbage_collection(); } } $cron_lock->release(); } + +garbage_collection(); diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html index a46cea47b1..e3e12a3176 100644 --- a/phpBB/docs/INSTALL.html +++ b/phpBB/docs/INSTALL.html @@ -61,6 +61,7 @@ <li><a href="#update_all">All package types</a></li> </ol> </li> + <li><a href="#update30">Updating from phpBB 3.0.x to phpBB 3.1.x</a></li> <li><a href="#convert">Conversion from phpBB 2.0.x to phpBB 3.1.x</a> <ol style="list-style-type: lower-roman;"> <li><a href="#prereq">Requirements before converting</a></li> @@ -324,7 +325,41 @@ <hr /> - <a name="convert"></a><h2>5. Conversion from phpBB 2.0.x to phpBB 3.1.x</h2> + <a name="update30"></a><h2>5. Updating from phpBB 3.0.x to phpBB 3.1.x</h2> + + <div class="paragraph"> + <div class="inner"><span class="corners-top"><span></span></span> + + <div class="content"> + + <p>Updating from phpBB 3.0.x to 3.1.x is just the same as <a href="#update">updating from stable releases of phpBB 3.1.x</a></p> + + <p>However you can also start with a new set of phpBB 3.1.x files.</p> + + <ol> + <li>Delete all files <strong>EXCEPT</strong> for the following: + + <ul> + <li>The <code>config.php</code> file</li> + <li>The <code>images/</code> directory</li> + <li>The <code>files/</code> directory</li> + <li>The <code>store/</code> directory</li> + </ul></li> + + <li>Upload the contents of the 3.1.x Full Package into your forum's directory.</li> + <li>Browse to install/database_update.php</li> + <li>Delete the <code>install/</code> directory</li> + </ol> + </div> + + <div class="back2top"><a href="#wrap" class="top">Back to Top</a></div> + + <span class="corners-bottom"><span></span></span></div> + </div> + + <hr /> + + <a name="convert"></a><h2>6. Conversion from phpBB 2.0.x to phpBB 3.1.x</h2> <div class="paragraph"> <div class="inner"><span class="corners-top"><span></span></span> @@ -387,7 +422,7 @@ <hr /> - <a name="postinstall"></a><h2>6. Important (security related) post-Install tasks for all installation methods</h2> + <a name="postinstall"></a><h2>7. Important (security related) post-Install tasks for all installation methods</h2> <div class="paragraph"> <div class="inner"><span class="corners-top"><span></span></span> @@ -425,7 +460,7 @@ <hr /> -<a name="anti_spam"></a><h2>7. Anti-Spam Measures</h2> +<a name="anti_spam"></a><h2>8. Anti-Spam Measures</h2> <div class="paragraph"> <div class="inner"><span class="corners-top"><span></span></span> @@ -441,7 +476,7 @@ <hr /> -<a name="disclaimer"></a><h2>8. Copyright and disclaimer</h2> +<a name="disclaimer"></a><h2>9. Copyright and disclaimer</h2> <div class="paragraph"> <div class="inner"><span class="corners-top"><span></span></span> diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index f1c03672c3..4f39e71c3c 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -64,6 +64,13 @@ acp_overall_header_head_append * Since: 3.1.0-a1 * Purpose: Add assets within the `<head>` tags in the ACP +acp_overall_header_stylesheets_after +=== +* Location: adm/style/overall_header.html +* Since: 3.1.0-RC3 +* Purpose: Add assets after stylesheets within the `<head>` tags in the ACP. +Note that INCLUDECSS will not work with this event. + acp_posting_buttons_after === * Locations: @@ -78,6 +85,50 @@ acp_posting_buttons_before * Since: 3.1.0-b4 * Purpose: Add content before BBCode posting buttons in the ACP +acp_ranks_edit_after +=== +* Locations: + + adm/style/acp_ranks.html +* Since: 3.1.0-RC3 +* Purpose: Add content after the rank details when editing a rank in the ACP + +acp_ranks_edit_before +=== +* Locations: + + adm/style/acp_ranks.html +* Since: 3.1.0-RC3 +* Purpose: Add content before the rank details when editing a rank in the ACP + +acp_ranks_list_column_after +=== +* Locations: + + adm/style/acp_ranks.html +* Since: 3.1.0-RC3 +* Purpose: Add content before the first column in the ranks list in the ACP + +acp_ranks_list_column_before +=== +* Locations: + + adm/style/acp_ranks.html +* Since: 3.1.0-RC3 +* Purpose: Add content after the last column (but before the action column) +in the ranks list in the ACP + +acp_ranks_list_header_after +=== +* Locations: + + adm/style/acp_ranks.html +* Since: 3.1.0-RC3 +* Purpose: Add content before the first header-column in the ranks list in the ACP + +acp_ranks_list_header_before +=== +* Locations: + + adm/style/acp_ranks.html +* Since: 3.1.0-RC3 +* Purpose: Add content after the last header-column (but before the action column) +in the ranks list in the ACP + acp_simple_footer_after === * Location: adm/style/simple_footer.html @@ -96,6 +147,13 @@ acp_simple_header_head_append * Since: 3.1.0-a1 * Purpose: Add assets within the `<head>` tags in the simple header of the ACP +acp_simple_header_stylesheets_after +=== +* Location: adm/style/simple_header.html +* Since: 3.1.0-RC3 +* Purpose: Add assets after stylesheets within the `<head>` tags in the simple header +of the ACP. Note that INCLUDECSS will not work with this event. + acp_users_overview_options_append === * Location: adm/style/acp_users_overview.html @@ -278,6 +336,38 @@ index_body_stat_blocks_before * Since: 3.1.0-a1 * Purpose: Add new statistic blocks above the Who Is Online and Board Statistics blocks +mcp_ban_fields_after +=== +* Locations: + + styles/prosilver/template/mcp_ban.html + + styles/subsilver2/template/mcp_ban.html +* Since: 3.1.0-RC3 +* Purpose: Add additional fields to the ban form in MCP + +mcp_ban_fields_before +=== +* Locations: + + styles/prosilver/template/mcp_ban.html + + styles/subsilver2/template/mcp_ban.html +* Since: 3.1.0-RC3 +* Purpose: Add additional fields to the ban form in MCP + +mcp_ban_unban_after +=== +* Locations: + + styles/prosilver/template/mcp_ban.html + + styles/subsilver2/template/mcp_ban.html +* Since: 3.1.0-RC3 +* Purpose: Add additional fields to the unban form in MCP + +mcp_ban_unban_before +=== +* Locations: + + styles/prosilver/template/mcp_ban.html + + styles/subsilver2/template/mcp_ban.html +* Since: 3.1.0-RC3 +* Purpose: Add additional fields to the unban form in MCP + memberlist_body_username_append === * Locations: @@ -405,9 +495,18 @@ overall_footer_breadcrumb_append === * Locations: + styles/prosilver/template/navbar_footer.html + + styles/subsilver2/template/breadcrumbs.html * Since: 3.1.0-a1 * Purpose: Add links to the list of breadcrumbs in the footer +overall_footer_breadcrumb_prepend +=== +* Locations: + + styles/prosilver/template/navbar_footer.html + + styles/subsilver2/template/breadcrumbs.html +* Since: 3.1.0-RC3 +* Purpose: Add links to the list of breadcrumbs in the footer (after site-home, but before board-index) + overall_footer_content_after === * Locations: @@ -488,6 +587,30 @@ overall_header_breadcrumb_append * Since: 3.1.0-a1 * Purpose: Add links to the list of breadcrumbs in the header +overall_header_breadcrumb_prepend +=== +* Locations: + + styles/prosilver/template/navbar_header.html + + styles/subsilver2/template/breadcrumbs.html +* Since: 3.1.0-RC3 +* Purpose: Add links to the list of breadcrumbs in the header (after site-home, but before board-index) + +overall_header_breadcrumbs_after +=== +* Locations: + + styles/prosilver/template/navbar_header.html + + styles/subsilver2/template/breadcrumbs.html +* Since: 3.1.0-RC3 +* Purpose: Add content after the breadcrumbs (outside of the breadcrumbs container) + +overall_header_breadcrumbs_before +=== +* Locations: + + styles/prosilver/template/navbar_header.html + + styles/subsilver2/template/breadcrumbs.html +* Since: 3.1.0-RC3 +* Purpose: Add content before the breadcrumbs (outside of the breadcrumbs container) + overall_header_content_before === * Locations: @@ -544,6 +667,15 @@ overall_header_page_body_before * Since: 3.1.0-b3 * Purpose: Add content after the page-header, but before the page-body +overall_header_stylesheets_after +=== +* Locations: + + styles/prosilver/template/overall_header.html + + styles/subsilver2/template/overall_header.html +* Since: 3.1.0-RC3 +* Purpose: Add asset calls after stylesheets within the `</head>` tag. +Note that INCLUDECSS will not work with this event. + posting_editor_buttons_after === * Locations: @@ -702,6 +834,15 @@ simple_header_head_append * Since: 3.1.0-b4 * Purpose: Add asset calls directly before the `</head>` tag +simple_header_stylesheets_after +=== +* Locations: + + styles/prosilver/template/simple_header.html + + styles/subsilver2/template/simple_header.html +* Since: 3.1.0-RC3 +* Purpose: Add asset calls after stylesheets within the `</head>` tag. +Note that INCLUDECSS will not work with this event. + topiclist_row_prepend === * Locations: @@ -738,6 +879,20 @@ ucp_agreement_terms_before * Since: 3.1.0-b3 * Purpose: Add content before the terms of agreement text at user registration +ucp_pm_viewmessage_avatar_after +=== +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html +* Since: 3.1.0-RC3 +* Purpose: Add content right after the avatar when viewing a private message + +ucp_pm_viewmessage_avatar_before +=== +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html +* Since: 3.1.0-RC3 +* Purpose: Add content right before the avatar when viewing a private message + ucp_pm_viewmessage_contact_fields_after === * Locations: @@ -770,6 +925,24 @@ ucp_pm_viewmessage_custom_fields_before * Purpose: Add data before the custom fields on the user profile when viewing a private message +ucp_pm_viewmessage_post_buttons_after +=== +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html + + styles/subsilver2/template/ucp_pm_viewmessage.html +* Since: 3.1.0-RC3 +* Purpose: Add post button to private messages (next to edit, quote etc), at +the end of the list. + +ucp_pm_viewmessage_post_buttons_before +=== +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html + + styles/subsilver2/template/ucp_pm_viewmessage.html +* Since: 3.1.0-RC3 +* Purpose: Add post button to private messages (next to edit, quote etc), at +the start of the list. + ucp_pm_viewmessage_print_head_append === * Locations: @@ -926,6 +1099,22 @@ viewtopic_print_head_append * Since: 3.1.0-a1 * Purpose: Add asset calls directly before the `</head>` tag of the Print Topic screen +viewtopic_body_avatar_after +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-RC3 +* Purpose: Add content right after the avatar when viewing topics + +viewtopic_body_avatar_before +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-RC3 +* Purpose: Add content right before the avatar when viewing topics + viewtopic_body_contact_fields_after === * Locations: diff --git a/phpBB/download/file.php b/phpBB/download/file.php index d4e0f04d2b..984de2165f 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -11,10 +11,6 @@ * */ -use Symfony\Component\Config\FileLocator; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; - /** * @ignore */ @@ -143,11 +139,7 @@ if (isset($_GET['avatar'])) include($phpbb_root_path . 'common.' . $phpEx); require($phpbb_root_path . 'includes/functions_download' . '.' . $phpEx); -$download_id = request_var('id', 0); -$topic_id = $request->variable('topic_id', 0); -$post_id = $request->variable('post_id', 0); -$msg_id = $request->variable('msg_id', 0); -$archive = $request->variable('archive', '.tar'); +$attach_id = request_var('id', 0); $mode = request_var('mode', ''); $thumbnail = request_var('t', false); @@ -162,27 +154,7 @@ if (!$config['allow_attachments'] && !$config['allow_pm_attach']) trigger_error('ATTACHMENT_FUNCTIONALITY_DISABLED'); } -if ($download_id) -{ - // Attachment id (only 1 attachment) - $sql_where = 'attach_id = ' . $download_id; -} -else if ($msg_id) -{ - // Private message id (multiple attachments) - $sql_where = 'is_orphan = 0 AND in_message = 1 AND post_msg_id = ' . $msg_id; -} -else if ($post_id) -{ - // Post id (multiple attachments) - $sql_where = 'is_orphan = 0 AND in_message = 0 AND post_msg_id = ' . $post_id; -} -else if ($topic_id) -{ - // Topic id (multiple attachments) - $sql_where = 'is_orphan = 0 AND topic_id = ' . $topic_id; -} -else +if (!$attach_id) { send_status_line(404, 'Not Found'); trigger_error('NO_ATTACHMENT_SELECTED'); @@ -190,25 +162,12 @@ else $sql = 'SELECT attach_id, post_msg_id, topic_id, in_message, poster_id, is_orphan, physical_filename, real_filename, extension, mimetype, filesize, filetime FROM ' . ATTACHMENTS_TABLE . " - WHERE $sql_where"; + WHERE attach_id = $attach_id"; $result = $db->sql_query($sql); - -$attachments = $attachment_ids = array(); -while ($row = $db->sql_fetchrow($result)) -{ - $attachment_id = (int) $row['attach_id']; - - $row['physical_filename'] = utf8_basename($row['physical_filename']); - - $attachment_ids[$attachment_id] = $attachment_id; - $attachments[$attachment_id] = $row; -} +$attachment = $db->sql_fetchrow($result); $db->sql_freeresult($result); -// Make $attachment the first of the attachments we fetched. -$attachment = current($attachments); - -if (empty($attachments)) +if (!$attachment) { send_status_line(404, 'Not Found'); trigger_error('ERROR_NO_ATTACHMENT'); @@ -218,9 +177,9 @@ else if (!download_allowed()) send_status_line(403, 'Forbidden'); trigger_error($user->lang['LINKAGE_FORBIDDEN']); } -else if ($download_id) +else { - // sizeof($attachments) == 1 + $attachment['physical_filename'] = utf8_basename($attachment['physical_filename']); if (!$attachment['in_message'] && !$config['allow_attachments'] || $attachment['in_message'] && !$config['allow_pm_attach']) { @@ -327,142 +286,3 @@ else if ($download_id) } } } -else -{ - // sizeof($attachments) >= 1 - if ($attachment['in_message']) - { - phpbb_download_handle_pm_auth($db, $auth, $user->data['user_id'], $attachment['post_msg_id']); - } - else - { - phpbb_download_handle_forum_auth($db, $auth, $attachment['topic_id']); - } - - if (!class_exists('compress')) - { - require $phpbb_root_path . 'includes/functions_compress.' . $phpEx; - } - - if (!in_array($archive, compress::methods())) - { - $archive = '.tar'; - } - - $post_visibility = array(); - if ($msg_id) - { - $sql = 'SELECT message_subject AS attach_subject - FROM ' . PRIVMSGS_TABLE . " - WHERE msg_id = $msg_id"; - } - else if ($post_id) - { - $sql = 'SELECT post_subject AS attach_subject, forum_id, post_visibility - FROM ' . POSTS_TABLE . " - WHERE post_id = $post_id"; - } - else - { - $sql = 'SELECT post_id, post_visibility - FROM ' . POSTS_TABLE . " - WHERE topic_id = $topic_id - AND post_attachment = 1"; - $result = $db->sql_query($sql); - while ($row = $db->sql_fetchrow($result)) - { - $post_visibility[(int) $row['post_id']] = (int) $row['post_visibility']; - } - $db->sql_freeresult($result); - - $sql = 'SELECT topic_title AS attach_subject, forum_id - FROM ' . TOPICS_TABLE . " - WHERE topic_id = $topic_id"; - } - - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - if (empty($row)) - { - send_status_line(404, 'Not Found'); - trigger_error('ERROR_NO_ATTACHMENT'); - } - - $clean_name = phpbb_download_clean_filename($row['attach_subject']); - $suffix = '_' . (($msg_id) ? 'm' . $msg_id : (($post_id) ? 'p' . $post_id : 't' . $topic_id)) . '_' . $clean_name; - $archive_name = 'attachments' . $suffix; - - $store_name = 'att_' . time() . '_' . unique_id(); - $archive_path = "{$phpbb_root_path}store/{$store_name}{$archive}"; - - if ($archive === '.zip') - { - $compress = new compress_zip('w', $archive_path); - } - else - { - $compress = new compress_tar('w', $archive_path, $archive); - } - - $extensions = array(); - $files_added = 0; - $forum_id = ($attachment['in_message']) ? false : (int) $row['forum_id']; - $disallowed_extension = array(); - - foreach ($attachments as $attach) - { - if (!extension_allowed($forum_id, $attach['extension'], $extensions)) - { - $disallowed_extension[$attach['extension']] = $attach['extension']; - continue; - } - - if ($post_id && $row['post_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $forum_id)) - { - // Attachment of a soft deleted post and the user is not allowed to see the post - continue; - } - - if ($topic_id && (!isset($post_visibility[$attach['post_msg_id']]) || $post_visibility[$attach['post_msg_id']] != ITEM_APPROVED) && !$auth->acl_get('m_approve', $forum_id)) - { - // Attachment of a soft deleted post and the user is not allowed to see the post - continue; - } - - $prefix = ''; - if ($topic_id) - { - $prefix = $attach['post_msg_id'] . '_'; - } - - $compress->add_custom_file("{$phpbb_root_path}files/{$attach['physical_filename']}", "{$prefix}{$attach['real_filename']}"); - $files_added++; - } - - $compress->close(); - - if ($files_added) - { - phpbb_increment_downloads($db, $attachment_ids); - $compress->download($store_name, $archive_name); - } - - unlink($archive_path); - - if (!$files_added && !empty($disallowed_extension)) - { - // None of the attachments had a valid extension - $disallowed_extension = implode($user->lang['COMMA_SEPARATOR'], $disallowed_extension); - send_status_line(403, 'Forbidden'); - trigger_error($user->lang('EXTENSION_DISABLED_AFTER_POSTING', $disallowed_extension)); - } - else if (!$files_added) - { - send_status_line(404, 'Not Found'); - trigger_error('ERROR_NO_ATTACHMENT'); - } - - file_gc(); -} diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 59057a0447..2372c1f73c 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -1301,7 +1301,6 @@ class acp_attachments /** * Check accuracy of attachment statistics. * - * @param $resync bool Resync stats if they're incorrect. * @return bool|string Returns false if stats are correct or error message * otherwise. */ diff --git a/phpBB/includes/acp/acp_ban.php b/phpBB/includes/acp/acp_ban.php index 7cc6741e23..361ef2666c 100644 --- a/phpBB/includes/acp/acp_ban.php +++ b/phpBB/includes/acp/acp_ban.php @@ -176,8 +176,6 @@ class acp_ban $result = $db->sql_query($sql); $banned_options = $excluded_options = array(); - $ban_length = $ban_reasons = $ban_give_reasons = array(); - while ($row = $db->sql_fetchrow($result)) { $option = '<option value="' . $row['ban_id'] . '">' . $row[$field] . '</option>'; @@ -196,60 +194,31 @@ class acp_ban if ($time_length == 0) { // Banned permanently - $ban_length[$row['ban_id']] = $user->lang['PERMANENT']; + $ban_length = $user->lang['PERMANENT']; } else if (isset($ban_end_text[$time_length])) { // Banned for a given duration - $ban_length[$row['ban_id']] = sprintf($user->lang['BANNED_UNTIL_DURATION'], $ban_end_text[$time_length], $user->format_date($row['ban_end'], false, true)); + $ban_length = $user->lang('BANNED_UNTIL_DURATION', $ban_end_text[$time_length], $user->format_date($row['ban_end'], false, true)); } else { // Banned until given date - $ban_length[$row['ban_id']] = sprintf($user->lang['BANNED_UNTIL_DATE'], $user->format_date($row['ban_end'], false, true)); + $ban_length = $user->lang('BANNED_UNTIL_DATE', $user->format_date($row['ban_end'], false, true)); } - $ban_reasons[$row['ban_id']] = $row['ban_reason']; - $ban_give_reasons[$row['ban_id']] = $row['ban_give_reason']; + $template->assign_block_vars('bans', array( + 'BAN_ID' => (int) $row['ban_id'], + 'LENGTH' => $ban_length, + 'A_LENGTH' => addslashes($ban_length), + 'REASON' => $row['ban_reason'], + 'A_REASON' => addslashes($row['ban_reason']), + 'GIVE_REASON' => $row['ban_give_reason'], + 'A_GIVE_REASON' => addslashes($row['ban_give_reason']), + )); } $db->sql_freeresult($result); - if (sizeof($ban_length)) - { - foreach ($ban_length as $ban_id => $length) - { - $template->assign_block_vars('ban_length', array( - 'BAN_ID' => (int) $ban_id, - 'LENGTH' => $length, - 'A_LENGTH' => addslashes($length), - )); - } - } - - if (sizeof($ban_reasons)) - { - foreach ($ban_reasons as $ban_id => $reason) - { - $template->assign_block_vars('ban_reason', array( - 'BAN_ID' => $ban_id, - 'REASON' => $reason, - 'A_REASON' => addslashes($reason), - )); - } - } - - if (sizeof($ban_give_reasons)) - { - foreach ($ban_give_reasons as $ban_id => $reason) - { - $template->assign_block_vars('ban_give_reason', array( - 'BAN_ID' => $ban_id, - 'REASON' => $reason, - 'A_REASON' => addslashes($reason), - )); - } - } - $options = ''; if ($excluded_options) { diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 1811748c2f..f2707f15ca 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -925,7 +925,7 @@ class acp_board { $user->timezone = new DateTimeZone($config['board_timezone']); } - catch (Exception $e) + catch (\Exception $e) { // If the board timezone is invalid, we just use the users timezone. } diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index aba9caaece..9bdd8eb458 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -137,6 +137,12 @@ class acp_extensions trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING); } + $extension = $phpbb_extension_manager->get_extension($ext_name); + if (!$extension->is_enableable()) + { + trigger_error($user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING); + } + if ($phpbb_extension_manager->is_enabled($ext_name)) { redirect($this->u_action); @@ -162,6 +168,12 @@ class acp_extensions trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING); } + $extension = $phpbb_extension_manager->get_extension($ext_name); + if (!$extension->is_enableable()) + { + trigger_error($user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING); + } + if ($phpbb_extension_manager->is_enabled($ext_name)) { redirect($this->u_action); diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index 0d0d49774c..2a28226d6c 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -26,7 +26,7 @@ class acp_main function main($id, $mode) { global $config, $db, $cache, $user, $auth, $template, $request; - global $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_container; + global $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_container, $phpbb_dispatcher; // Show restore permissions notice if ($user->data['user_perm_from'] && $auth->acl_get('a_switchperm')) @@ -445,6 +445,14 @@ class acp_main )); } + /** + * Notice admin + * + * @event core.acp_main_notice + * @since 3.1.0-RC3 + */ + $phpbb_dispatcher->dispatch('core.acp_main_notice'); + // Get forum statistics $total_posts = $config['num_posts']; $total_topics = $config['num_topics']; diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 5932f4cddd..ea6b388328 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -766,7 +766,8 @@ class acp_modules /** * Update/Add module * - * @param bool $run_inline if set to true errors will be returned and no logs being written + * @param array &$module_data The module data + * @param bool $run_inline if set to true errors will be returned and no logs being written */ function update_module_data(&$module_data, $run_inline = false) { diff --git a/phpBB/includes/acp/acp_ranks.php b/phpBB/includes/acp/acp_ranks.php index fdbd0e0a1d..5885de57ec 100644 --- a/phpBB/includes/acp/acp_ranks.php +++ b/phpBB/includes/acp/acp_ranks.php @@ -25,7 +25,7 @@ class acp_ranks function main($id, $mode) { - global $db, $user, $auth, $template, $cache, $request; + global $db, $user, $auth, $template, $cache, $request, $phpbb_dispatcher; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/posting'); @@ -73,6 +73,17 @@ class acp_ranks 'rank_image' => htmlspecialchars_decode($rank_image) ); + /** + * Modify the SQL array when saving a rank + * + * @event core.acp_ranks_save_modify_sql_ary + * @var int rank_id The ID of the rank (if available) + * @var array sql_ary Array with the rank's data + * @since 3.1.0-RC3 + */ + $vars = array('rank_id', 'sql_ary'); + extract($phpbb_dispatcher->trigger_event('core.acp_ranks_save_modify_sql_ary', compact($vars))); + if ($rank_id) { $sql = 'UPDATE ' . RANKS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " WHERE rank_id = $rank_id"; @@ -202,7 +213,7 @@ class acp_ranks $filename_list = '<option value=""' . (($edit_img == '') ? ' selected="selected"' : '') . '>----------</option>' . $filename_list; unset($existing_imgs, $imglist); - $template->assign_vars(array( + $tpl_ary = array( 'S_EDIT' => true, 'U_BACK' => $this->u_action, 'RANKS_PATH' => $phpbb_root_path . $config['ranks_path'], @@ -212,9 +223,21 @@ class acp_ranks 'S_FILENAME_LIST' => $filename_list, 'RANK_IMAGE' => ($edit_img) ? $phpbb_root_path . $config['ranks_path'] . '/' . $edit_img : htmlspecialchars($phpbb_admin_path) . 'images/spacer.gif', 'S_SPECIAL_RANK' => (isset($ranks['rank_special']) && $ranks['rank_special']) ? true : false, - 'MIN_POSTS' => (isset($ranks['rank_min']) && !$ranks['rank_special']) ? $ranks['rank_min'] : 0) + 'MIN_POSTS' => (isset($ranks['rank_min']) && !$ranks['rank_special']) ? $ranks['rank_min'] : 0, ); + /** + * Modify the template output array for editing/adding ranks + * + * @event core.acp_ranks_edit_modify_tpl_ary + * @var array ranks Array with the rank's data + * @var array tpl_ary Array with the rank's template data + * @since 3.1.0-RC3 + */ + $vars = array('ranks', 'tpl_ary'); + extract($phpbb_dispatcher->trigger_event('core.acp_ranks_edit_modify_tpl_ary', compact($vars))); + + $template->assign_vars($tpl_ary); return; break; @@ -231,7 +254,7 @@ class acp_ranks while ($row = $db->sql_fetchrow($result)) { - $template->assign_block_vars('ranks', array( + $rank_row = array( 'S_RANK_IMAGE' => ($row['rank_image']) ? true : false, 'S_SPECIAL_RANK' => ($row['rank_special']) ? true : false, @@ -240,8 +263,21 @@ class acp_ranks 'MIN_POSTS' => $row['rank_min'], 'U_EDIT' => $this->u_action . '&action=edit&id=' . $row['rank_id'], - 'U_DELETE' => $this->u_action . '&action=delete&id=' . $row['rank_id']) + 'U_DELETE' => $this->u_action . '&action=delete&id=' . $row['rank_id'], ); + + /** + * Modify the template output array for each listed rank + * + * @event core.acp_ranks_list_modify_rank_row + * @var array row Array with the rank's data + * @var array rank_row Array with the rank's template data + * @since 3.1.0-RC3 + */ + $vars = array('row', 'rank_row'); + extract($phpbb_dispatcher->trigger_event('core.acp_ranks_list_modify_rank_row', compact($vars))); + + $template->assign_block_vars('ranks', $rank_row); } $db->sql_freeresult($result); diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 4cc93e5670..2a02e3e845 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -804,7 +804,7 @@ class acp_styles * * @param array $styles Styles list, passed as reference * @param string $name Name of parent style - * @param string $level Styles tree level + * @param int $level Styles tree level */ protected function show_available_child_styles(&$styles, $name, $level) { @@ -888,7 +888,7 @@ class acp_styles * Show item in styles list * * @param array $style style row - * @param array $level style inheritance level + * @param int $level style inheritance level */ protected function list_style(&$style, $level) { diff --git a/phpBB/includes/acp/auth.php b/phpBB/includes/acp/auth.php index 7ff3212b72..905e981cdc 100644 --- a/phpBB/includes/acp/auth.php +++ b/phpBB/includes/acp/auth.php @@ -183,7 +183,10 @@ class auth_admin extends \phpbb\auth\auth } // Defining the user-function here to save some memory - $return_acl_fill = create_function('$value', 'return ' . $acl_fill . ';'); + $return_acl_fill = function () use ($acl_fill) + { + return $acl_fill; + }; // Actually fill the gaps if (sizeof($hold_ary)) diff --git a/phpBB/includes/diff/diff.php b/phpBB/includes/diff/diff.php index dd0fbcee02..d307880c4b 100644 --- a/phpBB/includes/diff/diff.php +++ b/phpBB/includes/diff/diff.php @@ -46,8 +46,9 @@ class diff /** * Computes diffs between sequences of strings. * - * @param array $from_lines An array of strings. Typically these are lines from a file. - * @param array $to_lines An array of strings. + * @param array &$from_content An array of strings. Typically these are lines from a file. + * @param array &$to_content An array of strings. + * @param bool $preserve_cr If true, \r is replaced by a new line in the diff output */ function diff(&$from_content, &$to_content, $preserve_cr = true) { @@ -491,9 +492,11 @@ class diff3 extends diff /** * Computes diff between 3 sequences of strings. * - * @param array $orig The original lines to use. - * @param array $final1 The first version to compare to. - * @param array $final2 The second version to compare to. + * @param array &$orig The original lines to use. + * @param array &$final1 The first version to compare to. + * @param array &$final2 The second version to compare to. + * @param bool $preserve_cr If true, \r\n and bare \r are replaced by a new line + * in the diff output */ function diff3(&$orig, &$final1, &$final2, $preserve_cr = true) { diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index ced3b36cbe..53ccf2df2c 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1031,7 +1031,7 @@ function phpbb_get_timezone_identifiers($selected_timezone) $validate_timezone = new DateTimeZone($selected_timezone); $timezones[] = $selected_timezone; } - catch (Exception $e) + catch (\Exception $e) { } } @@ -1067,7 +1067,7 @@ function phpbb_timezone_select($user, $default = '', $truncate = false) $offset_string = phpbb_format_timezone_offset($offset); $timezones['GMT' . $offset_string . ' - ' . $timezone] = array( 'tz' => $timezone, - 'offest' => 'GMT' . $offset_string, + 'offset' => 'GMT' . $offset_string, 'current' => $current_time, ); if ($timezone === $default) @@ -1084,14 +1084,14 @@ function phpbb_timezone_select($user, $default = '', $truncate = false) foreach ($timezones as $timezone) { - if ($opt_group != $timezone['offest']) + if ($opt_group != $timezone['offset']) { $tz_select .= ($opt_group) ? '</optgroup>' : ''; - $tz_select .= '<optgroup label="' . $timezone['offest'] . ' - ' . $timezone['current'] . '">'; - $opt_group = $timezone['offest']; + $tz_select .= '<optgroup label="' . $timezone['offset'] . ' - ' . $timezone['current'] . '">'; + $opt_group = $timezone['offset']; - $selected = ($default_offset == $timezone['offest']) ? ' selected="selected"' : ''; - $tz_dates .= '<option value="' . $timezone['offest'] . ' - ' . $timezone['current'] . '"' . $selected . '>' . $timezone['offest'] . ' - ' . $timezone['current'] . '</option>'; + $selected = ($default_offset == $timezone['offset']) ? ' selected="selected"' : ''; + $tz_dates .= '<option value="' . $timezone['offset'] . ' - ' . $timezone['current'] . '"' . $selected . '>' . $timezone['offset'] . ' - ' . $timezone['current'] . '</option>'; } $label = $timezone['tz']; @@ -1099,7 +1099,7 @@ function phpbb_timezone_select($user, $default = '', $truncate = false) { $label = $user->lang['timezones'][$label]; } - $title = $timezone['offest'] . ' - ' . $label; + $title = $timezone['offset'] . ' - ' . $label; if ($truncate) { @@ -2210,7 +2210,7 @@ function generate_board_url($without_script_path = false) */ function redirect($url, $return = false, $disable_cd_check = false) { - global $db, $cache, $config, $user, $phpbb_root_path, $phpbb_filesystem, $phpbb_path_helper, $phpEx; + global $db, $cache, $config, $user, $phpbb_root_path, $phpbb_filesystem, $phpbb_path_helper, $phpEx, $phpbb_dispatcher; $failover_flag = false; @@ -2219,11 +2219,6 @@ function redirect($url, $return = false, $disable_cd_check = false) $user->add_lang('common'); } - if (!$return) - { - garbage_collection(); - } - // Make sure no &'s are in, this will break the redirect $url = str_replace('&', '&', $url); @@ -2298,10 +2293,26 @@ function redirect($url, $return = false, $disable_cd_check = false) trigger_error('INSECURE_REDIRECT', E_USER_ERROR); } + /** + * Execute code and/or overwrite redirect() + * + * @event core.functions.redirect + * @var string url The url + * @var bool return If true, do not redirect but return the sanitized URL. + * @var bool disable_cd_check If true, redirect() will redirect to an external domain. If false, the redirect point to the boards url if it does not match the current domain. + * @since 3.1.0-RC3 + */ + $vars = array('url', 'return', 'disable_cd_check'); + extract($phpbb_dispatcher->trigger_event('core.functions.redirect', compact($vars))); + if ($return) { return $url; } + else + { + garbage_collection(); + } // Redirect via an HTML form for PITA webservers if (@preg_match('#Microsoft|WebSTAR|Xitami#', getenv('SERVER_SOFTWARE'))) @@ -4955,7 +4966,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id = 'U_SEARCH_UNREAD' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=unreadposts'), 'U_SEARCH_ACTIVE_TOPICS'=> append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=active_topics'), 'U_DELETE_COOKIES' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=delete_cookies'), - 'U_CONTACT_US' => ($config['contact_admin_form_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contactadmin') : '', + 'U_CONTACT_US' => ($config['contact_admin_form_enable'] && $config['email_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contactadmin') : '', 'U_TEAM' => ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile')) ? '' : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=team'), 'U_TERMS_USE' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=terms'), 'U_PRIVACY' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=privacy'), @@ -5091,9 +5102,10 @@ function phpbb_check_and_display_sql_report(\phpbb\request\request_interface $re * @param \phpbb\config\config $config Config object * @param \phpbb\auth\auth $auth Auth object * @param \phpbb\user $user User object +* @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher * @return string */ -function phpbb_generate_debug_output(phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\auth\auth $auth, \phpbb\user $user) +function phpbb_generate_debug_output(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\auth\auth $auth, \phpbb\user $user, \phpbb\event\dispatcher_interface $phpbb_dispatcher) { $debug_info = array(); @@ -5132,6 +5144,17 @@ function phpbb_generate_debug_output(phpbb\db\driver\driver_interface $db, \phpb } } + /** + * Modify debug output information + * + * @event core.phpbb_generate_debug_output + * @var array debug_info Array of strings with debug information + * + * @since 3.1.0-RC3 + */ + $vars = array('debug_info'); + extract($phpbb_dispatcher->trigger_event('core.phpbb_generate_debug_output', compact($vars))); + return implode(' | ', $debug_info); } @@ -5170,7 +5193,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler = phpbb_check_and_display_sql_report($request, $auth, $db); $template->assign_vars(array( - 'DEBUG_OUTPUT' => phpbb_generate_debug_output($db, $config, $auth, $user), + 'DEBUG_OUTPUT' => phpbb_generate_debug_output($db, $config, $auth, $user, $phpbb_dispatcher), 'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '', 'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Limited'), @@ -5362,7 +5385,7 @@ function phpbb_get_board_contact(\phpbb\config\config $config, $phpEx) */ function phpbb_get_board_contact_link(\phpbb\config\config $config, $phpbb_root_path, $phpEx) { - if ($config['contact_admin_form_enable']) + if ($config['contact_admin_form_enable'] && $config['email_enable']) { return append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contactadmin'); } diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php index 6b2b0000d1..d9dc11239c 100644 --- a/phpBB/includes/functions_acp.php +++ b/phpBB/includes/functions_acp.php @@ -168,7 +168,7 @@ function adm_page_footer($copyright_html = true) phpbb_check_and_display_sql_report($request, $auth, $db); $template->assign_vars(array( - 'DEBUG_OUTPUT' => phpbb_generate_debug_output($db, $config, $auth, $user), + 'DEBUG_OUTPUT' => phpbb_generate_debug_output($db, $config, $auth, $user, $phpbb_dispatcher), 'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '', 'S_COPYRIGHT_HTML' => $copyright_html, 'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Limited'), @@ -259,7 +259,6 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars) case 'range': case 'search': case 'tel': - case 'url': case 'week': $size = (int) $tpl_type[1]; $maxlength = (int) $tpl_type[2]; @@ -675,3 +674,30 @@ function validate_range($value_ary, &$error) } } } + +/** +* Inserts new config display_vars into an exisiting display_vars array +* at the given position. +* +* @param array $display_vars An array of existing config display vars +* @param array $add_config_vars An array of new config display vars +* @param array $where Where to place the new config vars, +* before or after an exisiting config, as an array +* of the form: array('after' => 'config_name') or +* array('before' => 'config_name'). +* @return array The array of config display vars +*/ +function phpbb_insert_config_array($display_vars, $add_config_vars, $where) +{ + if (is_array($where) && array_key_exists(current($where), $display_vars)) + { + $position = array_search(current($where), array_keys($display_vars)) + ((key($where) == 'before') ? 0 : 1); + $display_vars = array_merge( + array_slice($display_vars, 0, $position), + $add_config_vars, + array_slice($display_vars, $position) + ); + } + + return $display_vars; +} diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 68b1356297..78137d075b 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -1063,7 +1063,8 @@ function display_reasons($reason_id = 0) function display_user_activity(&$userdata) { global $auth, $template, $db, $user; - global $phpbb_root_path, $phpEx, $phpbb_container; + global $phpbb_root_path, $phpEx; + global $phpbb_container, $phpbb_dispatcher; // Do not display user activity for users having more than 5000 posts... if ($userdata['user_posts'] > 5000) @@ -1134,6 +1135,18 @@ function display_user_activity(&$userdata) } } + /** + * Alter list of forums and topics to display as active + * + * @event core.display_user_activity_modify_actives + * @var array userdata User's data + * @var array active_f_row List of active forums + * @var array active_t_row List of active posts + * @since 3.1.0-RC3 + */ + $vars = array('userdata', 'active_f_row', 'active_t_row'); + extract($phpbb_dispatcher->trigger_event('core.display_user_activity_modify_actives', compact($vars))); + $userdata['active_t_row'] = $active_t_row; $userdata['active_f_row'] = $active_f_row; @@ -1408,44 +1421,6 @@ function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank } /** -* Generate a list of archive types available for compressing attachments -* -* @param string $param_key Either topic_id or post_id -* @param string $param_val The value of the topic or post id -* @param string $phpbb_root_path The root path of the phpBB installation -* @param string $phpEx The PHP extension -* -* @return array Array containing the link and the type of compression -*/ -function phpbb_gen_download_links($param_key, $param_val, $phpbb_root_path, $phpEx) -{ - if (!class_exists('compress')) - { - require $phpbb_root_path . 'includes/functions_compress.' . $phpEx; - } - - $methods = compress::methods(); - // Sort by preferred type. - $methods = array_intersect(array('.zip', '.tar.bz2', '.tar.gz', '.tar'), $methods); - $links = array(); - - foreach ($methods as $method) - { - $exploded = explode('.', $method); - $type = array_pop($exploded); - $params = array('archive' => $method); - $params[$param_key] = $param_val; - - $links[] = array( - 'LINK' => append_sid("{$phpbb_root_path}download/file.$phpEx", $params), - 'TYPE' => $type, - ); - } - - return $links; -} - -/** * Prepare profile data */ function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabled = false) diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index 7a7efd5b34..4ff3994f4c 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -718,27 +718,6 @@ function phpbb_download_check_pm_auth($db, $user_id, $msg_id) } /** -* Cleans a filename of any characters that could potentially cause a problem on -* a user's filesystem. -* -* @param string $filename The filename to clean -* -* @return string The cleaned filename -*/ -function phpbb_download_clean_filename($filename) -{ - $bad_chars = array("'", "\\", ' ', '/', ':', '*', '?', '"', '<', '>', '|'); - - // rawurlencode to convert any potentially 'bad' characters that we missed - $filename = rawurlencode(str_replace($bad_chars, '_', $filename)); - - // Turn the %xx entities created by rawurlencode to _ - $filename = preg_replace("/%(\w{2})/", '_', $filename); - - return $filename; -} - -/** * Check if the browser is internet explorer version 7+ * * @param string $user_agent User agent HTTP header diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index 06f49e4b50..28cc603bdb 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -266,7 +266,7 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix, if (is_array($db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true))) { $db_error = $db->sql_error(); - $error[] = $lang['INST_ERR_DB_CONNECT'] . '<br />' . (($db_error['message']) ? $db_error['message'] : $lang['INST_ERR_DB_NO_ERROR']); + $error[] = $lang['INST_ERR_DB_CONNECT'] . '<br />' . (($db_error['message']) ? utf8_convert_message($db_error['message']) : $lang['INST_ERR_DB_NO_ERROR']); } else { @@ -449,6 +449,7 @@ function phpbb_create_config_file_data($data, $dbms, $debug = false, $debug_cont } $config_data .= "\n@define('PHPBB_INSTALLED', true);\n"; + $config_data .= "// @define('PHPBB_DISPLAY_LOAD_TIME', true);\n"; if ($debug) { diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index 86439ea03f..fe9bcdb9d1 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -489,6 +489,12 @@ class p_master $id = request_var('icat', ''); } + // Restore the backslashes in class names + if (strpos($id, '-') !== false) + { + $id = str_replace('-', '\\', $id); + } + if ($id && !is_numeric($id) && !$this->is_full_class($id)) { $id = $this->p_class . '_' . $id; @@ -541,7 +547,9 @@ class p_master * * This method loads a given module, passing it the relevant id and mode. * - * @param string $mode mode, as passed through to the module + * @param string|false $mode mode, as passed through to the module + * @param string|false $module_url If supplied, we use this module url + * @param bool $execute_module If true, at the end we execute the main method for the new instance */ function load_active($mode = false, $module_url = false, $execute_module = true) { @@ -614,7 +622,7 @@ class p_master } // Not being able to overwrite ;) - $this->module->u_action = append_sid("{$phpbb_admin_path}index.$phpEx", 'i=' . $this->get_module_identifier($this->p_name, $this->p_id)) . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; + $this->module->u_action = append_sid("{$phpbb_admin_path}index.$phpEx", 'i=' . $this->get_module_identifier($this->p_name)) . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; } else { @@ -646,7 +654,7 @@ class p_master $this->module->u_action = $phpbb_root_path . (($user->page['page_dir']) ? $user->page['page_dir'] . '/' : '') . $user->page['page_name']; } - $this->module->u_action = append_sid($this->module->u_action, 'i=' . $this->get_module_identifier($this->p_name, $this->p_id)) . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; + $this->module->u_action = append_sid($this->module->u_action, 'i=' . $this->get_module_identifier($this->p_name)) . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; } // Add url_extra parameter to u_action url @@ -899,7 +907,7 @@ class p_master else { // if the category has a name, then use it. - $u_title .= $this->get_module_identifier($item_ary['name'], $item_ary['id']); + $u_title .= $this->get_module_identifier($item_ary['name']); } // If the item is not a category append the mode if (!$item_ary['cat']) @@ -1040,19 +1048,45 @@ class p_master */ function add_mod_info($module_class) { - global $user, $phpEx; - - global $phpbb_extension_manager; + global $config, $user, $phpEx, $phpbb_extension_manager; $finder = $phpbb_extension_manager->get_finder(); - $lang_files = $finder + // We grab the language files from the default, English and user's language. + // So we can fall back to the other files like we do when using add_lang() + $default_lang_files = $english_lang_files = $user_lang_files = array(); + + // Search for board default language if it's not the user language + if ($config['default_lang'] != $user->lang_name) + { + $default_lang_files = $finder + ->prefix('info_' . strtolower($module_class) . '_') + ->suffix(".$phpEx") + ->extension_directory('/language/' . basename($config['default_lang'])) + ->core_path('language/' . basename($config['default_lang']) . '/mods/') + ->find(); + } + + // Search for english, if its not the default or user language + if ($config['default_lang'] != 'en' && $user->lang_name != 'en') + { + $english_lang_files = $finder + ->prefix('info_' . strtolower($module_class) . '_') + ->suffix(".$phpEx") + ->extension_directory('/language/en') + ->core_path('language/en/mods/') + ->find(); + } + + // Find files in the user's language + $user_lang_files = $finder ->prefix('info_' . strtolower($module_class) . '_') ->suffix(".$phpEx") ->extension_directory('/language/' . $user->lang_name) ->core_path('language/' . $user->lang_name . '/mods/') ->find(); + $lang_files = array_unique(array_merge($user_lang_files, $english_lang_files, $default_lang_files)); foreach ($lang_files as $lang_file => $ext_name) { $user->add_lang_ext($ext_name, $lang_file); @@ -1078,26 +1112,24 @@ class p_master } /** - * If the basename contains a \ we dont use that for the URL. + * If the basename contains a \ we don't use that for the URL. * * Firefox is currently unable to correctly copy a urlencoded \ * so users will be unable to post links to modules. - * However we can still fallback to the id instead of the name, - * so we do that in this case. + * However we can replace them with dashes and re-replace them later * * @param string $basename Basename of the module - * @param int $id Id of the module - * @return mixed Identifier that should be used for + * @return string Identifier that should be used for * module link creation */ - protected function get_module_identifier($basename, $id) + protected function get_module_identifier($basename) { if (strpos($basename, '\\') === false) { return $basename; } - return $id; + return str_replace('\\', '-', $basename); } /** diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 0b37af0ee0..624ce187b9 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -398,14 +398,15 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL) * @param string $local_storage The path to the local file * @param bool $is_message Whether it is a PM or not * @param \filespec $local_filedata A filespec object created for the local file +* @param \phpbb\mimetype\guesser $mimetype_guesser The mimetype guesser object if used * @param \phpbb\plupload\plupload $plupload The plupload object if one is being used * * @return object filespec */ -function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false, \phpbb\plupload\plupload $plupload = null) +function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { global $auth, $user, $config, $db, $cache; - global $phpbb_root_path, $phpEx; + global $phpbb_root_path, $phpEx, $phpbb_dispatcher; $filedata = array( 'error' => array() @@ -434,7 +435,7 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage $extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id)); $upload->set_allowed_extensions(array_keys($extensions['_allowed_'])); - $file = ($local) ? $upload->local_upload($local_storage, $local_filedata) : $upload->form_upload($form_name, $plupload); + $file = ($local) ? $upload->local_upload($local_storage, $local_filedata, $mimetype_guesser) : $upload->form_upload($form_name, $mimetype_guesser, $plupload); if ($file->init_error) { @@ -506,6 +507,20 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage $filedata['real_filename'] = $file->get('uploadname'); $filedata['filetime'] = time(); + /** + * Event to modify uploaded file before submit to the post + * + * @event core.modify_uploaded_file + * @var array filedata Array containing uploaded file data + * @var bool is_image Flag indicating if the file is an image + * @since 3.1.0-RC3 + */ + $vars = array( + 'filedata', + 'is_image', + ); + extract($phpbb_dispatcher->trigger_event('core.modify_uploaded_file', compact($vars))); + // Check our complete quota if ($config['attachment_quota']) { @@ -893,7 +908,7 @@ function posting_gen_attachment_entry($attachment_data, &$filename_data, $show_a function load_drafts($topic_id = 0, $forum_id = 0, $id = 0, $pm_action = '', $msg_id = 0) { global $user, $db, $template, $auth; - global $phpbb_root_path, $phpEx; + global $phpbb_root_path, $phpbb_dispatcher, $phpEx; $topic_ids = $forum_ids = $draft_rows = array(); @@ -936,7 +951,7 @@ function load_drafts($topic_id = 0, $forum_id = 0, $id = 0, $pm_action = '', $ms $topic_rows = array(); if (sizeof($topic_ids)) { - $sql = 'SELECT topic_id, forum_id, topic_title + $sql = 'SELECT topic_id, forum_id, topic_title, topic_poster FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', array_unique($topic_ids)); $result = $db->sql_query($sql); @@ -947,6 +962,20 @@ function load_drafts($topic_id = 0, $forum_id = 0, $id = 0, $pm_action = '', $ms } $db->sql_freeresult($result); } + + /** + * Drafts found and their topics + * Edit $draft_rows in order to add or remove drafts loaded + * + * @event core.load_drafts_draft_list_result + * @var array draft_rows The drafts query result. Includes its forum id and everything about the draft + * @var array topic_ids The list of topics got from the topics table + * @var array topic_rows The topics that draft_rows references + * @since 3.1.0-RC3 + */ + $vars = array('draft_rows', 'topic_ids', 'topic_rows'); + extract($phpbb_dispatcher->trigger_event('core.load_drafts_draft_list_result', compact($vars))); + unset($topic_ids); $template->assign_var('S_SHOW_DRAFTS', true); @@ -1295,18 +1324,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $ { delete_topics('topic_id', array($topic_id), false); - if ($data['topic_visibility'] == ITEM_APPROVED) - { - $sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1'; - } - else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) - { - $sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1'; - } - else if ($data['topic_visibility'] == ITEM_DELETED) - { - $sql_data[FORUMS_TABLE] .= 'forum_posts_softdeleted = forum_posts_softdeleted - 1, forum_topics_softdeleted = forum_topics_softdeleted - 1'; - } + $phpbb_content_visibility->remove_topic_from_statistic($data, $sql_data); $update_sql = update_post_information('forum', $forum_id, true); if (sizeof($update_sql)) @@ -1402,20 +1420,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $ { if (!$is_soft) { - if ($data['post_visibility'] == ITEM_APPROVED) - { - $phpbb_content_visibility->remove_post_from_statistic($data, $sql_data); - } - else if ($data['post_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) - { - $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_unapproved = forum_posts_unapproved - 1'; - $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_unapproved = topic_posts_unapproved - 1'; - } - else if ($data['post_visibility'] == ITEM_DELETED) - { - $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_softdeleted = forum_posts_softdeleted - 1'; - $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_softdeleted = topic_posts_softdeleted - 1'; - } + $phpbb_content_visibility->remove_post_from_statistic($data, $sql_data); } $sql = 'SELECT 1 AS has_attachments @@ -2373,12 +2378,31 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u * event is to modify the return URL ($url). * * @event core.submit_post_end - * @var string url The "Return to topic" URL - * @var array data Array of post data about the - * submitted post + * @var string mode Variable containing posting mode value + * @var string subject Variable containing post subject value + * @var string username Variable containing post author name + * @var int topic_type Variable containing topic type value + * @var array poll Array with the poll data for the post + * @var array data Array with the data for the post + * @var bool update_message Flag indicating if the post will be updated + * @var bool update_search_index Flag indicating if the search index will be updated + * @var string url The "Return to topic" URL + * * @since 3.1.0-a3 + * @change 3.1.0-RC3 Added vars mode, subject, username, topic_type, + * poll, update_message, update_search_index */ - $vars = array('url', 'data'); + $vars = array( + 'mode', + 'subject', + 'username', + 'topic_type', + 'poll', + 'data', + 'update_message', + 'update_search_index', + 'url', + ); extract($phpbb_dispatcher->trigger_event('core.submit_post_end', compact($vars))); return $url; diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index e60311f8ab..488f46a398 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -212,7 +212,7 @@ function get_folder($user_id, $folder_id = false) ); } - if ($folder_id !== false && !isset($folder[$folder_id])) + if ($folder_id !== false && $folder_id !== PRIVMSGS_HOLD_BOX && !isset($folder[$folder_id])) { trigger_error('UNKNOWN_FOLDER'); } diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index 0847c3a550..a0a67ccf3d 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -53,10 +53,16 @@ class filespec protected $plupload; /** + * phpBB Mimetype guesser + * @var \phpbb\mimetype\guesser + */ + protected $mimetype_guesser; + + /** * File Class * @access private */ - function filespec($upload_ary, $upload_namespace, \phpbb\plupload\plupload $plupload = null) + function filespec($upload_ary, $upload_namespace, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { if (!isset($upload_ary)) { @@ -76,7 +82,7 @@ class filespec if (!$this->mimetype) { - $this->mimetype = 'application/octetstream'; + $this->mimetype = 'application/octet-stream'; } $this->extension = strtolower(self::get_extension($this->realname)); @@ -90,6 +96,7 @@ class filespec $this->local = (isset($upload_ary['local_mode'])) ? true : false; $this->upload = $upload_namespace; $this->plupload = $plupload; + $this->mimetype_guesser = $mimetype_guesser; } /** @@ -97,6 +104,7 @@ class filespec * * @param real|unique|unique_ext $mode real creates a realname, filtering some characters, lowering every character. Unique creates an unique filename * @param string $prefix Prefix applied to filename + * @param string $user_id The user_id is only needed for when cleaning a user's avatar * @access public */ function clean_filename($mode = 'unique', $prefix = '', $user_id = '') @@ -215,25 +223,19 @@ class filespec } /** - * Get mimetype. Utilize mime_content_type if the function exist. - * Not used at the moment... + * Get mimetype + * + * @param string $filename Filename that needs to be checked + * @return string Mimetype of supplied filename */ function get_mimetype($filename) { - $mimetype = ''; - - if (function_exists('mime_content_type')) - { - $mimetype = mime_content_type($filename); - } - - // Some browsers choke on a mimetype of application/octet-stream - if (!$mimetype || $mimetype == 'application/octet-stream') + if ($this->mimetype_guesser !== null) { - $mimetype = 'application/octetstream'; + $this->mimetype = $this->mimetype_guesser->guess($filename); } - return $mimetype; + return $this->mimetype; } /** @@ -276,8 +278,9 @@ class filespec * Move file to destination folder * The phpbb_root_path variable will be applied to the destination path * - * @param string $destination_path Destination path, for example $config['avatar_path'] + * @param string $destination Destination path, for example $config['avatar_path'] * @param bool $overwrite If set to true, an already existing file will be overwritten + * @param bool $skip_image_check If set to true, the check for the file to be a valid image is skipped * @param string $chmod Permission mask for chmodding the file after a successful move. The mode entered here reflects the mode defined by {@link phpbb_chmod()} * * @access public @@ -372,6 +375,9 @@ class filespec // Try to get real filesize from destination folder $this->filesize = (@filesize($this->destination_file)) ? @filesize($this->destination_file) : $this->filesize; + // Get mimetype of supplied file + $this->mimetype = $this->get_mimetype($this->destination_file); + if ($this->is_image() && !$skip_image_check) { $this->width = $this->height = 0; @@ -498,6 +504,8 @@ class fileupload * @param int $min_height Minimum image height (only checked for images) * @param int $max_width Maximum image width (only checked for images) * @param int $max_height Maximum image height (only checked for images) + * @param bool|array $disallowed_content If enabled, the first 256 bytes of the file must not + * contain any of its values. Defaults to false. * */ function fileupload($error_prefix = '', $allowed_extensions = false, $max_filesize = false, $min_width = false, $min_height = false, $max_width = false, $max_height = false, $disallowed_content = false) @@ -578,12 +586,13 @@ class fileupload * Upload file from users harddisk * * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) + * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser * @param \phpbb\plupload\plupload $plupload The plupload object * * @return object $file Object "filespec" is returned, all further operations can be done with this object * @access public */ - function form_upload($form_name, \phpbb\plupload\plupload $plupload = null) + function form_upload($form_name, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) { global $user, $request; @@ -599,7 +608,7 @@ class fileupload } } - $file = new filespec($upload, $this, $plupload); + $file = new filespec($upload, $this, $mimetype_guesser, $plupload); if ($file->init_error) { @@ -659,7 +668,7 @@ class fileupload /** * Move file from another location to phpBB */ - function local_upload($source_file, $filedata = false) + function local_upload($source_file, $filedata = false, \phpbb\mimetype\guesser $mimetype_guesser = null) { global $user, $request; @@ -672,20 +681,6 @@ class fileupload { $upload['name'] = utf8_basename($source_file); $upload['size'] = 0; - $mimetype = ''; - - if (function_exists('mime_content_type')) - { - $mimetype = mime_content_type($source_file); - } - - // Some browsers choke on a mimetype of application/octet-stream - if (!$mimetype || $mimetype == 'application/octet-stream') - { - $mimetype = 'application/octetstream'; - } - - $upload['type'] = $mimetype; } else { @@ -694,7 +689,7 @@ class fileupload $upload['type'] = $filedata['type']; } - $file = new filespec($upload, $this); + $file = new filespec($upload, $this, $mimetype_guesser); if ($file->init_error) { @@ -749,10 +744,11 @@ class fileupload * Uploads file from given url * * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif + * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser * @return object $file Object "filespec" is returned, all further operations can be done with this object * @access public */ - function remote_upload($upload_url) + function remote_upload($upload_url, \phpbb\mimetype\guesser $mimetype_guesser = null) { global $user, $phpbb_root_path; @@ -931,7 +927,7 @@ class fileupload $upload_ary['tmp_name'] = $filename; - $file = new filespec($upload_ary, $this); + $file = new filespec($upload_ary, $this, $mimetype_guesser); $this->common_checks($file); return $file; diff --git a/phpBB/includes/functions_url_matcher.php b/phpBB/includes/functions_url_matcher.php index 7e17d1c2d8..b965046aad 100644 --- a/phpBB/includes/functions_url_matcher.php +++ b/phpBB/includes/functions_url_matcher.php @@ -29,7 +29,7 @@ if (!defined('IN_PHPBB')) * @param \phpbb\extension\manager $manager Extension manager * @param RequestContext $context Symfony RequestContext object * @param string $root_path Root path -* @param string $php_ext PHP extension +* @param string $php_ext PHP file extension * @return null */ function phpbb_get_url_matcher(\phpbb\extension\manager $manager, RequestContext $context, $root_path, $php_ext) @@ -52,7 +52,7 @@ function phpbb_get_url_matcher(\phpbb\extension\manager $manager, RequestContext * * @param \phpbb\extension\manager $manager Extension manager * @param string $root_path Root path -* @param string $php_ext PHP extension +* @param string $php_ext PHP file extension * @return null */ function phpbb_create_dumped_url_matcher(\phpbb\extension\manager $manager, $root_path, $php_ext) @@ -88,7 +88,7 @@ function phpbb_create_url_matcher(\phpbb\extension\manager $manager, RequestCont * * @param RequestContext $context Symfony RequestContext object * @param string $root_path Root path -* @param string $php_ext PHP extension +* @param string $php_ext PHP file extension * @return phpbb_url_matcher */ function phpbb_load_url_matcher(RequestContext $context, $root_path, $php_ext) @@ -103,7 +103,7 @@ function phpbb_load_url_matcher(RequestContext $context, $root_path, $php_ext) * The class is automatically dumped to the cache directory * * @param string $root_path Root path -* @param string $php_ext PHP extension +* @param string $php_ext PHP file extension * @return bool True if it exists, false if not */ function phpbb_url_matcher_dumped($root_path, $php_ext) diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php index 04206a6fcd..b4ec0092e7 100644 --- a/phpBB/includes/mcp/mcp_front.php +++ b/phpBB/includes/mcp/mcp_front.php @@ -26,6 +26,7 @@ function mcp_front_view($id, $mode, $action) { global $phpEx, $phpbb_root_path, $config; global $template, $db, $user, $auth, $module; + global $phpbb_dispatcher; // Latest 5 unapproved if ($module->loaded('queue')) @@ -80,6 +81,19 @@ function mcp_front_view($id, $mode, $action) } } + /** + * Alter list of posts and total as required + * + * @event core.mcp_front_view_queue_postid_list_after + * @var int total Number of unapproved posts + * @var array post_list List of unapproved posts + * @var array forum_list List of forums that contain the posts + * @var array forum_names Associative array with forum_id as key and it's corresponding forum_name as value + * @since 3.1.0-RC3 + */ + $vars = array('total', 'post_list', 'forum_list', 'forum_names'); + extract($phpbb_dispatcher->trigger_event('core.mcp_front_view_queue_postid_list_after', compact($vars))); + if ($total) { $sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.post_attachment, p.poster_id, p.post_username, u.username, u.username_clean, u.user_colour, t.topic_id, t.topic_title, t.topic_first_post_id, p.forum_id @@ -178,6 +192,18 @@ function mcp_front_view($id, $mode, $action) 'ORDER_BY' => 'p.post_time DESC', ); + + /** + * Alter sql query to get latest reported posts + * + * @event core.mcp_front_reports_listing_query_before + * @var int sql_ary Associative array with the query to be executed + * @var array forum_list List of forums that contain the posts + * @since 3.1.0-RC3 + */ + $vars = array('sql_ary', 'forum_list'); + extract($phpbb_dispatcher->trigger_event('core.mcp_front_reports_listing_query_before', compact($vars))); + $sql = $db->sql_build_query('SELECT', $sql_ary); $result = $db->sql_query_limit($sql, 5); diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 9f6125f256..92000c6ceb 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -1114,6 +1114,7 @@ function mcp_fork_topic($topic_ids) $forum_id = request_var('f', 0); $redirect = request_var('redirect', build_url(array('action', 'quickmod'))); $additional_msg = $success_msg = ''; + $counter = array(); $s_hidden_fields = build_hidden_fields(array( 'topic_id_list' => $topic_ids, @@ -1306,9 +1307,20 @@ function mcp_fork_topic($topic_ids) 'post_edit_time' => (int) $row['post_edit_time'], 'post_edit_count' => (int) $row['post_edit_count'], 'post_edit_locked' => (int) $row['post_edit_locked'], - 'post_postcount' => 0, + 'post_postcount' => $row['post_postcount'], ); - + // Adjust post count only if the post can be incremented to the user counter + if ($row['post_postcount']) + { + if (isset($counter[$row['poster_id']])) + { + ++$counter[$row['poster_id']]; + } + else + { + $counter[$row['poster_id']] = 1; + } + } $db->sql_query('INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $new_post_id = $db->sql_nextid(); @@ -1428,6 +1440,18 @@ function mcp_fork_topic($topic_ids) WHERE forum_id = ' . $to_forum_id; $db->sql_query($sql); + if (!empty($counter)) + { + // Do only one query per user and not a query per post. + foreach ($counter as $user_id => $count) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_posts = user_posts + ' . (int) $count . ' + WHERE user_id = ' . (int) $user_id; + $db->sql_query($sql); + } + } + sync('topic', 'topic_id', $new_topic_id_list); sync('forum', 'forum_id', $to_forum_id); diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 37ce3c6fc3..54b31c642a 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -429,6 +429,29 @@ class mcp_queue OR t.topic_delete_user = 0) $limit_time_sql ORDER BY $sort_order_sql"; + + /** + * Alter sql query to get posts in queue to be accepted + * + * @event core.mcp_queue_get_posts_query_before + * @var string sql Associative array with the query to be executed + * @var array forum_list List of forums that contain the posts + * @var int visibility_const Integer with one of the possible ITEM_* constant values + * @var int topic_id If topic_id not equal to 0, the topic id to filter the posts to display + * @var string limit_time_sql String with the SQL code to limit the time interval of the post (Note: May be empty string) + * @var string sort_order_sql String with the ORDER BY SQL code used in this query + * @since 3.1.0-RC3 + */ + $vars = array( + 'sql', + 'forum_list', + 'visibility_const', + 'topic_id', + 'limit_time_sql', + 'sort_order_sql', + ); + extract($phpbb_dispatcher->trigger_event('core.mcp_queue_get_posts_query_before', compact($vars))); + $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start); $i = 0; @@ -478,6 +501,29 @@ class mcp_queue AND topic_delete_user <> 0 $limit_time_sql ORDER BY $sort_order_sql"; + + /** + * Alter sql query to get information on all topics in the list of forums provided. + * + * @event core.mcp_queue_get_posts_for_topics_query_before + * @var string sql String with the query to be executed + * @var array forum_list List of forums that contain the posts + * @var int visibility_const Integer with one of the possible ITEM_* constant values + * @var int topic_id topic_id in the page request + * @var string limit_time_sql String with the SQL code to limit the time interval of the post (Note: May be empty string) + * @var string sort_order_sql String with the ORDER BY SQL code used in this query + * @since 3.1.0-RC3 + */ + $vars = array( + 'sql', + 'forum_list', + 'visibility_const', + 'topic_id', + 'limit_time_sql', + 'sort_order_sql', + ); + extract($phpbb_dispatcher->trigger_event('core.mcp_queue_get_posts_for_topics_query_before', compact($vars))); + $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start); $rowset = array(); diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index da27d8900d..92ace7b585 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -1083,6 +1083,12 @@ class parse_message extends bbcode_firstpass protected $plupload; /** + * The mimetype guesser object used for attachment mimetypes + * @var \phpbb\mimetype\guesser + */ + protected $mimetype_guesser; + + /** * Init - give message here or manually */ function parse_message($message = '') @@ -1560,7 +1566,7 @@ class parse_message extends bbcode_firstpass { if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id)) { - $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message, false, $this->plupload); + $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message, false, $this->mimetype_guesser, $this->plupload); $error = array_merge($error, $filedata['error']); if (!sizeof($error)) @@ -1792,4 +1798,16 @@ class parse_message extends bbcode_firstpass { $this->plupload = $plupload; } + + /** + * Setter function for passing the mimetype_guesser object + * + * @param \phpbb\mimetype\guesser $mimetype_guesser The mimetype_guesser object + * + * @return null + */ + public function set_mimetype_guesser(\phpbb\mimetype\guesser $mimetype_guesser) + { + $this->mimetype_guesser = $mimetype_guesser; + } } diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index 94383b935f..d5a1dbae87 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -250,7 +250,6 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) 'U_PM_ACTION' => $url . '&mode=compose&f=' . $folder_id . '&p=' . $message_row['msg_id'], 'S_HAS_ATTACHMENTS' => (sizeof($attachments)) ? true : false, - 'S_HAS_MULTIPLE_ATTACHMENTS' => (sizeof($attachments) > 1), 'S_DISPLAY_NOTICE' => $display_notice && $message_row['message_attachment'], 'S_AUTHOR_DELETED' => ($author_id == ANONYMOUS) ? true : false, 'S_SPECIAL_FOLDER' => in_array($folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)), @@ -339,12 +338,6 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) // Display not already displayed Attachments for this post, we already parsed them. ;) if (isset($attachments) && sizeof($attachments)) { - $methods = phpbb_gen_download_links('msg_id', $msg_id, $phpbb_root_path, $phpEx); - foreach ($methods as $method) - { - $template->assign_block_vars('dl_method', $method); - } - foreach ($attachments as $attachment) { $template->assign_block_vars('attachment', array( diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index 35bb844170..a8c8920a7d 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -43,7 +43,7 @@ class ucp_prefs 'notifymethod' => request_var('notifymethod', $user->data['user_notify_type']), 'dateformat' => request_var('dateformat', $user->data['user_dateformat'], true), 'lang' => basename(request_var('lang', $user->data['user_lang'])), - 'style' => request_var('style', (int) $user->data['user_style']), + 'user_style' => request_var('user_style', (int) $user->data['user_style']), 'tz' => request_var('tz', $user->data['user_timezone']), 'viewemail' => request_var('viewemail', (bool) $user->data['user_allow_viewemail']), @@ -76,11 +76,11 @@ class ucp_prefs { if ($config['override_user_style']) { - $data['style'] = (int) $config['default_style']; + $data['user_style'] = (int) $config['default_style']; } - else if (!phpbb_style_is_active($data['style'])) + else if (!phpbb_style_is_active($data['user_style'])) { - $data['style'] = (int) $user->data['user_style']; + $data['user_style'] = (int) $user->data['user_style']; } $error = validate_data($data, array( @@ -107,7 +107,7 @@ class ucp_prefs 'user_dateformat' => $data['dateformat'], 'user_lang' => $data['lang'], 'user_timezone' => $data['tz'], - 'user_style' => $data['style'], + 'user_style' => $data['user_style'], ); /** @@ -115,7 +115,7 @@ class ucp_prefs * * @event core.ucp_prefs_personal_update_data * @var array data Submitted display options data - * @var array sql_ary Display options data we udpate + * @var array sql_ary Display options data we update * @since 3.1.0-a1 */ $vars = array('data', 'sql_ary'); @@ -207,7 +207,7 @@ class ucp_prefs 'S_MORE_STYLES' => $s_more_styles, 'S_LANG_OPTIONS' => language_select($data['lang']), - 'S_STYLE_OPTIONS' => ($config['override_user_style']) ? '' : style_select($data['style']), + 'S_STYLE_OPTIONS' => ($config['override_user_style']) ? '' : style_select($data['user_style']), 'S_TZ_OPTIONS' => $timezone_selects['tz_select'], 'S_TZ_DATE_OPTIONS' => $timezone_selects['tz_dates'], 'S_CAN_HIDE_ONLINE' => ($auth->acl_get('u_hideonline')) ? true : false, @@ -294,7 +294,7 @@ class ucp_prefs * * @event core.ucp_prefs_view_update_data * @var array data Submitted display options data - * @var array sql_ary Display options data we udpate + * @var array sql_ary Display options data we update * @since 3.1.0-a1 */ $vars = array('data', 'sql_ary'); @@ -420,7 +420,7 @@ class ucp_prefs * * @event core.ucp_prefs_post_update_data * @var array data Submitted display options data - * @var array sql_ary Display options data we udpate + * @var array sql_ary Display options data we update * @since 3.1.0-a1 */ $vars = array('data', 'sql_ary'); @@ -451,6 +451,24 @@ class ucp_prefs break; } + /** + * Modify UCP preferences data before the page load + * + * @event core.ucp_prefs_modify_common + * @var array data Array with current/submitted UCP options data + * @var array error Errors data + * @var string mode UCP prefs operation mode + * @var string s_hidden_fields Hidden fields data + * @since 3.1.0-RC3 + */ + $vars = array( + 'data', + 'error', + 'mode', + 's_hidden_fields', + ); + extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_modify_common', compact($vars))); + $template->assign_vars(array( 'L_TITLE' => $user->lang['UCP_PREFS_' . strtoupper($mode)], diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index c54c84cdbc..6a91033dbb 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -13,10 +13,6 @@ $update_start_time = time(); -use Symfony\Component\Config\FileLocator; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; - /** * @ignore */ @@ -177,25 +173,9 @@ define('IN_DB_UPDATE', true); // End startup code -// Make sure migrations have been installed. -$db_tools = $phpbb_container->get('dbal.tools'); -if (!$db_tools->sql_table_exists($table_prefix . 'migrations')) -{ - $db_tools->sql_create_table($table_prefix . 'migrations', array( - 'COLUMNS' => array( - 'migration_name' => array('VCHAR', ''), - 'migration_depends_on' => array('TEXT', ''), - 'migration_schema_done' => array('BOOL', 0), - 'migration_data_done' => array('BOOL', 0), - 'migration_data_state' => array('TEXT', ''), - 'migration_start_time' => array('TIMESTAMP', 0), - 'migration_end_time' => array('TIMESTAMP', 0), - ), - 'PRIMARY_KEY' => 'migration_name', - )); -} - $migrator = $phpbb_container->get('migrator'); +$migrator->create_migrations_table(); + $phpbb_extension_manager = $phpbb_container->get('ext.manager'); $finder = $phpbb_extension_manager->get_finder(); diff --git a/phpBB/install/index.php b/phpBB/install/index.php index d443c537fa..395aff6c7d 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -11,10 +11,6 @@ * */ -use Symfony\Component\Config\FileLocator; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; - /**#@+ * @ignore */ diff --git a/phpBB/install/install_update.php b/phpBB/install/install_update.php index 28777a8d24..82ca0fc18d 100644 --- a/phpBB/install/install_update.php +++ b/phpBB/install/install_update.php @@ -1063,6 +1063,14 @@ class install_update extends module $transfer->write_file($file_struct['filename'], $contents); } break; + + case 'deleted': + + if ($update_mode != 'download') + { + $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); + } + break; } } } diff --git a/phpBB/install/schemas/schema.json b/phpBB/install/schemas/schema.json index a3ffd923a1..4e014c77ed 100644 --- a/phpBB/install/schemas/schema.json +++ b/phpBB/install/schemas/schema.json @@ -2397,14 +2397,6 @@ ] }, "KEYS": { - "unq_mtch": [ - "UNIQUE", - [ - "word_id", - "post_id", - "title_match" - ] - ], "word_id": [ "INDEX", "word_id" @@ -2412,6 +2404,14 @@ "post_id": [ "INDEX", "post_id" + ], + "un_mtch": [ + "UNIQUE", + [ + "word_id", + "post_id", + "title_match" + ] ] } }, @@ -2711,8 +2711,9 @@ 0 ], "topic_first_poster_name": [ - "VCHAR_UNI", - "" + "VCHAR_UNI:255", + "", + "true_sort" ], "topic_first_poster_colour": [ "VCHAR:6", diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index 61c718195e..91fc1215fc 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -225,12 +225,6 @@ $lang = array_merge($lang, array( 'BACK' => 'Back', - 'CLI_DESCRIPTION_CRON_LIST' => 'Prints a list of ready and unready cron jobs.', - 'CLI_DESCRIPTION_CRON_RUN' => 'Runs all ready cron tasks.', - 'CLI_DESCRIPTION_CRON_RUN_ARGUMENT_1' => 'Name of the task to be run', - - 'CLI_DESCRIPTION_OPTION_SHELL' => 'Launch the shell.', - 'COLOUR_SWATCH' => 'Web-safe colour swatch', 'CONFIG_UPDATED' => 'Configuration updated successfully.', 'CRON_LOCK_ERROR' => 'Could not obtain cron lock.', diff --git a/phpBB/language/en/acp/extensions.php b/phpBB/language/en/acp/extensions.php index 6ec722bb78..28cdc8829d 100644 --- a/phpBB/language/en/acp/extensions.php +++ b/phpBB/language/en/acp/extensions.php @@ -42,6 +42,7 @@ $lang = array_merge($lang, array( 'EXTENSION_INVALID_LIST' => 'The “%s” extension is not valid.<br />%s<br /><br />', 'EXTENSION_NOT_AVAILABLE' => 'The selected extension is not available for this board, please verify your phpBB and PHP versions are allowed (see the details page).', 'EXTENSION_DIR_INVALID' => 'The selected extension has an invalid directory structure and cannot be enabled.', + 'EXTENSION_NOT_ENABLEABLE' => 'The selected extension cannot be enabled, please verify the extension’s requirements.', 'DETAILS' => 'Details', diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php new file mode 100644 index 0000000000..eb0f5bb357 --- /dev/null +++ b/phpBB/language/en/cli.php @@ -0,0 +1,78 @@ +<?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. +* +*/ + +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* DO NOT CHANGE +*/ +if (empty($lang) || !is_array($lang)) +{ + $lang = array(); +} + +// DEVELOPERS PLEASE NOTE +// +// Placeholders can now contain order information, e.g. instead of +// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows +// translators to re-order the output of data while ensuring it remains correct +// +// You do not need this where single placeholders are used, e.g. 'Message %d' is fine +// equally where a string contains only two placeholders which are used to wrap text +// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine + +$lang = array_merge($lang, array( + 'CLI_CONFIG_CANNOT_CACHED' => 'Set this option if the configuration option changes too frequently to be efficiently cached.', + 'CLI_CONFIG_CURRENT' => 'Current configuration value, use 0 and 1 to specify boolean values', + 'CLI_CONFIG_DELETE_SUCCESS' => 'Successfully deleted config %s.', + 'CLI_CONFIG_NEW' => 'New configuration value, use 0 and 1 to specify boolean values', + 'CLI_CONFIG_NOT_EXISTS' => 'Config %s does not exist', + 'CLI_CONFIG_OPTION_NAME' => 'The configuration option’s name', + 'CLI_CONFIG_PRINT_WITHOUT_NEWLINE' => 'Set this option if the value should be printed without a new line at the end.', + 'CLI_CONFIG_INCREMENT_BY' => 'Amount to increment by', + 'CLI_CONFIG_INCREMENT_SUCCESS' => 'Successfully incremented config %s', + 'CLI_CONFIG_SET_FAILURE' => 'Could not set config %s', + 'CLI_CONFIG_SET_SUCCESS' => 'Successfully set config %s', + + 'CLI_DESCRIPTION_CRON_LIST' => 'Prints a list of ready and unready cron jobs.', + 'CLI_DESCRIPTION_CRON_RUN' => 'Runs all ready cron tasks.', + 'CLI_DESCRIPTION_CRON_RUN_ARGUMENT_1' => 'Name of the task to be run', + 'CLI_DESCRIPTION_DB_MIGRATE' => 'Updates the database by applying migrations.', + 'CLI_DESCRIPTION_DELETE_CONFIG' => 'Deletes a configuration option', + 'CLI_DESCRIPTION_DISABLE_EXTENSION' => 'Disables the specified extension.', + 'CLI_DESCRIPTION_ENABLE_EXTENSION' => 'Enables the specified extension.', + 'CLI_DESCRIPTION_FIND_MIGRATIONS' => 'Finds migrations that are not depended on.', + 'CLI_DESCRIPTION_GET_CONFIG' => 'Gets a configuration option’s value', + 'CLI_DESCRIPTION_INCREMENT_CONFIG' => 'Increments a configuration option’s value', + 'CLI_DESCRIPTION_LIST_EXTENSIONS' => 'Lists all extensions in the database and on the filesystem.', + 'CLI_DESCRIPTION_OPTION_SAFE_MODE' => 'Run in Safe Mode (without extensions).', + 'CLI_DESCRIPTION_OPTION_SHELL' => 'Launch the shell.', + 'CLI_DESCRIPTION_PURGE_EXTENSION' => 'Purges the specified extension.', + 'CLI_DESCRIPTION_RECALCULATE_EMAIL_HASH' => 'Recalculates the user_email_hash column of the users table.', + 'CLI_DESCRIPTION_SET_ATOMIC_CONFIG' => 'Sets a configuration option’s value only if the old matches the current value', + 'CLI_DESCRIPTION_SET_CONFIG' => 'Sets a configuration option’s value', + + 'CLI_EXTENSION_DISABLE_FAILURE' => 'Could not disable extension %s', + 'CLI_EXTENSION_DISABLE_SUCCESS' => 'Successfully disabled extension %s', + 'CLI_EXTENSION_ENABLE_FAILURE' => 'Could not enable extension %s', + 'CLI_EXTENSION_ENABLE_SUCCESS' => 'Successfully enabled extension %s', + 'CLI_EXTENSION_NAME' => 'Name of the extension', + 'CLI_EXTENSION_PURGE_FAILURE' => 'Could not purge extension %s', + 'CLI_EXTENSION_PURGE_SUCCESS' => 'Successfully purged extension %s', + 'CLI_EXTENSION_NOT_FOUND' => 'No extensions were found.', + + 'CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS' => 'Successfully recalculated all email hashes.', +)); diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 5af3ad4fbc..4ce69e0b85 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -191,8 +191,6 @@ $lang = array_merge($lang, array( 'DISPLAY_MESSAGES' => 'Display messages from previous', 'DISPLAY_POSTS' => 'Display posts from previous', 'DISPLAY_TOPICS' => 'Display topics from previous', - 'DOWNLOAD_ALL' => 'Download all', - 'DOWNLOAD_ALL_ATTACHMENTS' => 'Download all attachments', 'DOWNLOADED' => 'Downloaded', 'DOWNLOADING_FILE' => 'Downloading file', 'DOWNLOAD_COUNTS' => array( @@ -821,6 +819,7 @@ $lang = array_merge($lang, array( 1 => 'Viewed %d time', 2 => 'Viewed %d times', ), + 'VIEWING_CONTACT_ADMIN' => 'Viewing contact page', 'VIEWING_FAQ' => 'Viewing FAQ', 'VIEWING_MEMBERS' => 'Viewing member details', 'VIEWING_ONLINE' => 'Viewing who is online', diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php index 31d49e8bdf..2cd6ec59cc 100644 --- a/phpBB/language/en/posting.php +++ b/phpBB/language/en/posting.php @@ -60,7 +60,7 @@ $lang = array_merge($lang, array( 'BBCODE_O_HELP' => 'Ordered list: e.g. [list=1][*]First point[/list] or [list=a][*]Point a[/list]', 'BBCODE_P_HELP' => 'Insert image: [img]http://image_url[/img]', 'BBCODE_Q_HELP' => 'Quote text: [quote]text[/quote]', - 'BBCODE_S_HELP' => 'Font colour: [color=red]text[/color] Tip: you can also use color=#FF0000', + 'BBCODE_S_HELP' => 'Font colour: [color=red]text[/color] or [color=#FF0000]text[/color]', 'BBCODE_U_HELP' => 'Underline text: [u]text[/u]', 'BBCODE_W_HELP' => 'Insert URL: [url]http://url[/url] or [url=http://url]URL text[/url]', 'BBCODE_Y_HELP' => 'List: Add list element', diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index d464a9219e..d692828bd7 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -40,7 +40,7 @@ if (empty($lang) || !is_array($lang)) $lang = array_merge($lang, array( 'TERMS_OF_USE_CONTENT' => 'By accessing “%1$s” (hereinafter “we”, “us”, “our”, “%1$s”, “%2$s”), you agree to be legally bound by the following terms. If you do not agree to be legally bound by all of the following terms then please do not access and/or use “%1$s”. We may change these at any time and we’ll do our utmost in informing you, though it would be prudent to review this regularly yourself as your continued usage of “%1$s” after changes mean you agree to be legally bound by these terms as they are updated and/or amended.<br /> <br /> - Our forums are powered by phpBB (hereinafter “they”, “them”, “their”, “phpBB software”, “www.phpbb.com”, “phpBB Limited”, “phpBB Teams”) which is a bulletin board solution released under the “<a href="http://opensource.org/licenses/gpl-2.0.php">GNU General Public License v2</a>” (hereinafter “GPL”) and can be downloaded from <a href="https://www.phpbb.com/">www.phpbb.com</a>. The phpBB software only facilitates internet based discussions, the phpBB Limited are not responsible for what we allow and/or disallow as permissible content and/or conduct. For further information about phpBB, please see: <a href="https://www.phpbb.com/">https://www.phpbb.com/</a>.<br /> + Our forums are powered by phpBB (hereinafter “they”, “them”, “their”, “phpBB software”, “www.phpbb.com”, “phpBB Limited”, “phpBB Teams”) which is a bulletin board solution released under the “<a href="http://opensource.org/licenses/gpl-2.0.php">GNU General Public License v2</a>” (hereinafter “GPL”) and can be downloaded from <a href="https://www.phpbb.com/">www.phpbb.com</a>. The phpBB software only facilitates internet based discussions; phpBB Limited is not responsible for what we allow and/or disallow as permissible content and/or conduct. For further information about phpBB, please see: <a href="https://www.phpbb.com/">https://www.phpbb.com/</a>.<br /> <br /> You agree not to post any abusive, obscene, vulgar, slanderous, hateful, threatening, sexually-orientated or any other material that may violate any laws be it of your country, the country where “%1$s” is hosted or International Law. Doing so may lead to you being immediately and permanently banned, with notification of your Internet Service Provider if deemed required by us. The IP address of all posts are recorded to aid in enforcing these conditions. You agree that “%1$s” have the right to remove, edit, move or close any topic at any time should we see fit. As a user you agree to any information you have entered to being stored in a database. While this information will not be disclosed to any third party without your consent, neither “%1$s” nor phpBB shall be held responsible for any hacking attempt that may lead to the data being compromised. ', diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php index 65249275d4..38755ccf99 100644 --- a/phpBB/phpbb/auth/auth.php +++ b/phpBB/phpbb/auth/auth.php @@ -208,9 +208,12 @@ class auth /** * Get forums with the specified permission setting - * if the option is prefixed with !, then the result becomes negated * - * @param bool $clean set to true if only values needs to be returned which are set/unset + * @param string $opt The permission name to lookup. If prefixed with !, the result is negated. + * @param bool $clean set to true if only values needs to be returned which are set/unset + * + * @return array Contains the forum ids with the specified permission set to true. + This is a nested array: array => forum_id => permission => true */ function acl_getf($opt, $clean = false) { diff --git a/phpBB/phpbb/auth/provider/apache.php b/phpBB/phpbb/auth/provider/apache.php index 4f44efe9af..9137a77210 100644 --- a/phpBB/phpbb/auth/provider/apache.php +++ b/phpBB/phpbb/auth/provider/apache.php @@ -28,13 +28,13 @@ class apache extends \phpbb\auth\provider\base /** * Apache Authentication Constructor * - * @param \phpbb\db\driver\driver_interface $db - * @param \phpbb\config\config $config - * @param \phpbb\passwords\manager $passwords_manager - * @param \phpbb\request\request $request - * @param \phpbb\user $user - * @param string $phpbb_root_path - * @param string $php_ext + * @param \phpbb\db\driver\driver_interface $db Database object + * @param \phpbb\config\config $config Config object + * @param \phpbb\passwords\manager $passwords_manager Passwords Manager object + * @param \phpbb\request\request $request Request object + * @param \phpbb\user $user User object + * @param string $phpbb_root_path Relative path to phpBB root + * @param string $php_ext PHP file extension */ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext) { diff --git a/phpBB/phpbb/auth/provider/ldap.php b/phpBB/phpbb/auth/provider/ldap.php index e7764b754b..d32e7504eb 100644 --- a/phpBB/phpbb/auth/provider/ldap.php +++ b/phpBB/phpbb/auth/provider/ldap.php @@ -29,10 +29,10 @@ class ldap extends \phpbb\auth\provider\base /** * LDAP Authentication Constructor * - * @param \phpbb\db\driver\driver_interface $db - * @param \phpbb\config\config $config - * @param \phpbb\passwords\manager $passwords_manager - * @param \phpbb\user $user + * @param \phpbb\db\driver\driver_interface $db Database object + * @param \phpbb\config\config $config Config object + * @param \phpbb\passwords\manager $passwords_manager Passwords manager object + * @param \phpbb\user $user User object */ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\user $user) { diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index c43004f340..f5ba50451a 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -19,6 +19,31 @@ namespace phpbb\avatar\driver; class upload extends \phpbb\avatar\driver\driver { /** + * @var \phpbb\mimetype\guesser + */ + protected $mimetype_guesser; + + /** + * Construct a driver object + * + * @param \phpbb\config\config $config phpBB configuration + * @param string $phpbb_root_path Path to the phpBB root + * @param string $php_ext PHP file extension + * @param \phpbb_path_helper $path_helper phpBB path helper + * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser + * @param \phpbb\cache\driver\driver_interface $cache Cache driver + */ + public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\cache\driver\driver_interface $cache = null) + { + $this->config = $config; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->path_helper = $path_helper; + $this->mimetype_guesser = $mimetype_guesser; + $this->cache = $cache; + } + + /** * {@inheritdoc} */ public function get_data($row, $ignore_config = false) @@ -70,7 +95,7 @@ class upload extends \phpbb\avatar\driver\driver if (!empty($upload_file['name'])) { - $file = $upload->form_upload('avatar_upload_file'); + $file = $upload->form_upload('avatar_upload_file', $this->mimetype_guesser); } else if (!empty($this->config['allow_avatar_remote_upload']) && !empty($url)) { @@ -100,7 +125,7 @@ class upload extends \phpbb\avatar\driver\driver return false; } - $file = $upload->remote_upload($url); + $file = $upload->remote_upload($url, $this->mimetype_guesser); } else { diff --git a/phpBB/phpbb/cache/driver/base.php b/phpBB/phpbb/cache/driver/base.php index 685cdc4e57..4c20ad916d 100644 --- a/phpBB/phpbb/cache/driver/base.php +++ b/phpBB/phpbb/cache/driver/base.php @@ -15,4 +15,217 @@ namespace phpbb\cache\driver; abstract class base implements \phpbb\cache\driver\driver_interface { + var $vars = array(); + var $is_modified = false; + + var $sql_rowset = array(); + var $sql_row_pointer = array(); + var $cache_dir = ''; + + /** + * {@inheritDoc} + */ + function purge() + { + // Purge all phpbb cache files + try + { + $iterator = new \DirectoryIterator($this->cache_dir); + } + catch (\Exception $e) + { + return; + } + + foreach ($iterator as $fileInfo) + { + if ($fileInfo->isDot()) + { + continue; + } + $filename = $fileInfo->getFilename(); + if ($fileInfo->isDir()) + { + $this->remove_dir($fileInfo->getPathname()); + } + else if (strpos($filename, 'container_') === 0 || + strpos($filename, 'url_matcher') === 0 || + strpos($filename, 'sql_') === 0 || + strpos($filename, 'data_') === 0) + { + $this->remove_file($fileInfo->getPathname()); + } + } + + unset($this->vars); + unset($this->sql_rowset); + unset($this->sql_row_pointer); + + $this->vars = array(); + $this->sql_rowset = array(); + $this->sql_row_pointer = array(); + + $this->is_modified = false; + } + + /** + * {@inheritDoc} + */ + function unload() + { + $this->save(); + unset($this->vars); + unset($this->sql_rowset); + unset($this->sql_row_pointer); + + $this->vars = array(); + $this->sql_rowset = array(); + $this->sql_row_pointer = array(); + } + + /** + * {@inheritDoc} + */ + function sql_load($query) + { + // Remove extra spaces and tabs + $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); + + if (($rowset = $this->_read('sql_' . md5($query))) === false) + { + return false; + } + + $query_id = sizeof($this->sql_rowset); + $this->sql_rowset[$query_id] = $rowset; + $this->sql_row_pointer[$query_id] = 0; + + return $query_id; + } + + /** + * {@inheritDoc} + */ + function sql_exists($query_id) + { + return isset($this->sql_rowset[$query_id]); + } + + /** + * {@inheritDoc} + */ + function sql_fetchrow($query_id) + { + if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) + { + return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++]; + } + + return false; + } + + /** + * {@inheritDoc} + */ + function sql_fetchfield($query_id, $field) + { + if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) + { + return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false; + } + + return false; + } + + /** + * {@inheritDoc} + */ + function sql_rowseek($rownum, $query_id) + { + if ($rownum >= sizeof($this->sql_rowset[$query_id])) + { + return false; + } + + $this->sql_row_pointer[$query_id] = $rownum; + return true; + } + + /** + * {@inheritDoc} + */ + function sql_freeresult($query_id) + { + if (!isset($this->sql_rowset[$query_id])) + { + return false; + } + + unset($this->sql_rowset[$query_id]); + unset($this->sql_row_pointer[$query_id]); + + return true; + } + + /** + * Removes/unlinks file + * + * @param string $filename Filename to remove + * @param bool $check Check file permissions + * @return bool True if the file was successfully removed, otherwise false + */ + function remove_file($filename, $check = false) + { + if (!function_exists('phpbb_is_writable')) + { + global $phpbb_root_path, $phpEx; + include($phpbb_root_path . 'includes/functions.' . $phpEx); + } + + if ($check && !phpbb_is_writable($this->cache_dir)) + { + // E_USER_ERROR - not using language entry - intended. + trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR); + } + + return @unlink($filename); + } + + /** + * Remove directory + * + * @param string $dir Directory to remove + * + * @return null + */ + protected function remove_dir($dir) + { + try + { + $iterator = new \DirectoryIterator($dir); + } + catch (\Exception $e) + { + return; + } + + foreach ($iterator as $fileInfo) + { + if ($fileInfo->isDot()) + { + continue; + } + + if ($fileInfo->isDir()) + { + $this->remove_dir($fileInfo->getPathname()); + } + else + { + $this->remove_file($fileInfo->getPathname()); + } + } + + @rmdir($dir); + } } diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index b32af32d25..fd5bce4515 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -18,13 +18,7 @@ namespace phpbb\cache\driver; */ class file extends \phpbb\cache\driver\base { - var $vars = array(); var $var_expires = array(); - var $is_modified = false; - - var $sql_rowset = array(); - var $sql_row_pointer = array(); - var $cache_dir = ''; /** * Set cache path @@ -50,16 +44,9 @@ class file extends \phpbb\cache\driver\base */ function unload() { - $this->save(); - unset($this->vars); + parent::unload(); unset($this->var_expires); - unset($this->sql_rowset); - unset($this->sql_row_pointer); - - $this->vars = array(); $this->var_expires = array(); - $this->sql_rowset = array(); - $this->sql_row_pointer = array(); } /** @@ -166,8 +153,6 @@ class file extends \phpbb\cache\driver\base { if ($var_name[0] == '_') { - global $phpEx; - if (!$this->_exists($var_name)) { return false; @@ -203,85 +188,8 @@ class file extends \phpbb\cache\driver\base */ function purge() { - // Purge all phpbb cache files - try - { - $iterator = new \DirectoryIterator($this->cache_dir); - } - catch (Exception $e) - { - return; - } - - foreach ($iterator as $fileInfo) - { - if ($fileInfo->isDot()) - { - continue; - } - $filename = $fileInfo->getFilename(); - if ($fileInfo->isDir()) - { - $this->remove_dir($fileInfo->getPathname()); - } - else if (strpos($filename, 'container_') === 0 || - strpos($filename, 'url_matcher') === 0 || - strpos($filename, 'sql_') === 0 || - strpos($filename, 'data_') === 0) - { - $this->remove_file($fileInfo->getPathname()); - } - } - - unset($this->vars); - unset($this->var_expires); - unset($this->sql_rowset); - unset($this->sql_row_pointer); - - $this->vars = array(); + parent::purge(); $this->var_expires = array(); - $this->sql_rowset = array(); - $this->sql_row_pointer = array(); - - $this->is_modified = false; - } - - /** - * Remove directory - * - * @param string $dir Directory to remove - * - * @return null - */ - protected function remove_dir($dir) - { - try - { - $iterator = new \DirectoryIterator($dir); - } - catch (Exception $e) - { - return; - } - - foreach ($iterator as $fileInfo) - { - if ($fileInfo->isDot()) - { - continue; - } - - if ($fileInfo->isDir()) - { - $this->remove_dir($fileInfo->getPathname()); - } - else - { - $this->remove_file($fileInfo->getPathname()); - } - } - - @rmdir($dir); } /** @@ -392,26 +300,6 @@ class file extends \phpbb\cache\driver\base /** * {@inheritDoc} */ - function sql_load($query) - { - // Remove extra spaces and tabs - $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); - - if (($rowset = $this->_read('sql_' . md5($query))) === false) - { - return false; - } - - $query_id = sizeof($this->sql_rowset); - $this->sql_rowset[$query_id] = $rowset; - $this->sql_row_pointer[$query_id] = 0; - - return $query_id; - } - - /** - * {@inheritDoc} - */ function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) { // Remove extra spaces and tabs @@ -436,70 +324,6 @@ class file extends \phpbb\cache\driver\base } /** - * {@inheritDoc} - */ - function sql_exists($query_id) - { - return isset($this->sql_rowset[$query_id]); - } - - /** - * {@inheritDoc} - */ - function sql_fetchrow($query_id) - { - if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) - { - return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++]; - } - - return false; - } - - /** - * {@inheritDoc} - */ - function sql_fetchfield($query_id, $field) - { - if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) - { - return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false; - } - - return false; - } - - /** - * {@inheritDoc} - */ - function sql_rowseek($rownum, $query_id) - { - if ($rownum >= sizeof($this->sql_rowset[$query_id])) - { - return false; - } - - $this->sql_row_pointer[$query_id] = $rownum; - return true; - } - - /** - * {@inheritDoc} - */ - function sql_freeresult($query_id) - { - if (!isset($this->sql_rowset[$query_id])) - { - return false; - } - - unset($this->sql_rowset[$query_id]); - unset($this->sql_row_pointer[$query_id]); - - return true; - } - - /** * Read cached data from a specified file * * @access private @@ -760,28 +584,4 @@ class file extends \phpbb\cache\driver\base return $return_value; } - - /** - * Removes/unlinks file - * - * @param string $filename Filename to remove - * @param bool $check Check file permissions - * @return bool True if the file was successfully removed, otherwise false - */ - function remove_file($filename, $check = false) - { - if (!function_exists('phpbb_is_writable')) - { - global $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/functions.' . $phpEx); - } - - if ($check && !phpbb_is_writable($this->cache_dir)) - { - // E_USER_ERROR - not using language entry - intended. - trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR); - } - - return @unlink($filename); - } } diff --git a/phpBB/phpbb/cache/driver/memory.php b/phpBB/phpbb/cache/driver/memory.php index 5dee375192..56308be8da 100644 --- a/phpBB/phpbb/cache/driver/memory.php +++ b/phpBB/phpbb/cache/driver/memory.php @@ -20,13 +20,6 @@ abstract class memory extends \phpbb\cache\driver\base { var $key_prefix; - var $vars = array(); - var $is_modified = false; - - var $sql_rowset = array(); - var $sql_row_pointer = array(); - var $cache_dir = ''; - /** * Set cache path */ @@ -71,21 +64,6 @@ abstract class memory extends \phpbb\cache\driver\base /** * {@inheritDoc} */ - function unload() - { - $this->save(); - unset($this->vars); - unset($this->sql_rowset); - unset($this->sql_row_pointer); - - $this->vars = array(); - $this->sql_rowset = array(); - $this->sql_row_pointer = array(); - } - - /** - * {@inheritDoc} - */ function save() { if (!$this->is_modified) @@ -147,47 +125,6 @@ abstract class memory extends \phpbb\cache\driver\base /** * {@inheritDoc} */ - function purge() - { - // Purge all phpbb cache files - $dir = @opendir($this->cache_dir); - - if (!$dir) - { - return; - } - - while (($entry = readdir($dir)) !== false) - { - if (strpos($entry, 'container_') !== 0 && - strpos($entry, 'url_matcher') !== 0 && - strpos($entry, 'sql_') !== 0 && - strpos($entry, 'data_') !== 0 && - strpos($entry, 'ctpl_') !== 0 && - strpos($entry, 'tpl_') !== 0) - { - continue; - } - - $this->remove_file($this->cache_dir . $entry); - } - closedir($dir); - - unset($this->vars); - unset($this->sql_rowset); - unset($this->sql_row_pointer); - - $this->vars = array(); - $this->sql_rowset = array(); - $this->sql_row_pointer = array(); - - $this->is_modified = false; - } - - - /** - * {@inheritDoc} - */ function destroy($var_name, $table = '') { if ($var_name == 'sql' && !empty($table)) @@ -262,26 +199,6 @@ abstract class memory extends \phpbb\cache\driver\base /** * {@inheritDoc} */ - function sql_load($query) - { - // Remove extra spaces and tabs - $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); - $query_id = sizeof($this->sql_rowset); - - if (($result = $this->_read('sql_' . md5($query))) === false) - { - return false; - } - - $this->sql_rowset[$query_id] = $result; - $this->sql_row_pointer[$query_id] = 0; - - return $query_id; - } - - /** - * {@inheritDoc} - */ function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) { // Remove extra spaces and tabs @@ -338,94 +255,6 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * {@inheritDoc} - */ - function sql_exists($query_id) - { - return isset($this->sql_rowset[$query_id]); - } - - /** - * {@inheritDoc} - */ - function sql_fetchrow($query_id) - { - if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) - { - return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++]; - } - - return false; - } - - /** - * {@inheritDoc} - */ - function sql_fetchfield($query_id, $field) - { - if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) - { - return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false; - } - - return false; - } - - /** - * {@inheritDoc} - */ - function sql_rowseek($rownum, $query_id) - { - if ($rownum >= sizeof($this->sql_rowset[$query_id])) - { - return false; - } - - $this->sql_row_pointer[$query_id] = $rownum; - return true; - } - - /** - * {@inheritDoc} - */ - function sql_freeresult($query_id) - { - if (!isset($this->sql_rowset[$query_id])) - { - return false; - } - - unset($this->sql_rowset[$query_id]); - unset($this->sql_row_pointer[$query_id]); - - return true; - } - - /** - * Removes/unlinks file - * - * @param string $filename Filename to remove - * @param bool $check Check file permissions - * @return bool True if the file was successfully removed, otherwise false - */ - function remove_file($filename, $check = false) - { - if (!function_exists('phpbb_is_writable')) - { - global $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/functions.' . $phpEx); - } - - if ($check && !phpbb_is_writable($this->cache_dir)) - { - // E_USER_ERROR - not using language entry - intended. - trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR); - } - - return @unlink($filename); - } - - /** * Check if a cache var exists * * @access protected diff --git a/phpBB/phpbb/cache/service.php b/phpBB/phpbb/cache/service.php index d6bf150384..56727c2ad5 100644 --- a/phpBB/phpbb/cache/service.php +++ b/phpBB/phpbb/cache/service.php @@ -47,7 +47,7 @@ class service protected $phpbb_root_path; /** - * PHP extension. + * PHP file extension. * * @var string */ @@ -60,7 +60,7 @@ class service * @param \phpbb\config\config $config The config * @param \phpbb\db\driver\driver_interface $db Database connection * @param string $phpbb_root_path Root path - * @param string $php_ext PHP extension + * @param string $php_ext PHP file extension */ public function __construct(\phpbb\cache\driver\driver_interface $driver, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, $phpbb_root_path, $php_ext) { @@ -168,18 +168,12 @@ class service { if ($row['rank_special']) { - $ranks['special'][$row['rank_id']] = array( - 'rank_title' => $row['rank_title'], - 'rank_image' => $row['rank_image'] - ); + unset($row['rank_min']); + $ranks['special'][$row['rank_id']] = $row; } else { - $ranks['normal'][] = array( - 'rank_title' => $row['rank_title'], - 'rank_min' => $row['rank_min'], - 'rank_image' => $row['rank_image'] - ); + $ranks['normal'][$row['rank_id']] = $row; } } $this->db->sql_freeresult($result); diff --git a/phpBB/phpbb/composer.json b/phpBB/phpbb/composer.json new file mode 100644 index 0000000000..513d7e4559 --- /dev/null +++ b/phpBB/phpbb/composer.json @@ -0,0 +1,27 @@ +{ + "name": "phpbb/phpbb-core", + "description": "Collection of core phpBB libraries", + "type": "library", + "keywords": ["phpbb", "forum"], + "homepage": "https://www.phpbb.com", + "license": "GPL-2.0", + "authors": [ + { + "name": "phpBB Limited", + "email": "operations@phpbb.com", + "homepage": "https://www.phpbb.com/go/authors" + } + ], + "support": { + "issues": "https://tracker.phpbb.com", + "forum": "https://www.phpbb.com/community/", + "wiki": "https://wiki.phpbb.com", + "irc": "irc://irc.freenode.org/phpbb" + }, + "autoload": { + "classmap": [""] + }, + "require": { + "php": ">=5.3.3" + } +} diff --git a/phpBB/phpbb/config_php_file.php b/phpBB/phpbb/config_php_file.php index 1a562e470d..7445e7df22 100644 --- a/phpBB/phpbb/config_php_file.php +++ b/phpBB/phpbb/config_php_file.php @@ -71,59 +71,44 @@ class config_php_file /** * Returns an associative array containing the variables defined by the config file. * - * @return bool|array Return the content of the config file or false if the file does not exists. + * @return array Return the content of the config file or an empty array if the file does not exists. */ public function get_all() { - if (!$this->load_config_file()) - { - return false; - } + $this->load_config_file(); return $this->config_data; } /** - * Return the value of a variable defined into the config.php file and false if the variable does not exist. + * Return the value of a variable defined into the config.php file or null if the variable does not exist. * * @param string $variable The name of the variable - * @return mixed + * @return mixed Value of the variable or null if the variable is not defined. */ public function get($variable) { - if (!$this->load_config_file()) - { - return false; - } + $this->load_config_file(); - return isset($this->config_data[$variable]) ? $this->config_data[$variable] : false; + return isset($this->config_data[$variable]) ? $this->config_data[$variable] : null; } /** * Load the config file and store the information. * - * @return bool True if the file was correctly loaded, false otherwise. + * @return null */ protected function load_config_file() { - if (!$this->config_loaded) + if (!$this->config_loaded && file_exists($this->config_file)) { - if (file_exists($this->config_file)) - { - $this->defined_vars = get_defined_vars(); + $this->defined_vars = get_defined_vars(); - require($this->config_file); - $this->config_data = array_diff_key(get_defined_vars(), $this->defined_vars); + require($this->config_file); + $this->config_data = array_diff_key(get_defined_vars(), $this->defined_vars); - $this->config_loaded = true; - } - else - { - return false; - } + $this->config_loaded = true; } - - return true; } /** diff --git a/phpBB/phpbb/console/application.php b/phpBB/phpbb/console/application.php index b1f0635913..bc4897af18 100644 --- a/phpBB/phpbb/console/application.php +++ b/phpBB/phpbb/console/application.php @@ -17,7 +17,6 @@ use Symfony\Component\Console\Shell; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\DependencyInjection\TaggedContainerInterface; class application extends \Symfony\Component\Console\Application { @@ -38,9 +37,26 @@ class application extends \Symfony\Component\Console\Application */ public function __construct($name, $version, \phpbb\user $user) { + $this->user = $user; + parent::__construct($name, $version); + } - $this->user = $user; + /** + * {@inheritdoc} + */ + protected function getDefaultInputDefinition() + { + $input_definition = parent::getDefaultInputDefinition(); + + $input_definition->addOption(new InputOption( + 'safe-mode', + null, + InputOption::VALUE_NONE, + $this->user->lang('CLI_DESCRIPTION_OPTION_SAFE_MODE') + )); + + return $input_definition; } /** @@ -73,14 +89,13 @@ class application extends \Symfony\Component\Console\Application /** * Register a set of commands from the container * - * @param TaggedContainerInterface $container The container - * @param string $tag The tag used to register the commands + * @param \phpbb\di\service_collection $command_collection The console service collection */ - public function register_container_commands(TaggedContainerInterface $container, $tag = 'console.command') + public function register_container_commands(\phpbb\di\service_collection $command_collection) { - foreach($container->findTaggedServiceIds($tag) as $id => $void) + foreach ($command_collection as $service_command) { - $this->add($container->get($id)); + $this->add($service_command); } } diff --git a/phpBB/phpbb/console/command/cache/purge.php b/phpBB/phpbb/console/command/cache/purge.php index 379d2aa1ca..ec8229200c 100644 --- a/phpBB/phpbb/console/command/cache/purge.php +++ b/phpBB/phpbb/console/command/cache/purge.php @@ -29,31 +29,27 @@ class purge extends \phpbb\console\command\command /** @var \phpbb\log\log */ protected $log; - /** @var \phpbb\user */ - protected $user; - /** @var \phpbb\config\config */ protected $config; /** * Constructor * + * @param \phpbb\user $user User instance * @param \phpbb\cache\driver\driver_interface $cache Cache instance * @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\auth\auth $auth Auth instance * @param \phpbb\log\log $log Logger instance - * @param \phpbb\user $user User instance * @param \phpbb\config\config $config Config instance */ - public function __construct(\phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\auth\auth $auth, \phpbb\log\log $log, \phpbb\user $user, \phpbb\config\config $config) + public function __construct(\phpbb\user $user, \phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\auth\auth $auth, \phpbb\log\log $log, \phpbb\config\config $config) { $this->cache = $cache; $this->db = $db; $this->auth = $auth; $this->log = $log; - $this->user = $user; $this->config = $config; - parent::__construct(); + parent::__construct($user); } /** @@ -63,7 +59,7 @@ class purge extends \phpbb\console\command\command { $this ->setName('cache:purge') - ->setDescription('Purge the cache.') + ->setDescription($this->user->lang('PURGE_CACHE')) ; } diff --git a/phpBB/phpbb/console/command/command.php b/phpBB/phpbb/console/command/command.php index d3449c0c38..638c989da2 100644 --- a/phpBB/phpbb/console/command/command.php +++ b/phpBB/phpbb/console/command/command.php @@ -15,4 +15,17 @@ namespace phpbb\console\command; abstract class command extends \Symfony\Component\Console\Command\Command { + /** @var \phpbb\user */ + protected $user; + + /** + * Constructor + * + * @param \phpbb\user $user User instance (mostly for translation) + */ + public function __construct(\phpbb\user $user) + { + $this->user = $user; + parent::__construct(); + } } diff --git a/phpBB/phpbb/console/command/config/command.php b/phpBB/phpbb/console/command/config/command.php index de3fbd7fa7..f0ad5d4d19 100644 --- a/phpBB/phpbb/console/command/config/command.php +++ b/phpBB/phpbb/console/command/config/command.php @@ -17,10 +17,10 @@ abstract class command extends \phpbb\console\command\command /** @var \phpbb\config\config */ protected $config; - function __construct(\phpbb\config\config $config) + function __construct(\phpbb\user $user, \phpbb\config\config $config) { $this->config = $config; - parent::__construct(); + parent::__construct($user); } } diff --git a/phpBB/phpbb/console/command/config/delete.php b/phpBB/phpbb/console/command/config/delete.php index 1310bb18b4..efd276d7e3 100644 --- a/phpBB/phpbb/console/command/config/delete.php +++ b/phpBB/phpbb/console/command/config/delete.php @@ -25,11 +25,11 @@ class delete extends command { $this ->setName('config:delete') - ->setDescription('Deletes a configuration option') + ->setDescription($this->user->lang('CLI_DESCRIPTION_DELETE_CONFIG')) ->addArgument( 'key', InputArgument::REQUIRED, - "The configuration option's name" + $this->user->lang('CLI_CONFIG_OPTION_NAME') ) ; } @@ -53,11 +53,11 @@ class delete extends command { $this->config->delete($key); - $output->writeln("<info>Successfully deleted config $key</info>"); + $output->writeln('<info>' . $this->user->lang('CLI_CONFIG_DELETE_SUCCESS', $key) . '</info>'); } else { - $output->writeln("<error>Config $key does not exist</error>"); + $output->writeln('<error>' . $this->user->lang('CLI_CONFIG_NOT_EXISTS', $key) . '</error>'); } } } diff --git a/phpBB/phpbb/console/command/config/get.php b/phpBB/phpbb/console/command/config/get.php index ee8c65110e..9c03b49a3d 100644 --- a/phpBB/phpbb/console/command/config/get.php +++ b/phpBB/phpbb/console/command/config/get.php @@ -26,17 +26,17 @@ class get extends command { $this ->setName('config:get') - ->setDescription("Gets a configuration option's value") + ->setDescription($this->user->lang('CLI_DESCRIPTION_GET_CONFIG')) ->addArgument( 'key', InputArgument::REQUIRED, - "The configuration option's name" + $this->user->lang('CLI_CONFIG_OPTION_NAME') ) ->addOption( 'no-newline', null, InputOption::VALUE_NONE, - 'Set this option if the value should be printed without a new line at the end.' + $this->user->lang('CLI_CONFIG_PRINT_WITHOUT_NEWLINE') ) ; } @@ -66,7 +66,7 @@ class get extends command } else { - $output->writeln("<error>Could not get config $key</error>"); + $output->writeln('<error>' . $this->user->lang('CLI_CONFIG_NOT_EXISTS', $key) . '</error>'); } } } diff --git a/phpBB/phpbb/console/command/config/increment.php b/phpBB/phpbb/console/command/config/increment.php index 21f0660e61..b4d7438b66 100644 --- a/phpBB/phpbb/console/command/config/increment.php +++ b/phpBB/phpbb/console/command/config/increment.php @@ -26,22 +26,22 @@ class increment extends command { $this ->setName('config:increment') - ->setDescription("Increments a configuration option's value") + ->setDescription($this->user->lang('CLI_DESCRIPTION_INCREMENT_CONFIG')) ->addArgument( 'key', InputArgument::REQUIRED, - "The configuration option's name" + $this->user->lang('CLI_CONFIG_OPTION_NAME') ) ->addArgument( 'increment', InputArgument::REQUIRED, - 'Amount to increment by' + $this->user->lang('CLI_CONFIG_INCREMENT_BY') ) ->addOption( 'dynamic', 'd', InputOption::VALUE_NONE, - 'Set this option if the configuration option changes too frequently to be efficiently cached.' + $this->user->lang('CLI_CONFIG_CANNOT_CACHED') ) ; } @@ -65,6 +65,6 @@ class increment extends command $this->config->increment($key, $increment, $use_cache); - $output->writeln("<info>Successfully incremented config $key</info>"); + $output->writeln('<info>' . $this->user->lang('CLI_CONFIG_INCREMENT_SUCCESS', $key) . '</info>'); } } diff --git a/phpBB/phpbb/console/command/config/set.php b/phpBB/phpbb/console/command/config/set.php index 587b7fb0de..695de31013 100644 --- a/phpBB/phpbb/console/command/config/set.php +++ b/phpBB/phpbb/console/command/config/set.php @@ -26,22 +26,22 @@ class set extends command { $this ->setName('config:set') - ->setDescription("Sets a configuration option's value") + ->setDescription($this->user->lang('CLI_DESCRIPTION_SET_CONFIG')) ->addArgument( 'key', InputArgument::REQUIRED, - "The configuration option's name" + $this->user->lang('CLI_CONFIG_OPTION_NAME') ) ->addArgument( 'value', InputArgument::REQUIRED, - 'New configuration value, use 0 and 1 to specify boolean values' + $this->user->lang('CLI_CONFIG_NEW') ) ->addOption( 'dynamic', 'd', InputOption::VALUE_NONE, - 'Set this option if the configuration option changes too frequently to be efficiently cached.' + $this->user->lang('CLI_CONFIG_CANNOT_CACHED') ) ; } @@ -65,6 +65,6 @@ class set extends command $this->config->set($key, $value, $use_cache); - $output->writeln("<info>Successfully set config $key</info>"); + $output->writeln('<info>' . $this->user->lang('CLI_CONFIG_SET_SUCCESS', $key) . '</info>'); } } diff --git a/phpBB/phpbb/console/command/config/set_atomic.php b/phpBB/phpbb/console/command/config/set_atomic.php index a7a52155f9..e8c69a0885 100644 --- a/phpBB/phpbb/console/command/config/set_atomic.php +++ b/phpBB/phpbb/console/command/config/set_atomic.php @@ -26,27 +26,27 @@ class set_atomic extends command { $this ->setName('config:set-atomic') - ->setDescription("Sets a configuration option's value only if the old matches the current value.") + ->setDescription($this->user->lang('CLI_DESCRIPTION_SET_ATOMIC_CONFIG')) ->addArgument( 'key', InputArgument::REQUIRED, - "The configuration option's name" + $this->user->lang('CLI_CONFIG_OPTION_NAME') ) ->addArgument( 'old', InputArgument::REQUIRED, - 'Current configuration value, use 0 and 1 to specify boolean values' + $this->user->lang('CLI_CONFIG_CURRENT') ) ->addArgument( 'new', InputArgument::REQUIRED, - 'New configuration value, use 0 and 1 to specify boolean values' + $this->user->lang('CLI_CONFIG_NEW') ) ->addOption( 'dynamic', 'd', InputOption::VALUE_NONE, - 'Set this option if the configuration option changes too frequently to be efficiently cached.' + $this->user->lang('CLI_CONFIG_CANNOT_CACHED') ) ; } @@ -72,12 +72,12 @@ class set_atomic extends command if ($this->config->set_atomic($key, $old_value, $new_value, $use_cache)) { - $output->writeln("<info>Successfully set config $key</info>"); + $output->writeln('<info>' . $this->user->lang('CLI_CONFIG_SET_SUCCESS', $key) . '</info>'); return 0; } else { - $output->writeln("<error>Could not set config $key</error>"); + $output->writeln('<error>' . $this->user->lang('CLI_CONFIG_SET_FAILURE', $key) . '</error>'); return 1; } } diff --git a/phpBB/phpbb/console/command/cron/cron_list.php b/phpBB/phpbb/console/command/cron/cron_list.php index 4f4228d9b3..c515fd9e80 100644 --- a/phpBB/phpbb/console/command/cron/cron_list.php +++ b/phpBB/phpbb/console/command/cron/cron_list.php @@ -20,20 +20,16 @@ class cron_list extends \phpbb\console\command\command /** @var \phpbb\cron\manager */ protected $cron_manager; - /** @var \phpbb\user */ - protected $user; - /** * Constructor * - * @param \phpbb\cron\manager $cron_manager Cron manager * @param \phpbb\user $user User instance + * @param \phpbb\cron\manager $cron_manager Cron manager */ - public function __construct(\phpbb\cron\manager $cron_manager, \phpbb\user $user) + public function __construct(\phpbb\user $user, \phpbb\cron\manager $cron_manager) { $this->cron_manager = $cron_manager; - $this->user = $user; - parent::__construct(); + parent::__construct($user); } /** diff --git a/phpBB/phpbb/console/command/cron/run.php b/phpBB/phpbb/console/command/cron/run.php index 0b365ece67..72ad1205ef 100644 --- a/phpBB/phpbb/console/command/cron/run.php +++ b/phpBB/phpbb/console/command/cron/run.php @@ -25,23 +25,19 @@ class run extends \phpbb\console\command\command /** @var \phpbb\lock\db */ protected $lock_db; - /** @var \phpbb\user */ - protected $user; - /** * Construct method * + * @param \phpbb\user $user The user object (used to get language information) * @param \phpbb\cron\manager $cron_manager The cron manager containing * the cron tasks to be executed. * @param \phpbb\lock\db $lock_db The lock for accessing database. - * @param \phpbb\user $user The user object (used to get language information) */ - public function __construct(\phpbb\cron\manager $cron_manager, \phpbb\lock\db $lock_db, \phpbb\user $user) + public function __construct(\phpbb\user $user, \phpbb\cron\manager $cron_manager, \phpbb\lock\db $lock_db) { $this->cron_manager = $cron_manager; $this->lock_db = $lock_db; - $this->user = $user; - parent::__construct(); + parent::__construct($user); } /** diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php index 2abeaf5268..c3caae5f70 100644 --- a/phpBB/phpbb/console/command/db/migrate.php +++ b/phpBB/phpbb/console/command/db/migrate.php @@ -32,31 +32,29 @@ class migrate extends \phpbb\console\command\command /** @var \phpbb\log\log */ protected $log; - /** @var \phpbb\user */ - protected $user; - - function __construct(\phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\user $user) + function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log) { $this->migrator = $migrator; $this->extension_manager = $extension_manager; $this->config = $config; $this->cache = $cache; $this->log = $log; - $this->user = $user; + parent::__construct($user); $this->user->add_lang(array('common', 'install', 'migrator')); - parent::__construct(); } protected function configure() { $this ->setName('db:migrate') - ->setDescription('Updates the database by applying migrations.') + ->setDescription($this->user->lang('CLI_DESCRIPTION_DB_MIGRATE')) ; } protected function execute(InputInterface $input, OutputInterface $output) { + $this->migrator->create_migrations_table(); + $this->load_migrations(); $orig_version = $this->config['version']; while (!$this->migrator->finished()) diff --git a/phpBB/phpbb/console/command/dev/migration_tips.php b/phpBB/phpbb/console/command/dev/migration_tips.php index c2f61568ea..f9047bdac8 100644 --- a/phpBB/phpbb/console/command/dev/migration_tips.php +++ b/phpBB/phpbb/console/command/dev/migration_tips.php @@ -20,17 +20,17 @@ class migration_tips extends \phpbb\console\command\command /** @var \phpbb\extension\manager */ protected $extension_manager; - function __construct(\phpbb\extension\manager $extension_manager) + function __construct(\phpbb\user $user, \phpbb\extension\manager $extension_manager) { $this->extension_manager = $extension_manager; - parent::__construct(); + parent::__construct($user); } protected function configure() { $this ->setName('dev:migration-tips') - ->setDescription('Finds migrations that are not depended on.') + ->setDescription($this->user->lang('CLI_DESCRIPTION_FIND_MIGRATIONS')) ; } diff --git a/phpBB/phpbb/console/command/extension/command.php b/phpBB/phpbb/console/command/extension/command.php index 21bb640504..364d954082 100644 --- a/phpBB/phpbb/console/command/extension/command.php +++ b/phpBB/phpbb/console/command/extension/command.php @@ -20,11 +20,11 @@ abstract class command extends \phpbb\console\command\command /** @var \phpbb\log\log */ protected $log; - public function __construct(\phpbb\extension\manager $manager, \phpbb\log\log $log) + public function __construct(\phpbb\user $user, \phpbb\extension\manager $manager, \phpbb\log\log $log) { $this->manager = $manager; $this->log = $log; - parent::__construct(); + parent::__construct($user); } } diff --git a/phpBB/phpbb/console/command/extension/disable.php b/phpBB/phpbb/console/command/extension/disable.php index c04848aa01..1eee16cbd9 100644 --- a/phpBB/phpbb/console/command/extension/disable.php +++ b/phpBB/phpbb/console/command/extension/disable.php @@ -22,11 +22,11 @@ class disable extends command { $this ->setName('extension:disable') - ->setDescription('Disables the specified extension.') + ->setDescription($this->user->lang('CLI_DESCRIPTION_DISABLE_EXTENSION')) ->addArgument( 'extension-name', InputArgument::REQUIRED, - 'Name of the extension' + $this->user->lang('CLI_EXTENSION_NAME') ) ; } @@ -39,13 +39,13 @@ class disable extends command if ($this->manager->is_enabled($name)) { - $output->writeln("<error>Could not disable extension $name</error>"); + $output->writeln('<error>' . $this->user->lang('CLI_EXTENSION_DISABLE_FAILURE', $name) . '</error>'); return 1; } else { $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_DISABLE', time(), array($name)); - $output->writeln("<info>Successfully disabled extension $name</info>"); + $output->writeln('<info>' . $this->user->lang('CLI_EXTENSION_DISABLE_SUCCESS', $name) . '</info>'); return 0; } } diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index 86a034cdf4..59ff11e9b7 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -22,11 +22,11 @@ class enable extends command { $this ->setName('extension:enable') - ->setDescription('Enables the specified extension.') + ->setDescription($this->user->lang('CLI_DESCRIPTION_ENABLE_EXTENSION')) ->addArgument( 'extension-name', InputArgument::REQUIRED, - 'Name of the extension' + $this->user->lang('CLI_EXTENSION_NAME') ) ; } @@ -40,12 +40,12 @@ class enable extends command if ($this->manager->is_enabled($name)) { $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($name)); - $output->writeln("<info>Successfully enabled extension $name</info>"); + $output->writeln('<info>' . $this->user->lang('CLI_EXTENSION_ENABLE_SUCCESS', $name) . '</info>'); return 0; } else { - $output->writeln("<error>Could not enable extension $name</error>"); + $output->writeln('<error>' . $this->user->lang('CLI_EXTENSION_ENABLE_FAILURE', $name) . '</error>'); return 1; } } diff --git a/phpBB/phpbb/console/command/extension/purge.php b/phpBB/phpbb/console/command/extension/purge.php index 841598b90a..517e9a74c9 100644 --- a/phpBB/phpbb/console/command/extension/purge.php +++ b/phpBB/phpbb/console/command/extension/purge.php @@ -22,11 +22,11 @@ class purge extends command { $this ->setName('extension:purge') - ->setDescription('Purges the specified extension.') + ->setDescription($this->user->lang('CLI_DESCRIPTION_PURGE_EXTENSION')) ->addArgument( 'extension-name', InputArgument::REQUIRED, - 'Name of the extension' + $this->user->lang('CLI_EXTENSION_NAME') ) ; } @@ -39,13 +39,13 @@ class purge extends command if ($this->manager->is_enabled($name)) { - $output->writeln("<error>Could not purge extension $name</error>"); + $output->writeln('<error>' . $this->user->lang('CLI_EXTENSION_PURGE_FAILURE', $name) . '</error>'); return 1; } else { $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_PURGE', time(), array($name)); - $output->writeln("<info>Successfully purge extension $name</info>"); + $output->writeln('<info>' . $this->user->lang('CLI_EXTENSION_PURGE_SUCCESS', $name) . '</info>'); return 0; } } diff --git a/phpBB/phpbb/console/command/extension/show.php b/phpBB/phpbb/console/command/extension/show.php index 2db1c59e24..6ce9607098 100644 --- a/phpBB/phpbb/console/command/extension/show.php +++ b/phpBB/phpbb/console/command/extension/show.php @@ -21,7 +21,7 @@ class show extends command { $this ->setName('extension:show') - ->setDescription('Lists all extensions in the database and on the filesystem.') + ->setDescription($this->user->lang('CLI_DESCRIPTION_LIST_EXTENSIONS')) ; } @@ -32,7 +32,7 @@ class show extends command if (empty($all)) { - $output->writeln('<comment>No extensions were found.</comment>'); + $output->writeln('<comment>' . $this->user->lang('CLI_EXTENSION_NOT_FOUND') . '</comment>'); return 3; } diff --git a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php index ec04da4267..ec4e1b0ee7 100644 --- a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php +++ b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php @@ -20,18 +20,18 @@ class recalculate_email_hash extends \phpbb\console\command\command /** @var \phpbb\db\driver\driver_interface */ protected $db; - function __construct(\phpbb\db\driver\driver_interface $db) + function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db) { $this->db = $db; - parent::__construct(); + parent::__construct($user); } protected function configure() { $this ->setName('fixup:recalculate-email-hash') - ->setDescription('Recalculates the user_email_hash column of the users table.') + ->setDescription($this->user->lang('CLI_DESCRIPTION_RECALCULATE_EMAIL_HASH')) ; } @@ -70,6 +70,6 @@ class recalculate_email_hash extends \phpbb\console\command\command } $this->db->sql_freeresult($result); - $output->writeln('<info>Successfully recalculated all email hashes.</info>'); + $output->writeln('<info>' . $this->user->lang('CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS') . '</info>'); } } diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php index 1f50032f26..8bd537586e 100644 --- a/phpBB/phpbb/content_visibility.php +++ b/phpBB/phpbb/content_visibility.php @@ -38,6 +38,12 @@ class content_visibility protected $auth; /** + * config object + * @var \phpbb\config\config + */ + protected $config; + + /** * phpBB root path * @var string */ @@ -53,6 +59,7 @@ class content_visibility * Constructor * * @param \phpbb\auth\auth $auth Auth object + * @param \phpbb\config\config $config Config object * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\user $user User object * @param string $phpbb_root_path Root path @@ -62,9 +69,10 @@ 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\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\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->db = $db; $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; @@ -562,7 +570,7 @@ class content_visibility * Add post to topic and forum statistics * * @param $data array Contains information from the topics table about given topic - * @param $sql_data array Populated with the SQL changes, may be empty at call time + * @param &$sql_data array Populated with the SQL changes, may be empty at call time * @return null */ public function add_post_to_statistic($data, &$sql_data) @@ -576,90 +584,68 @@ class content_visibility $sql_data[$this->users_table] = (($sql_data[$this->users_table]) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts + 1'; } - set_config_count('num_posts', 1, true); + $this->config->increment('num_posts', 1, false); } /** * Remove post from topic and forum statistics * * @param $data array Contains information from the topics table about given topic - * @param $sql_data array Populated with the SQL changes, may be empty at call time + * @param &$sql_data array Populated with the SQL changes, may be empty at call time * @return null */ public function remove_post_from_statistic($data, &$sql_data) { - $sql_data[$this->topics_table] = ((!empty($sql_data[$this->topics_table])) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved - 1'; - $sql_data[$this->forums_table] = ((!empty($sql_data[$this->forums_table])) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved - 1'; + if ($data['post_visibility'] == ITEM_APPROVED) + { + $sql_data[$this->topics_table] = ((!empty($sql_data[$this->topics_table])) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved - 1'; + $sql_data[$this->forums_table] = ((!empty($sql_data[$this->forums_table])) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved - 1'; - if ($data['post_postcount']) + if ($data['post_postcount']) + { + $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1'; + } + + $this->config->increment('num_posts', -1, false); + } + else if ($data['post_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) { - $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1'; + $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_unapproved = forum_posts_unapproved - 1'; + $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_unapproved = topic_posts_unapproved - 1'; + } + else if ($data['post_visibility'] == ITEM_DELETED) + { + $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_softdeleted = forum_posts_softdeleted - 1'; + $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_softdeleted = topic_posts_softdeleted - 1'; } - - set_config_count('num_posts', -1, true); } /** * Remove topic from forum statistics * - * @param $topic_id int The topic to act on - * @param $forum_id int Forum where the topic is found - * @param $topic_row array Contains information from the topic, may be empty at call time - * @param $sql_data array Populated with the SQL changes, may be empty at call time + * @param $data array Post and topic data + * @param &$sql_data array Populated with the SQL changes, may be empty at call time * @return null */ - public function remove_topic_from_statistic($topic_id, $forum_id, &$topic_row, &$sql_data) + public function remove_topic_from_statistic($data, &$sql_data) { - // Do we need to grab some topic informations? - if (!sizeof($topic_row)) + if ($data['topic_visibility'] == ITEM_APPROVED) { - $sql = 'SELECT topic_type, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, topic_visibility - FROM ' . $this->topics_table . ' - WHERE topic_id = ' . (int) $topic_id; - $result = $this->db->sql_query($sql); - $topic_row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - } + $sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1'; - // If this is an edited topic or the first post the topic gets completely disapproved later on... - $sql_data[$this->forums_table] = (($sql_data[$this->forums_table]) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_topics_approved = forum_topics_approved - 1'; - $sql_data[$this->forums_table] .= ', forum_posts_approved = forum_posts_approved - ' . $topic_row['topic_posts_approved']; - $sql_data[$this->forums_table] .= ', forum_posts_unapproved = forum_posts_unapproved - ' . $topic_row['topic_posts_unapproved']; - $sql_data[$this->forums_table] .= ', forum_posts_softdeleted = forum_posts_softdeleted - ' . $topic_row['topic_posts_softdeleted']; - - set_config_count('num_topics', -1, true); - set_config_count('num_posts', $topic_row['topic_posts_approved'] * (-1), true); - - // Get user post count information - $sql = 'SELECT poster_id, COUNT(post_id) AS num_posts - FROM ' . $this->posts_table . ' - WHERE topic_id = ' . (int) $topic_id . ' - AND post_postcount = 1 - AND post_visibility = ' . ITEM_APPROVED . ' - GROUP BY poster_id'; - $result = $this->db->sql_query($sql); - - $postcounts = array(); - while ($row = $this->db->sql_fetchrow($result)) + if ($data['post_postcount']) + { + $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1'; + } + } + else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) { - $postcounts[(int) $row['num_posts']][] = (int) $row['poster_id']; + $sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1'; } - $this->db->sql_freeresult($result); - - // Decrement users post count - foreach ($postcounts as $num_posts => $poster_ids) + else if ($data['topic_visibility'] == ITEM_DELETED) { - $sql = 'UPDATE ' . $this->users_table . ' - SET user_posts = 0 - WHERE user_posts < ' . $num_posts . ' - AND ' . $this->db->sql_in_set('user_id', $poster_ids); - $this->db->sql_query($sql); - - $sql = 'UPDATE ' . $this->users_table . ' - SET user_posts = user_posts - ' . $num_posts . ' - WHERE user_posts >= ' . $num_posts . ' - AND ' . $this->db->sql_in_set('user_id', $poster_ids); - $this->db->sql_query($sql); + $sql_data[FORUMS_TABLE] .= 'forum_posts_softdeleted = forum_posts_softdeleted - 1, forum_topics_softdeleted = forum_topics_softdeleted - 1'; } + } } diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index e330fb5b6d..dd89d0504a 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -50,7 +50,7 @@ class helper protected $phpbb_root_path; /** - * PHP extension + * PHP file extension * @var string */ protected $php_ext; @@ -65,7 +65,7 @@ class helper * @param \phpbb\extension\manager $manager Extension manager object * @param \phpbb\symfony_request $symfony_request Symfony Request object * @param string $phpbb_root_path phpBB root path - * @param string $php_ext PHP extension + * @param string $php_ext PHP file extension */ public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, $phpbb_root_path, $php_ext) { @@ -82,9 +82,11 @@ class helper /** * Automate setting up the page and creating the response object. * - * @param string $handle The template handle to render + * @param string $template_file The template handle to render * @param string $page_title The title of the page to output * @param int $status_code The status code to be sent to the page header + * @param bool $display_online_list Do we display online users list + * * @return Response object containing rendered page */ public function render($template_file, $page_title = '', $status_code = 200, $display_online_list = false) diff --git a/phpBB/phpbb/controller/resolver.php b/phpBB/phpbb/controller/resolver.php index efab34b701..948a6a218c 100644 --- a/phpBB/phpbb/controller/resolver.php +++ b/phpBB/phpbb/controller/resolver.php @@ -41,6 +41,12 @@ class resolver implements ControllerResolverInterface protected $template; /** + * Request type cast helper object + * @var \phpbb\request\type_cast_helper + */ + protected $type_cast_helper; + + /** * phpBB root path * @var string */ @@ -59,6 +65,7 @@ class resolver implements ControllerResolverInterface $this->user = $user; $this->container = $container; $this->template = $template; + $this->type_cast_helper = new \phpbb\request\type_cast_helper(); $this->phpbb_root_path = $phpbb_root_path; } @@ -138,7 +145,16 @@ class resolver implements ControllerResolverInterface { if (array_key_exists($param->name, $attributes)) { - $arguments[] = $attributes[$param->name]; + if (is_string($attributes[$param->name])) + { + $value = $attributes[$param->name]; + $this->type_cast_helper->set_var($value, $attributes[$param->name], 'string', true, false); + $arguments[] = $value; + } + else + { + $arguments[] = $attributes[$param->name]; + } } else if ($param->getClass() && $param->getClass()->isInstance($request)) { diff --git a/phpBB/phpbb/cron/manager.php b/phpBB/phpbb/cron/manager.php index b0601e641a..5c8ac04b77 100644 --- a/phpBB/phpbb/cron/manager.php +++ b/phpBB/phpbb/cron/manager.php @@ -35,6 +35,8 @@ class manager * Constructor. Loads all available tasks. * * @param array|\Traversable $tasks Provides an iterable set of task names + * @param string $phpbb_root_path Relative path to phpBB root + * @param string $php_ext PHP file extension */ public function __construct($tasks, $phpbb_root_path, $php_ext) { diff --git a/phpBB/phpbb/cron/task/core/prune_all_forums.php b/phpBB/phpbb/cron/task/core/prune_all_forums.php index 032ba1d2cc..b47939ccbe 100644 --- a/phpBB/phpbb/cron/task/core/prune_all_forums.php +++ b/phpBB/phpbb/cron/task/core/prune_all_forums.php @@ -31,7 +31,7 @@ class prune_all_forums extends \phpbb\cron\task\base * Constructor. * * @param string $phpbb_root_path The root path - * @param string $php_ext The PHP extension + * @param string $php_ext The PHP file extension * @param \phpbb\config\config $config The config * @param \phpbb\db\driver\driver_interface $db The db connection */ diff --git a/phpBB/phpbb/cron/task/core/prune_forum.php b/phpBB/phpbb/cron/task/core/prune_forum.php index 8da0048baa..ba68565197 100644 --- a/phpBB/phpbb/cron/task/core/prune_forum.php +++ b/phpBB/phpbb/cron/task/core/prune_forum.php @@ -41,7 +41,7 @@ class prune_forum extends \phpbb\cron\task\base implements \phpbb\cron\task\para * Constructor. * * @param string $phpbb_root_path The root path - * @param string $php_ext The PHP extension + * @param string $php_ext PHP file extension * @param \phpbb\config\config $config The config * @param \phpbb\db\driver\driver_interface $db The db connection */ diff --git a/phpBB/phpbb/cron/task/core/prune_shadow_topics.php b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php index 83a2460454..97a4b0ea86 100644 --- a/phpBB/phpbb/cron/task/core/prune_shadow_topics.php +++ b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php @@ -43,7 +43,7 @@ class prune_shadow_topics extends \phpbb\cron\task\base implements \phpbb\cron\t * Constructor. * * @param string $phpbb_root_path The root path - * @param string $php_ext The PHP extension + * @param string $php_ext PHP file extension * @param \phpbb\config\config $config The config * @param \phpbb\db\driver\driver_interface $db The db connection * @param \phpbb\log\log $log The phpBB log system diff --git a/phpBB/phpbb/cron/task/core/queue.php b/phpBB/phpbb/cron/task/core/queue.php index 553e424bd0..796a96d7f5 100644 --- a/phpBB/phpbb/cron/task/core/queue.php +++ b/phpBB/phpbb/cron/task/core/queue.php @@ -26,7 +26,7 @@ class queue extends \phpbb\cron\task\base * Constructor. * * @param string $phpbb_root_path The root path - * @param string $php_ext The PHP extension + * @param string $php_ext PHP file extension * @param \phpbb\config\config $config The config */ public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config) diff --git a/phpBB/phpbb/cron/task/core/tidy_database.php b/phpBB/phpbb/cron/task/core/tidy_database.php index ec058b4a50..949bba8012 100644 --- a/phpBB/phpbb/cron/task/core/tidy_database.php +++ b/phpBB/phpbb/cron/task/core/tidy_database.php @@ -26,7 +26,7 @@ class tidy_database extends \phpbb\cron\task\base * Constructor. * * @param string $phpbb_root_path The root path - * @param string $php_ext The PHP extension + * @param string $php_ext The PHP file extension * @param \phpbb\config\config $config The config */ public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config) diff --git a/phpBB/phpbb/cron/task/core/tidy_search.php b/phpBB/phpbb/cron/task/core/tidy_search.php index 2de744b7c1..ce16b3f988 100644 --- a/phpBB/phpbb/cron/task/core/tidy_search.php +++ b/phpBB/phpbb/cron/task/core/tidy_search.php @@ -31,7 +31,7 @@ class tidy_search extends \phpbb\cron\task\base * Constructor. * * @param string $phpbb_root_path The root path - * @param string $php_ext The PHP extension + * @param string $php_ext The PHP file extension * @param \phpbb\auth\auth $auth The auth * @param \phpbb\config\config $config The config * @param \phpbb\db\driver\driver_interface $db The db connection @@ -54,8 +54,7 @@ class tidy_search extends \phpbb\cron\task\base */ public function run() { - // Select the search method - $search_type = basename($this->config['search_type']); + $search_type = $this->config['search_type']; // We do some additional checks in the module to ensure it can actually be utilised $error = false; @@ -78,10 +77,7 @@ class tidy_search extends \phpbb\cron\task\base */ public function is_runnable() { - // Select the search method - $search_type = basename($this->config['search_type']); - - return class_exists($search_type); + return class_exists($this->config['search_type']); } /** diff --git a/phpBB/phpbb/cron/task/core/tidy_warnings.php b/phpBB/phpbb/cron/task/core/tidy_warnings.php index 058288222c..7b67eae6ef 100644 --- a/phpBB/phpbb/cron/task/core/tidy_warnings.php +++ b/phpBB/phpbb/cron/task/core/tidy_warnings.php @@ -28,7 +28,7 @@ class tidy_warnings extends \phpbb\cron\task\base * Constructor. * * @param string $phpbb_root_path The root path - * @param string $php_ext The PHP extension + * @param string $php_ext PHP file extension * @param \phpbb\config\config $config The config */ public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config) diff --git a/phpBB/phpbb/cron/task/wrapper.php b/phpBB/phpbb/cron/task/wrapper.php index 11399282d3..8a4a8b1f0c 100644 --- a/phpBB/phpbb/cron/task/wrapper.php +++ b/phpBB/phpbb/cron/task/wrapper.php @@ -29,6 +29,8 @@ class wrapper * Wraps a task $task, which must implement cron_task interface. * * @param \phpbb\cron\task\task $task The cron task to wrap. + * @param string $phpbb_root_path Relative path to phpBB root + * @param string $php_ext PHP file extension */ public function __construct(\phpbb\cron\task\task $task, $phpbb_root_path, $php_ext) { diff --git a/phpBB/phpbb/datetime.php b/phpBB/phpbb/datetime.php index 9c9292a8e4..e674707883 100644 --- a/phpBB/phpbb/datetime.php +++ b/phpBB/phpbb/datetime.php @@ -38,9 +38,9 @@ class datetime extends \DateTime * Constructs a new instance of \phpbb\datetime, expanded to include an argument to inject * the user context and modify the timezone to the users selected timezone if one is not set. * + * @param user $user object for context. * @param string $time String in a format accepted by strtotime(). * @param \DateTimeZone $timezone Time zone of the time. - * @param user $user object for context. */ public function __construct($user, $time = 'now', \DateTimeZone $timezone = null) { diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 3e9110d8bc..9fc04d47a1 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -372,6 +372,17 @@ abstract class driver implements driver_interface /** * {@inheritDoc} */ + function sql_not_like_expression($expression) + { + $expression = utf8_str_replace(array('_', '%'), array("\_", "\%"), $expression); + $expression = utf8_str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $expression); + + return $this->_sql_not_like_expression('NOT LIKE \'' . $this->sql_escape($expression) . '\''); + } + + /** + * {@inheritDoc} + */ public function sql_case($condition, $action_true, $action_false = false) { $sql_case = 'CASE WHEN ' . $condition; diff --git a/phpBB/phpbb/db/driver/driver_interface.php b/phpBB/phpbb/db/driver/driver_interface.php index 6722d059a5..8b487c5d42 100644 --- a/phpBB/phpbb/db/driver/driver_interface.php +++ b/phpBB/phpbb/db/driver/driver_interface.php @@ -419,6 +419,16 @@ interface driver_interface public function sql_like_expression($expression); /** + * Correctly adjust NOT LIKE expression for special characters + * Some DBMS are handling them in a different way + * + * @param string $expression The expression to use. Every wildcard is + * escaped, except $this->any_char and $this->one_char + * @return string A SQL statement like: "NOT LIKE 'bertie_%'" + */ + public function sql_not_like_expression($expression); + + /** * Explain queries * * @param string $mode Available modes: display, start, stop, diff --git a/phpBB/phpbb/db/driver/factory.php b/phpBB/phpbb/db/driver/factory.php index f0fa18051b..fb3a826254 100644 --- a/phpBB/phpbb/db/driver/factory.php +++ b/phpBB/phpbb/db/driver/factory.php @@ -420,6 +420,14 @@ class factory implements driver_interface /** * {@inheritdoc} */ + public function sql_not_like_expression($expression) + { + return $this->get_driver()->sql_not_like_expression($expression); + } + + /** + * {@inheritdoc} + */ public function sql_report($mode, $query = '') { return $this->get_driver()->sql_report($mode, $query); diff --git a/phpBB/phpbb/db/driver/mssql.php b/phpBB/phpbb/db/driver/mssql.php index 268463a151..f9ea884ce2 100644 --- a/phpBB/phpbb/db/driver/mssql.php +++ b/phpBB/phpbb/db/driver/mssql.php @@ -351,6 +351,15 @@ class mssql extends \phpbb\db\driver\driver } /** + * Build NOT LIKE expression + * @access private + */ + function _sql_not_like_expression($expression) + { + return $expression . " ESCAPE '\\'"; + } + + /** * return sql error array * @access private */ diff --git a/phpBB/phpbb/db/driver/mssql_base.php b/phpBB/phpbb/db/driver/mssql_base.php index e7101903b8..514df9eaca 100644 --- a/phpBB/phpbb/db/driver/mssql_base.php +++ b/phpBB/phpbb/db/driver/mssql_base.php @@ -52,6 +52,15 @@ abstract class mssql_base extends \phpbb\db\driver\driver } /** + * Build NOT LIKE expression + * @access private + */ + function _sql_not_like_expression($expression) + { + return $expression . " ESCAPE '\\'"; + } + + /** * Build db-specific query data * @access private */ diff --git a/phpBB/phpbb/db/driver/mysql_base.php b/phpBB/phpbb/db/driver/mysql_base.php index e7c9b63f20..5e0b359134 100644 --- a/phpBB/phpbb/db/driver/mysql_base.php +++ b/phpBB/phpbb/db/driver/mysql_base.php @@ -112,6 +112,15 @@ abstract class mysql_base extends \phpbb\db\driver\driver } /** + * Build NOT LIKE expression + * @access private + */ + function _sql_not_like_expression($expression) + { + return $expression; + } + + /** * Build db-specific query data * @access private */ diff --git a/phpBB/phpbb/db/driver/oracle.php b/phpBB/phpbb/db/driver/oracle.php index d1a186f1ba..6dcab5dd7d 100644 --- a/phpBB/phpbb/db/driver/oracle.php +++ b/phpBB/phpbb/db/driver/oracle.php @@ -645,6 +645,15 @@ class oracle extends \phpbb\db\driver\driver return $expression . " ESCAPE '\\'"; } + /** + * Build NOT LIKE expression + * @access private + */ + function _sql_not_like_expression($expression) + { + return $expression . " ESCAPE '\\'"; + } + function _sql_custom_build($stage, $data) { return $data; diff --git a/phpBB/phpbb/db/driver/postgres.php b/phpBB/phpbb/db/driver/postgres.php index 83e9fa51f6..a3b9aa4c6b 100644 --- a/phpBB/phpbb/db/driver/postgres.php +++ b/phpBB/phpbb/db/driver/postgres.php @@ -371,6 +371,15 @@ class postgres extends \phpbb\db\driver\driver } /** + * Build NOT LIKE expression + * @access private + */ + function _sql_not_like_expression($expression) + { + return $expression; + } + + /** * {@inheritDoc} */ function cast_expr_to_bigint($expression) diff --git a/phpBB/phpbb/db/driver/sqlite.php b/phpBB/phpbb/db/driver/sqlite.php index 2112e5ba2f..d5da0e2438 100644 --- a/phpBB/phpbb/db/driver/sqlite.php +++ b/phpBB/phpbb/db/driver/sqlite.php @@ -277,7 +277,7 @@ class sqlite extends \phpbb\db\driver\driver */ function sql_like_expression($expression) { - // Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it! + // Unlike LIKE, GLOB is unfortunately case sensitive. // We only catch * and ? here, not the character map possible on file globbing. $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression); @@ -288,6 +288,23 @@ class sqlite extends \phpbb\db\driver\driver } /** + * {@inheritDoc} + * + * For SQLite an underscore is a not-known character... + */ + function sql_not_like_expression($expression) + { + // Unlike NOT LIKE, NOT GLOB is unfortunately case sensitive. + // We only catch * and ? here, not the character map possible on file globbing. + $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression); + + $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression); + $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression); + + return 'NOT GLOB \'' . $this->sql_escape($expression) . '\''; + } + + /** * return sql error array * @access private */ diff --git a/phpBB/phpbb/db/driver/sqlite3.php b/phpBB/phpbb/db/driver/sqlite3.php index 0922229e0a..4e3e0d3329 100644 --- a/phpBB/phpbb/db/driver/sqlite3.php +++ b/phpBB/phpbb/db/driver/sqlite3.php @@ -260,11 +260,11 @@ class sqlite3 extends \phpbb\db\driver\driver /** * {@inheritDoc} * - * For SQLite an underscore is a not-known character... + * For SQLite an underscore is an unknown character. */ public function sql_like_expression($expression) { - // Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it! + // Unlike LIKE, GLOB is unfortunately case sensitive. // We only catch * and ? here, not the character map possible on file globbing. $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression); @@ -275,6 +275,23 @@ class sqlite3 extends \phpbb\db\driver\driver } /** + * {@inheritDoc} + * + * For SQLite an underscore is an unknown character. + */ + public function sql_not_like_expression($expression) + { + // Unlike NOT LIKE, NOT GLOB is unfortunately case sensitive + // We only catch * and ? here, not the character map possible on file globbing. + $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression); + + $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression); + $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression); + + return 'NOT GLOB \'' . $this->sql_escape($expression) . '\''; + } + + /** * return sql error array * * @return array diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php b/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php index 5964e7a997..7324b893cc 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php @@ -18,8 +18,9 @@ class profilefield_facebook extends \phpbb\db\migration\profilefield_base_migrat static public function depends_on() { return array( - '\phpbb\db\migration\data\v310\profilefield_types', + '\phpbb\db\migration\data\v310\profilefield_contact_field', '\phpbb\db\migration\data\v310\profilefield_show_novalue', + '\phpbb\db\migration\data\v310\profilefield_types', ); } diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php b/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php index 9bef0a4c0b..3b0963fc19 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php @@ -18,8 +18,9 @@ class profilefield_googleplus extends \phpbb\db\migration\profilefield_base_migr static public function depends_on() { return array( - '\phpbb\db\migration\data\v310\profilefield_types', + '\phpbb\db\migration\data\v310\profilefield_contact_field', '\phpbb\db\migration\data\v310\profilefield_show_novalue', + '\phpbb\db\migration\data\v310\profilefield_types', ); } diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php b/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php index 9a5de9d0eb..0dbe9041bb 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php @@ -18,8 +18,9 @@ class profilefield_skype extends \phpbb\db\migration\profilefield_base_migration static public function depends_on() { return array( - '\phpbb\db\migration\data\v310\profilefield_types', + '\phpbb\db\migration\data\v310\profilefield_contact_field', '\phpbb\db\migration\data\v310\profilefield_show_novalue', + '\phpbb\db\migration\data\v310\profilefield_types', ); } diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php b/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php index 68d038f609..850e096439 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php @@ -18,8 +18,9 @@ class profilefield_twitter extends \phpbb\db\migration\profilefield_base_migrati static public function depends_on() { return array( - '\phpbb\db\migration\data\v310\profilefield_types', + '\phpbb\db\migration\data\v310\profilefield_contact_field', '\phpbb\db\migration\data\v310\profilefield_show_novalue', + '\phpbb\db\migration\data\v310\profilefield_types', ); } diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php b/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php index bb90c0aa5c..40a569d2a2 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php @@ -18,8 +18,9 @@ class profilefield_youtube extends \phpbb\db\migration\profilefield_base_migrati static public function depends_on() { return array( - '\phpbb\db\migration\data\v310\profilefield_types', + '\phpbb\db\migration\data\v310\profilefield_contact_field', '\phpbb\db\migration\data\v310\profilefield_show_novalue', + '\phpbb\db\migration\data\v310\profilefield_types', ); } diff --git a/phpBB/phpbb/db/migration/data/v310/rename_too_long_indexes.php b/phpBB/phpbb/db/migration/data/v310/rename_too_long_indexes.php new file mode 100644 index 0000000000..8d2a15d8ea --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/rename_too_long_indexes.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\v310; + +class rename_too_long_indexes extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v30x\release_3_0_0'); + } + + public function update_schema() + { + return array( + 'drop_keys' => array( + $this->table_prefix . 'search_wordmatch' => array( + 'unq_mtch', + ), + ), + 'add_unique_index' => array( + $this->table_prefix . 'search_wordmatch' => array( + 'un_mtch' => array('word_id', 'post_id', 'title_match'), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/search_type.php b/phpBB/phpbb/db/migration/data/v310/search_type.php new file mode 100644 index 0000000000..f89456ae19 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/search_type.php @@ -0,0 +1,34 @@ +<?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\v310; + +class search_type extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\dev', + ); + } + + public function update_data() + { + return array( + array('if', array( + (is_file($this->phpbb_root_path . 'phpbb/search/' . $this->config['search_type'] . $this->php_ext)), + array('config.update', array('search_type', '\\phpbb\\search\\' . $this->config['search_type'])), + )), + ); + } +} 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 f5970e74b2..6335c75398 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 @@ -119,6 +119,7 @@ class soft_delete_mod_convert extends \phpbb\db\migration\migration { return new \phpbb\content_visibility( new \phpbb\auth\auth(), + $this->config, $this->db, new \phpbb\user(), $this->phpbb_root_path, diff --git a/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php b/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php new file mode 100644 index 0000000000..527da20590 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php @@ -0,0 +1,44 @@ +<?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\v310; + +class topic_sort_username extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\dev'); + } + + public function update_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'topics' => array( + 'topic_first_poster_name' => array('VCHAR_UNI:255', '', 'true_sort'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'topics' => array( + 'topic_first_poster_name' => array('VCHAR_UNI:255', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/profilefield_base_migration.php b/phpBB/phpbb/db/migration/profilefield_base_migration.php index e66e5fd080..9000949a7d 100644 --- a/phpBB/phpbb/db/migration/profilefield_base_migration.php +++ b/phpBB/phpbb/db/migration/profilefield_base_migration.php @@ -107,8 +107,8 @@ abstract class profilefield_base_migration extends \phpbb\db\migration\migration while ($lang_id = (int) $this->db->sql_fetchfield('lang_id')) { $insert_buffer->insert(array( - 'field_id' => $field_id, - 'lang_id' => $lang_id, + 'field_id' => (int) $field_id, + 'lang_id' => (int) $lang_id, 'lang_name' => $lang_name, 'lang_explain' => '', 'lang_default_value' => '', @@ -136,8 +136,8 @@ abstract class profilefield_base_migration extends \phpbb\db\migration\migration foreach ($this->profilefield_language_data as $language_data) { $insert_buffer->insert(array_merge(array( - 'field_id' => $field_id, - 'lang_id' => $lang_id, + 'field_id' => (int) $field_id, + 'lang_id' => (int) $lang_id, ), $language_data)); } } @@ -154,15 +154,15 @@ abstract class profilefield_base_migration extends \phpbb\db\migration\migration $field_id = $this->get_custom_profile_field_id(); $sql = 'DELETE FROM ' . PROFILE_FIELDS_TABLE . ' - WHERE field_id = ' . $field_id; + WHERE field_id = ' . (int) $field_id; $this->db->sql_query($sql); $sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . ' - WHERE field_id = ' . $field_id; + WHERE field_id = ' . (int) $field_id; $this->db->sql_query($sql); $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . ' - WHERE field_id = ' . $field_id; + WHERE field_id = ' . (int) $field_id; $this->db->sql_query($sql); } diff --git a/phpBB/phpbb/db/migration/tool/permission.php b/phpBB/phpbb/db/migration/tool/permission.php index d2df27613a..5cfbc5ca00 100644 --- a/phpBB/phpbb/db/migration/tool/permission.php +++ b/phpBB/phpbb/db/migration/tool/permission.php @@ -105,6 +105,7 @@ class permission implements \phpbb\db\migration\tool\tool_interface * @param string $auth_option The name of the permission (auth) option * @param bool $global True for checking a global permission setting, * False for a local permission setting + * @param int|false $copy_from If set, contains the id of the permission from which to copy the new one. * @return null */ public function add($auth_option, $global = true, $copy_from = false) @@ -243,7 +244,9 @@ class permission implements \phpbb\db\migration\tool\tool_interface * Add a new permission role * * @param string $role_name The new role name - * @param sting $role_type The type (u_, m_, a_) + * @param string $role_type The type (u_, m_, a_) + * @param string $role_description Description of the new role + * * @return null */ public function role_add($role_name, $role_type, $role_description = '') diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 8b089a060f..8bc63e564a 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -767,4 +767,28 @@ class migrator return $this->migrations; } + + /** + * Creates the migrations table if it does not exist. + * @return null + */ + public function create_migrations_table() + { + // Make sure migrations have been installed. + if (!$this->db_tools->sql_table_exists($this->table_prefix . 'migrations')) + { + $this->db_tools->sql_create_table($this->table_prefix . 'migrations', array( + 'COLUMNS' => array( + 'migration_name' => array('VCHAR', ''), + 'migration_depends_on' => array('TEXT', ''), + 'migration_schema_done' => array('BOOL', 0), + 'migration_data_done' => array('BOOL', 0), + 'migration_data_state' => array('TEXT', ''), + 'migration_start_time' => array('TIMESTAMP', 0), + 'migration_end_time' => array('TIMESTAMP', 0), + ), + 'PRIMARY_KEY' => 'migration_name', + )); + } + } } diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 18defc4535..3567570137 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -1487,8 +1487,16 @@ class tools $return_array['textimage'] = $column_type === '[text]'; - $sql .= 'NOT NULL'; - $sql_default .= 'NOT NULL'; + if (!is_null($column_data[1]) || (isset($column_data[2]) && $column_data[2] == 'auto_increment')) + { + $sql .= 'NOT NULL'; + $sql_default .= 'NOT NULL'; + } + else + { + $sql .= 'NULL'; + $sql_default .= 'NULL'; + } $return_array['column_type_sql_default'] = $sql_default; @@ -1503,7 +1511,15 @@ class tools { $sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' "; } - $sql .= 'NOT NULL'; + + if (!is_null($column_data[1])) + { + $sql .= 'NOT NULL'; + } + else + { + $sql .= 'NULL'; + } if (isset($column_data[2])) { @@ -1528,7 +1544,7 @@ class tools // Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields) if (!preg_match('/number/i', $column_type)) { - $sql .= ($column_data[1] === '') ? '' : 'NOT NULL'; + $sql .= ($column_data[1] === '' || $column_data[1] === null) ? '' : 'NOT NULL'; } $return_array['auto_increment'] = false; @@ -1556,6 +1572,12 @@ class tools $return_array['null'] = 'NOT NULL'; $sql .= 'NOT NULL '; } + else + { + $default_val = "'" . $column_data[1] . "'"; + $return_array['null'] = 'NULL'; + $sql .= 'NULL '; + } $return_array['default'] = $default_val; @@ -1588,8 +1610,11 @@ class tools $sql .= ' ' . $column_type; } - $sql .= ' NOT NULL '; - $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : ''; + if (!is_null($column_data[1])) + { + $sql .= ' NOT NULL '; + $sql .= "DEFAULT '{$column_data[1]}'"; + } break; } @@ -1791,7 +1816,8 @@ class tools $old_return_statements = $this->return_statements; $this->return_statements = true; - $indexes = $this->mssql_get_existing_indexes($table_name, $column_name); + $indexes = $this->get_existing_indexes($table_name, $column_name); + $indexes = array_merge($indexes, $this->get_existing_indexes($table_name, $column_name, true)); // Drop any indexes $recreate_indexes = array(); @@ -2013,7 +2039,7 @@ class tools break; case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; + $statements[] = 'ALTER TABLE ' . $table_name . ' add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; break; case 'sqlite': @@ -2079,7 +2105,7 @@ class tools $statements = array(); $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) - if (strlen($table_name . $index_name) - strlen($table_prefix) > 24) + if (strlen($table_name . '_' . $index_name) - strlen($table_prefix) > 24) { $max_length = strlen($table_prefix) + 24; trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); @@ -2249,10 +2275,23 @@ class tools } /** + * Removes table_name from the index_name if it is at the beginning + * + * @param $table_name + * @param $index_name + * @return string + */ + protected function strip_table_name_from_index_name($table_name, $index_name) + { + return (strpos(strtoupper($index_name), strtoupper($table_name)) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name; + } + + /** * Change column type (not name!) */ function sql_column_change($table_name, $column_name, $column_data, $inline = false) { + $original_column_data = $column_data; $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); $statements = array(); @@ -2264,12 +2303,14 @@ class tools $old_return_statements = $this->return_statements; $this->return_statements = true; - $indexes = $this->mssql_get_existing_indexes($table_name, $column_name); + $indexes = $this->get_existing_indexes($table_name, $column_name); + $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); // Drop any indexes - if (!empty($indexes)) + if (!empty($indexes) || !empty($unique_indexes)) { - foreach ($indexes as $index_name => $index_data) + $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); + foreach ($drop_indexes as $index_name) { $result = $this->sql_index_drop($table_name, $index_name); $statements = array_merge($statements, $result); @@ -2299,6 +2340,16 @@ class tools } } + if (!empty($unique_indexes)) + { + // Recreate unique indexes after we changed the column + foreach ($unique_indexes as $index_name => $index_data) + { + $result = $this->sql_create_unique_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + $this->return_statements = $old_return_statements; break; @@ -2308,7 +2359,69 @@ class tools break; case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql']; + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + // Get list of existing indexes + $indexes = $this->get_existing_indexes($table_name, $column_name); + $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); + + // Drop any indexes + if (!empty($indexes) || !empty($unique_indexes)) + { + $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); + foreach ($drop_indexes as $index_name) + { + $result = $this->sql_index_drop($table_name, $this->strip_table_name_from_index_name($table_name, $index_name)); + $statements = array_merge($statements, $result); + } + } + + $temp_column_name = 'temp_' . substr(md5($column_name), 0, 25); + // Add a temporary table with the new type + $result = $this->sql_column_add($table_name, $temp_column_name, $original_column_data); + $statements = array_merge($statements, $result); + + // Copy the data to the new column + $statements[] = 'UPDATE ' . $table_name . ' SET ' . $temp_column_name . ' = ' . $column_name; + + // Drop the original column + $result = $this->sql_column_remove($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Recreate the original column with the new type + $result = $this->sql_column_add($table_name, $column_name, $original_column_data); + $statements = array_merge($statements, $result); + + if (!empty($indexes)) + { + // Recreate indexes after we changed the column + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_create_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data); + $statements = array_merge($statements, $result); + } + } + + if (!empty($unique_indexes)) + { + // Recreate unique indexes after we changed the column + foreach ($unique_indexes as $index_name => $index_data) + { + $result = $this->sql_create_unique_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data); + $statements = array_merge($statements, $result); + } + } + + // Copy the data to the original column + $statements[] = 'UPDATE ' . $table_name . ' SET ' . $column_name . ' = ' . $temp_column_name; + + // Drop the temporary column again + $result = $this->sql_column_remove($table_name, $temp_column_name); + $statements = array_merge($statements, $result); + + $this->return_statements = $old_return_statements; break; case 'postgres': @@ -2492,45 +2605,78 @@ class tools * * @param string $table_name * @param string $column_name + * @param bool $unique Should we get unique indexes or normal ones * @return array Array with Index name => columns */ - protected function mssql_get_existing_indexes($table_name, $column_name) + public function get_existing_indexes($table_name, $column_name, $unique = false) { - $existing_indexes = array(); - if ($this->mssql_is_sql_server_2000()) + switch ($this->sql_layer) { - // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx - // Deprecated in SQL Server 2005 - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name - FROM sysindexes ix - INNER JOIN sysindexkeys ixc - ON ixc.id = ix.id - AND ixc.indid = ix.indid - INNER JOIN syscolumns cols - ON cols.colid = ixc.colid - AND cols.id = ix.id - WHERE ix.id = object_id('{$table_name}') - AND cols.name = '{$column_name}'"; + case 'mysql_40': + case 'mysql_41': + case 'postgres': + case 'sqlite': + case 'sqlite3': + // Not supported + throw new \Exception('DBMS is not supported'); + break; } - else + + $sql = ''; + $existing_indexes = array(); + + switch ($this->sql_layer) { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name - FROM sys.indexes ix - INNER JOIN sys.index_columns ixc - ON ixc.object_id = ix.object_id - AND ixc.index_id = ix.index_id - INNER JOIN sys.columns cols - ON cols.column_id = ixc.column_id - AND cols.object_id = ix.object_id - WHERE ix.object_id = object_id('{$table_name}') - AND cols.name = '{$column_name}'"; + case 'mssql': + case 'mssqlnative': + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND cols.name = '{$column_name}' + AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique) ? '1' : '0'; + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND cols.name = '{$column_name}' + AND ix.is_unique = " . ($unique) ? '1' : '0'; + } + break; + + case 'oracle': + $sql = "SELECT ix.index_name AS phpbb_index_name, ix.uniqueness AS is_unique + FROM all_ind_columns ixc, all_indexes ix + WHERE ix.index_name = ixc.index_name + AND ixc.table_name = '" . strtoupper($table_name) . "' + AND ixc.column_name = '" . strtoupper($column_name) . "'"; + break; } $result = $this->db->sql_query($sql); - $existing_indexes = array(); while ($row = $this->db->sql_fetchrow($result)) { - $existing_indexes[$row['phpbb_index_name']] = array(); + if (!isset($row['is_unique']) || ($unique && $row['is_unique'] == 'UNIQUE') || (!$unique && $row['is_unique'] == 'NONUNIQUE')) + { + $existing_indexes[$row['phpbb_index_name']] = array(); + } } $this->db->sql_freeresult($result); @@ -2539,35 +2685,47 @@ class tools return array(); } - if ($this->mssql_is_sql_server_2000()) - { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name - FROM sysindexes ix - INNER JOIN sysindexkeys ixc - ON ixc.id = ix.id - AND ixc.indid = ix.indid - INNER JOIN syscolumns cols - ON cols.colid = ixc.colid - AND cols.id = ix.id - WHERE ix.id = object_id('{$table_name}') - AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); - } - else + switch ($this->sql_layer) { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name - FROM sys.indexes ix - INNER JOIN sys.index_columns ixc - ON ixc.object_id = ix.object_id - AND ixc.index_id = ix.index_id - INNER JOIN sys.columns cols - ON cols.column_id = ixc.column_id - AND cols.object_id = ix.object_id - WHERE ix.object_id = object_id('{$table_name}') - AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + case 'mssql': + case 'mssqlnative': + if ($this->mssql_is_sql_server_2000()) + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + break; + + case 'oracle': + $sql = "SELECT index_name AS phpbb_index_name, column_name AS phpbb_column_name + FROM all_ind_columns + WHERE table_name = '" . strtoupper($table_name) . "' + AND " . $this->db->sql_in_set('index_name', array_keys($existing_indexes)); + break; } $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) { $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index ab10073013..553b723cc8 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -175,7 +175,7 @@ class container_builder $this->container->compile(); } - if ($this->dump_container && !defined('DEBUG')) + if ($this->dump_container && !defined('DEBUG_CONTAINER')) { $this->dump_container($container_filename); } diff --git a/phpBB/phpbb/event/kernel_request_subscriber.php b/phpBB/phpbb/event/kernel_request_subscriber.php index 323dabb84c..ee9f29a59d 100644 --- a/phpBB/phpbb/event/kernel_request_subscriber.php +++ b/phpBB/phpbb/event/kernel_request_subscriber.php @@ -28,7 +28,7 @@ class kernel_request_subscriber implements EventSubscriberInterface protected $manager; /** - * PHP extension + * PHP file extension * @var string */ protected $php_ext; @@ -44,7 +44,7 @@ class kernel_request_subscriber implements EventSubscriberInterface * * @param \phpbb\extension\manager $manager Extension manager object * @param string $root_path Root path - * @param string $php_ext PHP extension + * @param string $php_ext PHP file extension */ public function __construct(\phpbb\extension\manager $manager, $root_path, $php_ext) { diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index cbbd7bc622..288fb7d19c 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -40,6 +40,7 @@ class base implements \phpbb\extension\extension_interface * * @param ContainerInterface $container Container object * @param \phpbb\finder $extension_finder + * @param \phpbb\db\migrator $migrator * @param string $extension_name Name of this extension (from ext.manager) * @param string $extension_path Relative path to this extension */ @@ -54,6 +55,14 @@ class base implements \phpbb\extension\extension_interface } /** + * {@inheritdoc} + */ + public function is_enableable() + { + return true; + } + + /** * Single enable step that installs any included migrations * * @param mixed $old_state State returned by previous call of this method diff --git a/phpBB/phpbb/extension/extension_interface.php b/phpBB/phpbb/extension/extension_interface.php index cc8b8be980..6a6b6adb8f 100644 --- a/phpBB/phpbb/extension/extension_interface.php +++ b/phpBB/phpbb/extension/extension_interface.php @@ -20,6 +20,13 @@ namespace phpbb\extension; interface extension_interface { /** + * Indicate whether or not the extension can be enabled. + * + * @return bool + */ + public function is_enableable(); + + /** * enable_step is executed on enabling an extension until it returns false. * * Calls to this function can be made in subsequent requests, when the diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index b19eb9f8a3..76f0e3558e 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -77,11 +77,12 @@ class manager { $this->extensions = array(); - // Do not try to load any extensions when installing or updating + // Do not try to load any extensions if the extension table + // does not exist or when installing or updating. // Note: database updater invokes this code, and in 3.0 // there is no extension table therefore the rest of this function // fails - if (defined('IN_INSTALL')) + if (defined('IN_INSTALL') || version_compare($this->config['version'], '3.1.0-dev', '<')) { return; } @@ -177,6 +178,12 @@ class manager $old_state = (isset($this->extensions[$name]['ext_state'])) ? unserialize($this->extensions[$name]['ext_state']) : false; $extension = $this->get_extension($name); + + if (!$extension->is_enableable()) + { + return false; + } + $state = $extension->enable_step($old_state); $active = ($state === false); diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index 1051021ea7..edca8ee1af 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -330,27 +330,6 @@ class metadata_manager } /** - * Version validation helper - * - * @param string $string The string for comparing to a version - * @param string $current_version The version to compare to - * @return bool True/False if meets version requirements - */ - private function _validate_version($string, $current_version) - { - // Allow them to specify their own comparison operator (ex: <3.1.2, >=3.1.0) - $comparison_matches = false; - preg_match('#[=<>]+#', $string, $comparison_matches); - - if (!empty($comparison_matches)) - { - return version_compare($current_version, str_replace(array($comparison_matches[0], ' '), '', $string), $comparison_matches[0]); - } - - return version_compare($current_version, $string, '>='); - } - - /** * Outputs the metadata into the template * * @return null diff --git a/phpBB/phpbb/feed/helper.php b/phpBB/phpbb/feed/helper.php index 9741b752af..198134cdcf 100644 --- a/phpBB/phpbb/feed/helper.php +++ b/phpBB/phpbb/feed/helper.php @@ -36,7 +36,7 @@ class helper * @param \phpbb\config\config $config Config object * @param \phpbb\user $user User object * @param string $phpbb_root_path Root path - * @param string $phpEx PHP extension + * @param string $phpEx PHP file extension */ public function __construct(\phpbb\config\config $config, \phpbb\user $user, $phpbb_root_path, $phpEx) { diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php index c522c3273f..2af8b50b54 100644 --- a/phpBB/phpbb/log/log.php +++ b/phpBB/phpbb/log/log.php @@ -245,9 +245,9 @@ class log implements \phpbb\log\log_interface break; case 'mod': - $forum_id = (int) $additional_data['forum_id']; + $forum_id = isset($additional_data['forum_id']) ? (int) $additional_data['forum_id'] : 0; unset($additional_data['forum_id']); - $topic_id = (int) $additional_data['topic_id']; + $topic_id = isset($additional_data['topic_id']) ? (int) $additional_data['topic_id'] : 0; unset($additional_data['topic_id']); $sql_ary += array( 'log_type' => LOG_MOD, diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index 9c83e8dd73..f3ad7f5f41 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -20,7 +20,7 @@ class content_guesser extends guesser_base */ public function is_supported() { - return function_exists('mime_content_type'); + return function_exists('mime_content_type') && is_callable('mime_content_type'); } /** diff --git a/phpBB/phpbb/mimetype/guesser.php b/phpBB/phpbb/mimetype/guesser.php index 87b164b561..773a1f822a 100644 --- a/phpBB/phpbb/mimetype/guesser.php +++ b/phpBB/phpbb/mimetype/guesser.php @@ -99,6 +99,7 @@ class guesser * Guess mimetype of supplied file * * @param string $file Path to file + * @param string $file_name The real file name * * @return string Guess for mimetype of file */ diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index 74ef980445..5e4bab1530 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -68,12 +68,14 @@ class manager * @param \phpbb\user_loader $user_loader * @param \phpbb\config\config $config * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\cache\service $cache * @param \phpbb\user $user * @param string $phpbb_root_path * @param string $php_ext * @param string $notification_types_table * @param string $notifications_table * @param string $user_notifications_table + * * @return \phpbb\notification\manager */ public function __construct($notification_types, $notification_methods, ContainerInterface $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\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) @@ -832,7 +834,7 @@ class manager * Delete all notifications older than a certain time * * @param int $timestamp Unix timestamp to delete all notifications that were created before - * @param bool $only_unread True (default) to only prune read notifications + * @param bool $only_read True (default) to only prune read notifications */ public function prune_notifications($timestamp, $only_read = true) { diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php index a6735dc793..22c9076adc 100644 --- a/phpBB/phpbb/notification/type/approve_post.php +++ b/phpBB/phpbb/notification/type/approve_post.php @@ -67,7 +67,8 @@ class approve_post extends \phpbb\notification\type\post /** * Find the users who want to receive notifications * - * @param array $post Data from + * @param array $post Data from submit_post + * @param array $options Options for finding users for notification * * @return array */ @@ -80,14 +81,7 @@ class approve_post extends \phpbb\notification\type\post $users = array(); $users[$post['poster_id']] = array(''); - $auth_read = $this->auth->acl_get_list(array_keys($users), 'f_read', $post['forum_id']); - - if (empty($auth_read)) - { - return array(); - } - - return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array( + return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array( 'item_type' => self::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php index 459a0ec348..77e53a0064 100644 --- a/phpBB/phpbb/notification/type/approve_topic.php +++ b/phpBB/phpbb/notification/type/approve_topic.php @@ -67,7 +67,8 @@ class approve_topic extends \phpbb\notification\type\topic /** * Find the users who want to receive notifications * - * @param array $post Data from + * @param array $post Data from submit_post + * @param array $options Options for finding users for notification * * @return array */ @@ -80,14 +81,7 @@ class approve_topic extends \phpbb\notification\type\topic $users = array(); $users[$post['poster_id']] = array(''); - $auth_read = $this->auth->acl_get_list(array_keys($users), 'f_read', $post['forum_id']); - - if (empty($auth_read)) - { - return array(); - } - - return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array( + return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array( 'item_type' => self::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index 910f51b3a6..4ead06071e 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -161,6 +161,8 @@ abstract class base implements \phpbb\notification\type\type_interface * Magic method to set data on this notification * * @param mixed $name + * @param mixed $value + * * @return null */ public function __set($name, $value) @@ -174,7 +176,6 @@ abstract class base implements \phpbb\notification\type\type_interface * * Primarily for testing * - * @param string $name * @return mixed */ public function __toString() @@ -532,4 +533,37 @@ abstract class base implements \phpbb\notification\type\type_interface WHERE ' . $where; $this->db->sql_query($sql); } + + /** + * Get a list of users that are authorised to receive notifications + * + * @param array $users Array of users that have subscribed to a notification + * @param int $forum_id Forum ID of the forum + * @param array $options Array of notification options + * @param bool $sort Whether the users array should be sorted. Default: false + * @return array Array of users that are authorised recipients + */ + protected function get_authorised_recipients($users, $forum_id, $options, $sort = false) + { + if (empty($users)) + { + return array(); + } + + $users = array_unique($users); + + if ($sort) + { + sort($users); + } + + $auth_read = $this->auth->acl_get_list($users, 'f_read', $forum_id); + + if (empty($auth_read)) + { + return array(); + } + + return $this->check_user_notification_options($auth_read[$forum_id]['f_read'], $options); + } } diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php index f4870e8a52..21180b3b53 100644 --- a/phpBB/phpbb/notification/type/bookmark.php +++ b/phpBB/phpbb/notification/type/bookmark.php @@ -59,7 +59,8 @@ class bookmark extends \phpbb\notification\type\post /** * Find the users who want to receive notifications * - * @param array $post Data from + * @param array $post Data from submit_post + * @param array $options Options for finding users for notification * * @return array */ @@ -82,21 +83,13 @@ class bookmark extends \phpbb\notification\type\post } $this->db->sql_freeresult($result); - if (empty($users)) - { - return array(); - } - sort($users); + $notify_users = $this->get_authorised_recipients($users, $post['forum_id'], $options, true); - $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']); - - if (empty($auth_read)) + if (empty($notify_users)) { return array(); } - $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options); - // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications $update_notifications = array(); $sql = 'SELECT n.* diff --git a/phpBB/phpbb/notification/type/pm.php b/phpBB/phpbb/notification/type/pm.php index 4f54e93e06..8445ca4b22 100644 --- a/phpBB/phpbb/notification/type/pm.php +++ b/phpBB/phpbb/notification/type/pm.php @@ -72,7 +72,8 @@ class pm extends \phpbb\notification\type\base /** * Find the users who want to receive notifications * - * @param array $pm Data from + * @param array $pm Data from submit_pm + * @param array $options Options for finding users for notification * * @return array */ @@ -178,7 +179,7 @@ class pm extends \phpbb\notification\type\base * Function for preparing the data for insertion in an SQL query * (The service handles insertion) * - * @param array $post Data from submit_post + * @param array $pm Data from submit_post * @param array $pre_create_data Data from pre_create_insert_array() * * @return array Array of data ready to be inserted into the database diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index ee3a253e0f..1eba4a6a88 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -86,7 +86,8 @@ class post extends \phpbb\notification\type\base /** * Find the users who want to receive notifications * - * @param array $post Data from + * @param array $post Data from submit_post + * @param array $options Options for finding users for notification * * @return array */ @@ -122,23 +123,13 @@ class post extends \phpbb\notification\type\base } $this->db->sql_freeresult($result); - if (empty($users)) - { - return array(); - } + $notify_users = $this->get_authorised_recipients($users, $post['forum_id'], $options, true); - $users = array_unique($users); - sort($users); - - $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']); - - if (empty($auth_read)) + if (empty($notify_users)) { return array(); } - $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options); - // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications $update_notifications = array(); $sql = 'SELECT n.* diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php index b893ad0d15..3bb1028619 100644 --- a/phpBB/phpbb/notification/type/post_in_queue.php +++ b/phpBB/phpbb/notification/type/post_in_queue.php @@ -70,6 +70,7 @@ class post_in_queue extends \phpbb\notification\type\post * Find the users who want to receive notifications * * @param array $post Data from the post + * @param array $options Options for finding users for notification * * @return array */ diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 7c61b76b58..5c3c822ec2 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -66,7 +66,8 @@ class quote extends \phpbb\notification\type\post /** * Find the users who want to receive notifications * - * @param array $post Data from + * @param array $post Data from submit_post + * @param array $options Options for finding users for notification * * @return array */ @@ -101,28 +102,13 @@ class quote extends \phpbb\notification\type\post } $this->db->sql_freeresult($result); - if (empty($users)) - { - return array(); - } - sort($users); - - $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']); - - if (empty($auth_read)) - { - return array(); - } - - $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options); - - return $notify_users; + return $this->get_authorised_recipients($users, $post['forum_id'], $options, true); } /** * Update a notification * - * @param array $data Data specific for this type that will be updated + * @param array $post Data specific for this type that will be updated */ public function update_notifications($post) { diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php index 2eb802eb4b..14a328e104 100644 --- a/phpBB/phpbb/notification/type/report_pm.php +++ b/phpBB/phpbb/notification/type/report_pm.php @@ -94,6 +94,7 @@ class report_pm extends \phpbb\notification\type\pm * (copied from post_in_queue) * * @param array $post Data from the post + * @param array $options Options for finding users for notification * * @return array */ diff --git a/phpBB/phpbb/notification/type/report_pm_closed.php b/phpBB/phpbb/notification/type/report_pm_closed.php index ed40df67f3..de7bf74a97 100644 --- a/phpBB/phpbb/notification/type/report_pm_closed.php +++ b/phpBB/phpbb/notification/type/report_pm_closed.php @@ -52,7 +52,8 @@ class report_pm_closed extends \phpbb\notification\type\pm /** * Find the users who want to receive notifications * - * @param array $pm Data from + * @param array $pm Data from submit_pm + * @param array $options Options for finding users for notification * * @return array */ diff --git a/phpBB/phpbb/notification/type/report_post.php b/phpBB/phpbb/notification/type/report_post.php index 024c8d9d42..bec59df9d5 100644 --- a/phpBB/phpbb/notification/type/report_post.php +++ b/phpBB/phpbb/notification/type/report_post.php @@ -76,6 +76,7 @@ class report_post extends \phpbb\notification\type\post_in_queue * Find the users who want to receive notifications * * @param array $post Data from the post + * @param array $options Options for finding users for notification * * @return array */ diff --git a/phpBB/phpbb/notification/type/report_post_closed.php b/phpBB/phpbb/notification/type/report_post_closed.php index a979af1fb0..cd1400f8fa 100644 --- a/phpBB/phpbb/notification/type/report_post_closed.php +++ b/phpBB/phpbb/notification/type/report_post_closed.php @@ -59,7 +59,8 @@ class report_post_closed extends \phpbb\notification\type\post /** * Find the users who want to receive notifications * - * @param array $post Data from + * @param array $post Data from submit_post + * @param array $options Options for finding users for notification * * @return array */ diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php index a512a12f20..af199fb765 100644 --- a/phpBB/phpbb/notification/type/topic.php +++ b/phpBB/phpbb/notification/type/topic.php @@ -87,6 +87,7 @@ class topic extends \phpbb\notification\type\base * Find the users who want to receive notifications * * @param array $topic Data from the topic + * @param array $options Options for finding users for notification * * @return array */ @@ -110,19 +111,7 @@ class topic extends \phpbb\notification\type\base } $this->db->sql_freeresult($result); - if (empty($users)) - { - return array(); - } - - $auth_read = $this->auth->acl_get_list($users, 'f_read', $topic['forum_id']); - - if (empty($auth_read)) - { - return array(); - } - - return $this->check_user_notification_options($auth_read[$topic['forum_id']]['f_read'], $options); + return $this->get_authorised_recipients($users, $topic['forum_id'], $options); } /** diff --git a/phpBB/phpbb/notification/type/topic_in_queue.php b/phpBB/phpbb/notification/type/topic_in_queue.php index 2d54a68648..aef1487d77 100644 --- a/phpBB/phpbb/notification/type/topic_in_queue.php +++ b/phpBB/phpbb/notification/type/topic_in_queue.php @@ -70,6 +70,7 @@ class topic_in_queue extends \phpbb\notification\type\topic * Find the users who want to receive notifications * * @param array $topic Data from the topic + * @param array $options Options for finding users for notification * * @return array */ diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php index a8592eac6c..38dbbab51e 100644 --- a/phpBB/phpbb/path_helper.php +++ b/phpBB/phpbb/path_helper.php @@ -46,7 +46,7 @@ class path_helper * @param \phpbb\filesystem $filesystem * @param \phpbb\request\request_interface $request * @param string $phpbb_root_path Relative path to phpBB root - * @param string $php_ext PHP extension (php) + * @param string $php_ext PHP file extension * @param mixed $adm_relative_path Relative path admin path to adm/ root */ public function __construct(\phpbb\symfony_request $symfony_request, \phpbb\filesystem $filesystem, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext, $adm_relative_path = null) diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index c610d49a63..3c686a552f 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -79,8 +79,7 @@ class plupload $this->php_ini = $php_ini; $this->mimetype_guesser = $mimetype_guesser; - $this->upload_directory = $this->phpbb_root_path . $this->config['upload_path']; - $this->temporary_directory = $this->upload_directory . '/plupload'; + $this->set_default_directories(); } /** @@ -120,6 +119,9 @@ class plupload { rename("{$file_path}.part", $file_path); + // Reset upload directories to defaults once completed + $this->set_default_directories(); + // Need to modify some of the $_FILES values to reflect the new file return array( 'tmp_name' => $file_path, @@ -372,4 +374,29 @@ class plupload ); } } + + /** + * Sets the default directories for uploads + * + * @return null + */ + protected function set_default_directories() + { + $this->upload_directory = $this->phpbb_root_path . $this->config['upload_path']; + $this->temporary_directory = $this->upload_directory . '/plupload'; + } + + /** + * Sets the upload directories to the specified paths + * + * @param string $upload_directory Upload directory + * @param string $temporary_directory Temporary directory + * + * @return null + */ + public function set_upload_directories($upload_directory, $temporary_directory) + { + $this->upload_directory = $upload_directory; + $this->temporary_directory = $temporary_directory; + } } diff --git a/phpBB/phpbb/profilefields/manager.php b/phpBB/phpbb/profilefields/manager.php index f3b1676799..98802d2209 100644 --- a/phpBB/phpbb/profilefields/manager.php +++ b/phpBB/phpbb/profilefields/manager.php @@ -397,7 +397,7 @@ class manager } $field_desc = $contact_url = ''; - if ($use_contact_fields) + if ($use_contact_fields && $ident_ary['data']['field_is_contact']) { $value = $profile_field->get_profile_contact_value($ident_ary['value'], $ident_ary['data']); $field_desc = $this->user->lang($ident_ary['data']['field_contact_desc']); diff --git a/phpBB/phpbb/profilefields/type/type_googleplus.php b/phpBB/phpbb/profilefields/type/type_googleplus.php index df1bcc7f4b..e6729b1935 100644 --- a/phpBB/phpbb/profilefields/type/type_googleplus.php +++ b/phpBB/phpbb/profilefields/type/type_googleplus.php @@ -18,6 +18,14 @@ class type_googleplus extends type_string /** * {@inheritDoc} */ + public function get_name() + { + return $this->user->lang('FIELD_GOOGLEPLUS'); + } + + /** + * {@inheritDoc} + */ public function get_service_name() { return 'profilefields.type.googleplus'; @@ -32,7 +40,7 @@ class type_googleplus extends type_string 'field_length' => 20, 'field_minlen' => 3, 'field_maxlen' => 255, - 'field_validation' => '[\w]+', + 'field_validation' => '(?:(?!\.{2,})([^<>=+]))+', 'field_novalue' => '', 'field_default_value' => '', ); diff --git a/phpBB/phpbb/profilefields/type/type_interface.php b/phpBB/phpbb/profilefields/type/type_interface.php index 2dd13fa480..ec770f9467 100644 --- a/phpBB/phpbb/profilefields/type/type_interface.php +++ b/phpBB/phpbb/profilefields/type/type_interface.php @@ -189,8 +189,8 @@ interface type_interface /** * Allows manipulating the intended variables if needed * - * @param string $key Name of the option * @param int $step Step on which the option is hidden + * @param string $key Name of the option * @param string $action Currently performed action (create|edit) * @param array $field_data Array with data for this field * @return mixed Final value of the option diff --git a/phpBB/phpbb/profilefields/type/type_string_common.php b/phpBB/phpbb/profilefields/type/type_string_common.php index c2b951b6c9..0eaf7e527d 100644 --- a/phpBB/phpbb/profilefields/type/type_string_common.php +++ b/phpBB/phpbb/profilefields/type/type_string_common.php @@ -98,7 +98,7 @@ abstract class type_string_common extends type_base */ public function get_profile_value($field_value, $field_data) { - if (!$field_value && !$field_data['field_show_novalue']) + if (($field_value === null || $field_value === '') && !$field_data['field_show_novalue']) { return null; } @@ -114,7 +114,7 @@ abstract class type_string_common extends type_base */ public function get_profile_value_raw($field_value, $field_data) { - if (!$field_value && !$field_data['field_show_novalue']) + if (($field_value === null || $field_value === '') && !$field_data['field_show_novalue']) { return null; } @@ -127,12 +127,7 @@ abstract class type_string_common extends type_base */ public function get_profile_contact_value($field_value, $field_data) { - if (!$field_value && !$field_data['field_show_novalue']) - { - return null; - } - - return $field_value; + return $this->get_profile_value_raw($field_value, $field_data); } /** diff --git a/phpBB/phpbb/search/base.php b/phpBB/phpbb/search/base.php index 9395b6a273..30781975d8 100644 --- a/phpBB/phpbb/search/base.php +++ b/phpBB/phpbb/search/base.php @@ -85,8 +85,12 @@ class base /** * Retrieves cached search results * - * @param int &$result_count will contain the number of all results for the search (not only for the current page) - * @param array &$id_ary is filled with the ids belonging to the requested page that are stored in the cache + * @param string $search_key an md5 string generated from all the passed search options to identify the results + * @param int &$result_count will contain the number of all results for the search (not only for the current page) + * @param array &$id_ary is filled with the ids belonging to the requested page that are stored in the cache + * @param int &$start indicates the first index of the page + * @param int $per_page number of ids each page is supposed to contain + * @param string $sort_dir is either a or d representing ASC and DESC * * @return int SEARCH_RESULT_NOT_IN_CACHE or SEARCH_RESULT_IN_CACHE or SEARCH_RESULT_INCOMPLETE */ @@ -160,8 +164,16 @@ class base /** * Caches post/topic ids * - * @param array &$id_ary contains a list of post or topic ids that shall be cached, the first element + * @param string $search_key an md5 string generated from all the passed search options to identify the results + * @param string $keywords contains the keywords as entered by the user + * @param array $author_ary an array of author ids, if the author should be ignored during the search the array is empty + * @param int $result_count contains the number of all results for the search (not only for the current page) + * @param array &$id_ary contains a list of post or topic ids that shall be cached, the first element * must have the absolute index $start in the result set. + * @param int $start indicates the first index of the page + * @param string $sort_dir is either a or d representing ASC and DESC + * + * @return null */ function save_ids($search_key, $keywords, $author_ary, $result_count, &$id_ary, $start, $sort_dir) { diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index d4e7de31e5..1a0aba096f 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -73,6 +73,12 @@ class fulltext_mysql extends \phpbb\search\base * Creates a new \phpbb\search\fulltext_mysql, which is used as a search backend * * @param string|bool $error Any error that occurs is passed on through this reference variable otherwise false + * @param string $phpbb_root_path Relative path to phpBB root + * @param string $phpEx PHP file extension + * @param \phpbb\auth\auth $auth Auth object + * @param \phpbb\config\config $config Config object + * @param \phpbb\db\driver\driver_interface Database object + * @param \phpbb\user $user User object */ public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user) { diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php index b3e7f51f87..b6af371d13 100644 --- a/phpBB/phpbb/search/fulltext_postgres.php +++ b/phpBB/phpbb/search/fulltext_postgres.php @@ -86,6 +86,12 @@ class fulltext_postgres extends \phpbb\search\base * Creates a new \phpbb\search\fulltext_postgres, which is used as a search backend * * @param string|bool $error Any error that occurs is passed on through this reference variable otherwise false + * @param string $phpbb_root_path Relative path to phpBB root + * @param string $phpEx PHP file extension + * @param \phpbb\auth\auth $auth Auth object + * @param \phpbb\config\config $config Config object + * @param \phpbb\db\driver\driver_interface Database object + * @param \phpbb\user $user User object */ public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user) { diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index 78c11f1180..79d68d2ae1 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -119,6 +119,12 @@ class fulltext_sphinx * Creates a new \phpbb\search\fulltext_postgres, which is used as a search backend * * @param string|bool $error Any error that occurs is passed on through this reference variable otherwise false + * @param string $phpbb_root_path Relative path to phpBB root + * @param string $phpEx PHP file extension + * @param \phpbb\auth\auth $auth Auth object + * @param \phpbb\config\config $config Config object + * @param \phpbb\db\driver\driver_interface Database object + * @param \phpbb\user $user User object */ public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user) { diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 59b7ec2029..5a0d7c0031 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -1062,11 +1062,13 @@ class session * Check for banned user * * Checks whether the supplied user is banned by id, ip or email. If no parameters - * are passed to the method pre-existing session data is used. If $return is false - * this routine does not return on finding a banned user, it outputs a relevant - * message and stops execution. + * are passed to the method pre-existing session data is used. * - * @param string|array $user_ips Can contain a string with one IP or an array of multiple IPs + * @param int|false $user_id The user id + * @param mixed $user_ips Can contain a string with one IP or an array of multiple IPs + * @param string|false $user_email The user email + * @param bool $return If $return is false this routine does not return on finding a banned user, + * it outputs a relevant message and stops execution. */ function check_ban($user_id = false, $user_ips = false, $user_email = false, $return = false) { @@ -1254,12 +1256,14 @@ class session /** * Check if ip is blacklisted - * This should be called only where absolutly necessary + * This should be called only where absolutely necessary * * Only IPv4 (rbldns does not support AAAA records/IPv6 lookups) * * @author satmd (from the php manual) - * @param string $mode register/post - spamcop for example is ommitted for posting + * @param string $mode register/post - spamcop for example is ommitted for posting + * @param string|false $ip the IPv4 address to check + * * @return false if ip is not blacklisted, else an array([checked server], [lookup]) */ function check_dnsbl($mode, $ip = false) diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php index 5a01ee3a93..67dbd7b357 100644 --- a/phpBB/phpbb/template/asset.php +++ b/phpBB/phpbb/template/asset.php @@ -24,6 +24,7 @@ class asset * Constructor * * @param string $url URL + * @param \phpbb\path_helper $path_helper Path helper object */ public function __construct($url, \phpbb\path_helper $path_helper) { diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 0a32879943..4ee48205c8 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -34,6 +34,11 @@ class context */ private $rootref; + /** + * @var bool + */ + private $num_rows_is_set; + public function __construct() { $this->clear(); @@ -46,6 +51,7 @@ class context { $this->tpldata = array('.' => array(0 => array())); $this->rootref = &$this->tpldata['.'][0]; + $this->num_rows_is_set = false; } /** @@ -95,10 +101,59 @@ class context // returning a reference directly is not // something php is capable of doing $ref = &$this->tpldata; + + if (!$this->num_rows_is_set) + { + /* + * We do not set S_NUM_ROWS while adding a row, to reduce the complexity + * If we would set it on adding, each subsequent adding would cause + * n modifications, resulting in a O(n!) complexity, rather then O(n) + */ + foreach ($ref as $loop_name => &$loop_data) + { + if ($loop_name === '.') + { + continue; + } + + $this->set_num_rows($loop_data); + } + $this->num_rows_is_set = true; + } + return $ref; } /** + * Set S_NUM_ROWS for each row in this template block + * + * @param array $loop_data + */ + protected function set_num_rows(&$loop_data) + { + $s_num_rows = sizeof($loop_data); + foreach ($loop_data as &$mod_block) + { + foreach ($mod_block as $sub_block_name => &$sub_block) + { + // If the key name is lowercase and the data is an array, + // it could be a template loop. So we set the S_NUM_ROWS there + // aswell. + if ($sub_block_name === strtolower($sub_block_name) && is_array($sub_block)) + { + $this->set_num_rows($sub_block); + } + } + + // Check whether we are inside a block before setting the variable + if (isset($mod_block['S_BLOCK_NAME'])) + { + $mod_block['S_NUM_ROWS'] = $s_num_rows; + } + } + } + + /** * Returns a reference to template root scope. * * This function is public so that template renderer may invoke it. @@ -123,6 +178,7 @@ class context */ public function assign_block_vars($blockname, array $vararray) { + $this->num_rows_is_set = false; if (strpos($blockname, '.') !== false) { // Nested block. @@ -160,13 +216,6 @@ class context // We're adding a new iteration to this block with the given // variable assignments. $str[$blocks[$blockcount]][] = $vararray; - $s_num_rows = sizeof($str[$blocks[$blockcount]]); - - // Set S_NUM_ROWS - foreach ($str[$blocks[$blockcount]] as &$mod_block) - { - $mod_block['S_NUM_ROWS'] = $s_num_rows; - } } else { @@ -192,13 +241,6 @@ class context // Add a new iteration to this block with the variable assignments we were given. $this->tpldata[$blockname][] = $vararray; - $s_num_rows = sizeof($this->tpldata[$blockname]); - - // Set S_NUM_ROWS - foreach ($this->tpldata[$blockname] as &$mod_block) - { - $mod_block['S_NUM_ROWS'] = $s_num_rows; - } } return true; @@ -250,6 +292,7 @@ class context */ public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') { + $this->num_rows_is_set = false; if (strpos($blockname, '.') !== false) { // Nested block. @@ -349,12 +392,6 @@ class context $block[$key] = $vararray; $block[$key]['S_ROW_COUNT'] = $block[$key]['S_ROW_NUM'] = $key; - // Set S_NUM_ROWS - foreach ($this->tpldata[$blockname] as &$mod_block) - { - $mod_block['S_NUM_ROWS'] = sizeof($this->tpldata[$blockname]); - } - return true; } @@ -382,6 +419,7 @@ class context */ public function destroy_block_vars($blockname) { + $this->num_rows_is_set = false; if (strpos($blockname, '.') !== false) { // Nested block. diff --git a/phpBB/phpbb/template/twig/definition.php b/phpBB/phpbb/template/twig/definition.php index 39653f6d26..cb3c953692 100644 --- a/phpBB/phpbb/template/twig/definition.php +++ b/phpBB/phpbb/template/twig/definition.php @@ -25,6 +25,8 @@ class definition * Get a DEFINE'd variable * * @param string $name + * @param array $arguments + * * @return mixed Null if not found */ public function __call($name, $arguments) diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 8d25153e14..476ffd935e 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -36,11 +36,10 @@ class environment extends \Twig_Environment /** * Constructor * - * @param \phpbb\config\config $phpbb_config - * @param \phpbb\path_helper - * @param \phpbb\extension\manager - * @param string $phpbb_root_path - * @param \Twig_LoaderInterface $loader + * @param \phpbb\config\config $phpbb_config The phpBB configuration + * @param \phpbb\path_helper $path_helper phpBB path helper + * @param \phpbb\extension\manager $extension_manager phpBB extension manager + * @param \Twig_LoaderInterface $loader Twig loader interface * @param array $options Array of options to pass to Twig */ public function __construct($phpbb_config, \phpbb\path_helper $path_helper, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array()) diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index 8f523684dd..3a983491b9 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -162,7 +162,6 @@ class extension extends \Twig_Extension * (e.g. in the ACP, L_TITLE) * If not, we return the result of $user->lang() * - * @param string $lang name * @return string */ function lang() diff --git a/phpBB/phpbb/tree/tree_interface.php b/phpBB/phpbb/tree/tree_interface.php index 8238a072ff..5df01a89cf 100644 --- a/phpBB/phpbb/tree/tree_interface.php +++ b/phpBB/phpbb/tree/tree_interface.php @@ -18,7 +18,7 @@ interface tree_interface /** * Inserts an item into the database table and into the tree. * - * @param array $item The item to be added + * @param array $additional_data The item to be added * @return array Array with item data as set in the database */ public function insert(array $additional_data); diff --git a/phpBB/posting.php b/phpBB/posting.php index 70df052099..6638caa94b 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -523,7 +523,9 @@ $orig_poll_options_size = sizeof($post_data['poll_options']); $message_parser = new parse_message(); $plupload = $phpbb_container->get('plupload'); +$mimetype_guesser = $phpbb_container->get('mimetype.guesser'); $message_parser->set_plupload($plupload); +$message_parser->set_mimetype_guesser($mimetype_guesser); if (isset($post_data['post_text'])) { diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 70bc703582..63efe5f8ae 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -2,17 +2,6 @@ "use strict"; -/** -* Close popup alert after a specified delay -* -* @param int Delay in ms until darkenwrapper's click event is triggered -*/ -phpbb.closeDarkenWrapper = function(delay) { - phpbbAlertTimer = setTimeout(function() { - $('#darkenwrapper').trigger('click'); - }, delay); -}; - // This callback will mark all forum icons read phpbb.addAjaxCallback('mark_forums_read', function(res) { var readTitle = res.NO_UNREAD_POSTS; @@ -145,6 +134,11 @@ phpbb.markNotifications = function(el, unreadCount) { if (!unreadCount) { $('#mark_all_notifications').remove(); } + + // Update page title + $('title').text( + (unreadCount ? '(' + unreadCount + ')' : '') + $('title').text().replace(/(\(([0-9])\))/, '') + ); }; // This callback finds the post from the delete link, and removes it. diff --git a/phpBB/styles/prosilver/template/mcp_ban.html b/phpBB/styles/prosilver/template/mcp_ban.html index 591dbf8076..5a7eaa7840 100644 --- a/phpBB/styles/prosilver/template/mcp_ban.html +++ b/phpBB/styles/prosilver/template/mcp_ban.html @@ -5,27 +5,34 @@ var ban_length = new Array(); ban_length[-1] = ''; - <!-- BEGIN ban_length --> - ban_length['{ban_length.BAN_ID}'] = '{ban_length.A_LENGTH}'; - <!-- END ban_length --> - var ban_reason = new Array(); ban_reason[-1] = ''; - <!-- BEGIN ban_reason --> - ban_reason['{ban_reason.BAN_ID}'] = '{ban_reason.A_REASON}'; - <!-- END ban_reason --> - var ban_give_reason = new Array(); ban_give_reason[-1] = ''; - <!-- BEGIN ban_give_reason --> - ban_give_reason['{ban_give_reason.BAN_ID}'] = '{ban_give_reason.A_REASON}'; - <!-- END ban_give_reason --> + + <!-- BEGIN bans --> + ban_length['{bans.BAN_ID}'] = '{bans.A_LENGTH}'; + <!-- IF bans.A_REASON --> + ban_reason['{bans.BAN_ID}'] = '{bans.A_REASON}'; + <!-- ENDIF --> + <!-- IF bans.A_GIVE_REASON --> + ban_give_reason['{bans.BAN_ID}'] = '{bans.A_GIVE_REASON}'; + <!-- ENDIF --> + <!-- END bans --> function display_details(option) { - document.getElementById('unbangivereason').innerHTML = ban_give_reason[option]; - document.getElementById('unbanreason').innerHTML = ban_reason[option]; document.getElementById('unbanlength').innerHTML = ban_length[option]; + if (option in ban_reason) { + document.getElementById('unbanreason').innerHTML = ban_reason[option]; + } else { + document.getElementById('unbanreason').innerHTML = ''; + } + if (option in ban_give_reason) { + document.getElementById('unbangivereason').innerHTML = ban_give_reason[option]; + } else { + document.getElementById('unbangivereason').innerHTML = ''; + } } // ]]> @@ -42,6 +49,7 @@ <p>{L_EXPLAIN}</p> <fieldset> + <!-- EVENT mcp_ban_fields_before --> <dl> <dt><label for="ban">{L_BAN_CELL}{L_COLON}</label></dt> <dd><label for="ban"><textarea name="ban" id="ban" class="inputbox" cols="40" rows="3">{BAN_QUANTIFIER}</textarea></label></dd> @@ -70,6 +78,7 @@ <label for="banexclude0"><input type="radio" name="banexclude" id="banexclude0" value="0" checked="checked" /> {L_NO}</label> </dd> </dl> + <!-- EVENT mcp_ban_fields_after --> </fieldset> </div> @@ -89,6 +98,7 @@ <!-- IF S_BANNED_OPTIONS --> <fieldset> + <!-- EVENT mcp_ban_unban_before --> <dl> <dt><label for="unban">{L_BAN_CELL}{L_COLON}</label></dt> <dd><select name="unban[]" id="unban" multiple="multiple" size="5" onchange="if (this.selectedIndex != -1) {display_details(this.options[this.selectedIndex].value);}">{BANNED_OPTIONS}</select></dd> @@ -105,6 +115,7 @@ <dt>{L_BAN_GIVE_REASON}{L_COLON}</dt> <dd><strong id="unbangivereason"></strong></dd> </dl> + <!-- EVENT mcp_ban_unban_after --> </fieldset> </div> diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index 6bf6af1b78..082bea22f1 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -34,7 +34,7 @@ <fieldset id="display-panel" class="fields2" role="tabpanel"> <dl> <dt><label for="posts_per_page">{L_POSTS_PER_PAGE}{L_COLON}</label><br /><span>{L_POSTS_PER_PAGE_EXPLAIN}</span></dt> - <dd><input class="inputbox autowidth" type="number" min="1" name="posts_per_page" id="posts_per_page" size="6" value="{POSTS_PER_PAGE}" /></dd> + <dd><input class="inputbox autowidth" type="number" min="0" name="posts_per_page" id="posts_per_page" size="6" value="{POSTS_PER_PAGE}" /></dd> </dl> <dl> <dt><label>{L_DISPLAY_POSTS}{L_COLON}</label></dt> diff --git a/phpBB/styles/prosilver/template/navbar_footer.html b/phpBB/styles/prosilver/template/navbar_footer.html index 675322c56c..4a9275c898 100644 --- a/phpBB/styles/prosilver/template/navbar_footer.html +++ b/phpBB/styles/prosilver/template/navbar_footer.html @@ -2,8 +2,9 @@ <div class="inner"> <ul id="nav-footer" class="linklist bulletin" role="menubar"> - <li class="small-icon icon-home breadcrumbs" role="navigation"> + <li class="small-icon icon-home breadcrumbs"> <!-- IF U_SITE_HOME --><span class="crumb"><a href="{U_SITE_HOME}" data-navbar-reference="home">{L_SITE_HOME}</a></span><!-- ENDIF --> + <!-- EVENT overall_footer_breadcrumb_prepend --> <span class="crumb"><a href="{U_INDEX}" data-navbar-reference="index">{L_INDEX}</a></span> <!-- EVENT overall_footer_breadcrumb_append --> </li> diff --git a/phpBB/styles/prosilver/template/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html index cb646f25e4..41c5793320 100644 --- a/phpBB/styles/prosilver/template/navbar_header.html +++ b/phpBB/styles/prosilver/template/navbar_header.html @@ -23,6 +23,14 @@ <!-- ENDIF --> <li class="small-icon icon-search-unanswered"><a href="{U_SEARCH_UNANSWERED}" role="menuitem">{L_SEARCH_UNANSWERED}</a></li> <li class="small-icon icon-search-active"><a href="{U_SEARCH_ACTIVE_TOPICS}" role="menuitem">{L_SEARCH_ACTIVE_TOPICS}</a></li> + <li class="separator"></li> + <li class="small-icon icon-search"><a href="{U_SEARCH}" role="menuitem">{L_SEARCH}</a></li> + <!-- ENDIF --> + + <!-- IF not S_IS_BOT and (S_DISPLAY_MEMBERLIST or U_TEAM) --> + <li class="separator"></li> + <!-- IF S_DISPLAY_MEMBERLIST --><li class="small-icon icon-members"><a href="{U_MEMBERLIST}" role="menuitem">{L_MEMBERLIST}</a></li><!-- ENDIF --> + <!-- IF U_TEAM --><li class="small-icon icon-team"><a href="{U_TEAM}" role="menuitem">{L_THE_TEAM}</a></li><!-- ENDIF --> <!-- ENDIF --> <li class="separator"></li> @@ -32,10 +40,10 @@ </li> <!-- EVENT overall_header_navigation_prepend --> - <li class="small-icon icon-faq" <!-- IF not S_USER_LOGGED_IN -->data-skip-responsive="true"<!-- ELSE -->data-last-responsive="true"<!-- ENDIF -->><a href="{U_FAQ}" title="{L_FAQ_EXPLAIN}" role="menuitem">{L_FAQ}</a></li> + <li class="small-icon icon-faq" <!-- IF not S_USER_LOGGED_IN -->data-skip-responsive="true"<!-- ELSE -->data-last-responsive="true"<!-- ENDIF -->><a href="{U_FAQ}" rel="help" title="{L_FAQ_EXPLAIN}" role="menuitem">{L_FAQ}</a></li> <!-- EVENT overall_header_navigation_append --> - <!-- IF U_ACP --><li class="small-icon icon-acp" data-skip-responsive="true"><a href="{U_ACP}" title="{L_ACP}" role="menuitem">{L_ACP_SHORT}</a></li><!-- ENDIF --> - <!-- IF U_MCP --><li class="small-icon icon-mcp" data-skip-responsive="true"><a href="{U_MCP}" title="{L_MCP}" role="menuitem">{L_MCP_SHORT}</a></li><!-- ENDIF --> + <!-- IF U_ACP --><li class="small-icon icon-acp" data-last-responsive="true"><a href="{U_ACP}" title="{L_ACP}" role="menuitem">{L_ACP_SHORT}</a></li><!-- ENDIF --> + <!-- IF U_MCP --><li class="small-icon icon-mcp" data-last-responsive="true"><a href="{U_MCP}" title="{L_MCP}" role="menuitem">{L_MCP_SHORT}</a></li><!-- ENDIF --> <!-- IF S_REGISTERED_USER --> <li id="username_logged_in" class="rightside <!-- IF CURRENT_USER_AVATAR --> no-bulletin<!-- ENDIF -->" data-skip-responsive="true"> @@ -83,8 +91,10 @@ <ul id="nav-breadcrumbs" class="linklist navlinks" role="menubar"> <!-- DEFINE $MICRODATA = ' itemtype="http://data-vocabulary.org/Breadcrumb" itemscope=""' --> - <li class="small-icon icon-home breadcrumbs" role="navigation"> + <!-- EVENT overall_header_breadcrumbs_before --> + <li class="small-icon icon-home breadcrumbs"> <!-- IF U_SITE_HOME --><span class="crumb"><a href="{U_SITE_HOME}"{$MICRODATA} data-navbar-reference="home">{L_SITE_HOME}</a></span><!-- ENDIF --> + <!-- EVENT overall_header_breadcrumb_prepend --> <span class="crumb"><a href="{U_INDEX}" accesskey="h"{$MICRODATA} data-navbar-reference="index">{L_INDEX}</a></span> <!-- BEGIN navlinks --> <!-- EVENT overall_header_navlink_prepend --> @@ -93,6 +103,7 @@ <!-- END navlinks --> <!-- EVENT overall_header_breadcrumb_append --> </li> + <!-- EVENT overall_header_breadcrumbs_after --> <!-- IF S_DISPLAY_SEARCH and not S_IN_SEARCH --> <li class="rightside responsive-search" style="display: none;"><a href="{U_SEARCH}" title="{L_SEARCH_ADV_EXPLAIN}" role="menuitem">{L_SEARCH}</a></li> diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html index df09fc6a30..076a3160f0 100644 --- a/phpBB/styles/prosilver/template/overall_header.html +++ b/phpBB/styles/prosilver/template/overall_header.html @@ -51,6 +51,8 @@ {$STYLESHEETS} +<!-- EVENT overall_header_stylesheets_after --> + </head> <body id="phpbb" class="nojs notouch section-{SCRIPT_NAME} {S_CONTENT_DIRECTION} {BODY_CLASS}"> diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html index d31dd32cf6..0831d5f9dc 100644 --- a/phpBB/styles/prosilver/template/simple_header.html +++ b/phpBB/styles/prosilver/template/simple_header.html @@ -28,6 +28,8 @@ {$STYLESHEETS} +<!-- EVENT simple_header_stylesheets_after --> + </head> <body id="phpbb" class="nojs {S_CONTENT_DIRECTION} {BODY_CLASS}"> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index 9f33bc04f7..941541c582 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -18,7 +18,14 @@ <div class="inner"> <dl class="postprofile" id="profile{MESSAGE_ID}"> - <dt class="<!-- IF RANK_TITLE or RANK_IMG -->has-profile-rank<!-- ELSE -->no-profile-rank<!-- ENDIF -->"><!-- IF AUTHOR_AVATAR --><a href="{U_MESSAGE_AUTHOR}" class="avatar">{AUTHOR_AVATAR}</a><!-- ENDIF -->{MESSAGE_AUTHOR_FULL}</dt> + <dt class="<!-- IF RANK_TITLE or RANK_IMG -->has-profile-rank<!-- ELSE -->no-profile-rank<!-- ENDIF --> <!-- IF AUTHOR_AVATAR -->has-avatar<!-- ELSE -->no-avatar<!-- ENDIF -->"> + <div class="avatar-container"> + <!-- EVENT ucp_pm_viewmessage_avatar_before --> + <!-- IF AUTHOR_AVATAR --><a href="{U_MESSAGE_AUTHOR}" class="avatar">{AUTHOR_AVATAR}</a><!-- ENDIF --> + <!-- EVENT ucp_pm_viewmessage_avatar_after --> + </div> + {MESSAGE_AUTHOR_FULL} + </dt> <!-- IF RANK_TITLE or RANK_IMG --><dd class="profile-rank">{RANK_TITLE}<!-- IF RANK_TITLE and RANK_IMG --><br /><!-- ENDIF -->{RANK_IMG}</dd><!-- ENDIF --> @@ -67,6 +74,7 @@ <!-- IF U_DELETE or U_EDIT or U_QUOTE or U_REPORT --> <ul class="post-buttons"> + <!-- EVENT ucp_pm_viewmessage_post_buttons_before --> <!-- IF U_EDIT --> <li> <a href="{U_EDIT}" title="{L_POST_EDIT_PM}" class="button icon-button edit-icon"><span>{L_POST_EDIT_PM}</span></a> @@ -87,6 +95,7 @@ <a href="{U_QUOTE}" title="{L_POST_QUOTE_PM}" class="button icon-button quote-icon"><span>{L_POST_QUOTE_PM}</span></a> </li> <!-- ENDIF --> + <!-- EVENT ucp_pm_viewmessage_post_buttons_after --> </ul> <!-- ENDIF --> @@ -104,16 +113,6 @@ <dl class="attachbox"> <dt> {L_ATTACHMENTS} - <!-- IF S_HAS_MULTIPLE_ATTACHMENTS --> - <div class="dl_links"> - <strong>{L_DOWNLOAD_ALL}{L_COLON}</strong> - <ul> - <!-- BEGIN dl_method --> - <li>[ <a href="{dl_method.LINK}">{dl_method.TYPE}</a> ]</li> - <!-- END dl_method --> - </ul> - </div> - <!-- ENDIF --> </dt> <!-- BEGIN attachment --> <dd>{attachment.DISPLAY_ATTACHMENT}</dd> diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html index d07aab1a89..c8b028f83a 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html @@ -58,8 +58,8 @@ <!-- ENDIF --> <!-- IF S_STYLE_OPTIONS and S_MORE_STYLES --> <dl> - <dt><label for="style">{L_BOARD_STYLE}{L_COLON}</label></dt> - <dd><select name="style" id="style">{S_STYLE_OPTIONS}</select></dd> + <dt><label for="user_style">{L_BOARD_STYLE}{L_COLON}</label></dt> + <dd><select name="user_style" id="user_style">{S_STYLE_OPTIONS}</select></dd> </dl> <!-- ENDIF --> <!-- INCLUDE timezone_option.html --> diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index b764979f97..ac9c9a362a 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -124,10 +124,14 @@ <div class="inner"> <dl class="postprofile" id="profile{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->> - <dt class="<!-- IF postrow.RANK_TITLE or postrow.RANK_IMG -->has-profile-rank<!-- ELSE -->no-profile-rank<!-- ENDIF -->"> - <!-- IF postrow.POSTER_AVATAR --> - <!-- IF postrow.U_POST_AUTHOR --><a href="{postrow.U_POST_AUTHOR}" class="avatar">{postrow.POSTER_AVATAR}</a><!-- ELSE --><span class="avatar">{postrow.POSTER_AVATAR}</span><!-- ENDIF --> - <!-- ENDIF --> + <dt class="<!-- IF postrow.RANK_TITLE or postrow.RANK_IMG -->has-profile-rank<!-- ELSE -->no-profile-rank<!-- ENDIF --> <!-- IF postrow.POSTER_AVATAR -->has-avatar<!-- ELSE -->no-avatar<!-- ENDIF -->"> + <div class="avatar-container"> + <!-- EVENT viewtopic_body_avatar_before --> + <!-- IF postrow.POSTER_AVATAR --> + <!-- IF postrow.U_POST_AUTHOR --><a href="{postrow.U_POST_AUTHOR}" class="avatar">{postrow.POSTER_AVATAR}</a><!-- ELSE --><span class="avatar">{postrow.POSTER_AVATAR}</span><!-- ENDIF --> + <!-- ENDIF --> + <!-- EVENT viewtopic_body_avatar_after --> + </div> <!-- IF not postrow.U_POST_AUTHOR --><strong>{postrow.POST_AUTHOR_FULL}</strong><!-- ELSE -->{postrow.POST_AUTHOR_FULL}<!-- ENDIF --> </dt> @@ -274,16 +278,6 @@ <dl class="attachbox"> <dt> {L_ATTACHMENTS} - <!-- IF postrow.S_MULTIPLE_ATTACHMENTS --> - <div class="dl_links"> - <strong>{L_DOWNLOAD_ALL}{L_COLON}</strong> - <ul> - <!-- BEGIN dl_method --> - <li>[ <a href="{postrow.dl_method.LINK}">{postrow.dl_method.TYPE}</a> ]</li> - <!-- END dl_method --> - </ul> - </div> - <!-- ENDIF --> </dt> <!-- BEGIN attachment --> <dd>{postrow.attachment.DISPLAY_ATTACHMENT}</dd> diff --git a/phpBB/styles/prosilver/template/viewtopic_topic_tools.html b/phpBB/styles/prosilver/template/viewtopic_topic_tools.html index 2a34ebd446..83904bf63d 100644 --- a/phpBB/styles/prosilver/template/viewtopic_topic_tools.html +++ b/phpBB/styles/prosilver/template/viewtopic_topic_tools.html @@ -18,18 +18,6 @@ <!-- IF U_BUMP_TOPIC --><li class="small-icon icon-bump"><a href="{U_BUMP_TOPIC}" title="{L_BUMP_TOPIC}" data-ajax="true">{L_BUMP_TOPIC}</a></li><!-- ENDIF --> <!-- IF U_EMAIL_TOPIC --><li class="small-icon icon-sendemail"><a href="{U_EMAIL_TOPIC}" title="{L_EMAIL_TOPIC}">{L_EMAIL_TOPIC}</a></li><!-- ENDIF --> <!-- IF U_PRINT_TOPIC --><li class="small-icon icon-print"><a href="{U_PRINT_TOPIC}" title="{L_PRINT_TOPIC}" accesskey="p">{L_PRINT_TOPIC}</a></li><!-- ENDIF --> - <!-- IF S_HAS_ATTACHMENTS --> - <li class="small-icon icon-download"> - <a class="dropdown-toggle-submenu" href="{U_DOWNLOAD_ALL_ATTACHMENTS}" title="{L_DOWNLOAD_ALL_ATTACHMENTS}">{L_DOWNLOAD_ALL_ATTACHMENTS}</a> - <ul class="dropdown-submenu hidden"> - <li> - <!-- BEGIN dl_method --> - <a href="{dl_method.LINK}">{dl_method.TYPE}</a><!-- IF not dl_method.S_LAST_ROW --> • <!-- ENDIF --> - <!-- END dl_method --> - </li> - </ul> - </li> - <!-- ENDIF --> <!-- EVENT viewtopic_topic_tools_after --> </ul> </div> diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css index bc9e4b3965..f6e490f82a 100644 --- a/phpBB/styles/prosilver/theme/bidi.css +++ b/phpBB/styles/prosilver/theme/bidi.css @@ -114,7 +114,7 @@ .rtl .dropdown li li { padding-left: 0; - padding-right: 10px; + padding-right: 18px; } .rtl .dropdown-extended .header { @@ -315,7 +315,7 @@ unicode-bidi: embed; } -ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a { +li.breadcrumbs span:first-child > a { padding-left: 0; padding-right: 19px; } @@ -332,12 +332,8 @@ ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a { .rtl .skiplink { /* invisible skip link, used for accessibility */ - position: relative; - width: 1px; - height: 1px; - overflow: hidden; - display: block; left: 0; + right: -999px; } .rtl a.feed-icon-forum { @@ -586,6 +582,10 @@ ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a { margin-right: 8px; } +.rtl .postprofile .avatar { + float: right; +} + .rtl .online { background-position: 0 0; } @@ -628,12 +628,11 @@ ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a { ---------------------------------------- */ .rtl .small-icon { background-position: 100% 50%; - padding-left: 0; - padding-right: 19px; } -.rtl ul.linklist li.small-icon { - padding-right: 0; +.rtl .small-icon > a { + padding-left: 0; + padding-right: 19px; } /* Post control buttons @@ -1079,8 +1078,11 @@ ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a { border-width: 0 0 1px 0; } + .rtl .postprofile dt, .rtl .postprofile dd.profile-rank, .rtl .search .postprofile dd { + margin: 0; + } + .rtl .postprofile .avatar { - float: right; margin-left: 5px; margin-right: 0; } diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index 18c71d251e..b45aae5672 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -105,17 +105,21 @@ background-position: 0 50%; background-repeat: no-repeat; background-image: none; - padding: 0 0 0 17px; } -ul.linklist li.small-icon { - padding-left: 0; +.small-icon > a { + display: inline-block; + padding: 0 0 0 18px; } ul.linklist.bulletin > li.small-icon:before { display: none; } +.dropdown .small-icon > a { + display: block; +} + /* Poster contact icons ----------------------------------------*/ .contact-icons.dropdown-contents { diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index fce66f7efb..82542c8d86 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -654,7 +654,6 @@ Colours and backgrounds for buttons.css .icon-pm { background-image: url("./images/icon_pm.gif"); } .icon-print { background-image: url("./images/icon_print.gif"); } .icon-profile { background-image: url("./images/icon_profile.gif"); } -.icon-quick-links { background-image: url("./images/icon_quick_links.gif"); } .icon-register { background-image: url("./images/icon_register.gif"); } .icon-search, .responsive-search a { background-image: url("./images/icon_search.gif"); } .icon-search-active { background-image: url("./images/subforum_read.gif"); } diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index e33bf99965..45cb88890d 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -305,12 +305,6 @@ ol ol ul, ol ul ul, ul ol ul, ul ul ul { border-radius: 7px; } -.inner:after { - content: ''; - clear: both; - display: block; -} - .rowbg { margin: 5px 5px 2px 5px; } @@ -326,12 +320,6 @@ ul.linklist { margin: 0; } -ul.linklist:after { - content: ''; - display: block; - clear: both; -} - #cp-main .panel { padding: 5px 10px; } @@ -625,7 +613,7 @@ ul.linklist.bulletin > li.no-bulletin:before { .dropdown li li { border-top: 1px dotted transparent; - padding-left: 10px; + padding-left: 18px; } .wrap .dropdown li, .dropdown.wrap li, .dropdown-extended li { @@ -856,12 +844,6 @@ fieldset.fields1 dl.pmlist dd.recipients { margin-top: 2em; } -.action-bar:after { - clear: both; - content: ''; - display: block; -} - /* Pagination ---------------------------------------- */ .pagination { @@ -1130,6 +1112,20 @@ form > p.post-notice strong { background: transparent; } +/* Inner box-model clearing */ +.inner:after, +ul.linklist:after, +.action-bar:after, +.notification_text:after, +.tabs-container:after, +#tabs > ul:after, +#minitabs > ul:after, +.postprofile .avatar-container:after { + clear: both; + content: ''; + display: block; +} + .hidden { display: none; } @@ -1285,12 +1281,6 @@ form > p.post-notice strong { margin-left: 58px; } -.notification_text:after { - content: ''; - clear: both; - display: block; -} - /* Navbar specific list items ----------------------------------------*/ diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index a014f57d47..8b84545a2c 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -710,15 +710,22 @@ fieldset.polls dd div { margin-bottom: 10px; } +/* Post-profile avatars */ +.postprofile .has-avatar .avatar-container { + margin-bottom: 3px; + overflow: hidden; +} + .postprofile .avatar { display: block; - border: none; - margin-bottom: 3px; + float: left; + max-width: 100%; } .postprofile .avatar img { - max-width: 90%; + display: block; height: auto !important; + max-width: 100%; } dd.profile-warnings { diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css index 5149a16ec9..d3699c3012 100644 --- a/phpBB/styles/prosilver/theme/cp.css +++ b/phpBB/styles/prosilver/theme/cp.css @@ -96,12 +96,6 @@ ul.cplist { margin-bottom: 0px; } -.tabs-container:after { - clear: both; - content: ''; - display: block; -} - /* CP tabs shared ----------------------------------------*/ #tabs, #minitabs { @@ -115,12 +109,6 @@ ul.cplist { position: relative; } -#tabs > ul:after, #minitabs > ul:after { - clear: both; - content: ''; - display: block; -} - #tabs .tab, #minitabs .tab { display: inline-block; float: left; diff --git a/phpBB/styles/prosilver/theme/images/icon_print.gif b/phpBB/styles/prosilver/theme/images/icon_print.gif Binary files differindex e464e304ea..e464e304ea 100755..100644 --- a/phpBB/styles/prosilver/theme/images/icon_print.gif +++ b/phpBB/styles/prosilver/theme/images/icon_print.gif diff --git a/phpBB/styles/prosilver/theme/links.css b/phpBB/styles/prosilver/theme/links.css index 890f854baa..9b5c00d9b6 100644 --- a/phpBB/styles/prosilver/theme/links.css +++ b/phpBB/styles/prosilver/theme/links.css @@ -27,7 +27,7 @@ a:hover { text-decoration: underline; } } /* Navigation bar links */ -ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a { +li.breadcrumbs span:first-child > a { display: inline-block; padding-left: 17px; } diff --git a/phpBB/styles/prosilver/theme/responsive.css b/phpBB/styles/prosilver/theme/responsive.css index 241b4d132e..b9cbd4cdfb 100644 --- a/phpBB/styles/prosilver/theme/responsive.css +++ b/phpBB/styles/prosilver/theme/responsive.css @@ -424,16 +424,22 @@ fieldset.polls dd.resultbar, fieldset.polls dd.poll_option_percent { margin: 0; } +.postprofile .has-avatar .avatar-container { + margin: 0; + overflow: inherit; +} + +.postprofile .avatar-container:after { + clear: none; +} + .postprofile .avatar { - display: block; - float: left; margin-right: 5px; } .postprofile .avatar img { width: auto !important; height: auto !important; - display: block; max-height: 32px; } diff --git a/phpBB/styles/prosilver/theme/tweaks.css b/phpBB/styles/prosilver/theme/tweaks.css index ea0c66d20a..851b3a6bb6 100644 --- a/phpBB/styles/prosilver/theme/tweaks.css +++ b/phpBB/styles/prosilver/theme/tweaks.css @@ -71,3 +71,8 @@ dd.option { .header-avatar img { height: 20px; } + +/* IE8 often can't handle max-width in %, so we use px instead */ +.postprofile .avatar img { + max-width: 150px; +} diff --git a/phpBB/styles/subsilver2/template/breadcrumbs.html b/phpBB/styles/subsilver2/template/breadcrumbs.html index 3aa05bc0eb..25387da832 100644 --- a/phpBB/styles/subsilver2/template/breadcrumbs.html +++ b/phpBB/styles/subsilver2/template/breadcrumbs.html @@ -2,8 +2,10 @@ <table class="tablebg" width="100%" cellspacing="1" cellpadding="0" style="margin-top: 5px;"> <tr> <td class="row1"> - <p class="breadcrumbs"><!-- IF U_SITE_HOME --><a href="{U_SITE_HOME}"{$MICRODATA} data-navbar-reference="home">{L_SITE_HOME}</a> <strong>»</strong> <!-- ENDIF --><a href="{U_INDEX}"{$MICRODATA} data-navbar-reference="index">{L_INDEX}</a><!-- BEGIN navlinks --><!-- EVENT overall_header_navlink_prepend --> » <a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->>{navlinks.FORUM_NAME}</a><!-- EVENT overall_header_navlink_append --><!-- END navlinks --> - <!-- EVENT overall_header_breadcrumb_append --></p> + <!-- EVENT overall_header_breadcrumbs_before --> + <p class="breadcrumbs"><!-- IF U_SITE_HOME --><a href="{U_SITE_HOME}"{$MICRODATA} data-navbar-reference="home">{L_SITE_HOME}</a> <strong>»</strong> <!-- ENDIF --><!-- IF $OVERALL_HEADER_BREADCRUMBS --><!-- EVENT overall_header_breadcrumb_prepend --><!-- ELSE --><!-- EVENT overall_footer_breadcrumb_prepend --><!-- ENDIF --><a href="{U_INDEX}"{$MICRODATA} data-navbar-reference="index">{L_INDEX}</a><!-- BEGIN navlinks --><!-- EVENT overall_header_navlink_prepend --> » <a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->>{navlinks.FORUM_NAME}</a><!-- EVENT overall_header_navlink_append --><!-- END navlinks --> + <!-- IF $OVERALL_HEADER_BREADCRUMBS --><!-- EVENT overall_header_breadcrumb_append --><!-- ELSE --><!-- EVENT overall_footer_breadcrumb_append --><!-- ENDIF --></p> + <!-- EVENT overall_header_breadcrumbs_after --> <!-- EVENT overall_footer_timezone_before --> <p class="datetime">{S_TIMEZONE}</p> <!-- EVENT overall_footer_timezone_after --> diff --git a/phpBB/styles/subsilver2/template/mcp_ban.html b/phpBB/styles/subsilver2/template/mcp_ban.html index edf81c6d76..cc24d21d73 100644 --- a/phpBB/styles/subsilver2/template/mcp_ban.html +++ b/phpBB/styles/subsilver2/template/mcp_ban.html @@ -5,27 +5,34 @@ var ban_length = new Array(); ban_length[-1] = ''; - <!-- BEGIN ban_length --> - ban_length['{ban_length.BAN_ID}'] = '{ban_length.A_LENGTH}'; - <!-- END ban_length --> - var ban_reason = new Array(); ban_reason[-1] = ''; - <!-- BEGIN ban_reason --> - ban_reason['{ban_reason.BAN_ID}'] = '{ban_reason.A_REASON}'; - <!-- END ban_reason --> - var ban_give_reason = new Array(); ban_give_reason[-1] = ''; - <!-- BEGIN ban_give_reason --> - ban_give_reason['{ban_give_reason.BAN_ID}'] = '{ban_give_reason.A_REASON}'; - <!-- END ban_give_reason --> + + <!-- BEGIN bans --> + ban_length['{bans.BAN_ID}'] = '{bans.A_LENGTH}'; + <!-- IF bans.A_REASON --> + ban_reason['{bans.BAN_ID}'] = '{bans.A_REASON}'; + <!-- ENDIF --> + <!-- IF bans.A_GIVE_REASON --> + ban_give_reason['{bans.BAN_ID}'] = '{bans.A_GIVE_REASON}'; + <!-- ENDIF --> + <!-- END bans --> function display_details(option) { - document.getElementById('mcp_ban').unbangivereason.value = ban_give_reason[option]; - document.getElementById('mcp_ban').unbanreason.value = ban_reason[option]; document.getElementById('mcp_ban').unbanlength.value = ban_length[option]; + if (option in ban_reason) { + document.getElementById('mcp_ban').unbanreason.value = ban_reason[option]; + } else { + document.getElementById('mcp_ban').unbanreason.value = ''; + } + if (option in ban_give_reason) { + document.getElementById('mcp_ban').unbangivereason.value = ban_give_reason[option]; + } else { + document.getElementById('mcp_ban').unbangivereason.value = ''; + } } // ]]> @@ -40,6 +47,7 @@ <tr> <td class="row3" colspan="2">{L_EXPLAIN}</td> </tr> +<!-- EVENT mcp_ban_fields_before --> <tr> <td class="row1" width="45%" valign="top"><b>{L_BAN_CELL}{L_COLON}</b></td> <td class="row2"> @@ -63,6 +71,7 @@ <td class="row1" valign="top"><b>{L_BAN_GIVE_REASON}{L_COLON}</b></td> <td class="row2"><input name="bangivereason" type="text" class="post" maxlength="255" /></td> </tr> +<!-- EVENT mcp_ban_fields_after --> <tr> <td class="cat" colspan="2" align="center"><input type="submit" name="bansubmit" value="{L_SUBMIT}" class="btnmain" /> <input type="reset" value="{L_RESET}" class="btnlite" /> </td> </tr> @@ -78,6 +87,7 @@ <td class="row3" colspan="2">{L_UNBAN_EXPLAIN}</td> </tr> <!-- IF S_BANNED_OPTIONS --> + <!-- EVENT mcp_ban_unban_before --> <tr> <td class="row1" valign="top" width="45%"><b>{L_BAN_CELL}{L_COLON}</b></td> <td class="row2"><select name="unban[]" multiple="multiple" size="10" style="width: 50%" onchange="if (this.selectedIndex > -1) display_details(this.options[this.selectedIndex].value); else display_details(-1);">{BANNED_OPTIONS}</select></td> @@ -94,6 +104,7 @@ <td class="row1" valign="top"><b>{L_BAN_GIVE_REASON}{L_COLON}</b></td> <td class="row2"><textarea style="border: 0; width: 100%" name="unbangivereason" readonly="readonly" rows="5" cols="80"> </textarea></td> </tr> + <!-- EVENT mcp_ban_unban_after --> <tr> <td class="cat" colspan="2" align="center"><input type="submit" name="unbansubmit" value="{L_SUBMIT}" class="btnmain" /> <input type="reset" value="{L_RESET}" class="btnlite" /> </td> </tr> diff --git a/phpBB/styles/subsilver2/template/mcp_topic.html b/phpBB/styles/subsilver2/template/mcp_topic.html index 5bd762ec0b..cba473147e 100644 --- a/phpBB/styles/subsilver2/template/mcp_topic.html +++ b/phpBB/styles/subsilver2/template/mcp_topic.html @@ -55,7 +55,7 @@ </tr> <tr> <td class="row1" nowrap="nowrap"><span class="gen">{L_POSTS_PER_PAGE}</span><br /><span class="gensmall">{L_POSTS_PER_PAGE_EXPLAIN}</span></td> - <td class="row2" colspan="2"><input class="post" type="number" min="1" name="posts_per_page" size="6" value="{POSTS_PER_PAGE}" /></td> + <td class="row2" colspan="2"><input class="post" type="number" min="0" name="posts_per_page" size="6" value="{POSTS_PER_PAGE}" /></td> </tr> <tr> <td class="cat" colspan="3" align="center"><span class="gensmall">{L_DISPLAY_POSTS}{L_COLON}</span> {S_SELECT_SORT_DAYS} <span class="gensmall">{L_SORT_BY}</span> {S_SELECT_SORT_KEY} {S_SELECT_SORT_DIR} <input class="btnlite" type="submit" name="sort" value="{L_GO}" /></td> diff --git a/phpBB/styles/subsilver2/template/overall_header.html b/phpBB/styles/subsilver2/template/overall_header.html index 711ce66362..ebb7b3be4d 100644 --- a/phpBB/styles/subsilver2/template/overall_header.html +++ b/phpBB/styles/subsilver2/template/overall_header.html @@ -135,6 +135,8 @@ function marklist(id, name, state) {$STYLESHEETS} +<!-- EVENT overall_header_stylesheets_after --> + </head> <body class="{S_CONTENT_DIRECTION} {BODY_CLASS}"> @@ -212,7 +214,7 @@ function marklist(id, name, state) </td> <td class="genmed" align="{S_CONTENT_FLOW_END}"> <!-- EVENT overall_header_navigation_prepend --> - <a href="{U_FAQ}"><img src="{T_THEME_PATH}/images/icon_mini_faq.gif" width="12" height="13" alt="*" /> {L_FAQ}</a> + <a href="{U_FAQ}" rel="help"><img src="{T_THEME_PATH}/images/icon_mini_faq.gif" width="12" height="13" alt="*" /> {L_FAQ}</a> <!-- IF S_DISPLAY_SEARCH --> <a href="{U_SEARCH}"><img src="{T_THEME_PATH}/images/icon_mini_search.gif" width="12" height="13" alt="*" /> {L_SEARCH}</a><!-- ENDIF --> <!-- IF not S_IS_BOT --> <!-- IF S_DISPLAY_MEMBERLIST --> <a href="{U_MEMBERLIST}"><img src="{T_THEME_PATH}/images/icon_mini_members.gif" width="12" height="13" alt="*" /> {L_MEMBERLIST}</a><!-- ENDIF --> @@ -251,7 +253,9 @@ function marklist(id, name, state) <br style="clear: both;" /> <!-- DEFINE $S_MICRODATA = 1 --> + <!-- DEFINE $OVERALL_HEADER_BREADCRUMBS = 1 --> <!-- INCLUDE breadcrumbs.html --> + <!-- UNDEFINE $OVERALL_HEADER_BREADCRUMBS --> <!-- DEFINE $S_MICRODATA = 0 --> <br /> diff --git a/phpBB/styles/subsilver2/template/simple_header.html b/phpBB/styles/subsilver2/template/simple_header.html index faeeaea3d5..0c3dff4a05 100644 --- a/phpBB/styles/subsilver2/template/simple_header.html +++ b/phpBB/styles/subsilver2/template/simple_header.html @@ -14,6 +14,8 @@ {$STYLESHEETS} +<!-- EVENT simple_header_stylesheets_after --> + </head> <body class="{S_CONTENT_DIRECTION} {BODY_CLASS}"> diff --git a/phpBB/styles/subsilver2/template/ucp_pm_viewmessage.html b/phpBB/styles/subsilver2/template/ucp_pm_viewmessage.html index be1e27c5f3..9536b1f8c5 100644 --- a/phpBB/styles/subsilver2/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/subsilver2/template/ucp_pm_viewmessage.html @@ -104,7 +104,19 @@ </tr> <tr class="row1"> - <td><div class="gensmall" style="float: {S_CONTENT_FLOW_BEGIN};"> <!-- IF U_MESSAGE_AUTHOR --><a href="{U_MESSAGE_AUTHOR}" class="imageset">{PROFILE_IMG}</a> <!-- ENDIF --> <!-- IF U_EMAIL --><a href="{U_EMAIL}" class="imageset">{EMAIL_IMG}</a> <!-- ENDIF --> </div> <div class="gensmall" style="float: {S_CONTENT_FLOW_END};"><!-- IF U_EDIT --><a href="{U_EDIT}" class="imageset">{EDIT_IMG}</a> <!-- ENDIF --> <!-- IF U_QUOTE --><a href="{U_QUOTE}" class="imageset">{QUOTE_IMG}</a> <!-- ENDIF --> <!-- IF U_POST_REPLY_PM --><a href="{U_POST_REPLY_PM}" class="imageset">{REPLY_IMG}</a><!-- ENDIF --> </div></td> + <td> + <div class="gensmall" style="float: {S_CONTENT_FLOW_BEGIN};"> + <!-- IF U_MESSAGE_AUTHOR --><a href="{U_MESSAGE_AUTHOR}" class="imageset">{PROFILE_IMG}</a> <!-- ENDIF --> + <!-- IF U_EMAIL --><a href="{U_EMAIL}" class="imageset">{EMAIL_IMG}</a> <!-- ENDIF --> + </div> + <div class="gensmall" style="float: {S_CONTENT_FLOW_END};"> + <!-- EVENT ucp_pm_viewmessage_post_buttons_before --> + <!-- IF U_EDIT --><a href="{U_EDIT}" class="imageset">{EDIT_IMG}</a> <!-- ENDIF --> + <!-- IF U_QUOTE --><a href="{U_QUOTE}" class="imageset">{QUOTE_IMG}</a> <!-- ENDIF --> + <!-- IF U_POST_REPLY_PM --><a href="{U_POST_REPLY_PM}" class="imageset">{REPLY_IMG}</a><!-- ENDIF --> + <!-- EVENT ucp_pm_viewmessage_post_buttons_after --> + </div> + </td> </tr> <tr> diff --git a/phpBB/styles/subsilver2/template/ucp_prefs_personal.html b/phpBB/styles/subsilver2/template/ucp_prefs_personal.html index 93fcfac5b1..1c76e3226d 100644 --- a/phpBB/styles/subsilver2/template/ucp_prefs_personal.html +++ b/phpBB/styles/subsilver2/template/ucp_prefs_personal.html @@ -49,7 +49,7 @@ <!-- IF S_STYLE_OPTIONS and S_MORE_STYLES --> <tr> <td class="row1" width="50%"><b class="genmed">{L_BOARD_STYLE}{L_COLON}</b></td> - <td class="row2"><select name="style">{S_STYLE_OPTIONS}</select></td> + <td class="row2"><select name="user_style">{S_STYLE_OPTIONS}</select></td> </tr> <!-- ENDIF --> <!-- INCLUDE timezone_option.html --> diff --git a/phpBB/styles/subsilver2/template/viewtopic_body.html b/phpBB/styles/subsilver2/template/viewtopic_body.html index c69be83a1e..0f34b50950 100644 --- a/phpBB/styles/subsilver2/template/viewtopic_body.html +++ b/phpBB/styles/subsilver2/template/viewtopic_body.html @@ -192,11 +192,15 @@ <td>{postrow.RANK_IMG}</td> </tr> <!-- ENDIF --> + + <!-- EVENT viewtopic_body_avatar_before --> <!-- IF postrow.POSTER_AVATAR --> <tr> <td>{postrow.POSTER_AVATAR}</td> </tr> <!-- ENDIF --> + <!-- EVENT viewtopic_body_avatar_after --> + <!-- IF not (postrow.ONLINE_IMG or postrow.RANK_TITLE or postrow.RANK_IMG or postrow.POSTER_AVATAR) --> <tr> <td></td> diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index c9623293c6..9086feb390 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -469,11 +469,11 @@ if ($forum_data['forum_type'] == FORUM_POST) $forum_tracking_info = array(); -if ($user->data['is_registered']) +if ($user->data['is_registered'] && $config['load_db_lastread']) { $forum_tracking_info[$forum_id] = $forum_data['mark_time']; - if (!empty($global_announce_forums) && $config['load_db_lastread']) + if (!empty($global_announce_forums)) { $sql = 'SELECT forum_id, mark_time FROM ' . FORUMS_TRACK_TABLE . ' diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php index 4c897c58aa..a03a81a15e 100644 --- a/phpBB/viewonline.php +++ b/phpBB/viewonline.php @@ -295,8 +295,21 @@ while ($row = $db->sql_fetchrow($result)) break; case 'memberlist': - $location = (strpos($row['session_page'], 'mode=viewprofile') !== false) ? $user->lang['VIEWING_MEMBER_PROFILE'] : $user->lang['VIEWING_MEMBERS']; $location_url = append_sid("{$phpbb_root_path}memberlist.$phpEx"); + + if (strpos($row['session_page'], 'mode=viewprofile') !== false) + { + $location = $user->lang['VIEWING_MEMBER_PROFILE']; + } + else if (strpos($row['session_page'], 'mode=contactadmin') !== false) + { + $location = $user->lang['VIEWING_CONTACT_ADMIN']; + $location_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contactadmin'); + } + else + { + $location = $user->lang['VIEWING_MEMBERS']; + } break; case 'mcp': diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 23f2fe8e3d..8d7ab5323d 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -539,8 +539,8 @@ $s_quickmod_action = append_sid( $quickmod_array = array( // 'key' => array('LANG_KEY', $userHasPermissions), - 'lock' => array('LOCK_TOPIC', ($topic_data['topic_status'] == ITEM_UNLOCKED) && ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $topic_data['topic_poster'] && $topic_data['topic_status'] == ITEM_UNLOCKED))), - 'unlock' => array('UNLOCK_TOPIC', ($topic_data['topic_status'] != ITEM_UNLOCKED) && ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $topic_data['topic_poster'] && $topic_data['topic_status'] == ITEM_UNLOCKED))), + 'lock' => array('LOCK_TOPIC', ($topic_data['topic_status'] == ITEM_UNLOCKED) && ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $topic_data['topic_poster']))), + 'unlock' => array('UNLOCK_TOPIC', ($topic_data['topic_status'] != ITEM_UNLOCKED) && ($auth->acl_get('m_lock', $forum_id))), 'delete_topic' => array('DELETE_TOPIC', ($auth->acl_get('m_delete', $forum_id) || (($topic_data['topic_visibility'] != ITEM_DELETED) && $auth->acl_get('m_softdelete', $forum_id)))), 'restore_topic' => array('RESTORE_TOPIC', (($topic_data['topic_visibility'] == ITEM_DELETED) && $auth->acl_get('m_approve', $forum_id))), 'move' => array('MOVE_TOPIC', $auth->acl_get('m_move', $forum_id) && $topic_data['topic_status'] != ITEM_MOVED), @@ -1392,17 +1392,6 @@ if (sizeof($attach_list)) } } -$methods = phpbb_gen_download_links('topic_id', $topic_id, $phpbb_root_path, $phpEx); -foreach ($methods as $method) -{ - $template->assign_block_vars('dl_method', $method); -} - -$template->assign_vars(array( - 'S_HAS_ATTACHMENTS' => $topic_data['topic_attachment'], - 'U_DOWNLOAD_ALL_ATTACHMENTS' => $methods[0]['LINK'], -)); - // Instantiate BBCode if need be if ($bbcode_bitfield !== '') { @@ -1420,9 +1409,50 @@ $i_total = sizeof($rowset) - 1; $prev_post_id = ''; $template->assign_vars(array( + 'S_HAS_ATTACHMENTS' => $topic_data['topic_attachment'], 'S_NUM_POSTS' => sizeof($post_list)) ); +/** +* Event to modify the post, poster and attachment data before assigning the posts +* +* @event core.viewtopic_modify_post_data +* @var int forum_id Forum ID +* @var int topic_id Topic ID +* @var array topic_data Array with topic data +* @var array post_list Array with post_ids we are going to display +* @var array rowset Array with post_id => post data +* @var array user_cache Array with prepared user data +* @var int start Pagination information +* @var int sort_days Display posts of previous x days +* @var string sort_key Key the posts are sorted by +* @var string sort_dir Direction the posts are sorted by +* @var bool display_notice Shall we display a notice instead of attachments +* @var bool has_approved_attachments Does the topic have approved attachments +* @var array attachments List of attachments post_id => array of attachments +* @var array permanently_banned_users List of permanently banned users +* @var array can_receive_pm_list Array with posters that can receive pms +* @since 3.1.0-RC3 +*/ +$vars = array( + 'forum_id', + 'topic_id', + 'topic_data', + 'post_list', + 'rowset', + 'user_cache', + 'sort_days', + 'sort_key', + 'sort_dir', + 'start', + 'permanently_banned_users', + 'can_receive_pm_list', + 'display_notice', + 'has_approved_attachments', + 'attachments', +); +extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_post_data', compact($vars))); + // Output the posts $first_unread = $post_unread = false; for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) @@ -1789,6 +1819,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) * @var int current_row_number Number of the post on this page * @var int end Number of posts on this page * @var int total_posts Total posts count + * @var int poster_id Post author id * @var array row Array with original post and user data * @var array cp_row Custom profile field data of the poster * @var array attachments List of attachments @@ -1798,12 +1829,14 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) * @since 3.1.0-a1 * @change 3.1.0-a3 Added vars start, current_row_number, end, attachments * @change 3.1.0-b3 Added topic_data array, total_posts + * @change 3.1.0-RC3 Added poster_id */ $vars = array( 'start', 'current_row_number', 'end', 'total_posts', + 'poster_id', 'row', 'cp_row', 'attachments', @@ -1875,12 +1908,6 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'DISPLAY_ATTACHMENT' => $attachment) ); } - - $methods = phpbb_gen_download_links('post_id', $row['post_id'], $phpbb_root_path, $phpEx); - foreach ($methods as $method) - { - $template->assign_block_vars('postrow.dl_method', $method); - } } $current_row_number = $i; diff --git a/tests/avatar/manager_test.php b/tests/avatar/manager_test.php index de505e2c9f..d8099b40d4 100644 --- a/tests/avatar/manager_test.php +++ b/tests/avatar/manager_test.php @@ -43,6 +43,14 @@ class phpbb_avatar_manager_test extends \phpbb_test_case $phpEx ); + $guessers = array( + new \Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser(), + new \Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser(), + new \phpbb\mimetype\extension_guesser, + new \phpbb\mimetype\content_guesser, + ); + $guesser = new \phpbb\mimetype\guesser($guessers); + // $this->avatar_foobar will be needed later on $this->avatar_foobar = $this->getMock('\phpbb\avatar\driver\foobar', array('get_name'), array($config, $phpbb_root_path, $phpEx, $path_helper, $cache)); $this->avatar_foobar->expects($this->any()) @@ -57,7 +65,14 @@ class phpbb_avatar_manager_test extends \phpbb_test_case foreach ($this->avatar_drivers() as $driver) { - $cur_avatar = $this->getMock('\phpbb\avatar\driver\\' . $driver, array('get_name'), array($config, $phpbb_root_path, $phpEx, $path_helper, $cache)); + if ($driver !== 'upload') + { + $cur_avatar = $this->getMock('\phpbb\avatar\driver\\' . $driver, array('get_name'), array($config, $phpbb_root_path, $phpEx, $path_helper, $cache)); + } + else + { + $cur_avatar = $this->getMock('\phpbb\avatar\driver\\' . $driver, array('get_name'), array($config, $phpbb_root_path, $phpEx, $path_helper, $guesser, $cache)); + } $cur_avatar->expects($this->any()) ->method('get_name') ->will($this->returnValue('avatar.driver.' . $driver)); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 2856ba02bb..bb4a703cc3 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -31,5 +31,4 @@ require_once 'test_framework/phpbb_test_case_helpers.php'; require_once 'test_framework/phpbb_test_case.php'; require_once 'test_framework/phpbb_database_test_case.php'; require_once 'test_framework/phpbb_database_test_connection_manager.php'; -require_once 'test_framework/phpbb_mink_test_case.php'; require_once 'test_framework/phpbb_functional_test_case.php'; diff --git a/tests/config_php_file_test.php b/tests/config_php_file_test.php index c2e4eb21c7..c319678108 100644 --- a/tests/config_php_file_test.php +++ b/tests/config_php_file_test.php @@ -17,6 +17,7 @@ class phpbb_config_php_file_test extends phpbb_test_case { $config_php = new \phpbb\config_php_file(dirname( __FILE__ ) . '/fixtures/', 'php'); $this->assertSame('bar', $config_php->get('foo')); + $this->assertNull($config_php->get('bar')); $this->assertSame(array('foo' => 'bar', 'foo_foo' => 'bar bar'), $config_php->get_all()); } @@ -25,6 +26,15 @@ class phpbb_config_php_file_test extends phpbb_test_case $config_php = new \phpbb\config_php_file(dirname( __FILE__ ) . '/fixtures/', 'php'); $config_php->set_config_file(dirname( __FILE__ ) . '/fixtures/config_other.php'); $this->assertSame('foo', $config_php->get('bar')); + $this->assertNull($config_php->get('foo')); $this->assertSame(array('bar' => 'foo', 'bar_bar' => 'foo foo'), $config_php->get_all()); } + + public function test_non_existent_file() + { + $config_php = new \phpbb\config_php_file(dirname( __FILE__ ) . '/fixtures/non_existent/', 'php'); + $this->assertNull($config_php->get('bar')); + $this->assertNull($config_php->get('foo')); + $this->assertSame(array(), $config_php->get_all()); + } } diff --git a/tests/console/cron/cron_list_test.php b/tests/console/cron/cron_list_test.php index f04c14e847..1059a3f221 100644 --- a/tests/console/cron/cron_list_test.php +++ b/tests/console/cron/cron_list_test.php @@ -75,7 +75,7 @@ class phpbb_console_command_cron_list_test extends phpbb_test_case public function get_command_tester() { $application = new Application(); - $application->add(new cron_list($this->cron_manager, $this->user)); + $application->add(new cron_list($this->user, $this->cron_manager)); $command = $application->find('cron:list'); $this->command_name = $command->getName(); diff --git a/tests/console/cron/run_test.php b/tests/console/cron/run_test.php index ff251cff3c..60bd74e1f0 100644 --- a/tests/console/cron/run_test.php +++ b/tests/console/cron/run_test.php @@ -148,7 +148,7 @@ class phpbb_console_command_cron_run_test extends phpbb_database_test_case public function get_command_tester() { $application = new Application(); - $application->add(new run($this->cron_manager, $this->lock, $this->user)); + $application->add(new run($this->user, $this->cron_manager, $this->lock)); $command = $application->find('cron:run'); $this->command_name = $command->getName(); diff --git a/tests/content_visibility/delete_post_test.php b/tests/content_visibility/delete_post_test.php index 99068729df..7f31dd9b28 100644 --- a/tests/content_visibility/delete_post_test.php +++ b/tests/content_visibility/delete_post_test.php @@ -67,6 +67,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case array( array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3), ), + array( + array('user_posts' => 3), + ), ), array( 1, 1, 1, @@ -93,6 +96,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case array( array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3), ), + array( + array('user_posts' => 3), + ), ), array( 1, 1, 3, @@ -119,6 +125,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case array( array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 2), ), + array( + array('user_posts' => 3), + ), ), array( 1, 1, 2, @@ -145,6 +154,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case array( array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3), ), + array( + array('user_posts' => 3), + ), ), array( 1, 1, 1, @@ -171,6 +183,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case array( array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3), ), + array( + array('user_posts' => 3), + ), ), array( 1, 1, 3, @@ -197,6 +212,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case array( array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 2), ), + array( + array('user_posts' => 3), + ), ), array( @@ -222,6 +240,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case array( array('forum_posts_approved' => 0, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 0, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 0), ), + array( + array('user_posts' => 3), + ), ), array( @@ -257,6 +278,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case array( array('forum_posts_approved' => 0, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 0, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 1, 'forum_last_post_id' => 0), ), + array( + array('user_posts' => 3), + ), ), ); } @@ -264,14 +288,15 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case /** * @dataProvider delete_post_data */ - public function test_delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $reason, $expected_posts, $expected_topic, $expected_forum) + public function test_delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $reason, $expected_posts, $expected_topic, $expected_forum, $expected_user) { global $auth, $cache, $config, $db, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx; $config['search_type'] = 'phpbb_mock_search'; $cache = new phpbb_mock_cache; $db = $this->new_dbal(); - set_config_count(null, null, null, new \phpbb\config\config(array('num_posts' => 3, 'num_topics' => 1))); + $phpbb_config = new \phpbb\config\config(array('num_posts' => 3, 'num_topics' => 1)); + set_config_count(null, null, null, $phpbb_config); // Create auth mock $auth = $this->getMock('\phpbb\auth\auth'); @@ -287,7 +312,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, $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, $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); @@ -312,5 +337,13 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case $this->assertEquals($expected_forum, $db->sql_fetchrowset($result)); $db->sql_freeresult($result); + + $sql = 'SELECT user_posts + FROM ' . USERS_TABLE . ' + WHERE user_id = ' . (int) $data['poster_id']; + $result = $db->sql_query($sql); + + $this->assertEquals($expected_user, $db->sql_fetchrowset($result)); + $db->sql_freeresult($result); } } diff --git a/tests/content_visibility/get_forums_visibility_sql_test.php b/tests/content_visibility/get_forums_visibility_sql_test.php index 9fd84d7c04..7e4ce6577d 100644 --- a/tests/content_visibility/get_forums_visibility_sql_test.php +++ b/tests/content_visibility/get_forums_visibility_sql_test.php @@ -135,7 +135,8 @@ class phpbb_content_visibility_get_forums_visibility_sql_test extends phpbb_data ->with($this->stringContains('_'), $this->anything()) ->will($this->returnValueMap($permissions)); $user = $this->getMock('\phpbb\user'); - $content_visibility = new \phpbb\content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $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); $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 6397cd6e45..082e0d76ab 100644 --- a/tests/content_visibility/get_global_visibility_sql_test.php +++ b/tests/content_visibility/get_global_visibility_sql_test.php @@ -135,7 +135,8 @@ class phpbb_content_visibility_get_global_visibility_sql_test extends phpbb_data ->with($this->stringContains('_'), $this->anything()) ->will($this->returnValueMap($permissions)); $user = $this->getMock('\phpbb\user'); - $content_visibility = new \phpbb\content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $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); $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 daad901b67..2d4f24f1c6 100644 --- a/tests/content_visibility/get_visibility_sql_test.php +++ b/tests/content_visibility/get_visibility_sql_test.php @@ -82,7 +82,8 @@ class phpbb_content_visibility_get_visibility_sql_test extends phpbb_database_te ->with($this->stringContains('_'), $this->anything()) ->will($this->returnValueMap($permissions)); $user = $this->getMock('\phpbb\user'); - $content_visibility = new \phpbb\content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $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); $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 abfefaddfa..a596b45714 100644 --- a/tests/content_visibility/set_post_visibility_test.php +++ b/tests/content_visibility/set_post_visibility_test.php @@ -125,7 +125,8 @@ class phpbb_content_visibility_set_post_visibility_test extends phpbb_database_t $db = $this->new_dbal(); $auth = $this->getMock('\phpbb\auth\auth'); $user = $this->getMock('\phpbb\user'); - $content_visibility = new \phpbb\content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $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); $content_visibility->set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest); @@ -174,7 +175,8 @@ class phpbb_content_visibility_set_post_visibility_test extends phpbb_database_t $db = $this->new_dbal(); $auth = $this->getMock('\phpbb\auth\auth'); $user = $this->getMock('\phpbb\user'); - $content_visibility = new \phpbb\content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $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); $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 6437c61436..230474428c 100644 --- a/tests/content_visibility/set_topic_visibility_test.php +++ b/tests/content_visibility/set_topic_visibility_test.php @@ -89,7 +89,8 @@ class phpbb_content_visibility_set_topic_visibility_test extends phpbb_database_ $db = $this->new_dbal(); $auth = $this->getMock('\phpbb\auth\auth'); $user = $this->getMock('\phpbb\user'); - $content_visibility = new \phpbb\content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + $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); $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 f3c6888c8d..51f9daacfb 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -46,6 +46,7 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case 'c_bool' => array('BOOL', 1), 'c_vchar' => array('VCHAR', 'foo'), 'c_vchar_size' => array('VCHAR:4', 'foo'), + 'c_vchar_null' => array('VCHAR', null), 'c_char_size' => array('CHAR:4', 'foo'), 'c_xstext' => array('XSTEXT', 'foo'), 'c_stext' => array('STEXT', 'foo'), @@ -111,6 +112,7 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case 'c_bool' => 0, 'c_vchar' => '', 'c_vchar_size' => '', + 'c_vchar_null' => null, 'c_char_size' => 'abcd', 'c_xstext' => '', 'c_stext' => '', @@ -144,6 +146,7 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case array('c_bool', 0), array('c_vchar', str_repeat('a', 255)), array('c_vchar_size', str_repeat('a', 4)), + array('c_vchar_null', str_repeat('a', 4)), array('c_char_size', str_repeat('a', 4)), array('c_xstext', str_repeat('a', 1000)), array('c_stext', str_repeat('a', 3000)), @@ -285,13 +288,13 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2')); // Create index over the column - $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_2')); - $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'i_bug_12012_2', array('c_bug_12012_2', 'c_bool'))); - $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_2')); + $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_2')); + $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'bug_12012_2', array('c_bug_12012_2', 'c_bool'))); + $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_2')); - $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_3')); - $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'i_bug_12012_3', array('c_bug_12012_2'))); - $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_3')); + $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_3')); + $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'bug_12012_3', array('c_bug_12012_2'))); + $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_3')); // Remove the column $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2')); diff --git a/tests/dbal/select_test.php b/tests/dbal/select_test.php index e480716a49..b7074552ba 100644 --- a/tests/dbal/select_test.php +++ b/tests/dbal/select_test.php @@ -233,6 +233,66 @@ class phpbb_dbal_select_test extends phpbb_database_test_case $db->sql_freeresult($result); } + public function not_like_expression_data() + { + // * = any_char; # = one_char + return array( + array('barfoo', array( + array('username_clean' => 'foobar'), + array('username_clean' => 'bertie') + )), + array('bar', array( + array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'), + array('username_clean' => 'bertie'), + )), + array('bar*', array( + array('username_clean' => 'foobar'), + array('username_clean' => 'bertie')) + ), + array('*bar*', array(array('username_clean' => 'bertie'))), + array('b*r', array( + array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'), + array('username_clean' => 'bertie') + )), + array('b*e', array( + array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar') + )), + array('#b*e', array( + array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar'), + array('username_clean' => 'bertie') + )), + array('b####e', array( + array('username_clean' => 'barfoo'), + array('username_clean' => 'foobar') + )), + ); + } + + /** + * @dataProvider not_like_expression_data + */ + public function test_not_like_expression($like_expression, $expected) + { + $db = $this->new_dbal(); + + $like_expression = str_replace('*', $db->get_any_char(), $like_expression); + $like_expression = str_replace('#', $db->get_one_char(), $like_expression); + $where = ($like_expression) ? 'username_clean ' . $db->sql_not_like_expression($like_expression) : ''; + + $result = $db->sql_query('SELECT username_clean + FROM phpbb_users + ' . (($where) ? ' WHERE ' . $where : '') . ' + ORDER BY user_id ASC'); + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + + $db->sql_freeresult($result); + } + public function in_set_data() { return array( diff --git a/tests/di/create_container_test.php b/tests/di/create_container_test.php index 559c0b122c..4ae6017989 100644 --- a/tests/di/create_container_test.php +++ b/tests/di/create_container_test.php @@ -191,6 +191,10 @@ namespace phpbb\db\driver { } + function sql_not_like_expression($expression) + { + } + function sql_fetchrowset($query_id = false) { return array( diff --git a/tests/extension/ext/vendor3/foo/composer.json b/tests/extension/ext/vendor3/foo/composer.json new file mode 100644 index 0000000000..b4b3e6f32f --- /dev/null +++ b/tests/extension/ext/vendor3/foo/composer.json @@ -0,0 +1,23 @@ +{ + "name": "vendor3/foo", + "type": "phpbb-extension", + "description": "An example/sample extension to be used for testing purposes in phpBB Development.", + "version": "1.0.0", + "time": "2012-02-15 01:01:01", + "license": "GPL-2.0", + "authors": [{ + "name": "John Smith", + "email": "email@phpbb.com", + "homepage": "http://phpbb.com", + "role": "N/A" + }], + "require": { + "php": ">=5.3" + }, + "extra": { + "display-name": "phpBB Bar Extension", + "soft-require": { + "phpbb/phpbb": "3.1.*@dev" + } + } +} diff --git a/tests/extension/ext/vendor3/foo/ext.php b/tests/extension/ext/vendor3/foo/ext.php new file mode 100644 index 0000000000..b52649d921 --- /dev/null +++ b/tests/extension/ext/vendor3/foo/ext.php @@ -0,0 +1,20 @@ +<?php + +namespace vendor3\foo; + +class ext extends \phpbb\extension\base +{ + static public $enabled; + + public function enable_step($old_state) + { + self::$enabled = true; + + return self::$enabled; + } + + public function is_enableable() + { + return false; + } +} diff --git a/tests/extension/manager_test.php b/tests/extension/manager_test.php index 230c90c7c7..1e43c2a0a3 100644 --- a/tests/extension/manager_test.php +++ b/tests/extension/manager_test.php @@ -13,6 +13,7 @@ require_once dirname(__FILE__) . '/ext/vendor2/bar/ext.php'; require_once dirname(__FILE__) . '/ext/vendor2/foo/ext.php'; +require_once dirname(__FILE__) . '/ext/vendor3/foo/ext.php'; require_once dirname(__FILE__) . '/ext/vendor/moo/ext.php'; class phpbb_extension_manager_test extends phpbb_database_test_case @@ -35,7 +36,7 @@ class phpbb_extension_manager_test extends phpbb_database_test_case public function test_all_available() { // barfoo and vendor3/bar should not listed due to missing composer.json. barfoo also has incorrect dir structure. - $this->assertEquals(array('vendor/moo', 'vendor2/bar', 'vendor2/foo'), array_keys($this->extension_manager->all_available())); + $this->assertEquals(array('vendor/moo', 'vendor2/bar', 'vendor2/foo', 'vendor3/foo'), array_keys($this->extension_manager->all_available())); } public function test_all_enabled() @@ -100,6 +101,18 @@ class phpbb_extension_manager_test extends phpbb_database_test_case $this->assertEquals(4, vendor2\bar\ext::$state); } + public function test_enable_not_enableable() + { + vendor3\foo\ext::$enabled = false; + + $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); + $this->extension_manager->enable('vendor3/foo'); + $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); + $this->assertEquals(array('vendor/moo', 'vendor2/foo'), array_keys($this->extension_manager->all_configured())); + + $this->assertSame(false, vendor3\foo\ext::$enabled); + } + public function test_disable() { vendor2\foo\ext::$disabled = false; @@ -135,7 +148,7 @@ class phpbb_extension_manager_test extends phpbb_database_test_case protected function create_extension_manager($with_cache = true) { - $config = new \phpbb\config\config(array()); + $config = new \phpbb\config\config(array('version' => PHPBB_VERSION)); $db = $this->new_dbal(); $db_tools = new \phpbb\db\tools($db); $phpbb_root_path = __DIR__ . './../../phpBB/'; diff --git a/tests/functional/download_test.php b/tests/functional/download_test.php index 6a6df14c81..4e4995c21e 100644 --- a/tests/functional/download_test.php +++ b/tests/functional/download_test.php @@ -80,20 +80,6 @@ class phpbb_functional_download_test extends phpbb_functional_test_case 'attachments' => true, )); - // Download topic archive as guest - $crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); - self::assert_response_status_code(200); - $content = self::$client->getResponse()->getContent(); - $finfo = new finfo(FILEINFO_MIME_TYPE); - self::assertEquals('application/zip', $finfo->buffer($content)); - - // Download post archive as guest - $crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); - self::assert_response_status_code(200); - $content = self::$client->getResponse()->getContent(); - $finfo = new finfo(FILEINFO_MIME_TYPE); - self::assertEquals('application/zip', $finfo->buffer($content)); - // Download attachment as guest $crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false); self::assert_response_status_code(200); @@ -147,18 +133,6 @@ class phpbb_functional_download_test extends phpbb_functional_test_case )); $this->add_lang('viewtopic'); - // Download topic archive as guest: still works - $crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); - self::assert_response_status_code(200); - $content = self::$client->getResponse()->getContent(); - $finfo = new finfo(FILEINFO_MIME_TYPE); - self::assertEquals('application/zip', $finfo->buffer($content)); - - // No download post archive as guest - $crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); - self::assert_response_html(404); - $this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); - // No download attachment as guest $crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false); self::assert_response_html(404); @@ -167,20 +141,6 @@ class phpbb_functional_download_test extends phpbb_functional_test_case // Login as admin and try again, should work now. $this->login(); - // Download topic archive as admin - $crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); - self::assert_response_status_code(200); - $content = self::$client->getResponse()->getContent(); - $finfo = new finfo(FILEINFO_MIME_TYPE); - self::assertEquals('application/zip', $finfo->buffer($content)); - - // Download post archive as admin - $crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); - self::assert_response_status_code(200); - $content = self::$client->getResponse()->getContent(); - $finfo = new finfo(FILEINFO_MIME_TYPE); - self::assertEquals('application/zip', $finfo->buffer($content)); - // Download attachment as admin $crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false); self::assert_response_status_code(200); @@ -235,16 +195,6 @@ class phpbb_functional_download_test extends phpbb_functional_test_case )); $this->add_lang('viewtopic'); - // Download topic archive as guest: still works - $crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); - self::assert_response_html(404); - $this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); - - // No download post archive as guest - $crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); - self::assert_response_html(404); - $this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); - // No download attachment as guest $crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false); self::assert_response_html(404); @@ -253,20 +203,6 @@ class phpbb_functional_download_test extends phpbb_functional_test_case // Login as admin and try again, should work now. $this->login(); - // Download topic archive as admin - $crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); - self::assert_response_status_code(200); - $content = self::$client->getResponse()->getContent(); - $finfo = new finfo(FILEINFO_MIME_TYPE); - self::assertEquals('application/zip', $finfo->buffer($content)); - - // Download post archive as admin - $crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); - self::assert_response_status_code(200); - $content = self::$client->getResponse()->getContent(); - $finfo = new finfo(FILEINFO_MIME_TYPE); - self::assertEquals('application/zip', $finfo->buffer($content)); - // Download attachment as admin $crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false); self::assert_response_status_code(200); diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php index b6dd5db708..6490c1ead3 100644 --- a/tests/functional/extension_acp_test.php +++ b/tests/functional/extension_acp_test.php @@ -84,7 +84,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid); $this->assertCount(1, $crawler->filter('.ext_enabled')); - $this->assertCount(4, $crawler->filter('.ext_disabled')); + $this->assertCount(5, $crawler->filter('.ext_disabled')); $this->assertContains('phpBB Foo Extension', $crawler->filter('.ext_enabled')->eq(0)->text()); $this->assertContainsLang('EXTENSION_DISABLE', $crawler->filter('.ext_enabled')->eq(0)->text()); @@ -162,6 +162,10 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); $this->assertContains($this->lang('EXTENSION_ENABLE_CONFIRM', 'phpBB Moo Extension'), $crawler->filter('#main')->text()); + + // Correctly submit the enable form + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor3%2Ffoo&sid=' . $this->sid); + $this->assertContainsLang('EXTENSION_NOT_ENABLEABLE', $crawler->filter('.errorbox')->text()); } public function test_disable_pre() diff --git a/tests/functional/fileupload_form_test.php b/tests/functional/fileupload_form_test.php index b9d55fbd3c..e87953367f 100644 --- a/tests/functional/fileupload_form_test.php +++ b/tests/functional/fileupload_form_test.php @@ -42,8 +42,6 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case unlink($fileinfo->getPathname()); } - - parent::tearDown(); } private function upload_file($filename, $mimetype) @@ -109,9 +107,9 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case $crawler = $this->upload_file('disallowed.jpg', 'image/jpeg'); - // Hitting the UNABLE_GET_IMAGE_SIZE error means we passed the + // Hitting the ATTACHED_IMAGE_NOT_IMAGE error means we passed the // DISALLOWED_CONTENT check - $this->assertEquals($this->lang('UNABLE_GET_IMAGE_SIZE'), $crawler->filter('p.error')->text()); + $this->assertContains($this->lang('ATTACHED_IMAGE_NOT_IMAGE'), $crawler->text()); } public function test_too_large() diff --git a/tests/functional/fileupload_remote_test.php b/tests/functional/fileupload_remote_test.php index b170fc051f..6ece150b23 100644 --- a/tests/functional/fileupload_remote_test.php +++ b/tests/functional/fileupload_remote_test.php @@ -11,6 +11,8 @@ * */ +require_once __DIR__ . '/../../phpBB/includes/functions_upload.php'; + /** * @group functional */ @@ -43,8 +45,6 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case global $config, $user; $user = null; $config = array(); - - parent::tearDown(); } public function test_invalid_extension() diff --git a/tests/functional/forgot_password_test.php b/tests/functional/forgot_password_test.php index c95efc5b2e..64fa19557f 100644 --- a/tests/functional/forgot_password_test.php +++ b/tests/functional/forgot_password_test.php @@ -57,7 +57,5 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case 'config[allow_password_reset]' => 1, )); $crawler = self::submit($form); - - parent::tearDown(); } } diff --git a/tests/functional/plupload_test.php b/tests/functional/plupload_test.php index d9faec035c..ee71597ffc 100644 --- a/tests/functional/plupload_test.php +++ b/tests/functional/plupload_test.php @@ -57,8 +57,6 @@ class phpbb_functional_plupload_test extends phpbb_functional_test_case unlink($fileinfo->getPathname()); } - - parent::tearDown(); } public function get_urls() diff --git a/tests/functional/private_messages_test.php b/tests/functional/private_messages_test.php new file mode 100644 index 0000000000..1f6dc3a979 --- /dev/null +++ b/tests/functional/private_messages_test.php @@ -0,0 +1,69 @@ +<?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_private_messages_test extends phpbb_functional_test_case +{ + public function test_setup_config() + { + $this->login(); + $this->admin_login(); + + $crawler = self::request('GET', "adm/index.php?sid={$this->sid}&i=board&mode=message"); + + $form = $crawler->selectButton('Submit')->form(); + $values = $form->getValues(); + + // Set the maximum number of private messages per folder to 1 + $values['config[pm_max_msgs]'] = 1; + + $form->setValues($values); + + $crawler = self::submit($form); + $this->assertContains($this->lang('CONFIG_UPDATED'), $crawler->filter('.successbox')->text()); + } + + public function test_inbox_full() + { + $this->login(); + $message_id = $this->create_private_message('Test private message #1', 'This is a test private message sent by the testing framework.', array(2)); + + $crawler = self::request('GET', "ucp.php?i=pm&mode=view&sid{$this->sid}&p={$message_id}"); + $this->assertContains($this->lang('UCP_PM_VIEW'), $crawler->filter('html')->text()); + + $message_id = $this->create_private_message('Test private message #2', 'This is a test private message sent by the testing framework.', array(2)); + + $crawler = self::request('GET', "ucp.php?i=pm&mode=view&sid{$this->sid}&p={$message_id}"); + $this->assertContains($this->lang('NO_AUTH_READ_HOLD_MESSAGE'), $crawler->filter('html')->text()); + } + + public function test_restore_config() + { + $this->login(); + $this->admin_login(); + + $crawler = self::request('GET', "adm/index.php?sid={$this->sid}&i=board&mode=message"); + + $form = $crawler->selectButton('Submit')->form(); + $values = $form->getValues(); + + $values['config[pm_max_msgs]'] = 50; + + $form->setValues($values); + + $crawler = self::submit($form); + $this->assertContains($this->lang('CONFIG_UPDATED'), $crawler->filter('.successbox')->text()); + } +} diff --git a/tests/functions/insert_config_array_test.php b/tests/functions/insert_config_array_test.php new file mode 100644 index 0000000000..bfcb05862e --- /dev/null +++ b/tests/functions/insert_config_array_test.php @@ -0,0 +1,142 @@ +<?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. +* +*/ + +class phpbb_functions_insert_config_array_test extends phpbb_test_case +{ + public function config_display_vars() + { + return array( + 'legend1' => '', + 'acp_config_1' => array(), + 'acp_config_2' => array(), + 'acp_config_3' => array(), + 'acp_config_4' => array(), + 'acp_config_5' => array(), + ); + } + + public function insert_config_array_data() + { + return array( + array( // Add a new config after 1st array item + array('new_config_1' => array()), + array('after' => 'legend1'), + array( + 'legend1' => '', + 'new_config_1' => array(), + 'acp_config_1' => array(), + 'acp_config_2' => array(), + 'acp_config_3' => array(), + 'acp_config_4' => array(), + 'acp_config_5' => array(), + ), + ), + array( // Add a new config after last array item + array('new_config_1' => array()), + array('after' => 'acp_config_5'), + array( + 'legend1' => '', + 'acp_config_1' => array(), + 'acp_config_2' => array(), + 'acp_config_3' => array(), + 'acp_config_4' => array(), + 'acp_config_5' => array(), + 'new_config_1' => array(), + ), + ), + array( // Add a new config before 2nd array item + array('new_config_1' => array()), + array('before' => 'acp_config_1'), + array( + 'legend1' => '', + 'new_config_1' => array(), + 'acp_config_1' => array(), + 'acp_config_2' => array(), + 'acp_config_3' => array(), + 'acp_config_4' => array(), + 'acp_config_5' => array(), + ), + ), + array( // Add a new config before last config item + array('new_config_1' => array()), + array('before' => 'acp_config_5'), + array( + 'legend1' => '', + 'acp_config_1' => array(), + 'acp_config_2' => array(), + 'acp_config_3' => array(), + 'acp_config_4' => array(), + 'new_config_1' => array(), + 'acp_config_5' => array(), + ), + ), + array( // When an array key does not exist + array('new_config_1' => array()), + array('after' => 'foobar'), + array( + 'legend1' => '', + 'acp_config_1' => array(), + 'acp_config_2' => array(), + 'acp_config_3' => array(), + 'acp_config_4' => array(), + 'acp_config_5' => array(), + ), + ), + array( // When after|before is not used correctly (defaults to after) + array('new_config_1' => array()), + array('foobar' => 'acp_config_1'), + array( + 'legend1' => '', + 'acp_config_1' => array(), + 'new_config_1' => array(), + 'acp_config_2' => array(), + 'acp_config_3' => array(), + 'acp_config_4' => array(), + 'acp_config_5' => array(), + ), + ), + array( // Add a new config set after the last array item + array( + 'legend2' => array(), + 'new_config_1' => array(), + 'new_config_2' => array(), + 'new_config_3' => array(), + ), + array('after' => 'acp_config_5'), + array( + 'legend1' => '', + 'acp_config_1' => array(), + 'acp_config_2' => array(), + 'acp_config_3' => array(), + 'acp_config_4' => array(), + 'acp_config_5' => array(), + 'legend2' => array(), + 'new_config_1' => array(), + 'new_config_2' => array(), + 'new_config_3' => array(), + ), + ), + ); + } + + /** + * @dataProvider insert_config_array_data + */ + public function test_insert_config_array($new_config, $position, $expected) + { + $config_array = $this->config_display_vars(); + $new_config_array = phpbb_insert_config_array($config_array, $new_config, $position); + + $this->assertSame($expected, $new_config_array); + } +} diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php index c22c4c5ad2..bd926e2a98 100644 --- a/tests/notification/submit_post_base.php +++ b/tests/notification/submit_post_base.php @@ -100,7 +100,7 @@ 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, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE)); + $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)); $user_loader = new \phpbb\user_loader($db, $phpbb_root_path, $phpEx, USERS_TABLE); diff --git a/tests/profilefields/type_googleplus_test.php b/tests/profilefields/type_googleplus_test.php index fdbdd86553..3e0af36a73 100644 --- a/tests/profilefields/type_googleplus_test.php +++ b/tests/profilefields/type_googleplus_test.php @@ -11,8 +11,27 @@ * */ +require_once __DIR__ . '/../../phpBB/includes/utf/utf_tools.php'; + class phpbb_profilefield_type_googleplus_test extends phpbb_test_case { + protected $field; + + public function setUp() + { + parent::setUp(); + + $user = new \phpbb\user(); + $user->add_lang('ucp'); + $request = $this->getMock('\phpbb\request\request'); + $template = $this->getMock('\phpbb\template\template'); + + $this->field = new \phpbb\profilefields\type\type_googleplus( + $request, + $template, + $user + ); + } public function get_profile_contact_value_data() { return array( @@ -36,16 +55,6 @@ class phpbb_profilefield_type_googleplus_test extends phpbb_test_case */ public function test_get_profile_contact_value($value, $field_options, $expected, $description) { - $user = $this->getMock('\phpbb\user'); - $request = $this->getMock('\phpbb\request\request'); - $template = $this->getMock('\phpbb\template\template'); - - $field = new \phpbb\profilefields\type\type_googleplus( - $request, - $template, - $user - ); - $default_field_options = array( 'field_type' => '\phpbb\profilefields\type\type_googleplus', 'field_name' => 'field', @@ -57,6 +66,29 @@ class phpbb_profilefield_type_googleplus_test extends phpbb_test_case ); $field_options = array_merge($default_field_options, $field_options); - $this->assertSame($expected, $field->get_profile_contact_value($value, $field_options), $description); + $this->assertSame($expected, $this->field->get_profile_contact_value($value, $field_options), $description); + } + + public function data_validate_googleplus() + { + return array( + array('foobar', false), + array('2342340929304', false), + array('foo<bar', 'The field “googleplus” has invalid characters.'), + array('klkd.klkl', false), + array('kl+', 'The field “googleplus” has invalid characters.'), + array('foo=bar', 'The field “googleplus” has invalid characters.'), + array('..foo', 'The field “googleplus” has invalid characters.'), + array('foo..bar', 'The field “googleplus” has invalid characters.'), + ); + } + + /** + * @dataProvider data_validate_googleplus + */ + public function test_validate_googleplus($input, $expected) + { + $field_data = array_merge(array('lang_name' => 'googleplus'), $this->field->get_default_option_values()); + $this->assertSame($expected, $this->field->validate_string_profile_field('string', $input, $field_data)); } } diff --git a/tests/profilefields/type_string_test.php b/tests/profilefields/type_string_test.php index f6c14ee38b..2277526758 100644 --- a/tests/profilefields/type_string_test.php +++ b/tests/profilefields/type_string_test.php @@ -249,8 +249,14 @@ class phpbb_profilefield_type_string_test extends phpbb_test_case array( 0, array('field_show_novalue' => false), - null, - 'Field should return null for empty integer without show_novalue', + 0, + 'Field should return value of integer 0 without show_novalue', + ), + array( + '0', + array('field_show_novalue' => false), + '0', + 'Field should return string 0', ), array( 0, diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 07ef826abf..c131754d23 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -11,12 +11,14 @@ * */ use Symfony\Component\BrowserKit\CookieJar; -use Behat\Mink\Driver\Goutte\Client; -use Behat\Mink\Driver\GoutteDriver; -class phpbb_functional_test_case extends phpbb_mink_test_case +require_once __DIR__ . '/../../phpBB/includes/functions_install.php'; + +class phpbb_functional_test_case extends phpbb_test_case { + static protected $client; static protected $cookieJar; + static protected $root_url; protected $cache = null; protected $db = null; @@ -34,6 +36,7 @@ class phpbb_functional_test_case extends phpbb_mink_test_case */ protected $lang = array(); + static protected $config = array(); static protected $already_installed = false; static public function setUpBeforeClass() @@ -43,24 +46,6 @@ class phpbb_functional_test_case extends phpbb_mink_test_case self::$config = phpbb_test_case_helpers::get_test_config(); self::$root_url = self::$config['phpbb_functional_url']; - self::$cookieJar = new CookieJar; - self::$client = new Client(array(), null, self::$cookieJar); - - $client_options = array( - Guzzle\Http\Client::DISABLE_REDIRECTS => true, - 'curl.options' => array( - CURLOPT_TIMEOUT => 120, - ), - ); - - self::$client->setClient(new Guzzle\Http\Client('', $client_options)); - - // Reset the curl handle because it is 0 at this point and not a valid - // resource - self::$client->getClient()->getCurlMulti()->reset(true); - - self::$driver = new GoutteDriver(self::$client); - // Important: this is used both for installation and by // test cases for querying the tables. // Therefore table prefix must be set before a board is @@ -93,6 +78,12 @@ class phpbb_functional_test_case extends phpbb_mink_test_case $this->bootstrap(); + self::$cookieJar = new CookieJar; + self::$client = new Goutte\Client(array(), null, self::$cookieJar); + // Reset the curl handle because it is 0 at this point and not a valid + // resource + self::$client->getClient()->getCurlMulti()->reset(true); + // Clear the language array so that things // that were added in other tests are gone $this->lang = array(); @@ -119,14 +110,13 @@ class phpbb_functional_test_case extends phpbb_mink_test_case protected function tearDown() { + parent::tearDown(); + if ($this->db instanceof \phpbb\db\driver\driver_interface) { // Close the database connections again this test $this->db->sql_close(); } - - self::$cookieJar->clear(); - parent::tearDown(); } /** @@ -266,6 +256,144 @@ class phpbb_functional_test_case extends phpbb_mink_test_case return $extension_manager; } + static protected function install_board() + { + global $phpbb_root_path, $phpEx; + + self::recreate_database(self::$config); + + $config_file = $phpbb_root_path . "config.$phpEx"; + $config_file_dev = $phpbb_root_path . "config_dev.$phpEx"; + $config_file_test = $phpbb_root_path . "config_test.$phpEx"; + + if (file_exists($config_file)) + { + if (!file_exists($config_file_dev)) + { + rename($config_file, $config_file_dev); + } + else + { + unlink($config_file); + } + } + + self::$cookieJar = new CookieJar; + self::$client = new Goutte\Client(array(), null, self::$cookieJar); + // Set client manually so we can increase the cURL timeout + self::$client->setClient(new Guzzle\Http\Client('', array( + Guzzle\Http\Client::DISABLE_REDIRECTS => true, + 'curl.options' => array( + CURLOPT_TIMEOUT => 120, + ), + ))); + + // Reset the curl handle because it is 0 at this point and not a valid + // resource + self::$client->getClient()->getCurlMulti()->reset(true); + + $parseURL = parse_url(self::$config['phpbb_functional_url']); + + $crawler = self::request('GET', 'install/index.php?mode=install&language=en'); + self::assertContains('Welcome to Installation', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(); + + // install/index.php?mode=install&sub=requirements + $crawler = self::submit($form); + self::assertContains('Installation compatibility', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(); + + // install/index.php?mode=install&sub=database + $crawler = self::submit($form); + self::assertContains('Database configuration', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(array( + // Installer uses 3.0-style dbms name + 'dbms' => str_replace('phpbb\db\driver\\', '', self::$config['dbms']), + 'dbhost' => self::$config['dbhost'], + 'dbport' => self::$config['dbport'], + 'dbname' => self::$config['dbname'], + 'dbuser' => self::$config['dbuser'], + 'dbpasswd' => self::$config['dbpasswd'], + 'table_prefix' => self::$config['table_prefix'], + )); + + // install/index.php?mode=install&sub=database + $crawler = self::submit($form); + self::assertContains('Successful connection', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(); + + // install/index.php?mode=install&sub=administrator + $crawler = self::submit($form); + self::assertContains('Administrator configuration', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(array( + 'default_lang' => 'en', + 'admin_name' => 'admin', + 'admin_pass1' => 'adminadmin', + 'admin_pass2' => 'adminadmin', + 'board_email' => 'nobody@example.com', + )); + + // install/index.php?mode=install&sub=administrator + $crawler = self::submit($form); + self::assertContains('Tests passed', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(); + + // We have to skip install/index.php?mode=install&sub=config_file + // because that step will create a config.php file if phpBB has the + // permission to do so. We have to create the config file on our own + // in order to get the DEBUG constants defined. + $config_php_data = phpbb_create_config_file_data(self::$config, self::$config['dbms'], true, false, true); + $config_created = file_put_contents($config_file, $config_php_data) !== false; + if (!$config_created) + { + self::markTestSkipped("Could not write $config_file file."); + } + + // We also have to create a install lock that is normally created by + // the installer. The file will be removed by the final step of the + // installer. + $install_lock_file = $phpbb_root_path . 'cache/install_lock'; + $lock_created = file_put_contents($install_lock_file, '') !== false; + if (!$lock_created) + { + self::markTestSkipped("Could not create $lock_created file."); + } + @chmod($install_lock_file, 0666); + + // install/index.php?mode=install&sub=advanced + $form_data = $form->getValues(); + unset($form_data['submit']); + + $crawler = self::request('POST', 'install/index.php?mode=install&sub=advanced', $form_data); + self::assertContains('The settings on this page are only necessary to set if you know that you require something different from the default.', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(array( + 'email_enable' => true, + 'smtp_delivery' => true, + 'smtp_host' => 'nxdomain.phpbb.com', + 'smtp_auth' => 'PLAIN', + 'smtp_user' => 'nxuser', + 'smtp_pass' => 'nxpass', + 'cookie_secure' => false, + 'force_server_vars' => false, + 'server_protocol' => $parseURL['scheme'] . '://', + 'server_name' => 'localhost', + 'server_port' => isset($parseURL['port']) ? (int) $parseURL['port'] : 80, + 'script_path' => $parseURL['path'], + )); + + // install/index.php?mode=install&sub=create_table + $crawler = self::submit($form); + self::assertContains('The database tables used by phpBB', $crawler->filter('#main')->text()); + self::assertContains('have been created and populated with some initial data.', $crawler->filter('#main')->text()); + $form = $crawler->selectButton('submit')->form(); + + // install/index.php?mode=install&sub=final + $crawler = self::submit($form); + self::assertContains('You have successfully installed', $crawler->text()); + + copy($config_file, $config_file_test); + } + public function install_ext($extension) { $this->login(); @@ -284,6 +412,12 @@ class phpbb_functional_test_case extends phpbb_mink_test_case $this->logout(); } + static private function recreate_database($config) + { + $db_conn_mgr = new phpbb_database_test_connection_manager($config); + $db_conn_mgr->recreate_db(); + } + /** * Creates a new style * @@ -897,6 +1031,76 @@ class phpbb_functional_test_case extends phpbb_mink_test_case { $this->add_lang('posting'); + $crawler = $this->submit_message($posting_url, $posting_contains, $form_data); + + if ($expected !== '') + { + if (isset($this->lang[$expected])) + { + $this->assertContainsLang($expected, $crawler->filter('html')->text()); + } + else + { + $this->assertContains($expected, $crawler->filter('html')->text()); + } + return null; + } + + $url = $crawler->selectLink($form_data['subject'])->link()->getUri(); + + return array( + 'topic_id' => $this->get_parameter_from_link($url, 't'), + 'post_id' => $this->get_parameter_from_link($url, 'p'), + ); + } + + /** + * Creates a private message + * + * Be sure to login before creating + * + * @param string $subject + * @param string $message + * @param array $to + * @param array $additional_form_data Any additional form data to be sent in the request + * @return int private_message_id + */ + public function create_private_message($subject, $message, $to, $additional_form_data = array()) + { + $this->add_lang(array('ucp', 'posting')); + + $posting_url = "ucp.php?i=pm&mode=compose&sid={$this->sid}"; + + $form_data = array_merge(array( + 'subject' => $subject, + 'message' => $message, + 'post' => true, + ), $additional_form_data); + + foreach ($to as $user_id) + { + $form_data['address_list[u][' . $user_id . ']'] = 'to'; + } + + $crawler = self::submit_message($posting_url, 'POST_NEW_PM', $form_data); + + $this->assertContains($this->lang('MESSAGE_STORED'), $crawler->filter('html')->text()); + $url = $crawler->selectLink($this->lang('VIEW_PRIVATE_MESSAGE', '', ''))->link()->getUri(); + + return $this->get_parameter_from_link($url, 'p'); + } + + /** + * Helper for submitting a message (post or private message) + * + * @param string $posting_url + * @param string $posting_contains + * @param array $form_data + * @return \Symfony\Component\DomCrawler\Crawler the crawler object + */ + protected function submit_message($posting_url, $posting_contains, $form_data) + { + $crawler = self::request('GET', $posting_url); $this->assertContains($this->lang($posting_contains), $crawler->filter('html')->text()); @@ -938,27 +1142,7 @@ class phpbb_functional_test_case extends phpbb_mink_test_case // I use a request because the form submission method does not allow you to send data that is not // contained in one of the actual form fields that the browser sees (i.e. it ignores "hidden" inputs) // Instead, I send it as a request with the submit button "post" set to true. - $crawler = self::request('POST', $posting_url, $form_data); - - if ($expected !== '') - { - if (isset($this->lang[$expected])) - { - $this->assertContainsLang($expected, $crawler->filter('html')->text()); - } - else - { - $this->assertContains($expected, $crawler->filter('html')->text()); - } - return null; - } - - $url = $crawler->selectLink($form_data['subject'])->link()->getUri(); - - return array( - 'topic_id' => $this->get_parameter_from_link($url, 't'), - 'post_id' => $this->get_parameter_from_link($url, 'p'), - ); + return self::request('POST', $posting_url, $form_data); } /** diff --git a/tests/test_framework/phpbb_mink_test_case.php b/tests/test_framework/phpbb_mink_test_case.php deleted file mode 100644 index ba480e35fb..0000000000 --- a/tests/test_framework/phpbb_mink_test_case.php +++ /dev/null @@ -1,183 +0,0 @@ -<?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. -* -*/ -use \Behat\Mink\Session; - -require_once __DIR__ . '/../../phpBB/includes/functions_install.php'; - -abstract class phpbb_mink_test_case extends phpbb_test_case -{ - static protected $driver; - static protected $client; - static protected $session; - static protected $config = array(); - static protected $root_url; - - public function __construct($name = null, array $data = array(), $dataName = '') - { - parent::__construct($name, $data, $dataName); - - $this->backupStaticAttributesBlacklist += array( - 'phpbb_mink_test_case' => array('config', 'already_installed'), - ); - } - - static public function setUpBeforeClass() - { - parent::setUpBeforeClass(); - } - - public function setUp() - { - parent::setUp(); - - if (!self::$driver) - { - self::markTestSkipped('Mink driver not initialized.'); - } - - if (!self::$session) - { - self::$session = new Session(self::$driver); - } - } - - static protected function recreate_database($config) - { - $db_conn_mgr = new phpbb_database_test_connection_manager($config); - $db_conn_mgr->recreate_db(); - } - - protected function tearDown() - { - self::$session->reset(); - parent::tearDown(); - } - - static protected function visit($path) - { - self::$session->visit(self::$root_url . $path); - return self::$session->getPage(); - } - - static protected function click_submit($submit_button_id = 'submit') - { - self::$session->getPage()->findById($submit_button_id)->click(); - return self::$session->getPage(); - } - - static protected function install_board() - { - global $phpbb_root_path, $phpEx; - - self::recreate_database(self::$config); - self::$session = new Session(self::$driver); - - $config_file = $phpbb_root_path . "config.$phpEx"; - $config_file_dev = $phpbb_root_path . "config_dev.$phpEx"; - $config_file_test = $phpbb_root_path . "config_test.$phpEx"; - - if (file_exists($config_file)) - { - if (!file_exists($config_file_dev)) - { - rename($config_file, $config_file_dev); - } - else - { - unlink($config_file); - } - } - - $parseURL = parse_url(self::$config['phpbb_functional_url']); - - $page = self::visit('install/index.php?mode=install'); - self::assertContains('Welcome to Installation', $page->findById('main')->getText()); - - // install/index.php?mode=install&sub=requirements - $page = self::click_submit(); - self::assertContains('Installation compatibility', $page->findById('main')->getText()); - - // install/index.php?mode=install&sub=database - $page = self::click_submit(); - self::assertContains('Database configuration', $page->findById('main')->getText()); - - $page->findById('dbms')->setValue(str_replace('phpbb\db\driver\\', '', self::$config['dbms'])); - $page->findById('dbhost')->setValue(self::$config['dbhost']); - $page->findById('dbport')->setValue(self::$config['dbport']); - $page->findById('dbname')->setValue(self::$config['dbname']); - $page->findById('dbuser')->setValue(self::$config['dbuser']); - $page->findById('dbpasswd')->setValue(self::$config['dbpasswd']); - $page->findById('table_prefix')->setValue(self::$config['table_prefix']); - - // install/index.php?mode=install&sub=database - $page = self::click_submit(); - self::assertContains('Successful connection', $page->findById('main')->getText()); - - // install/index.php?mode=install&sub=administrator - $page = self::click_submit(); - self::assertContains('Administrator configuration', $page->findById('main')->getText()); - - $page->findById('admin_name')->setValue('admin'); - $page->findById('admin_pass1')->setValue('adminadmin'); - $page->findById('admin_pass2')->setValue('adminadmin'); - $page->findById('board_email')->setValue('nobody@example.com'); - - // install/index.php?mode=install&sub=administrator - $page = self::click_submit(); - self::assertContains('Tests passed', $page->findById('main')->getText()); - - // install/index.php?mode=install&sub=config_file - $page = self::click_submit(); - - // Installer has created a config.php file, we will overwrite it with a - // config file of our own in order to get the DEBUG constants defined - $config_php_data = phpbb_create_config_file_data(self::$config, self::$config['dbms'], true, false, true); - $config_created = file_put_contents($config_file, $config_php_data) !== false; - if (!$config_created) - { - self::markTestSkipped("Could not write $config_file file."); - } - - if (strpos($page->findById('main')->getText(), 'The configuration file has been written') === false) - { - $page = self::click_submit('dldone'); - } - self::assertContains('The configuration file has been written', $page->findById('main')->getText()); - - // install/index.php?mode=install&sub=advanced - $page = self::click_submit(); - self::assertContains('The settings on this page are only necessary to set if you know that you require something different from the default.', $page->findById('main')->getText()); - - $page->findById('smtp_delivery')->setValue('1'); - $page->findById('smtp_host')->setValue('nxdomain.phpbb.com'); - $page->findById('smtp_user')->setValue('nxuser'); - $page->findById('smtp_pass')->setValue('nxpass'); - $page->findById('server_protocol')->setValue($parseURL['scheme'] . '://'); - $page->findById('server_name')->setValue('localhost'); - $page->findById('server_port')->setValue(isset($parseURL['port']) ? $parseURL['port'] : 80); - $page->findById('script_path')->setValue($parseURL['path']); - - // install/index.php?mode=install&sub=create_table - $page = self::click_submit(); - self::assertContains('The database tables used by phpBB', $page->findById('main')->getText()); - self::assertContains('have been created and populated with some initial data.', $page->findById('main')->getText()); - - // install/index.php?mode=install&sub=final - $page = self::click_submit(); - self::assertContains('You have successfully installed', $page->getText()); - - copy($config_file, $config_file_test); - - self::$session->stop(); - } -} diff --git a/tests/upload/filespec_test.php b/tests/upload/filespec_test.php index 5e333213f4..d8fa82e2b5 100644 --- a/tests/upload/filespec_test.php +++ b/tests/upload/filespec_test.php @@ -65,6 +65,16 @@ class phpbb_filespec_test extends phpbb_test_case copy($fileinfo->getPathname(), $this->path . 'copies/' . $fileinfo->getFilename() . '_copy_2'); } } + + $guessers = array( + new \Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser(), + new \Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser(), + new \phpbb\mimetype\content_guesser(), + new \phpbb\mimetype\extension_guesser(), + ); + $guessers[2]->set_priority(-2); + $guessers[3]->set_priority(-2); + $this->mimetype_guesser = new \phpbb\mimetype\guesser($guessers); } private function get_filespec($override = array()) @@ -78,7 +88,7 @@ class phpbb_filespec_test extends phpbb_test_case 'error' => '', ); - return new filespec(array_merge($upload_ary, $override), null); + return new filespec(array_merge($upload_ary, $override), null, $this->mimetype_guesser); } protected function tearDown() @@ -222,6 +232,9 @@ class phpbb_filespec_test extends phpbb_test_case array('png', 'image/png', true), array('tif', 'image/tif', true), array('txt', 'text/plain', false), + array('jpg', 'application/octet-stream', false), + array('gif', 'application/octetstream', false), + array('png', 'application/mime', false), ); } @@ -234,6 +247,30 @@ class phpbb_filespec_test extends phpbb_test_case $this->assertEquals($expected, $filespec->is_image()); } + public function is_image_get_mimetype() + { + return array( + array('gif', 'image/gif', true), + array('jpg', 'image/jpg', true), + array('png', 'image/png', true), + array('tif', 'image/tif', true), + array('txt', 'text/plain', false), + array('jpg', 'application/octet-stream', true), + array('gif', 'application/octetstream', true), + array('png', 'application/mime', true), + ); + } + + /** + * @dataProvider is_image_get_mimetype + */ + public function test_is_image_get_mimetype($filename, $mimetype, $expected) + { + $filespec = $this->get_filespec(array('tmp_name' => $this->path . $filename, 'type' => $mimetype)); + $filespec->get_mimetype($this->path . $filename); + $this->assertEquals($expected, $filespec->is_image()); + } + public function move_file_variables() { return array( diff --git a/travis/check-executable-files.sh b/travis/check-executable-files.sh new file mode 100755 index 0000000000..4d420add1c --- /dev/null +++ b/travis/check-executable-files.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# +# 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. +# +set -e + +DB=$1 +TRAVIS_PHP_VERSION=$2 +root="$3" +path="${root}phpBB/" + +if [ "$TRAVIS_PHP_VERSION" == "5.3.3" -a "$DB" == "mysqli" ] +then + # Check the permissions of the files + + # The following variables MUST NOT contain any wildcard + # Directories to skip + directories_skipped="-path ${path}develop -o -path ${path}vendor" + + # Files to skip + files_skipped="-false" + + # Files which have to be executable + executable_files="-path ${path}bin/*" + + incorrect_files=$( \ + find ${path} \ + '(' \ + '(' \ + ${directories_skipped} \ + ')' \ + -a -type d -prune -a -type f \ + ')' -o \ + '(' \ + -type f -a \ + -not '(' \ + ${files_skipped} \ + ')' -a \ + '(' \ + '(' \ + '(' \ + ${executable_files} \ + ')' -a \ + -not -perm +100 \ + ')' -o \ + '(' \ + -not '(' \ + ${executable_files} \ + ')' -a \ + -perm +111 \ + ')' \ + ')' \ + ')' \ + ) + + if [ "${incorrect_files}" != '' ] + then + echo "The following files do not have proper permissions:"; + ls -la ${incorrect_files} + exit 1; + fi +fi diff --git a/travis/check-image-icc-profiles.sh b/travis/check-image-icc-profiles.sh index 31848dc9e7..bb070ccc27 100755 --- a/travis/check-image-icc-profiles.sh +++ b/travis/check-image-icc-profiles.sh @@ -13,7 +13,7 @@ set -e DB=$1 TRAVIS_PHP_VERSION=$2 -if [ "$TRAVIS_PHP_VERSION" == "5.5" -a "$DB" == "mysqli" ] +if [ "$TRAVIS_PHP_VERSION" == "5.3.3" -a "$DB" == "mysqli" ] then find . -type f -not -path './phpBB/vendor/*' -iregex '.*\.\(gif\|jpg\|jpeg\|png\)$' | \ parallel --gnu --keep-order 'phpBB/develop/strip_icc_profiles.sh {}' diff --git a/travis/check-sami-parse-errors.sh b/travis/check-sami-parse-errors.sh new file mode 100755 index 0000000000..847c54a61a --- /dev/null +++ b/travis/check-sami-parse-errors.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# +# 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. +# +set -e + +DB=$1 +TRAVIS_PHP_VERSION=$2 + +if [ "$TRAVIS_PHP_VERSION" == "5.3.3" -a "$DB" == "mysqli" ] +then + # Workarounds for + # https://github.com/fabpot/Sami/issues/116 + # and + # https://github.com/fabpot/Sami/issues/117 + errors=$( + unbuffer phpBB/vendor/bin/sami.php parse travis/sami.conf.php -v | \ + sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | \ + grep "ERROR: " | \ + tee /dev/tty | \ + wc -l + ) + if [ "$errors" != "0" ] + then + exit 1 + fi +fi diff --git a/travis/sami.conf.php b/travis/sami.conf.php new file mode 100644 index 0000000000..8e7cfa42e9 --- /dev/null +++ b/travis/sami.conf.php @@ -0,0 +1,19 @@ +<?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 __DIR__ . '/../build/' . basename(__FILE__); + +// Removing the versions array key will make Sami use the current branch. +unset($config['versions']); + +return new Sami\Sami($iterator, $config); diff --git a/travis/setup-php-extensions.sh b/travis/setup-php-extensions.sh index 3655d6e952..c0defe44ef 100755 --- a/travis/setup-php-extensions.sh +++ b/travis/setup-php-extensions.sh @@ -42,12 +42,6 @@ function install_php_extension php_ini_file=$(find_php_ini) -# disable broken opcache on PHP 5.5.7 and 5.5.8 -if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.5.9', '<');"` == "1" ] -then - sed -i '/opcache.so/d' "$php_ini_file" -fi - # apc if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.5.0-dev', '<');"` == "1" ] then diff --git a/travis/setup-phpbb.sh b/travis/setup-phpbb.sh index e2cf6eeda2..d829772196 100755 --- a/travis/setup-phpbb.sh +++ b/travis/setup-phpbb.sh @@ -14,9 +14,10 @@ set -x DB=$1 TRAVIS_PHP_VERSION=$2 -if [ "$TRAVIS_PHP_VERSION" == "5.5" -a "$DB" == "mysqli" ] +if [ "$TRAVIS_PHP_VERSION" == "5.3.3" -a "$DB" == "mysqli" ] then travis/setup-exiftool.sh + travis/setup-unbuffer.sh fi if [ "$DB" == "mariadb" ] diff --git a/travis/setup-unbuffer.sh b/travis/setup-unbuffer.sh new file mode 100755 index 0000000000..4423d1b8b6 --- /dev/null +++ b/travis/setup-unbuffer.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# +# 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. +# +set -e + +sudo apt-get update +sudo apt-get install -y expect-dev diff --git a/travis/setup-webserver.sh b/travis/setup-webserver.sh index ea1929a5b0..ab045431cc 100755 --- a/travis/setup-webserver.sh +++ b/travis/setup-webserver.sh @@ -72,8 +72,11 @@ echo " index index.php index.html; location ~ \.php { - fastcgi_pass unix:$APP_SOCK; - include fastcgi_params; + include fastcgi_params; + fastcgi_split_path_info ^(.+\.php)(/.*)$; + fastcgi_param PATH_INFO \$fastcgi_path_info; + fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; + fastcgi_pass unix:$APP_SOCK; } } " | sudo tee $NGINX_CONF > /dev/null |