aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--build/build.xml196
-rwxr-xr-xbuild/package.php15
-rw-r--r--phpBB/adm/style/acp_avatar_options_local.html2
-rw-r--r--phpBB/adm/style/acp_main.html7
-rw-r--r--phpBB/adm/style/acp_styles.html1
-rw-r--r--phpBB/adm/style/admin.css23
-rw-r--r--phpBB/adm/style/captcha_recaptcha.html26
-rw-r--r--phpBB/adm/style/installer_footer.html2
-rw-r--r--phpBB/adm/style/installer_form.html24
-rw-r--r--phpBB/adm/style/installer_header.html2
-rw-r--r--phpBB/adm/style/installer_install.html2
-rw-r--r--phpBB/adm/style/installer_update.html13
-rw-r--r--phpBB/adm/style/installer_update_file_status.html80
-rw-r--r--phpBB/assets/javascript/installer.js121
-rw-r--r--phpBB/composer.json1
-rw-r--r--phpBB/composer.lock261
-rw-r--r--phpBB/config/default/config.yml1
-rw-r--r--phpBB/config/default/container/services.yml3
-rw-r--r--phpBB/config/default/container/services_attachment.yml40
-rw-r--r--phpBB/config/default/container/services_console.yml2
-rw-r--r--phpBB/config/default/container/services_event.yml9
-rw-r--r--phpBB/config/default/container/services_files.yml3
-rw-r--r--phpBB/config/default/container/services_filesystem.yml3
-rw-r--r--phpBB/config/default/container/services_hook.yml7
-rw-r--r--phpBB/config/default/container/services_routing.yml2
-rw-r--r--phpBB/config/installer/container/services.yml18
-rw-r--r--phpBB/config/installer/container/services_file_updater.yml38
-rw-r--r--phpBB/config/installer/container/services_install_controller.yml19
-rw-r--r--phpBB/config/installer/container/services_install_navigation.yml8
-rw-r--r--phpBB/config/installer/container/services_install_obtain_data.yml2
-rw-r--r--phpBB/config/installer/container/services_install_requirements.yml3
-rw-r--r--phpBB/config/installer/container/services_installer.yml27
-rw-r--r--phpBB/config/installer/container/services_update_database.yml29
-rw-r--r--phpBB/config/installer/container/services_update_filesystem.yml72
-rw-r--r--phpBB/config/installer/container/services_update_obtain_data.yml53
-rw-r--r--phpBB/config/installer/container/services_update_requirements.yml40
-rw-r--r--phpBB/config/installer/routing/installer.yml15
-rw-r--r--phpBB/docs/INSTALL.html10
-rw-r--r--phpBB/docs/events.md14
-rw-r--r--phpBB/download/file.php5
-rw-r--r--phpBB/includes/acp/acp_attachments.php15
-rw-r--r--phpBB/includes/acp/acp_ban.php5
-rw-r--r--phpBB/includes/acp/acp_bots.php6
-rw-r--r--phpBB/includes/acp/acp_disallow.php4
-rw-r--r--phpBB/includes/acp/acp_email.php11
-rw-r--r--phpBB/includes/acp/acp_forums.php31
-rw-r--r--phpBB/includes/acp/acp_groups.php10
-rw-r--r--phpBB/includes/acp/acp_inactive.php15
-rw-r--r--phpBB/includes/acp/acp_jabber.php5
-rw-r--r--phpBB/includes/acp/acp_language.php5
-rw-r--r--phpBB/includes/acp/acp_main.php31
-rw-r--r--phpBB/includes/acp/acp_permission_roles.php11
-rw-r--r--phpBB/includes/acp/acp_permissions.php11
-rw-r--r--phpBB/includes/acp/acp_profile.php11
-rw-r--r--phpBB/includes/acp/acp_prune.php6
-rw-r--r--phpBB/includes/acp/acp_send_statistics.php5
-rw-r--r--phpBB/includes/acp/acp_styles.php18
-rw-r--r--phpBB/includes/acp/acp_users.php72
-rw-r--r--phpBB/includes/functions.php21
-rw-r--r--phpBB/includes/functions_acp.php8
-rw-r--r--phpBB/includes/functions_admin.php352
-rw-r--r--phpBB/includes/functions_content.php16
-rw-r--r--phpBB/includes/functions_display.php19
-rw-r--r--phpBB/includes/functions_mcp.php36
-rw-r--r--phpBB/includes/functions_posting.php223
-rw-r--r--phpBB/includes/functions_privmsgs.php36
-rw-r--r--phpBB/includes/functions_user.php13
-rw-r--r--phpBB/includes/mcp/mcp_forum.php8
-rw-r--r--phpBB/includes/mcp/mcp_queue.php11
-rw-r--r--phpBB/includes/message_parser.php36
-rw-r--r--phpBB/includes/ucp/ucp_attachments.php10
-rw-r--r--phpBB/includes/ucp/ucp_pm.php2
-rw-r--r--phpBB/includes/ucp/ucp_pm_compose.php14
-rw-r--r--phpBB/includes/ucp/ucp_profile.php52
-rw-r--r--phpBB/install/database_update.php5
-rw-r--r--phpBB/install/index.php7
-rw-r--r--phpBB/install/install_update.php5
-rw-r--r--phpBB/install_new/app.php40
-rw-r--r--phpBB/install_new/phpbbcli.php29
-rw-r--r--phpBB/install_new/startup.php84
-rw-r--r--phpBB/language/en/captcha_recaptcha.php6
-rw-r--r--phpBB/language/en/common.php3
-rw-r--r--phpBB/language/en/install_new.php102
-rw-r--r--phpBB/language/en/ucp.php2
-rw-r--r--phpBB/memberlist.php29
-rw-r--r--phpBB/phpbb/attachment/delete.php432
-rw-r--r--phpBB/phpbb/attachment/manager.php99
-rw-r--r--phpBB/phpbb/attachment/resync.php124
-rw-r--r--phpBB/phpbb/attachment/upload.php334
-rw-r--r--phpBB/phpbb/auth/auth.php19
-rw-r--r--phpBB/phpbb/avatar/driver/gravatar.php13
-rw-r--r--phpBB/phpbb/avatar/driver/local.php6
-rw-r--r--phpBB/phpbb/captcha/plugins/recaptcha.php127
-rw-r--r--phpBB/phpbb/console/command/db/console_migrator_output_handler.php2
-rw-r--r--phpBB/phpbb/console/command/db/migrate.php9
-rw-r--r--phpBB/phpbb/console/command/db/revert.php9
-rw-r--r--phpBB/phpbb/db/driver/driver.php137
-rw-r--r--phpBB/phpbb/db/migrator.php4
-rw-r--r--phpBB/phpbb/db/output_handler/html_migrator_output_handler.php (renamed from phpBB/phpbb/db/html_migrator_output_handler.php)18
-rw-r--r--phpBB/phpbb/db/output_handler/installer_migrator_output_handler.php46
-rw-r--r--phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php (renamed from phpBB/phpbb/db/log_wrapper_migrator_output_handler.php)25
-rw-r--r--phpBB/phpbb/db/output_handler/migrator_output_handler_interface.php (renamed from phpBB/phpbb/db/migrator_output_handler_interface.php)2
-rw-r--r--phpBB/phpbb/db/output_handler/null_migrator_output_handler.php (renamed from phpBB/phpbb/db/null_migrator_output_handler.php)2
-rw-r--r--phpBB/phpbb/di/container_builder.php1
-rw-r--r--phpBB/phpbb/event/kernel_exception_subscriber.php22
-rw-r--r--phpBB/phpbb/hook/finder.php13
-rw-r--r--phpBB/phpbb/install/controller/archive_download.php93
-rw-r--r--phpBB/phpbb/install/controller/helper.php96
-rw-r--r--phpBB/phpbb/install/controller/install.php43
-rw-r--r--phpBB/phpbb/install/controller/update.php162
-rw-r--r--phpBB/phpbb/install/exception/file_updater_failure_exception.php22
-rw-r--r--phpBB/phpbb/install/exception/jump_to_restart_point_exception.php44
-rw-r--r--phpBB/phpbb/install/helper/config.php52
-rw-r--r--phpBB/phpbb/install/helper/container_factory.php54
-rw-r--r--phpBB/phpbb/install/helper/database.php2
-rw-r--r--phpBB/phpbb/install/helper/file_updater/compression_file_updater.php133
-rw-r--r--phpBB/phpbb/install/helper/file_updater/factory.php69
-rw-r--r--phpBB/phpbb/install/helper/file_updater/file_updater.php202
-rw-r--r--phpBB/phpbb/install/helper/file_updater/file_updater_interface.php49
-rw-r--r--phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php136
-rw-r--r--phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php119
-rw-r--r--phpBB/phpbb/install/helper/iohandler/cli_iohandler.php24
-rw-r--r--phpBB/phpbb/install/helper/iohandler/iohandler_base.php4
-rw-r--r--phpBB/phpbb/install/helper/iohandler/iohandler_interface.php19
-rw-r--r--phpBB/phpbb/install/helper/navigation/update_navigation.php80
-rw-r--r--phpBB/phpbb/install/helper/update_helper.php113
-rw-r--r--phpBB/phpbb/install/installer.php42
-rw-r--r--phpBB/phpbb/install/module/obtain_data/install_module.php (renamed from phpBB/phpbb/install/module/obtain_data/module.php)2
-rw-r--r--phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php2
-rw-r--r--phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php2
-rw-r--r--phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php168
-rw-r--r--phpBB/phpbb/install/module/obtain_data/task/obtain_update_files.php113
-rw-r--r--phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php164
-rw-r--r--phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php103
-rw-r--r--phpBB/phpbb/install/module/obtain_data/update_module.php33
-rw-r--r--phpBB/phpbb/install/module/requirements/abstract_requirements_module.php (renamed from phpBB/phpbb/install/module/requirements/module.php)16
-rw-r--r--phpBB/phpbb/install/module/requirements/install_module.php25
-rw-r--r--phpBB/phpbb/install/module/requirements/task/check_filesystem.php16
-rw-r--r--phpBB/phpbb/install/module/requirements/task/check_update.php185
-rw-r--r--phpBB/phpbb/install/module/requirements/update_module.php25
-rw-r--r--phpBB/phpbb/install/module/update_database/module.php33
-rw-r--r--phpBB/phpbb/install/module/update_database/task/update.php212
-rw-r--r--phpBB/phpbb/install/module/update_filesystem/module.php33
-rw-r--r--phpBB/phpbb/install/module/update_filesystem/task/diff_files.php205
-rw-r--r--phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php124
-rw-r--r--phpBB/phpbb/install/module/update_filesystem/task/file_check.php186
-rw-r--r--phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php168
-rw-r--r--phpBB/phpbb/install/module/update_filesystem/task/update_files.php294
-rw-r--r--phpBB/phpbb/install/module_base.php2
-rw-r--r--phpBB/phpbb/install/task_base.php2
-rw-r--r--phpBB/phpbb/notification/type/approve_post.php2
-rw-r--r--phpBB/phpbb/notification/type/approve_topic.php2
-rw-r--r--phpBB/phpbb/notification/type/bookmark.php2
-rw-r--r--phpBB/phpbb/notification/type/post.php2
-rw-r--r--phpBB/phpbb/notification/type/post_in_queue.php2
-rw-r--r--phpBB/phpbb/notification/type/quote.php4
-rw-r--r--phpBB/phpbb/notification/type/report_pm.php2
-rw-r--r--phpBB/phpbb/notification/type/topic_in_queue.php2
-rw-r--r--phpBB/phpbb/passwords/driver/salted_md5.php2
-rw-r--r--phpBB/phpbb/plupload/plupload.php2
-rw-r--r--phpBB/phpbb/routing/resources_locator/installer_resources_locator.php78
-rw-r--r--phpBB/phpbb/search/fulltext_mysql.php72
-rw-r--r--phpBB/phpbb/search/fulltext_native.php80
-rw-r--r--phpBB/phpbb/search/fulltext_postgres.php72
-rw-r--r--phpBB/phpbb/search/fulltext_sphinx.php52
-rw-r--r--phpBB/posting.php13
-rw-r--r--phpBB/search.php2
-rw-r--r--phpBB/styles/prosilver/template/captcha_recaptcha.html19
-rw-r--r--phpBB/styles/prosilver/template/forum_fn.js5
-rw-r--r--phpBB/styles/prosilver/template/memberlist_body.html4
-rw-r--r--phpBB/styles/prosilver/template/memberlist_team.html6
-rw-r--r--phpBB/styles/prosilver/template/navbar_footer.html2
-rw-r--r--phpBB/styles/prosilver/template/navbar_header.html3
-rw-r--r--phpBB/styles/prosilver/template/quickreply_editor.html1
-rw-r--r--phpBB/styles/prosilver/template/simple_header.html1
-rw-r--r--phpBB/styles/prosilver/template/ucp_avatar_options_local.html3
-rw-r--r--phpBB/styles/prosilver/template/viewtopic_body.html4
-rw-r--r--phpBB/styles/prosilver/theme/content.css4
-rw-r--r--phpBB/styles/prosilver/theme/plupload.css5
-rw-r--r--phpBB/styles/prosilver/theme/responsive.css10
-rw-r--r--phpBB/viewonline.php2
-rw-r--r--tests/attachment/delete_test.php127
-rw-r--r--tests/attachment/fixtures/resync.xml130
-rw-r--r--tests/attachment/manager_test.php131
-rw-r--r--tests/attachment/resync_test.php74
-rw-r--r--tests/attachment/upload_test.php430
-rw-r--r--tests/content_visibility/delete_post_test.php3
-rw-r--r--tests/dbal/boolean_processor_test.php306
-rw-r--r--tests/dbal/fixtures/boolean_processor.xml84
-rw-r--r--tests/di/fixtures/other_config/production/config.yml2
-rw-r--r--tests/di/fixtures/other_config/production/container/environment.yml29
-rw-r--r--tests/event/exception_listener_test.php4
-rw-r--r--tests/functions_user/delete_user_test.php4
-rw-r--r--tests/installer/installer_config_test.php19
-rw-r--r--tests/privmsgs/delete_user_pms_test.php4
-rwxr-xr-xtravis/setup-php-extensions.sh3
197 files changed, 8130 insertions, 1436 deletions
diff --git a/.travis.yml b/.travis.yml
index 4f9734a19a..8d0fe27203 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,7 +25,6 @@ matrix:
- php: hhvm
env: DB=mysqli
allow_failures:
- - php: 7.0
- php: hhvm
fast_finish: true
diff --git a/build/build.xml b/build/build.xml
index 2fe39bbf13..2985218e7b 100644
--- a/build/build.xml
+++ b/build/build.xml
@@ -321,75 +321,82 @@
<delete dir="${dir}/vendor/s9e/text-formatter/.git" />
- <delete dir="${dir}/vendor/symfony/config/Symfony/Component/Config/Tests" />
- <delete dir="${dir}/vendor/symfony/config/Symfony/Component/Config/.git" />
- <delete file="${dir}/vendor/symfony/config/Symfony/Component/Config/.gitignore" />
- <delete file="${dir}/vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/config/Symfony/Component/Config/README.md" />
- <delete file="${dir}/vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/console/Symfony/Component/Console/Tests" />
- <delete dir="${dir}/vendor/symfony/console/Symfony/Component/Console/.git" />
- <delete file="${dir}/vendor/symfony/console/Symfony/Component/Console/.gitignore" />
- <delete file="${dir}/vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/console/Symfony/Component/Console/README.md" />
- <delete file="${dir}/vendor/symfony/console/Symfony/Component/Console/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/debug/Symfony/Component/Debug/Tests" />
- <delete dir="${dir}/vendor/symfony/debug/Symfony/Component/Debug/.git" />
- <delete file="${dir}/vendor/symfony/debug/Symfony/Component/Debug/.gitignore" />
- <delete file="${dir}/vendor/symfony/debug/Symfony/Component/Debug/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/debug/Symfony/Component/Debug/README.md" />
- <delete file="${dir}/vendor/symfony/debug/Symfony/Component/Debug/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests" />
- <delete dir="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/.git" />
- <delete file="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/.gitignore" />
- <delete file="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/README.md" />
- <delete file="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/Tests" />
- <delete dir="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/.git" />
- <delete file="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/.gitignore" />
- <delete file="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/README.md" />
- <delete file="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests" />
- <delete dir="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/.git" />
- <delete file="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore" />
- <delete file="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md" />
- <delete file="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests" />
- <delete dir="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/.git" />
- <delete file="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/.gitignore" />
- <delete file="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/README.md" />
- <delete file="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests" />
- <delete dir="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/.git" />
- <delete file="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/.gitignore" />
- <delete file="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/README.md" />
- <delete file="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/routing/Symfony/Component/Routing/Tests" />
- <delete dir="${dir}/vendor/symfony/routing/Symfony/Component/Routing/.git" />
- <delete file="${dir}/vendor/symfony/routing/Symfony/Component/Routing/.gitignore" />
- <delete file="${dir}/vendor/symfony/routing/Symfony/Component/Routing/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/routing/Symfony/Component/Routing/README.md" />
- <delete file="${dir}/vendor/symfony/routing/Symfony/Component/Routing/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/Tests" />
- <delete dir="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/.git" />
- <delete file="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/.gitignore" />
- <delete file="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/README.md" />
- <delete file="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/phpunit.xml.dist" />
+ <delete dir="${dir}/vendor/symfony/config/.git" />
+ <delete dir="${dir}/vendor/symfony/config/Tests" />
+ <delete file="${dir}/vendor/symfony/config/.gitignore" />
+ <delete file="${dir}/vendor/symfony/config/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/config/README.md" />
+ <delete file="${dir}/vendor/symfony/config/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/console/.git" />
+ <delete dir="${dir}/vendor/symfony/console/Tests" />
+ <delete file="${dir}/vendor/symfony/console/.gitignore" />
+ <delete file="${dir}/vendor/symfony/console/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/console/README.md" />
+ <delete file="${dir}/vendor/symfony/console/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/debug/.git" />
+ <delete dir="${dir}/vendor/symfony/debug/Tests" />
+ <delete file="${dir}/vendor/symfony/debug/.gitignore" />
+ <delete file="${dir}/vendor/symfony/debug/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/debug/README.md" />
+ <delete file="${dir}/vendor/symfony/debug/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/dependency-injection/.git" />
+ <delete dir="${dir}/vendor/symfony/dependency-injection/Tests" />
+ <delete file="${dir}/vendor/symfony/dependency-injection/.gitignore" />
+ <delete file="${dir}/vendor/symfony/dependency-injection/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/dependency-injection/README.md" />
+ <delete file="${dir}/vendor/symfony/dependency-injection/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/event-dispatcher/.git" />
+ <delete dir="${dir}/vendor/symfony/event-dispatcher/Tests" />
+ <delete file="${dir}/vendor/symfony/event-dispatcher/.gitignore" />
+ <delete file="${dir}/vendor/symfony/event-dispatcher/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/event-dispatcher/README.md" />
+ <delete file="${dir}/vendor/symfony/event-dispatcher/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/filesystem/.git" />
+ <delete dir="${dir}/vendor/symfony/filesystem/Tests" />
+ <delete file="${dir}/vendor/symfony/filesystem/.gitignore" />
+ <delete file="${dir}/vendor/symfony/filesystem/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/filesystem/README.md" />
+ <delete file="${dir}/vendor/symfony/filesystem/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/finder/.git" />
+ <delete dir="${dir}/vendor/symfony/finder/Tests" />
+ <delete file="${dir}/vendor/symfony/finder/.gitignore" />
+ <delete file="${dir}/vendor/symfony/finder/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/finder/README.md" />
+ <delete file="${dir}/vendor/symfony/finder/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/http-foundation/.git" />
+ <delete dir="${dir}/vendor/symfony/http-foundation/Tests" />
+ <delete file="${dir}/vendor/symfony/http-foundation/.gitignore" />
+ <delete file="${dir}/vendor/symfony/http-foundation/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/http-foundation/README.md" />
+ <delete file="${dir}/vendor/symfony/http-foundation/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/http-kernel/.git" />
+ <delete dir="${dir}/vendor/symfony/http-kernel/Tests" />
+ <delete file="${dir}/vendor/symfony/http-kernel/.gitignore" />
+ <delete file="${dir}/vendor/symfony/http-kernel/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/http-kernel/README.md" />
+ <delete file="${dir}/vendor/symfony/http-kernel/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/routing/.git" />
+ <delete dir="${dir}/vendor/symfony/routing/Tests" />
+ <delete file="${dir}/vendor/symfony/routing/.gitignore" />
+ <delete file="${dir}/vendor/symfony/routing/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/routing/README.md" />
+ <delete file="${dir}/vendor/symfony/routing/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/yaml/.git" />
+ <delete dir="${dir}/vendor/symfony/yaml/Symfony/Tests" />
+ <delete file="${dir}/vendor/symfony/yaml/Symfony/.gitignore" />
+ <delete file="${dir}/vendor/symfony/yaml/Symfony/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/yaml/Symfony/README.md" />
+ <delete file="${dir}/vendor/symfony/yaml/Symfony/phpunit.xml.dist" />
<delete dir="${dir}/vendor/twig/twig/doc" />
<delete dir="${dir}/vendor/twig/twig/ext" />
@@ -402,40 +409,33 @@
<delete file="${dir}/vendor/twig/twig/phpunit.xml.dist" />
<delete file="${dir}/vendor/twig/twig/README.markdown" />
- <delete dir="${dir}/vendor/symfony/security-core/Symfony/Bridge/Twig/Tests" />
- <delete dir="${dir}/vendor/symfony/security-core/Symfony/Bridge/Twig/.git" />
- <delete file="${dir}/vendor/symfony/security-core/Symfony/Bridge/Twig/.gitignore" />
- <delete file="${dir}/vendor/symfony/security-core/Symfony/Bridge/Twig/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/security-core/Symfony/Bridge/Twig/README.md" />
- <delete file="${dir}/vendor/symfony/security-core/Symfony/Bridge/Twig/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/security-core/Symfony/Component/Security/Core/Tests" />
- <delete dir="${dir}/vendor/symfony/security-core/Symfony/Component/Security/Core/.git" />
- <delete file="${dir}/vendor/symfony/security-core/Symfony/Component/Security/Core/.gitignore" />
- <delete file="${dir}/vendor/symfony/security-core/Symfony/Component/Security/Core/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/security-core/Symfony/Component/Security/Core/README.md" />
- <delete file="${dir}/vendor/symfony/security-core/Symfony/Component/Security/Core/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/security-csrf/Symfony/Bridge/Twig/Tests" />
- <delete dir="${dir}/vendor/symfony/security-csrf/Symfony/Bridge/Twig/.git" />
- <delete file="${dir}/vendor/symfony/security-csrf/Symfony/Bridge/Twig/.gitignore" />
- <delete file="${dir}/vendor/symfony/security-csrf/Symfony/Bridge/Twig/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/security-csrf/Symfony/Bridge/Twig/README.md" />
- <delete file="${dir}/vendor/symfony/security-csrf/Symfony/Bridge/Twig/phpunit.xml.dist" />
-
- <delete dir="${dir}/vendor/symfony/security-csrf/Symfony/Component/Security/Csrf/Tests" />
- <delete dir="${dir}/vendor/symfony/security-csrf/Symfony/Component/Security/Csrf/.git" />
- <delete file="${dir}/vendor/symfony/security-csrf/Symfony/Component/Security/Csrf/.gitignore" />
- <delete file="${dir}/vendor/symfony/security-csrf/Symfony/Component/Security/Csrf/CHANGELOG.md" />
- <delete file="${dir}/vendor/symfony/security-csrf/Symfony/Component/Security/Csrf/README.md" />
- <delete file="${dir}/vendor/symfony/security-csrf/Symfony/Component/Security/Csrf/phpunit.xml.dist" />
-
+ <delete dir="${dir}/vendor/symfony/security-core/.git" />
+ <delete dir="${dir}/vendor/symfony/security-core/Core/Tests" />
+ <delete file="${dir}/vendor/symfony/security-core/Core/.gitignore" />
+ <delete file="${dir}/vendor/symfony/security-core/Core/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/security-core/Core/README.md" />
+ <delete file="${dir}/vendor/symfony/security-core/Core/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/security-csrf/.git" />
+ <delete dir="${dir}/vendor/symfony/security-csrf/Csrf/Tests" />
+ <delete file="${dir}/vendor/symfony/security-csrf/Csrf/.gitignore" />
+ <delete file="${dir}/vendor/symfony/security-csrf/Csrf/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/security-csrf/Csrf/README.md" />
+ <delete file="${dir}/vendor/symfony/security-csrf/Csrf/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/twig-bridge/.git" />
<delete dir="${dir}/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/Tests" />
- <delete dir="${dir}/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/.git" />
<delete file="${dir}/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/.gitignore" />
<delete file="${dir}/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/CHANGELOG.md" />
<delete file="${dir}/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/README.md" />
<delete file="${dir}/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/phpunit.xml.dist" />
+
+ <delete dir="${dir}/vendor/symfony/security/.git" />
+ <delete dir="${dir}/vendor/symfony/security/Tests" />
+ <delete file="${dir}/vendor/symfony/security/.gitignore" />
+ <delete file="${dir}/vendor/symfony/security/CHANGELOG.md" />
+ <delete file="${dir}/vendor/symfony/security/README.md" />
+ <delete file="${dir}/vendor/symfony/security/phpunit.xml.dist" />
</target>
<target name="clean-diff-dir">
diff --git a/build/package.php b/build/package.php
index 37a2250fce..178a27faad 100755
--- a/build/package.php
+++ b/build/package.php
@@ -196,9 +196,10 @@ if (sizeof($package->old_packages))
*/
$copy_relative_directories = array(
'config/' => array(
+ 'recursive' => true,
'copied' => false,
'copy' => array(
- 'config/*.yml' => 'config',
+ 'config/*' => 'config',
),
),
);
@@ -256,7 +257,15 @@ if (sizeof($package->old_packages))
}
$source_dir_files = $package->locations['old_versions'] . $package->get('simple_name') . '/' . $source_dir_files;
$destination_dir = $dest_filename_dir . '/install/update/new/' . $destination_dir;
- $package->run_command('cp ' . $source_dir_files . ' ' . $destination_dir);
+
+ if (isset($data['recursive']) && $data['recursive'])
+ {
+ $package->run_command('cp -Rp ' . $source_dir_files . ' ' . $destination_dir);
+ }
+ else
+ {
+ $package->run_command('cp ' . $source_dir_files . ' ' . $destination_dir);
+ }
}
$copy_relative_directories[$reference]['copied'] = true;
}
@@ -272,7 +281,7 @@ if (sizeof($package->old_packages))
'adm/style/admin.css' => 'adm/style',
'adm/style/admin.js' => 'adm/style',
'adm/style/ajax.js' => 'adm/style',
- 'adm/style/install_*' => 'adm/style',
+ 'adm/style/installer_*' => 'adm/style',
'assets/javascript/*' => 'assets/javascript',
);
diff --git a/phpBB/adm/style/acp_avatar_options_local.html b/phpBB/adm/style/acp_avatar_options_local.html
index 8adafa1d99..bee3c57ea0 100644
--- a/phpBB/adm/style/acp_avatar_options_local.html
+++ b/phpBB/adm/style/acp_avatar_options_local.html
@@ -12,7 +12,7 @@
<!-- BEGIN avatar_local_col -->
<li>
<label for="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}"><img src="{avatar_local_row.avatar_local_col.AVATAR_IMAGE}" alt="" /><br />
- <input type="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}" value="{avatar_local_row.avatar_local_col.AVATAR_FILE}" /></label>
+ <input type="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}" value="{avatar_local_row.avatar_local_col.AVATAR_FILE}"<!-- IF avatar_local_row.avatar_local_col.CHECKED -->checked="checked"<!-- ENDIF --> /></label>
</li>
<!-- END avatar_local_col -->
<!-- END avatar_local_row -->
diff --git a/phpBB/adm/style/acp_main.html b/phpBB/adm/style/acp_main.html
index 065dd7ac4f..6e51e1fc70 100644
--- a/phpBB/adm/style/acp_main.html
+++ b/phpBB/adm/style/acp_main.html
@@ -141,19 +141,24 @@
<td>{L_GZIP_COMPRESSION}{L_COLON} </td>
<td><strong>{GZIP_COMPRESSION}</strong></td>
</tr>
+ <!-- IF S_TOTAL_ORPHAN or S_VERSIONCHECK -->
<tr>
+ <!-- IF S_VERSIONCHECK -->
<td>{L_BOARD_VERSION}{L_COLON} </td>
<td>
<strong><a href="{U_VERSIONCHECK}" <!-- IF S_VERSION_UP_TO_DATE -->style="color: #228822;"<!-- ELSE -->style="color: #BC2A4D;"<!-- ENDIF --> title="{L_MORE_INFORMATION}">{BOARD_VERSION}</a></strong> [&nbsp;<a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a>&nbsp;]
</td>
+ <!-- ENDIF -->
<!-- IF S_TOTAL_ORPHAN -->
<td>{L_NUMBER_ORPHAN}{L_COLON} </td>
<td><strong>{TOTAL_ORPHAN}</strong></td>
- <!-- ELSE -->
+ <!-- ENDIF -->
+ <!-- IF not S_TOTAL_ORPHAN or not S_VERSIONCHECK -->
<td>&nbsp;</td>
<td>&nbsp;</td>
<!-- ENDIF -->
</tr>
+ <!-- ENDIF -->
</tbody>
</table>
diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html
index 572486e877..a36d15fe73 100644
--- a/phpBB/adm/style/acp_styles.html
+++ b/phpBB/adm/style/acp_styles.html
@@ -87,6 +87,7 @@
<!-- ENDIF -->
<!-- IF .styles_list -->
+ <!-- EVENT acp_styles_list_before -->
<table class="table1 styles">
<thead>
<tr>
diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css
index cf009562b3..cfa55b58a1 100644
--- a/phpBB/adm/style/admin.css
+++ b/phpBB/adm/style/admin.css
@@ -1836,10 +1836,33 @@ li.pagination ul {
font-weight: bold;
}
+#log-container {
+ display: none;
+ max-height: 300px;
+ padding: 8px;
+ margin: 10px 0;
+ clear: both;
+ overflow-y: auto;
+ background-color: #FFFFFF;
+}
+
+#log-container.show_log_container {
+ display: block;
+ border: 1px solid #DBD7D1;
+}
+
+.log {
+ font-size: 0.8em;
+}
+
.notice {
background-color: #62A5CC;
}
+.download-box {
+ margin: 10px 0 10px 0;
+}
+
/* Special cases for the error page */
#errorpage #page-header a {
font-weight: bold;
diff --git a/phpBB/adm/style/captcha_recaptcha.html b/phpBB/adm/style/captcha_recaptcha.html
index d3038fd714..3f61c76cb1 100644
--- a/phpBB/adm/style/captcha_recaptcha.html
+++ b/phpBB/adm/style/captcha_recaptcha.html
@@ -1,32 +1,12 @@
<!-- IF S_RECAPTCHA_AVAILABLE -->
<dl>
<dd>
- <script type="text/javascript">
- // <![CDATA[
- var RecaptchaOptions = {
- lang : '{LA_RECAPTCHA_LANG}',
- theme : 'clean'
- };
- // ]]>
- </script>
- <script type="text/javascript" src="{RECAPTCHA_SERVER}/challenge?k={RECAPTCHA_PUBKEY}{RECAPTCHA_ERRORGET}"></script>
- <script type="text/javascript">
- // <![CDATA[
- <!-- IF S_CONTENT_DIRECTION eq 'rtl' -->
- document.getElementById('recaptcha_table').style.direction = 'ltr';
- <!-- ENDIF -->
- // ]]>
- </script>
-
-
<noscript>
- <div>
- <object data="{RECAPTCHA_SERVER}/noscript?k={RECAPTCHA_PUBKEY}{RECAPTCHA_ERRORGET}" type="text/html" height="300" width="500"></object><br />
- <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
- <input type="hidden" name="recaptcha_response_field" value="manual_challenge" />
- </div>
+ <div>{L_RECAPTCHA_NOSCRIPT}</div>
</noscript>
+ <script src="{RECAPTCHA_SERVER}.js?hl={LA_RECAPTCHA_LANG}" async defer></script>
+ <div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}"></div>
</dd>
</dl>
<!-- ELSE -->
diff --git a/phpBB/adm/style/installer_footer.html b/phpBB/adm/style/installer_footer.html
index 617d3dc254..b2eba48ae6 100644
--- a/phpBB/adm/style/installer_footer.html
+++ b/phpBB/adm/style/installer_footer.html
@@ -13,7 +13,7 @@
<script type="text/javascript" src="{T_JQUERY_LINK}"></script>
<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF -->
-<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
+<script type="text/javascript" src="{T_ASSETS_PATH}javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- INCLUDEJS admin.js -->
{$SCRIPTS}
diff --git a/phpBB/adm/style/installer_form.html b/phpBB/adm/style/installer_form.html
index 669f7aa834..cc5b041fa1 100644
--- a/phpBB/adm/style/installer_form.html
+++ b/phpBB/adm/style/installer_form.html
@@ -1,6 +1,6 @@
<form id="<!-- IF FORM_ID -->{FORM_ID}<!-- ELSE -->install_install<!-- ENDIF -->" method="POST" action="{U_ACTION}">
<!-- IF .options -->
-<!-- IF S_FORM_ELEM_COUNT > 1 -->
+<!-- IF S_NOT_ONLY_BUTTON_FORM -->
<fieldset>
<!-- ENDIF -->
@@ -13,8 +13,6 @@
<!-- ENDIF -->
<legend>{options.LEGEND}</legend>
<!-- ELSE -->
-
- <!-- IF options.TYPE <> 'submit' -->
<dl>
<dt><label for="{options.KEY}">{options.TITLE}{L_COLON}</label><!-- IF options.S_EXPLAIN --><br /><span class="explain">{options.TITLE_EXPLAIN}</span><!-- ENDIF --></dt>
<dd>
@@ -41,16 +39,18 @@
<!-- ENDIF -->
</dd>
</dl>
- <!-- ELSE -->
-<!-- IF S_FORM_ELEM_COUNT > 1 -->
-</fieldset>
-<!-- ENDIF -->
- <fieldset class="submit-buttons">
- <legend>{L_SUBMIT}</legend>
- <input class="button1" type="submit" name="{options.KEY}" value="{options.TITLE}" />
- </fieldset>
- <!-- ENDIF -->
<!-- ENDIF-->
<!-- END options -->
+<!-- IF S_NOT_ONLY_BUTTON_FORM -->
+</fieldset>
+<!-- ENDIF -->
+<!-- ENDIF -->
+<!-- IF .submit_buttons -->
+<fieldset class="submit-buttons">
+ <legend>{L_SUBMIT}</legend>
+ <!-- BEGIN submit_buttons -->
+ <input class="button1" type="submit" name="{submit_buttons.KEY}" value="{submit_buttons.TITLE}" />
+ <!-- END submit_buttons -->
+</fieldset>
<!-- ENDIF -->
</form>
diff --git a/phpBB/adm/style/installer_header.html b/phpBB/adm/style/installer_header.html
index 775caa7c67..c4c3427fdb 100644
--- a/phpBB/adm/style/installer_header.html
+++ b/phpBB/adm/style/installer_header.html
@@ -6,7 +6,7 @@
<!-- IF META -->{META}<!-- ENDIF -->
<title>{PAGE_TITLE}</title>
- <link href="{T_TEMPLATE_PATH}/admin.css" rel="stylesheet" type="text/css" media="screen" />
+ <link href="{T_TEMPLATE_PATH}admin.css" rel="stylesheet" type="text/css" media="screen" />
</head>
<body class="{S_CONTENT_DIRECTION} nojs">
diff --git a/phpBB/adm/style/installer_install.html b/phpBB/adm/style/installer_install.html
index 53a91f2700..747b1291f4 100644
--- a/phpBB/adm/style/installer_install.html
+++ b/phpBB/adm/style/installer_install.html
@@ -9,5 +9,5 @@
</fieldset>
</form>
<!-- ENDIF -->
-<!-- INCLUDEJS {T_ASSETS_PATH}/javascript/installer.js -->
+<!-- INCLUDEJS {T_ASSETS_PATH}javascript/installer.js -->
<!-- INCLUDE installer_footer.html -->
diff --git a/phpBB/adm/style/installer_update.html b/phpBB/adm/style/installer_update.html
new file mode 100644
index 0000000000..6bcbc525e9
--- /dev/null
+++ b/phpBB/adm/style/installer_update.html
@@ -0,0 +1,13 @@
+<!-- INCLUDE installer_header.html -->
+<h1>{TITLE}</h1>
+<p>{CONTENT}</p>
+<!-- IF SHOW_INSTALL_START_FORM -->
+<form id="install_install" method="post" action="{U_ACTION}">
+ <fieldset class="submit-buttons">
+ <legend>{L_SUBMIT}</legend>
+ <input class="button1" name="update" type="submit" value="{L_UPDATE}" />
+ </fieldset>
+</form>
+<!-- ENDIF -->
+<!-- INCLUDEJS {T_ASSETS_PATH}javascript/installer.js -->
+<!-- INCLUDE installer_footer.html -->
diff --git a/phpBB/adm/style/installer_update_file_status.html b/phpBB/adm/style/installer_update_file_status.html
new file mode 100644
index 0000000000..9f15c402e9
--- /dev/null
+++ b/phpBB/adm/style/installer_update_file_status.html
@@ -0,0 +1,80 @@
+<!-- IF .deleted -->
+<h2>{L_FILES_DELETED}</h2>
+<div style="float: {S_CONTENT_FLOW_END};">&raquo; <a href="#" onclick="phpbb.toggleDisplay('deleted', 0); return false;">{L_TOGGLE_DISPLAY}</a></div>
+<p>{L_FILES_DELETED_EXPLAIN}</p>
+
+<fieldset id="deleted">
+ <legend><img src="{T_IMAGE_PATH}icon_delete.gif" alt="{L_STATUS_DELETED}" /></legend>
+ <!-- BEGIN deleted -->
+ <dl>
+ <dt style="width: 100%;"><!-- IF deleted.DIR_PART -->{deleted.DIR_PART}<!-- ENDIF --><strong>{deleted.FILE_PART}</strong></dt>
+ </dl>
+ <!-- END deleted -->
+</fieldset>
+
+<!-- ENDIF -->
+
+<!-- IF .conflict -->
+<h2>{L_FILES_CONFLICT}</h2>
+<div style="float: {S_CONTENT_FLOW_END};">&raquo; <a href="#" onclick="phpbb.toggleDisplay('conflict', 0); return false;">{L_TOGGLE_DISPLAY}</a></div>
+<p>{L_FILES_CONFLICT_EXPLAIN}</p>
+
+<fieldset id="conflict">
+ <legend><img src="{T_IMAGE_PATH}file_conflict.gif" alt="{L_STATUS_CONFLICT}" /></legend>
+ <!-- BEGIN conflict -->
+ <dl>
+ <dt style="width: 100%;"><!-- IF conflict.DIR_PART -->{conflict.DIR_PART}<!-- ENDIF --><strong>{conflict.FILE_PART}</strong></dt>
+ </dl>
+ <!-- END conflict -->
+</fieldset>
+
+<!-- ENDIF -->
+
+<!-- IF .modified -->
+<h2>{L_FILES_MODIFIED}</h2>
+<div style="float: {S_CONTENT_FLOW_END};">&raquo; <a href="#" onclick="phpbb.toggleDisplay('modified', 0); return false;">{L_TOGGLE_DISPLAY}</a></div>
+<p>{L_FILES_MODIFIED_EXPLAIN}</p>
+
+<fieldset id="modified">
+ <legend><img src="{T_IMAGE_PATH}file_modified.gif" alt="{L_STATUS_MODIFIED}" /></legend>
+ <!-- BEGIN modified -->
+ <dl>
+ <dt style="width: 100%;"><!-- IF modified.DIR_PART -->{modified.DIR_PART}<!-- ENDIF --><strong>{modified.FILE_PART}</strong></dt>
+ </dl>
+ <!-- END modified -->
+</fieldset>
+
+<!-- ENDIF -->
+
+<!-- IF .new -->
+<h2>{L_FILES_NEW}</h2>
+<div style="float: {S_CONTENT_FLOW_END};">&raquo; <a href="#" onclick="phpbb.toggleDisplay('new_files', 0); return false;">{L_TOGGLE_DISPLAY}</a></div>
+<p>{L_FILES_NEW_EXPLAIN}</p>
+
+<fieldset id="new_files" style="display: none;">
+ <legend><img src="{T_IMAGE_PATH}file_new.gif" alt="{L_STATUS_NEW}" /></legend>
+ <!-- BEGIN new -->
+ <dl>
+ <dt style="width: 100%;"><!-- IF new.DIR_PART -->{new.DIR_PART}<!-- ENDIF --><strong>{new.FILE_PART}</strong>
+ </dt>
+ </dl>
+ <!-- END new -->
+</fieldset>
+
+<!-- ENDIF -->
+
+<!-- IF .not_modified -->
+<h2>{L_FILES_NOT_MODIFIED}</h2>
+<div style="float: {S_CONTENT_FLOW_END};">&raquo; <a href="#" onclick="phpbb.toggleDisplay('not_modified', 0); return false;">{L_TOGGLE_DISPLAY}</a></div>
+<p>{L_FILES_NOT_MODIFIED_EXPLAIN}</p>
+
+<fieldset id="not_modified" style="display: none;">
+ <legend><img src="{T_IMAGE_PATH}file_not_modified.gif" alt="{L_STATUS_NOT_MODIFIED}" /></legend>
+ <!-- BEGIN not_modified -->
+ <dl>
+ <dt style="width: 100%;"><!-- IF not_modified.DIR_PART -->{not_modified.DIR_PART}<!-- ENDIF --><strong>{not_modified.FILE_PART}</strong></dt>
+ </dl>
+ <!-- END not_modified -->
+</fieldset>
+
+<!-- ENDIF -->
diff --git a/phpBB/assets/javascript/installer.js b/phpBB/assets/javascript/installer.js
index 56bfd6aea9..e61adc7f99 100644
--- a/phpBB/assets/javascript/installer.js
+++ b/phpBB/assets/javascript/installer.js
@@ -11,6 +11,7 @@
var progressBarTriggered = false;
var progressTimer = null;
var currentProgress = 0;
+ var refreshRequested = false;
// Template related variables
var $contentWrapper = $('.install-body').find('.main');
@@ -67,7 +68,8 @@
break;
case 'log':
$msgElement.addClass('log');
- $logContainer.append($msgElement);
+ $logContainer.prepend($msgElement);
+ $logContainer.addClass('show_log_container');
break;
case 'success':
$msgElement.addClass('successbox');
@@ -78,12 +80,53 @@
}
/**
+ * Render a download box
+ */
+ function addDownloadBox(downloadArray)
+ {
+ var $downloadContainer = $('#download-wrapper');
+ var $downloadBox, $title, $content, $link;
+
+ for (var i = 0; i < downloadArray.length; i++) {
+ $downloadBox = $('<div />');
+ $downloadBox.addClass('download-box');
+
+ $title = $('<strong />');
+ $title.text(downloadArray[i].title);
+ $downloadBox.append($title);
+
+ if (downloadArray[i].hasOwnProperty('msg')) {
+ $content = $('<p />');
+ $content.text(downloadArray[i].msg);
+ $downloadBox.append($content);
+ }
+
+ $link = $('<a />');
+ $link.addClass('button1');
+ $link.attr('href', downloadArray[i].href);
+ $link.text(downloadArray[i].download);
+ $downloadBox.append($link);
+
+ $downloadContainer.append($downloadBox);
+ }
+ }
+
+ /**
+ * Render update files' status
+ */
+ function addUpdateFileStatus(fileStatus)
+ {
+ var $statusContainer = $('#file-status-wrapper');
+ $statusContainer.html(fileStatus);
+ }
+
+ /**
* Displays a form from the response
*
* @param formHtml
*/
function addForm(formHtml) {
- var $formContainer = $('#content-container');
+ var $formContainer = $('#form-wrapper');
$formContainer.html(formHtml);
var $form = $('#install_install');
interceptFormSubmit($form);
@@ -139,7 +182,7 @@
if (progressObject.task_name.length) {
if (!progressBarTriggered) {
// Create progress bar
- var $contentContainer = $('#content-container');
+ var $progressBarWrapper = $('#progress-bar-container');
// Create progress bar elements
$progressBar = $('<div />');
@@ -155,10 +198,21 @@
$progressBar.append($progressFiller);
$progressBar.append($progressText);
- $contentContainer.append($statusText);
- $contentContainer.append($progressBar);
+ $progressBarWrapper.append($statusText);
+ $progressBarWrapper.append($progressBar);
progressBarTriggered = true;
+ } else if (progressObject.hasOwnProperty('restart')) {
+ clearInterval(progressTimer);
+
+ $progressFiller = $('#progress-bar-filler');
+ $progressText = $('#progress-bar-text');
+ $statusText = $('#progress-status-text');
+
+ $progressText.text('0%');
+ $progressFiller.css('width', '0%');
+
+ currentProgress = 0;
} else {
$statusText = $('#progress-status-text');
}
@@ -217,6 +271,14 @@
setProgress(responseObject.progress);
}
+ if (responseObject.hasOwnProperty('download')) {
+ addDownloadBox(responseObject.download);
+ }
+
+ if (responseObject.hasOwnProperty('file_status')) {
+ addUpdateFileStatus(responseObject.file_status);
+ }
+
if (responseObject.hasOwnProperty('nav')) {
updateNavbarStatus(responseObject.nav);
}
@@ -224,6 +286,10 @@
if (responseObject.hasOwnProperty('cookies')) {
setCookies(responseObject.cookies);
}
+
+ if (responseObject.hasOwnProperty('refresh')) {
+ refreshRequested = true;
+ }
}
/**
@@ -243,7 +309,7 @@
if (messageEndIndex !== -1) {
endOfMessageIndex = messageEndIndex + msgSeparator.length;
message = unprocessed.substring(0, endOfMessageIndex);
- parseMessage(message);
+ parseMessage($.trim(message));
nextReadPosition += endOfMessageIndex;
}
} while (messageEndIndex !== -1);
@@ -251,6 +317,11 @@
if (xhReq.readyState === 4) {
$('#loading_indicator').css('display', 'none');
resetPolling();
+
+ if (refreshRequested) {
+ refreshRequested = false;
+ doRefresh();
+ }
}
}
@@ -310,9 +381,25 @@
}
/**
+ * Refresh page
+ */
+ function doRefresh() {
+ resetPolling();
+
+ var xhReq = createXhrObject();
+ xhReq.open('GET', $(location).attr('pathname'), true);
+ xhReq.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
+ xhReq.send();
+
+ startPolling(xhReq);
+ }
+
+ /**
* Renders the AJAX UI layout
*/
function setupAjaxLayout() {
+ progressBarTriggered = false;
+
// Clear content
$contentWrapper.html('');
@@ -332,14 +419,30 @@
$warningContainer.attr('id', 'warning-container');
$contentWrapper.append($warningContainer);
- var $installerContentWrapper = $('<div />');
- $installerContentWrapper.attr('id', 'content-container');
- $contentWrapper.append($installerContentWrapper);
+ var $progressContainer = $('<div />');
+ $progressContainer.attr('id', 'progress-bar-container');
+ $contentWrapper.append($progressContainer);
var $logContainer = $('<div />');
$logContainer.attr('id', 'log-container');
$contentWrapper.append($logContainer);
+ var $installerContentWrapper = $('<div />');
+ $installerContentWrapper.attr('id', 'content-container');
+ $contentWrapper.append($installerContentWrapper);
+
+ var $installerDownloadWrapper = $('<div />');
+ $installerDownloadWrapper.attr('id', 'download-wrapper');
+ $installerContentWrapper.append($installerDownloadWrapper);
+
+ var $updaterFileStatusWrapper = $('<div />');
+ $updaterFileStatusWrapper.attr('id', 'file-status-wrapper');
+ $installerContentWrapper.append($updaterFileStatusWrapper);
+
+ var $formWrapper = $('<div />');
+ $formWrapper.attr('id', 'form-wrapper');
+ $installerContentWrapper.append($formWrapper);
+
var $spinner = $('<div />');
$spinner.attr('id', 'loading_indicator');
$spinner.html('&nbsp;');
diff --git a/phpBB/composer.json b/phpBB/composer.json
index b96e6cacf6..71848d5a5f 100644
--- a/phpBB/composer.json
+++ b/phpBB/composer.json
@@ -26,6 +26,7 @@
},
"require": {
"bantu/ini-get-wrapper": "1.0.*",
+ "google/recaptcha": "~1.1",
"lusitanian/oauth": "0.2.*",
"marc1706/fast-image-size": "1.1.*",
"patchwork/utf8": "1.1.*",
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index bd08a36fdc..5ea4af4d75 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "3a1fb55478d50b5b7b5888f3a07e0b43",
+ "hash": "3f4f026ae8fdec714dd7fb816db22be5",
"packages": [
{
"name": "bantu/ini-get-wrapper",
@@ -37,6 +37,51 @@
"time": "2014-09-15 13:12:35"
},
{
+ "name": "google/recaptcha",
+ "version": "1.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/google/recaptcha.git",
+ "reference": "2b7e00566afca82a38a1d3adb8e42c118006296e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/google/recaptcha/zipball/2b7e00566afca82a38a1d3adb8e42c118006296e",
+ "reference": "2b7e00566afca82a38a1d3adb8e42c118006296e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.5.*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "ReCaptcha\\": "src/ReCaptcha"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "Client library for reCAPTCHA, a free service that protect websites from spam and abuse.",
+ "homepage": "http://www.google.com/recaptcha/",
+ "keywords": [
+ "Abuse",
+ "captcha",
+ "recaptcha",
+ "spam"
+ ],
+ "time": "2015-09-02 17:23:59"
+ },
+ {
"name": "lusitanian/oauth",
"version": "v0.2.1",
"source": {
@@ -226,7 +271,7 @@
"Psr\\Log\\": ""
}
},
- "notification-url": "https://packagist.org/downloads/",
+ "notification-url": "http://packagist.org/downloads/",
"license": [
"MIT"
],
@@ -308,22 +353,19 @@
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Config.git",
- "reference": "a3aa17e2dcec2dc1c764bedd21e69fdf888b8b55"
+ "url": "https://github.com/symfony/config.git",
+ "reference": "647a2a148d8ce2847ea75e58608b0a89f5a1dd1b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Config/zipball/546b5c41f8e0c3b18e55e4450ec51444adf3e61e",
- "reference": "a3aa17e2dcec2dc1c764bedd21e69fdf888b8b55",
+ "url": "https://api.github.com/repos/symfony/config/zipball/647a2a148d8ce2847ea75e58608b0a89f5a1dd1b",
+ "reference": "647a2a148d8ce2847ea75e58608b0a89f5a1dd1b",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/filesystem": "~2.3|~3.0.0"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7|~3.0.0"
- },
"type": "library",
"extra": {
"branch-alias": {
@@ -351,20 +393,20 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
- "time": "2015-08-27 18:34:50"
+ "time": "2015-10-11 08:29:26"
},
{
"name": "symfony/console",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Console.git",
- "reference": "d31246d93cd99dc57858adb5da63841d56969928"
+ "url": "https://github.com/symfony/console.git",
+ "reference": "89a795226477f66745e8ea10415e769304114920"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Console/zipball/a0d4aa01cfe2e3646e50c13c721c04d044534535",
- "reference": "d31246d93cd99dc57858adb5da63841d56969928",
+ "url": "https://api.github.com/repos/symfony/console/zipball/89a795226477f66745e8ea10415e769304114920",
+ "reference": "89a795226477f66745e8ea10415e769304114920",
"shasum": ""
},
"require": {
@@ -373,7 +415,6 @@
"require-dev": {
"psr/log": "~1.0",
"symfony/event-dispatcher": "~2.1|~3.0.0",
- "symfony/phpunit-bridge": "~2.7|~3.0.0",
"symfony/process": "~2.1|~3.0.0"
},
"suggest": {
@@ -408,20 +449,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2015-09-01 07:33:03"
+ "time": "2015-10-12 10:31:17"
},
{
"name": "symfony/debug",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Debug.git",
- "reference": "3c14966b099b4ba807f146df4c6a7acffba2f793"
+ "url": "https://github.com/symfony/debug.git",
+ "reference": "0c250fd873c7ceb31a9e7ad629b4a7048c931c28"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Debug/zipball/7eac742c453af47ae561d6c41743dc7faefc9464",
- "reference": "3c14966b099b4ba807f146df4c6a7acffba2f793",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/0c250fd873c7ceb31a9e7ad629b4a7048c931c28",
+ "reference": "0c250fd873c7ceb31a9e7ad629b4a7048c931c28",
"shasum": ""
},
"require": {
@@ -433,8 +474,7 @@
},
"require-dev": {
"symfony/class-loader": "~2.2|~3.0.0",
- "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0",
- "symfony/phpunit-bridge": "~2.7|~3.0.0"
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
},
"type": "library",
"extra": {
@@ -463,20 +503,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2015-08-31 12:33:08"
+ "time": "2015-10-11 08:29:26"
},
{
"name": "symfony/dependency-injection",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/DependencyInjection.git",
- "reference": "99c05679526e9293783ce3a9059890b47da1d97e"
+ "url": "https://github.com/symfony/dependency-injection.git",
+ "reference": "dc1fb82df24dfd4e13735265d18d027f28a72a3e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/0558c49dc0abbf4702b432fb9813bcd849d46ff9",
- "reference": "99c05679526e9293783ce3a9059890b47da1d97e",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/dc1fb82df24dfd4e13735265d18d027f28a72a3e",
+ "reference": "dc1fb82df24dfd4e13735265d18d027f28a72a3e",
"shasum": ""
},
"require": {
@@ -488,7 +528,6 @@
"require-dev": {
"symfony/config": "~2.2|~3.0.0",
"symfony/expression-language": "~2.6|~3.0.0",
- "symfony/phpunit-bridge": "~2.7|~3.0.0",
"symfony/yaml": "~2.1|~3.0.0"
},
"suggest": {
@@ -523,20 +562,20 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
- "time": "2015-08-24 07:31:10"
+ "time": "2015-10-11 08:29:26"
},
{
"name": "symfony/event-dispatcher",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/EventDispatcher.git",
- "reference": "d7246885b7fe4cb5a2786bda34362d2f0e40b730"
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "41899a21d196332ab23e40f76e1276f2b7aa4d0d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/e79162fa079bb559ddad17c58cf8b7ecbaffd9b6",
- "reference": "d7246885b7fe4cb5a2786bda34362d2f0e40b730",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/41899a21d196332ab23e40f76e1276f2b7aa4d0d",
+ "reference": "41899a21d196332ab23e40f76e1276f2b7aa4d0d",
"shasum": ""
},
"require": {
@@ -547,7 +586,6 @@
"symfony/config": "~2.0,>=2.0.5|~3.0.0",
"symfony/dependency-injection": "~2.6|~3.0.0",
"symfony/expression-language": "~2.6|~3.0.0",
- "symfony/phpunit-bridge": "~2.7|~3.0.0",
"symfony/stopwatch": "~2.3|~3.0.0"
},
"suggest": {
@@ -581,28 +619,25 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2015-06-24 15:32:32"
+ "time": "2015-10-12 10:13:39"
},
{
"name": "symfony/filesystem",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Filesystem.git",
- "reference": "b9fa06f1822de287e660130955b546777994597b"
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "fc3fe52fef85e1f3e7775ffad92539e16c20e0af"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Filesystem/zipball/287fc0b1dcb11ff729eeefc20441c08eaf628f29",
- "reference": "b9fa06f1822de287e660130955b546777994597b",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/fc3fe52fef85e1f3e7775ffad92539e16c20e0af",
+ "reference": "fc3fe52fef85e1f3e7775ffad92539e16c20e0af",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7|~3.0.0"
- },
"type": "library",
"extra": {
"branch-alias": {
@@ -630,28 +665,25 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2015-08-27 07:03:53"
+ "time": "2015-10-11 08:29:26"
},
{
"name": "symfony/finder",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Finder.git",
- "reference": "142440d48e10fd4b4f2ffb2d72fa0aad6f03cacf"
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "dcd5aaba34ca332abb7f33ec554ebd4d829cb202"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Finder/zipball/142440d48e10fd4b4f2ffb2d72fa0aad6f03cacf",
- "reference": "142440d48e10fd4b4f2ffb2d72fa0aad6f03cacf",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/dcd5aaba34ca332abb7f33ec554ebd4d829cb202",
+ "reference": "dcd5aaba34ca332abb7f33ec554ebd4d829cb202",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7|~3.0.0"
- },
"type": "library",
"extra": {
"branch-alias": {
@@ -679,28 +711,27 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2015-08-27 06:53:13"
+ "time": "2015-10-11 08:29:26"
},
{
"name": "symfony/http-foundation",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/HttpFoundation.git",
- "reference": "3f179ebcfc2f9cb82a47e890ed4622f48cfb4602"
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "7e8c33e9e6464d75091296e4615852ec4981ed80"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/3f179ebcfc2f9cb82a47e890ed4622f48cfb4602",
- "reference": "3f179ebcfc2f9cb82a47e890ed4622f48cfb4602",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/7e8c33e9e6464d75091296e4615852ec4981ed80",
+ "reference": "7e8c33e9e6464d75091296e4615852ec4981ed80",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"require-dev": {
- "symfony/expression-language": "~2.4|~3.0.0",
- "symfony/phpunit-bridge": "~2.7|~3.0.0"
+ "symfony/expression-language": "~2.4|~3.0.0"
},
"type": "library",
"extra": {
@@ -732,20 +763,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "time": "2015-08-27 06:53:13"
+ "time": "2015-10-13 16:11:28"
},
{
"name": "symfony/http-kernel",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/HttpKernel.git",
- "reference": "330079921340f2d273dd24df16fc129948614e77"
+ "url": "https://github.com/symfony/http-kernel.git",
+ "reference": "8f2cb3dfac5090be80fdf71e13f41aadaefc31e0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/39aa7db7997031951ad4a4019153199287e1cc88",
- "reference": "330079921340f2d273dd24df16fc129948614e77",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8f2cb3dfac5090be80fdf71e13f41aadaefc31e0",
+ "reference": "8f2cb3dfac5090be80fdf71e13f41aadaefc31e0",
"shasum": ""
},
"require": {
@@ -761,14 +792,13 @@
"require-dev": {
"symfony/browser-kit": "~2.3|~3.0.0",
"symfony/class-loader": "~2.1|~3.0.0",
- "symfony/config": "~2.7",
+ "symfony/config": "~2.8",
"symfony/console": "~2.3|~3.0.0",
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
"symfony/dependency-injection": "~2.8|~3.0.0",
"symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0",
"symfony/expression-language": "~2.4|~3.0.0",
"symfony/finder": "~2.0,>=2.0.5|~3.0.0",
- "symfony/phpunit-bridge": "~2.7|~3.0.0",
"symfony/process": "~2.0,>=2.0.5|~3.0.0",
"symfony/routing": "~2.8|~3.0.0",
"symfony/stopwatch": "~2.3|~3.0.0",
@@ -812,20 +842,20 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
- "time": "2015-09-01 07:33:03"
+ "time": "2015-10-13 16:11:28"
},
{
"name": "symfony/routing",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Routing.git",
- "reference": "e9554bafc78c93b15ef56ce72c5aa2f3a511e683"
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "765f56756fdd425e73224980693c97d4862e4b6f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Routing/zipball/7ee642267d616c9855c28387d30050e093f26c6b",
- "reference": "e9554bafc78c93b15ef56ce72c5aa2f3a511e683",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/765f56756fdd425e73224980693c97d4862e4b6f",
+ "reference": "765f56756fdd425e73224980693c97d4862e4b6f",
"shasum": ""
},
"require": {
@@ -841,12 +871,12 @@
"symfony/config": "~2.7|~3.0.0",
"symfony/expression-language": "~2.4|~3.0.0",
"symfony/http-foundation": "~2.3|~3.0.0",
- "symfony/phpunit-bridge": "~2.7|~3.0.0",
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0"
},
"suggest": {
"doctrine/annotations": "For using the annotation loader",
"symfony/config": "For using the all-in-one router or any loader",
+ "symfony/dependency-injection": "For loading routes from a service",
"symfony/expression-language": "For using expression matching",
"symfony/yaml": "For using the YAML loader"
},
@@ -883,7 +913,7 @@
"uri",
"url"
],
- "time": "2015-08-24 07:31:10"
+ "time": "2015-10-11 08:29:26"
},
{
"name": "symfony/security",
@@ -966,13 +996,13 @@
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/TwigBridge.git",
- "reference": "f85dc88ede5943c63c8681c02d8ef6b4252be54c"
+ "url": "https://github.com/symfony/twig-bridge.git",
+ "reference": "ff97292bc36ca33214e7bdff355085143ead11f6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/TwigBridge/zipball/2d1b0ac84ff35256d14c7dd5d949e50d138fa7f3",
- "reference": "f85dc88ede5943c63c8681c02d8ef6b4252be54c",
+ "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/ff97292bc36ca33214e7bdff355085143ead11f6",
+ "reference": "ff97292bc36ca33214e7bdff355085143ead11f6",
"shasum": ""
},
"require": {
@@ -981,13 +1011,12 @@
},
"require-dev": {
"symfony/asset": "~2.7|~3.0.0",
- "symfony/console": "~2.7|~3.0.0",
+ "symfony/console": "~2.8|~3.0.0",
"symfony/expression-language": "~2.4|~3.0.0",
"symfony/finder": "~2.3|~3.0.0",
"symfony/form": "~2.8",
- "symfony/http-kernel": "~2.3|~3.0.0",
+ "symfony/http-kernel": "~2.8|~3.0.0",
"symfony/intl": "~2.3|~3.0.0",
- "symfony/phpunit-bridge": "~2.7|~3.0.0",
"symfony/routing": "~2.2|~3.0.0",
"symfony/security": "~2.6|~3.0.0",
"symfony/security-acl": "~2.6|~3.0.0",
@@ -1038,28 +1067,25 @@
],
"description": "Symfony Twig Bridge",
"homepage": "https://symfony.com",
- "time": "2015-09-01 07:33:03"
+ "time": "2015-10-11 08:29:26"
},
{
"name": "symfony/yaml",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Yaml.git",
- "reference": "1a0bd40f71908db4c9d44d308e0008cc44fc5f2f"
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "ff7f886a33f5b7a26a94d62f6e14bb9cf0e3bf5d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Yaml/zipball/1a0bd40f71908db4c9d44d308e0008cc44fc5f2f",
- "reference": "1a0bd40f71908db4c9d44d308e0008cc44fc5f2f",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/ff7f886a33f5b7a26a94d62f6e14bb9cf0e3bf5d",
+ "reference": "ff7f886a33f5b7a26a94d62f6e14bb9cf0e3bf5d",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7|~3.0.0"
- },
"type": "library",
"extra": {
"branch-alias": {
@@ -1087,7 +1113,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2015-08-24 07:18:02"
+ "time": "2015-10-12 11:16:35"
},
{
"name": "twig/twig",
@@ -1246,6 +1272,7 @@
"event",
"exception"
],
+ "abandoned": "guzzle/guzzle",
"time": "2013-09-08 21:09:18"
},
{
@@ -1303,6 +1330,7 @@
"http",
"http client"
],
+ "abandoned": "guzzle/guzzle",
"time": "2013-09-06 11:34:26"
},
{
@@ -1347,6 +1375,7 @@
"message",
"url"
],
+ "abandoned": "guzzle/guzzle",
"time": "2013-07-11 22:46:03"
},
{
@@ -1400,6 +1429,7 @@
"component",
"stream"
],
+ "abandoned": "guzzle/guzzle",
"time": "2013-07-30 22:07:23"
},
{
@@ -1992,12 +2022,12 @@
"version": "v1.0.2",
"source": {
"type": "git",
- "url": "https://github.com/silexphp/Pimple.git",
+ "url": "https://github.com/fabpot/Pimple.git",
"reference": "ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/silexphp/Pimple/zipball/ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94",
+ "url": "https://api.github.com/repos/fabpot/Pimple/zipball/ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94",
"reference": "ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94",
"shasum": ""
},
@@ -2309,7 +2339,8 @@
},
{
"name": "Adam Harvey",
- "email": "aharvey@php.net"
+ "email": "aharvey@php.net",
+ "role": "Lead"
},
{
"name": "Bernhard Schussek",
@@ -2438,13 +2469,13 @@
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/BrowserKit.git",
- "reference": "4f297d7e00c375b6ab03732e076f65799a73937d"
+ "url": "https://github.com/symfony/browser-kit.git",
+ "reference": "35bde11fc81eecb2409eb60c5f7920659ad7e00a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/4dbd336331f5e7ba7a6f9e4f9f608b89093f49b3",
- "reference": "4f297d7e00c375b6ab03732e076f65799a73937d",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/35bde11fc81eecb2409eb60c5f7920659ad7e00a",
+ "reference": "35bde11fc81eecb2409eb60c5f7920659ad7e00a",
"shasum": ""
},
"require": {
@@ -2453,7 +2484,6 @@
},
"require-dev": {
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
- "symfony/phpunit-bridge": "~2.7|~3.0.0",
"symfony/process": "~2.0,>=2.0.5|~3.0.0"
},
"suggest": {
@@ -2486,28 +2516,25 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
- "time": "2015-07-09 16:11:14"
+ "time": "2015-10-11 08:29:26"
},
{
"name": "symfony/css-selector",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/CssSelector.git",
- "reference": "6470dad1d5c3a926906b5660a7046bbd61bd7806"
+ "url": "https://github.com/symfony/css-selector.git",
+ "reference": "01e341a68e06e540e0322017506b58b0e072c626"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/CssSelector/zipball/6470dad1d5c3a926906b5660a7046bbd61bd7806",
- "reference": "6470dad1d5c3a926906b5660a7046bbd61bd7806",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/01e341a68e06e540e0322017506b58b0e072c626",
+ "reference": "01e341a68e06e540e0322017506b58b0e072c626",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7|~3.0.0"
- },
"type": "library",
"extra": {
"branch-alias": {
@@ -2539,28 +2566,27 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2015-08-24 07:18:02"
+ "time": "2015-10-11 08:29:26"
},
{
"name": "symfony/dom-crawler",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/DomCrawler.git",
- "reference": "be577b3a5d4a06d8ce03db57222bd06b5a6509de"
+ "url": "https://github.com/symfony/dom-crawler.git",
+ "reference": "93bfc2cc94cdfc16c728c663658117a25acd1aa5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/1b459587235fb74b213269ec5ad8ac2f6e22f5f4",
- "reference": "be577b3a5d4a06d8ce03db57222bd06b5a6509de",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/93bfc2cc94cdfc16c728c663658117a25acd1aa5",
+ "reference": "93bfc2cc94cdfc16c728c663658117a25acd1aa5",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"require-dev": {
- "symfony/css-selector": "~2.3|~3.0.0",
- "symfony/phpunit-bridge": "~2.7|~3.0.0"
+ "symfony/css-selector": "~2.8|~3.0.0"
},
"suggest": {
"symfony/css-selector": ""
@@ -2592,28 +2618,25 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
- "time": "2015-08-27 06:53:13"
+ "time": "2015-10-11 08:29:26"
},
{
"name": "symfony/process",
"version": "2.8.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Process.git",
- "reference": "fc18e378d05c6b81bcac39338bf334e053186efa"
+ "url": "https://github.com/symfony/process.git",
+ "reference": "4e1daf58b375ea7c506d525dc7801df1c9a6ebbd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Process/zipball/fc18e378d05c6b81bcac39338bf334e053186efa",
- "reference": "fc18e378d05c6b81bcac39338bf334e053186efa",
+ "url": "https://api.github.com/repos/symfony/process/zipball/4e1daf58b375ea7c506d525dc7801df1c9a6ebbd",
+ "reference": "4e1daf58b375ea7c506d525dc7801df1c9a6ebbd",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7|~3.0.0"
- },
"type": "library",
"extra": {
"branch-alias": {
@@ -2641,7 +2664,7 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2015-08-27 06:53:13"
+ "time": "2015-10-11 08:29:26"
}
],
"aliases": [],
diff --git a/phpBB/config/default/config.yml b/phpBB/config/default/config.yml
index e69de29bb2..e8d0536287 100644
--- a/phpBB/config/default/config.yml
+++ b/phpBB/config/default/config.yml
@@ -0,0 +1 @@
+# phpBB's config file (This line is needed because of the packager)
diff --git a/phpBB/config/default/container/services.yml b/phpBB/config/default/container/services.yml
index 9bbcdcbd57..e67af18a9c 100644
--- a/phpBB/config/default/container/services.yml
+++ b/phpBB/config/default/container/services.yml
@@ -1,4 +1,5 @@
imports:
+ - { resource: services_attachment.yml }
- { resource: services_auth.yml }
- { resource: services_avatar.yml }
- { resource: services_captcha.yml }
@@ -9,7 +10,9 @@ imports:
- { resource: services_event.yml }
- { resource: services_feed.yml }
- { resource: services_files.yml }
+ - { resource: services_filesystem.yml }
- { resource: services_help.yml }
+ - { resource: services_hook.yml }
- { resource: services_http.yml }
- { resource: services_language.yml }
- { resource: services_migrator.yml }
diff --git a/phpBB/config/default/container/services_attachment.yml b/phpBB/config/default/container/services_attachment.yml
new file mode 100644
index 0000000000..5506b2ec90
--- /dev/null
+++ b/phpBB/config/default/container/services_attachment.yml
@@ -0,0 +1,40 @@
+services:
+ attachment.delete:
+ class: phpbb\attachment\delete
+ scope: prototype
+ arguments:
+ - @config
+ - @dbal.conn
+ - @dispatcher
+ - @filesystem
+ - @attachment.resync
+ - %core.root_path%
+
+ attachment.manager:
+ class: phpbb\attachment\manager
+ scope: prototype
+ arguments:
+ - @attachment.delete
+ - @attachment.resync
+ - @attachment.upload
+
+ attachment.resync:
+ class: phpbb\attachment\resync
+ scope: prototype
+ arguments:
+ - @dbal.conn
+
+ attachment.upload:
+ class: phpbb\attachment\upload
+ scope: prototype
+ arguments:
+ - @auth
+ - @cache
+ - @config
+ - @files.upload
+ - @language
+ - @mimetype.guesser
+ - @dispatcher
+ - @plupload
+ - @user
+ - %core.root_path%
diff --git a/phpBB/config/default/container/services_console.yml b/phpBB/config/default/container/services_console.yml
index 6b46375c7d..6f6e129b29 100644
--- a/phpBB/config/default/container/services_console.yml
+++ b/phpBB/config/default/container/services_console.yml
@@ -98,6 +98,7 @@ services:
class: phpbb\console\command\db\migrate
arguments:
- @user
+ - @language
- @migrator
- @ext.manager
- @config
@@ -112,6 +113,7 @@ services:
class: phpbb\console\command\db\revert
arguments:
- @user
+ - @language
- @migrator
- @ext.manager
- @config
diff --git a/phpBB/config/default/container/services_event.yml b/phpBB/config/default/container/services_event.yml
index 8fd4faa274..4a35add776 100644
--- a/phpBB/config/default/container/services_event.yml
+++ b/phpBB/config/default/container/services_event.yml
@@ -4,18 +4,11 @@ services:
arguments:
- @service_container
- hook_finder:
- class: phpbb\hook\finder
- arguments:
- - %core.root_path%
- - %core.php_ext%
- - @cache.driver
-
kernel_exception_subscriber:
class: phpbb\event\kernel_exception_subscriber
arguments:
- @template
- - @user
+ - @language
tags:
- { name: kernel.event_subscriber }
diff --git a/phpBB/config/default/container/services_files.yml b/phpBB/config/default/container/services_files.yml
index cfdade37df..425df6dc9b 100644
--- a/phpBB/config/default/container/services_files.yml
+++ b/phpBB/config/default/container/services_files.yml
@@ -1,7 +1,4 @@
services:
- filesystem:
- class: phpbb\filesystem\filesystem
-
files.factory:
class: phpbb\files\factory
arguments:
diff --git a/phpBB/config/default/container/services_filesystem.yml b/phpBB/config/default/container/services_filesystem.yml
new file mode 100644
index 0000000000..828f9076dd
--- /dev/null
+++ b/phpBB/config/default/container/services_filesystem.yml
@@ -0,0 +1,3 @@
+services:
+ filesystem:
+ class: phpbb\filesystem\filesystem
diff --git a/phpBB/config/default/container/services_hook.yml b/phpBB/config/default/container/services_hook.yml
new file mode 100644
index 0000000000..9d0d355cff
--- /dev/null
+++ b/phpBB/config/default/container/services_hook.yml
@@ -0,0 +1,7 @@
+services:
+ hook_finder:
+ class: phpbb\hook\finder
+ arguments:
+ - %core.root_path%
+ - %core.php_ext%
+ - @cache.driver
diff --git a/phpBB/config/default/container/services_routing.yml b/phpBB/config/default/container/services_routing.yml
index 12fc98ce74..4bedc951ee 100644
--- a/phpBB/config/default/container/services_routing.yml
+++ b/phpBB/config/default/container/services_routing.yml
@@ -56,7 +56,7 @@ services:
tags:
- { name: routing.loader }
-# ---- Resources Locators ----
+# ---- Resources Locators ----
routing.chained_resources_locator:
class: phpbb\routing\resources_locator\chained_resources_locator
diff --git a/phpBB/config/installer/container/services.yml b/phpBB/config/installer/container/services.yml
index 5cd30f9222..e7325399ad 100644
--- a/phpBB/config/installer/container/services.yml
+++ b/phpBB/config/installer/container/services.yml
@@ -1,6 +1,7 @@
imports:
- { resource: services_installer.yml }
- - { resource: ../../default/container/services_files.yml }
+ - { resource: ../../default/container/services_event.yml }
+ - { resource: ../../default/container/services_filesystem.yml }
- { resource: ../../default/container/services_http.yml }
- { resource: ../../default/container/services_language.yml }
- { resource: ../../default/container/services_php.yml }
@@ -20,10 +21,11 @@ services:
- %core.root_path%
- @template
- dispatcher:
- class: phpbb\event\dispatcher
+ file_locator:
+ class: phpbb\routing\file_locator
arguments:
- - @service_container
+ - @filesystem
+ - %core.root_path%
language.loader:
parent: language.loader_abstract
@@ -37,14 +39,14 @@ services:
- %core.root_path%
- %core.php_ext%
- router:
- class: phpbb\routing\router
+ routing.resources_locator.default:
+ class: phpbb\routing\resources_locator\installer_resources_locator
arguments:
- - @service_container
- @filesystem
- %core.root_path%
- - %core.php_ext%
- %core.environment%
+ tags:
+ - { name: routing.resources_locator }
template:
class: phpbb\template\twig\twig
diff --git a/phpBB/config/installer/container/services_file_updater.yml b/phpBB/config/installer/container/services_file_updater.yml
new file mode 100644
index 0000000000..10e52acd16
--- /dev/null
+++ b/phpBB/config/installer/container/services_file_updater.yml
@@ -0,0 +1,38 @@
+services:
+ installer.file_updater.factory:
+ class: phpbb\install\helper\file_updater\factory
+ arguments:
+ - @installer.file_updater.collection
+
+ installer.file_updater.collection:
+ class: phpbb\di\service_collection
+ arguments:
+ - @service_container
+ tags:
+ - { name: service_collection, tag: file_updater }
+
+ installer.file_updater.compress:
+ class: phpbb\install\helper\file_updater\compression_file_updater
+ arguments:
+ - @installer.helper.update_helper
+ - %core.root_path%
+ - %core.php_ext%
+ tags:
+ - { name: file_updater }
+
+ installer.file_updater.ftp:
+ class: phpbb\install\helper\file_updater\ftp_file_updater
+ arguments:
+ - @installer.helper.update_helper
+ - %core.root_path%
+ - %core.php_ext%
+ tags:
+ - { name: file_updater }
+
+ installer.file_updater.file:
+ class: phpbb\install\helper\file_updater\file_updater
+ arguments:
+ - @filesystem
+ - %core.root_path%
+ tags:
+ - { name: file_updater }
diff --git a/phpBB/config/installer/container/services_install_controller.yml b/phpBB/config/installer/container/services_install_controller.yml
index a3595ff0a3..221a73f2c3 100644
--- a/phpBB/config/installer/container/services_install_controller.yml
+++ b/phpBB/config/installer/container/services_install_controller.yml
@@ -10,6 +10,7 @@ services:
phpbb.installer.controller.helper:
class: phpbb\install\controller\helper
arguments:
+ - @installer.helper.config
- @language
- @language.helper.language_file
- @installer.navigation.provider
@@ -24,7 +25,6 @@ services:
class: phpbb\install\controller\install
arguments:
- @phpbb.installer.controller.helper
- - @installer.helper.config
- @installer.helper.iohandler_factory
- @installer.navigation.provider
- @language
@@ -32,3 +32,20 @@ services:
- @request
- @installer.installer.install
- @installer.helper.install_helper
+
+ phpbb.installer.controller.update:
+ class: phpbb\install\controller\update
+ arguments:
+ - @phpbb.installer.controller.helper
+ - @installer.installer.update
+ - @installer.helper.install_helper
+ - @installer.helper.iohandler_factory
+ - @language
+ - @installer.navigation.provider
+ - @request
+ - @template
+
+ phpbb.installer.controller.file_downloader:
+ class: phpbb\install\controller\archive_download
+ arguments:
+ - @installer.helper.config
diff --git a/phpBB/config/installer/container/services_install_navigation.yml b/phpBB/config/installer/container/services_install_navigation.yml
index 53e20e89cc..4e39e07043 100644
--- a/phpBB/config/installer/container/services_install_navigation.yml
+++ b/phpBB/config/installer/container/services_install_navigation.yml
@@ -25,3 +25,11 @@ services:
tags:
- { name: installer.navigation }
+ installer.navigation.update_navigation:
+ class: phpbb\install\helper\navigation\update_navigation
+ arguments:
+ - @installer.helper.install_helper
+ scope: prototype
+ tags:
+ - { name: installer.navigation }
+
diff --git a/phpBB/config/installer/container/services_install_obtain_data.yml b/phpBB/config/installer/container/services_install_obtain_data.yml
index a1fab313c4..dce261b8c7 100644
--- a/phpBB/config/installer/container/services_install_obtain_data.yml
+++ b/phpBB/config/installer/container/services_install_obtain_data.yml
@@ -56,7 +56,7 @@ services:
- { name: service_collection, tag: install_obtain_data, class_name_aware: true }
installer.module.obtain_data_install:
- class: phpbb\install\module\obtain_data\module
+ class: phpbb\install\module\obtain_data\install_module
parent: installer.module_base
arguments:
- @installer.module.install_obtain_data_collection
diff --git a/phpBB/config/installer/container/services_install_requirements.yml b/phpBB/config/installer/container/services_install_requirements.yml
index f368031707..47910e7200 100644
--- a/phpBB/config/installer/container/services_install_requirements.yml
+++ b/phpBB/config/installer/container/services_install_requirements.yml
@@ -16,6 +16,7 @@ services:
- @installer.helper.iohandler
tags:
- { name: installer_requirements, order: 20 }
+ - { name: update_requirements, order: 20 }
installer.module.install_requirements_collection:
class: phpbb\di\ordered_service_collection
@@ -26,7 +27,7 @@ services:
# Please note, that the name of this module is hard coded in the installer service
installer.module.requirements_install:
- class: phpbb\install\module\requirements\module
+ class: phpbb\install\module\requirements\install_module
parent: installer.module_base
arguments:
- @installer.module.install_requirements_collection
diff --git a/phpBB/config/installer/container/services_installer.yml b/phpBB/config/installer/container/services_installer.yml
index 62137aa9d8..667ff2bafd 100644
--- a/phpBB/config/installer/container/services_installer.yml
+++ b/phpBB/config/installer/container/services_installer.yml
@@ -1,4 +1,5 @@
imports:
+ - { resource: services_file_updater.yml }
- { resource: services_install_console.yml }
- { resource: services_install_controller.yml }
- { resource: services_install_data.yml }
@@ -8,6 +9,10 @@ imports:
- { resource: services_install_navigation.yml }
- { resource: services_install_obtain_data.yml }
- { resource: services_install_requirements.yml }
+ - { resource: services_update_database.yml }
+ - { resource: services_update_filesystem.yml }
+ - { resource: services_update_obtain_data.yml }
+ - { resource: services_update_requirements.yml }
services:
# -------- Installer helpers ------------------------
@@ -38,8 +43,10 @@ services:
class: phpbb\install\helper\iohandler\ajax_iohandler
parent: installer.helper.iohandler_abstract
arguments:
+ - @path_helper
- @request
- @template
+ - @router
installer.helper.iohandler_cli:
class: phpbb\install\helper\iohandler\cli_iohandler
@@ -52,7 +59,9 @@ services:
installer.helper.container_factory:
class: phpbb\install\helper\container_factory
arguments:
+ - @language
- @request
+ - @installer.helper.update_helper
- %core.root_path%
- %core.php_ext%
@@ -62,6 +71,11 @@ services:
- %core.root_path%
- %core.php_ext%
+ installer.helper.update_helper:
+ class: phpbb\install\helper\update_helper
+ arguments:
+ - %core.root_path%
+
# -------- Installer --------------------------------
installer.module_base:
abstract: true
@@ -73,6 +87,7 @@ services:
abstract: true
arguments:
- @installer.helper.config
+ - @path_helper
installer.install.module_collection:
class: phpbb\di\ordered_service_collection
@@ -81,7 +96,19 @@ services:
tags:
- { name: service_collection, tag: installer_install_module }
+ installer.update.module_collection:
+ class: phpbb\di\ordered_service_collection
+ arguments:
+ - @service_container
+ tags:
+ - { name: service_collection, tag: installer_update_module }
+
installer.installer.install:
parent: installer.installer.abstract
calls:
- [set_modules, [@installer.install.module_collection]]
+
+ installer.installer.update:
+ parent: installer.installer.abstract
+ calls:
+ - [set_modules, [@installer.update.module_collection]]
diff --git a/phpBB/config/installer/container/services_update_database.yml b/phpBB/config/installer/container/services_update_database.yml
new file mode 100644
index 0000000000..85f943f928
--- /dev/null
+++ b/phpBB/config/installer/container/services_update_database.yml
@@ -0,0 +1,29 @@
+services:
+ installer.update_database.update_task:
+ class: phpbb\install\module\update_database\task\update
+ arguments:
+ - @installer.helper.container_factory
+ - @filesystem
+ - @installer.helper.config
+ - @installer.helper.iohandler
+ - @language
+ - %core.root_path%
+ tags:
+ - { name: update_database_task, order: 10 }
+
+ installer.module.update_database_collection:
+ class: phpbb\di\ordered_service_collection
+ arguments:
+ - @service_container
+ tags:
+ - { name: service_collection, tag: update_database_task, class_name_aware: true }
+
+ installer.module.update_database:
+ class: phpbb\install\module\update_database\module
+ parent: installer.module_base
+ arguments:
+ - @installer.module.update_database_collection
+ - true
+ - false
+ tags:
+ - { name: installer_update_module, order: 40 }
diff --git a/phpBB/config/installer/container/services_update_filesystem.yml b/phpBB/config/installer/container/services_update_filesystem.yml
new file mode 100644
index 0000000000..2882df4294
--- /dev/null
+++ b/phpBB/config/installer/container/services_update_filesystem.yml
@@ -0,0 +1,72 @@
+services:
+ installer.update_filesystem.check_task:
+ class: phpbb\install\module\update_filesystem\task\file_check
+ arguments:
+ - @filesystem
+ - @installer.helper.config
+ - @installer.helper.iohandler
+ - @installer.helper.update_helper
+ - %core.root_path%
+ tags:
+ - { name: update_filesystem, order: 10 }
+
+ installer.update_filesystem.diff_files:
+ class: phpbb\install\module\update_filesystem\task\diff_files
+ arguments:
+ - @installer.helper.container_factory
+ - @installer.helper.config
+ - @installer.helper.iohandler
+ - @installer.helper.update_helper
+ - %core.root_path%
+ - %core.php_ext%
+ tags:
+ - { name: update_filesystem, order: 20 }
+
+ installer.update_filesystem.show_file_status:
+ class: phpbb\install\module\update_filesystem\task\show_file_status
+ arguments:
+ - @installer.helper.container_factory
+ - @installer.helper.config
+ - @installer.helper.iohandler
+ - @filesystem
+ - @installer.file_updater.factory
+ tags:
+ - { name: update_filesystem, order: 30 }
+
+ installer.update_filesystem.update_files:
+ class: phpbb\install\module\update_filesystem\task\update_files
+ arguments:
+ - @installer.helper.container_factory
+ - @installer.helper.config
+ - @installer.helper.iohandler
+ - @installer.file_updater.factory
+ - @installer.helper.update_helper
+ - %core.root_path%
+ tags:
+ - { name: update_filesystem, order: 40 }
+
+ installer.update_filesystem.download_updated_files:
+ class: phpbb\install\module\update_filesystem\task\download_updated_files
+ arguments:
+ - @installer.helper.config
+ - @installer.helper.iohandler
+ - @filesystem
+ tags:
+ - { name: update_filesystem, order: 50 }
+
+ installer.module.update_filesystem_collection:
+ class: phpbb\di\ordered_service_collection
+ arguments:
+ - @service_container
+ tags:
+ - { name: service_collection, tag: update_filesystem, class_name_aware: true }
+
+ installer.module.filesystem_update:
+ class: phpbb\install\module\update_filesystem\module
+ parent: installer.module_base
+ arguments:
+ - @installer.module.update_filesystem_collection
+ - true
+ - false
+ tags:
+ - { name: installer_update_module, order: 30 }
diff --git a/phpBB/config/installer/container/services_update_obtain_data.yml b/phpBB/config/installer/container/services_update_obtain_data.yml
new file mode 100644
index 0000000000..fe0d3bc43f
--- /dev/null
+++ b/phpBB/config/installer/container/services_update_obtain_data.yml
@@ -0,0 +1,53 @@
+services:
+ installer.obtain_data.update_options:
+ class: phpbb\install\module\obtain_data\task\obtain_update_settings
+ arguments:
+ - @installer.helper.config
+ - @installer.helper.iohandler
+ tags:
+ - { name: update_obtain_data, order: 10 }
+
+ installer.obtain_data.file_updater_method:
+ class: phpbb\install\module\obtain_data\task\obtain_file_updater_method
+ arguments:
+ - @installer.helper.config
+ - @installer.helper.iohandler
+ tags:
+ - { name: update_obtain_data, order: 20 }
+
+ installer.obtain_data.update_files:
+ class: phpbb\install\module\obtain_data\task\obtain_update_files
+ arguments:
+ - @installer.helper.config
+ - @installer.helper.iohandler
+ - %core.root_path%
+ - %core.php_ext%
+ tags:
+ - { name: update_obtain_data, order: 30 }
+
+ installer.obtain_data.update_ftp_settings:
+ class: phpbb\install\module\obtain_data\task\obtain_update_ftp_data
+ arguments:
+ - @installer.helper.config
+ - @installer.helper.iohandler
+ - @installer.helper.update_helper
+ - %core.php_ext%
+ tags:
+ - { name: update_obtain_data, order: 40 }
+
+ installer.module.update_obtain_data_collection:
+ class: phpbb\di\ordered_service_collection
+ arguments:
+ - @service_container
+ tags:
+ - { name: service_collection, tag: update_obtain_data, class_name_aware: true }
+
+ installer.module.obtain_data_update:
+ class: phpbb\install\module\obtain_data\update_module
+ parent: installer.module_base
+ arguments:
+ - @installer.module.update_obtain_data_collection
+ - true
+ - false
+ tags:
+ - { name: installer_update_module, order: 20 }
diff --git a/phpBB/config/installer/container/services_update_requirements.yml b/phpBB/config/installer/container/services_update_requirements.yml
new file mode 100644
index 0000000000..ebb1bea409
--- /dev/null
+++ b/phpBB/config/installer/container/services_update_requirements.yml
@@ -0,0 +1,40 @@
+services:
+ installer.requirements.check_filesystem_update:
+ class: phpbb\install\module\requirements\task\check_filesystem
+ arguments:
+ - @filesystem
+ - @installer.helper.iohandler
+ - %core.root_path%
+ - %core.php_ext%
+ - false
+ tags:
+ - { name: update_requirements, order: 10 }
+
+ installer.requirements.update_requirements:
+ class: phpbb\install\module\requirements\task\check_update
+ arguments:
+ - @installer.helper.container_factory
+ - @filesystem
+ - @installer.helper.iohandler
+ - @installer.helper.update_helper
+ - %core.root_path%
+ - %core.php_ext%
+ tags:
+ - { name: update_requirements, order: 30 }
+
+ installer.module.update_requirements_collection:
+ class: phpbb\di\ordered_service_collection
+ arguments:
+ - @service_container
+ tags:
+ - { name: service_collection, tag: update_requirements, class_name_aware: true }
+
+ installer.module.requirements_update:
+ class: phpbb\install\module\requirements\update_module
+ parent: installer.module_base
+ arguments:
+ - @installer.module.update_requirements_collection
+ - true
+ - false
+ tags:
+ - { name: installer_update_module, order: 10 }
diff --git a/phpBB/config/installer/routing/installer.yml b/phpBB/config/installer/routing/installer.yml
index 80a995ab6e..49e103dd7d 100644
--- a/phpBB/config/installer/routing/installer.yml
+++ b/phpBB/config/installer/routing/installer.yml
@@ -20,3 +20,18 @@ phpbb_installer_install:
path: /install
defaults:
_controller: phpbb.installer.controller.install:handle
+
+phpbb_installer_update:
+ path: /update
+ defaults:
+ _controller: phpbb.installer.controller.update:handle
+
+phpbb_installer_update_file_download:
+ path: /download/updated
+ defaults:
+ _controller: phpbb.installer.controller.file_downloader:update_archive
+
+phpbb_installer_update_conflict_download:
+ path: /download/conflict
+ defaults:
+ _controller: phpbb.installer.controller.file_downloader:conflict_archive
diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html
index c6a88def7f..a5b1778848 100644
--- a/phpBB/docs/INSTALL.html
+++ b/phpBB/docs/INSTALL.html
@@ -265,7 +265,7 @@
<p>If you are currently using a stable release of phpBB, updating to this version is straightforward. You would have downloaded one of four packages and your choice determines what you need to do. <strong>Note</strong>: Before updating, we heavily recommend you do a <em>full backup of your database and existing phpBB files</em>! If you are unsure how to achieve this please ask your hosting provider for advice.</p>
-<p><strong>Please make sure you update your phpBB source files too, even if you run the <code>database_update.php</code> file.</strong></p>
+<p><strong>Please make sure you update your phpBB source files too, even if you run the <code>database_update.php</code> file.</strong> If you have shell access to your server, you may wish to update via the command line interface. From your board's root, execute the following command: <code>php bin/phpbbcli.php --safe-mode db:migrate</code>.</p>
<a name="update_full"></a><h3>4.i. Full package</h3>
@@ -273,7 +273,7 @@
<p>First, you should make a copy of your existing <code>config.php</code> file; keep it in a safe place! Next, delete all the existing phpBB files, you may want to leave your <code>files/</code> and <code>images/</code> directories in place. You can leave alternative styles in place too. With this complete, you can upload the new phpBB files (see <a href="#install">New installation</a> for details if necessary). Once complete, copy back your saved <code>config.php</code>, replacing the new one. Another method is to just <strong>replace</strong> the existing files with the files from the full package - though make sure you do <strong>not</strong> overwrite your config.php file.</p>
- <p>You should now run <code>install/database_update.php</code> which, depending on your previous version, will make a number of database changes. You may receive <em>FAILURES</em> during this procedure. They should not be a cause for concern unless you see an actual <em>ERROR</em>, in which case the script will stop (in this case you should seek help via our forums or bug tracker).</p>
+ <p>You should now run <code>install/database_update.php</code> which, depending on your previous version, will make a number of database changes. You may receive <em>FAILURES</em> during this procedure. They should not be a cause for concern unless you see an actual <em>ERROR</em>, in which case the script will stop (in this case you should seek help via our forums or bug tracker). If you have shell access to your server, you may wish to update via the command line interface. From your board's root, execute the following command: <code>php bin/phpbbcli.php --safe-mode db:migrate</code>.</p>
<p>Once <code>install/database_update.php</code> has completed, you may proceed to the Administration Control Panel and then remove the install directory as advised.</p>
@@ -285,7 +285,7 @@
<p>The directory structure has been preserved, enabling you (if you wish) to simply upload the uncompressed contents of the archive to the appropriate location on your server, i.e. simply overwrite the existing files with the new versions. Do not forget that if you have installed any modifications (MODs) these files will overwrite the originals, possibly destroying them in the process. You will need to re-add MODs to any affected file before uploading.</p>
- <p>As for the other update procedures, you should run <code>install/database_update.php</code> after you have finished updating the files. This will update your database schema and increment the version number.</p>
+ <p>As for the other update procedures, you should run <code>install/database_update.php</code> after you have finished updating the files. This will update your database schema and increment the version number. If you have shell access to your server, you may wish to update via the command line interface. From your board's root, execute the following command: <code>php bin/phpbbcli.php --safe-mode db:migrate</code>.</p>
<a name="update_patch"></a><h3>4.iii. Patch file</h3>
@@ -297,13 +297,13 @@
<p>If you do get failures, you should look at using the <a href="#update_files">Changed Files</a> package to replace the files which failed to patch. Please note that you will need to manually re-add any MODs to these particular files. Alternatively, if you know how, you can examine the .rej files to determine what failed where and make manual adjustments to the relevant source.</p>
- <p>You should, of course, delete the patch file (or files) after use. As for the other update procedures, you should run <code>install/database_update.php</code> after you have finished updating the files. This will update your database schema and data (if appropriate) and increment the version number.</p>
+ <p>You should, of course, delete the patch file (or files) after use. As for the other update procedures, you should run <code>install/database_update.php</code> after you have finished updating the files. This will update your database schema and data (if appropriate) and increment the version number. If you have shell access to your server, you may wish to update via the command line interface. From your board's root, execute the following command: <code>php bin/phpbbcli.php --safe-mode db:migrate</code>.</p>
<a name="update_auto"></a><h3>4.iv. Automatic update package</h3>
<p>This update method is the recommended method for updating. This package detects changed files automatically and merges in changes if needed.</p>
- <p>The automatic update package will update the board from a given version to the latest version. A number of automatic update files are available, and you should choose the one that corresponds to the version of the board that you are currently running. For example, if your current version is <strong>3.0.13</strong>, you need the <code>phpBB-3.0.13_to_3.0.14.zip/tar.bz2</code> file.</p>
+ <p>The automatic update package will update the board from a given version to the latest version. A number of automatic update files are available, and you should choose the one that corresponds to the version of the board that you are currently running. For example, if your current version is <strong>3.1.5</strong>, you need the <code>phpBB-3.1.5_to_3.1.6.zip/tar.bz2</code> file.</p>
<p>To perform the update, either follow the instructions from the <strong>Administration Control Panel-&gt;System</strong> Tab - this should point out that you are running an outdated version and will guide you through the update - or follow the instructions listed below.</p>
diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md
index a763f279d1..81a43b5664 100644
--- a/phpBB/docs/events.md
+++ b/phpBB/docs/events.md
@@ -190,6 +190,13 @@ acp_ranks_list_header_before
* Purpose: Add content after the last header-column (but before the action column)
in the ranks list in the ACP
+acp_styles_list_before
+===
+* Locations:
+ + adm/style/acp_styles.html
+* Since: 3.1.7-RC1
+* Purpose: Add content before list of styles
+
acp_users_profile_before
===
* Locations:
@@ -1170,6 +1177,13 @@ quickreply_editor_message_before
* Since: 3.1.0-a4
* Purpose: Add content before the quick reply textbox
+quickreply_editor_subject_before
+===
+* Locations:
+ + styles/prosilver/template/quickreply_editor.html
+* Since: 3.1.7-RC1
+* Purpose: Add content before the quick reply subject textbox
+
search_body_form_before
===
* Locations:
diff --git a/phpBB/download/file.php b/phpBB/download/file.php
index fb2b9602cd..7a20145968 100644
--- a/phpBB/download/file.php
+++ b/phpBB/download/file.php
@@ -268,17 +268,18 @@ else
* @var array attachment Array with attachment data
* @var int display_cat Attachment category
* @var int download_mode File extension specific download mode
- * @var array extension Array with file extensions data
+ * @var array extensions Array with file extensions data
* @var string mode Download mode
* @var bool thumbnail Flag indicating if the file is a thumbnail
* @since 3.1.6-RC1
+ * @change 3.1.7-RC1 Fixing wrong name of a variable (replacing "extension" by "extensions")
*/
$vars = array(
'attach_id',
'attachment',
'display_cat',
'download_mode',
- 'extension',
+ 'extensions',
'mode',
'thumbnail',
);
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index 7ff9846a75..00dd209c6f 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -39,6 +39,9 @@ class acp_attachments
/** @var \phpbb\filesystem\filesystem_interface */
protected $filesystem;
+ /** @var \phpbb\attachment\manager */
+ protected $attachment_manager;
+
public $id;
public $u_action;
protected $new_config;
@@ -55,6 +58,7 @@ class acp_attachments
$this->user = $user;
$this->phpbb_container = $phpbb_container;
$this->filesystem = $phpbb_filesystem;
+ $this->attachment_manager = $phpbb_container->get('attachment.manager');
$user->add_lang(array('posting', 'viewtopic', 'acp/attachments'));
@@ -110,7 +114,10 @@ class acp_attachments
{
case 'attach':
- include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
+ if (!function_exists('get_supported_image_types'))
+ {
+ include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
+ }
$sql = 'SELECT group_name, cat_id
FROM ' . EXTENSION_GROUPS_TABLE . '
@@ -922,11 +929,11 @@ class acp_attachments
$delete_files = array();
while ($row = $db->sql_fetchrow($result))
{
- phpbb_unlink($row['physical_filename'], 'file');
+ $this->attachment_manager->unlink($row['physical_filename'], 'file');
if ($row['thumbnail'])
{
- phpbb_unlink($row['physical_filename'], 'thumbnail');
+ $this->attachment_manager->unlink($row['physical_filename'], 'thumbnail');
}
$delete_files[$row['attach_id']] = $row['real_filename'];
@@ -1091,7 +1098,7 @@ class acp_attachments
}
$db->sql_freeresult($result);
- if ($num_deleted = delete_attachments('attach', $delete_files))
+ if ($num_deleted = $this->attachment_manager->delete('attach', $delete_files))
{
if (sizeof($delete_files) != $num_deleted)
{
diff --git a/phpBB/includes/acp/acp_ban.php b/phpBB/includes/acp/acp_ban.php
index b555f46a94..286bc92813 100644
--- a/phpBB/includes/acp/acp_ban.php
+++ b/phpBB/includes/acp/acp_ban.php
@@ -28,7 +28,10 @@ class acp_ban
global $user, $template, $request, $phpbb_dispatcher;
global $phpbb_root_path, $phpEx;
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_ban'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$bansubmit = $request->is_set_post('bansubmit');
$unbansubmit = $request->is_set_post('unbansubmit');
diff --git a/phpBB/includes/acp/acp_bots.php b/phpBB/includes/acp/acp_bots.php
index e0220ad0c3..422e1e34d7 100644
--- a/phpBB/includes/acp/acp_bots.php
+++ b/phpBB/includes/acp/acp_bots.php
@@ -141,7 +141,11 @@ class acp_bots
case 'edit':
case 'add':
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+
+ if (!function_exists('user_update_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$bot_row = array(
'bot_name' => $request->variable('bot_name', '', true),
diff --git a/phpBB/includes/acp/acp_disallow.php b/phpBB/includes/acp/acp_disallow.php
index 2c27616748..b2a7128209 100644
--- a/phpBB/includes/acp/acp_disallow.php
+++ b/phpBB/includes/acp/acp_disallow.php
@@ -26,9 +26,7 @@ class acp_disallow
function main($id, $mode)
{
global $db, $user, $auth, $template, $cache, $phpbb_log, $request;
- global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
-
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ global $config, $phpbb_admin_path;
$user->add_lang('acp/posting');
diff --git a/phpBB/includes/acp/acp_email.php b/phpBB/includes/acp/acp_email.php
index ebc4a86de3..98c74ff8b3 100644
--- a/phpBB/includes/acp/acp_email.php
+++ b/phpBB/includes/acp/acp_email.php
@@ -189,8 +189,15 @@ class acp_email
$db->sql_freeresult($result);
// Send the messages
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!class_exists('messenger'))
+ {
+ include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ }
+
+ if (!function_exists('get_group_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$messenger = new messenger($use_queue);
$errored = false;
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index f252f2a594..dd9ff37773 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -950,17 +950,21 @@ class acp_forums
$errors = array();
+ $forum_data_ary = $forum_data;
/**
* Validate the forum data before we create/update the forum
*
* @event core.acp_manage_forums_validate_data
- * @var array forum_data Array with new forum data
+ * @var array forum_data_ary Array with new forum data
* @var array errors Array of errors, should be strings and not
* language key.
* @since 3.1.0-a1
+ * @change 3.2.0-a1 Replaced forum_data with forum_data_ary
*/
- $vars = array('forum_data', 'errors');
+ $vars = array('forum_data_ary', 'errors');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_validate_data', compact($vars)));
+ $forum_data = $forum_data_ary;
+ unset($forum_data_ary);
if ($forum_data['forum_name'] == '')
{
@@ -1058,18 +1062,22 @@ class acp_forums
}
unset($forum_data_sql['forum_password_unset']);
+ $forum_data_ary = $forum_data;
/**
* Remove invalid values from forum_data_sql that should not be updated
*
* @event core.acp_manage_forums_update_data_before
- * @var array forum_data Array with forum data
+ * @var array forum_data_ary Array with forum data
* @var array forum_data_sql Array with data we are going to update
* If forum_data_sql[forum_id] is set, we update
* that forum, otherwise a new one is created.
* @since 3.1.0-a1
+ * @change 3.2.0-a1 Replaced forum_data by forum_data_ary
*/
- $vars = array('forum_data', 'forum_data_sql');
+ $vars = array('forum_data_ary', 'forum_data_sql');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_before', compact($vars)));
+ $forum_data = $forum_data_ary;
+ unset($forum_data_ary);
$is_new_forum = !isset($forum_data_sql['forum_id']);
@@ -1348,11 +1356,12 @@ class acp_forums
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_FORUM_EDIT', false, array($forum_data['forum_name']));
}
+ $forum_data_ary = $forum_data;
/**
* Event after a forum was updated or created
*
* @event core.acp_manage_forums_update_data_after
- * @var array forum_data Array with forum data
+ * @var array forum_data_ary Array with forum data
* @var array forum_data_sql Array with data we updated
* @var bool is_new_forum Did we create a forum or update one
* If you want to overwrite this value,
@@ -1360,9 +1369,12 @@ class acp_forums
* @var array errors Array of errors, should be strings and not
* language key.
* @since 3.1.0-a1
+ * @change 3.2.0-a1 Replaced forum_data with forum_data_ary
*/
- $vars = array('forum_data', 'forum_data_sql', 'is_new_forum', 'errors');
+ $vars = array('forum_data_ary', 'forum_data_sql', 'is_new_forum', 'errors');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_after', compact($vars)));
+ $forum_data = $forum_data_ary;
+ unset($forum_data_ary);
return $errors;
}
@@ -1788,7 +1800,7 @@ class acp_forums
*/
function delete_forum_content($forum_id)
{
- global $db, $config, $phpbb_root_path, $phpEx, $phpbb_dispatcher;
+ global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
@@ -1809,7 +1821,10 @@ class acp_forums
}
$db->sql_freeresult($result);
- delete_attachments('topic', $topic_ids, false);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('topic', $topic_ids, false);
+ unset($attachment_manager);
// Delete shadow topics pointing to topics in this forum
delete_topic_shadows($forum_id);
diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php
index 138234caee..41366982d2 100644
--- a/phpBB/includes/acp/acp_groups.php
+++ b/phpBB/includes/acp/acp_groups.php
@@ -42,7 +42,10 @@ class acp_groups
return;
}
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('group_user_attributes'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
// Check and set some common vars
$action = (isset($_POST['add'])) ? 'add' : ((isset($_POST['addusers'])) ? 'addusers' : $request->variable('action', ''));
@@ -298,7 +301,10 @@ class acp_groups
case 'edit':
case 'add':
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ if (!function_exists('display_forums'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
$data = $submit_ary = array();
diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php
index df445394db..8c021560a0 100644
--- a/phpBB/includes/acp/acp_inactive.php
+++ b/phpBB/includes/acp/acp_inactive.php
@@ -34,7 +34,10 @@ class acp_inactive
global $config, $db, $user, $auth, $template, $phpbb_container, $phpbb_log, $request;
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix;
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_active_flip'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$user->add_lang('memberlist');
@@ -111,7 +114,10 @@ class acp_inactive
if ($config['require_activation'] == USER_ACTIVATION_ADMIN && !empty($inactive_users))
{
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ if (!class_exists('messenger'))
+ {
+ include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ }
$messenger = new messenger(false);
@@ -200,7 +206,10 @@ class acp_inactive
if ($row = $db->sql_fetchrow($result))
{
// Send the messages
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ if (!class_exists('messenger'))
+ {
+ include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ }
$messenger = new messenger();
$usernames = $user_ids = array();
diff --git a/phpBB/includes/acp/acp_jabber.php b/phpBB/includes/acp/acp_jabber.php
index 5058e9c769..1726728086 100644
--- a/phpBB/includes/acp/acp_jabber.php
+++ b/phpBB/includes/acp/acp_jabber.php
@@ -34,7 +34,10 @@ class acp_jabber
$user->add_lang('acp/board');
- include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx);
+ if (!class_exists('jabber'))
+ {
+ include($phpbb_root_path . 'includes/functions_jabber.' . $phpEx);
+ }
$action = $request->variable('action', '');
$submit = (isset($_POST['submit'])) ? true : false;
diff --git a/phpBB/includes/acp/acp_language.php b/phpBB/includes/acp/acp_language.php
index e7ee7f47d6..03172e475a 100644
--- a/phpBB/includes/acp/acp_language.php
+++ b/phpBB/includes/acp/acp_language.php
@@ -34,7 +34,10 @@ class acp_language
global $config, $db, $user, $template, $phpbb_log, $phpbb_container;
global $phpbb_root_path, $phpEx, $request;
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('validate_language_iso_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
// Check and set some common vars
$action = (isset($_POST['update_details'])) ? 'update_details' : '';
diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php
index 47e2660770..529c3a1835 100644
--- a/phpBB/includes/acp/acp_main.php
+++ b/phpBB/includes/acp/acp_main.php
@@ -434,21 +434,29 @@ class acp_main
));
}
- /* @var $version_helper \phpbb\version_helper */
- $version_helper = $phpbb_container->get('version_helper');
- try
+ if ($auth->acl_get('a_board'))
{
- $recheck = $request->variable('versioncheck_force', false);
- $updates_available = $version_helper->get_suggested_updates($recheck);
+ /* @var $version_helper \phpbb\version_helper */
+ $version_helper = $phpbb_container->get('version_helper');
+ try
+ {
+ $recheck = $request->variable('versioncheck_force', false);
+ $updates_available = $version_helper->get_suggested_updates($recheck);
- $template->assign_var('S_VERSION_UP_TO_DATE', empty($updates_available));
+ $template->assign_var('S_VERSION_UP_TO_DATE', empty($updates_available));
+ }
+ catch (\RuntimeException $e)
+ {
+ $template->assign_vars(array(
+ 'S_VERSIONCHECK_FAIL' => true,
+ 'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== $user->lang('VERSIONCHECK_FAIL')) ? $e->getMessage() : '',
+ ));
+ }
}
- catch (\RuntimeException $e)
+ else
{
- $template->assign_vars(array(
- 'S_VERSIONCHECK_FAIL' => true,
- 'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== $user->lang('VERSIONCHECK_FAIL')) ? $e->getMessage() : '',
- ));
+ // We set this template var to true, to not display an outdated version notice.
+ $template->assign_var('S_VERSION_UP_TO_DATE', true);
}
/**
@@ -559,6 +567,7 @@ class acp_main
'U_VERSIONCHECK' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=update&amp;mode=version_check'),
'U_VERSIONCHECK_FORCE' => append_sid("{$phpbb_admin_path}index.$phpEx", 'versioncheck_force=1'),
+ 'S_VERSIONCHECK' => ($auth->acl_get('a_board')) ? true : false,
'S_ACTION_OPTIONS' => ($auth->acl_get('a_board')) ? true : false,
'S_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false,
)
diff --git a/phpBB/includes/acp/acp_permission_roles.php b/phpBB/includes/acp/acp_permission_roles.php
index 21c751b61a..2d71ab4c71 100644
--- a/phpBB/includes/acp/acp_permission_roles.php
+++ b/phpBB/includes/acp/acp_permission_roles.php
@@ -30,8 +30,15 @@ class acp_permission_roles
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
global $request, $phpbb_log;
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
- include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
+
+ if (!class_exists('auth_admin'))
+ {
+ include($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ }
$this->auth_admin = new auth_admin();
diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php
index 1c54ce2c65..26e7266409 100644
--- a/phpBB/includes/acp/acp_permissions.php
+++ b/phpBB/includes/acp/acp_permissions.php
@@ -34,8 +34,15 @@ class acp_permissions
global $db, $user, $auth, $template, $cache, $phpbb_container, $request;
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
- include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
+
+ if (!class_exists('auth_admin'))
+ {
+ include($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ }
$this->permissions = $phpbb_container->get('acl.permissions');
diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php
index c60e203040..07620d0dcd 100644
--- a/phpBB/includes/acp/acp_profile.php
+++ b/phpBB/includes/acp/acp_profile.php
@@ -37,8 +37,15 @@ class acp_profile
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix;
global $request, $phpbb_container, $phpbb_log, $phpbb_dispatcher;
- include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('generate_smilies'))
+ {
+ include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
+ }
+
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$user->add_lang(array('ucp', 'acp/profile'));
$this->tpl_name = 'acp_profile';
diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php
index 025ace9809..2ea1e89df6 100644
--- a/phpBB/includes/acp/acp_prune.php
+++ b/phpBB/includes/acp/acp_prune.php
@@ -28,7 +28,11 @@ class acp_prune
global $user, $phpEx, $phpbb_admin_path, $phpbb_root_path;
$user->add_lang('acp/prune');
- include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+
+ if (!function_exists('user_active_flip'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
switch ($mode)
{
diff --git a/phpBB/includes/acp/acp_send_statistics.php b/phpBB/includes/acp/acp_send_statistics.php
index 4c5786dbe9..74da5996f1 100644
--- a/phpBB/includes/acp/acp_send_statistics.php
+++ b/phpBB/includes/acp/acp_send_statistics.php
@@ -27,7 +27,10 @@ class acp_send_statistics
{
global $config, $template, $phpbb_admin_path, $phpbb_root_path, $phpEx;
- include($phpbb_root_path . 'includes/questionnaire/questionnaire.' . $phpEx);
+ if (!class_exists('phpbb_questionnaire_data_collector'))
+ {
+ include($phpbb_root_path . 'includes/questionnaire/questionnaire.' . $phpEx);
+ }
$collect_url = "https://www.phpbb.com/stats/receive_stats.php";
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php
index de3ca5f787..0cd6633710 100644
--- a/phpBB/includes/acp/acp_styles.php
+++ b/phpBB/includes/acp/acp_styles.php
@@ -62,9 +62,12 @@ class acp_styles
/** @var string */
protected $php_ext;
+ /** @var \phpbb\event\dispatcher_interface */
+ protected $dispatcher;
+
public function main($id, $mode)
{
- global $db, $user, $phpbb_admin_path, $phpbb_root_path, $phpEx, $template, $request, $cache, $auth, $config, $phpbb_container;
+ global $db, $user, $phpbb_admin_path, $phpbb_root_path, $phpEx, $template, $request, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_container;
$this->db = $db;
$this->user = $user;
@@ -76,6 +79,7 @@ class acp_styles
$this->config = $config;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $phpEx;
+ $this->dispatcher = $phpbb_dispatcher;
$this->default_style = $config['default_style'];
$this->styles_path = $this->phpbb_root_path . $this->styles_path_absolute . '/';
@@ -125,6 +129,18 @@ class acp_styles
)
);
+ /**
+ * Run code before ACP styles action execution
+ *
+ * @event core.acp_styles_action_before
+ * @var int id Module ID
+ * @var string mode Active module
+ * @var string action Module that should be run
+ * @since 3.1.7-RC1
+ */
+ $vars = array('id', 'mode', 'action');
+ extract($this->dispatcher->trigger_event('core.acp_styles_action_before', compact($vars)));
+
// Execute actions
switch ($action)
{
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 857c625867..b0b8fb1e60 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -57,7 +57,10 @@ class acp_users
// Whois (special case)
if ($action == 'whois')
{
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$this->page_title = 'WHOIS';
$this->tpl_name = 'simple_body';
@@ -170,7 +173,10 @@ class acp_users
{
case 'overview':
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$user->add_lang('acp/ban');
@@ -354,7 +360,10 @@ class acp_users
if ($config['email_enable'])
{
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ if (!class_exists('messenger'))
+ {
+ include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ }
$server_url = generate_board_url();
@@ -440,7 +449,10 @@ class acp_users
$phpbb_notifications = $phpbb_container->get('notification_manager');
$phpbb_notifications->delete_notifications('notification.type.admin_activate_user', $user_row['user_id']);
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ if (!class_exists('messenger'))
+ {
+ include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
+ }
$messenger = new messenger(false);
@@ -543,7 +555,10 @@ class acp_users
if (confirm_box(true))
{
- delete_attachments('user', $user_id);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('user', $user_id);
+ unset($attachment_manager);
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_USER_DEL_ATTACH', false, array($user_row['username']));
trigger_error($user->lang['USER_ATTACHMENTS_REMOVED'] . adm_back_link($this->u_action . '&amp;u=' . $user_id));
@@ -1397,7 +1412,10 @@ class acp_users
case 'profile':
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
/* @var $cp \phpbb\profilefields\manager */
$cp = $phpbb_container->get('profilefields.manager');
@@ -1557,7 +1575,10 @@ class acp_users
case 'prefs':
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('user_get_id_name'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$data = array(
'dateformat' => $request->variable('dateformat', $user_row['user_dateformat'], true),
@@ -1827,8 +1848,6 @@ class acp_users
case 'avatar':
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
-
$avatars_enabled = false;
if ($config['allow_avatar'])
@@ -1984,7 +2003,10 @@ class acp_users
case 'sig':
- include_once($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ if (!function_exists('display_custom_bbcodes'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
$enable_bbcode = ($config['allow_sig_bbcode']) ? $this->optionget($user_row, 'sig_bbcode') : false;
$enable_smilies = ($config['allow_sig_smilies']) ? $this->optionget($user_row, 'sig_smilies') : false;
@@ -2007,7 +2029,20 @@ class acp_users
}
$bbcode_uid = $bbcode_bitfield = $bbcode_flags = '';
- $warn_msg = generate_text_for_storage($signature, $bbcode_uid, $bbcode_bitfield, $bbcode_flags, $enable_bbcode, $enable_urls, $enable_smilies);
+ $warn_msg = generate_text_for_storage(
+ $signature,
+ $bbcode_uid,
+ $bbcode_bitfield,
+ $bbcode_flags,
+ $enable_bbcode,
+ $enable_urls,
+ $enable_smilies,
+ $config['allow_sig_img'],
+ $config['allow_sig_flash'],
+ true,
+ $config['allow_sig_links'],
+ 'sig'
+ );
if (sizeof($warn_msg))
{
@@ -2126,7 +2161,10 @@ class acp_users
}
$db->sql_freeresult($result);
- delete_attachments('attach', $marked);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('attach', $marked);
+ unset($attachment_manager);
$message = (sizeof($log_attachments) == 1) ? $user->lang['ATTACHMENT_DELETED'] : $user->lang['ATTACHMENTS_DELETED'];
@@ -2236,7 +2274,10 @@ class acp_users
case 'groups':
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ if (!function_exists('group_user_attributes'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
$user->add_lang(array('groups', 'acp/groups'));
$group_id = $request->variable('g', 0);
@@ -2455,7 +2496,10 @@ class acp_users
case 'perm':
- include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ if (!class_exists('auth_admin'))
+ {
+ include($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
+ }
$auth_admin = new auth_admin();
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 58b2f0ca57..d4f662626e 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -3618,10 +3618,14 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum'
if (sizeof($online_users['online_users']))
{
- $sql = 'SELECT username, username_clean, user_id, user_type, user_allow_viewonline, user_colour
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('user_id', $online_users['online_users']) . '
- ORDER BY username_clean ASC';
+ $sql_ary = array(
+ 'SELECT' => 'u.username, u.username_clean, u.user_id, u.user_type, u.user_allow_viewonline, u.user_colour',
+ 'FROM' => array(
+ USERS_TABLE => 'u',
+ ),
+ 'WHERE' => $db->sql_in_set('u.user_id', $online_users['online_users']),
+ 'ORDER_BY' => 'u.username_clean ASC',
+ );
/**
* Modify SQL query to obtain online users data
@@ -3633,13 +3637,14 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum'
* @var string item Restrict online users to a certain
* session item, e.g. forum for
* session_forum_id
- * @var string sql SQL query to obtain users online data
+ * @var string sql_ary SQL query to obtain users online data
* @since 3.1.4-RC1
+ * @changed 3.1.7-RC1 Change sql query into array and adjust var accordingly. Allows extension authors the ability to adjust the sql_ary.
*/
- $vars = array('online_users', 'item_id', 'item', 'sql');
+ $vars = array('online_users', 'item_id', 'item', 'sql_ary');
extract($phpbb_dispatcher->trigger_event('core.obtain_users_online_string_sql', compact($vars)));
- $result = $db->sql_query($sql);
+ $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary));
$rowset = $db->sql_fetchrowset($result);
$db->sql_freeresult($result);
@@ -3653,7 +3658,7 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum'
$row['username'] = '<em>' . $row['username'] . '</em>';
}
- if (!isset($online_users['hidden_users'][$row['user_id']]) || $auth->acl_get('u_viewonline'))
+ if (!isset($online_users['hidden_users'][$row['user_id']]) || $auth->acl_get('u_viewonline') || $row['user_id'] === $user->data['user_id'])
{
$user_online_link[$row['user_id']] = get_username_string(($row['user_type'] <> USER_IGNORE) ? 'full' : 'no_profile', $row['user_id'], $row['username'], $row['user_colour']);
}
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index eea18a0c47..390b59b9e9 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -383,6 +383,7 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars)
$tpl .= $vars['append'];
}
+ $new_ary = $new;
/**
* Overwrite the html code we display for the config value
*
@@ -392,14 +393,17 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars)
* 1 [optional] => string: size, int: minimum
* 2 [optional] => string: max. length, int: maximum
* @var string key Should be used for the id attribute in html
- * @var array new Array with the config values we display
+ * @var array new_ary Array with the config values we display
* @var string name Should be used for the name attribute
* @var array vars Array with the options for the config
* @var string tpl The resulting html code we display
* @since 3.1.0-a1
+ * @change 3.2.0-a1 Replaced new with new_ary
*/
- $vars = array('tpl_type', 'key', 'new', 'name', 'vars', 'tpl');
+ $vars = array('tpl_type', 'key', 'new_ary', 'name', 'vars', 'tpl');
extract($phpbb_dispatcher->trigger_event('core.build_config_template', compact($vars)));
+ $new = $new_ary;
+ unset($new_ary);
return $tpl;
}
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index 3515150f93..459d61a17a 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -833,6 +833,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
'notification.type.quote',
'notification.type.approve_post',
'notification.type.post_in_queue',
+ 'notification.type.report_post',
);
/**
@@ -1024,7 +1025,10 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
$search->index_remove($post_ids, $poster_ids, $forum_ids);
- delete_attachments('post', $post_ids, false);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('post', $post_ids, false);
+ unset($attachment_manager);
/**
* Perform additional actions during post(s) deletion
@@ -1111,329 +1115,21 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
/**
* Delete Attachments
*
+* @deprecated 3.2.0-a1 (To be removed: 3.4.0)
+*
* @param string $mode can be: post|message|topic|attach|user
* @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids
* @param bool $resync set this to false if you are deleting posts or topics
*/
function delete_attachments($mode, $ids, $resync = true)
{
- global $db, $config, $phpbb_dispatcher;
-
- // 0 is as bad as an empty array
- if (empty($ids))
- {
- return false;
- }
-
- if (is_array($ids))
- {
- $ids = array_unique($ids);
- $ids = array_map('intval', $ids);
- }
- else
- {
- $ids = array((int) $ids);
- }
-
- $sql_where = '';
-
- switch ($mode)
- {
- case 'post':
- case 'message':
- $sql_id = 'post_msg_id';
- $sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0);
- break;
-
- case 'topic':
- $sql_id = 'topic_id';
- break;
-
- case 'user':
- $sql_id = 'poster_id';
- break;
-
- case 'attach':
- default:
- $sql_id = 'attach_id';
- $mode = 'attach';
- break;
- }
-
- $post_ids = $message_ids = $topic_ids = $physical = array();
-
- /**
- * Perform additional actions before collecting data for attachment(s) deletion
- *
- * @event core.delete_attachments_collect_data_before
- * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
- * @var mixed ids Array or comma separated list of ids corresponding to the mode
- * @var bool resync Flag indicating if posts/messages/topics should be synchronized
- * @var string sql_id The field name to collect/delete data for depending on the mode
- * @since 3.1.7-RC1
- */
- $vars = array(
- 'mode',
- 'ids',
- 'resync',
- 'sql_id',
- );
- extract($phpbb_dispatcher->trigger_event('core.delete_attachments_collect_data_before', compact($vars)));
-
- // Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled)
- $sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan
- FROM ' . ATTACHMENTS_TABLE . '
- WHERE ' . $db->sql_in_set($sql_id, $ids);
-
- $sql .= $sql_where;
-
- $result = $db->sql_query($sql);
-
- while ($row = $db->sql_fetchrow($result))
- {
- // We only need to store post/message/topic ids if resync is enabled and the file is not orphaned
- if ($resync && !$row['is_orphan'])
- {
- if (!$row['in_message'])
- {
- $post_ids[] = $row['post_msg_id'];
- $topic_ids[] = $row['topic_id'];
- }
- else
- {
- $message_ids[] = $row['post_msg_id'];
- }
- }
-
- $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize'], 'is_orphan' => $row['is_orphan']);
- }
- $db->sql_freeresult($result);
-
- /**
- * Perform additional actions before attachment(s) deletion
- *
- * @event core.delete_attachments_before
- * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
- * @var mixed ids Array or comma separated list of ids corresponding to the mode
- * @var bool resync Flag indicating if posts/messages/topics should be synchronized
- * @var string sql_id The field name to collect/delete data for depending on the mode
- * @var array post_ids Array with post ids for deleted attachment(s)
- * @var array topic_ids Array with topic ids for deleted attachment(s)
- * @var array message_ids Array with private message ids for deleted attachment(s)
- * @var array physical Array with deleted attachment(s) physical file(s) data
- * @since 3.1.7-RC1
- */
- $vars = array(
- 'mode',
- 'ids',
- 'resync',
- 'sql_id',
- 'post_ids',
- 'topic_ids',
- 'message_ids',
- 'physical',
- );
- extract($phpbb_dispatcher->trigger_event('core.delete_attachments_before', compact($vars)));
-
- // Delete attachments
- $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . '
- WHERE ' . $db->sql_in_set($sql_id, $ids);
-
- $sql .= $sql_where;
-
- $db->sql_query($sql);
- $num_deleted = $db->sql_affectedrows();
-
- /**
- * Perform additional actions after attachment(s) deletion from the database
- *
- * @event core.delete_attachments_from_database_after
- * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
- * @var mixed ids Array or comma separated list of ids corresponding to the mode
- * @var bool resync Flag indicating if posts/messages/topics should be synchronized
- * @var string sql_id The field name to collect/delete data for depending on the mode
- * @var array post_ids Array with post ids for deleted attachment(s)
- * @var array topic_ids Array with topic ids for deleted attachment(s)
- * @var array message_ids Array with private message ids for deleted attachment(s)
- * @var array physical Array with deleted attachment(s) physical file(s) data
- * @var int num_deleted The number of deleted attachment(s) from the database
- * @since 3.1.7-RC1
- */
- $vars = array(
- 'mode',
- 'ids',
- 'resync',
- 'sql_id',
- 'post_ids',
- 'topic_ids',
- 'message_ids',
- 'physical',
- 'num_deleted',
- );
- extract($phpbb_dispatcher->trigger_event('core.delete_attachments_from_database_after', compact($vars)));
-
- if (!$num_deleted)
- {
- return 0;
- }
+ global $phpbb_container;
- // Delete attachments from filesystem
- $space_removed = $files_removed = 0;
- foreach ($physical as $file_ary)
- {
- if (phpbb_unlink($file_ary['filename'], 'file', true) && !$file_ary['is_orphan'])
- {
- // Only non-orphaned files count to the file size
- $space_removed += $file_ary['filesize'];
- $files_removed++;
- }
-
- if ($file_ary['thumbnail'])
- {
- phpbb_unlink($file_ary['filename'], 'thumbnail', true);
- }
- }
-
- /**
- * Perform additional actions after attachment(s) deletion from the filesystem
- *
- * @event core.delete_attachments_from_filesystem_after
- * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
- * @var mixed ids Array or comma separated list of ids corresponding to the mode
- * @var bool resync Flag indicating if posts/messages/topics should be synchronized
- * @var string sql_id The field name to collect/delete data for depending on the mode
- * @var array post_ids Array with post ids for deleted attachment(s)
- * @var array topic_ids Array with topic ids for deleted attachment(s)
- * @var array message_ids Array with private message ids for deleted attachment(s)
- * @var array physical Array with deleted attachment(s) physical file(s) data
- * @var int num_deleted The number of deleted attachment(s) from the database
- * @var int space_removed The size of deleted files(s) from the filesystem
- * @var int files_removed The number of deleted file(s) from the filesystem
- * @since 3.1.7-RC1
- */
- $vars = array(
- 'mode',
- 'ids',
- 'resync',
- 'sql_id',
- 'post_ids',
- 'topic_ids',
- 'message_ids',
- 'physical',
- 'num_deleted',
- 'space_removed',
- 'files_removed',
- );
- extract($phpbb_dispatcher->trigger_event('core.delete_attachments_from_filesystem_after', compact($vars)));
-
- if ($space_removed || $files_removed)
- {
- $config->increment('upload_dir_size', $space_removed * (-1), false);
- $config->increment('num_files', $files_removed * (-1), false);
- }
-
- // If we do not resync, we do not need to adjust any message, post, topic or user entries
- if (!$resync)
- {
- return $num_deleted;
- }
-
- // No more use for the original ids
- unset($ids);
-
- // Now, we need to resync posts, messages, topics. We go through every one of them
- $post_ids = array_unique($post_ids);
- $message_ids = array_unique($message_ids);
- $topic_ids = array_unique($topic_ids);
-
- // Update post indicators for posts now no longer having attachments
- if (sizeof($post_ids))
- {
- // Just check which posts are still having an assigned attachment not orphaned by querying the attachments table
- $sql = 'SELECT post_msg_id
- FROM ' . ATTACHMENTS_TABLE . '
- WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . '
- AND in_message = 0
- AND is_orphan = 0';
- $result = $db->sql_query($sql);
-
- $remaining_ids = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $remaining_ids[] = $row['post_msg_id'];
- }
- $db->sql_freeresult($result);
-
- // Now only unset those ids remaining
- $post_ids = array_diff($post_ids, $remaining_ids);
-
- if (sizeof($post_ids))
- {
- $sql = 'UPDATE ' . POSTS_TABLE . '
- SET post_attachment = 0
- WHERE ' . $db->sql_in_set('post_id', $post_ids);
- $db->sql_query($sql);
- }
- }
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $num_deleted = $attachment_manager->delete($mode, $ids, $resync);
- // Update message table if messages are affected
- if (sizeof($message_ids))
- {
- // Just check which messages are still having an assigned attachment not orphaned by querying the attachments table
- $sql = 'SELECT post_msg_id
- FROM ' . ATTACHMENTS_TABLE . '
- WHERE ' . $db->sql_in_set('post_msg_id', $message_ids) . '
- AND in_message = 1
- AND is_orphan = 0';
- $result = $db->sql_query($sql);
-
- $remaining_ids = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $remaining_ids[] = $row['post_msg_id'];
- }
- $db->sql_freeresult($result);
-
- // Now only unset those ids remaining
- $message_ids = array_diff($message_ids, $remaining_ids);
-
- if (sizeof($message_ids))
- {
- $sql = 'UPDATE ' . PRIVMSGS_TABLE . '
- SET message_attachment = 0
- WHERE ' . $db->sql_in_set('msg_id', $message_ids);
- $db->sql_query($sql);
- }
- }
-
- // Now update the topics. This is a bit trickier, because there could be posts still having attachments within the topic
- if (sizeof($topic_ids))
- {
- // Just check which topics are still having an assigned attachment not orphaned by querying the attachments table (much less entries expected)
- $sql = 'SELECT topic_id
- FROM ' . ATTACHMENTS_TABLE . '
- WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . '
- AND is_orphan = 0';
- $result = $db->sql_query($sql);
-
- $remaining_ids = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $remaining_ids[] = $row['topic_id'];
- }
- $db->sql_freeresult($result);
-
- // Now only unset those ids remaining
- $topic_ids = array_diff($topic_ids, $remaining_ids);
-
- if (sizeof($topic_ids))
- {
- $sql = 'UPDATE ' . TOPICS_TABLE . '
- SET topic_attachment = 0
- WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
- $db->sql_query($sql);
- }
- }
+ unset($attachment_manager);
return $num_deleted;
}
@@ -1551,27 +1247,19 @@ function update_posted_info(&$topic_ids)
/**
* Delete attached file
+*
+* @deprecated 3.2.0-a1 (To be removed: 3.4.0)
*/
function phpbb_unlink($filename, $mode = 'file', $entry_removed = false)
{
- global $db, $phpbb_root_path, $config;
+ global $phpbb_container;
- // Because of copying topics or modifications a physical filename could be assigned more than once. If so, do not remove the file itself.
- $sql = 'SELECT COUNT(attach_id) AS num_entries
- FROM ' . ATTACHMENTS_TABLE . "
- WHERE physical_filename = '" . $db->sql_escape(utf8_basename($filename)) . "'";
- $result = $db->sql_query($sql);
- $num_entries = (int) $db->sql_fetchfield('num_entries');
- $db->sql_freeresult($result);
-
- // Do not remove file if at least one additional entry with the same name exist.
- if (($entry_removed && $num_entries > 0) || (!$entry_removed && $num_entries > 1))
- {
- return false;
- }
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $unlink = $attachment_manager->unlink($filename, $mode, $entry_removed);
+ unset($attachment_manager);
- $filename = ($mode == 'thumbnail') ? 'thumb_' . utf8_basename($filename) : utf8_basename($filename);
- return @unlink($phpbb_root_path . $config['upload_path'] . '/' . $filename);
+ return $unlink;
}
/**
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index 345df1d47a..b87220caa5 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -564,10 +564,11 @@ function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text
* @param bool $allow_flash_bbcode
* @param bool $allow_quote_bbcode
* @param bool $allow_url_bbcode
+* @param string $mode Mode to parse text as, e.g. post or sig
*
* @return array An array of string with the errors that occurred while parsing
*/
-function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true)
+function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $mode = 'post')
{
global $phpbb_root_path, $phpEx, $phpbb_dispatcher;
@@ -586,7 +587,9 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb
* @var bool allow_flash_bbcode Whether or not to parse the [flash] BBCode
* @var bool allow_quote_bbcode Whether or not to parse the [quote] BBCode
* @var bool allow_url_bbcode Whether or not to parse the [url] BBCode
+ * @var string mode Mode to parse text as, e.g. post or sig
* @since 3.1.0-a1
+ * @changed 3.2.0-a1
*/
$vars = array(
'text',
@@ -600,6 +603,7 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb
'allow_flash_bbcode',
'allow_quote_bbcode',
'allow_url_bbcode',
+ 'mode',
);
extract($phpbb_dispatcher->trigger_event('core.modify_text_for_storage_before', compact($vars)));
@@ -612,7 +616,7 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb
}
$message_parser = new parse_message($text);
- $message_parser->parse($allow_bbcode, $allow_urls, $allow_smilies, $allow_img_bbcode, $allow_flash_bbcode, $allow_quote_bbcode, $allow_url_bbcode);
+ $message_parser->parse($allow_bbcode, $allow_urls, $allow_smilies, $allow_img_bbcode, $allow_flash_bbcode, $allow_quote_bbcode, $allow_url_bbcode, true, $mode);
$text = $message_parser->message;
$uid = $message_parser->bbcode_uid;
@@ -1206,6 +1210,7 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
);
}
+ $update_count_ary = $update_count;
/**
* Use this event to modify the attachment template data.
*
@@ -1219,8 +1224,9 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
* @var array extensions Array with attachment extensions data
* @var mixed forum_id The forum id the attachments are displayed in (false if in private message)
* @var bool preview Flag indicating if we are in post preview mode
- * @var array update_count Array with attachment ids to update download count
+ * @var array update_count_ary Array with attachment ids to update download count
* @since 3.1.0-RC5
+ * @change 3.2.0-a1 Replaced update_count with update_count_ary
*/
$vars = array(
'attachment',
@@ -1230,9 +1236,11 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
'extensions',
'forum_id',
'preview',
- 'update_count',
+ 'update_count_ary',
);
extract($phpbb_dispatcher->trigger_event('core.parse_attachments_modify_template_data', compact($vars)));
+ $update_count = $update_count_ary;
+ unset($update_count_ary);
$template->assign_block_vars('_file', $block_array);
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index 3d61b5c098..9e45f32689 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -438,15 +438,14 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
*
* @event core.display_forums_modify_category_template_vars
* @var array cat_row Template data of the 'category'
- * @var bool catless The flag indicating whether the 'category' has a parent category
* @var bool last_catless The flag indicating whether the last forum had a parent category
* @var array root_data Array with the root forum data
* @var array row The data of the 'category'
* @since 3.1.0-RC4
+ * @change 3.1.7-RC1 Removed undefined catless variable
*/
$vars = array(
'cat_row',
- 'catless',
'last_catless',
'root_data',
'row',
@@ -811,25 +810,29 @@ function generate_forum_nav(&$forum_data)
'S_ENABLE_FEEDS_FORUM' => ($config['feed_forum'] && $forum_data['forum_type'] == FORUM_POST && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $forum_data['forum_options'])) ? true : false,
);
+ $forum_data_ary = $forum_data;
/**
* Event to modify the navlinks text
*
* @event core.generate_forum_nav
- * @var array forum_data Array with the forum data
+ * @var array forum_data_ary Array with the forum data
* @var array forum_template_data Array with generic forum template data
* @var string microdata_attr The microdata attribute
* @var array navlinks_parents Array with the forum parents navlinks data
* @var array navlinks Array with the forum navlinks data
* @since 3.1.5-RC1
+ * @change 3.2.0-a1 Replaced forum_data with forum_data_ary
*/
$vars = array(
- 'forum_data',
+ 'forum_data_ary',
'forum_template_data',
'microdata_attr',
'navlinks_parents',
'navlinks',
);
extract($phpbb_dispatcher->trigger_event('core.generate_forum_nav', compact($vars)));
+ $forum_data = $forum_data_ary;
+ unset($forum_data_ary);
$template->assign_block_vars_array('navlinks', $navlinks_parents);
$template->assign_block_vars('navlinks', $navlinks);
@@ -1237,17 +1240,21 @@ function display_user_activity(&$userdata)
}
}
+ $userdata_ary = $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 userdata_ary 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
+ * @change 3.2.0-a1 Replaced userdata with userdata_ary
*/
- $vars = array('userdata', 'active_f_row', 'active_t_row');
+ $vars = array('userdata_ary', 'active_f_row', 'active_t_row');
extract($phpbb_dispatcher->trigger_event('core.display_user_activity_modify_actives', compact($vars)));
+ $userdata = $userdata_ary;
+ unset($userdata_ary);
$userdata['active_t_row'] = $active_t_row;
$userdata['active_f_row'] = $active_f_row;
diff --git a/phpBB/includes/functions_mcp.php b/phpBB/includes/functions_mcp.php
index 50acbebd4f..f9e38e8aa0 100644
--- a/phpBB/includes/functions_mcp.php
+++ b/phpBB/includes/functions_mcp.php
@@ -557,6 +557,11 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
// Default total to -1 to allow editing by the event
$total = -1;
+ $sort_by_sql_ary = $sort_by_sql;
+ $sort_days_val = $sort_days;
+ $sort_dir_val = $sort_dir;
+ $sort_key_val = $sort_key;
+ $total_val = $total;
/**
* This event allows you to control the SQL query used to get the total number
* of reports the user can access.
@@ -571,19 +576,20 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
* @var string type Which kind of information is this being used for displaying. Posts, topics, etc...
* @var int forum_id The forum id of the posts the user is trying to access, if not 0
* @var int topic_id The topic id of the posts the user is trying to access, if not 0
- * @var int sort_days The max age of the oldest report to be shown, in days
- * @var string sort_key The way the user has decided to sort the data.
+ * @var int sort_days_val The max age of the oldest report to be shown, in days
+ * @var string sort_key_val The way the user has decided to sort the data.
* The valid values must be in the keys of the sort_by_* variables
- * @var string sort_dir Either 'd' for "DESC" or 'a' for 'ASC' in the SQL query
+ * @var string sort_dir_val Either 'd' for "DESC" or 'a' for 'ASC' in the SQL query
* @var int limit_days The possible max ages of the oldest report for the user to choose, in days.
- * @var array sort_by_sql SQL text (values) for the possible names of the ways of sorting data (keys).
+ * @var array sort_by_sql_ary SQL text (values) for the possible names of the ways of sorting data (keys).
* @var array sort_by_text Language text (values) for the possible names of the ways of sorting data (keys).
* @var int min_time Integer with the minimum post time that the user is searching for
* @var int limit_time_sql Time limiting options used in the SQL query.
- * @var int total The total number of reports that exist. Only set if you want to override the result
+ * @var int total_val The total number of reports that exist. Only set if you want to override the result
* @var string where_sql Extra information included in the WHERE clause. It must end with "WHERE" or "AND" or "OR".
* Set to "WHERE" and set total above -1 to override the total value
* @since 3.1.4-RC1
+ * @change 3.2.0-a1 Replaced sort_days, sort_key, sort_dir, sort_by_sql, total with replacement variables
*/
$vars = array(
'sql',
@@ -591,18 +597,28 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
'type',
'forum_id',
'topic_id',
- 'sort_days',
- 'sort_key',
- 'sort_dir',
+ 'sort_days_val',
+ 'sort_key_val',
+ 'sort_dir_val',
'limit_days',
- 'sort_by_sql',
+ 'sort_by_sql_ary',
'sort_by_text',
'min_time',
'limit_time_sql',
- 'total',
+ 'total_val',
'where_sql',
);
extract($phpbb_dispatcher->trigger_event('core.mcp_sorting_query_before', compact($vars)));
+ $sort_by_sql = $sort_by_sql_ary;
+ $sort_days = $sort_days_val;
+ $sort_key = $sort_key_val;
+ $sort_dir = $sort_dir_val;
+ $total = $total_val;
+ unset($sort_by_sql_ary);
+ unset($sort_days_val);
+ unset($sort_key_val);
+ unset($sort_dir_val);
+ unset($total_val);
if (!isset($sort_by_sql[$sort_key]))
{
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 19756d97b4..4f14dc8683 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -391,183 +391,27 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL)
* Upload Attachment - filedata is generated here
* Uses upload class
*
+* @deprecated 3.2.0-a1 (To be removed: 3.4.0)
+*
* @param string $form_name The form name of the file upload input
* @param int $forum_id The id of the forum
* @param bool $local Whether the file is local or not
* @param string $local_storage The path to the local file
* @param bool $is_message Whether it is a PM or not
-* @param \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
+* @param array $local_filedata A filespec object created for the local file
*
-* @return object filespec
+* @return array File data array
*/
-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)
+function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false)
{
- global $auth, $user, $config, $db, $cache;
- global $phpbb_root_path, $phpEx, $phpbb_dispatcher, $phpbb_container;
-
- $filedata = array(
- 'error' => array()
- );
-
- $upload = $phpbb_container->get('files.upload');
-
- if ($config['check_attachment_content'] && isset($config['mime_triggers']))
- {
- $upload->set_disallowed_content(explode('|', $config['mime_triggers']));
- }
- else if (!$config['check_attachment_content'])
- {
- $upload->set_disallowed_content(array());
- }
-
- $filedata['post_attach'] = $local || $upload->is_valid($form_name);
+ global $phpbb_container;
- if (!$filedata['post_attach'])
- {
- $filedata['error'][] = $user->lang['NO_UPLOAD_FORM_FOUND'];
- return $filedata;
- }
-
- $extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id));
- $upload->set_allowed_extensions(array_keys($extensions['_allowed_']));
-
- /** @var \phpbb\files\filespec $file */
- $file = ($local) ? $upload->handle_upload('files.types.local', $local_storage, $local_filedata) : $upload->handle_upload('files.types.form', $form_name);
-
- if ($file->init_error())
- {
- $filedata['post_attach'] = false;
- return $filedata;
- }
-
- // Whether the uploaded file is in the image category
- $is_image = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false;
-
- if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id))
- {
- // Check Image Size, if it is an image
- if ($is_image)
- {
- $file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
- }
-
- // Admins and mods are allowed to exceed the allowed filesize
- if (!empty($extensions[$file->get('extension')]['max_filesize']))
- {
- $allowed_filesize = $extensions[$file->get('extension')]['max_filesize'];
- }
- else
- {
- $allowed_filesize = ($is_message) ? $config['max_filesize_pm'] : $config['max_filesize'];
- }
-
- $file->upload->set_max_filesize($allowed_filesize);
- }
-
- $file->clean_filename('unique', $user->data['user_id'] . '_');
-
- // Are we uploading an image *and* this image being within the image category?
- // Only then perform additional image checks.
- $file->move_file($config['upload_path'], false, !$is_image);
-
- // Do we have to create a thumbnail?
- $filedata['thumbnail'] = ($is_image && $config['img_create_thumbnail']) ? 1 : 0;
-
- if (sizeof($file->error))
- {
- $file->remove();
- $filedata['error'] = array_merge($filedata['error'], $file->error);
- $filedata['post_attach'] = false;
-
- return $filedata;
- }
-
- // Make sure the image category only holds valid images...
- if ($is_image && !$file->is_image())
- {
- $file->remove();
-
- if ($plupload && $plupload->is_active())
- {
- $plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE');
- }
-
- // If this error occurs a user tried to exploit an IE Bug by renaming extensions
- // Since the image category is displaying content inline we need to catch this.
- trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
- }
-
- $filedata['filesize'] = $file->get('filesize');
- $filedata['mimetype'] = $file->get('mimetype');
- $filedata['extension'] = $file->get('extension');
- $filedata['physical_filename'] = $file->get('realname');
- $filedata['real_filename'] = $file->get('uploadname');
- $filedata['filetime'] = time();
-
- /**
- * Event to modify uploaded file before submit to the post
- *
- * @event core.modify_uploaded_file
- * @var array filedata Array containing uploaded file data
- * @var bool is_image Flag indicating if the file is an image
- * @since 3.1.0-RC3
- */
- $vars = array(
- 'filedata',
- 'is_image',
- );
- extract($phpbb_dispatcher->trigger_event('core.modify_uploaded_file', compact($vars)));
-
- // Check our complete quota
- if ($config['attachment_quota'])
- {
- if ($config['upload_dir_size'] + $file->get('filesize') > $config['attachment_quota'])
- {
- $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
- $filedata['post_attach'] = false;
-
- $file->remove();
-
- return $filedata;
- }
- }
-
- // Check free disk space
- if ($free_space = @disk_free_space($phpbb_root_path . $config['upload_path']))
- {
- if ($free_space <= $file->get('filesize'))
- {
- if ($auth->acl_get('a_'))
- {
- $filedata['error'][] = $user->lang['ATTACH_DISK_FULL'];
- }
- else
- {
- $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
- }
- $filedata['post_attach'] = false;
-
- $file->remove();
-
- return $filedata;
- }
- }
-
- // Create Thumbnail
- if ($filedata['thumbnail'])
- {
- $source = $file->get('destination_file');
- $destination = $file->get('destination_path') . '/thumb_' . $file->get('realname');
-
- if (!create_thumbnail($source, $destination, $file->get('mimetype')))
- {
- $filedata['thumbnail'] = 0;
- }
- }
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $file = $attachment_manager->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata);
+ unset($attachment_manager);
- return $filedata;
+ return $file;
}
/**
@@ -1520,6 +1364,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
{
global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher, $phpbb_log, $request;
+ $poll_ary = $poll;
+ $data_ary = $data;
/**
* Modify the data for post submitting
*
@@ -1528,23 +1374,28 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
* @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 array poll_ary Array with the poll data for the post
+ * @var array data_ary 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
* @since 3.1.0-a4
+ * @change 3.2.0-a1 Replaced poll and data with poll_ary and data_ary
*/
$vars = array(
'mode',
'subject',
'username',
'topic_type',
- 'poll',
- 'data',
+ 'poll_ary',
+ 'data_ary',
'update_message',
'update_search_index',
);
extract($phpbb_dispatcher->trigger_event('core.modify_submit_post_data', compact($vars)));
+ $poll = $poll_ary;
+ $data = $data_ary;
+ unset($poll_ary);
+ unset($data_ary);
// We do not handle erasing posts here
if ($mode == 'delete')
@@ -1869,22 +1720,25 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
break;
}
+ $poll_ary = $poll;
+ $data_ary = $data;
/**
* Modify sql query data for post submitting
*
* @event core.submit_post_modify_sql_data
- * @var array data Array with the data for the post
- * @var array poll Array with the poll data for the post
+ * @var array data_ary Array with the data for the post
+ * @var array poll_ary Array with the poll data for the post
* @var string post_mode Variable containing posting mode value
* @var bool sql_data Array with the data for the posting SQL query
* @var string subject Variable containing post subject value
* @var int topic_type Variable containing topic type value
* @var string username Variable containing post author name
* @since 3.1.3-RC1
+ * @change 3.2.0-a1 Replace poll and data with poll_ary and data_ary
*/
$vars = array(
- 'data',
- 'poll',
+ 'data_ary',
+ 'poll_ary',
'post_mode',
'sql_data',
'subject',
@@ -1892,6 +1746,10 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
'username',
);
extract($phpbb_dispatcher->trigger_event('core.submit_post_modify_sql_data', compact($vars)));
+ $poll = $poll_ary;
+ $data = $data_ary;
+ unset($poll_ary);
+ unset($data_ary);
// Submit new topic
if ($post_mode == 'post')
@@ -2439,6 +2297,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
$url = (!$params) ? "{$phpbb_root_path}viewforum.$phpEx" : "{$phpbb_root_path}viewtopic.$phpEx";
$url = append_sid($url, 'f=' . $data['forum_id'] . $params) . $add_anchor;
+ $poll_ary = $poll;
+ $data_ary = $data;
/**
* This event is used for performing actions directly after a post or topic
* has been submitted. When a new topic is posted, the topic ID is
@@ -2452,8 +2312,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
* @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 array poll_ary Array with the poll data for the post
+ * @var array data_ary Array with the data for the post
* @var int post_visibility Variable containing up to date post visibility
* @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
@@ -2462,20 +2322,25 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
* @since 3.1.0-a3
* @change 3.1.0-RC3 Added vars mode, subject, username, topic_type,
* poll, update_message, update_search_index
+ * @change 3.2.0-a1 Replaced data and poll with data_ary and poll_ary
*/
$vars = array(
'mode',
'subject',
'username',
'topic_type',
- 'poll',
- 'data',
+ 'poll_ary',
+ 'data_ary',
'post_visibility',
'update_message',
'update_search_index',
'url',
);
extract($phpbb_dispatcher->trigger_event('core.submit_post_end', compact($vars)));
+ $data = $data_ary;
+ $poll = $poll_ary;
+ unset($data_ary);
+ unset($poll_ary);
return $url;
}
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index 7b6540cda7..b2928d5df8 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -1153,12 +1153,10 @@ function delete_pm($user_id, $msg_ids, $folder_id)
if (sizeof($delete_ids))
{
// Check if there are any attachments we need to remove
- if (!function_exists('delete_attachments'))
- {
- include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
- }
-
- delete_attachments('message', $delete_ids, false);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('message', $delete_ids, false);
+ unset($attachment_manager);
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
@@ -1363,12 +1361,10 @@ function phpbb_delete_users_pms($user_ids)
if (!empty($delete_ids))
{
// Check if there are any attachments we need to remove
- if (!function_exists('delete_attachments'))
- {
- include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
- }
-
- delete_attachments('message', $delete_ids, false);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('message', $delete_ids, false);
+ unset($attachment_manager);
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
@@ -1624,17 +1620,21 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
$current_time = time();
+ $data_ary = $data;
/**
* Get all parts of the PM that are to be submited to the DB.
*
* @event core.submit_pm_before
* @var string mode PM Post mode - post|reply|quote|quotepost|forward|edit
* @var string subject Subject of the private message
- * @var array data The whole row data of the PM.
+ * @var array data_ary The whole row data of the PM.
* @since 3.1.0-b3
+ * @change 3.2.0-a1 Replaced data with data_ary
*/
- $vars = array('mode', 'subject', 'data');
+ $vars = array('mode', 'subject', 'data_ary');
extract($phpbb_dispatcher->trigger_event('core.submit_pm_before', compact($vars)));
+ $data = $data_ary;
+ unset($data_ary);
// Collect some basic information about which tables and which rows to update/insert
$sql_data = array();
@@ -1943,18 +1943,22 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
$phpbb_notifications->add_notifications('notification.type.pm', $pm_data);
}
+ $data_ary = $data;
/**
* Get PM message ID after submission to DB
*
* @event core.submit_pm_after
* @var string mode PM Post mode - post|reply|quote|quotepost|forward|edit
* @var string subject Subject of the private message
- * @var array data The whole row data of the PM.
+ * @var array data_ary The whole row data of the PM.
* @var array pm_data The data sent to notification class
* @since 3.1.0-b5
+ * @change 3.2.0-a1 Replaced data with data_ary
*/
- $vars = array('mode', 'subject', 'data', 'pm_data');
+ $vars = array('mode', 'subject', 'data_ary', 'pm_data');
extract($phpbb_dispatcher->trigger_event('core.submit_pm_after', compact($vars)));
+ $data = $data_ary;
+ unset($data_ary);
return $data['msg_id'];
}
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 98ffb4227d..7620cf1ff7 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -2871,6 +2871,19 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false,
// Clear permissions cache of relevant users
$auth->acl_clear_prefetch($user_id_ary);
+ /**
+ * Event after users are removed from a group
+ *
+ * @event core.group_delete_user_after
+ * @var int group_id ID of the group from which users are deleted
+ * @var string group_name Name of the group
+ * @var array user_id_ary IDs of the users which are removed
+ * @var array username_ary names of the users which are removed
+ * @since 3.1.7-RC1
+ */
+ $vars = array('group_id', 'group_name', 'user_id_ary', 'username_ary');
+ extract($phpbb_dispatcher->trigger_event('core.group_delete_user_after', compact($vars)));
+
if (!$group_name)
{
$group_name = get_group_name($group_id);
diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php
index f73973b81d..8237b834d6 100644
--- a/phpBB/includes/mcp/mcp_forum.php
+++ b/phpBB/includes/mcp/mcp_forum.php
@@ -334,16 +334,20 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
));
}
+ $row_ary = $row;
/**
* Modify the topic data before it is assigned to the template in MCP
*
* @event core.mcp_view_forum_modify_topicrow
- * @var array row Array with topic data
+ * @var array row_ary Array with topic data
* @var array topic_row Template array with topic data
* @since 3.1.0-a1
+ * @change 3.2.0-a1 Replace row with row_ary
*/
- $vars = array('row', 'topic_row');
+ $vars = array('row_ary', 'topic_row');
extract($phpbb_dispatcher->trigger_event('core.mcp_view_forum_modify_topicrow', compact($vars)));
+ $row = $row_ary;
+ unset($row_ary);
$template->assign_block_vars('topicrow', $topic_row);
}
diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php
index 132786818b..cb4b590196 100644
--- a/phpBB/includes/mcp/mcp_queue.php
+++ b/phpBB/includes/mcp/mcp_queue.php
@@ -1148,6 +1148,11 @@ class mcp_queue
// Build a list of posts to be disapproved and get the related topics real replies count
foreach ($post_info as $post_id => $post_data)
{
+ if ($mode === 'unapproved_topics' && $post_data['post_visibility'] == ITEM_APPROVED)
+ {
+ continue;
+ }
+
$post_disapprove_list[$post_id] = $post_data['topic_id'];
if (!isset($topic_posts_unapproved[$post_data['topic_id']]))
{
@@ -1157,6 +1162,12 @@ class mcp_queue
$topic_posts_unapproved[$post_data['topic_id']]++;
}
+ // Do not try to disapprove if no posts are selected
+ if (empty($post_disapprove_list))
+ {
+ trigger_error('NO_POST_SELECTED');
+ }
+
// Now we build the log array
foreach ($post_disapprove_list as $post_id => $topic_id)
{
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php
index 31fc1577a2..059037168d 100644
--- a/phpBB/includes/message_parser.php
+++ b/phpBB/includes/message_parser.php
@@ -1141,12 +1141,6 @@ 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 = '')
@@ -1541,6 +1535,7 @@ class parse_message extends bbcode_firstpass
function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false)
{
global $config, $auth, $user, $phpbb_root_path, $phpEx, $db, $request;
+ global $phpbb_container;
$error = array();
@@ -1576,7 +1571,9 @@ class parse_message extends bbcode_firstpass
{
if ($num_attachments < $cfg['max_attachments'] || $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id))
{
- $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $filedata = $attachment_manager->upload($form_name, $forum_id, false, '', $is_message);
$error = $filedata['error'];
if ($filedata['post_attach'] && !sizeof($error))
@@ -1646,6 +1643,9 @@ class parse_message extends bbcode_firstpass
if ($index !== false && !empty($this->attachment_data[$index]))
{
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+
// delete selected attachment
if ($this->attachment_data[$index]['is_orphan'])
{
@@ -1660,11 +1660,11 @@ class parse_message extends bbcode_firstpass
if ($row)
{
- phpbb_unlink($row['physical_filename'], 'file');
+ $attachment_manager->unlink($row['physical_filename'], 'file');
if ($row['thumbnail'])
{
- phpbb_unlink($row['physical_filename'], 'thumbnail');
+ $attachment_manager->unlink($row['physical_filename'], 'thumbnail');
}
$db->sql_query('DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id']);
@@ -1672,7 +1672,7 @@ class parse_message extends bbcode_firstpass
}
else
{
- delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id'])));
+ $attachment_manager->delete('attach', $this->attachment_data[$index]['attach_id']);
}
unset($this->attachment_data[$index]);
@@ -1692,7 +1692,9 @@ 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->mimetype_guesser, $this->plupload);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $filedata = $attachment_manager->upload($form_name, $forum_id, false, '', $is_message);
$error = array_merge($error, $filedata['error']);
if (!sizeof($error))
@@ -1981,18 +1983,6 @@ class parse_message extends bbcode_firstpass
}
/**
- * 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;
- }
-
- /**
* Function to perform custom bbcode validation by extensions
* can be used in bbcode_init() to assign regexp replacement
* Example: 'regexp' => array('#\[b\](.*?)\[/b\]#uise' => "\$this->validate_bbcode_by_extension('\$1')")
diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php
index 639f308091..b8cb3c4100 100644
--- a/phpBB/includes/ucp/ucp_attachments.php
+++ b/phpBB/includes/ucp/ucp_attachments.php
@@ -70,12 +70,10 @@ class ucp_attachments
if (confirm_box(true))
{
- if (!function_exists('delete_attachments'))
- {
- include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
- }
-
- delete_attachments('attach', $delete_ids);
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $attachment_manager->delete('attach', $delete_ids);
+ unset($attachment_manager);
meta_refresh(3, $this->u_action);
$message = ((sizeof($delete_ids) == 1) ? $user->lang['ATTACHMENT_DELETED'] : $user->lang['ATTACHMENTS_DELETED']) . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php
index 5f24d05c8b..33dff97fe6 100644
--- a/phpBB/includes/ucp/ucp_pm.php
+++ b/phpBB/includes/ucp/ucp_pm.php
@@ -92,7 +92,7 @@ class ucp_pm
$user_folders = get_folder($user->data['user_id']);
- if (!$auth->acl_get('u_sendpm'))
+ if ($action != 'delete' && !$auth->acl_get('u_sendpm'))
{
// trigger_error('NO_AUTH_SEND_MESSAGE');
$template->assign_vars(array(
diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php
index 5c32a23ad6..024a9c332f 100644
--- a/phpBB/includes/ucp/ucp_pm_compose.php
+++ b/phpBB/includes/ucp/ucp_pm_compose.php
@@ -266,8 +266,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
*
* @event core.ucp_pm_compose_compose_pm_basic_info_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 msg_id topic_id in the page request
* @var int to_user_id The id of whom the message is to
* @var int to_group_id The id of the group whom the message is to
@@ -276,14 +274,11 @@ function compose_pm($id, $mode, $action, $user_folders = array())
* @var string action One of: post, reply, quote, forward, quotepost, edit, delete, smilies
* @var bool delete Whether the user is deleting the PM
* @var int reply_to_all Value of reply_to_all request variable.
- * @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-RC5
+ * @change 3.2.0-a1 Removed undefined variables
*/
$vars = array(
'sql',
- 'forum_list',
- 'visibility_const',
'msg_id',
'to_user_id',
'to_group_id',
@@ -292,8 +287,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
'action',
'delete',
'reply_to_all',
- 'limit_time_sql',
- 'sort_order_sql',
);
extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_compose_pm_basic_info_query_before', compact($vars)));
@@ -338,8 +331,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
* @var string sql The original SQL used in the query
* @var array post Associative array with the data of the quoted post
* @var array msg_id The post_id that was searched to get the message for quoting
- * @var int visibility_const Visibility of the quoted post (one of the possible ITEM_* constant values)
- * @var int topic_id Topic ID of the quoted post
* @var int to_user_id Users the message is sent to
* @var int to_group_id Groups the message is sent to
* @var bool submit Whether the user is sending the PM or not
@@ -348,13 +339,12 @@ function compose_pm($id, $mode, $action, $user_folders = array())
* @var bool delete If deleting message
* @var int reply_to_all Value of reply_to_all request variable.
* @since 3.1.0-RC5
+ * @change 3.2.0-a1 Removed undefined variables
*/
$vars = array(
'sql',
'post',
'msg_id',
- 'visibility_const',
- 'topic_id',
'to_user_id',
'to_group_id',
'submit',
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index 2f4d650ed0..f6e9acc8c4 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -195,37 +195,12 @@ class ucp_profile
if ($config['require_activation'] == USER_ACTIVATION_ADMIN)
{
- // Grab an array of user_id's with a_user permissions ... these users can activate a user
- $admin_ary = $auth->acl_get_list(false, 'a_user', false);
- $admin_ary = (!empty($admin_ary[0]['a_user'])) ? $admin_ary[0]['a_user'] : array();
-
- // Also include founders
- $where_sql = ' WHERE user_type = ' . USER_FOUNDER;
-
- if (sizeof($admin_ary))
- {
- $where_sql .= ' OR ' . $db->sql_in_set('user_id', $admin_ary);
- }
-
- $sql = 'SELECT user_id, username, user_email, user_lang, user_jabber, user_notify_type
- FROM ' . USERS_TABLE . ' ' .
- $where_sql;
- $result = $db->sql_query($sql);
-
- while ($row = $db->sql_fetchrow($result))
- {
- $messenger->template('admin_activate', $row['user_lang']);
- $messenger->set_addresses($row);
-
- $messenger->assign_vars(array(
- 'USERNAME' => htmlspecialchars_decode($data['username']),
- 'U_USER_DETAILS' => "$server_url/memberlist.$phpEx?mode=viewprofile&u={$user->data['user_id']}",
- 'U_ACTIVATE' => "$server_url/ucp.$phpEx?mode=activate&u={$user->data['user_id']}&k=$user_actkey")
- );
-
- $messenger->send($row['user_notify_type']);
- }
- $db->sql_freeresult($result);
+ $notifications_manager = $phpbb_container->get('notification_manager');
+ $notifications_manager->add_notifications('notification.type.admin_activate_user', array(
+ 'user_id' => $user->data['user_id'],
+ 'user_actkey' => $user_actkey,
+ 'user_regdate' => time(), // Notification time
+ ));
}
user_active_flip('deactivate', $user->data['user_id'], INACTIVE_PROFILE);
@@ -518,7 +493,20 @@ class ucp_profile
}
$bbcode_uid = $bbcode_bitfield = $bbcode_flags = '';
- $warn_msg = generate_text_for_storage($signature, $bbcode_uid, $bbcode_bitfield, $bbcode_flags, $enable_bbcode, $enable_urls, $enable_smilies);
+ $warn_msg = generate_text_for_storage(
+ $signature,
+ $bbcode_uid,
+ $bbcode_bitfield,
+ $bbcode_flags,
+ $enable_bbcode,
+ $enable_urls,
+ $enable_smilies,
+ $config['allow_sig_img'],
+ $config['allow_sig_flash'],
+ true,
+ $config['allow_sig_links'],
+ 'sig'
+ );
if (sizeof($warn_msg))
{
diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php
index 299467b5f3..a611a33125 100644
--- a/phpBB/install/database_update.php
+++ b/phpBB/install/database_update.php
@@ -111,6 +111,9 @@ $db = $phpbb_container->get('dbal.conn');
/* @var $phpbb_log \phpbb\log\log_interface */
$phpbb_log = $phpbb_container->get('log');
+/** @var \phpbb\language\language $language */
+$language = $phpbb_container->get('language');
+
// Grab global variables, re-cache if necessary
/* @var $config \phpbb\config\config */
$config = $phpbb_container->get('config');
@@ -188,7 +191,7 @@ $migrator = $phpbb_container->get('migrator');
/** @var \phpbb\filesystem\filesystem_interface $phpbb_filesystem */
$phpbb_filesystem = $phpbb_container->get('filesystem');
-$migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($user, new \phpbb\db\html_migrator_output_handler($user), $phpbb_root_path . 'store/migrations_' . time() . '.log', $phpbb_filesystem));
+$migrator->set_output_handler(new \phpbb\db\output_handler\log_wrapper_migrator_output_handler($language, new \phpbb\db\output_handler\html_migrator_output_handler($language), $phpbb_root_path . 'store/migrations_' . time() . '.log', $phpbb_filesystem));
$migrator->create_migrations_table();
diff --git a/phpBB/install/index.php b/phpBB/install/index.php
index 6320b14947..a578e664cd 100644
--- a/phpBB/install/index.php
+++ b/phpBB/install/index.php
@@ -243,6 +243,8 @@ $sub = $request->variable('sub', '');
set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler');
$lang_service = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
+$lang_service->add_lang($load_lang_files);
+$lang_service->set_user_language($language);
$user = new \phpbb\user($lang_service, '\phpbb\datetime');
$auth = new \phpbb\auth\auth();
@@ -303,6 +305,11 @@ $template = new \phpbb\template\twig\twig(
array($phpbb_container->get('template.twig.extensions.phpbb'))
);
+/** @var \phpbb\language\language $lang_service */
+$lang_service = $phpbb_container->get('language');
+$lang_service->add_lang($load_lang_files);
+$lang_service->set_user_language($language);
+
$paths = array($phpbb_root_path . 'install/update/new/adm/style', $phpbb_admin_path . 'style');
$paths = array_filter($paths, 'is_dir');
$template->set_custom_style(array(
diff --git a/phpBB/install/install_update.php b/phpBB/install/install_update.php
index d9ba2e7fe9..2f8fd71c54 100644
--- a/phpBB/install/install_update.php
+++ b/phpBB/install/install_update.php
@@ -1115,7 +1115,7 @@ class install_update extends module
*/
function show_diff(&$update_list)
{
- global $phpbb_root_path, $template, $user, $request, $phpbb_adm_relative_path;
+ global $phpbb_root_path, $template, $user, $request;
$this->tpl_name = 'install_update_diff';
@@ -1669,10 +1669,9 @@ class install_update extends module
*/
function get_file($mode)
{
- global $user, $db;
+ global $user;
$errstr = '';
- $errno = 0;
switch ($mode)
{
diff --git a/phpBB/install_new/app.php b/phpBB/install_new/app.php
index b173f40dfc..b2de72dcbc 100644
--- a/phpBB/install_new/app.php
+++ b/phpBB/install_new/app.php
@@ -20,44 +20,21 @@ define('PHPBB_ENVIRONMENT', 'production');
$phpbb_root_path = '../';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
-//
-// Let's do the common.php logic
-//
-require($phpbb_root_path . 'includes/startup.' . $phpEx);
-require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx);
+$startup_new_path = $phpbb_root_path . 'install/update/update/new/install_new/startup.' . $phpEx;
+$startup_path = (file_exists($startup_new_path)) ? $startup_new_path : $phpbb_root_path . 'install_new/startup.' . $phpEx;
+require($startup_path);
-$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx);
-$phpbb_class_loader->register();
-
-// In case $phpbb_adm_relative_path is not set (in case of an update), use the default.
-$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/';
-$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path;
-
-// Include files
-require($phpbb_root_path . 'includes/functions.' . $phpEx);
-require($phpbb_root_path . 'includes/functions_content.' . $phpEx);
-include($phpbb_root_path . 'includes/functions_compatibility.' . $phpEx);
-require($phpbb_root_path . 'includes/functions_user.' . $phpEx);
-require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);
+/** @var \phpbb\filesystem\filesystem $phpbb_filesystem */
+$phpbb_filesystem = $phpbb_installer_container->get('filesystem');
-// Set PHP error handler to ours
-set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler');
+/** @var \phpbb\template\template $template */
+$template = $phpbb_installer_container->get('template');
-$phpbb_installer_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx);
-$phpbb_installer_container = $phpbb_installer_container_builder
- ->with_environment('installer')
- ->without_extensions()
- ->get_container();
// Path to templates
$paths = array($phpbb_root_path . 'install/update/new/adm/style', $phpbb_admin_path . 'style');
$paths = array_filter($paths, 'is_dir');
-/** @var \phpbb\filesystem\filesystem $phpbb_filesystem */
-$phpbb_filesystem = $phpbb_installer_container->get('filesystem');
-
-/** @var \phpbb\template\template $template */
-$template = $phpbb_installer_container->get('template');
$template->set_custom_style(array(
array(
'name' => 'adm',
@@ -65,6 +42,9 @@ $template->set_custom_style(array(
),
), $paths);
+/* @var $phpbb_dispatcher \phpbb\event\dispatcher */
+$phpbb_dispatcher = $phpbb_installer_container->get('dispatcher');
+
/** @var \phpbb\language\language $language */
$language = $phpbb_installer_container->get('language');
$language->add_lang(array('common', 'acp/common', 'acp/board', 'install_new', 'posting'));
diff --git a/phpBB/install_new/phpbbcli.php b/phpBB/install_new/phpbbcli.php
index c1e9a9eaef..49a2920900 100644
--- a/phpBB/install_new/phpbbcli.php
+++ b/phpBB/install_new/phpbbcli.php
@@ -27,32 +27,9 @@ $phpEx = substr(strrchr(__FILE__, '.'), 1);
//
// Let's do the common.php logic
//
-require($phpbb_root_path . 'includes/startup.' . $phpEx);
-require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx);
-
-$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx);
-$phpbb_class_loader->register();
-
-// In case $phpbb_adm_relative_path is not set (in case of an update), use the default.
-$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/';
-$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path;
-
-// Include files
-require($phpbb_root_path . 'includes/functions.' . $phpEx);
-require($phpbb_root_path . 'includes/functions_content.' . $phpEx);
-include($phpbb_root_path . 'includes/functions_compatibility.' . $phpEx);
-require($phpbb_root_path . 'includes/functions_user.' . $phpEx);
-require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);
-
-// Set PHP error handler to ours
-set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler');
-
-$phpbb_installer_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx);
-$phpbb_installer_container = $phpbb_installer_container_builder
- ->with_environment('installer')
- ->without_extensions()
- ->without_cache()
- ->get_container();
+$startup_new_path = $phpbb_root_path . 'install/update/update/new/install_new/startup.' . $phpEx;
+$startup_path = (file_exists($startup_new_path)) ? $startup_new_path : $phpbb_root_path . 'install_new/startup.' . $phpEx;
+require($startup_path);
/** @var \phpbb\filesystem\filesystem $phpbb_filesystem */
$phpbb_filesystem = $phpbb_installer_container->get('filesystem');
diff --git a/phpBB/install_new/startup.php b/phpBB/install_new/startup.php
new file mode 100644
index 0000000000..766f6be38a
--- /dev/null
+++ b/phpBB/install_new/startup.php
@@ -0,0 +1,84 @@
+<?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.
+ *
+ */
+
+/** @ignore */
+if (!defined('IN_PHPBB') || !defined('IN_INSTALL'))
+{
+ exit;
+}
+
+function phpbb_require_updated($path, $phpbb_root_path, $optional = false)
+{
+ $new_path = $phpbb_root_path . 'install/update/new/' . $path;
+ $old_path = $phpbb_root_path . $path;
+
+ if (file_exists($new_path))
+ {
+ require($new_path);
+ }
+ else if (!$optional || file_exists($old_path))
+ {
+ require($old_path);
+ }
+}
+
+function phpbb_include_updated($path, $phpbb_root_path, $optional = false)
+{
+ $new_path = $phpbb_root_path . 'install/update/new/' . $path;
+ $old_path = $phpbb_root_path . $path;
+
+ if (file_exists($new_path))
+ {
+ include($new_path);
+ }
+ else if (!$optional || file_exists($old_path))
+ {
+ include($old_path);
+ }
+}
+
+phpbb_require_updated('includes/startup.' . $phpEx, $phpbb_root_path);
+phpbb_require_updated('phpbb/class_loader.' . $phpEx, $phpbb_root_path);
+
+$phpbb_class_loader_new = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}install/update/new/phpbb/", $phpEx);
+$phpbb_class_loader_new->register();
+$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx);
+$phpbb_class_loader->register();
+$phpbb_class_loader_ext = new \phpbb\class_loader('\\', "{$phpbb_root_path}ext/", $phpEx);
+$phpbb_class_loader_ext->register();
+
+// In case $phpbb_adm_relative_path is not set (in case of an update), use the default.
+$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/';
+$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path;
+
+// Include files
+phpbb_require_updated('includes/functions.' . $phpEx, $phpbb_root_path);
+phpbb_require_updated('includes/functions_content.' . $phpEx, $phpbb_root_path);
+phpbb_include_updated('includes/functions_compatibility.' . $phpEx, $phpbb_root_path);
+phpbb_require_updated('includes/functions_user.' . $phpEx, $phpbb_root_path);
+phpbb_require_updated('includes/utf/utf_tools.' . $phpEx, $phpbb_root_path);
+
+// Set PHP error handler to ours
+set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler');
+
+$phpbb_installer_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx);
+$phpbb_installer_container_builder
+ ->with_environment('installer')
+ ->without_extensions();
+
+$other_config_path = $phpbb_root_path . 'install/update/new/config';
+$config_path = (file_exists($other_config_path . '/installer/config.yml')) ? $other_config_path : $phpbb_root_path . 'config';
+
+$phpbb_installer_container = $phpbb_installer_container_builder
+ ->with_config_path($config_path)
+ ->get_container();
diff --git a/phpBB/language/en/captcha_recaptcha.php b/phpBB/language/en/captcha_recaptcha.php
index df2ad4e51b..0acf850043 100644
--- a/phpBB/language/en/captcha_recaptcha.php
+++ b/phpBB/language/en/captcha_recaptcha.php
@@ -40,13 +40,13 @@ $lang = array_merge($lang, array(
'RECAPTCHA_LANG' => 'en',
'RECAPTCHA_NOT_AVAILABLE' => 'In order to use reCaptcha, you must create an account on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.',
'CAPTCHA_RECAPTCHA' => 'reCaptcha',
- 'RECAPTCHA_INCORRECT' => 'The visual confirmation code you submitted was incorrect',
+ 'RECAPTCHA_INCORRECT' => 'The solution you provided was incorrect',
+ 'RECAPTCHA_NOSCRIPT' => 'Please enable JavaScript in your browser to load the challenge.',
'RECAPTCHA_PUBLIC' => 'Public reCaptcha key',
'RECAPTCHA_PUBLIC_EXPLAIN' => 'Your public reCaptcha key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.',
'RECAPTCHA_PRIVATE' => 'Private reCaptcha key',
'RECAPTCHA_PRIVATE_EXPLAIN' => 'Your private reCaptcha key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.',
- 'RECAPTCHA_EXPLAIN' => 'In an effort to prevent automatic submissions, we require that you type the text displayed into the field underneath.',
- 'RECAPTCHA_SOCKET_ERROR' => 'There was a problem connecting to the RECAPTCHA service: could not open socket. Try again later.',
+ 'RECAPTCHA_EXPLAIN' => 'In an effort to prevent automatic submissions, we require that you complete the following challenge.',
));
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index a0dda19df9..f6b9bce58b 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -333,6 +333,7 @@ $lang = array_merge($lang, array(
'IMAGE_FILETYPE_INVALID' => 'Image file type %d for mimetype %s not supported.',
'IMAGE_FILETYPE_MISMATCH' => 'Image file type mismatch: expected extension %1$s but extension %2$s given.',
'IN' => 'in',
+ 'INACTIVE' => 'Inactive',
'INDEX' => 'Index page',
'INFORMATION' => 'Information',
'INSECURE_REDIRECT' => 'Tried to redirect to potentially insecure url.',
@@ -472,7 +473,7 @@ $lang = array_merge($lang, array(
'NOTIFICATION_TOPIC_DISAPPROVED' => '<strong>Topic disapproved</strong>:',
'NOTIFICATION_TOPIC_IN_QUEUE' => '<strong>Topic approval</strong> request by %1$s:',
'NOTIFICATION_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.',
- 'NOTIFICATION_ADMIN_ACTIVATE_USER' => '<strong>Activation required</strong> for newly registered user: “%1$s”',
+ 'NOTIFICATION_ADMIN_ACTIVATE_USER' => '<strong>Activation required</strong> for deactivated or newly registered user: “%1$s”',
// Used in conjuction with NOTIFICATION_BOOKMARK and NOTIFICATION_POST.
'NOTIFICATION_MANY_OTHERS' => 'others',
'NOTIFICATION_X_OTHERS' => array(
diff --git a/phpBB/language/en/install_new.php b/phpBB/language/en/install_new.php
index 5b3942c125..db7e96829d 100644
--- a/phpBB/language/en/install_new.php
+++ b/phpBB/language/en/install_new.php
@@ -292,10 +292,10 @@ $lang = array_merge($lang, array(
// Installer's general messages
$lang = array_merge($lang, array(
'MODULE_NOT_FOUND' => 'Module not found',
- 'MODULE_NOT_FOUND_DESCRIPTION' => 'No module is found under the service definition “%s” is not defined.',
+ 'MODULE_NOT_FOUND_DESCRIPTION' => 'A module could not be found because the service, %s, is undefined.',
'TASK_NOT_FOUND' => 'Task not found',
- 'TASK_NOT_FOUND_DESCRIPTION' => 'No task is found under the service definition “%s” is not defined.',
+ 'TASK_NOT_FOUND_DESCRIPTION' => 'A task could not be found because the service, %s, is undefined.',
'SKIP_MODULE' => 'Skip “%s” module',
'SKIP_TASK' => 'Skip “%s” task',
@@ -308,8 +308,104 @@ $lang = array_merge($lang, array(
// CLI messages
$lang = array_merge($lang, array(
- 'CLI_INSTALL_BOARD' => 'Install phpBB',
+ 'CLI_INSTALL_BOARD' => 'Install phpBB',
'CLI_INSTALL_SHOW_CONFIG' => 'Show the configuration which will be used',
'CLI_INSTALL_VALIDATE_CONFIG' => 'Validate a configuration file',
'CLI_CONFIG_FILE' => 'Config file to use',
));
+
+// Common updater messages
+$lang = array_merge($lang, array(
+ 'UPDATE_INSTALLATION' => 'Update phpBB installation',
+ 'UPDATE_INSTALLATION_EXPLAIN' => 'With this option, it is possible to update your phpBB installation to the latest version.<br />During the process all of your files will be checked for their integrity. You are able to review all differences and files before the update.<br /><br />The file update itself can be done in two different ways.</p><h2>Manual Update</h2><p>With this update you only download your personal set of changed files to make sure you do not lose your file modifications you may have done. After you downloaded this package you need to manually upload the files to their correct position under your phpBB root directory. Once done, you are able to do the file check stage again to see if you moved the files to their correct location.</p><h2>Automatic Update with FTP</h2><p>This method is similar to the first one but without the need to download the changed files and uploading them on your own. This will be done for you. In order to use this method you need to know your FTP login details since you will be asked for them. Once finished you will be redirected to the file check again to make sure everything got updated correctly.<br /><br />',
+));
+
+// Updater forms
+$lang = array_merge($lang, array(
+ // Updater types
+ 'UPDATE_TYPE' => 'Type of update to run',
+
+ 'UPDATE_TYPE_ALL' => 'Update filesystem and database',
+ 'UPDATE_TYPE_DB_ONLY' => 'Update database only',
+
+ // File updater methods
+ 'UPDATE_FILE_METHOD_TITLE' => 'File updater methods',
+
+ 'UPDATE_FILE_METHOD' => 'File updater method',
+ 'UPDATE_FILE_METHOD_DOWNLOAD' => 'Download modified files in an archive',
+ 'UPDATE_FILE_METHOD_FTP' => 'Update files via FTP (Automatic)',
+ 'UPDATE_FILE_METHOD_FILESYSTEM' => 'Update files via direct file access (Automatic)',
+
+ // File updater archives
+ 'SELECT_DOWNLOAD_FORMAT' => 'Select download archive format',
+
+ // FTP settings
+ 'FTP_SETTINGS' => 'FTP settings',
+));
+
+// Requirements messages
+$lang = array_merge($lang, array(
+ 'UPDATE_FILES_NOT_FOUND' => 'No valid update directory was found, please make sure you uploaded the relevant files.',
+
+ 'NO_UPDATE_FILES_UP_TO_DATE' => 'Your version is up to date. There is no need to run the update tool. If you want to make an integrity check on your files make sure you uploaded the correct update files.',
+ 'OLD_UPDATE_FILES' => 'Update files are out of date. The update files found are for updating from phpBB %1$s to phpBB %2$s but the latest version of phpBB is %3$s.',
+ 'INCOMPATIBLE_UPDATE_FILES' => 'The update files found are incompatible with your installed version. Your installed version is %1$s and the update file is for updating phpBB %2$s to %3$s.',
+));
+
+// Update files
+$lang = array_merge($lang, array(
+ 'STAGE_UPDATE_FILES' => 'Update files',
+
+ // Check files
+ 'UPDATE_CHECK_FILES' => 'Check files to update',
+
+ // Update file differ
+ 'FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ' => 'The file differ failed to open %s.',
+
+ 'UPDATE_FILE_DIFF' => 'Diffing changed files',
+ 'ALL_FILES_DIFFED' => 'All modified files has been diffed.',
+
+ // File status
+ 'UPDATE_CONTINUE_FILE_UPDATE' => 'Update files',
+
+ 'DOWNLOAD' => 'Download',
+ 'DOWNLOAD_CONFLICTS' => 'Download merge conflicts archive',
+ 'DOWNLOAD_CONFLICTS_EXPLAIN' => 'Search for &lt;&lt;&lt; to spot conflicts',
+ 'DOWNLOAD_UPDATE_METHOD' => 'Download modified files archive',
+ 'DOWNLOAD_UPDATE_METHOD_EXPLAIN' => 'Once downloaded you should unpack the archive. You will find the modified files you need to upload to your phpBB root directory within it. Please upload the files to their respective locations then. After you have uploaded all files, you may continue with the update process.',
+
+ 'FILE_ALREADY_UP_TO_DATE' => 'File is already up to date.',
+ 'FILE_DIFF_NOT_ALLOWED' => 'File not allowed to be diffed.',
+ 'FILE_USED' => 'Information used from', // Single file
+ 'FILES_CONFLICT' => 'Conflict files',
+ 'FILES_CONFLICT_EXPLAIN' => 'The following files are modified and do not represent the original files from the old version. phpBB determined that these files create conflicts if they are tried to be merged. Please investigate the conflicts and try to manually resolve them or continue the update choosing the preferred merging method. If you resolve the conflicts manually check the files again after you modified them. You are also able to choose between the preferred merge method for every file. The first one will result in a file where the conflicting lines from your old file will be lost, the other one will result in losing the changes from the newer file.',
+ 'FILES_DELETED' => 'Deleted files',
+ 'FILES_DELETED_EXPLAIN' => 'The following files do not exist in the new version. These files have to be deleted from your installation.',
+ 'FILES_MODIFIED' => 'Modified files',
+ 'FILES_MODIFIED_EXPLAIN' => 'The following files are modified and do not represent the original files from the old version. The updated file will be a merge between your modifications and the new file.',
+ 'FILES_NEW' => 'New files',
+ 'FILES_NEW_EXPLAIN' => 'The following files currently do not exist within your installation. These files will be added to your installation.',
+ 'FILES_NEW_CONFLICT' => 'New conflicting files',
+ 'FILES_NEW_CONFLICT_EXPLAIN' => 'The following files are new within the latest version but it has been determined that there is already a file with the same name within the same position. This file will be overwritten by the new file.',
+ 'FILES_NOT_MODIFIED' => 'Not modified files',
+ 'FILES_NOT_MODIFIED_EXPLAIN' => 'The following files are not modified and represent the original phpBB files from the version you want to update from.',
+ 'FILES_UP_TO_DATE' => 'Already updated files',
+ 'FILES_UP_TO_DATE_EXPLAIN' => 'The following files are already up to date and do not need to be updated.',
+ 'TOGGLE_DISPLAY' => 'View/Hide file list',
+
+ // File updater
+ 'UPDATE_UPDATING_FILES' => 'Updating files',
+
+ 'UPDATE_FILE_UPDATER_HAS_FAILED' => 'File updater “%1$s“ has failed. The installer will try to fallback to “%2$s“.',
+ 'UPDATE_FILE_UPDATERS_HAVE_FAILED' => 'The file updater failed. No further fallback methods are available.',
+
+ 'UPDATE_CONTINUE_UPDATE_PROCESS' => 'Continue update process',
+ 'UPDATE_RECHECK_UPDATE_FILES' => 'Check files again',
+));
+
+// Update database
+$lang = array_merge($lang, array(
+ 'STAGE_UPDATE_DATABASE' => 'Update database',
+
+ 'INLINE_UPDATE_SUCCESSFUL' => 'The database update was successful.',
+));
diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php
index b346051108..6063f71d98 100644
--- a/phpBB/language/en/ucp.php
+++ b/phpBB/language/en/ucp.php
@@ -340,7 +340,7 @@ $lang = array_merge($lang, array(
'NOTIFICATION_TYPE_QUOTE' => 'Someone quotes you in a post',
'NOTIFICATION_TYPE_REPORT' => 'Someone reports a post',
'NOTIFICATION_TYPE_TOPIC' => 'Someone creates a topic in a forum to which you are subscribed',
- 'NOTIFICATION_TYPE_ADMIN_ACTIVATE_USER' => 'Newly registered user requiring activation',
+ 'NOTIFICATION_TYPE_ADMIN_ACTIVATE_USER' => 'User requiring activation',
'NOTIFY_METHOD' => 'Notification method',
'NOTIFY_METHOD_BOTH' => 'Both',
diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php
index b167e0e7dc..c4865ab3c2 100644
--- a/phpBB/memberlist.php
+++ b/phpBB/memberlist.php
@@ -154,7 +154,7 @@ switch ($mode)
$db->sql_freeresult($result);
$sql_ary = array(
- 'SELECT' => 'u.user_id, u.group_id as default_group, u.username, u.username_clean, u.user_colour, u.user_rank, u.user_posts, u.user_allow_pm, g.group_id',
+ 'SELECT' => 'u.user_id, u.group_id as default_group, u.username, u.username_clean, u.user_colour, u.user_type, u.user_rank, u.user_posts, u.user_allow_pm, g.group_id',
'FROM' => array(
USER_GROUP_TABLE => 'ug',
@@ -317,6 +317,8 @@ switch ($mode)
'RANK_IMG' => $user_rank_data['img'],
'RANK_IMG_SRC' => $user_rank_data['img_src'],
+ 'S_INACTIVE' => $row['user_type'] == USER_INACTIVE,
+
'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($row['user_allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;u=' . $row['user_id']) : '',
'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
@@ -1390,13 +1392,19 @@ switch ($mode)
);
}
+ $user_types = array(USER_NORMAL, USER_FOUNDER);
+ if ($auth->acl_get('a_user'))
+ {
+ $user_types[] = USER_INACTIVE;
+ }
+
$start = $pagination->validate_start($start, $config['topics_per_page'], $config['num_users']);
// Get us some users :D
$sql = "SELECT u.user_id
FROM " . USERS_TABLE . " u
$sql_from
- WHERE u.user_type IN (" . USER_NORMAL . ', ' . USER_FOUNDER . ")
+ WHERE " . $db->sql_in_set('u.user_type', $user_types) . "
$sql_where
ORDER BY $order_by";
$result = $db->sql_query_limit($sql, $config['topics_per_page'], $start);
@@ -1494,6 +1502,20 @@ switch ($mode)
usort($user_list, 'phpbb_sort_last_active');
}
+ // do we need to display contact fields as such
+ $use_contact_fields = false;
+
+ /**
+ * Modify list of users before member row is created
+ *
+ * @event core.memberlist_memberrow_before
+ * @var array user_list Array containing list of users
+ * @var bool use_contact_fields Should we display contact fields as such?
+ * @since 3.1.7-RC1
+ */
+ $vars = array('user_list', 'use_contact_fields');
+ extract($phpbb_dispatcher->trigger_event('core.memberlist_memberrow_before', compact($vars)));
+
for ($i = 0, $end = sizeof($user_list); $i < $end; ++$i)
{
$user_id = $user_list[$i];
@@ -1504,7 +1526,7 @@ switch ($mode)
$cp_row = array();
if ($config['load_cpf_memberlist'])
{
- $cp_row = (isset($profile_fields_cache[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields_cache[$user_id], false) : array();
+ $cp_row = (isset($profile_fields_cache[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields_cache[$user_id], $use_contact_fields) : array();
}
$memberrow = array_merge(phpbb_show_profile($row, false, false, false), array(
@@ -1512,6 +1534,7 @@ switch ($mode)
'S_CUSTOM_PROFILE' => (isset($cp_row['row']) && sizeof($cp_row['row'])) ? true : false,
'S_GROUP_LEADER' => $is_leader,
+ 'S_INACTIVE' => $row['user_type'] == USER_INACTIVE,
'U_VIEW_PROFILE' => get_username_string('profile', $user_id, $row['username']),
));
diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php
new file mode 100644
index 0000000000..e093da8865
--- /dev/null
+++ b/phpBB/phpbb/attachment/delete.php
@@ -0,0 +1,432 @@
+<?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\attachment;
+
+use \phpbb\config\config;
+use \phpbb\db\driver\driver_interface;
+use \phpbb\event\dispatcher;
+use \phpbb\filesystem\filesystem;
+
+/**
+ * Attachment delete class
+ */
+class delete
+{
+ /** @var config */
+ protected $config;
+
+ /** @var driver_interface */
+ protected $db;
+
+ /** @var \phpbb\event\dispatcher */
+ protected $dispatcher;
+
+ /** @var filesystem */
+ protected $filesystem;
+
+ /** @var resync */
+ protected $resync;
+
+ /** @var string phpBB root path */
+ protected $phpbb_root_path;
+
+ /** @var array Attachement IDs */
+ protected $ids;
+
+ /** @var string SQL ID string */
+ private $sql_id;
+
+ /** @var string SQL where string */
+ private $sql_where = '';
+
+ /** @var int Number of deleted items */
+ private $num_deleted;
+
+ /** @var array Post IDs */
+ private $post_ids = array();
+
+ /** @var array Message IDs */
+ private $message_ids = array();
+
+ /** @var array Topic IDs */
+ private $topic_ids = array();
+
+ /** @var array Info of physical file */
+ private $physical = array();
+
+ /**
+ * Attachment delete class constructor
+ *
+ * @param config $config
+ * @param driver_interface $db
+ * @param dispatcher $dispatcher
+ * @param filesystem $filesystem
+ * @param resync $resync
+ * @param string $phpbb_root_path
+ */
+ public function __construct(config $config, driver_interface $db, dispatcher $dispatcher, filesystem $filesystem, resync $resync, $phpbb_root_path)
+ {
+ $this->config = $config;
+ $this->db = $db;
+ $this->dispatcher = $dispatcher;
+ $this->filesystem = $filesystem;
+ $this->resync = $resync;
+ $this->phpbb_root_path = $phpbb_root_path;
+ }
+
+ /**
+ * Delete Attachments
+ *
+ * @param string $mode can be: post|message|topic|attach|user
+ * @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids
+ * @param bool $resync set this to false if you are deleting posts or topics
+ *
+ * @return int|bool Number of deleted attachments or false if something
+ * went wrong during attachment deletion
+ */
+ public function delete($mode, $ids, $resync = true)
+ {
+ if (!$this->set_attachment_ids($ids))
+ {
+ return false;
+ }
+
+ $this->set_sql_constraints($mode);
+
+ /**
+ * Perform additional actions before collecting data for attachment(s) deletion
+ *
+ * @event core.delete_attachments_collect_data_before
+ * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
+ * @var mixed ids Array or comma separated list of ids corresponding to the mode
+ * @var bool resync Flag indicating if posts/messages/topics should be synchronized
+ * @var string sql_id The field name to collect/delete data for depending on the mode
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'ids',
+ 'resync',
+ 'sql_id',
+ );
+ extract($this->dispatcher->trigger_event('core.delete_attachments_collect_data_before', compact($vars)));
+
+ // Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled)
+ $this->collect_attachment_info($resync);
+
+ // Delete attachments from database
+ $this->delete_attachments_from_db();
+
+ /**
+ * Perform additional actions after attachment(s) deletion from the database
+ *
+ * @event core.delete_attachments_from_database_after
+ * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
+ * @var mixed ids Array or comma separated list of ids corresponding to the mode
+ * @var bool resync Flag indicating if posts/messages/topics should be synchronized
+ * @var string sql_id The field name to collect/delete data for depending on the mode
+ * @var array post_ids Array with post ids for deleted attachment(s)
+ * @var array topic_ids Array with topic ids for deleted attachment(s)
+ * @var array message_ids Array with private message ids for deleted attachment(s)
+ * @var array physical Array with deleted attachment(s) physical file(s) data
+ * @var int num_deleted The number of deleted attachment(s) from the database
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'ids',
+ 'resync',
+ 'sql_id',
+ 'post_ids',
+ 'topic_ids',
+ 'message_ids',
+ 'physical',
+ 'num_deleted',
+ );
+ extract($this->dispatcher->trigger_event('core.delete_attachments_from_database_after', compact($vars)));
+
+ if (!$this->num_deleted)
+ {
+ return 0;
+ }
+
+ // Delete attachments from filesystem
+ $this->remove_from_filesystem();
+
+ // If we do not resync, we do not need to adjust any message, post, topic or user entries
+ if (!$resync)
+ {
+ return $this->num_deleted;
+ }
+
+ // No more use for the original ids
+ unset($ids);
+
+ // Update post indicators for posts now no longer having attachments
+ $this->resync->resync('post', $this->post_ids);
+
+ // Update message table if messages are affected
+ $this->resync->resync('message', $this->message_ids);
+
+ // Now update the topics. This is a bit trickier, because there could be posts still having attachments within the topic
+ $this->resync->resync('topic', $this->topic_ids);
+
+ return $this->num_deleted;
+ }
+
+ /**
+ * Set attachment IDs
+ *
+ * @param mixed $ids ID or array of IDs
+ *
+ * @return bool True if attachment IDs were set, false if not
+ */
+ protected function set_attachment_ids($ids)
+ {
+ // 0 is as bad as an empty array
+ if (empty($ids))
+ {
+ return false;
+ }
+
+ if (is_array($ids))
+ {
+ $ids = array_unique($ids);
+ $this->ids = array_map('intval', $ids);
+ }
+ else
+ {
+ $this->ids = array((int) $ids);
+ }
+
+ return true;
+ }
+
+ /**
+ * Set SQL constraints based on mode
+ *
+ * @param string $mode Delete mode; can be: post|message|topic|attach|user
+ */
+ private function set_sql_constraints($mode)
+ {
+ switch ($mode)
+ {
+ case 'post':
+ case 'message':
+ $this->sql_id = 'post_msg_id';
+ $this->sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0);
+ break;
+
+ case 'topic':
+ $this->sql_id = 'topic_id';
+ break;
+
+ case 'user':
+ $this->sql_id = 'poster_id';
+ break;
+
+ case 'attach':
+ default:
+ $this->sql_id = 'attach_id';
+ break;
+ }
+ }
+
+ /**
+ * Collect info about attachment IDs
+ *
+ * @param bool $resync Whether topics/posts should be resynced after delete
+ */
+ protected function collect_attachment_info($resync)
+ {
+ // Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled)
+ $sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan
+ FROM ' . ATTACHMENTS_TABLE . '
+ WHERE ' . $this->db->sql_in_set($this->sql_id, $this->ids);
+
+ $sql .= $this->sql_where;
+
+ $result = $this->db->sql_query($sql);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ // We only need to store post/message/topic ids if resync is enabled and the file is not orphaned
+ if ($resync && !$row['is_orphan'])
+ {
+ if (!$row['in_message'])
+ {
+ $this->post_ids[] = $row['post_msg_id'];
+ $this->topic_ids[] = $row['topic_id'];
+ }
+ else
+ {
+ $this->message_ids[] = $row['post_msg_id'];
+ }
+ }
+
+ $this->physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize'], 'is_orphan' => $row['is_orphan']);
+ }
+ $this->db->sql_freeresult($result);
+
+ // IDs should be unique
+ $this->post_ids = array_unique($this->post_ids);
+ $this->message_ids = array_unique($this->message_ids);
+ $this->topic_ids = array_unique($this->topic_ids);
+ }
+
+ /**
+ * Delete attachments from database table
+ */
+ protected function delete_attachments_from_db()
+ {
+ /**
+ * Perform additional actions before attachment(s) deletion
+ *
+ * @event core.delete_attachments_before
+ * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
+ * @var mixed ids Array or comma separated list of ids corresponding to the mode
+ * @var bool resync Flag indicating if posts/messages/topics should be synchronized
+ * @var string sql_id The field name to collect/delete data for depending on the mode
+ * @var array post_ids Array with post ids for deleted attachment(s)
+ * @var array topic_ids Array with topic ids for deleted attachment(s)
+ * @var array message_ids Array with private message ids for deleted attachment(s)
+ * @var array physical Array with deleted attachment(s) physical file(s) data
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'ids',
+ 'resync',
+ 'sql_id',
+ 'post_ids',
+ 'topic_ids',
+ 'message_ids',
+ 'physical',
+ );
+ extract($this->dispatcher->trigger_event('core.delete_attachments_before', compact($vars)));
+
+ // Delete attachments
+ $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . '
+ WHERE ' . $this->db->sql_in_set($this->sql_id, $this->ids);
+
+ $sql .= $this->sql_where;
+
+ $this->db->sql_query($sql);
+ $this->num_deleted = $this->db->sql_affectedrows();
+ }
+
+ /**
+ * Delete attachments from filesystem
+ */
+ protected function remove_from_filesystem()
+ {
+ $space_removed = $files_removed = 0;
+
+ foreach ($this->physical as $file_ary)
+ {
+ if ($this->unlink_attachment($file_ary['filename'], 'file', true) && !$file_ary['is_orphan'])
+ {
+ // Only non-orphaned files count to the file size
+ $space_removed += $file_ary['filesize'];
+ $files_removed++;
+ }
+
+ if ($file_ary['thumbnail'])
+ {
+ $this->unlink_attachment($file_ary['filename'], 'thumbnail', true);
+ }
+ }
+
+ /**
+ * Perform additional actions after attachment(s) deletion from the filesystem
+ *
+ * @event core.delete_attachments_from_filesystem_after
+ * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
+ * @var mixed ids Array or comma separated list of ids corresponding to the mode
+ * @var bool resync Flag indicating if posts/messages/topics should be synchronized
+ * @var string sql_id The field name to collect/delete data for depending on the mode
+ * @var array post_ids Array with post ids for deleted attachment(s)
+ * @var array topic_ids Array with topic ids for deleted attachment(s)
+ * @var array message_ids Array with private message ids for deleted attachment(s)
+ * @var array physical Array with deleted attachment(s) physical file(s) data
+ * @var int num_deleted The number of deleted attachment(s) from the database
+ * @var int space_removed The size of deleted files(s) from the filesystem
+ * @var int files_removed The number of deleted file(s) from the filesystem
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'ids',
+ 'resync',
+ 'sql_id',
+ 'post_ids',
+ 'topic_ids',
+ 'message_ids',
+ 'physical',
+ 'num_deleted',
+ 'space_removed',
+ 'files_removed',
+ );
+ extract($this->dispatcher->trigger_event('core.delete_attachments_from_filesystem_after', compact($vars)));
+
+ if ($space_removed || $files_removed)
+ {
+ $this->config->increment('upload_dir_size', $space_removed * (-1), false);
+ $this->config->increment('num_files', $files_removed * (-1), false);
+ }
+ }
+
+ /**
+ * Delete attachment from filesystem
+ *
+ * @param string $filename Filename of attachment
+ * @param string $mode Delete mode
+ * @param bool $entry_removed Whether entry was removed. Defaults to false
+ * @return bool True if file was removed, false if not
+ */
+ public function unlink_attachment($filename, $mode = 'file', $entry_removed = false)
+ {
+ // Because of copying topics or modifications a physical filename could be assigned more than once. If so, do not remove the file itself.
+ $sql = 'SELECT COUNT(attach_id) AS num_entries
+ FROM ' . ATTACHMENTS_TABLE . "
+ WHERE physical_filename = '" . $this->db->sql_escape(utf8_basename($filename)) . "'";
+ $result = $this->db->sql_query($sql);
+ $num_entries = (int) $this->db->sql_fetchfield('num_entries');
+ $this->db->sql_freeresult($result);
+
+ // Do not remove file if at least one additional entry with the same name exist.
+ if (($entry_removed && $num_entries > 0) || (!$entry_removed && $num_entries > 1))
+ {
+ return false;
+ }
+
+ $filename = ($mode == 'thumbnail') ? 'thumb_' . utf8_basename($filename) : utf8_basename($filename);
+ $filepath = $this->phpbb_root_path . $this->config['upload_path'] . '/' . $filename;
+
+ try
+ {
+ if ($this->filesystem->exists($filepath))
+ {
+ $this->filesystem->remove($this->phpbb_root_path . $this->config['upload_path'] . '/' . $filename);
+ return true;
+ }
+ }
+ catch (\phpbb\filesystem\exception\filesystem_exception $exception)
+ {
+ // Fail is covered by return statement below
+ }
+
+ return false;
+ }
+}
diff --git a/phpBB/phpbb/attachment/manager.php b/phpBB/phpbb/attachment/manager.php
new file mode 100644
index 0000000000..3c47171b2f
--- /dev/null
+++ b/phpBB/phpbb/attachment/manager.php
@@ -0,0 +1,99 @@
+<?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\attachment;
+
+/**
+ * Attachment manager
+ */
+class manager
+{
+ /** @var delete Attachment delete class */
+ protected $delete;
+
+ /** @var resync Attachment resync class */
+ protected $resync;
+
+ /** @var upload Attachment upload class */
+ protected $upload;
+
+ /**
+ * Constructor for attachment manager
+ *
+ * @param delete $delete Attachment delete class
+ * @param resync $resync Attachment resync class
+ * @param upload $upload Attachment upload class
+ */
+ public function __construct(delete $delete, resync $resync, upload $upload)
+ {
+ $this->delete = $delete;
+ $this->resync = $resync;
+ $this->upload = $upload;
+ }
+
+ /**
+ * Wrapper method for deleting attachments
+ *
+ * @param string $mode can be: post|message|topic|attach|user
+ * @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids
+ * @param bool $resync set this to false if you are deleting posts or topics
+ *
+ * @return int|bool Number of deleted attachments or false if something
+ * went wrong during attachment deletion
+ */
+ public function delete($mode, $ids, $resync = true)
+ {
+ return $this->delete->delete($mode, $ids, $resync);
+ }
+
+ /**
+ * Wrapper method for deleting attachments from filesystem
+ *
+ * @param string $filename Filename of attachment
+ * @param string $mode Delete mode
+ * @param bool $entry_removed Whether entry was removed. Defaults to false
+ * @return bool True if file was removed, false if not
+ */
+ public function unlink($filename, $mode = 'file', $entry_removed = false)
+ {
+ return $this->delete->unlink_attachment($filename, $mode, $entry_removed);
+ }
+
+ /**
+ * Wrapper method for resyncing specified type
+ *
+ * @param string $type Type of resync
+ * @param array $ids IDs to resync
+ */
+ public function resync($type, $ids)
+ {
+ $this->resync->resync($type, $ids);
+ }
+
+ /**
+ * Wrapper method for uploading attachment
+ *
+ * @param string $form_name The form name of the file upload input
+ * @param int $forum_id The id of the forum
+ * @param bool $local Whether the file is local or not
+ * @param string $local_storage The path to the local file
+ * @param bool $is_message Whether it is a PM or not
+ * @param array $local_filedata An file data object created for the local file
+ *
+ * @return array File data array
+ */
+ public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = [])
+ {
+ return $this->upload->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata);
+ }
+}
diff --git a/phpBB/phpbb/attachment/resync.php b/phpBB/phpbb/attachment/resync.php
new file mode 100644
index 0000000000..6c2e0a8b0d
--- /dev/null
+++ b/phpBB/phpbb/attachment/resync.php
@@ -0,0 +1,124 @@
+<?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\attachment;
+
+use \phpbb\db\driver\driver_interface;
+
+/**
+ * Attachment resync class
+ */
+class resync
+{
+ /** @var driver_interface */
+ protected $db;
+
+ /** @var string Attachment table SQL ID */
+ private $attach_sql_id;
+
+ /** @var string Resync table SQL ID */
+ private $resync_sql_id;
+
+ /** @var string Resync SQL table */
+ private $resync_table;
+
+ /** @var string SQL where statement */
+ private $sql_where;
+
+ /**
+ * Constructor for attachment resync class
+ *
+ * @param driver_interface $db Database driver
+ */
+ public function __construct(driver_interface $db)
+ {
+ $this->db = $db;
+ }
+
+ /**
+ * Set type constraints for attachment resync
+ *
+ * @param string $type Type of resync; can be: message|post|topic
+ */
+ protected function set_type_constraints($type)
+ {
+ switch ($type)
+ {
+ case 'message':
+ $this->attach_sql_id = 'post_msg_id';
+ $this->sql_where = ' AND in_message = 1
+ AND is_orphan = 0';
+ $this->resync_table = PRIVMSGS_TABLE;
+ $this->resync_sql_id = 'msg_id';
+ break;
+
+ case 'post':
+ $this->attach_sql_id = 'post_msg_id';
+ $this->sql_where = ' AND in_message = 0
+ AND is_orphan = 0';
+ $this->resync_table = POSTS_TABLE;
+ $this->resync_sql_id = 'post_id';
+ break;
+
+ case 'topic':
+ $this->attach_sql_id = 'topic_id';
+ $this->sql_where = ' AND is_orphan = 0';
+ $this->resync_table = TOPICS_TABLE;
+ $this->resync_sql_id = 'topic_id';
+ break;
+ }
+ }
+
+ /**
+ * Resync specified type
+ *
+ * @param string $type Type of resync
+ * @param array $ids IDs to resync
+ */
+ public function resync($type, $ids)
+ {
+ if (empty($type) || !is_array($ids) || !sizeof($ids) || !in_array($type, array('post', 'topic', 'message')))
+ {
+ return;
+ }
+
+ $this->set_type_constraints($type);
+
+ // Just check which elements are still having an assigned attachment
+ // not orphaned by querying the attachments table
+ $sql = 'SELECT ' . $this->attach_sql_id . '
+ FROM ' . ATTACHMENTS_TABLE . '
+ WHERE ' . $this->db->sql_in_set($this->attach_sql_id, $ids)
+ . $this->sql_where;
+ $result = $this->db->sql_query($sql);
+
+ $remaining_ids = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $remaining_ids[] = $row[$this->attach_sql_id];
+ }
+ $this->db->sql_freeresult($result);
+
+ // Now only unset those ids remaining
+ $ids = array_diff($ids, $remaining_ids);
+
+ if (sizeof($ids))
+ {
+ $sql = 'UPDATE ' . $this->resync_table . '
+ SET ' . $type . '_attachment = 0
+ WHERE ' . $this->db->sql_in_set($this->resync_sql_id, $ids);
+ $this->db->sql_query($sql);
+ }
+ }
+
+}
diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php
new file mode 100644
index 0000000000..957558768b
--- /dev/null
+++ b/phpBB/phpbb/attachment/upload.php
@@ -0,0 +1,334 @@
+<?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\attachment;
+
+use phpbb\auth\auth;
+use \phpbb\cache\service;
+use \phpbb\config\config;
+use \phpbb\event\dispatcher;
+use \phpbb\language\language;
+use \phpbb\mimetype\guesser;
+use \phpbb\plupload\plupload;
+use \phpbb\user;
+
+/**
+ * Attachment upload class
+ */
+class upload
+{
+ /** @var auth */
+ protected $auth;
+
+ /** @var service */
+ protected $cache;
+
+ /** @var config */
+ protected $config;
+
+ /** @var \phpbb\files\upload Upload class */
+ protected $files_upload;
+
+ /** @var \phpbb\language\language */
+ protected $language;
+
+ /** @var guesser Mimetype guesser */
+ protected $mimetype_guesser;
+
+ /** @var dispatcher */
+ protected $phpbb_dispatcher;
+
+ /** @var plupload Plupload */
+ protected $plupload;
+
+ /** @var user */
+ protected $user;
+
+ /** @var \phpbb\files\filespec Current filespec instance */
+ private $file;
+
+ /** @var array File data */
+ private $file_data = array(
+ 'error' => array()
+ );
+
+ /** @var array Extensions array */
+ private $extensions;
+
+ /**
+ * Constructor for attachments upload class
+ *
+ * @param auth $auth
+ * @param service $cache
+ * @param config $config
+ * @param \phpbb\files\upload $files_upload
+ * @param language $language
+ * @param guesser $mimetype_guesser
+ * @param dispatcher $phpbb_dispatcher
+ * @param plupload $plupload
+ * @param user $user
+ * @param $phpbb_root_path
+ */
+ public function __construct(auth $auth, service $cache, config $config, \phpbb\files\upload $files_upload, language $language, guesser $mimetype_guesser, dispatcher $phpbb_dispatcher, plupload $plupload, user $user, $phpbb_root_path)
+ {
+ $this->auth = $auth;
+ $this->cache = $cache;
+ $this->config = $config;
+ $this->files_upload = $files_upload;
+ $this->language = $language;
+ $this->mimetype_guesser = $mimetype_guesser;
+ $this->phpbb_dispatcher = $phpbb_dispatcher;
+ $this->plupload = $plupload;
+ $this->user = $user;
+ $this->phpbb_root_path = $phpbb_root_path;
+ }
+
+ /**
+ * Upload Attachment - filedata is generated here
+ * Uses upload class
+ *
+ * @param string $form_name The form name of the file upload input
+ * @param int $forum_id The id of the forum
+ * @param bool $local Whether the file is local or not
+ * @param string $local_storage The path to the local file
+ * @param bool $is_message Whether it is a PM or not
+ * @param array $local_filedata An file data object created for the local file
+ *
+ * @return array File data array
+ */
+ public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = array())
+ {
+ $this->init_files_upload($forum_id, $is_message);
+
+ $this->file_data['post_attach'] = $local || $this->files_upload->is_valid($form_name);
+
+ if (!$this->file_data['post_attach'])
+ {
+ $this->file_data['error'][] = $this->language->lang('NO_UPLOAD_FORM_FOUND');
+ return $this->file_data;
+ }
+
+ $this->file = ($local) ? $this->files_upload->handle_upload('files.types.local', $local_storage, $local_filedata) : $this->files_upload->handle_upload('files.types.form', $form_name);
+
+ if ($this->file->init_error())
+ {
+ $this->file_data['post_attach'] = false;
+ return $this->file_data;
+ }
+
+ // Whether the uploaded file is in the image category
+ $is_image = (isset($this->extensions[$this->file->get('extension')]['display_cat'])) ? $this->extensions[$this->file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false;
+
+ if (!$this->auth->acl_get('a_') && !$this->auth->acl_get('m_', $forum_id))
+ {
+ // Check Image Size, if it is an image
+ if ($is_image)
+ {
+ $this->file->upload->set_allowed_dimensions(0, 0, $this->config['img_max_width'], $this->config['img_max_height']);
+ }
+
+ // Admins and mods are allowed to exceed the allowed filesize
+ if (!empty($this->extensions[$this->file->get('extension')]['max_filesize']))
+ {
+ $allowed_filesize = $this->extensions[$this->file->get('extension')]['max_filesize'];
+ }
+ else
+ {
+ $allowed_filesize = ($is_message) ? $this->config['max_filesize_pm'] : $this->config['max_filesize'];
+ }
+
+ $this->file->upload->set_max_filesize($allowed_filesize);
+ }
+
+ $this->file->clean_filename('unique', $this->user->data['user_id'] . '_');
+
+ // Are we uploading an image *and* this image being within the image category?
+ // Only then perform additional image checks.
+ $this->file->move_file($this->config['upload_path'], false, !$is_image);
+
+ // Do we have to create a thumbnail?
+ $this->file_data['thumbnail'] = ($is_image && $this->config['img_create_thumbnail']) ? 1 : 0;
+
+ // Make sure the image category only holds valid images...
+ $this->check_image($is_image);
+
+ if (sizeof($this->file->error))
+ {
+ $this->file->remove();
+ $this->file_data['error'] = array_merge($this->file_data['error'], $this->file->error);
+ $this->file_data['post_attach'] = false;
+
+ return $this->file_data;
+ }
+
+ $this->fill_file_data();
+
+ $filedata = $this->file_data;
+
+ /**
+ * Event to modify uploaded file before submit to the post
+ *
+ * @event core.modify_uploaded_file
+ * @var array filedata Array containing uploaded file data
+ * @var bool is_image Flag indicating if the file is an image
+ * @since 3.1.0-RC3
+ */
+ $vars = array(
+ 'filedata',
+ 'is_image',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.modify_uploaded_file', compact($vars)));
+ $this->file_data = $filedata;
+ unset($filedata);
+
+ // Check for attachment quota and free space
+ if (!$this->check_attach_quota() || !$this->check_disk_space())
+ {
+ return $this->file_data;
+ }
+
+ // Create Thumbnail
+ $this->create_thumbnail();
+
+ return $this->file_data;
+ }
+
+ /**
+ * Create thumbnail for file if necessary
+ *
+ * @return array Updated $filedata
+ */
+ protected function create_thumbnail()
+ {
+ if ($this->file_data['thumbnail'])
+ {
+ $source = $this->file->get('destination_file');
+ $destination = $this->file->get('destination_path') . '/thumb_' . $this->file->get('realname');
+
+ if (!create_thumbnail($source, $destination, $this->file->get('mimetype')))
+ {
+ $this->file_data['thumbnail'] = 0;
+ }
+ }
+ }
+
+ /**
+ * Init files upload class
+ *
+ * @param int $forum_id Forum ID
+ * @param bool $is_message Whether attachment is inside PM or not
+ */
+ protected function init_files_upload($forum_id, $is_message)
+ {
+ if ($this->config['check_attachment_content'] && isset($this->config['mime_triggers']))
+ {
+ $this->files_upload->set_disallowed_content(explode('|', $this->config['mime_triggers']));
+ }
+ else if (!$this->config['check_attachment_content'])
+ {
+ $this->files_upload->set_disallowed_content(array());
+ }
+
+ $this->extensions = $this->cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id));
+ $this->files_upload->set_allowed_extensions(array_keys($this->extensions['_allowed_']));
+ }
+
+ /**
+ * Check if uploaded file is really an image
+ *
+ * @param bool $is_image Whether file is image
+ */
+ protected function check_image($is_image)
+ {
+ // Make sure the image category only holds valid images...
+ if ($is_image && !$this->file->is_image())
+ {
+ $this->file->remove();
+
+ if ($this->plupload && $this->plupload->is_active())
+ {
+ $this->plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE');
+ }
+
+ // If this error occurs a user tried to exploit an IE Bug by renaming extensions
+ // Since the image category is displaying content inline we need to catch this.
+ $this->file->set_error($this->language->lang('ATTACHED_IMAGE_NOT_IMAGE'));
+ }
+ }
+
+ /**
+ * Check if attachment quota was reached
+ *
+ * @return bool False if attachment quota was reached, true if not
+ */
+ protected function check_attach_quota()
+ {
+ if ($this->config['attachment_quota'])
+ {
+ if (intval($this->config['upload_dir_size']) + $this->file->get('filesize') > $this->config['attachment_quota'])
+ {
+ $this->file_data['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED');
+ $this->file_data['post_attach'] = false;
+
+ $this->file->remove();
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Check if there is enough free space available on disk
+ *
+ * @return bool True if disk space is available, false if not
+ */
+ protected function check_disk_space()
+ {
+ if ($free_space = @disk_free_space($this->phpbb_root_path . $this->config['upload_path']))
+ {
+ if ($free_space <= $this->file->get('filesize'))
+ {
+ if ($this->auth->acl_get('a_'))
+ {
+ $this->file_data['error'][] = $this->language->lang('ATTACH_DISK_FULL');
+ }
+ else
+ {
+ $this->file_data['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED');
+ }
+ $this->file_data['post_attach'] = false;
+
+ $this->file->remove();
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Fills file data with file information and current time as filetime
+ */
+ protected function fill_file_data()
+ {
+ $this->file_data['filesize'] = $this->file->get('filesize');
+ $this->file_data['mimetype'] = $this->file->get('mimetype');
+ $this->file_data['extension'] = $this->file->get('extension');
+ $this->file_data['physical_filename'] = $this->file->get('realname');
+ $this->file_data['real_filename'] = $this->file->get('uploadname');
+ $this->file_data['filetime'] = time();
+ }
+}
diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php
index 92c19fd5f7..fc7cc1a0b1 100644
--- a/phpBB/phpbb/auth/auth.php
+++ b/phpBB/phpbb/auth/auth.php
@@ -928,6 +928,7 @@ class auth
function login($username, $password, $autologin = false, $viewonline = 1, $admin = 0)
{
global $db, $user, $phpbb_root_path, $phpEx, $phpbb_container;
+ global $phpbb_dispatcher;
/* @var $provider_collection \phpbb\auth\provider_collection */
$provider_collection = $phpbb_container->get('auth.provider_collection');
@@ -983,6 +984,24 @@ class auth
redirect($url);
}
+ /**
+ * Event is triggered after checking for valid username and password, and before the actual session creation.
+ *
+ * @event core.auth_login_session_create_before
+ * @var array login Variable containing login array
+ * @var bool admin Boolean variable whether user is logging into the ACP
+ * @var string username Username of user to log in
+ * @var bool autologin Boolean variable signaling whether login is triggered via auto login
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'login',
+ 'admin',
+ 'username',
+ 'autologin',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.auth_login_session_create_before', compact($vars)));
+
// If login succeeded, we will log the user in... else we pass the login array through...
if ($login['status'] == LOGIN_SUCCESS)
{
diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php
index badbd9421d..b8cf84424a 100644
--- a/phpBB/phpbb/avatar/driver/gravatar.php
+++ b/phpBB/phpbb/avatar/driver/gravatar.php
@@ -172,6 +172,8 @@ class gravatar extends \phpbb\avatar\driver\driver
*/
protected function get_gravatar_url($row)
{
+ global $phpbb_dispatcher;
+
$url = self::GRAVATAR_URL;
$url .= md5(strtolower(trim($row['avatar'])));
@@ -180,6 +182,17 @@ class gravatar extends \phpbb\avatar\driver\driver
$url .= '?s=' . max($row['avatar_width'], $row['avatar_height']);
}
+ /**
+ * Modify gravatar url
+ *
+ * @event core.get_gravatar_url_after
+ * @var string row User data or group data
+ * @var string url Gravatar URL
+ * @since 3.1.7-RC1
+ */
+ $vars = array('row', 'url');
+ extract($phpbb_dispatcher->trigger_event('core.get_gravatar_url_after', compact($vars)));
+
return $url;
}
}
diff --git a/phpBB/phpbb/avatar/driver/local.php b/phpBB/phpbb/avatar/driver/local.php
index 88a139f81e..f5547c4bc6 100644
--- a/phpBB/phpbb/avatar/driver/local.php
+++ b/phpBB/phpbb/avatar/driver/local.php
@@ -84,11 +84,13 @@ class local extends \phpbb\avatar\driver\driver
'AVATAR_IMAGE' => $this->phpbb_root_path . $this->config['avatar_gallery_path'] . '/' . $img['file'],
'AVATAR_NAME' => $img['name'],
'AVATAR_FILE' => $img['filename'],
+ 'CHECKED' => $img['file'] === $row['avatar'],
));
$template->assign_block_vars('avatar_local_row.avatar_local_option', array(
'AVATAR_FILE' => $img['filename'],
- 'S_OPTIONS_AVATAR' => $img['filename']
+ 'S_OPTIONS_AVATAR' => $img['filename'],
+ 'CHECKED' => $img['file'] === $row['avatar'],
));
$col_count = ($col_count + 1) % $table_cols;
@@ -184,7 +186,7 @@ class local extends \phpbb\avatar\driver\driver
}
$cat = ($path == $file_path) ? $user->lang['NO_AVATAR_CATEGORY'] : str_replace("$path/", '', $file_path);
$avatar_list[$cat][$image] = array(
- 'file' => ($cat != $user->lang['NO_AVATAR_CATEGORY']) ? rawurlencode($cat) . '/' . rawurlencode($image) : rawurlencode($image),
+ 'file' => ($cat != $user->lang['NO_AVATAR_CATEGORY']) ? str_replace('%2F', '/', rawurlencode($cat)) . '/' . rawurlencode($image) : rawurlencode($image),
'filename' => rawurlencode($image),
'name' => ucfirst(str_replace('_', ' ', preg_replace('#^(.*)\..*$#', '\1', $image))),
'width' => $dims[0],
diff --git a/phpBB/phpbb/captcha/plugins/recaptcha.php b/phpBB/phpbb/captcha/plugins/recaptcha.php
index 98132ab47d..152709a9ea 100644
--- a/phpBB/phpbb/captcha/plugins/recaptcha.php
+++ b/phpBB/phpbb/captcha/plugins/recaptcha.php
@@ -18,12 +18,6 @@ class recaptcha extends captcha_abstract
var $recaptcha_server = 'http://www.google.com/recaptcha/api';
var $recaptcha_server_secure = 'https://www.google.com/recaptcha/api'; // class constants :(
- // We are opening a socket to port 80 of this host and send
- // the POST request asking for verification to the path specified here.
- var $recaptcha_verify_server = 'www.google.com';
- var $recaptcha_verify_path = '/recaptcha/api/verify';
-
- var $challenge;
var $response;
/**
@@ -37,12 +31,11 @@ class recaptcha extends captcha_abstract
function init($type)
{
- global $config, $db, $user, $request;
+ global $user, $request;
$user->add_lang('captcha_recaptcha');
parent::init($type);
- $this->challenge = $request->variable('recaptcha_challenge_field', '');
- $this->response = $request->variable('recaptcha_response_field', '');
+ $this->response = $request->variable('g-recaptcha-response', '');
}
public function is_available()
@@ -75,7 +68,7 @@ class recaptcha extends captcha_abstract
function acp_page($id, &$module)
{
- global $config, $db, $template, $user, $phpbb_log, $request;
+ global $config, $template, $user, $phpbb_log, $request;
$captcha_vars = array(
'recaptcha_pubkey' => 'RECAPTCHA_PUBKEY',
@@ -151,7 +144,6 @@ class recaptcha extends captcha_abstract
$template->assign_vars(array(
'RECAPTCHA_SERVER' => $this->recaptcha_server,
'RECAPTCHA_PUBKEY' => isset($config['recaptcha_pubkey']) ? $config['recaptcha_pubkey'] : '',
- 'RECAPTCHA_ERRORGET' => '',
'S_RECAPTCHA_AVAILABLE' => self::is_available(),
'S_CONFIRM_CODE' => true,
'S_TYPE' => $this->type,
@@ -202,106 +194,25 @@ class recaptcha extends captcha_abstract
}
}
-// Code from here on is based on recaptchalib.php
-/*
- * This is a PHP library that handles calling reCAPTCHA.
- * - Documentation and latest version
- * http://recaptcha.net/plugins/php/
- * - Get a reCAPTCHA API Key
- * http://recaptcha.net/api/getkey
- * - Discussion group
- * http://groups.google.com/group/recaptcha
- *
- * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
- * AUTHORS:
- * Mike Crawford
- * Ben Maurer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
- /**
- * Submits an HTTP POST to a reCAPTCHA server
- * @param string $host
- * @param string $path
- * @param array $data
- * @param int port
- * @return array response
- */
- function _recaptcha_http_post($host, $path, $data, $port = 80)
- {
- $req = $this->_recaptcha_qsencode ($data);
-
- $http_request = "POST $path HTTP/1.0\r\n";
- $http_request .= "Host: $host\r\n";
- $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
- $http_request .= "Content-Length: " . strlen($req) . "\r\n";
- $http_request .= "User-Agent: reCAPTCHA/PHP/phpBB\r\n";
- $http_request .= "\r\n";
- $http_request .= $req;
-
- $response = '';
- if (false == ($fs = @fsockopen($host, $port, $errno, $errstr, 10)))
- {
- trigger_error('RECAPTCHA_SOCKET_ERROR', E_USER_ERROR);
- }
-
- fwrite($fs, $http_request);
-
- while (!feof($fs))
- {
- // One TCP-IP packet
- $response .= fgets($fs, 1160);
- }
- fclose($fs);
- $response = explode("\r\n\r\n", $response, 2);
-
- return $response;
- }
-
/**
* Calls an HTTP POST function to verify if the user's guess was correct
- * @param array $extra_params an array of extra variables to post to the server
- * @return ReCaptchaResponse
+ *
+ * @return bool|string Returns false on success or error string on failure.
*/
- function recaptcha_check_answer($extra_params = array())
+ function recaptcha_check_answer()
{
global $config, $user;
//discard spam submissions
- if ($this->challenge == null || strlen($this->challenge) == 0 || $this->response == null || strlen($this->response) == 0)
+ if ($this->response == null || strlen($this->response) == 0)
{
return $user->lang['RECAPTCHA_INCORRECT'];
}
- $response = $this->_recaptcha_http_post($this->recaptcha_verify_server, $this->recaptcha_verify_path,
- array(
- 'privatekey' => $config['recaptcha_privkey'],
- 'remoteip' => $user->ip,
- 'challenge' => $this->challenge,
- 'response' => $this->response
- ) + $extra_params
- );
-
- $answers = explode("\n", $response[1]);
+ $recaptcha = new \ReCaptcha\ReCaptcha($config['recaptcha_privkey']);
+ $result = $recaptcha->verify($this->response, $user->ip);
- if (trim($answers[0]) === 'true')
+ if ($result->isSuccess())
{
$this->solved = true;
return false;
@@ -311,22 +222,4 @@ class recaptcha extends captcha_abstract
return $user->lang['RECAPTCHA_INCORRECT'];
}
}
-
- /**
- * Encodes the given data into a query string format
- * @param $data - array of string elements to be encoded
- * @return string - encoded request
- */
- function _recaptcha_qsencode($data)
- {
- $req = '';
- foreach ($data as $key => $value)
- {
- $req .= $key . '=' . urlencode(stripslashes($value)) . '&';
- }
-
- // Cut the last '&'
- $req = substr($req, 0, strlen($req) - 1);
- return $req;
- }
}
diff --git a/phpBB/phpbb/console/command/db/console_migrator_output_handler.php b/phpBB/phpbb/console/command/db/console_migrator_output_handler.php
index b9741a3838..568b2646d4 100644
--- a/phpBB/phpbb/console/command/db/console_migrator_output_handler.php
+++ b/phpBB/phpbb/console/command/db/console_migrator_output_handler.php
@@ -13,8 +13,8 @@
namespace phpbb\console\command\db;
+use phpbb\db\output_handler\migrator_output_handler_interface;
use phpbb\user;
-use phpbb\db\migrator_output_handler_interface;
use Symfony\Component\Console\Output\OutputInterface;
class console_migrator_output_handler implements migrator_output_handler_interface
diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php
index 43029b7458..ae4211f7be 100644
--- a/phpBB/phpbb/console/command/db/migrate.php
+++ b/phpBB/phpbb/console/command/db/migrate.php
@@ -12,6 +12,7 @@
*/
namespace phpbb\console\command\db;
+use phpbb\db\output_handler\log_wrapper_migrator_output_handler;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -26,8 +27,12 @@ class migrate extends \phpbb\console\command\db\migration_command
/** @var \phpbb\filesystem\filesystem_interface */
protected $filesystem;
- function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path)
+ /** @var \phpbb\language\language */
+ protected $language;
+
+ function __construct(\phpbb\user $user, \phpbb\language\language $language, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path)
{
+ $this->language = $language;
$this->log = $log;
$this->filesystem = $filesystem;
$this->phpbb_root_path = $phpbb_root_path;
@@ -45,7 +50,7 @@ class migrate extends \phpbb\console\command\db\migration_command
protected function execute(InputInterface $input, OutputInterface $output)
{
- $this->migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($this->user, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem));
+ $this->migrator->set_output_handler(new log_wrapper_migrator_output_handler($this->language, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem));
$this->migrator->create_migrations_table();
diff --git a/phpBB/phpbb/console/command/db/revert.php b/phpBB/phpbb/console/command/db/revert.php
index 838640968e..3fa2e17515 100644
--- a/phpBB/phpbb/console/command/db/revert.php
+++ b/phpBB/phpbb/console/command/db/revert.php
@@ -12,6 +12,7 @@
*/
namespace phpbb\console\command\db;
+use phpbb\db\output_handler\log_wrapper_migrator_output_handler;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -24,9 +25,13 @@ class revert extends \phpbb\console\command\db\migration_command
/** @var \phpbb\filesystem\filesystem_interface */
protected $filesystem;
- function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path)
+ /** @var \phpbb\language\language */
+ protected $language;
+
+ function __construct(\phpbb\user $user, \phpbb\language\language $language, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path)
{
$this->filesystem = $filesystem;
+ $this->language = $language;
$this->phpbb_root_path = $phpbb_root_path;
parent::__construct($user, $migrator, $extension_manager, $config, $cache);
$this->user->add_lang(array('common', 'migrator'));
@@ -49,7 +54,7 @@ class revert extends \phpbb\console\command\db\migration_command
{
$name = str_replace('/', '\\', $input->getArgument('name'));
- $this->migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($this->user, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem));
+ $this->migrator->set_output_handler(new log_wrapper_migrator_output_handler($this->language, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log', $this->filesystem));
$this->cache->purge();
diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php
index 2925765e94..7e2d7a5ea6 100644
--- a/phpBB/phpbb/db/driver/driver.php
+++ b/phpBB/phpbb/db/driver/driver.php
@@ -774,7 +774,18 @@ abstract class driver implements driver_interface
if (!empty($array['WHERE']))
{
- $sql .= ' WHERE ' . $this->_sql_custom_build('WHERE', $array['WHERE']);
+ $sql .= ' WHERE ';
+
+ if (is_array($array['WHERE']))
+ {
+ $sql_where = $this->_process_boolean_tree_first($array['WHERE']);
+ }
+ else
+ {
+ $sql_where = $array['WHERE'];
+ }
+
+ $sql .= $this->_sql_custom_build('WHERE', $sql_where);
}
if (!empty($array['GROUP_BY']))
@@ -793,6 +804,130 @@ abstract class driver implements driver_interface
return $sql;
}
+
+ protected function _process_boolean_tree_first($operations_ary)
+ {
+ // In cases where an array exists but there is no head condition,
+ // it should be because there's only 1 WHERE clause. This seems the best way to deal with it.
+ if ($operations_ary[0] !== 'AND' &&
+ $operations_ary[0] !== 'OR')
+ {
+ $operations_ary = array('AND', $operations_ary);
+ }
+ return $this->_process_boolean_tree($operations_ary) . "\n";
+ }
+
+ protected function _process_boolean_tree($operations_ary)
+ {
+ $operation = array_shift($operations_ary);
+
+ foreach ($operations_ary as &$condition)
+ {
+ switch ($condition[0])
+ {
+ case 'AND':
+ case 'OR':
+
+ $condition = ' ( ' . $this->_process_boolean_tree($condition) . ') ';
+
+ break;
+ case 'NOT':
+
+ $condition = ' NOT (' . $this->_process_boolean_tree($condition) . ') ';
+
+ break;
+
+ default:
+
+ switch (sizeof($condition))
+ {
+ case 3:
+
+ // Typical 3 element clause with {left hand} {operator} {right hand}
+ switch ($condition[1])
+ {
+ case 'IN':
+ case 'NOT_IN':
+
+ // As this is used with an IN, assume it is a set of elements for sql_in_set()
+ $condition = $this->sql_in_set($condition[0], $condition[2], $condition[1] === 'NOT_IN', true);
+
+ break;
+
+ case 'LIKE':
+
+ $condition = $condition[0] . ' ' . $this->sql_like_expression($condition[2]) . ' ';
+
+ break;
+
+ case 'NOT_LIKE':
+
+ $condition = $condition[0] . ' ' . $this->sql_not_like_expression($condition[2]) . ' ';
+
+ break;
+
+ case 'IS_NOT':
+
+ $condition[1] = 'IS NOT';
+
+ // no break
+ case 'IS':
+
+ // If the value is NULL, the string of it is the empty string ('') which is not the intended result.
+ // this should solve that
+ if ($condition[2] === null)
+ {
+ $condition[2] = 'NULL';
+ }
+
+ $condition = implode(' ', $condition);
+
+ break;
+
+ default:
+
+ $condition = implode(' ', $condition);
+
+ break;
+ }
+
+ break;
+
+ case 5:
+
+ // Subquery with {left hand} {operator} {compare kind} {SELECT Kind } {Sub Query}
+
+ $condition = $condition[0] . ' ' . $condition[1] . ' ' . $condition[2] . ' ( ';
+ $condition .= $this->sql_build_query($condition[3], $condition[4]);
+ $condition .= ' )';
+
+ break;
+
+ default:
+ // This is an unpredicted clause setup. Just join all elements.
+ $condition = implode(' ', $condition);
+
+ break;
+ }
+
+ break;
+ }
+
+ }
+
+ if ($operation === 'NOT')
+ {
+ $operations_ary = implode("", $operations_ary);
+ }
+ else
+ {
+ $operations_ary = implode(" \n $operation ", $operations_ary);
+ }
+
+ return $operations_ary;
+ }
+
+
/**
* {@inheritDoc}
*/
diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php
index 18c6403c07..a809bc14f9 100644
--- a/phpBB/phpbb/db/migrator.php
+++ b/phpBB/phpbb/db/migrator.php
@@ -13,6 +13,8 @@
namespace phpbb\db;
+use phpbb\db\output_handler\migrator_output_handler_interface;
+use phpbb\db\output_handler\null_migrator_output_handler;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -122,7 +124,7 @@ class migrator
/**
* Set the output handler.
*
- * @param migrator_output_handler $handler The output handler
+ * @param migrator_output_handler_interface $handler The output handler
*/
public function set_output_handler(migrator_output_handler_interface $handler)
{
diff --git a/phpBB/phpbb/db/html_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/html_migrator_output_handler.php
index e37c667463..67309649c9 100644
--- a/phpBB/phpbb/db/html_migrator_output_handler.php
+++ b/phpBB/phpbb/db/output_handler/html_migrator_output_handler.php
@@ -11,27 +11,25 @@
*
*/
-namespace phpbb\db;
-
-use phpbb\user;
+namespace phpbb\db\output_handler;
class html_migrator_output_handler implements migrator_output_handler_interface
{
/**
- * User object.
+ * Language object.
*
- * @var user
+ * @var \phpbb\language\language
*/
- private $user;
+ private $language;
/**
* Constructor
*
- * @param user $user User object
+ * @param \phpbb\language\language $language Language object
*/
- public function __construct(user $user)
+ public function __construct(\phpbb\language\language $language)
{
- $this->user = $user;
+ $this->language = $language;
}
/**
@@ -41,7 +39,7 @@ class html_migrator_output_handler implements migrator_output_handler_interface
{
if ($verbosity <= migrator_output_handler_interface::VERBOSITY_VERBOSE)
{
- $final_message = call_user_func_array(array($this->user, 'lang'), $message);
+ $final_message = $this->language->lang_array(array_shift($message), $message);
echo $final_message . "<br />\n";
}
}
diff --git a/phpBB/phpbb/db/output_handler/installer_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/installer_migrator_output_handler.php
new file mode 100644
index 0000000000..56d5cf49a1
--- /dev/null
+++ b/phpBB/phpbb/db/output_handler/installer_migrator_output_handler.php
@@ -0,0 +1,46 @@
+<?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\output_handler;
+
+use phpbb\install\helper\iohandler\iohandler_interface;
+
+class installer_migrator_output_handler implements migrator_output_handler_interface
+{
+ /**
+ * @var iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * Constructor
+ *
+ * @param iohandler_interface $iohandler Installer's IO-handler
+ */
+ public function __construct(iohandler_interface $iohandler)
+ {
+ $this->iohandler = $iohandler;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($message, $verbosity)
+ {
+ if ($verbosity <= migrator_output_handler_interface::VERBOSITY_VERBOSE)
+ {
+ $this->iohandler->add_log_message($message);
+ $this->iohandler->send_response();
+ }
+ }
+}
diff --git a/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php
index 4c85bf4d67..20991746ac 100644
--- a/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php
+++ b/phpBB/phpbb/db/output_handler/log_wrapper_migrator_output_handler.php
@@ -11,18 +11,16 @@
*
*/
-namespace phpbb\db;
-
-use phpbb\user;
+namespace phpbb\db\output_handler;
class log_wrapper_migrator_output_handler implements migrator_output_handler_interface
{
/**
- * User object.
+ * Language object.
*
- * @var user
+ * @var \phpbb\language\language
*/
- protected $user;
+ protected $language;
/**
* A migrator output handler
@@ -45,14 +43,14 @@ class log_wrapper_migrator_output_handler implements migrator_output_handler_int
/**
* Constructor
*
- * @param user $user User object
- * @param migrator_output_handler_interface $migrator Migrator output handler
- * @param string $log_file File to log to
- * @param \phpbb\filesystem\filesystem_interface phpBB filesystem object
+ * @param \phpbb\language\language $language Language object
+ * @param migrator_output_handler_interface $migrator Migrator output handler
+ * @param string $log_file File to log to
+ * @param \phpbb\filesystem\filesystem_interface $filesystem phpBB filesystem object
*/
- public function __construct(user $user, migrator_output_handler_interface $migrator, $log_file, \phpbb\filesystem\filesystem_interface $filesystem)
+ public function __construct(\phpbb\language\language $language, migrator_output_handler_interface $migrator, $log_file, \phpbb\filesystem\filesystem_interface $filesystem)
{
- $this->user = $user;
+ $this->language = $language;
$this->migrator = $migrator;
$this->filesystem = $filesystem;
$this->file_open($log_file);
@@ -84,7 +82,8 @@ class log_wrapper_migrator_output_handler implements migrator_output_handler_int
if ($this->file_handle !== false)
{
- $translated_message = call_user_func_array(array($this->user, 'lang'), $message) . "\n";
+
+ $translated_message = $this->language->lang_array(array_shift($message), $message);
if ($verbosity <= migrator_output_handler_interface::VERBOSITY_NORMAL)
{
diff --git a/phpBB/phpbb/db/migrator_output_handler_interface.php b/phpBB/phpbb/db/output_handler/migrator_output_handler_interface.php
index a923af99f6..7bb5c73fec 100644
--- a/phpBB/phpbb/db/migrator_output_handler_interface.php
+++ b/phpBB/phpbb/db/output_handler/migrator_output_handler_interface.php
@@ -11,7 +11,7 @@
*
*/
-namespace phpbb\db;
+namespace phpbb\db\output_handler;
interface migrator_output_handler_interface
{
diff --git a/phpBB/phpbb/db/null_migrator_output_handler.php b/phpBB/phpbb/db/output_handler/null_migrator_output_handler.php
index 0e8cfbb049..5fc2a52577 100644
--- a/phpBB/phpbb/db/null_migrator_output_handler.php
+++ b/phpBB/phpbb/db/output_handler/null_migrator_output_handler.php
@@ -11,7 +11,7 @@
*
*/
-namespace phpbb\db;
+namespace phpbb\db\output_handler;
class null_migrator_output_handler implements migrator_output_handler_interface
{
diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php
index fb391760ce..0a94aac98d 100644
--- a/phpBB/phpbb/di/container_builder.php
+++ b/phpBB/phpbb/di/container_builder.php
@@ -355,6 +355,7 @@ class container_builder
->without_cache()
->without_extensions()
->with_config($this->config_php_file)
+ ->with_config_path($this->get_config_path())
->with_environment('production')
->without_compiled_container()
->get_container()
diff --git a/phpBB/phpbb/event/kernel_exception_subscriber.php b/phpBB/phpbb/event/kernel_exception_subscriber.php
index 0a8a0183dc..e427abf5e3 100644
--- a/phpBB/phpbb/event/kernel_exception_subscriber.php
+++ b/phpBB/phpbb/event/kernel_exception_subscriber.php
@@ -24,26 +24,28 @@ class kernel_exception_subscriber implements EventSubscriberInterface
{
/**
* Template object
+ *
* @var \phpbb\template\template
*/
protected $template;
/**
- * User object
- * @var \phpbb\user
+ * Language object
+ *
+ * @var \phpbb\language\language
*/
- protected $user;
+ protected $language;
/**
* Construct method
*
- * @param \phpbb\template\template $template Template object
- * @param \phpbb\user $user User object
+ * @param \phpbb\template\template $template Template object
+ * @param \phpbb\language\language $language Language object
*/
- public function __construct(\phpbb\template\template $template, \phpbb\user $user)
+ public function __construct(\phpbb\template\template $template, \phpbb\language\language $language)
{
$this->template = $template;
- $this->user = $user;
+ $this->language = $language;
}
/**
@@ -60,15 +62,15 @@ class kernel_exception_subscriber implements EventSubscriberInterface
if ($exception instanceof \phpbb\exception\exception_interface)
{
- $message = call_user_func_array(array($this->user, 'lang'), array_merge(array($message), $exception->get_parameters()));
+ $message = $this->language->lang_array($message, $exception->get_parameters());
}
if (!$event->getRequest()->isXmlHttpRequest())
{
- page_header($this->user->lang('INFORMATION'));
+ page_header($this->language->lang('INFORMATION'));
$this->template->assign_vars(array(
- 'MESSAGE_TITLE' => $this->user->lang('INFORMATION'),
+ 'MESSAGE_TITLE' => $this->language->lang('INFORMATION'),
'MESSAGE_TEXT' => $message,
));
diff --git a/phpBB/phpbb/hook/finder.php b/phpBB/phpbb/hook/finder.php
index a3d02d3aa0..f5a68a1370 100644
--- a/phpBB/phpbb/hook/finder.php
+++ b/phpBB/phpbb/hook/finder.php
@@ -18,8 +18,19 @@ namespace phpbb\hook;
*/
class finder
{
- protected $phpbb_root_path;
+ /**
+ * @var \phpbb\cache\driver\driver_interface
+ */
protected $cache;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * @var string
+ */
protected $php_ext;
/**
diff --git a/phpBB/phpbb/install/controller/archive_download.php b/phpBB/phpbb/install/controller/archive_download.php
new file mode 100644
index 0000000000..a0f0ba181d
--- /dev/null
+++ b/phpBB/phpbb/install/controller/archive_download.php
@@ -0,0 +1,93 @@
+<?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\install\controller;
+
+use phpbb\exception\http_exception;
+use phpbb\install\helper\config;
+use Symfony\Component\HttpFoundation\BinaryFileResponse;
+use Symfony\Component\HttpFoundation\ResponseHeaderBag;
+
+class archive_download
+{
+ /**
+ * @var config
+ */
+ protected $installer_config;
+
+ /**
+ * Constructor
+ *
+ * @param config $config
+ */
+ public function __construct(config $config)
+ {
+ $this->installer_config = $config;
+ $this->installer_config->load_config();
+ }
+
+ /**
+ * Sends response with the merge conflict archive
+ *
+ * Merge conflicts always have to be resolved manually,
+ * so we use a different archive for that.
+ *
+ * @return BinaryFileResponse
+ */
+ public function conflict_archive()
+ {
+ $filename = $this->installer_config->get('update_file_conflict_archive', false);
+
+ if (!$filename)
+ {
+ throw new http_exception(404, 'URL_NOT_FOUND');
+ }
+
+ return $this->send_response($filename);
+ }
+
+ /**
+ * Sends response with the updated files' archive
+ *
+ * @return BinaryFileResponse
+ */
+ public function update_archive()
+ {
+ $filename = $this->installer_config->get('update_file_archive', '');
+
+ if (!$filename)
+ {
+ throw new http_exception(404, 'URL_NOT_FOUND');
+ }
+
+ return $this->send_response($filename);
+ }
+
+ /**
+ * Generates a download response
+ *
+ * @param string $filename Path to the file to download
+ *
+ * @return BinaryFileResponse Response object
+ */
+ private function send_response($filename)
+ {
+ $response = new BinaryFileResponse($filename);
+ $response->setContentDisposition(
+ ResponseHeaderBag::DISPOSITION_ATTACHMENT,
+ basename($filename)
+ );
+
+ return $response;
+ }
+}
diff --git a/phpBB/phpbb/install/controller/helper.php b/phpBB/phpbb/install/controller/helper.php
index fdfa6821ed..bfa9ec6238 100644
--- a/phpBB/phpbb/install/controller/helper.php
+++ b/phpBB/phpbb/install/controller/helper.php
@@ -13,6 +13,7 @@
namespace phpbb\install\controller;
+use phpbb\install\helper\config;
use phpbb\install\helper\navigation\navigation_provider;
use phpbb\language\language;
use phpbb\language\language_file_helper;
@@ -34,6 +35,11 @@ use Symfony\Component\HttpFoundation\Cookie;
class helper
{
/**
+ * @var config
+ */
+ protected $installer_config;
+
+ /**
* @var \phpbb\language\language
*/
protected $language;
@@ -91,6 +97,7 @@ class helper
/**
* Constructor
*
+ * @param config $config
* @param language $language
* @param language_file_helper $lang_helper
* @param navigation_provider $nav
@@ -101,8 +108,9 @@ class helper
* @param router $router
* @param string $phpbb_root_path
*/
- public function __construct(language $language, language_file_helper $lang_helper, navigation_provider $nav, template $template, path_helper $path_helper, request $phpbb_request, symfony_request $request, router $router, $phpbb_root_path)
+ public function __construct(config $config, language $language, language_file_helper $lang_helper, navigation_provider $nav, template $template, path_helper $path_helper, request $phpbb_request, symfony_request $request, router $router, $phpbb_root_path)
{
+ $this->installer_config = $config;
$this->language = $language;
$this->language_cookie = false;
$this->lang_helper = $lang_helper;
@@ -200,6 +208,47 @@ class helper
}
/**
+ * Process navigation data to reflect active/completed stages
+ *
+ * @param \phpbb\install\helper\iohandler\iohandler_interface|null $iohandler
+ */
+ public function handle_navigation($iohandler = null)
+ {
+ $nav_data = $this->installer_config->get_navigation_data();
+
+ // Set active navigation stage
+ if (isset($nav_data['active']) && is_array($nav_data['active']))
+ {
+ if ($iohandler !== null)
+ {
+ $iohandler->set_active_stage_menu($nav_data['active']);
+ }
+
+ $this->navigation_provider->set_nav_property($nav_data['active'], array(
+ 'selected' => true,
+ 'completed' => false,
+ ));
+ }
+
+ // Set finished navigation stages
+ if (isset($nav_data['finished']) && is_array($nav_data['finished']))
+ {
+ foreach ($nav_data['finished'] as $finished_stage)
+ {
+ if ($iohandler !== null)
+ {
+ $iohandler->set_finished_stage_menu($finished_stage);
+ }
+
+ $this->navigation_provider->set_nav_property($finished_stage, array(
+ 'selected' => false,
+ 'completed' => true,
+ ));
+ }
+ }
+ }
+
+ /**
* Set default template variables
*
* @param string $page_title Title of the page
@@ -207,27 +256,32 @@ class helper
*/
protected function page_header($page_title, $selected_language = false)
{
+ // Path to templates
+ $paths = array($this->phpbb_root_path . 'install/update/new/adm/', $this->phpbb_admin_path);
+ $paths = array_filter($paths, 'is_dir');
+ $path = array_shift($paths);
+ $path = substr($path, strlen($this->phpbb_root_path));
+
$this->template->assign_vars(array(
- 'L_CHANGE' => $this->language->lang('CHANGE'),
- 'L_COLON' => $this->language->lang('COLON'),
- 'L_INSTALL_PANEL' => $this->language->lang('INSTALL_PANEL'),
- 'L_SELECT_LANG' => $this->language->lang('SELECT_LANG'),
- 'L_SKIP' => $this->language->lang('SKIP'),
- 'PAGE_TITLE' => $this->language->lang($page_title),
- 'T_IMAGE_PATH' => htmlspecialchars($this->phpbb_admin_path) . 'images/',
- 'T_JQUERY_LINK' => $this->path_helper->get_web_root_path() . 'assets/javascript/jquery.min.js',
- 'T_TEMPLATE_PATH' => $this->path_helper->get_web_root_path() . 'adm/style',
- 'T_ASSETS_PATH' => $this->path_helper->get_web_root_path() . 'assets/',
-
- 'S_CONTENT_DIRECTION' => $this->language->lang('DIRECTION'),
- 'S_CONTENT_FLOW_BEGIN' => ($this->language->lang('DIRECTION') === 'ltr') ? 'left' : 'right',
- 'S_CONTENT_FLOW_END' => ($this->language->lang('DIRECTION') === 'ltr') ? 'right' : 'left',
- 'S_CONTENT_ENCODING' => 'UTF-8',
- 'S_LANG_SELECT' => $selected_language,
-
- 'S_USER_LANG' => $this->language->lang('USER_LANG'),
- )
- );
+ 'L_CHANGE' => $this->language->lang('CHANGE'),
+ 'L_COLON' => $this->language->lang('COLON'),
+ 'L_INSTALL_PANEL' => $this->language->lang('INSTALL_PANEL'),
+ 'L_SELECT_LANG' => $this->language->lang('SELECT_LANG'),
+ 'L_SKIP' => $this->language->lang('SKIP'),
+ 'PAGE_TITLE' => $this->language->lang($page_title),
+ 'T_IMAGE_PATH' => $this->path_helper->get_web_root_path() . $path . 'images/',
+ 'T_JQUERY_LINK' => $this->path_helper->get_web_root_path() . $path . '../assets/javascript/jquery.min.js',
+ 'T_TEMPLATE_PATH' => $this->path_helper->get_web_root_path() . $path . 'style/',
+ 'T_ASSETS_PATH' => $this->path_helper->get_web_root_path() . $path . '../assets/',
+
+ 'S_CONTENT_DIRECTION' => $this->language->lang('DIRECTION'),
+ 'S_CONTENT_FLOW_BEGIN' => ($this->language->lang('DIRECTION') === 'ltr') ? 'left' : 'right',
+ 'S_CONTENT_FLOW_END' => ($this->language->lang('DIRECTION') === 'ltr') ? 'right' : 'left',
+ 'S_CONTENT_ENCODING' => 'UTF-8',
+ 'S_LANG_SELECT' => $selected_language,
+
+ 'S_USER_LANG' => $this->language->lang('USER_LANG'),
+ ));
$this->render_navigation();
}
diff --git a/phpBB/phpbb/install/controller/install.php b/phpBB/phpbb/install/controller/install.php
index 80f6651a39..8d5ff95958 100644
--- a/phpBB/phpbb/install/controller/install.php
+++ b/phpBB/phpbb/install/controller/install.php
@@ -13,7 +13,6 @@
namespace phpbb\install\controller;
-use phpbb\install\helper\config;
use phpbb\install\helper\install_helper;
use phpbb\install\helper\navigation\navigation_provider;
use Symfony\Component\HttpFoundation\StreamedResponse;
@@ -36,11 +35,6 @@ class install
protected $controller_helper;
/**
- * @var config
- */
- protected $installer_config;
-
- /**
* @var factory
*/
protected $iohandler_factory;
@@ -79,7 +73,6 @@ class install
* Constructor
*
* @param helper $helper
- * @param config $install_config
* @param factory $factory
* @param navigation_provider $nav_provider
* @param language $language
@@ -88,10 +81,9 @@ class install
* @param installer $installer
* @param install_helper $install_helper
*/
- public function __construct(helper $helper, config $install_config, factory $factory, navigation_provider $nav_provider, language $language, template $template, request_interface $request, installer $installer, install_helper $install_helper)
+ public function __construct(helper $helper, factory $factory, navigation_provider $nav_provider, language $language, template $template, request_interface $request, installer $installer, install_helper $install_helper)
{
$this->controller_helper = $helper;
- $this->installer_config = $install_config;
$this->iohandler_factory = $factory;
$this->menu_provider = $nav_provider;
$this->language = $language;
@@ -130,34 +122,6 @@ class install
// Set the appropriate input-output handler
$this->installer->set_iohandler($this->iohandler_factory->get());
- // Set up navigation
- $nav_data = $this->installer_config->get_navigation_data();
- /** @var \phpbb\install\helper\iohandler\iohandler_interface $iohandler */
- $iohandler = $this->iohandler_factory->get();
-
- // Set active navigation stage
- if (isset($nav_data['active']) && is_array($nav_data['active']))
- {
- $iohandler->set_active_stage_menu($nav_data['active']);
- $this->menu_provider->set_nav_property($nav_data['active'], array(
- 'selected' => true,
- 'completed' => false,
- ));
- }
-
- // Set finished navigation stages
- if (isset($nav_data['finished']) && is_array($nav_data['finished']))
- {
- foreach ($nav_data['finished'] as $finished_stage)
- {
- $iohandler->set_finished_stage_menu($finished_stage);
- $this->menu_provider->set_nav_property($finished_stage, array(
- 'selected' => false,
- 'completed' => true,
- ));
- }
- }
-
if ($this->request->is_ajax())
{
$installer = $this->installer;
@@ -193,6 +157,11 @@ class install
'TITLE' => $this->language->lang('INSTALL_INTRO'),
'CONTENT' => $this->language->lang('INSTALL_INTRO_BODY'),
));
+
+ /** @var \phpbb\install\helper\iohandler\iohandler_interface $iohandler */
+ $iohandler = $this->iohandler_factory->get();
+ $this->controller_helper->handle_navigation($iohandler);
+
return $this->controller_helper->render('installer_install.html', 'INSTALL', true);
}
diff --git a/phpBB/phpbb/install/controller/update.php b/phpBB/phpbb/install/controller/update.php
new file mode 100644
index 0000000000..5212ba7f26
--- /dev/null
+++ b/phpBB/phpbb/install/controller/update.php
@@ -0,0 +1,162 @@
+<?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\install\controller;
+
+use phpbb\install\helper\install_helper;
+use phpbb\install\helper\iohandler\factory;
+use phpbb\install\helper\navigation\navigation_provider;
+use phpbb\install\installer;
+use phpbb\language\language;
+use phpbb\request\request_interface;
+use phpbb\template\template;
+use Symfony\Component\HttpFoundation\StreamedResponse;
+
+/**
+ * Updater controller
+ */
+class update
+{
+ /**
+ * @var helper
+ */
+ protected $controller_helper;
+
+ /**
+ * @var installer
+ */
+ protected $installer;
+
+ /**
+ * @var install_helper
+ */
+ protected $install_helper;
+
+ /**
+ * @var factory
+ */
+ protected $iohandler_factory;
+
+ /**
+ * @var language
+ */
+ protected $language;
+
+ /**
+ * @var navigation_provider
+ */
+ protected $menu_provider;
+
+ /**
+ * @var request_interface
+ */
+ protected $request;
+
+ /**
+ * @var template
+ */
+ protected $template;
+
+ /**
+ * Constructor
+ *
+ * @param helper $controller_helper
+ * @param installer $installer
+ * @param install_helper $install_helper
+ * @param factory $iohandler
+ * @param language $language
+ * @param navigation_provider $menu_provider
+ * @param request_interface $request
+ * @param template $template
+ */
+ public function __construct(helper $controller_helper, installer $installer, install_helper $install_helper, factory $iohandler, language $language, navigation_provider $menu_provider, request_interface $request, template $template)
+ {
+ $this->controller_helper = $controller_helper;
+ $this->installer = $installer;
+ $this->install_helper = $install_helper;
+ $this->iohandler_factory = $iohandler;
+ $this->language = $language;
+ $this->menu_provider = $menu_provider;
+ $this->request = $request;
+ $this->template = $template;
+ }
+
+ /**
+ * Controller entry point
+ */
+ public function handle()
+ {
+ if (!$this->install_helper->is_phpbb_installed())
+ {
+ die ('phpBB is not installed');
+ }
+
+ $this->template->assign_vars(array(
+ 'U_ACTION' => $this->controller_helper->route('phpbb_installer_update'),
+ ));
+
+ // Set up input-output handler
+ if ($this->request->is_ajax())
+ {
+ $this->iohandler_factory->set_environment('ajax');
+ }
+ else
+ {
+ $this->iohandler_factory->set_environment('nojs');
+ }
+
+ // Set the appropriate input-output handler
+ $this->installer->set_iohandler($this->iohandler_factory->get());
+
+ // Render the intro page
+ if ($this->request->is_ajax())
+ {
+ $installer = $this->installer;
+ $response = new StreamedResponse();
+ $response->setCallback(function() use ($installer) {
+ $installer->run();
+ });
+
+ // Try to bypass any server output buffers
+ $response->headers->set('X-Accel-Buffering', 'no');
+ $response->headers->set('Content-type', 'application/json');
+
+ return $response;
+ }
+ else
+ {
+ $this->controller_helper->handle_language_select();
+
+ // Set active stage
+ $this->menu_provider->set_nav_property(
+ array('update', 0, 'introduction'),
+ array(
+ 'selected' => true,
+ 'completed' => false,
+ )
+ );
+
+ $this->template->assign_vars(array(
+ 'SHOW_INSTALL_START_FORM' => true,
+ 'TITLE' => $this->language->lang('UPDATE_INSTALLATION'),
+ 'CONTENT' => $this->language->lang('UPDATE_INSTALLATION_EXPLAIN'),
+ ));
+
+ /** @var \phpbb\install\helper\iohandler\iohandler_interface $iohandler */
+ $iohandler = $this->iohandler_factory->get();
+ $this->controller_helper->handle_navigation($iohandler);
+
+ return $this->controller_helper->render('installer_update.html', 'UPDATE_INSTALLATION', true);
+ }
+ }
+}
diff --git a/phpBB/phpbb/install/exception/file_updater_failure_exception.php b/phpBB/phpbb/install/exception/file_updater_failure_exception.php
new file mode 100644
index 0000000000..46ba2ed32d
--- /dev/null
+++ b/phpBB/phpbb/install/exception/file_updater_failure_exception.php
@@ -0,0 +1,22 @@
+<?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\install\exception;
+
+/**
+ * Thrown when the file updater fails
+ */
+class file_updater_failure_exception extends installer_exception
+{
+
+}
diff --git a/phpBB/phpbb/install/exception/jump_to_restart_point_exception.php b/phpBB/phpbb/install/exception/jump_to_restart_point_exception.php
new file mode 100644
index 0000000000..b628c4fbe3
--- /dev/null
+++ b/phpBB/phpbb/install/exception/jump_to_restart_point_exception.php
@@ -0,0 +1,44 @@
+<?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\install\exception;
+
+class jump_to_restart_point_exception extends installer_exception
+{
+ /**
+ * @var string
+ */
+ protected $restart_point_name;
+
+ /**
+ * Constructor
+ *
+ * @param string $restart_point_name
+ */
+ public function __construct($restart_point_name)
+ {
+ $this->restart_point_name = $restart_point_name;
+
+ parent::__construct();
+ }
+
+ /**
+ * Returns the restart point's name
+ *
+ * @return string
+ */
+ public function get_restart_point_name()
+ {
+ return $this->restart_point_name;
+ }
+}
diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php
index d5653f1924..0f0840f470 100644
--- a/phpBB/phpbb/install/helper/config.php
+++ b/phpBB/phpbb/install/helper/config.php
@@ -99,6 +99,8 @@ class config
'last_task_name' => '', // Stores the service name of the latest finished task
'max_task_progress' => 0,
'current_task_progress' => 0,
+ '_restart_points' => array(),
+ 'use_restart_point' => false,
);
$this->install_config_file = $this->phpbb_root_path . 'store/install_config.php';
@@ -240,6 +242,56 @@ class config
}
/**
+ * Creates a progress restart point
+ *
+ * Restart points can be used to repeat certain tasks periodically.
+ * You need to call this method from the first task you want to repeat.
+ *
+ * @param string $name Name of the restart point
+ */
+ public function create_progress_restart_point($name)
+ {
+ $tmp_progress_data = $this->progress_data;
+ unset($tmp_progress_data['_restart_points']);
+
+ $this->progress_data['_restart_points'][$name] = $tmp_progress_data;
+ }
+
+ /**
+ * Set restart point to continue from
+ *
+ * @param string $name Name of the restart point
+ *
+ * @return bool Returns false if the restart point name does not exist, otherwise true
+ */
+ public function jump_to_restart_point($name)
+ {
+ if (!isset($this->progress_data['_restart_points'][$name]) || empty($this->progress_data['_restart_points'][$name]))
+ {
+ return false;
+ }
+
+ foreach ($this->progress_data['_restart_points'][$name] as $key => $value)
+ {
+ $this->progress_data[$key] = $value;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns whether a restart point with a given name exists or not
+ *
+ * @param string $name Name of the restart point
+ *
+ * @return bool
+ */
+ public function has_restart_point($name)
+ {
+ return isset($this->progress_data['_restart_points'][$name]);
+ }
+
+ /**
* Dumps install configuration to disk
*/
public function save_config()
diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php
index dc0eef6485..6c1ecd2d02 100644
--- a/phpBB/phpbb/install/helper/container_factory.php
+++ b/phpBB/phpbb/install/helper/container_factory.php
@@ -15,10 +15,17 @@ namespace phpbb\install\helper;
use phpbb\cache\driver\dummy;
use phpbb\install\exception\cannot_build_container_exception;
+use phpbb\language\language;
+use phpbb\request\request;
class container_factory
{
/**
+ * @var language
+ */
+ protected $language;
+
+ /**
* @var string
*/
protected $phpbb_root_path;
@@ -34,6 +41,11 @@ class container_factory
protected $request;
/**
+ * @var update_helper
+ */
+ protected $update_helper;
+
+ /**
* The full phpBB container
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
@@ -43,13 +55,17 @@ class container_factory
/**
* Constructor
*
- * @param \phpbb\request\request $request Request interface
- * @param string $phpbb_root_path Path to phpBB's root
- * @param string $php_ext Extension of PHP files
+ * @param language $language Language service
+ * @param request $request Request interface
+ * @param update_helper $update_helper Update helper
+ * @param string $phpbb_root_path Path to phpBB's root
+ * @param string $php_ext Extension of PHP files
*/
- public function __construct(\phpbb\request\request $request, $phpbb_root_path, $php_ext)
+ public function __construct(language $language, request $request, update_helper $update_helper, $phpbb_root_path, $php_ext)
{
+ $this->language = $language;
$this->request = $request;
+ $this->update_helper = $update_helper;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
$this->container = null;
@@ -124,7 +140,7 @@ class container_factory
$phpbb_container_builder = new \phpbb\di\container_builder($this->phpbb_root_path, $this->php_ext);
// For BC with functions that we need during install
- global $phpbb_container;
+ global $phpbb_container, $table_prefix;
$disable_super_globals = $this->request->super_globals_disabled();
@@ -134,8 +150,13 @@ class container_factory
$this->request->enable_super_globals();
}
- $this->container = $phpbb_container = $phpbb_container_builder
+ $other_config_path = $this->phpbb_root_path . 'install/update/new/config';
+ $config_path = (is_dir($other_config_path)) ? $other_config_path : $this->phpbb_root_path . 'config';
+
+ $this->container = $phpbb_container_builder
+ ->with_environment('production')
->with_config($phpbb_config_php_file)
+ ->with_config_path($config_path)
->without_cache()
->without_compiled_container()
->get_container();
@@ -145,18 +166,29 @@ class container_factory
$this->container->register('request')->setSynthetic(true);
$this->container->set('request', $this->request);
- // Replace cache service, as config gets cached, and we don't want that
- $this->container->register('cache.driver')->setSynthetic(true);
- $this->container->set('cache.driver', new dummy());
+ $this->container->register('language')->setSynthetic(true);
+ $this->container->set('language', $this->language);
+
+ // Replace cache service, as config gets cached, and we don't want that when we are installing
+ if (!is_dir($other_config_path))
+ {
+ $this->container->register('cache.driver')->setSynthetic(true);
+ $this->container->set('cache.driver', new dummy());
+ }
+
$this->container->compile();
+ $phpbb_container = $this->container;
+ $table_prefix = $phpbb_config_php_file->get('table_prefix');
+
// Restore super globals to previous state
if ($disable_super_globals)
{
$this->request->disable_super_globals();
}
- // Get compatibilty globals
- require ($this->phpbb_root_path . 'includes/compatibility_globals.' . $this->php_ext);
+ // Get compatibilty globals and constants
+ $this->update_helper->include_file('includes/compatibility_globals.' . $this->php_ext);
+ $this->update_helper->include_file('includes/constants.' . $this->php_ext);
}
}
diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php
index 627e9ea9b0..c4c90a01a4 100644
--- a/phpBB/phpbb/install/helper/database.php
+++ b/phpBB/phpbb/install/helper/database.php
@@ -338,7 +338,7 @@ class database
$db->sql_return_on_error(true);
// Check that we actually have a database name before going any further
- if (!in_array($dbms_info['SCHEMA'], array('sqlite', 'oracle')) && $dbname === '')
+ if (!in_array($dbms_info['SCHEMA'], array('sqlite', 'oracle'), true) && $dbname === '')
{
$errors[] = array(
'title' => 'INST_ERR_DB_NO_NAME',
diff --git a/phpBB/phpbb/install/helper/file_updater/compression_file_updater.php b/phpBB/phpbb/install/helper/file_updater/compression_file_updater.php
new file mode 100644
index 0000000000..ede992fb6e
--- /dev/null
+++ b/phpBB/phpbb/install/helper/file_updater/compression_file_updater.php
@@ -0,0 +1,133 @@
+<?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\install\helper\file_updater;
+
+use phpbb\install\helper\update_helper;
+
+/**
+ * File updater for generating archive with updated files
+ */
+class compression_file_updater implements file_updater_interface
+{
+ /**
+ * @var \compress
+ */
+ protected $compress;
+
+ /**
+ * @var update_helper
+ */
+ protected $update_helper;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * @var string
+ */
+ protected $php_ext;
+
+ /**
+ * Constructor
+ *
+ * @param update_helper $update_helper
+ * @param string $phpbb_root_path
+ * @param string $php_ext
+ */
+ public function __construct(update_helper $update_helper, $phpbb_root_path, $php_ext)
+ {
+ $this->compress = null;
+ $this->update_helper = $update_helper;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ }
+
+ /**
+ * Set the compression method
+ *
+ * @param string $method Compression method's file extension
+ *
+ * @return string Archive's filename
+ */
+ public function init($method)
+ {
+ $this->update_helper->include_file('includes/functions_compress.' . $this->php_ext);
+
+ $archive_filename = 'update_archive_' . time() . '_' . uniqid();
+ $path = $this->phpbb_root_path . 'store/' . $archive_filename . '' . $method;
+
+ if ($method === '.zip')
+ {
+ $this->compress = new \compress_zip('w', $path);
+ }
+ else
+ {
+ $this->compress = new \compress_tar('w', $path, $method);
+ }
+
+ return $path;
+ }
+
+ /**
+ * Close archive writing process
+ */
+ public function close()
+ {
+ $this->compress->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete_file($path_to_file)
+ {
+ // We do absolutely nothing here, as this function is called when a file should be
+ // removed from the filesystem, but since this is an archive generator, it clearly
+ // cannot do that.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function create_new_file($path_to_file_to_create, $source, $create_from_content = false)
+ {
+ if ($create_from_content)
+ {
+ $this->compress->add_data($source, $path_to_file_to_create);
+ }
+ else
+ {
+ $this->compress->add_custom_file($source, $path_to_file_to_create);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function update_file($path_to_file_to_update, $source, $create_from_content = false)
+ {
+ // Both functions are identical here
+ $this->create_new_file($path_to_file_to_update, $source, $create_from_content);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_method_name()
+ {
+ return 'compression';
+ }
+}
diff --git a/phpBB/phpbb/install/helper/file_updater/factory.php b/phpBB/phpbb/install/helper/file_updater/factory.php
new file mode 100644
index 0000000000..d3a2f22782
--- /dev/null
+++ b/phpBB/phpbb/install/helper/file_updater/factory.php
@@ -0,0 +1,69 @@
+<?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\install\helper\file_updater;
+
+use phpbb\di\service_collection;
+use phpbb\install\exception\file_updater_failure_exception;
+
+/**
+ * File updater factory
+ */
+class factory
+{
+ /**
+ * @var array
+ */
+ protected $file_updaters;
+
+ /**
+ * Constructor
+ *
+ * @param service_collection $collection File updater service collection
+ */
+ public function __construct(service_collection $collection)
+ {
+ foreach ($collection as $service)
+ {
+ $this->register($service);
+ }
+ }
+
+ /**
+ * Register updater object
+ *
+ * @param file_updater_interface $updater Updater object
+ */
+ public function register(file_updater_interface $updater)
+ {
+ $name = $updater->get_method_name();
+ $this->file_updaters[$name] = $updater;
+ }
+
+ /**
+ * Returns file updater object
+ *
+ * @param string $name Name of the updater method
+ *
+ * @throws file_updater_failure_exception When the specified file updater does not exist
+ */
+ public function get($name)
+ {
+ if (!isset($this->file_updaters[$name]))
+ {
+ throw new file_updater_failure_exception();
+ }
+
+ return $this->file_updaters[$name];
+ }
+}
diff --git a/phpBB/phpbb/install/helper/file_updater/file_updater.php b/phpBB/phpbb/install/helper/file_updater/file_updater.php
new file mode 100644
index 0000000000..cc0f5c6b5f
--- /dev/null
+++ b/phpBB/phpbb/install/helper/file_updater/file_updater.php
@@ -0,0 +1,202 @@
+<?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\install\helper\file_updater;
+
+use phpbb\filesystem\exception\filesystem_exception;
+use phpbb\filesystem\filesystem;
+use phpbb\install\exception\file_updater_failure_exception;
+
+/**
+ * File updater for direct filesystem access
+ */
+class file_updater implements file_updater_interface
+{
+ /**
+ * @var filesystem
+ */
+ protected $filesystem;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * Constructor
+ *
+ * @param filesystem $filesystem
+ * @param string $phpbb_root_path
+ */
+ public function __construct(filesystem $filesystem, $phpbb_root_path)
+ {
+ $this->filesystem = $filesystem;
+ $this->phpbb_root_path = $phpbb_root_path;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws file_updater_failure_exception When the file is not writable
+ * @throws filesystem_exception When the filesystem class fails
+ */
+ public function delete_file($path_to_file)
+ {
+ $this->filesystem->remove($this->phpbb_root_path . $path_to_file);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws file_updater_failure_exception When the file is not writable
+ * @throws filesystem_exception When the filesystem class fails
+ */
+ public function create_new_file($path_to_file_to_create, $source, $create_from_content = false)
+ {
+ $path_to_file_to_create = $this->phpbb_root_path . $path_to_file_to_create;
+
+ $dir = dirname($path_to_file_to_create);
+ if (!$this->filesystem->exists($dir))
+ {
+ $this->make_dir($dir);
+ }
+
+ $original_dir_perms = false;
+
+ if (!$this->filesystem->is_writable($dir))
+ {
+ // Extract last 9 bits we actually need
+ $original_dir_perms = @fileperms($dir) & 511;
+ $this->filesystem->phpbb_chmod($dir, filesystem::CHMOD_ALL);
+ }
+
+ if (!$create_from_content)
+ {
+ try
+ {
+ $this->filesystem->copy($source, $path_to_file_to_create);
+ }
+ catch (filesystem_exception $e)
+ {
+ $this->write_file($path_to_file_to_create, $source, $create_from_content);
+ }
+ }
+ else
+ {
+ $this->write_file($path_to_file_to_create, $source, $create_from_content);
+ }
+
+ if ($original_dir_perms !== false)
+ {
+ $this->filesystem->phpbb_chmod($dir, $original_dir_perms);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws file_updater_failure_exception When the file is not writable
+ * @throws filesystem_exception When the filesystem class fails
+ */
+ public function update_file($path_to_file_to_update, $source, $create_from_content = false)
+ {
+ $path_to_file_to_update = $this->phpbb_root_path . $path_to_file_to_update;
+ $original_file_perms = false;
+
+ // Maybe necessary for binary files
+ $dir = dirname($path_to_file_to_update);
+ if (!$this->filesystem->exists($dir))
+ {
+ $this->make_dir($dir);
+ }
+
+ if (!$this->filesystem->is_writable($path_to_file_to_update))
+ {
+ // Extract last 9 bits we actually need
+ $original_file_perms = @fileperms($path_to_file_to_update) & 511;
+ $this->filesystem->phpbb_chmod($path_to_file_to_update, filesystem::CHMOD_WRITE);
+ }
+
+ if (!$create_from_content)
+ {
+ try
+ {
+ $this->filesystem->copy($source, $path_to_file_to_update, true);
+ }
+ catch (filesystem_exception $e)
+ {
+ $this->write_file($path_to_file_to_update, $source, $create_from_content);
+ }
+ }
+ else
+ {
+ $this->write_file($path_to_file_to_update, $source, $create_from_content);
+ }
+
+ if ($original_file_perms !== false)
+ {
+ $this->filesystem->phpbb_chmod($path_to_file_to_update, $original_file_perms);
+ }
+ }
+
+ /**
+ * Creates directory structure
+ *
+ * @param string $path Path to the directory where the file should be placed (and non-existent)
+ */
+ private function make_dir($path)
+ {
+ if (is_dir($path))
+ {
+ return;
+ }
+
+ $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
+ $this->filesystem->mkdir($path, 493); // 493 === 0755
+ }
+
+ /**
+ * Fallback function for file writing
+ *
+ * @param string $path_to_file Path to the file's location
+ * @param string $source Path to file to copy or string with the new file's content
+ * @param bool|false $create_from_content Whether or not to use $source as the content, false by default
+ *
+ * @throws file_updater_failure_exception When the file is not writable
+ */
+ private function write_file($path_to_file, $source, $create_from_content = false)
+ {
+ if (!$create_from_content)
+ {
+ $source = @file_get_contents($source);
+ }
+
+ $file_pointer = @fopen($path_to_file, 'w');
+
+ if (!is_resource($file_pointer))
+ {
+ throw new file_updater_failure_exception();
+ }
+
+ @fwrite($file_pointer, $source);
+ @fclose($file_pointer);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_method_name()
+ {
+ return 'direct_file';
+ }
+}
diff --git a/phpBB/phpbb/install/helper/file_updater/file_updater_interface.php b/phpBB/phpbb/install/helper/file_updater/file_updater_interface.php
new file mode 100644
index 0000000000..b13d7c9fe1
--- /dev/null
+++ b/phpBB/phpbb/install/helper/file_updater/file_updater_interface.php
@@ -0,0 +1,49 @@
+<?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\install\helper\file_updater;
+
+interface file_updater_interface
+{
+ /**
+ * Deletes a file
+ *
+ * @param string $path_to_file Path to the file to delete
+ */
+ public function delete_file($path_to_file);
+
+ /**
+ * Creates a new file
+ *
+ * @param string $path_to_file_to_create Path to the new file's location
+ * @param string $source Path to file to copy or string with the new file's content
+ * @param bool $create_from_content Whether or not to use $source as the content, false by default
+ */
+ public function create_new_file($path_to_file_to_create, $source, $create_from_content = false);
+
+ /**
+ * Update file
+ *
+ * @param string $path_to_file_to_update Path to the file's location
+ * @param string $source Path to file to copy or string with the new file's content
+ * @param bool $create_from_content Whether or not to use $source as the content, false by default
+ */
+ public function update_file($path_to_file_to_update, $source, $create_from_content = false);
+
+ /**
+ * Returns the name of the file updater method
+ *
+ * @return string
+ */
+ public function get_method_name();
+}
diff --git a/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php b/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php
new file mode 100644
index 0000000000..258a035768
--- /dev/null
+++ b/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php
@@ -0,0 +1,136 @@
+<?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\install\helper\file_updater;
+
+use phpbb\install\helper\update_helper;
+
+/**
+ * File updater for FTP updates
+ */
+class ftp_file_updater implements file_updater_interface
+{
+ /**
+ * @var \transfer
+ */
+ protected $transfer;
+
+ /**
+ * @var update_helper
+ */
+ protected $update_helper;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * @var string
+ */
+ protected $php_ext;
+
+ /**
+ * Constructor
+ *
+ * @param update_helper $update_helper
+ * @param string $phpbb_root_path
+ * @param string $php_ext
+ */
+ public function __constructor(update_helper $update_helper, $phpbb_root_path, $php_ext)
+ {
+ $this->transfer = null;
+ $this->update_helper = $update_helper;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ }
+
+ /**
+ * Initialize FTP connection
+ *
+ * @param string $method
+ * @param string $host
+ * @param string $user
+ * @param string $pass
+ * @param string $path
+ * @param int $port
+ * @param int $timeout
+ */
+ public function init($method, $host, $user, $pass, $path, $port, $timeout)
+ {
+ $this->update_helper->include_file('includes/functions_transfer.' . $this->php_ext);
+ $this->transfer = new $method($host, $user, $pass, $path, $port, $timeout);
+ $this->transfer->open_session();
+ }
+
+ /**
+ * Close FTP session
+ */
+ public function close()
+ {
+ $this->transfer->close_session();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete_file($path_to_file)
+ {
+ $this->transfer->delete_file($path_to_file);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function create_new_file($path_to_file_to_create, $source, $create_from_content = false)
+ {
+ $dirname = dirname($path_to_file_to_create);
+
+ if ($dirname && !file_exists($this->phpbb_root_path . $dirname))
+ {
+ $this->transfer->make_dir($dirname);
+ }
+
+ if ($create_from_content)
+ {
+ $this->transfer->write_file($path_to_file_to_create, $source);
+ }
+ else
+ {
+ $this->transfer->copy_file($path_to_file_to_create, $source);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function update_file($path_to_file_to_update, $source, $create_from_content = false)
+ {
+ if ($create_from_content)
+ {
+ $this->transfer->write_file($path_to_file_to_update, $source);
+ }
+ else
+ {
+ $this->transfer->copy_file($path_to_file_to_update, $source);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_method_name()
+ {
+ return 'ftp';
+ }
+}
diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php
index fa628f3365..1342ffa30f 100644
--- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php
+++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php
@@ -13,12 +13,20 @@
namespace phpbb\install\helper\iohandler;
+use phpbb\path_helper;
+use phpbb\routing\router;
+
/**
* Input-Output handler for the AJAX frontend
*/
class ajax_iohandler extends iohandler_base
{
/**
+ * @var path_helper
+ */
+ protected $path_helper;
+
+ /**
* @var \phpbb\request\request_interface
*/
protected $request;
@@ -29,6 +37,16 @@ class ajax_iohandler extends iohandler_base
protected $template;
/**
+ * @var router
+ */
+ protected $router;
+
+ /**
+ * @var string
+ */
+ protected $file_status;
+
+ /**
* @var string
*/
protected $form;
@@ -49,18 +67,29 @@ class ajax_iohandler extends iohandler_base
protected $cookies;
/**
+ * @var array
+ */
+ protected $download;
+
+ /**
* Constructor
*
+ * @param path_helper $path_helper
* @param \phpbb\request\request_interface $request HTTP request interface
* @param \phpbb\template\template $template Template engine
+ * @param router $router Router
*/
- public function __construct(\phpbb\request\request_interface $request, \phpbb\template\template $template)
+ public function __construct(path_helper $path_helper, \phpbb\request\request_interface $request, \phpbb\template\template $template, router $router)
{
+ $this->path_helper = $path_helper;
$this->request = $request;
+ $this->router = $router;
$this->template = $template;
$this->form = '';
$this->nav_data = array();
$this->cookies = array();
+ $this->download = array();
+ $this->file_status = '';
parent::__construct();
}
@@ -102,13 +131,13 @@ class ajax_iohandler extends iohandler_base
*/
public function add_user_form_group($title, $form)
{
- $this->template->assign_var('S_FORM_ELEM_COUNT', sizeof($form));
-
$this->template->assign_block_vars('options', array(
'LEGEND' => $this->language->lang($title),
'S_LEGEND' => true,
));
+ $not_button_form = false;
+
foreach ($form as $input_name => $input_options)
{
if (!isset($input_options['type']))
@@ -117,6 +146,7 @@ class ajax_iohandler extends iohandler_base
}
$tpl_ary = array();
+ $not_button_form = ($input_options['type'] !== 'submit' || $not_button_form);
$tpl_ary['TYPE'] = $input_options['type'];
$tpl_ary['TITLE'] = $this->language->lang($input_options['label']);
@@ -136,7 +166,7 @@ class ajax_iohandler extends iohandler_base
$tpl_ary['S_EXPLAIN'] = true;
}
- if (in_array($input_options['type'], array('select', 'radio')))
+ if (in_array($input_options['type'], array('select', 'radio'), true))
{
for ($i = 0, $total = sizeof($input_options['options']); $i < $total; $i++)
{
@@ -149,9 +179,12 @@ class ajax_iohandler extends iohandler_base
$tpl_ary['OPTIONS'] = $input_options['options'];
}
- $this->template->assign_block_vars('options', $tpl_ary);
+ $block_name = ($input_options['type'] === 'submit') ? 'submit_buttons' : 'options';
+ $this->template->assign_block_vars($block_name, $tpl_ary);
}
+ $this->template->assign_var('S_NOT_ONLY_BUTTON_FORM', $not_button_form);
+
$this->template->set_filenames(array(
'form_install' => 'installer_form.html',
));
@@ -185,14 +218,27 @@ class ajax_iohandler extends iohandler_base
'warnings' => $this->warnings,
'logs' => $this->logs,
'success' => $this->success,
+ 'download' => $this->download,
);
+ $this->errors = array();
+ $this->warnings = array();
+ $this->logs = array();
+ $this->success = array();
+ $this->download = array();
+
if (!empty($this->form))
{
$json_array['form'] = $this->form;
$this->form = '';
}
+ if (!empty($this->file_status))
+ {
+ $json_array['file_status'] = $this->file_status;
+ $this->file_status = '';
+ }
+
// If current task name is set, we push progress message to the client side
if (!empty($this->current_task_name))
{
@@ -201,19 +247,20 @@ class ajax_iohandler extends iohandler_base
'task_num' => $this->current_task_progress,
'task_count' => $this->task_progress_count,
);
+
+ if ($this->restart_progress_bar)
+ {
+ $json_array['progress']['restart'] = 1;
+ $this->restart_progress_bar = false;
+ }
}
if (!empty($this->nav_data))
{
$json_array['nav'] = $this->nav_data;
+ $this->nav_data = array();
}
- $this->errors = array();
- $this->warnings = array();
- $this->logs = array();
- $this->success = array();
- $this->nav_data = array();
-
if ($this->request_client_refresh)
{
$json_array['refresh'] = true;
@@ -276,6 +323,56 @@ class ajax_iohandler extends iohandler_base
}
/**
+ * {@inheritdoc}
+ */
+ public function add_download_link($route, $title, $msg = null)
+ {
+ $link_properties = array(
+ 'href' => $this->router->generate($route),
+ 'title' => $this->language->lang($title),
+ 'download' => $this->language->lang('DOWNLOAD'),
+ );
+
+ if ($msg !== null)
+ {
+ $link_properties['msg'] = htmlspecialchars_decode($this->language->lang($msg));
+ }
+
+ $this->download[] = $link_properties;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render_update_file_status($status_array)
+ {
+ $this->template->assign_vars(array(
+ 'T_IMAGE_PATH' => $this->path_helper->get_web_root_path() . 'adm/images/',
+ ));
+
+ foreach ($status_array as $block => $list)
+ {
+ foreach ($list as $filename)
+ {
+ $dirname = dirname($filename);
+
+ $this->template->assign_block_vars($block, array(
+ 'STATUS' => $block,
+ 'FILENAME' => $filename,
+ 'DIR_PART' => (!empty($dirname) && $dirname !== '.') ? dirname($filename) . '/' : false,
+ 'FILE_PART' => basename($filename),
+ ));
+ }
+ }
+
+ $this->template->set_filenames(array(
+ 'file_status' => 'installer_update_file_status.html',
+ ));
+
+ $this->file_status = $this->template->assign_display('file_status');
+ }
+
+ /**
* Callback function for language replacing
*
* @param array $matches
diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php
index c5b2bb06bc..abdd730d2e 100644
--- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php
+++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php
@@ -181,9 +181,12 @@ class cli_iohandler extends iohandler_base
}
}
- public function set_task_count($task_count)
+ /**
+ * {@inheritdoc}
+ */
+ public function set_task_count($task_count, $restart = false)
{
- parent::set_task_count($task_count);
+ parent::set_task_count($task_count, $restart);
if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL)
{
@@ -206,6 +209,9 @@ class cli_iohandler extends iohandler_base
}
}
+ /**
+ * {@inheritdoc}
+ */
public function set_progress($task_lang_key, $task_number)
{
parent::set_progress($task_lang_key, $task_number);
@@ -262,4 +268,18 @@ class cli_iohandler extends iohandler_base
public function set_cookie($cookie_name, $cookie_value)
{
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function add_download_link($route, $title, $msg = null)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render_update_file_status($status_array)
+ {
+ }
}
diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php
index 006411f1e3..530cb4766b 100644
--- a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php
+++ b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php
@@ -80,6 +80,7 @@ abstract class iohandler_base implements iohandler_interface
$this->logs = array();
$this->success = array();
+ $this->restart_progress_bar = false;
$this->task_progress_count = 0;
$this->current_task_progress = 0;
$this->current_task_name = '';
@@ -130,9 +131,10 @@ abstract class iohandler_base implements iohandler_interface
/**
* {@inheritdoc}
*/
- public function set_task_count($task_count)
+ public function set_task_count($task_count, $restart = false)
{
$this->task_progress_count = $task_count;
+ $this->restart_progress_bar = $restart;
}
/**
diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php
index 5f5f8499d6..00aab3283e 100644
--- a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php
+++ b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php
@@ -127,8 +127,9 @@ interface iohandler_interface
* Sets the number of tasks belonging to the installer in the current mode.
*
* @param int $task_count Number of tasks
+ * @param bool $restart Whether or not to restart the progress bar, false by default
*/
- public function set_task_count($task_count);
+ public function set_task_count($task_count, $restart = false);
/**
* Sets the progress information
@@ -165,6 +166,22 @@ interface iohandler_interface
public function finish_progress($message_lang_key);
/**
+ * Adds a download link
+ *
+ * @param string $route Route for the link
+ * @param string $title Language key for the title
+ * @param string|null|array $msg Language key for the message
+ */
+ public function add_download_link($route, $title, $msg = null);
+
+ /**
+ * Renders the status of update files
+ *
+ * @param array $status_array Array containing files in groups to render
+ */
+ public function render_update_file_status($status_array);
+
+ /**
* Sends and sets cookies
*
* @param string $cookie_name Name of the cookie to set
diff --git a/phpBB/phpbb/install/helper/navigation/update_navigation.php b/phpBB/phpbb/install/helper/navigation/update_navigation.php
new file mode 100644
index 0000000000..3d239c3451
--- /dev/null
+++ b/phpBB/phpbb/install/helper/navigation/update_navigation.php
@@ -0,0 +1,80 @@
+<?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\install\helper\navigation;
+
+use phpbb\install\helper\install_helper;
+
+class update_navigation implements navigation_interface
+{
+ /**
+ * @var install_helper
+ */
+ private $install_helper;
+
+ /**
+ * Constructor
+ *
+ * @param install_helper $install_helper
+ */
+ public function __construct(install_helper $install_helper)
+ {
+ $this->install_helper = $install_helper;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get()
+ {
+ if (!$this->install_helper->is_phpbb_installed())
+ {
+ return array();
+ }
+
+ return array(
+ 'update' => array(
+ 'label' => 'UPDATE',
+ 'route' => 'phpbb_installer_update',
+ 'order' => 1,
+ array(
+ 'introduction' => array(
+ 'label' => 'INTRODUCTION_TITLE',
+ 'stage' => true,
+ 'order' => 0,
+ ),
+ 'requirements' => array(
+ 'label' => 'STAGE_REQUIREMENTS',
+ 'stage' => true,
+ 'order' => 1,
+ ),
+ 'obtain_data' => array(
+ 'label' => 'STAGE_OBTAIN_DATA',
+ 'stage' => true,
+ 'order' => 2,
+ ),
+ 'update_files' => array(
+ 'label' => 'STAGE_UPDATE_FILES',
+ 'stage' => true,
+ 'order' => 3,
+ ),
+ 'update_database' => array(
+ 'label' => 'STAGE_UPDATE_DATABASE',
+ 'stage' => true,
+ 'order' => 4,
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/phpBB/phpbb/install/helper/update_helper.php b/phpBB/phpbb/install/helper/update_helper.php
new file mode 100644
index 0000000000..a00731d317
--- /dev/null
+++ b/phpBB/phpbb/install/helper/update_helper.php
@@ -0,0 +1,113 @@
+<?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\install\helper;
+
+/**
+ * General helper functionality for the updater
+ */
+class update_helper
+{
+ /**
+ * @var string
+ */
+ protected $path_to_new_files;
+
+ /**
+ * @var string
+ */
+ protected $path_to_old_files;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * Constructor
+ *
+ * @param string $phpbb_root_path
+ */
+ public function __construct($phpbb_root_path)
+ {
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->path_to_new_files = $phpbb_root_path . 'install/update/new/';
+ $this->path_to_old_files = $phpbb_root_path . 'install/update/old/';
+ }
+
+ /**
+ * Returns path to new update files
+ *
+ * @return string
+ */
+ public function get_path_to_new_update_files()
+ {
+ return $this->path_to_new_files;
+ }
+
+ /**
+ * Returns path to new update files
+ *
+ * @return string
+ */
+ public function get_path_to_old_update_files()
+ {
+ return $this->path_to_old_files;
+ }
+
+ /**
+ * Includes the updated file if available
+ *
+ * @param string $filename Path to the file relative to phpBB root path
+ */
+ public function include_file($filename)
+ {
+ if (is_file($this->path_to_new_files . $filename))
+ {
+ include_once($this->path_to_new_files . $filename);
+ }
+ else if (is_file($this->phpbb_root_path . $filename))
+ {
+ include_once($this->phpbb_root_path . $filename);
+ }
+ }
+
+ /**
+ * Customized version_compare()
+ *
+ * @param string $version_number1
+ * @param string $version_number2
+ * @param string|null $operator
+ * @return int|bool The returned value is identical to the PHP build-in function version_compare()
+ */
+ public function phpbb_version_compare($version_number1, $version_number2, $operator = null)
+ {
+ if ($operator === null)
+ {
+ $result = version_compare(
+ str_replace('rc', 'RC', strtolower($version_number1)),
+ str_replace('rc', 'RC', strtolower($version_number2))
+ );
+ }
+ else
+ {
+ $result = version_compare(
+ str_replace('rc', 'RC', strtolower($version_number1)),
+ str_replace('rc', 'RC', strtolower($version_number2)),
+ $operator
+ );
+ }
+
+ return $result;
+ }
+}
diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php
index 755edb5297..77e0a896bc 100644
--- a/phpBB/phpbb/install/installer.php
+++ b/phpBB/phpbb/install/installer.php
@@ -15,11 +15,13 @@ namespace phpbb\install;
use phpbb\di\ordered_service_collection;
use phpbb\install\exception\installer_config_not_writable_exception;
+use phpbb\install\exception\jump_to_restart_point_exception;
use phpbb\install\exception\resource_limit_reached_exception;
use phpbb\install\exception\user_interaction_required_exception;
use phpbb\install\helper\config;
use phpbb\install\helper\iohandler\cli_iohandler;
use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\path_helper;
class installer
{
@@ -39,6 +41,11 @@ class installer
protected $iohandler;
/**
+ * @var string
+ */
+ protected $web_root;
+
+ /**
* Stores the number of steps that a given module has
*
* @var array
@@ -48,12 +55,14 @@ class installer
/**
* Constructor
*
- * @param config $config Installer config handler
+ * @param config $config Installer config handler
+ * @param path_helper $path_helper Path helper
*/
- public function __construct(config $config)
+ public function __construct(config $config, path_helper $path_helper)
{
$this->install_config = $config;
$this->installer_modules = null;
+ $this->web_root = $path_helper->get_web_root_path();
}
/**
@@ -94,6 +103,7 @@ class installer
// Variable used to check if the install process have been finished
$install_finished = false;
$fail_cleanup = false;
+ $send_refresh = false;
// We are installing something, so the introduction stage can go now...
$this->install_config->set_finished_navigation_stage(array('install', 0, 'introduction'));
@@ -142,7 +152,7 @@ class installer
$this->install_config->set_active_module($name);
// Run until there are available resources
- if ($this->install_config->get_time_remaining() <= 0 && $this->install_config->get_memory_remaining() <= 0)
+ if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0)
{
throw new resource_limit_reached_exception();
}
@@ -181,21 +191,7 @@ class installer
else
{
global $SID;
-
- // Construct ACP url
- $acp_url = $protocol = $this->install_config->get('server_protocol');
- $acp_url .= $this->install_config->get('server_name');
- $port = $this->install_config->get('server_port');
-
- if (!((strpos($protocol, 'https:') === 0 && $port === 443)
- || (strpos($protocol, 'http:') === 0 && $port === 80)))
- {
- $acp_url .= ':' . $port;
- }
-
- $acp_url .= $this->install_config->get('script_path');
- $acp_url .= '/adm/index.php' . $SID;
-
+ $acp_url = $this->web_root . 'adm/index.php' . $SID;
$this->iohandler->add_success_message('INSTALLER_FINISHED', array(
'ACP_LINK',
$acp_url,
@@ -208,7 +204,12 @@ class installer
}
catch (resource_limit_reached_exception $e)
{
- // Do nothing
+ $send_refresh = true;
+ }
+ catch (jump_to_restart_point_exception $e)
+ {
+ $this->install_config->jump_to_restart_point($e->get_restart_point_name());
+ $send_refresh = true;
}
catch (\Exception $e)
{
@@ -222,9 +223,10 @@ class installer
// Send install finished message
$this->iohandler->set_progress('INSTALLER_FINISHED', $this->install_config->get_task_progress_count());
}
- else if (!$fail_cleanup)
+ else if ($send_refresh)
{
$this->iohandler->request_refresh();
+ $this->iohandler->send_response();
}
// Save install progress
diff --git a/phpBB/phpbb/install/module/obtain_data/module.php b/phpBB/phpbb/install/module/obtain_data/install_module.php
index 0e008796c5..deb4be90d8 100644
--- a/phpBB/phpbb/install/module/obtain_data/module.php
+++ b/phpBB/phpbb/install/module/obtain_data/install_module.php
@@ -13,7 +13,7 @@
namespace phpbb\install\module\obtain_data;
-class module extends \phpbb\install\module_base
+class install_module extends \phpbb\install\module_base
{
/**
* {@inheritdoc}
diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php
index b2250e524b..41616e995a 100644
--- a/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php
+++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php
@@ -155,7 +155,7 @@ class obtain_admin_data extends \phpbb\install\task_base implements \phpbb\insta
$data_valid = true;
// Check if none of admin data is empty
- if (in_array('', array($username, $pass1, $pass2, $email)))
+ if (in_array('', array($username, $pass1, $pass2, $email), true))
{
$this->io_handler->add_error_message('INST_ERR_MISSING_DATA');
$data_valid = false;
diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php
index 821c221123..0726cc449c 100644
--- a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php
+++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php
@@ -165,7 +165,7 @@ class obtain_board_data extends \phpbb\install\task_base implements \phpbb\insta
$this->io_handler->add_user_form_group('BOARD_CONFIG', $board_form);
$this->io_handler->send_response();
- throw new user_interaction_required_exception;
+ throw new user_interaction_required_exception();
}
/**
diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php
new file mode 100644
index 0000000000..9bcb73a6a9
--- /dev/null
+++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php
@@ -0,0 +1,168 @@
+<?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\install\module\obtain_data\task;
+
+use phpbb\install\exception\user_interaction_required_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\task_base;
+
+class obtain_file_updater_method extends task_base
+{
+ /**
+ * @var array Supported compression methods
+ *
+ * Note: .tar is assumed to be supported, but not in the list
+ */
+ protected $available_methods;
+
+ /**
+ * @var \phpbb\install\helper\config
+ */
+ protected $installer_config;
+
+ /**
+ * @var \phpbb\install\helper\iohandler\iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * Constructor
+ *
+ * @param config $installer_config
+ * @param iohandler_interface $iohandler
+ */
+ public function __construct(config $installer_config, iohandler_interface $iohandler)
+ {
+ $this->installer_config = $installer_config;
+ $this->iohandler = $iohandler;
+
+ $this->available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib');
+
+ parent::__construct(false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check_requirements()
+ {
+ return $this->installer_config->get('do_update_files', false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ // Check if data is sent
+ if ($this->iohandler->get_input('submit_update_file', false))
+ {
+ $supported_methods = array('compression', 'ftp', 'direct_file');
+ $method = $this->iohandler->get_input('method', 'compression');
+ $update_method = (in_array($method, $supported_methods, true)) ? $method : 'compression';
+ $this->installer_config->set('file_update_method', $update_method);
+
+ $compression = $this->iohandler->get_input('compression_method', '.zip');
+ $supported_methods = array_keys($this->available_methods);
+ $supported_methods[] = '.tar';
+ $compression = (in_array($compression, $supported_methods, true)) ? $compression : '.zip';
+ $this->installer_config->set('file_update_compression', $compression);
+ }
+ else
+ {
+ $this->iohandler->add_user_form_group('UPDATE_FILE_METHOD_TITLE', array(
+ 'method' => array(
+ 'label' => 'UPDATE_FILE_METHOD',
+ 'type' => 'select',
+ 'options' => array(
+ array(
+ 'value' => 'compression',
+ 'label' => 'UPDATE_FILE_METHOD_DOWNLOAD',
+ 'selected' => true,
+ ),
+ array(
+ 'value' => 'ftp',
+ 'label' => 'UPDATE_FILE_METHOD_FTP',
+ 'selected' => false,
+ ),
+ array(
+ 'value' => 'direct_file',
+ 'label' => 'UPDATE_FILE_METHOD_FILESYSTEM',
+ 'selected' => false,
+ ),
+ ),
+ ),
+ 'compression_method' => array(
+ 'label' => 'SELECT_DOWNLOAD_FORMAT',
+ 'type' => 'select',
+ 'options' => $this->get_available_compression_methods(),
+ ),
+ 'submit_update_file' => array(
+ 'label' => 'SUBMIT',
+ 'type' => 'submit',
+ ),
+ ));
+
+ $this->iohandler->send_response();
+ throw new user_interaction_required_exception();
+ }
+ }
+
+ /**
+ * Returns form elements in an array of available compression methods
+ *
+ * @return array
+ */
+ protected function get_available_compression_methods()
+ {
+ $methods[] = array(
+ 'value' => '.tar',
+ 'label' => '.tar',
+ 'selected' => true,
+ );
+
+ foreach ($this->available_methods as $type => $module)
+ {
+ if (!@extension_loaded($module))
+ {
+ continue;
+ }
+
+ $methods[] = array(
+ 'value' => $type,
+ 'label' => $type,
+ 'selected' => false,
+ );
+ }
+
+ return $methods;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_files.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_files.php
new file mode 100644
index 0000000000..0cb809154e
--- /dev/null
+++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_files.php
@@ -0,0 +1,113 @@
+<?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\install\module\obtain_data\task;
+
+use phpbb\install\exception\user_interaction_required_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\task_base;
+
+class obtain_update_files extends task_base
+{
+ /**
+ * @var config
+ */
+ protected $installer_config;
+
+ /**
+ * @var iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * @var string
+ */
+ protected $php_ext;
+
+ /**
+ * Constructor
+ *
+ * @param config $config
+ * @param iohandler_interface $iohandler
+ * @param string $phpbb_root_path
+ * @param string $php_ext
+ */
+ public function __construct(config $config, iohandler_interface $iohandler, $phpbb_root_path, $php_ext)
+ {
+ $this->installer_config = $config;
+ $this->iohandler = $iohandler;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+
+ parent::__construct(false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check_requirements()
+ {
+ return $this->installer_config->get('do_update_files', false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ // Load update info file
+ // The file should be checked in the requirements, so we assume that it exists
+ $update_info_file = $this->phpbb_root_path . 'install/update/index.' . $this->php_ext;
+ include($update_info_file);
+ $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info;
+
+ // If the file is invalid, abort mission
+ if (!$info)
+ {
+ $this->iohandler->add_error_message('WRONG_INFO_FILE_FORMAT');
+ throw new user_interaction_required_exception();
+ }
+
+ // Replace .php with $this->php_ext if needed
+ if ($this->php_ext !== 'php')
+ {
+ $custom_extension = '.' . $this->php_ext;
+ $info['files'] = preg_replace('#\.php$#i', $custom_extension, $info['files']);
+ }
+
+ // Save update info
+ $this->installer_config->set('update_info_unprocessed', $info);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php
new file mode 100644
index 0000000000..a4d362a0f1
--- /dev/null
+++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php
@@ -0,0 +1,164 @@
+<?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\install\module\obtain_data\task;
+
+use phpbb\install\exception\user_interaction_required_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\helper\update_helper;
+use phpbb\install\task_base;
+
+class obtain_update_ftp_data extends task_base
+{
+ /**
+ * @var \phpbb\install\helper\config
+ */
+ protected $installer_config;
+
+ /**
+ * @var \phpbb\install\helper\iohandler\iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * @var update_helper
+ */
+ protected $update_helper;
+
+ /**
+ * @var string
+ */
+ protected $php_ext;
+
+ /**
+ * Constructor
+ *
+ * @param config $installer_config
+ * @param iohandler_interface $iohandler
+ * @param update_helper $update_helper
+ * @param string $php_ext
+ */
+ public function __construct(config $installer_config, iohandler_interface $iohandler, update_helper $update_helper, $php_ext)
+ {
+ $this->installer_config = $installer_config;
+ $this->iohandler = $iohandler;
+ $this->update_helper = $update_helper;
+ $this->php_ext = $php_ext;
+
+ parent::__construct(false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check_requirements()
+ {
+ return ($this->installer_config->get('do_update_files', false) &&
+ ($this->installer_config->get('file_update_method', '') === 'ftp')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ if ($this->iohandler->get_input('submit_ftp', false))
+ {
+ $this->update_helper->include_file('includes/functions_transfer.' . $this->php_ext);
+
+ $method = 'ftp';
+ $methods = \transfer::methods();
+ if (!in_array($method, $methods, true))
+ {
+ $method = $methods[0];
+ }
+
+ $ftp_host = $this->iohandler->get_input('ftp_host', '');
+ $ftp_user = $this->iohandler->get_input('ftp_user', '');
+ $ftp_pass = htmlspecialchars_decode($this->iohandler->get_input('ftp_pass', ''));
+ $ftp_path = $this->iohandler->get_input('ftp_path', '');
+ $ftp_port = $this->iohandler->get_input('ftp_port', 21);
+ $ftp_time = $this->iohandler->get_input('ftp_timeout', 10);
+
+ $this->installer_config->set('ftp_host', $ftp_host);
+ $this->installer_config->set('ftp_user', $ftp_user);
+ $this->installer_config->set('ftp_pass', $ftp_pass);
+ $this->installer_config->set('ftp_path', $ftp_path);
+ $this->installer_config->set('ftp_port', (int) $ftp_port);
+ $this->installer_config->set('ftp_timeout', (int) $ftp_time);
+ $this->installer_config->set('ftp_method', $method);
+ }
+ else
+ {
+ $this->iohandler->add_user_form_group('FTP_SETTINGS', array(
+ 'ftp_host' => array(
+ 'label' => 'FTP_HOST',
+ 'description' => 'FTP_HOST_EXPLAIN',
+ 'type' => 'text',
+ ),
+ 'ftp_user' => array(
+ 'label' => 'FTP_USERNAME',
+ 'description' => 'FTP_USERNAME_EXPLAIN',
+ 'type' => 'text',
+ ),
+ 'ftp_pass' => array(
+ 'label' => 'FTP_PASSWORD',
+ 'description' => 'FTP_PASSWORD_EXPLAIN',
+ 'type' => 'password',
+ ),
+ 'ftp_path' => array(
+ 'label' => 'FTP_ROOT_PATH',
+ 'description' => 'FTP_ROOT_PATH_EXPLAIN',
+ 'type' => 'text',
+ ),
+ 'ftp_port' => array(
+ 'label' => 'FTP_PORT',
+ 'description' => 'FTP_PORT_EXPLAIN',
+ 'type' => 'text',
+ 'default' => 21,
+ ),
+ 'ftp_timeout' => array(
+ 'label' => 'FTP_TIMEOUT',
+ 'description' => 'FTP_TIMEOUT_EXPLAIN',
+ 'type' => 'text',
+ 'default' => 10,
+ ),
+ 'submit_ftp' => array(
+ 'label' => 'SUBMIT',
+ 'type' => 'submit',
+ ),
+ ));
+
+ $this->iohandler->send_response();
+ throw new user_interaction_required_exception();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php
new file mode 100644
index 0000000000..6a98721e77
--- /dev/null
+++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php
@@ -0,0 +1,103 @@
+<?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\install\module\obtain_data\task;
+
+use phpbb\install\exception\user_interaction_required_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\task_base;
+
+class obtain_update_settings extends task_base
+{
+ /**
+ * @var \phpbb\install\helper\config
+ */
+ protected $installer_config;
+
+ /**
+ * @var \phpbb\install\helper\iohandler\iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * Constructor
+ *
+ * @param config $installer_config
+ * @param iohandler_interface $iohandler
+ */
+ public function __construct(config $installer_config, iohandler_interface $iohandler)
+ {
+ $this->installer_config = $installer_config;
+ $this->iohandler = $iohandler;
+
+ parent::__construct(true);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ // Check if data is sent
+ if ($this->iohandler->get_input('submit_update', false))
+ {
+ $update_files = $this->iohandler->get_input('update_type', 'all') === 'all';
+ $this->installer_config->set('do_update_files', $update_files);
+ }
+ else
+ {
+ $this->iohandler->add_user_form_group('UPDATE_TYPE', array(
+ 'update_type' => array(
+ 'label' => 'UPDATE_TYPE',
+ 'type' => 'radio',
+ 'options' => array(
+ array(
+ 'value' => 'all',
+ 'label' => 'UPDATE_TYPE_ALL',
+ 'selected' => true,
+ ),
+ array(
+ 'value' => 'db_only',
+ 'label' => 'UPDATE_TYPE_DB_ONLY',
+ 'selected' => false,
+ ),
+ ),
+ ),
+ 'submit_update' => array(
+ 'label' => 'SUBMIT',
+ 'type' => 'submit',
+ ),
+ ));
+
+ $this->iohandler->send_response();
+ throw new user_interaction_required_exception();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module/obtain_data/update_module.php b/phpBB/phpbb/install/module/obtain_data/update_module.php
new file mode 100644
index 0000000000..c2f9019d34
--- /dev/null
+++ b/phpBB/phpbb/install/module/obtain_data/update_module.php
@@ -0,0 +1,33 @@
+<?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\install\module\obtain_data;
+
+class update_module extends \phpbb\install\module_base
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_navigation_stage_path()
+ {
+ return array('update', 0, 'obtain_data');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_step_count()
+ {
+ return 0;
+ }
+}
diff --git a/phpBB/phpbb/install/module/requirements/module.php b/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php
index 79a031bad9..26593e6777 100644
--- a/phpBB/phpbb/install/module/requirements/module.php
+++ b/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php
@@ -15,8 +15,12 @@ namespace phpbb\install\module\requirements;
use phpbb\install\exception\resource_limit_reached_exception;
use phpbb\install\exception\user_interaction_required_exception;
+use phpbb\install\module_base;
-class module extends \phpbb\install\module_base
+/**
+ * Base class for requirements installer module
+ */
+abstract class abstract_requirements_module extends module_base
{
public function run()
{
@@ -33,7 +37,7 @@ class module extends \phpbb\install\module_base
foreach ($this->task_collection as $name => $task)
{
// Run until there are available resources
- if ($this->install_config->get_time_remaining() <= 0 && $this->install_config->get_memory_remaining() <= 0)
+ if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0)
{
throw new resource_limit_reached_exception();
}
@@ -99,12 +103,4 @@ class module extends \phpbb\install\module_base
{
return 0;
}
-
- /**
- * {@inheritdoc}
- */
- public function get_navigation_stage_path()
- {
- return array('install', 0, 'requirements');
- }
}
diff --git a/phpBB/phpbb/install/module/requirements/install_module.php b/phpBB/phpbb/install/module/requirements/install_module.php
new file mode 100644
index 0000000000..ed0c5fbd94
--- /dev/null
+++ b/phpBB/phpbb/install/module/requirements/install_module.php
@@ -0,0 +1,25 @@
+<?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\install\module\requirements;
+
+class install_module extends abstract_requirements_module
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_navigation_stage_path()
+ {
+ return array('install', 0, 'requirements');
+ }
+}
diff --git a/phpBB/phpbb/install/module/requirements/task/check_filesystem.php b/phpBB/phpbb/install/module/requirements/task/check_filesystem.php
index ab6b1091e2..2aec3915e0 100644
--- a/phpBB/phpbb/install/module/requirements/task/check_filesystem.php
+++ b/phpBB/phpbb/install/module/requirements/task/check_filesystem.php
@@ -50,11 +50,9 @@ class check_filesystem extends \phpbb\install\task_base
* @param \phpbb\install\helper\iohandler\iohandler_interface $response response helper
* @param string $phpbb_root_path relative path to phpBB's root
* @param string $php_ext extension of php files
+ * @param bool $check_config_php Whether or not to check if config.php is writable
*/
- public function __construct(\phpbb\filesystem\filesystem_interface $filesystem,
- \phpbb\install\helper\iohandler\iohandler_interface $response,
- $phpbb_root_path,
- $php_ext)
+ public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, \phpbb\install\helper\iohandler\iohandler_interface $response, $phpbb_root_path, $php_ext, $check_config_php = true)
{
parent::__construct(true);
@@ -87,12 +85,16 @@ class check_filesystem extends \phpbb\install\task_base
'failable' => true,
'is_file' => false,
),
- array(
+ );
+
+ if ($check_config_php)
+ {
+ $this->files_to_check[] = array(
'path' => "config.$php_ext",
'failable' => false,
'is_file' => true,
- ),
- );
+ );
+ }
}
/**
diff --git a/phpBB/phpbb/install/module/requirements/task/check_update.php b/phpBB/phpbb/install/module/requirements/task/check_update.php
new file mode 100644
index 0000000000..c986c76810
--- /dev/null
+++ b/phpBB/phpbb/install/module/requirements/task/check_update.php
@@ -0,0 +1,185 @@
+<?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\install\module\requirements\task;
+
+use phpbb\filesystem\filesystem;
+use phpbb\install\helper\container_factory;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\helper\update_helper;
+use phpbb\install\task_base;
+
+/**
+ * Check the availability of updater files and update version
+ */
+class check_update extends task_base
+{
+ /**
+ * @var \phpbb\config\db
+ */
+ protected $config;
+
+ /**
+ * @var filesystem
+ */
+ protected $filesystem;
+
+ /**
+ * @var iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * @var update_helper
+ */
+ protected $update_helper;
+
+ /**
+ * @var \phpbb\version_helper
+ */
+ protected $version_helper;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * @var string
+ */
+ protected $php_ext;
+
+ /**
+ * @var bool
+ */
+ protected $tests_passed;
+
+ /**
+ * Constructor
+ *
+ * @param container_factory $container
+ * @param filesystem $filesystem
+ * @param iohandler_interface $iohandler
+ * @param update_helper $update_helper
+ * @param string $phpbb_root_path
+ * @param string $php_ext
+ */
+ public function __construct(container_factory $container, filesystem $filesystem, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path, $php_ext)
+ {
+ $this->filesystem = $filesystem;
+ $this->iohandler = $iohandler;
+ $this->update_helper = $update_helper;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ $this->tests_passed = true;
+
+ $this->config = $container->get('config');
+ $this->version_helper = $container->get('version_helper');
+
+ parent::__construct(true);
+ }
+
+ /**
+ * Sets $this->tests_passed
+ *
+ * @param bool $is_passed
+ */
+ protected function set_test_passed($is_passed)
+ {
+ // If one test failed, tests_passed should be false
+ $this->tests_passed = $this->tests_passed && $is_passed;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ // Array of update files
+ $update_files = array(
+ $this->phpbb_root_path . 'install/update',
+ $this->phpbb_root_path . 'install/update/index.' . $this->php_ext,
+ );
+
+ // Check for a valid update directory
+ if (!$this->filesystem->exists($update_files) || !$this->filesystem->is_readable($update_files))
+ {
+ $this->iohandler->add_error_message('UPDATE_FILES_NOT_FOUND');
+ $this->set_test_passed(false);
+
+ // If there are no update files, we can't check the version
+ return false;
+ }
+
+ // Recover version numbers
+ $update_info = array();
+ @include($this->phpbb_root_path . 'install/update/index.' . $this->php_ext);
+ $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info;
+ $update_version = false;
+
+ if ($info !== false)
+ {
+ $update_version = (!empty($info['version']['to'])) ? trim($info['version']['to']) : false;
+ }
+
+ // Get current and latest version
+ try
+ {
+ $latest_version = $this->version_helper->get_latest_on_current_branch(true);
+ }
+ catch (\RuntimeException $e)
+ {
+ $latest_version = $update_version;
+ }
+
+ $current_version = (!empty($this->config['version_update_from'])) ? $this->config['version_update_from'] : $this->config['version'];
+
+ // Check if the update package
+ if (!$this->update_helper->phpbb_version_compare($current_version, $update_version, '<'))
+ {
+ $this->iohandler->add_error_message('NO_UPDATE_FILES_UP_TO_DATE');
+ $this->tests_passed = false;
+ }
+
+ // Check if the update package works with the installed version
+ if (empty($info['version']['from']) || $info['version']['from'] !== $current_version)
+ {
+ $this->iohandler->add_error_message(array('INCOMPATIBLE_UPDATE_FILES', $current_version, $info['version']['from'], $update_version));
+ $this->tests_passed = false;
+ }
+
+ // check if this is the latest update package
+ if ($this->update_helper->phpbb_version_compare($update_version, $latest_version, '<'))
+ {
+ $this->iohandler->add_warning_message(array('OLD_UPDATE_FILES', $info['version']['from'], $update_version, $latest_version));
+ }
+
+ return $this->tests_passed;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module/requirements/update_module.php b/phpBB/phpbb/install/module/requirements/update_module.php
new file mode 100644
index 0000000000..223d12faf3
--- /dev/null
+++ b/phpBB/phpbb/install/module/requirements/update_module.php
@@ -0,0 +1,25 @@
+<?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\install\module\requirements;
+
+class update_module extends abstract_requirements_module
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_navigation_stage_path()
+ {
+ return array('update', 0, 'requirements');
+ }
+}
diff --git a/phpBB/phpbb/install/module/update_database/module.php b/phpBB/phpbb/install/module/update_database/module.php
new file mode 100644
index 0000000000..ee38afe17d
--- /dev/null
+++ b/phpBB/phpbb/install/module/update_database/module.php
@@ -0,0 +1,33 @@
+<?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\install\module\update_database;
+
+class module extends \phpbb\install\module_base
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_navigation_stage_path()
+ {
+ return array('update', 0, 'update_database');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_step_count()
+ {
+ return 0;
+ }
+}
diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php
new file mode 100644
index 0000000000..2d640134a3
--- /dev/null
+++ b/phpBB/phpbb/install/module/update_database/task/update.php
@@ -0,0 +1,212 @@
+<?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\install\module\update_database\task;
+
+use phpbb\db\migration\exception;
+use phpbb\db\output_handler\installer_migrator_output_handler;
+use phpbb\db\output_handler\log_wrapper_migrator_output_handler;
+use phpbb\install\exception\resource_limit_reached_exception;
+use phpbb\install\exception\user_interaction_required_exception;
+use phpbb\install\task_base;
+
+/**
+ * Database updater task
+ */
+class update extends task_base
+{
+ /**
+ * @var \phpbb\cache\driver\driver_interface
+ */
+ protected $cache;
+
+ /**
+ * @var \phpbb\config\config
+ */
+ protected $config;
+
+ /**
+ * @var \phpbb\extension\manager
+ */
+ protected $extension_manager;
+
+ /**
+ * @var \phpbb\filesystem\filesystem
+ */
+ protected $filesystem;
+
+ /**
+ * @var \phpbb\install\helper\config
+ */
+ protected $installer_config;
+
+ /**
+ * @var \phpbb\install\helper\iohandler\iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * @var \phpbb\language\language
+ */
+ protected $language;
+
+ /**
+ * @var \phpbb\log\log
+ */
+ protected $log;
+
+ /**
+ * @var \phpbb\db\migrator
+ */
+ protected $migrator;
+
+ /**
+ * @var \phpbb\user
+ */
+ protected $user;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\install\helper\container_factory $container
+ * @param \phpbb\filesystem\filesystem $filesystem
+ * @param \phpbb\install\helper\config $installer_config
+ * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler
+ * @param \phpbb\language\language $language
+ * @param string $phpbb_root_path
+ */
+ public function __construct(\phpbb\install\helper\container_factory $container, \phpbb\filesystem\filesystem $filesystem, \phpbb\install\helper\config $installer_config, \phpbb\install\helper\iohandler\iohandler_interface $iohandler, \phpbb\language\language $language, $phpbb_root_path)
+ {
+ $this->filesystem = $filesystem;
+ $this->installer_config = $installer_config;
+ $this->iohandler = $iohandler;
+ $this->language = $language;
+ $this->phpbb_root_path = $phpbb_root_path;
+
+ $this->cache = $container->get('cache.driver');
+ $this->config = $container->get('config');
+ $this->extension_manager = $container->get('ext.manager');
+ $this->log = $container->get('log');
+ $this->migrator = $container->get('migrator');
+ $this->user = $container->get('user');
+
+ parent::__construct(true);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ $this->language->add_lang('migrator');
+
+ if (!isset($this->config['version_update_from']))
+ {
+ $this->config->set('version_update_from', $this->config['version']);
+ }
+
+ $original_version = $this->config['version_update_from'];
+
+ $this->migrator->set_output_handler(
+ new log_wrapper_migrator_output_handler(
+ $this->language,
+ new installer_migrator_output_handler($this->iohandler),
+ $this->phpbb_root_path . 'store/migrations_' . time() . '.log',
+ $this->filesystem
+ )
+ );
+
+ $this->migrator->create_migrations_table();
+
+ $migrations = $this->extension_manager
+ ->get_finder()
+ ->core_path('phpbb/db/migration/data/')
+ ->extension_directory('/migrations')
+ ->get_classes();
+
+ $this->migrator->set_migrations($migrations);
+ $migration_count = count($migrations);
+ $this->iohandler->set_task_count($migration_count, true);
+ $progress_count = $this->installer_config->get('database_update_count', 0);
+
+ while (!$this->migrator->finished())
+ {
+ try
+ {
+ $this->migrator->update();
+ $progress_count++;
+ $this->iohandler->set_progress('STAGE_UPDATE_DATABASE', $progress_count);
+ }
+ catch (exception $e)
+ {
+ $msg = $e->getParameters();
+ array_unshift($msg, $e->getMessage());
+
+ $this->iohandler->add_error_message($msg);
+ throw new user_interaction_required_exception();
+ }
+
+ if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0)
+ {
+ $this->installer_config->set('database_update_count', $progress_count);
+ throw new resource_limit_reached_exception();
+ }
+ }
+
+ if ($original_version !== $this->config['version'])
+ {
+ $this->log->add(
+ 'admin',
+ $this->user->data['user_id'],
+ $this->user->ip,
+ 'LOG_UPDATE_DATABASE',
+ false,
+ array(
+ $original_version,
+ $this->config['version']
+ )
+ );
+ }
+
+ $this->iohandler->finish_progress('INLINE_UPDATE_SUCCESSFUL');
+
+ $this->iohandler->add_success_message('INLINE_UPDATE_SUCCESSFUL');
+
+ $this->config->delete('version_update_from');
+
+ $this->cache->purge();
+
+ $this->config->increment('assets_version', 1);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module/update_filesystem/module.php b/phpBB/phpbb/install/module/update_filesystem/module.php
new file mode 100644
index 0000000000..157c78a1ac
--- /dev/null
+++ b/phpBB/phpbb/install/module/update_filesystem/module.php
@@ -0,0 +1,33 @@
+<?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\install\module\update_filesystem;
+
+class module extends \phpbb\install\module_base
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_navigation_stage_path()
+ {
+ return array('update', 0, 'update_files');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_step_count()
+ {
+ return 0;
+ }
+}
diff --git a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php
new file mode 100644
index 0000000000..e3e6db6263
--- /dev/null
+++ b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php
@@ -0,0 +1,205 @@
+<?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\install\module\update_filesystem\task;
+
+use phpbb\install\exception\resource_limit_reached_exception;
+use phpbb\install\exception\user_interaction_required_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\container_factory;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\helper\update_helper;
+use phpbb\install\task_base;
+
+/**
+ * Merges user made changes into the files
+ */
+class diff_files extends task_base
+{
+ /**
+ * @var \phpbb\cache\driver\driver_interface
+ */
+ protected $cache;
+
+ /**
+ * @var config
+ */
+ protected $installer_config;
+
+ /**
+ * @var iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * @var string
+ */
+ protected $php_ext;
+
+ /**
+ * @var update_helper
+ */
+ protected $update_helper;
+
+ /**
+ * Constructor
+ *
+ * @param container_factory $container
+ * @param config $config
+ * @param iohandler_interface $iohandler
+ * @param update_helper $update_helper
+ * @param string $phpbb_root_path
+ * @param string $php_ext
+ */
+ public function __construct(container_factory $container, config $config, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path, $php_ext)
+ {
+ $this->installer_config = $config;
+ $this->iohandler = $iohandler;
+ $this->update_helper = $update_helper;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+
+ $this->cache = $container->get('cache.driver');
+
+ parent::__construct(false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check_requirements()
+ {
+ $files_to_diff = $this->installer_config->get('update_files', array());
+ $files_to_diff = (isset($files_to_diff['update_with_diff'])) ? $files_to_diff['update_with_diff'] : array();
+
+ return $this->installer_config->get('do_update_files', false) && count($files_to_diff) > 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ // Include diff engine
+ $this->update_helper->include_file('includes/diff/diff.' . $this->php_ext);
+ $this->update_helper->include_file('includes/diff/engine.' . $this->php_ext);
+
+ // Set up basic vars
+ $old_path = $this->update_helper->get_path_to_old_update_files();
+ $new_path = $this->update_helper->get_path_to_new_update_files();
+
+ $files_to_diff = $this->installer_config->get('update_files', array());
+ $files_to_diff = $files_to_diff['update_with_diff'];
+
+ // Set progress bar
+ $this->iohandler->set_task_count(count($files_to_diff), true);
+ $this->iohandler->set_progress('UPDATE_FILE_DIFF', 0);
+ $progress_count = $this->installer_config->get('file_diff_update_count', 0);
+
+ // Recover progress
+ $progress_key = $this->installer_config->get('differ_progress_key', -1);
+ $progress_recovered = ($progress_key === -1);
+ $merge_conflicts = $this->installer_config->get('merge_conflict_list', array());
+
+ foreach ($files_to_diff as $key => $filename)
+ {
+ if ($progress_recovered === false)
+ {
+ if ($progress_key === $key)
+ {
+ $progress_recovered = true;
+ }
+
+ continue;
+ }
+
+ // Read in files' content
+ $file_contents = array();
+
+ // Handle the special case when user created a file with the filename that is now new in the core
+ $file_contents[0] = (file_exists($old_path . $filename)) ? file_get_contents($old_path . $filename) : '';
+
+ $filenames = array(
+ $this->phpbb_root_path . $filename,
+ $new_path . $filename
+ );
+
+ foreach ($filenames as $file_to_diff)
+ {
+ $file_contents[] = file_get_contents($file_to_diff);
+
+ if ($file_contents[sizeof($file_contents) - 1] === false)
+ {
+ $this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff));
+ unset($file_contents);
+ throw new user_interaction_required_exception();
+ }
+ }
+
+ $diff = new \diff3($file_contents[0], $file_contents[1], $file_contents[2]);
+ unset($file_contents);
+
+ // Handle conflicts
+ if ($diff->get_num_conflicts() !== 0)
+ {
+ $merge_conflicts[] = $filename;
+ }
+
+ // Save merged output
+ $this->cache->put(
+ '_file_' . md5($filename),
+ base64_encode(implode("\n", $diff->merged_output()))
+ );
+
+ unset($diff);
+
+ $progress_count++;
+ $this->iohandler->set_progress('UPDATE_FILE_DIFF', $progress_count);
+
+ if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0)
+ {
+ // Save differ progress
+ $this->installer_config->set('differ_progress_key', $key);
+ $this->installer_config->set('merge_conflict_list', $merge_conflicts);
+ $this->installer_config->set('file_diff_update_count', $progress_count);
+
+ // Request refresh
+ throw new resource_limit_reached_exception();
+ }
+ }
+
+ $this->iohandler->finish_progress('ALL_FILES_DIFFED');
+ $this->installer_config->set('merge_conflict_list', $merge_conflicts);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php
new file mode 100644
index 0000000000..9271e8fd50
--- /dev/null
+++ b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php
@@ -0,0 +1,124 @@
+<?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\install\module\update_filesystem\task;
+
+use phpbb\filesystem\filesystem;
+use phpbb\install\exception\jump_to_restart_point_exception;
+use phpbb\install\exception\user_interaction_required_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\task_base;
+
+class download_updated_files extends task_base
+{
+ /**
+ * @var config
+ */
+ protected $installer_config;
+
+ /**
+ * @var filesystem
+ */
+ protected $filesystem;
+
+ /**
+ * @var iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * Constructor
+ *
+ * @param config $config
+ * @param iohandler_interface $iohandler
+ * @param filesystem $filesystem
+ */
+ public function __construct(config $config, iohandler_interface $iohandler, filesystem $filesystem)
+ {
+ $this->installer_config = $config;
+ $this->iohandler = $iohandler;
+ $this->filesystem = $filesystem;
+
+ parent::__construct(false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check_requirements()
+ {
+ return $this->installer_config->get('do_update_files', false)
+ && $this->installer_config->get('file_update_method', '') === 'compression';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ if ($this->iohandler->get_input('database_update_submit', false))
+ {
+ // Remove archive
+ $this->filesystem->remove(
+ $this->installer_config->get('update_file_archive', null)
+ );
+
+ $this->installer_config->set('update_file_archive', null);
+ }
+ else if ($this->iohandler->get_input('update_recheck_files_submit', false))
+ {
+ throw new jump_to_restart_point_exception('check_update_files');
+ }
+ else
+ {
+ // Render download box
+ $this->iohandler->add_download_link(
+ 'phpbb_installer_update_file_download',
+ 'DOWNLOAD_UPDATE_METHOD',
+ 'DOWNLOAD_UPDATE_METHOD_EXPLAIN'
+ );
+
+ // Add form to continue update
+ $this->iohandler->add_user_form_group('UPDATE_CONTINUE_UPDATE_PROCESS', array(
+ 'update_recheck_files_submit' => array(
+ 'label' => 'UPDATE_RECHECK_UPDATE_FILES',
+ 'type' => 'submit',
+ ),
+ 'database_update_submit' => array(
+ 'label' => 'UPDATE_CONTINUE_UPDATE_PROCESS',
+ 'type' => 'submit',
+ ),
+ ));
+
+ $this->iohandler->send_response();
+ throw new user_interaction_required_exception();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php
new file mode 100644
index 0000000000..5dbee6c259
--- /dev/null
+++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php
@@ -0,0 +1,186 @@
+<?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\install\module\update_filesystem\task;
+
+use phpbb\filesystem\filesystem;
+use phpbb\install\exception\resource_limit_reached_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\helper\update_helper;
+use phpbb\install\task_base;
+
+/**
+ * Updater task performing file checking
+ */
+class file_check extends task_base
+{
+ /**
+ * @var filesystem
+ */
+ protected $filesystem;
+
+ /**
+ * @var config
+ */
+ protected $installer_config;
+
+ /**
+ * @var iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * @var update_helper
+ */
+ protected $update_helper;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * Construct
+ *
+ * @param filesystem $filesystem
+ * @param config $config
+ * @param iohandler_interface $iohandler
+ * @param update_helper $update_helper
+ * @param string $phpbb_root_path
+ */
+ public function __construct(filesystem $filesystem, config $config, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path)
+ {
+ $this->filesystem = $filesystem;
+ $this->installer_config = $config;
+ $this->iohandler = $iohandler;
+ $this->update_helper = $update_helper;
+ $this->phpbb_root_path = $phpbb_root_path;
+
+ parent::__construct(false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check_requirements()
+ {
+ return $this->installer_config->get('do_update_files', false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ if (!$this->installer_config->has_restart_point('check_update_files'))
+ {
+ $this->installer_config->create_progress_restart_point('check_update_files');
+ }
+
+ $old_path = $this->update_helper->get_path_to_old_update_files();
+ $new_path = $this->update_helper->get_path_to_new_update_files();
+
+ $update_info = $this->installer_config->get('update_info', array());
+ $file_update_info = $this->installer_config->get('update_files', array());
+
+ if (empty($update_info))
+ {
+ $root_path = $this->phpbb_root_path;
+
+ $update_info = $this->installer_config->get('update_info_unprocessed', array());
+
+ $file_update_info = array();
+ $file_update_info['update_without_diff'] = array_diff($update_info['binary'], $update_info['deleted']);
+
+ // Filter out files that are already deleted
+ $file_update_info['delete'] = array_filter(
+ $update_info['deleted'],
+ function ($filename) use ($root_path)
+ {
+ return file_exists($root_path . $filename);
+ }
+ );
+ }
+
+ $progress_count = $this->installer_config->get('file_check_progress_count', 0);
+ $task_count = count($update_info['files']);
+ $this->iohandler->set_task_count($task_count);
+ $this->iohandler->set_progress('UPDATE_CHECK_FILES', 0);
+
+ foreach ($update_info['files'] as $key => $filename)
+ {
+ $old_file = $old_path . $filename;
+ $new_file = $new_path . $filename;
+ $file = $this->phpbb_root_path . $filename;
+
+ if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0)
+ {
+ // Save progress
+ $this->installer_config->set('update_info', $update_info);
+ $this->installer_config->set('file_check_progress_count', $progress_count);
+ $this->installer_config->set('update_files', $file_update_info);
+
+ // Request refresh
+ throw new resource_limit_reached_exception();
+ }
+
+ $progress_count++;
+ $this->iohandler->set_progress('UPDATE_CHECK_FILES', $progress_count);
+
+ if (!$this->filesystem->exists($file))
+ {
+ $file_update_info['new'][] = $filename;
+ }
+ else
+ {
+ $file_checksum = md5_file($file);
+
+ if ($file_checksum === md5_file($new_file))
+ {
+ // File already up to date
+ continue;
+ }
+ else if ($this->filesystem->exists($old_file) && $file_checksum === md5_file($old_file))
+ {
+ // No need to diff the file
+ $file_update_info['update_without_diff'][] = $filename;
+ }
+ else
+ {
+ $file_update_info['update_with_diff'][] = $filename;
+ }
+ }
+
+ unset($update_info['files'][$key]);
+ }
+
+ $this->installer_config->set('update_files', $file_update_info);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php
new file mode 100644
index 0000000000..1c6b9aa058
--- /dev/null
+++ b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php
@@ -0,0 +1,168 @@
+<?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\install\module\update_filesystem\task;
+
+use phpbb\filesystem\filesystem;
+use phpbb\install\exception\user_interaction_required_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\container_factory;
+use phpbb\install\helper\file_updater\factory;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\task_base;
+
+class show_file_status extends task_base
+{
+ /**
+ * @var \phpbb\cache\driver\driver_interface
+ */
+ protected $cache;
+
+ /**
+ * @var filesystem
+ */
+ protected $filesystem;
+
+ /**
+ * @var config
+ */
+ protected $installer_config;
+
+ /**
+ * @var iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * @var \phpbb\install\helper\file_updater\compression_file_updater
+ */
+ protected $file_updater;
+
+ /**
+ * Constructor
+ *
+ * @param container_factory $container
+ * @param config $config
+ * @param iohandler_interface $iohandler
+ * @param filesystem $filesystem
+ * @param factory $file_updater_factory
+ */
+ public function __construct(container_factory $container, config $config, iohandler_interface $iohandler, filesystem $filesystem, factory $file_updater_factory)
+ {
+ $this->installer_config = $config;
+ $this->iohandler = $iohandler;
+ $this->filesystem = $filesystem;
+
+ $this->cache = $container->get('cache.driver');
+
+ // Initialize compression file updater
+ $compression_method = $this->installer_config->get('compression_method', '');
+ $this->file_updater = $file_updater_factory->get('compression');
+ $conflict_archive = $this->file_updater->init($compression_method);
+
+ $this->installer_config->set('update_file_conflict_archive', $conflict_archive);
+
+ parent::__construct(false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check_requirements()
+ {
+ return $this->installer_config->get('do_update_files', false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ if (!$this->iohandler->get_input('submit_continue_file_update', false))
+ {
+ // Handle merge conflicts
+ $merge_conflicts = $this->installer_config->get('merge_conflict_list', array());
+
+ // Create archive for merge conflicts
+ if (!empty($merge_conflicts))
+ {
+ foreach ($merge_conflicts as $filename)
+ {
+ $this->file_updater->create_new_file(
+ $filename,
+ $this->cache->get('_file_' . md5($filename)),
+ true
+ );
+ }
+
+ // Render download box
+ $this->iohandler->add_download_link(
+ 'phpbb_installer_update_conflict_download',
+ 'DOWNLOAD_CONFLICTS',
+ 'DOWNLOAD_CONFLICTS_EXPLAIN'
+ );
+ }
+
+ $this->file_updater->close();
+
+ // Render update file statuses
+ $file_update_info = $this->installer_config->get('update_files', array());
+ $file_status = array(
+ 'deleted' => (!isset($file_update_info['delete'])) ? array() : $file_update_info['delete'],
+ 'new' => (!isset($file_update_info['new'])) ? array() : $file_update_info['new'],
+ 'conflict' => $this->installer_config->get('merge_conflict_list', array()),
+ 'modified' => (!isset($file_update_info['update_with_diff'])) ? array() : $file_update_info['update_with_diff'],
+ 'not_modified' => (!isset($file_update_info['update_without_diff'])) ? array() : $file_update_info['update_without_diff'],
+ );
+
+ $this->iohandler->render_update_file_status($file_status);
+
+ // Add form to continue update
+ $this->iohandler->add_user_form_group('UPDATE_CONTINUE_FILE_UPDATE', array(
+ 'submit_continue_file_update' => array(
+ 'label' => 'UPDATE_CONTINUE_FILE_UPDATE',
+ 'type' => 'submit',
+ ),
+ ));
+
+ // Show results to the user
+ $this->iohandler->send_response();
+ throw new user_interaction_required_exception();
+ }
+ else
+ {
+ // Remove archive
+ $this->filesystem->remove(
+ $this->installer_config->get('update_file_conflict_archive', null)
+ );
+
+ $this->installer_config->set('update_file_conflict_archive', null);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module/update_filesystem/task/update_files.php b/phpBB/phpbb/install/module/update_filesystem/task/update_files.php
new file mode 100644
index 0000000000..747a86281b
--- /dev/null
+++ b/phpBB/phpbb/install/module/update_filesystem/task/update_files.php
@@ -0,0 +1,294 @@
+<?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\install\module\update_filesystem\task;
+
+use phpbb\exception\runtime_exception;
+use phpbb\install\exception\resource_limit_reached_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\container_factory;
+use phpbb\install\helper\file_updater\factory;
+use phpbb\install\helper\file_updater\file_updater_interface;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\helper\update_helper;
+use phpbb\install\task_base;
+
+/**
+ * File updater task
+ */
+class update_files extends task_base
+{
+ /**
+ * @var \phpbb\cache\driver\driver_interface
+ */
+ protected $cache;
+
+ /**
+ * @var config
+ */
+ protected $installer_config;
+
+ /**
+ * @var iohandler_interface
+ */
+ protected $iohandler;
+
+ /**
+ * @var factory
+ */
+ protected $factory;
+
+ /**
+ * @var file_updater_interface
+ */
+ protected $file_updater;
+
+ /**
+ * @var update_helper
+ */
+ protected $update_helper;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * Constructor
+ *
+ * @param container_factory $container
+ * @param config $config
+ * @param iohandler_interface $iohandler
+ * @param factory $file_updater_factory
+ * @param update_helper $update_helper
+ * @param string $phpbb_root_path
+ */
+ public function __construct(container_factory $container, config $config, iohandler_interface $iohandler, factory $file_updater_factory, update_helper $update_helper, $phpbb_root_path)
+ {
+ $this->factory = $file_updater_factory;
+ $this->installer_config = $config;
+ $this->iohandler = $iohandler;
+ $this->update_helper = $update_helper;
+ $this->phpbb_root_path = $phpbb_root_path;
+
+ $this->cache = $container->get('cache.driver');
+ $this->file_updater = null;
+
+ parent::__construct(false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check_requirements()
+ {
+ return $this->installer_config->get('do_update_files', false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ $new_path = $this->update_helper->get_path_to_new_update_files();
+
+ $file_update_info = $this->installer_config->get('update_files', array());
+
+ $update_type_progress = $this->installer_config->get('file_updater_type_progress', '');
+ $update_elem_progress = $this->installer_config->get('file_updater_elem_progress', '');
+ $type_progress_found = false;
+ $elem_progress_found = false;
+
+ // Progress bar
+ $task_count = 0;
+ foreach ($file_update_info as $sub_array)
+ {
+ $task_count += count($sub_array);
+ }
+
+ // Everything is up to date, so just continue
+ if ($task_count === 0)
+ {
+ return;
+ }
+
+ $progress_count = $this->installer_config->get('file_update_progress_count', 0);
+ $this->iohandler->set_task_count($task_count, true);
+ $this->iohandler->set_progress('UPDATE_UPDATING_FILES', 0);
+
+ $this->file_updater = $this->get_file_updater();
+
+ // File updater fallback logic
+ try
+ {
+ // Update files
+ foreach ($file_update_info as $type => $file_update_vector)
+ {
+ if (!$type_progress_found)
+ {
+ if ($type === $update_type_progress || empty($update_elem_progress))
+ {
+ $type_progress_found = true;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ foreach ($file_update_vector as $path)
+ {
+ if (!$elem_progress_found)
+ {
+ if ($path === $update_elem_progress || empty($update_elem_progress))
+ {
+ $elem_progress_found = true;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ switch ($type)
+ {
+ case 'delete':
+ $this->file_updater->delete_file($path);
+ break;
+ case 'new':
+ $this->file_updater->create_new_file($path, $new_path . $path);
+ break;
+ case 'update_without_diff':
+ $this->file_updater->update_file($path, $new_path . $path);
+ break;
+ case 'update_with_diff':
+ $this->file_updater->update_file(
+ $path,
+ $this->cache->get('_file_' . md5($path)),
+ true
+ );
+ break;
+ }
+
+ // Save progress
+ $this->installer_config->set('file_updater_type_progress', $type);
+ $this->installer_config->set('file_updater_elem_progress', $path);
+ $progress_count++;
+ $this->iohandler->set_progress('UPDATE_UPDATING_FILES', $progress_count);
+
+ if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0)
+ {
+ // Request refresh
+ throw new resource_limit_reached_exception();
+ }
+ }
+ }
+
+ $this->iohandler->finish_progress('UPDATE_UPDATING_FILES');
+ }
+ catch (runtime_exception $e)
+ {
+ if ($e instanceof resource_limit_reached_exception)
+ {
+ throw new resource_limit_reached_exception();
+ }
+
+ $current_method = $this->installer_config->get('file_update_method', '');
+
+ // File updater failed, try to fallback to download file update mode
+ if ($current_method !== 'compression')
+ {
+ $this->iohandler->add_warning_message(array(
+ 'UPDATE_FILE_UPDATER_HAS_FAILED',
+ $current_method,
+ 'compression'
+ ));
+ $this->installer_config->set('file_update_method', 'compression');
+
+ // We only want a simple refresh here
+ throw new resource_limit_reached_exception();
+ }
+ else
+ {
+ // Nowhere to fallback to :(
+ // Due to the way the installer handles fatal errors, we need to throw a low level exception
+ throw new runtime_exception('UPDATE_FILE_UPDATERS_HAVE_FAILED');
+ }
+ }
+
+ $file_updater_method = $this->installer_config->get('file_update_method', '');
+ if ($file_updater_method === 'compression' || $file_updater_method === 'ftp')
+ {
+ $this->file_updater->close();
+ }
+ }
+
+ /**
+ * Get file updater
+ *
+ * @param null|string $file_updater_method Name of the file updater to use
+ *
+ * @return file_updater_interface File updater
+ */
+ protected function get_file_updater($file_updater_method = null)
+ {
+ $file_updater_method = ($file_updater_method === null) ? $this->installer_config->get('file_update_method', '') : $file_updater_method;
+
+ if ($file_updater_method === 'compression')
+ {
+ $compression_method = $this->installer_config->get('file_update_compression', '');
+
+ /** @var \phpbb\install\helper\file_updater\compression_file_updater $file_updater */
+ $file_updater = $this->factory->get('compression');
+ $archive_path = $file_updater->init($compression_method);
+ $this->installer_config->set('update_file_archive', $archive_path);
+ }
+ else if ($file_updater_method === 'ftp')
+ {
+ /** @var \phpbb\install\helper\file_updater\ftp_file_updater $file_updater */
+ $file_updater = $this->factory->get('ftp');
+ $file_updater->init(
+ $this->installer_config->get('ftp_method', ''),
+ $this->installer_config->get('ftp_host', ''),
+ $this->installer_config->get('ftp_user', ''),
+ $this->installer_config->get('ftp_pass', ''),
+ $this->installer_config->get('ftp_path', ''),
+ $this->installer_config->get('ftp_port', 0),
+ $this->installer_config->get('ftp_timeout', 10)
+ );
+ }
+ else
+ {
+ /** @var file_updater_interface $file_updater */
+ $file_updater = $this->factory->get('direct_file');
+ }
+
+ return $file_updater;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_step_count()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_task_lang_name()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/install/module_base.php b/phpBB/phpbb/install/module_base.php
index a933d4987c..fb68c3aca2 100644
--- a/phpBB/phpbb/install/module_base.php
+++ b/phpBB/phpbb/install/module_base.php
@@ -115,7 +115,7 @@ abstract class module_base implements module_interface
foreach ($this->task_collection as $name => $task)
{
// Run until there are available resources
- if ($this->install_config->get_time_remaining() <= 0 && $this->install_config->get_memory_remaining() <= 0)
+ if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0)
{
throw new resource_limit_reached_exception();
}
diff --git a/phpBB/phpbb/install/task_base.php b/phpBB/phpbb/install/task_base.php
index 5946be8c52..b5199be4af 100644
--- a/phpBB/phpbb/install/task_base.php
+++ b/phpBB/phpbb/install/task_base.php
@@ -44,7 +44,7 @@ abstract class task_base implements task_interface
/**
* {@inheritdoc}
*
- * Overwrite this method if your task is non-essential!
+ * Note: Overwrite this method if your task is non-essential!
*/
public function check_requirements()
{
diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php
index 9666647bd8..e4b111e4da 100644
--- a/phpBB/phpbb/notification/type/approve_post.php
+++ b/phpBB/phpbb/notification/type/approve_post.php
@@ -82,7 +82,7 @@ class approve_post extends \phpbb\notification\type\post
$users[$post['poster_id']] = $this->notification_manager->get_default_methods();
return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(
- 'item_type' => self::$notification_option['id'],
+ 'item_type' => static::$notification_option['id'],
)));
}
diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php
index e9f4c32852..f8a3fdec6f 100644
--- a/phpBB/phpbb/notification/type/approve_topic.php
+++ b/phpBB/phpbb/notification/type/approve_topic.php
@@ -82,7 +82,7 @@ class approve_topic extends \phpbb\notification\type\topic
$users[$post['poster_id']] = $this->notification_manager->get_default_methods();
return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(
- 'item_type' => self::$notification_option['id'],
+ 'item_type' => static::$notification_option['id'],
)));
}
diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php
index 5b3fc3a1f2..ebbb961c57 100644
--- a/phpBB/phpbb/notification/type/bookmark.php
+++ b/phpBB/phpbb/notification/type/bookmark.php
@@ -92,7 +92,7 @@ class bookmark extends \phpbb\notification\type\post
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$notified_users = $this->notification_manager->get_notified_users($this->get_type(), array(
- 'item_parent_id' => self::get_item_parent_id($post),
+ 'item_parent_id' => static::get_item_parent_id($post),
'read' => 0,
));
diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php
index b54a6610b2..b9afc6d70a 100644
--- a/phpBB/phpbb/notification/type/post.php
+++ b/phpBB/phpbb/notification/type/post.php
@@ -150,7 +150,7 @@ class post extends \phpbb\notification\type\base
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$notified_users = $this->notification_manager->get_notified_users($this->get_type(), array(
- 'item_parent_id' => self::get_item_parent_id($post),
+ 'item_parent_id' => static::get_item_parent_id($post),
'read' => 0,
));
diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php
index 8b21d77cdd..2d556fc9c8 100644
--- a/phpBB/phpbb/notification/type/post_in_queue.php
+++ b/phpBB/phpbb/notification/type/post_in_queue.php
@@ -108,7 +108,7 @@ class post_in_queue extends \phpbb\notification\type\post
}
return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array(
- 'item_type' => self::$notification_option['id'],
+ 'item_type' => static::$notification_option['id'],
)));
}
diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php
index 9e759ef137..684463c8c3 100644
--- a/phpBB/phpbb/notification/type/quote.php
+++ b/phpBB/phpbb/notification/type/quote.php
@@ -111,7 +111,7 @@ class quote extends \phpbb\notification\type\post
public function update_notifications($post)
{
$old_notifications = $this->notification_manager->get_notified_users($this->get_type(), array(
- 'item_id' => self::get_item_id($post),
+ 'item_id' => static::get_item_id($post),
));
// Find the new users to notify
@@ -133,7 +133,7 @@ class quote extends \phpbb\notification\type\post
// Remove the necessary notifications
if (!empty($remove_notifications))
{
- $this->notification_manager->delete_notifications($this->get_type(), self::get_item_id($post), false, $remove_notifications);
+ $this->notification_manager->delete_notifications($this->get_type(), static::get_item_id($post), false, $remove_notifications);
}
// return true to continue with the update code in the notifications service (this will update the rest of the notifications)
diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php
index b80afc1039..6091919769 100644
--- a/phpBB/phpbb/notification/type/report_pm.php
+++ b/phpBB/phpbb/notification/type/report_pm.php
@@ -121,7 +121,7 @@ class report_pm extends \phpbb\notification\type\pm
}
return $this->check_user_notification_options($auth_approve[$post['forum_id']][$this->permission], array_merge($options, array(
- 'item_type' => self::$notification_option['id'],
+ 'item_type' => static::$notification_option['id'],
)));
}
diff --git a/phpBB/phpbb/notification/type/topic_in_queue.php b/phpBB/phpbb/notification/type/topic_in_queue.php
index ad2961525e..2d732b9cd7 100644
--- a/phpBB/phpbb/notification/type/topic_in_queue.php
+++ b/phpBB/phpbb/notification/type/topic_in_queue.php
@@ -108,7 +108,7 @@ class topic_in_queue extends \phpbb\notification\type\topic
}
return $this->check_user_notification_options($auth_read[$topic['forum_id']]['f_read'], array_merge($options, array(
- 'item_type' => self::$notification_option['id'],
+ 'item_type' => static::$notification_option['id'],
)));
}
diff --git a/phpBB/phpbb/passwords/driver/salted_md5.php b/phpBB/phpbb/passwords/driver/salted_md5.php
index 81ac010785..38d6d9cd2c 100644
--- a/phpBB/phpbb/passwords/driver/salted_md5.php
+++ b/phpBB/phpbb/passwords/driver/salted_md5.php
@@ -75,7 +75,7 @@ class salted_md5 extends base
// happen if pre-determined settings are
// directly passed to the driver. The manager
// will not do this. Same as the old hashing
- // implementatio in phpBB 3.0
+ // implementation in phpBB 3.0
return md5($password);
}
}
diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php
index 0e67ee209b..a47fc87adf 100644
--- a/phpBB/phpbb/plupload/plupload.php
+++ b/phpBB/phpbb/plupload/plupload.php
@@ -125,7 +125,7 @@ class plupload
// Need to modify some of the $_FILES values to reflect the new file
return array(
'tmp_name' => $file_path,
- 'name' => $this->request->variable('real_filename', ''),
+ 'name' => $this->request->variable('real_filename', '', true),
'size' => filesize($file_path),
'type' => $this->mimetype_guesser->guess($file_path, $file_name),
);
diff --git a/phpBB/phpbb/routing/resources_locator/installer_resources_locator.php b/phpBB/phpbb/routing/resources_locator/installer_resources_locator.php
new file mode 100644
index 0000000000..42cd0f11af
--- /dev/null
+++ b/phpBB/phpbb/routing/resources_locator/installer_resources_locator.php
@@ -0,0 +1,78 @@
+<?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\routing\resources_locator;
+
+use phpbb\filesystem\filesystem_interface;
+
+/**
+ * Locates the yaml routing resources taking update directories into consideration
+ */
+class installer_resources_locator implements resources_locator_interface
+{
+ /**
+ * phpBB's filesystem handler
+ *
+ * @var filesystem_interface
+ */
+ protected $filesystem;
+
+ /**
+ * phpBB root path
+ *
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * Name of the current environment
+ *
+ * @var string
+ */
+ protected $environment;
+
+ /**
+ * Construct method
+ *
+ * @param filesystem_interface $filesystem phpBB's filesystem handler
+ * @param string $phpbb_root_path phpBB root path
+ * @param string $environment Name of the current environment
+ */
+ public function __construct(filesystem_interface $filesystem, $phpbb_root_path, $environment)
+ {
+ $this->filesystem = $filesystem;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->environment = $environment;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function locate_resources()
+ {
+ if ($this->filesystem->exists($this->phpbb_root_path . 'install/update/new/config'))
+ {
+ $resources = array(
+ array('install/update/new/config/' . $this->environment . '/routing/environment.yml', 'yaml')
+ );
+ }
+ else
+ {
+ $resources = array(
+ array('config/' . $this->environment . '/routing/environment.yml', 'yaml')
+ );
+ }
+
+ return $resources;
+ }
+}
diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php
index ba9f5f3a77..d1962bc8cc 100644
--- a/phpBB/phpbb/search/fulltext_mysql.php
+++ b/phpBB/phpbb/search/fulltext_mysql.php
@@ -379,7 +379,7 @@ class fulltext_mysql extends \phpbb\search\base
}
// generate a search_key from all the options to identify the results
- $search_key = md5(implode('#', array(
+ $search_key_array = array(
implode(', ', $this->split_words),
$type,
$fields,
@@ -390,7 +390,39 @@ class fulltext_mysql extends \phpbb\search\base
implode(',', $ex_fid_ary),
$post_visibility,
implode(',', $author_ary)
- )));
+ );
+
+ /**
+ * Allow changing the search_key for cached results
+ *
+ * @event core.search_mysql_by_keyword_modify_search_key
+ * @var array search_key_array Array with search parameters to generate the search_key
+ * @var string type Searching type ('posts', 'topics')
+ * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all')
+ * @var string terms Searching terms ('all', 'any')
+ * @var int sort_days Time, in days, of the oldest possible post to list
+ * @var string sort_key The sort type used from the possible sort types
+ * @var int topic_id Limit the search to this topic_id only
+ * @var array ex_fid_ary Which forums not to search on
+ * @var string post_visibility Post visibility data
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'search_key_array',
+ 'type',
+ 'fields',
+ 'terms',
+ 'sort_days',
+ 'sort_key',
+ 'topic_id',
+ 'ex_fid_ary',
+ 'post_visibility',
+ 'author_ary',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_mysql_by_keyword_modify_search_key', compact($vars)));
+
+ $search_key = md5(implode('#', $search_key_array));
if ($start < 0)
{
@@ -610,7 +642,7 @@ class fulltext_mysql extends \phpbb\search\base
}
// generate a search_key from all the options to identify the results
- $search_key = md5(implode('#', array(
+ $search_key_array = array(
'',
$type,
($firstpost_only) ? 'firstpost' : '',
@@ -623,7 +655,39 @@ class fulltext_mysql extends \phpbb\search\base
$post_visibility,
implode(',', $author_ary),
$author_name,
- )));
+ );
+
+ /**
+ * Allow changing the search_key for cached results
+ *
+ * @event core.search_mysql_by_author_modify_search_key
+ * @var array search_key_array Array with search parameters to generate the search_key
+ * @var string type Searching type ('posts', 'topics')
+ * @var boolean firstpost_only Flag indicating if only topic starting posts are considered
+ * @var int sort_days Time, in days, of the oldest possible post to list
+ * @var string sort_key The sort type used from the possible sort types
+ * @var int topic_id Limit the search to this topic_id only
+ * @var array ex_fid_ary Which forums not to search on
+ * @var string post_visibility Post visibility data
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @var string author_name The username to search on
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'search_key_array',
+ 'type',
+ 'firstpost_only',
+ 'sort_days',
+ 'sort_key',
+ 'topic_id',
+ 'ex_fid_ary',
+ 'post_visibility',
+ 'author_ary',
+ 'author_name',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_mysql_by_author_modify_search_key', compact($vars)));
+
+ $search_key = md5(implode('#', $search_key_array));
if ($start < 0)
{
diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php
index 41d3434c7d..3a74955a18 100644
--- a/phpBB/phpbb/search/fulltext_native.php
+++ b/phpBB/phpbb/search/fulltext_native.php
@@ -64,7 +64,7 @@ class fulltext_native extends \phpbb\search\base
protected $must_not_contain_ids = array();
/**
- * Post ids of posts containing atleast one word that needs to be excluded
+ * Post ids of posts containing at least one word that needs to be excluded
* @var array
*/
protected $must_exclude_one_ids = array();
@@ -533,7 +533,7 @@ class fulltext_native extends \phpbb\search\base
sort($must_exclude_one_ids);
// generate a search_key from all the options to identify the results
- $search_key = md5(implode('#', array(
+ $search_key_array = array(
serialize($must_contain_ids),
serialize($must_not_contain_ids),
serialize($must_exclude_one_ids),
@@ -547,7 +547,45 @@ class fulltext_native extends \phpbb\search\base
$post_visibility,
implode(',', $author_ary),
$author_name,
- )));
+ );
+
+ /**
+ * Allow changing the search_key for cached results
+ *
+ * @event core.search_native_by_keyword_modify_search_key
+ * @var array search_key_array Array with search parameters to generate the search_key
+ * @var array must_contain_ids Array with post ids of posts containing words that are to be included
+ * @var array must_not_contain_ids Array with post ids of posts containing words that should not be included
+ * @var array must_exclude_one_ids Array with post ids of posts containing at least one word that needs to be excluded
+ * @var string type Searching type ('posts', 'topics')
+ * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all')
+ * @var string terms Searching terms ('all', 'any')
+ * @var int sort_days Time, in days, of the oldest possible post to list
+ * @var string sort_key The sort type used from the possible sort types
+ * @var int topic_id Limit the search to this topic_id only
+ * @var array ex_fid_ary Which forums not to search on
+ * @var string post_visibility Post visibility data
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'search_key_array',
+ 'must_contain_ids',
+ 'must_not_contain_ids',
+ 'must_exclude_one_ids',
+ 'type',
+ 'fields',
+ 'terms',
+ 'sort_days',
+ 'sort_key',
+ 'topic_id',
+ 'ex_fid_ary',
+ 'post_visibility',
+ 'author_ary',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_native_by_keyword_modify_search_key', compact($vars)));
+
+ $search_key = md5(implode('#', $search_key_array));
// try reading the results from cache
$total_results = 0;
@@ -983,7 +1021,7 @@ class fulltext_native extends \phpbb\search\base
}
// generate a search_key from all the options to identify the results
- $search_key = md5(implode('#', array(
+ $search_key_array = array(
'',
$type,
($firstpost_only) ? 'firstpost' : '',
@@ -996,7 +1034,39 @@ class fulltext_native extends \phpbb\search\base
$post_visibility,
implode(',', $author_ary),
$author_name,
- )));
+ );
+
+ /**
+ * Allow changing the search_key for cached results
+ *
+ * @event core.search_native_by_author_modify_search_key
+ * @var array search_key_array Array with search parameters to generate the search_key
+ * @var string type Searching type ('posts', 'topics')
+ * @var boolean firstpost_only Flag indicating if only topic starting posts are considered
+ * @var int sort_days Time, in days, of the oldest possible post to list
+ * @var string sort_key The sort type used from the possible sort types
+ * @var int topic_id Limit the search to this topic_id only
+ * @var array ex_fid_ary Which forums not to search on
+ * @var string post_visibility Post visibility data
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @var string author_name The username to search on
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'search_key_array',
+ 'type',
+ 'firstpost_only',
+ 'sort_days',
+ 'sort_key',
+ 'topic_id',
+ 'ex_fid_ary',
+ 'post_visibility',
+ 'author_ary',
+ 'author_name',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_native_by_author_modify_search_key', compact($vars)));
+
+ $search_key = md5(implode('#', $search_key_array));
// try reading the results from cache
$total_results = 0;
diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php
index 8fe80a39a3..ab28fd2957 100644
--- a/phpBB/phpbb/search/fulltext_postgres.php
+++ b/phpBB/phpbb/search/fulltext_postgres.php
@@ -341,7 +341,7 @@ class fulltext_postgres extends \phpbb\search\base
}
// generate a search_key from all the options to identify the results
- $search_key = md5(implode('#', array(
+ $search_key_array = array(
implode(', ', $this->split_words),
$type,
$fields,
@@ -352,7 +352,39 @@ class fulltext_postgres extends \phpbb\search\base
implode(',', $ex_fid_ary),
$post_visibility,
implode(',', $author_ary)
- )));
+ );
+
+ /**
+ * Allow changing the search_key for cached results
+ *
+ * @event core.search_postgres_by_keyword_modify_search_key
+ * @var array search_key_array Array with search parameters to generate the search_key
+ * @var string type Searching type ('posts', 'topics')
+ * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all')
+ * @var string terms Searching terms ('all', 'any')
+ * @var int sort_days Time, in days, of the oldest possible post to list
+ * @var string sort_key The sort type used from the possible sort types
+ * @var int topic_id Limit the search to this topic_id only
+ * @var array ex_fid_ary Which forums not to search on
+ * @var string post_visibility Post visibility data
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'search_key_array',
+ 'type',
+ 'fields',
+ 'terms',
+ 'sort_days',
+ 'sort_key',
+ 'topic_id',
+ 'ex_fid_ary',
+ 'post_visibility',
+ 'author_ary',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_by_keyword_modify_search_key', compact($vars)));
+
+ $search_key = md5(implode('#', $search_key_array));
if ($start < 0)
{
@@ -585,7 +617,7 @@ class fulltext_postgres extends \phpbb\search\base
}
// generate a search_key from all the options to identify the results
- $search_key = md5(implode('#', array(
+ $search_key_array = array(
'',
$type,
($firstpost_only) ? 'firstpost' : '',
@@ -598,7 +630,39 @@ class fulltext_postgres extends \phpbb\search\base
$post_visibility,
implode(',', $author_ary),
$author_name,
- )));
+ );
+
+ /**
+ * Allow changing the search_key for cached results
+ *
+ * @event core.search_postgres_by_author_modify_search_key
+ * @var array search_key_array Array with search parameters to generate the search_key
+ * @var string type Searching type ('posts', 'topics')
+ * @var boolean firstpost_only Flag indicating if only topic starting posts are considered
+ * @var int sort_days Time, in days, of the oldest possible post to list
+ * @var string sort_key The sort type used from the possible sort types
+ * @var int topic_id Limit the search to this topic_id only
+ * @var array ex_fid_ary Which forums not to search on
+ * @var string post_visibility Post visibility data
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @var string author_name The username to search on
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'search_key_array',
+ 'type',
+ 'firstpost_only',
+ 'sort_days',
+ 'sort_key',
+ 'topic_id',
+ 'ex_fid_ary',
+ 'post_visibility',
+ 'author_ary',
+ 'author_name',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_by_author_modify_search_key', compact($vars)));
+
+ $search_key = md5(implode('#', $search_key_array));
if ($start < 0)
{
diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php
index 937292fd38..372a2792cf 100644
--- a/phpBB/phpbb/search/fulltext_sphinx.php
+++ b/phpBB/phpbb/search/fulltext_sphinx.php
@@ -359,6 +359,23 @@ class fulltext_sphinx
$non_unique = array('sql_query_pre' => true, 'sql_attr_uint' => true, 'sql_attr_timestamp' => true, 'sql_attr_str2ordinal' => true, 'sql_attr_bool' => true);
$delete = array('sql_group_column' => true, 'sql_date_column' => true, 'sql_str2ordinal_column' => true);
+
+ /**
+ * Allow adding/changing the Sphinx configuration data
+ *
+ * @event core.search_sphinx_modify_config_data
+ * @var array config_data Array with the Sphinx configuration data
+ * @var array non_unique Array with the Sphinx non-unique variables to delete
+ * @var array delete Array with the Sphinx variables to delete
+ * @since 3.1.7-RC1
+ */
+ $vars = array(
+ 'config_data',
+ 'non_unique',
+ 'delete',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_sphinx_modify_config_data', compact($vars)));
+
foreach ($config_data as $section_name => $section_data)
{
$section = $config_object->get_section_by_name($section_name);
@@ -534,6 +551,41 @@ class fulltext_sphinx
$this->sphinx->SetFilter('topic_id', array($topic_id));
}
+ /**
+ * Allow modifying the Sphinx search options
+ *
+ * @event core.search_sphinx_keywords_modify_options
+ * @var string type Searching type ('posts', 'topics')
+ * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all')
+ * @var string terms Searching terms ('all', 'any')
+ * @var int sort_days Time, in days, of the oldest possible post to list
+ * @var string sort_key The sort type used from the possible sort types
+ * @var int topic_id Limit the search to this topic_id only
+ * @var array ex_fid_ary Which forums not to search on
+ * @var string post_visibility Post visibility data
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @var string author_name The username to search on
+ * @var object sphinx The Sphinx searchd client object
+ * @since 3.1.7-RC1
+ */
+ $sphinx = $this->sphinx;
+ $vars = array(
+ 'type',
+ 'fields',
+ 'terms',
+ 'sort_days',
+ 'sort_key',
+ 'topic_id',
+ 'ex_fid_ary',
+ 'post_visibility',
+ 'author_ary',
+ 'author_name',
+ 'sphinx',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_sphinx_keywords_modify_options', compact($vars)));
+ $this->sphinx = $sphinx;
+ unset($sphinx);
+
$search_query_prefix = '';
switch ($fields)
diff --git a/phpBB/posting.php b/phpBB/posting.php
index 47fdb2d378..3174626f6b 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -571,7 +571,6 @@ $plupload = $phpbb_container->get('plupload');
/* @var $mimetype_guesser \phpbb\mimetype\guesser */
$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']))
{
@@ -1031,7 +1030,8 @@ if ($submit || $preview || $refresh)
$message_parser->bbcode_bitfield = $post_data['bbcode_bitfield'];
}
- if ($mode != 'edit' && !$preview && !$refresh && $config['flood_interval'] && !$auth->acl_get('f_ignoreflood', $forum_id))
+ $ignore_flood = $auth->acl_get('u_ignoreflood') ? true : $auth->acl_get('f_ignoreflood', $forum_id);
+ if ($mode != 'edit' && !$preview && !$refresh && $config['flood_interval'] && !$ignore_flood)
{
// Flood check
$last_post_time = 0;
@@ -1256,7 +1256,6 @@ if ($submit || $preview || $refresh)
* @var array poll Array with poll data from post (must be used instead of the post_data equivalent)
* @var string mode What action to take if the form is submitted
* post|reply|quote|edit|delete|bump|smilies|popup
- * @var string page_title Title of the mode page
* @var int post_id ID of the post
* @var int topic_id ID of the topic
* @var int forum_id ID of the forum
@@ -1265,12 +1264,12 @@ if ($submit || $preview || $refresh)
* NOTE: Should be actual language strings, NOT language keys.
* @since 3.1.0-RC5
* @change 3.1.5-RC1 Added poll array to the event
+ * @change 3.2.0-a1 Removed undefined page_title
*/
$vars = array(
'post_data',
'poll',
'mode',
- 'page_title',
'post_id',
'topic_id',
'forum_id',
@@ -1383,7 +1382,6 @@ if ($submit || $preview || $refresh)
* @var array data Array with post data going to be stored in the database
* @var string mode What action to take if the form is submitted
* post|reply|quote|edit|delete
- * @var string page_title Title of the mode page
* @var int post_id ID of the post
* @var int topic_id ID of the topic
* @var int forum_id ID of the forum
@@ -1393,13 +1391,13 @@ if ($submit || $preview || $refresh)
* NOTE: Should be actual language strings, NOT language keys.
* @since 3.1.0-RC5
* @changed 3.1.6-RC1 remove submit and error from event Submit and Error are checked previously prior to running event
+ * @change 3.2.0-a1 Removed undefined page_title
*/
$vars = array(
'post_data',
'poll',
'data',
'mode',
- 'page_title',
'post_id',
'topic_id',
'forum_id',
@@ -1421,7 +1419,6 @@ if ($submit || $preview || $refresh)
* @var array data Array with post data going to be stored in the database
* @var string mode What action to take if the form is submitted
* post|reply|quote|edit|delete
- * @var string page_title Title of the mode page
* @var int post_id ID of the post
* @var int topic_id ID of the topic
* @var int forum_id ID of the forum
@@ -1432,13 +1429,13 @@ if ($submit || $preview || $refresh)
* NOTE: Should be actual language strings, NOT language keys.
* @since 3.1.0-RC5
* @changed 3.1.6-RC1 remove submit and error from event Submit and Error are checked previously prior to running event
+ * @change 3.2.0-a1 Removed undefined page_title
*/
$vars = array(
'post_data',
'poll',
'data',
'mode',
- 'page_title',
'post_id',
'topic_id',
'forum_id',
diff --git a/phpBB/search.php b/phpBB/search.php
index 13e842c7f8..d9e5d0557a 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -779,7 +779,7 @@ if ($keywords || $author || $author_id || $search_id || $submit)
$result = $db->sql_query($sql);
$result_topic_id = 0;
- $rowset = array();
+ $rowset = $attachments = $topic_tracking_info = array();
if ($show_results == 'topics')
{
diff --git a/phpBB/styles/prosilver/template/captcha_recaptcha.html b/phpBB/styles/prosilver/template/captcha_recaptcha.html
index d3c0ea95d6..a123f543a8 100644
--- a/phpBB/styles/prosilver/template/captcha_recaptcha.html
+++ b/phpBB/styles/prosilver/template/captcha_recaptcha.html
@@ -12,24 +12,11 @@
<dl>
<dt><label>{L_CONFIRM_CODE}{L_COLON}</label><br /><span>{L_RECAPTCHA_EXPLAIN}</span></dt>
<dd class="captcha">
- <script>
- var RecaptchaOptions = {
- lang : '{LA_RECAPTCHA_LANG}',
- theme : 'clean',
- tabindex : <!-- IF $CAPTCHA_TAB_INDEX -->{$CAPTCHA_TAB_INDEX}<!-- ELSE -->10<!-- ENDIF -->
- };
- </script>
- <script src="{RECAPTCHA_SERVER}/challenge?k={RECAPTCHA_PUBKEY}{RECAPTCHA_ERRORGET}"></script>
-
<noscript>
- <div>
- <object data="{RECAPTCHA_SERVER}/noscript?k={RECAPTCHA_PUBKEY}{RECAPTCHA_ERRORGET}" type="text/html" height="300" width="500"></object><br />
- <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
- <input type="hidden" name="recaptcha_response_field" value="manual_challenge" />
- </div>
+ <div>{L_RECAPTCHA_NOSCRIPT}</div>
</noscript>
-
- <a href="http://www.google.com/intl/{L_RECAPTCHA_LANG}/policies/" target="_blank" class="recaptcha-responsive" style="display: none"><img alt="" width="71" height="36" src="{RECAPTCHA_SERVER}/img/clean/logo.png"></a>
+ <script src="{RECAPTCHA_SERVER}.js?hl={LA_RECAPTCHA_LANG}" async defer></script>
+ <div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}" data-tabindex="<!-- IF $CAPTCHA_TAB_INDEX -->{$CAPTCHA_TAB_INDEX}<!-- ELSE -->10<!-- ENDIF -->"></div>
</dd>
</dl>
<!-- ELSE -->
diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js
index c6f13df5c2..b803a6f5c8 100644
--- a/phpBB/styles/prosilver/template/forum_fn.js
+++ b/phpBB/styles/prosilver/template/forum_fn.js
@@ -159,7 +159,10 @@ function selectCode(a) {
try {
s.setBaseAndExtent(e, 0, e, l);
} catch (error) {
- s.setBaseAndExtent(e, 0, e, 1);
+ r = document.createRange();
+ r.selectNodeContents(e);
+ s.removeAllRanges();
+ s.addRange(r);
}
}
// Firefox and Opera
diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html
index 0ba945b933..c7f9340207 100644
--- a/phpBB/styles/prosilver/template/memberlist_body.html
+++ b/phpBB/styles/prosilver/template/memberlist_body.html
@@ -101,8 +101,8 @@
<!-- ENDIF -->
<!-- ENDIF -->
- <tr class="<!-- IF memberrow.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF -->">
- <td><span class="rank-img"><!-- EVENT memberlist_body_rank_prepend --><!-- IF memberrow.RANK_IMG -->{memberrow.RANK_IMG}<!-- ELSE -->{memberrow.RANK_TITLE}<!-- ENDIF --><!-- EVENT memberlist_body_rank_append --></span><!-- IF S_IN_SEARCH_POPUP and not S_SELECT_SINGLE --><input type="checkbox" name="user" value="{memberrow.USERNAME}" /> <!-- ENDIF --><!-- EVENT memberlist_body_username_prepend -->{memberrow.USERNAME_FULL}<!-- EVENT memberlist_body_username_append --><!-- IF S_IN_SEARCH_POPUP --><br />[&nbsp;<a href="#" onclick="insert_single_user('#results', '{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a>&nbsp;]<!-- ENDIF --></td>
+ <tr class="<!-- IF memberrow.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF memberrow.S_INACTIVE --> inactive<!-- ENDIF -->">
+ <td><span class="rank-img"><!-- EVENT memberlist_body_rank_prepend --><!-- IF memberrow.RANK_IMG -->{memberrow.RANK_IMG}<!-- ELSE -->{memberrow.RANK_TITLE}<!-- ENDIF --><!-- EVENT memberlist_body_rank_append --></span><!-- IF S_IN_SEARCH_POPUP and not S_SELECT_SINGLE --><input type="checkbox" name="user" value="{memberrow.USERNAME}" /> <!-- ENDIF --><!-- EVENT memberlist_body_username_prepend -->{memberrow.USERNAME_FULL}<!-- IF memberrow.S_INACTIVE --> ({L_INACTIVE})<!-- ENDIF --><!-- EVENT memberlist_body_username_append --><!-- IF S_IN_SEARCH_POPUP --><br />[&nbsp;<a href="#" onclick="insert_single_user('#results', '{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a>&nbsp;]<!-- ENDIF --></td>
<td class="posts"><!-- IF memberrow.POSTS and S_DISPLAY_SEARCH --><a href="{memberrow.U_SEARCH_USER}" title="{L_SEARCH_USER_POSTS}">{memberrow.POSTS}</a><!-- ELSE -->{memberrow.POSTS}<!-- ENDIF --></td>
<td class="info"><!-- BEGIN custom_fields --><div>{memberrow.custom_fields.PROFILE_FIELD_VALUE}</div><!-- BEGINELSE -->&nbsp;<!-- END custom_fields --></td>
<td>{memberrow.JOINED}</td>
diff --git a/phpBB/styles/prosilver/template/memberlist_team.html b/phpBB/styles/prosilver/template/memberlist_team.html
index fd2ba564d3..b7f2d66d94 100644
--- a/phpBB/styles/prosilver/template/memberlist_team.html
+++ b/phpBB/styles/prosilver/template/memberlist_team.html
@@ -8,7 +8,7 @@
<div class="forumbg forumbg-table">
<div class="inner">
- <table class="table1">
+ <table class="table1" id="team">
<thead>
<tr>
<th class="name" data-dfn="{L_RANK}{L_COMMA_SEPARATOR}{L_USERNAME}"><span class="rank-img">{L_RANK}&nbsp;</span><!-- IF group.U_GROUP --><a href="{group.U_GROUP}">{group.GROUP_NAME}</a><!-- ELSE -->{group.GROUP_NAME}<!-- ENDIF --></th>
@@ -18,8 +18,8 @@
</thead>
<tbody>
<!-- BEGIN user -->
- <tr class="<!-- IF group.user.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF -->">
- <td><!-- IF group.user.RANK_IMG --><span class="rank-img">{group.user.RANK_IMG}</span><!-- ELSE --><span class="rank-img">{group.user.RANK_TITLE}</span><!-- ENDIF -->{group.user.USERNAME_FULL}</td>
+ <tr class="<!-- IF group.user.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF group.user.S_INACTIVE --> inactive<!-- ENDIF -->">
+ <td><!-- IF group.user.RANK_IMG --><span class="rank-img">{group.user.RANK_IMG}</span><!-- ELSE --><span class="rank-img">{group.user.RANK_TITLE}</span><!-- ENDIF -->{group.user.USERNAME_FULL}<!-- IF group.user.S_INACTIVE --> ({L_INACTIVE})<!-- ENDIF --></td>
<td class="info"><!-- IF group.user.U_GROUP -->
<a<!-- IF group.user.GROUP_COLOR --> style="font-weight: bold; color: #{group.user.GROUP_COLOR}"<!-- ENDIF --> href="{group.user.U_GROUP}">{group.user.GROUP_NAME}</a>
<!-- ELSE -->
diff --git a/phpBB/styles/prosilver/template/navbar_footer.html b/phpBB/styles/prosilver/template/navbar_footer.html
index a6729cac7c..a7864e3a3d 100644
--- a/phpBB/styles/prosilver/template/navbar_footer.html
+++ b/phpBB/styles/prosilver/template/navbar_footer.html
@@ -13,7 +13,7 @@
<!-- EVENT overall_footer_breadcrumb_prepend -->
<span class="crumb">
<a href="{U_INDEX}" data-navbar-reference="index">
- <i class="icon fa-home fa-fw" aria-hidden="true"></i><span>{L_INDEX}</span>
+ <!-- IF not U_SITE_HOME --><i class="icon fa-home fa-fw" aria-hidden="true"></i><!-- ENDIF --><span>{L_INDEX}</span>
</a>
</span>
<!-- EVENT overall_footer_breadcrumb_append -->
diff --git a/phpBB/styles/prosilver/template/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html
index 087acc9cf9..a02ec45830 100644
--- a/phpBB/styles/prosilver/template/navbar_header.html
+++ b/phpBB/styles/prosilver/template/navbar_header.html
@@ -181,7 +181,8 @@
<span class="crumb" {$MICRODATA}><a href="{U_SITE_HOME}" data-navbar-reference="home"><i class="icon fa-home fa-fw" aria-hidden="true"></i><span>{L_SITE_HOME}</span></a></span>
<!-- ENDIF -->
<!-- EVENT overall_header_breadcrumb_prepend -->
- <span class="crumb" {$MICRODATA}><a href="{U_INDEX}" accesskey="h" data-navbar-reference="index"><i class="icon fa-home fa-fw" aria-hidden="true"></i><span>{L_INDEX}</span></a></span>
+ <span class="crumb" {$MICRODATA}><a href="{U_INDEX}" accesskey="h" data-navbar-reference="index"><!-- IF not U_SITE_HOME --><i class="icon fa-home fa-fw"></i><!-- ENDIF --><span>{L_INDEX}</span></a></span>
+
<!-- BEGIN navlinks -->
<!-- EVENT overall_header_navlink_prepend -->
<span class="crumb" {$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->><a href="{navlinks.U_VIEW_FORUM}" itemprop="url"><span itemprop="title">{navlinks.FORUM_NAME}</span></a></span>
diff --git a/phpBB/styles/prosilver/template/quickreply_editor.html b/phpBB/styles/prosilver/template/quickreply_editor.html
index c9ae52477e..9839494491 100644
--- a/phpBB/styles/prosilver/template/quickreply_editor.html
+++ b/phpBB/styles/prosilver/template/quickreply_editor.html
@@ -4,6 +4,7 @@
<div class="inner">
<h2 class="quickreply-title">{L_QUICKREPLY}</h2>
<fieldset class="fields1">
+ <!-- EVENT quickreply_editor_subject_before -->
<dl style="clear: left;">
<dt><label for="subject">{L_SUBJECT}{L_COLON}</label></dt>
<dd><input type="text" name="subject" id="subject" size="45" maxlength="124" tabindex="2" value="{SUBJECT}" class="inputbox autowidth" /></dd>
diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html
index 7ff62790b4..954eebd011 100644
--- a/phpBB/styles/prosilver/template/simple_header.html
+++ b/phpBB/styles/prosilver/template/simple_header.html
@@ -22,6 +22,7 @@
})(document);
</script>
<!-- ENDIF -->
+<link href="{T_FONT_AWESOME_LINK}" rel="stylesheet">
<link href="{T_STYLESHEET_LINK}" rel="stylesheet">
<link href="{T_STYLESHEET_LANG_LINK}" rel="stylesheet">
diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options_local.html b/phpBB/styles/prosilver/template/ucp_avatar_options_local.html
index ac8d287e5a..e431b7425e 100644
--- a/phpBB/styles/prosilver/template/ucp_avatar_options_local.html
+++ b/phpBB/styles/prosilver/template/ucp_avatar_options_local.html
@@ -10,7 +10,8 @@
<!-- BEGIN avatar_local_row -->
<!-- BEGIN avatar_local_col -->
<label for="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}"><img src="{avatar_local_row.avatar_local_col.AVATAR_IMAGE}" alt="" /><br />
- <input type="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}" value="{avatar_local_row.avatar_local_col.AVATAR_FILE}" /></label>
+ <input type="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}"
+ value="{avatar_local_row.avatar_local_col.AVATAR_FILE}"<!-- IF avatar_local_row.avatar_local_col.CHECKED --> checked="checked"<!-- ENDIF --> /></label>
<!-- END avatar_local_col -->
<!-- END avatar_local_row -->
</div>
diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html
index 5642c0a5cb..0c64adc305 100644
--- a/phpBB/styles/prosilver/template/viewtopic_body.html
+++ b/phpBB/styles/prosilver/template/viewtopic_body.html
@@ -281,10 +281,10 @@
<!-- EVENT viewtopic_body_postrow_post_details_before -->
<p class="author">
<!-- IF S_IS_BOT -->
- <span><i class="icon fa-file fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{postrow.MINI_POST}</span></span>
+ <span><i class="icon fa-file fa-fw <!-- IF postrow.S_UNREAD_POST -->icon-red<!-- ELSE -->icon-lightgray<!-- ENDIF --> icon-md" aria-hidden="true"></i><span class="sr-only">{postrow.MINI_POST}</span></span>
<!-- ELSE -->
<a href="{postrow.U_MINI_POST}" title="{postrow.MINI_POST}">
- <i class="icon fa-file fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{postrow.MINI_POST}</span>
+ <i class="icon fa-file fa-fw <!-- IF postrow.S_UNREAD_POST -->icon-red<!-- ELSE -->icon-lightgray<!-- ENDIF --> icon-md" aria-hidden="true"></i><span class="sr-only">{postrow.MINI_POST}</span>
</a>
<!-- ENDIF -->
<span class="responsive-hide">{L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong> &raquo; </span>{postrow.POST_DATE}
diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css
index c30ebba505..7eb501c21a 100644
--- a/phpBB/styles/prosilver/theme/content.css
+++ b/phpBB/styles/prosilver/theme/content.css
@@ -837,3 +837,7 @@ table.fixed-width-table {
background: rgba(0, 0, 0, .3);
border-radius: 3px;
}
+
+#memberlist tr.inactive, #team tr.inactive {
+ font-style: italic;
+}
diff --git a/phpBB/styles/prosilver/theme/plupload.css b/phpBB/styles/prosilver/theme/plupload.css
index bbbf7ebe53..f466803964 100644
--- a/phpBB/styles/prosilver/theme/plupload.css
+++ b/phpBB/styles/prosilver/theme/plupload.css
@@ -15,6 +15,11 @@
width: 30%;
}
+.attach-comment .inputbox {
+ resize: vertical;
+ width: 100%;
+}
+
.attach-filesize {
width: 15%;
}
diff --git a/phpBB/styles/prosilver/theme/responsive.css b/phpBB/styles/prosilver/theme/responsive.css
index 4f5a5db742..826972fdac 100644
--- a/phpBB/styles/prosilver/theme/responsive.css
+++ b/phpBB/styles/prosilver/theme/responsive.css
@@ -54,16 +54,6 @@
width: 100%;
}
- .recaptchatable tr td:last-child {
- display: none;
- }
-
- .captcha-panel .recaptcha-responsive {
- display: inline-block !important;
- margin-top: 10px;
- vertical-align: middle;
- }
-
dl.details dt, dl.details dd {
width: auto;
float: none;
diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php
index a44a4b218e..765599f165 100644
--- a/phpBB/viewonline.php
+++ b/phpBB/viewonline.php
@@ -196,7 +196,7 @@ while ($row = $db->sql_fetchrow($result))
if (!$row['session_viewonline'])
{
- $view_online = ($auth->acl_get('u_viewonline')) ? true : false;
+ $view_online = ($auth->acl_get('u_viewonline') || $row['user_id'] === $user->data['user_id']) ? true : false;
$logged_hidden_online++;
$username_full = '<em>' . $username_full . '</em>';
diff --git a/tests/attachment/delete_test.php b/tests/attachment/delete_test.php
new file mode 100644
index 0000000000..f1835dd37a
--- /dev/null
+++ b/tests/attachment/delete_test.php
@@ -0,0 +1,127 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+require_once(dirname(__FILE__) . '/../../phpBB/includes/functions_admin.php');
+
+class phpbb_attachment_delete_test extends \phpbb_database_test_case
+{
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ /** @var \phpbb\db\driver\driver_interface */
+ protected $db;
+
+ /** @var \phpbb\filesystem\filesystem */
+ protected $filesystem;
+
+ /** @var \phpbb\attachment\resync */
+ protected $resync;
+
+ /** @var \phpbb\attachment\delete */
+ protected $attachment_delete;
+
+ protected $phpbb_root_path;
+
+ public function getDataSet()
+ {
+ return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/resync.xml');
+ }
+
+ public function setUp()
+ {
+ global $db, $phpbb_root_path;
+
+ parent::setUp();
+
+ $this->config = new \phpbb\config\config(array());
+ $this->db = $this->new_dbal();
+ $db = $this->db;
+ $this->resync = new \phpbb\attachment\resync($this->db);
+ $this->filesystem = $this->getMock('\phpbb\filesystem\filesystem', array('remove', 'exists'));
+ $this->filesystem->expects($this->any())
+ ->method('remove')
+ ->willReturn(false);
+ $this->filesystem->expects($this->any())
+ ->method('exists')
+ ->willReturn(true);
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->dispatcher = new \phpbb_mock_event_dispatcher();
+ $this->attachment_delete = new \phpbb\attachment\delete($this->config, $this->db, $this->dispatcher, $this->filesystem, $this->resync, $phpbb_root_path);
+ }
+
+ public function data_attachment_delete()
+ {
+ return array(
+ array('attach', '', false, false),
+ array('meh', 5, false, 0),
+ array('attach', array(5), false, 0),
+ array('attach', array(1,2), false, 2),
+ array('attach', array(1,2), true, 2),
+ array('post', 5, false, 0),
+ array('topic', 5, false, 0),
+ array('topic', 1, true, 3),
+ array('user', 1, false, 0),
+ );
+ }
+
+ /**
+ * @dataProvider data_attachment_delete
+ */
+ public function test_attachment_delete($mode, $ids, $resync, $expected)
+ {
+ // We need to reset the attachment ID sequence to properly test this
+ if ($this->db->get_sql_layer() === 'postgres')
+ {
+ $sql = 'ALTER SEQUENCE phpbb_attachments_seq RESTART WITH 1';
+ $this->db->sql_query($sql);
+ }
+
+ $this->assertSame($expected, $this->attachment_delete->delete($mode, $ids, $resync));
+ }
+
+ public function data_attachment_unlink()
+ {
+ return array(
+ array(true, true, true),
+ array(true, false, false),
+ array(true, true, false, true),
+ );
+ }
+
+ /**
+ * @dataProvider data_attachment_unlink
+ */
+ public function test_attachment_delete_success($remove_success, $exists_success, $expected, $throw_exception = false)
+ {
+ $this->filesystem = $this->getMock('\phpbb\filesystem\filesystem', array('remove', 'exists'));
+ if ($throw_exception)
+ {
+ $this->filesystem->expects($this->any())
+ ->method('remove')
+ ->willThrowException(new \phpbb\filesystem\exception\filesystem_exception);;
+ }
+ else
+ {
+ $this->filesystem->expects($this->any())
+ ->method('remove')
+ ->willReturn($remove_success);
+ }
+
+ $this->filesystem->expects($this->any())
+ ->method('exists')
+ ->willReturn($exists_success);
+
+ $this->attachment_delete = new \phpbb\attachment\delete($this->config, $this->db, $this->dispatcher, $this->filesystem, $this->resync, $this->phpbb_root_path);
+ $this->assertSame($expected, $this->attachment_delete->unlink_attachment('foobar'));
+ }
+}
diff --git a/tests/attachment/fixtures/resync.xml b/tests/attachment/fixtures/resync.xml
new file mode 100644
index 0000000000..6e2cc62f68
--- /dev/null
+++ b/tests/attachment/fixtures/resync.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<dataset>
+ <table name="phpbb_attachments">
+ <column>post_msg_id</column>
+ <column>topic_id</column>
+ <column>in_message</column>
+ <column>is_orphan</column>
+ <column>attach_comment</column>
+ <column>physical_filename</column>
+ <column>thumbnail</column>
+ <row>
+ <value>1</value>
+ <value>1</value>
+ <value>0</value>
+ <value>0</value>
+ <value>foo</value>
+ <value>foo</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>1</value>
+ <value>1</value>
+ <value>1</value>
+ <value>0</value>
+ <value>foo2</value>
+ <value>foo2</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>1</value>
+ <value>1</value>
+ <value>1</value>
+ <value>0</value>
+ <value>foo2</value>
+ <value>foo2</value>
+ <value>1</value>
+ </row>
+ </table>
+ <table name="phpbb_extensions">
+ <column>extension</column>
+ <column>group_id</column>
+ <row>
+ <value>jpg</value>
+ <value>1</value>
+ </row>
+ <row>
+ <value>png</value>
+ <value>1</value>
+ </row>
+ </table>
+ <table name="phpbb_extension_groups">
+ <column>cat_id</column>
+ <column>group_id</column>
+ <column>download_mode</column>
+ <column>upload_icon</column>
+ <column>max_filesize</column>
+ <column>allow_group</column>
+ <column>allow_in_pm</column>
+ <column>allowed_forums</column>
+ <column>group_name</column>
+ <row>
+ <value>1</value>
+ <value>1</value>
+ <value>1</value>
+ <value> </value>
+ <value>1000</value>
+ <value>1</value>
+ <value>1</value>
+ <value>a:1:{i:0;i:1;}</value>
+ <value>Images</value>
+ </row>
+ </table>
+ <table name="phpbb_posts">
+ <column>post_id</column>
+ <column>post_text</column>
+ <column>poster_id</column>
+ <column>post_attachment</column>
+ <row>
+ <value>1</value>
+ <value>foo</value>
+ <value>1</value>
+ <value>1</value>
+ </row>
+ <row>
+ <value>2</value>
+ <value>foo</value>
+ <value>1</value>
+ <value>1</value>
+ </row>
+ </table>
+ <table name="phpbb_privmsgs">
+ <column>msg_id</column>
+ <column>message_text</column>
+ <column>message_attachment</column>
+ <column>to_address</column>
+ <column>bcc_address</column>
+ <row>
+ <value>1</value>
+ <value>foo</value>
+ <value>1</value>
+ <value>2</value>
+ <value>2</value>
+ </row>
+ <row>
+ <value>2</value>
+ <value>foo</value>
+ <value>1</value>
+ <value>2</value>
+ <value>2</value>
+ </row>
+ </table>
+ <table name="phpbb_topics">
+ <column>topic_id</column>
+ <column>forum_id</column>
+ <column>topic_title</column>
+ <column>topic_attachment</column>
+ <row>
+ <value>1</value>
+ <value>1</value>
+ <value>foo</value>
+ <value>1</value>
+ </row>
+ <row>
+ <value>2</value>
+ <value>1</value>
+ <value>bar</value>
+ <value>1</value>
+ </row>
+ </table>
+</dataset>
diff --git a/tests/attachment/manager_test.php b/tests/attachment/manager_test.php
new file mode 100644
index 0000000000..47d7f38b1d
--- /dev/null
+++ b/tests/attachment/manager_test.php
@@ -0,0 +1,131 @@
+<?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_attachment_manager_test extends \phpbb_test_case
+{
+ protected $delete;
+ protected $resync;
+ protected $upload;
+
+ public function setUp()
+ {
+ $this->delete = $this->getMockBuilder('\phpbb\attachment\delete')
+ ->disableOriginalConstructor()
+ ->setMethods(['delete', 'unlink_attachment'])
+ ->getMock();
+ $this->resync = $this->getMockBuilder('\phpbb\attachment\resync')
+ ->disableOriginalConstructor()
+ ->setMethods(['resync'])
+ ->getMock();
+ $this->upload = $this->getMockBuilder('\phpbb\attachment\upload')
+ ->disableOriginalConstructor()
+ ->setMethods(['upload'])
+ ->getMock();
+ }
+
+ protected function get_manager()
+ {
+ return new \phpbb\attachment\manager($this->delete, $this->resync, $this->upload);
+ }
+
+ public function data_manager()
+ {
+ return array(
+ array(
+ 'delete',
+ 'unlink_attachment',
+ 'unlink',
+ ['foo'],
+ ['foo', 'file', false],
+ true,
+ true,
+ ),
+ array(
+ 'delete',
+ 'unlink_attachment',
+ 'unlink',
+ ['foo', 'bar'],
+ ['foo', 'bar', false],
+ true,
+ true,
+ ),
+ array(
+ 'delete',
+ 'unlink_attachment',
+ 'unlink',
+ ['foo', 'bar', true],
+ ['foo', 'bar', true],
+ true,
+ true,
+ ),
+ array(
+ 'delete',
+ 'delete',
+ 'delete',
+ ['foo', [1, 2, 3]],
+ ['foo', [1, 2, 3], true],
+ 5,
+ 5,
+ ),
+ array(
+ 'delete',
+ 'delete',
+ 'delete',
+ ['foo', [1, 2, 3], false],
+ ['foo', [1, 2, 3], false],
+ 2,
+ 2,
+ ),
+ array(
+ 'resync',
+ 'resync',
+ 'resync',
+ ['foo', [1, 2, 3]],
+ ['foo', [1, 2, 3]],
+ true,
+ null,
+ ),
+ array(
+ 'upload',
+ 'upload',
+ 'upload',
+ ['foo', 1],
+ ['foo', 1, false, '', false, []],
+ true,
+ true,
+ ),
+ array(
+ 'upload',
+ 'upload',
+ 'upload',
+ ['foo', 1, true, 'bar', true, ['filename' => 'foobar']],
+ ['foo', 1, true, 'bar', true, ['filename' => 'foobar']],
+ true,
+ true,
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider data_manager
+ */
+ public function test_manager($class, $method_class, $method_manager, $input_manager, $input_method, $return, $output)
+ {
+ $mock = call_user_func_array([$this->{$class}, 'expects'], [$this->atLeastOnce()]);
+ $mock = $mock->method($method_class);
+ $mock = call_user_func_array([$mock, 'with'], $input_method);
+ $mock->willReturn($return);
+ $manager = $this->get_manager();
+ $this->assertSame($output, call_user_func_array([$manager, $method_manager], $input_manager));
+ }
+}
diff --git a/tests/attachment/resync_test.php b/tests/attachment/resync_test.php
new file mode 100644
index 0000000000..f882af9ae5
--- /dev/null
+++ b/tests/attachment/resync_test.php
@@ -0,0 +1,74 @@
+<?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_attachment_resync_test extends \phpbb_database_test_case
+{
+ /** @var \phpbb\db\driver\driver_interface */
+ protected $db;
+
+ /** @var \phpbb\attachment\resync */
+ protected $resync;
+
+ public function getDataSet()
+ {
+ return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/resync.xml');
+ }
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->db = $this->new_dbal();
+ $this->resync = new \phpbb\attachment\resync($this->db);
+ }
+
+ public function data_resync()
+ {
+ return array(
+ array('', array(1), 'post_id', POSTS_TABLE, array('post_attachment' => '1'), array('post_attachment' => '1')),
+ array('post', array(1), 'post_id', POSTS_TABLE, array('post_attachment' => '1'), array('post_attachment' => '1')),
+ array('post', array(2), 'post_id', POSTS_TABLE, array('post_attachment' => '1'), array('post_attachment' => '0')),
+ array('topic', array(1), 'topic_id', TOPICS_TABLE, array('topic_attachment' => '1'), array('topic_attachment' => '1')),
+ array('topic', array(2), 'topic_id', TOPICS_TABLE, array('topic_attachment' => '1'), array('topic_attachment' => '0')),
+ array('message', array(1), 'msg_id', PRIVMSGS_TABLE, array('message_attachment' => '1'), array('message_attachment' => '1')),
+ array('message', array(2), 'msg_id', PRIVMSGS_TABLE, array('message_attachment' => '1'), array('message_attachment' => '0')),
+ );
+ }
+
+ /**
+ * @dataProvider data_resync
+ */
+ public function test_resync($type, $ids, $sql_id, $exist_table, $exist_data, $resync_data)
+ {
+ $sql_prefix = ($type) ?: 'post';
+ $sql = 'SELECT ' . $sql_prefix . '_attachment
+ FROM ' . $exist_table . '
+ WHERE ' . $sql_id . ' = ' . $ids[0];
+ $result = $this->db->sql_query($sql);
+ $data = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ $this->assertEquals($exist_data, $data);
+
+ $this->resync->resync($type, $ids);
+
+ $sql = 'SELECT ' . $sql_prefix . '_attachment
+ FROM ' . $exist_table . '
+ WHERE ' . $sql_id . ' = ' . $ids[0];
+ $result = $this->db->sql_query($sql);
+ $data = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ $this->assertEquals($resync_data, $data);
+ }
+}
diff --git a/tests/attachment/upload_test.php b/tests/attachment/upload_test.php
new file mode 100644
index 0000000000..295b6b15c9
--- /dev/null
+++ b/tests/attachment/upload_test.php
@@ -0,0 +1,430 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+require_once(dirname(__FILE__) . '/../../phpBB/includes/functions.php');
+require_once(dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php');
+
+class phpbb_attachment_upload_test extends \phpbb_database_test_case
+{
+ /** @var \phpbb\auth\auth */
+ protected $auth;
+
+ /** @var \phpbb\cache\service */
+ protected $cache;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ /** @var \phpbb\files\upload */
+ protected $files_upload;
+
+ /** @var \phpbb\language\language */
+ protected $language;
+
+ /** @var \phpbb\mimetype\guesser */
+ protected $mimetype_guesser;
+
+ /** @var \phpbb\event\dispatcher */
+ protected $phpbb_dispatcher;
+
+ /** @var \phpbb\plupload\plupload */
+ protected $plupload;
+
+ /** @var \phpbb\user */
+ protected $user;
+
+ /** @var string phpBB root path */
+ protected $phpbb_root_path;
+
+ /** @var \phpbb\db\driver\driver_interface */
+ protected $db;
+
+ /** @var \phpbb\attachment\upload */
+ protected $upload;
+
+ private $filesystem;
+
+ /** @var \Symfony\Component\DependencyInjection\ContainerInterface */
+ protected $container;
+
+ /** @var \phpbb\files\factory */
+ protected $factory;
+
+ /** @var \bantu\IniGetWrapper\IniGetWrapper */
+ protected $php_ini;
+
+ public function getDataSet()
+ {
+ return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/resync.xml');
+ }
+
+ public function setUp()
+ {
+ global $config, $phpbb_root_path, $phpEx;
+
+ parent::setUp();
+
+ $this->auth = new \phpbb\auth\auth();
+ $this->config = new \phpbb\config\config(array(
+ 'upload_path' => '',
+ 'img_create_thumbnail' => true,
+ ));
+ $config = $this->config;
+ $this->db = $this->new_dbal();
+ $this->cache = new \phpbb\cache\service(new \phpbb\cache\driver\dummy(), $this->config, $this->db, $phpbb_root_path, $phpEx);
+ $this->request = $this->getMock('\phpbb\request\request');
+
+ $this->filesystem = new \phpbb\filesystem\filesystem();
+ $this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
+ $this->php_ini = new \bantu\IniGetWrapper\IniGetWrapper;
+ $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);
+ $this->plupload = new \phpbb\plupload\plupload($phpbb_root_path, $this->config, $this->request, new \phpbb\user($this->language, '\phpbb\datetime'), $this->php_ini, $this->mimetype_guesser);
+ $factory_mock = $this->getMockBuilder('\phpbb\files\factory')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $factory_mock->expects($this->any())
+ ->method('get')
+ ->willReturn(new \phpbb\files\filespec(
+ $this->filesystem,
+ $this->language,
+ $this->php_ini,
+ new \FastImageSize\FastImageSize(),
+ $this->phpbb_root_path,
+ $this->mimetype_guesser
+ ));
+
+ $this->container = new phpbb_mock_container_builder($phpbb_root_path, $phpEx);
+ $this->container->set('files.filespec', new \phpbb\files\filespec(
+ $this->filesystem,
+ $this->language,
+ $this->php_ini,
+ new \FastImageSize\FastImageSize(),
+ $phpbb_root_path,
+ new \phpbb\mimetype\guesser(array(
+ 'mimetype.extension_guesser' => new \phpbb\mimetype\extension_guesser(),
+ ))));
+ $this->container->set('files.types.form', new \phpbb\files\types\form(
+ $factory_mock,
+ $this->language,
+ $this->php_ini,
+ $this->plupload,
+ $this->request
+ ));
+ $this->container->set('files.types.local', new \phpbb\files\types\local(
+ $factory_mock,
+ $this->language,
+ $this->php_ini,
+ $this->request
+ ));
+ $this->factory = new \phpbb\files\factory($this->container);
+ $this->files_upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
+ $this->phpbb_dispatcher = new phpbb_mock_event_dispatcher();
+ $this->user = new \phpbb\user($this->language, '\phpbb\datetime');
+
+
+ $this->upload = new \phpbb\attachment\upload(
+ $this->auth,
+ $this->cache,
+ $this->config,
+ $this->files_upload,
+ $this->language,
+ $this->mimetype_guesser,
+ $this->phpbb_dispatcher,
+ $this->plupload,
+ $this->user,
+ $this->phpbb_root_path
+ );
+ }
+
+ public function data_upload()
+ {
+ return array(
+ array('foobar', 1, false,
+ array(),
+ array(
+ 'error' => array(
+ 'Upload initiated but no valid file upload form found.',
+ ),
+ 'post_attach' => false,
+ )
+ ),
+ array('foobar', 1, true,
+ array(
+ 'realname' => 'foobar.jpg',
+ 'type' => 'jpg',
+ 'size' => 100,
+ ),
+ array(
+ 'error' => array(
+ 'NOT_UPLOADED',
+ 'The image file you tried to attach is invalid.',
+ ),
+ 'post_attach' => false,
+ 'thumbnail' => 1,
+ )
+ ),
+ array('foobar', 1, true,
+ array(),
+ array(
+ 'error' => array(
+ 'NOT_UPLOADED',
+ ),
+ 'post_attach' => false,
+ 'thumbnail' => 0,
+ )
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider data_upload
+ */
+ public function test_upload($form_name, $forum_id, $local, $filedata, $expected)
+ {
+ $filedata = $this->upload->upload($form_name, $forum_id, $local, '', false, $filedata);
+
+ $this->assertSame($expected, $filedata);
+ }
+
+ public function test_init_error()
+ {
+ $filespec = $this->getMockBuilder('\phpbb\files\filespec')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $filespec->expects($this->any())
+ ->method('init_error')
+ ->willReturn(true);
+ $filespec->expects($this->any())
+ ->method('set_upload_namespace')
+ ->willReturnSelf();
+ $filespec->expects($this->any())
+ ->method('set_upload_ary')
+ ->willReturnSelf();
+ $this->container->set('files.filespec', $filespec);
+ $factory_mock = $this->getMockBuilder('\phpbb\files\factory')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $factory_mock->expects($this->any())
+ ->method('get')
+ ->willReturn($filespec);
+ $this->container->set('files.types.local', new \phpbb\files\types\local(
+ $factory_mock,
+ $this->language,
+ $this->php_ini,
+ $this->request
+ ));
+
+ $this->upload = new \phpbb\attachment\upload(
+ $this->auth,
+ $this->cache,
+ $this->config,
+ $this->files_upload,
+ $this->language,
+ $this->mimetype_guesser,
+ $this->phpbb_dispatcher,
+ $this->plupload,
+ $this->user,
+ $this->phpbb_root_path
+ );
+
+ $filedata = $this->upload->upload('foobar', 1, true);
+
+ $this->assertSame(array(
+ 'error' => array(),
+ 'post_attach' => false,
+ ), $filedata);
+ }
+
+ public function data_image_upload()
+ {
+ return array(
+ array(false, false, array(),
+ array(
+ 'error' => array('The image file you tried to attach is invalid.'),
+ 'post_attach' => false,
+ 'thumbnail' => 1,
+ )
+ ),
+ array(false, true, array(),
+ array(
+ 'error' => array('The image file you tried to attach is invalid.'),
+ 'post_attach' => false,
+ 'thumbnail' => 1,
+ )
+ ),
+ array(true, false, array(),
+ array(
+ 'error' => array(),
+ 'post_attach' => true,
+ // thumbnail gets reset to 0 as creation was not possible
+ 'thumbnail' => 0,
+ 'filesize' => 100,
+ 'mimetype' => 'jpg',
+ 'extension' => 'jpg',
+ 'real_filename' => 'foobar.jpg',
+ )
+ ),
+ array(true, false,
+ array(
+ 'check_attachment_content' => true,
+ 'mime_triggers' => '',
+ ),
+ array(
+ 'error' => array(),
+ 'post_attach' => true,
+ // thumbnail gets reset to 0 as creation was not possible
+ 'thumbnail' => 0,
+ 'filesize' => 100,
+ 'mimetype' => 'jpg',
+ 'extension' => 'jpg',
+ 'real_filename' => 'foobar.jpg',
+ )
+ ),
+ array(true, false,
+ array(
+ 'attachment_quota' => 150,
+ ),
+ array(
+ 'error' => array(),
+ 'post_attach' => true,
+ // thumbnail gets reset to 0 as creation was not possible
+ 'thumbnail' => 0,
+ 'filesize' => 100,
+ 'mimetype' => 'jpg',
+ 'extension' => 'jpg',
+ 'real_filename' => 'foobar.jpg',
+ )
+ ),
+ array(true, false,
+ array(
+ 'attachment_quota' => 50,
+ ),
+ array(
+ 'error' => array(
+ 'ATTACH_QUOTA_REACHED',
+ ),
+ 'post_attach' => false,
+ 'thumbnail' => 1,
+ 'filesize' => 100,
+ 'mimetype' => 'jpg',
+ 'extension' => 'jpg',
+ 'real_filename' => 'foobar.jpg',
+ )
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider data_image_upload
+ */
+ public function test_image_upload($is_image, $plupload_active, $config_data, $expected)
+ {
+ $filespec = $this->getMock('\phpbb\files\filespec',
+ array(
+ 'init_error',
+ 'is_image',
+ 'move_file',
+ 'is_uploaded',
+ ),
+ array(
+ $this->filesystem,
+ $this->language,
+ $this->php_ini,
+ new \FastImageSize\FastImageSize(),
+ $this->phpbb_root_path,
+ $this->mimetype_guesser,
+ $this->plupload
+ ));
+ foreach ($config_data as $key => $value)
+ {
+ $this->config[$key] = $value;
+ }
+ $filespec->set_upload_namespace($this->files_upload);
+ $filespec->expects($this->any())
+ ->method('init_error')
+ ->willReturn(false);
+ $filespec->expects($this->any())
+ ->method('is_image')
+ ->willReturn($is_image);
+ $filespec->expects($this->any())
+ ->method('is_uploaded')
+ ->willReturn(true);
+ $filespec->expects($this->any())
+ ->method('move_file')
+ ->willReturn(false);
+ $this->container->set('files.filespec', $filespec);
+ $factory_mock = $this->getMockBuilder('\phpbb\files\factory')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $factory_mock->expects($this->any())
+ ->method('get')
+ ->willReturn($filespec);
+ $this->container->set('files.types.local', new \phpbb\files\types\local(
+ $factory_mock,
+ $this->language,
+ $this->php_ini,
+ $this->request
+ ));
+
+ $plupload = $this->getMockBuilder('\phpbb\plupload\plupload')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $plupload->expects($this->any())
+ ->method('is_active')
+ ->willReturn($plupload_active);
+ if ($plupload_active)
+ {
+ $plupload->expects($this->once())
+ ->method('emit_error')
+ ->with(104, 'ATTACHED_IMAGE_NOT_IMAGE')
+ ->willReturn(false);
+ }
+ $this->upload = new \phpbb\attachment\upload(
+ $this->auth,
+ $this->cache,
+ $this->config,
+ $this->files_upload,
+ $this->language,
+ $this->mimetype_guesser,
+ $this->phpbb_dispatcher,
+ $plupload,
+ $this->user,
+ $this->phpbb_root_path
+ );
+
+ $filedata = $this->upload->upload('foobar', 1, true, '', false, array(
+ 'realname' => 'foobar.jpg',
+ 'type' => 'jpg',
+ 'size' => 100,
+ ));
+
+ foreach ($expected as $key => $entry)
+ {
+ $this->assertEquals($entry, $filedata[$key]);
+ }
+
+ // Reset config data
+ foreach ($config_data as $key => $value)
+ {
+ $this->config->delete($key);
+ }
+ }
+}
diff --git a/tests/content_visibility/delete_post_test.php b/tests/content_visibility/delete_post_test.php
index b59b6493d4..ba0a21a1a4 100644
--- a/tests/content_visibility/delete_post_test.php
+++ b/tests/content_visibility/delete_post_test.php
@@ -312,12 +312,15 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case
$lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx);
$lang = new \phpbb\language\language($lang_loader);
$user = new \phpbb\user($lang, '\phpbb\datetime');
+ $attachment_delete = new \phpbb\attachment\delete($config, $db, new \phpbb_mock_event_dispatcher(), new \phpbb\filesystem\filesystem(), new \phpbb\attachment\resync($db), $phpbb_root_path);
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$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, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE));
+ // Works as a workaround for tests
+ $phpbb_container->set('attachment.manager', $attachment_delete);
delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $reason);
diff --git a/tests/dbal/boolean_processor_test.php b/tests/dbal/boolean_processor_test.php
new file mode 100644
index 0000000000..8662485ac8
--- /dev/null
+++ b/tests/dbal/boolean_processor_test.php
@@ -0,0 +1,306 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
+require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php';
+
+class phpbb_boolean_processor_test extends phpbb_database_test_case
+{
+ public function getDataSet()
+ {
+ return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/boolean_processor.xml');
+ }
+
+ public function test_single_not_like()
+ {
+ $db = $this->new_dbal();
+
+ $db->sql_return_on_error(true);
+
+ $sql_ary = array(
+ 'SELECT' => 'u.user_id',
+ 'FROM' => array(
+ 'phpbb_users' => 'u',
+ ),
+ 'WHERE' => array('u.username_clean', 'NOT_LIKE', 'gr' . $db->get_any_char()),
+ 'ORDER_BY' => 'u.user_id',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
+ $result = $db->sql_query($sql);
+
+ $db->sql_return_on_error(false);
+
+ $this->assertEquals(array(
+ array('user_id' => '1'),
+ array('user_id' => '2'),
+ array('user_id' => '3'),
+ array('user_id' => '6'),
+ ), $db->sql_fetchrowset($result),
+ ($result === false) ?
+ "SQL ERROR:<br>" . var_export($sql, true) . "<br>" . $db->sql_error() :
+ var_export($sql, true) . ' ' . var_export($result, true)
+ );
+ }
+
+ public function test_single_like()
+ {
+ $db = $this->new_dbal();
+
+ $db->sql_return_on_error(true);
+
+ $sql_ary = array(
+ 'SELECT' => 'u.user_id',
+ 'FROM' => array(
+ 'phpbb_users' => 'u',
+ ),
+ 'WHERE' => array('u.username_clean', 'LIKE', 'gr' . $db->get_any_char()),
+ 'ORDER_BY' => 'u.user_id',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
+ $result = $db->sql_query($sql);
+
+ $db->sql_return_on_error(false);
+
+ $this->assertEquals(array(
+ array('user_id' => '4'),
+ array('user_id' => '5'),
+ ), $db->sql_fetchrowset($result),
+ ($result === false) ?
+ "SQL ERROR:<br>" . var_export($sql, true) . "<br>" . $db->sql_error() :
+ var_export($sql, true) . ' ' . var_export($result, true)
+ );
+ }
+
+ public function test_single_not_in()
+ {
+ $db = $this->new_dbal();
+
+ $db->sql_return_on_error(true);
+
+ $sql_ary = array(
+ 'SELECT' => 'u.user_id',
+ 'FROM' => array(
+ 'phpbb_users' => 'u',
+ ),
+ 'WHERE' => array('u.user_id', 'NOT_IN', array(3,4,5)),
+ 'ORDER_BY' => 'u.user_id',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
+ $result = $db->sql_query($sql);
+
+ $db->sql_return_on_error(false);
+
+ $this->assertEquals(array(
+ array('user_id' => '1'),
+ array('user_id' => '2'),
+ array('user_id' => '6'),
+ ), $db->sql_fetchrowset($result),
+ ($result === false) ?
+ "SQL ERROR:<br>" . var_export($sql, true) . "<br>" . $db->sql_error() :
+ var_export($sql, true) . ' ' . var_export($result, true)
+ );
+ }
+
+ public function test_single_in()
+ {
+ $db = $this->new_dbal();
+
+ $db->sql_return_on_error(true);
+
+ $sql_ary = array(
+ 'SELECT' => 'u.user_id',
+ 'FROM' => array(
+ 'phpbb_users' => 'u',
+ ),
+ 'WHERE' => array('u.user_id', 'IN', array(3,4,5)),
+ 'ORDER_BY' => 'u.user_id',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
+ $result = $db->sql_query($sql);
+
+ $db->sql_return_on_error(false);
+
+ $this->assertEquals(array(
+ array('user_id' => '3'),
+ array('user_id' => '4'),
+ array('user_id' => '5'),
+ ), $db->sql_fetchrowset($result),
+ ($result === false) ?
+ "SQL ERROR:<br>" . var_export($sql, true) . "<br>" . $db->sql_error() :
+ var_export($sql, true) . ' ' . var_export($result, true)
+ );
+ }
+
+ public function test_and_of_or_of_and()
+ {
+ $db = $this->new_dbal();
+
+ $db->sql_return_on_error(true);
+
+ $sql_ary = array(
+ 'SELECT' => 'u.user_id',
+ 'FROM' => array(
+ 'phpbb_users' => 'u',
+ 'phpbb_user_group' => 'ug',
+ ),
+ 'LEFT_JOIN' => array(
+ array(
+ 'FROM' => array(
+ 'phpbb_banlist' => 'b',
+ ),
+ 'ON' => 'u.user_id = b.ban_userid',
+ ),
+ ),
+ 'WHERE' => array('AND',
+ array('OR',
+ array('AND',
+ array('ug.user_id', 'IN', array(1, 2, 3, 4)),
+ array('ug.group_id', '=', 2),
+ ),
+ array('AND',
+ array('ug.group_id', '=', 1),
+ array('b.ban_id', 'IS_NOT', NULL),
+ ),
+ ),
+ array('u.user_id', '=', 'ug.user_id'),
+ ),
+ 'ORDER_BY' => 'u.user_id',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
+ $result = $db->sql_query($sql);
+
+ $db->sql_return_on_error(false);
+
+ $this->assertEquals(array(
+ array('user_id' => '2'),
+ array('user_id' => '4'),
+ ), $db->sql_fetchrowset($result),
+ ($result === false) ?
+ "SQL ERROR:<br>" . var_export($sql, true) . "<br>" . $db->sql_error() :
+ var_export($sql, true) . ' ' . var_export($result, true)
+ );
+ }
+
+ public function test_triple_and_with_in()
+ {
+ $db = $this->new_dbal();
+
+ $db->sql_return_on_error(true);
+
+ $sql_ary = array(
+ 'SELECT' => 'u.user_id',
+ 'FROM' => array(
+ 'phpbb_users' => 'u',
+ 'phpbb_user_group' => 'ug',
+ ),
+ 'WHERE' => array('AND',
+ array('ug.user_id', 'IN', array(1, 2, 3, 4)),
+ array('ug.group_id', '=', 1),
+ array('u.user_id', '=', 'ug.user_id'),
+ ),
+ 'ORDER_BY' => 'u.user_id',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
+ $result = $db->sql_query($sql);
+
+ $db->sql_return_on_error(false);
+
+ $this->assertEquals(array(
+ array('user_id' => '1'),
+ array('user_id' => '2'),
+ array('user_id' => '3'),
+ ), $db->sql_fetchrowset($result),
+ ($result === false) ?
+ "SQL ERROR:<br>" . var_export($sql, true) . "<br>" . $db->sql_error() :
+ var_export($sql, true) . ' ' . var_export($result, true)
+ );
+
+ }
+
+ public function test_double_and_with_not_of_or()
+ {
+ $db = $this->new_dbal();
+
+ $db->sql_return_on_error(true);
+
+ $sql_ary = array(
+ 'SELECT' => 'u.user_id',
+ 'FROM' => array(
+ 'phpbb_users' => 'u',
+ 'phpbb_user_group' => 'ug',
+ ),
+ 'WHERE' => array('AND',
+ array('NOT',
+ array('OR',
+ array('ug.group_id', '=', 1),
+ array('ug.group_id', '=', 2),
+ ),
+ ),
+ array('u.user_id', '=', 'ug.user_id'),
+ ),
+ 'ORDER_BY' => 'u.user_id',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
+ $result = $db->sql_query($sql);
+
+ $db->sql_return_on_error(false);
+
+ $this->assertEquals(array(), $db->sql_fetchrowset($result),
+ ($result === false) ?
+ "SQL ERROR:<br>" . var_export($sql, true) . "<br>" . $db->sql_error() :
+ var_export($sql, true) . ' ' . var_export($result, true)
+ );
+ }
+
+ public function test_triple_and_with_is_null()
+ {
+ $db = $this->new_dbal();
+
+ $db->sql_return_on_error(true);
+
+ $sql_ary = array(
+ 'SELECT' => 'u.username',
+ 'FROM' => array(
+ 'phpbb_users' => 'u',
+ 'phpbb_user_group' => 'ug',
+ ),
+ 'LEFT_JOIN' => array(
+ array(
+ 'FROM' => array(
+ 'phpbb_banlist' => 'b',
+ ),
+ 'ON' => 'u.user_id = b.ban_userid',
+ ),
+ ),
+ 'WHERE' => array('AND',
+ array('ug.group_id', '=', 1),
+ array('u.user_id', '=', 'ug.user_id'),
+ array('b.ban_id', 'IS', NULL),
+ ),
+ 'ORDER_BY' => 'u.username',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
+ $result = $db->sql_query($sql);
+
+ $db->sql_return_on_error(false);
+
+ $this->assertEquals(array(
+ array('username' => 'helper'),
+ array('username' => 'mass email'),
+ ), $db->sql_fetchrowset($result),
+ ($result === false) ?
+ "SQL ERROR:<br>" . var_export($sql, true) . "<br>" . $db->sql_error() :
+ var_export($sql, true) . ' ' . var_export($result, true)
+ );
+ }
+}
diff --git a/tests/dbal/fixtures/boolean_processor.xml b/tests/dbal/fixtures/boolean_processor.xml
new file mode 100644
index 0000000000..c5da677116
--- /dev/null
+++ b/tests/dbal/fixtures/boolean_processor.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<dataset>
+ <table name="phpbb_banlist">
+ <column>ban_id</column>
+ <column>ban_userid</column>
+ <row>
+ <value>1</value>
+ <value>2</value>
+ </row>
+ </table>
+ <table name="phpbb_users">
+ <column>user_id</column>
+ <column>username</column>
+ <column>username_clean</column>
+ <column>user_permissions</column>
+ <column>user_sig</column>
+ <row>
+ <value>1</value>
+ <value>mass email</value>
+ <value>mass email</value>
+ <value></value>
+ <value></value>
+ </row>
+ <row>
+ <value>2</value>
+ <value>banned</value>
+ <value>banned</value>
+ <value></value>
+ <value></value>
+ </row>
+ <row>
+ <value>3</value>
+ <value>helper</value>
+ <value>helper</value>
+ <value></value>
+ <value></value>
+ </row>
+ <row>
+ <value>4</value>
+ <value>GroupBPal</value>
+ <value>groupbpal</value>
+ <value></value>
+ <value></value>
+ </row>
+ <row>
+ <value>5</value>
+ <value>GroupBPal2</value>
+ <value>groupBPal2</value>
+ <value></value>
+ <value></value>
+ </row>
+ <row>
+ <value>6</value>
+ <value>not in group</value>
+ <value>not in group</value>
+ <value></value>
+ <value></value>
+ </row>
+ </table>
+ <table name="phpbb_user_group">
+ <column>user_id</column>
+ <column>group_id</column>
+ <row>
+ <value>1</value>
+ <value>1</value>
+ </row>
+ <row>
+ <value>2</value>
+ <value>1</value>
+ </row>
+ <row>
+ <value>3</value>
+ <value>1</value>
+ </row>
+ <row>
+ <value>4</value>
+ <value>2</value>
+ </row>
+ <row>
+ <value>5</value>
+ <value>2</value>
+ </row>
+ </table>
+</dataset>
diff --git a/tests/di/fixtures/other_config/production/config.yml b/tests/di/fixtures/other_config/production/config.yml
new file mode 100644
index 0000000000..fcfa84f68b
--- /dev/null
+++ b/tests/di/fixtures/other_config/production/config.yml
@@ -0,0 +1,2 @@
+core:
+ require_dev_dependencies: true
diff --git a/tests/di/fixtures/other_config/production/container/environment.yml b/tests/di/fixtures/other_config/production/container/environment.yml
new file mode 100644
index 0000000000..4960562a6c
--- /dev/null
+++ b/tests/di/fixtures/other_config/production/container/environment.yml
@@ -0,0 +1,29 @@
+parameters:
+ other_config: true
+
+services:
+ config.php:
+ synthetic: true
+
+ dbal.conn:
+ class: phpbb\db\driver\factory
+ arguments:
+ - @service_container
+
+ dispatcher:
+ class: phpbb\db\driver\container_mock
+
+ ext.manager:
+ class: phpbb\extension\manager_mock
+
+ template.twig.environment:
+ class: Exception
+ arguments:
+ - ~
+ - ~
+ - ~
+ - ~
+ - ~
+ - ~
+ - ~
+ - []
diff --git a/tests/event/exception_listener_test.php b/tests/event/exception_listener_test.php
index 608cde4f9b..e643fadf2c 100644
--- a/tests/event/exception_listener_test.php
+++ b/tests/event/exception_listener_test.php
@@ -83,10 +83,8 @@ class exception_listener extends phpbb_test_case
$lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx);
$lang = new \phpbb\language\language($lang_loader);
- $user = new \phpbb\user($lang, '\phpbb\datetime');
- $user->add_lang('common');
- $exception_listener = new \phpbb\event\kernel_exception_subscriber($template, $user);
+ $exception_listener = new \phpbb\event\kernel_exception_subscriber($template, $lang);
$event = new \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent($this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), $request, \Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST, $exception);
$exception_listener->on_kernel_exception($event);
diff --git a/tests/functions_user/delete_user_test.php b/tests/functions_user/delete_user_test.php
index 9e2caf9d21..6d2e1fa20a 100644
--- a/tests/functions_user/delete_user_test.php
+++ b/tests/functions_user/delete_user_test.php
@@ -25,7 +25,7 @@ class phpbb_functions_user_delete_user_test extends phpbb_database_test_case
{
parent::setUp();
- global $cache, $config, $db, $phpbb_dispatcher, $phpbb_container;
+ global $cache, $config, $db, $phpbb_dispatcher, $phpbb_container, $phpbb_root_path;
$db = $this->db = $this->new_dbal();
$config = new \phpbb\config\config(array(
@@ -36,6 +36,8 @@ class phpbb_functions_user_delete_user_test extends phpbb_database_test_case
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$phpbb_container = new phpbb_mock_container_builder();
$phpbb_container->set('notification_manager', new phpbb_mock_notification_manager());
+ // Works as a workaround for tests
+ $phpbb_container->set('attachment.manager', new \phpbb\attachment\delete($config, $db, new \phpbb_mock_event_dispatcher(), new \phpbb\filesystem\filesystem(), new \phpbb\attachment\resync($db), $phpbb_root_path));
$phpbb_container->set(
'auth.provider.db',
new phpbb_mock_auth_provider()
diff --git a/tests/installer/installer_config_test.php b/tests/installer/installer_config_test.php
index 7de23aea36..c8e482e260 100644
--- a/tests/installer/installer_config_test.php
+++ b/tests/installer/installer_config_test.php
@@ -62,13 +62,18 @@ class phpbb_installer_config_test extends phpbb_test_case
$this->config->increment_current_task_progress(2);
- $this->assertEquals(array(
- 'last_task_module_name' => 'bar',
- 'last_task_name' => 'foo',
- 'max_task_progress' => 10,
- 'current_task_progress' => 3,
- ),
- $this->config->get_progress_data()
+ // We only want to check these values
+ $result = $this->config->get_progress_data();
+ $expected_result = array(
+ 'last_task_module_name' => 'bar',
+ 'last_task_name' => 'foo',
+ 'max_task_progress' => 10,
+ 'current_task_progress' => 3,
);
+
+ foreach ($expected_result as $key => $value)
+ {
+ $this->assertEquals($value, $result[$key]);
+ }
}
}
diff --git a/tests/privmsgs/delete_user_pms_test.php b/tests/privmsgs/delete_user_pms_test.php
index 0f061e9784..9d6ba7a917 100644
--- a/tests/privmsgs/delete_user_pms_test.php
+++ b/tests/privmsgs/delete_user_pms_test.php
@@ -85,12 +85,14 @@ class phpbb_privmsgs_delete_user_pms_test extends phpbb_database_test_case
*/
public function test_delete_user_pms($delete_user, $remaining_privmsgs, $remaining_privmsgs_to)
{
- global $db, $phpbb_container;
+ global $db, $phpbb_container, $phpbb_root_path;
$db = $this->new_dbal();
$phpbb_container = new phpbb_mock_container_builder();
$phpbb_container->set('notification_manager', new phpbb_mock_notification_manager());
+ // Works as a workaround for tests
+ $phpbb_container->set('attachment.manager', new \phpbb\attachment\delete(new \phpbb\config\config(array()), $db, new \phpbb_mock_event_dispatcher(), new \phpbb\filesystem\filesystem(), new \phpbb\attachment\resync($db), $phpbb_root_path));
phpbb_delete_user_pms($delete_user);
diff --git a/travis/setup-php-extensions.sh b/travis/setup-php-extensions.sh
index c0defe44ef..d9544858b7 100755
--- a/travis/setup-php-extensions.sh
+++ b/travis/setup-php-extensions.sh
@@ -48,6 +48,9 @@ then
echo 'Enabling APC PHP extension'
register_php_extension 'apc' "$php_ini_file"
echo 'apc.enable_cli=1' >> "$php_ini_file"
+else
+ echo 'Disabling Opcache'
+ echo 'opcache.enable=0' >> "$php_ini_file"
fi
# redis