aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/phpbb')
-rw-r--r--phpBB/phpbb/auth/auth.php22
-rw-r--r--phpBB/phpbb/auth/provider/apache.php32
-rw-r--r--phpBB/phpbb/auth/provider/base.php12
-rw-r--r--phpBB/phpbb/auth/provider/db.php106
-rw-r--r--phpBB/phpbb/auth/provider/ldap.php23
-rw-r--r--phpBB/phpbb/auth/provider/oauth/oauth.php43
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/base.php12
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/bitly.php12
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/exception.php12
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/facebook.php20
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/google.php20
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/service_interface.php14
-rw-r--r--phpBB/phpbb/auth/provider/oauth/token_storage.php23
-rw-r--r--phpBB/phpbb/auth/provider/provider_interface.php18
-rw-r--r--phpBB/phpbb/auth/provider_collection.php65
-rw-r--r--phpBB/phpbb/avatar/driver/driver.php22
-rw-r--r--phpBB/phpbb/avatar/driver/driver_interface.php11
-rw-r--r--phpBB/phpbb/avatar/driver/gravatar.php31
-rw-r--r--phpBB/phpbb/avatar/driver/local.php30
-rw-r--r--phpBB/phpbb/avatar/driver/remote.php24
-rw-r--r--phpBB/phpbb/avatar/driver/upload.php57
-rw-r--r--phpBB/phpbb/avatar/manager.php49
-rw-r--r--phpBB/phpbb/cache/driver/apc.php11
-rw-r--r--phpBB/phpbb/cache/driver/base.php226
-rw-r--r--phpBB/phpbb/cache/driver/driver_interface.php18
-rw-r--r--phpBB/phpbb/cache/driver/eaccelerator.php11
-rw-r--r--phpBB/phpbb/cache/driver/file.php219
-rw-r--r--phpBB/phpbb/cache/driver/memcache.php11
-rw-r--r--phpBB/phpbb/cache/driver/memory.php200
-rw-r--r--phpBB/phpbb/cache/driver/null.php13
-rw-r--r--phpBB/phpbb/cache/driver/redis.php11
-rw-r--r--phpBB/phpbb/cache/driver/wincache.php11
-rw-r--r--phpBB/phpbb/cache/driver/xcache.php11
-rw-r--r--phpBB/phpbb/cache/service.php42
-rw-r--r--phpBB/phpbb/captcha/char_cube3d.php277
-rw-r--r--phpBB/phpbb/captcha/colour_manager.php527
-rw-r--r--phpBB/phpbb/captcha/factory.php88
-rw-r--r--phpBB/phpbb/captcha/gd.php1847
-rw-r--r--phpBB/phpbb/captcha/gd_wave.php845
-rw-r--r--phpBB/phpbb/captcha/non_gd.php386
-rw-r--r--phpBB/phpbb/captcha/plugins/captcha_abstract.php390
-rw-r--r--phpBB/phpbb/captcha/plugins/gd.php130
-rw-r--r--phpBB/phpbb/captcha/plugins/gd_wave.php42
-rw-r--r--phpBB/phpbb/captcha/plugins/nogd.php42
-rw-r--r--phpBB/phpbb/captcha/plugins/qa.php1009
-rw-r--r--phpBB/phpbb/captcha/plugins/recaptcha.php330
-rw-r--r--phpBB/phpbb/class_loader.php12
-rw-r--r--phpBB/phpbb/composer.json27
-rw-r--r--phpBB/phpbb/config/config.php13
-rw-r--r--phpBB/phpbb/config/db.php17
-rw-r--r--phpBB/phpbb/config/db_text.php22
-rw-r--r--phpBB/phpbb/config_php_file.php160
-rw-r--r--phpBB/phpbb/console/application.php111
-rw-r--r--phpBB/phpbb/console/command/cache/purge.php89
-rw-r--r--phpBB/phpbb/console/command/command.php23
-rw-r--r--phpBB/phpbb/console/command/config/command.php14
-rw-r--r--phpBB/phpbb/console/command/config/delete.php33
-rw-r--r--phpBB/phpbb/console/command/config/get.php34
-rw-r--r--phpBB/phpbb/console/command/config/increment.php34
-rw-r--r--phpBB/phpbb/console/command/config/set.php34
-rw-r--r--phpBB/phpbb/console/command/config/set_atomic.php39
-rw-r--r--phpBB/phpbb/console/command/cron/cron_list.php111
-rw-r--r--phpBB/phpbb/console/command/cron/run.php171
-rw-r--r--phpBB/phpbb/console/command/db/migrate.php133
-rw-r--r--phpBB/phpbb/console/command/dev/migration_tips.php64
-rw-r--r--phpBB/phpbb/console/command/extension/command.php18
-rw-r--r--phpBB/phpbb/console/command/extension/disable.php21
-rw-r--r--phpBB/phpbb/console/command/extension/enable.php21
-rw-r--r--phpBB/phpbb/console/command/extension/purge.php21
-rw-r--r--phpBB/phpbb/console/command/extension/show.php22
-rw-r--r--phpBB/phpbb/console/command/fixup/recalculate_email_hash.php20
-rw-r--r--phpBB/phpbb/content_visibility.php245
-rw-r--r--phpBB/phpbb/controller/exception.php11
-rw-r--r--phpBB/phpbb/controller/helper.php97
-rw-r--r--phpBB/phpbb/controller/provider.php47
-rw-r--r--phpBB/phpbb/controller/resolver.php49
-rw-r--r--phpBB/phpbb/cron/manager.php28
-rw-r--r--phpBB/phpbb/cron/task/base.php12
-rw-r--r--phpBB/phpbb/cron/task/core/prune_all_forums.php18
-rw-r--r--phpBB/phpbb/cron/task/core/prune_forum.php18
-rw-r--r--phpBB/phpbb/cron/task/core/prune_notifications.php12
-rw-r--r--phpBB/phpbb/cron/task/core/prune_shadow_topics.php200
-rw-r--r--phpBB/phpbb/cron/task/core/queue.php14
-rw-r--r--phpBB/phpbb/cron/task/core/tidy_cache.php12
-rw-r--r--phpBB/phpbb/cron/task/core/tidy_database.php14
-rw-r--r--phpBB/phpbb/cron/task/core/tidy_plupload.php12
-rw-r--r--phpBB/phpbb/cron/task/core/tidy_search.php26
-rw-r--r--phpBB/phpbb/cron/task/core/tidy_sessions.php12
-rw-r--r--phpBB/phpbb/cron/task/core/tidy_warnings.php14
-rw-r--r--phpBB/phpbb/cron/task/parametrized.php12
-rw-r--r--phpBB/phpbb/cron/task/task.php11
-rw-r--r--phpBB/phpbb/cron/task/wrapper.php14
-rw-r--r--phpBB/phpbb/datetime.php56
-rw-r--r--phpBB/phpbb/db/driver/driver.php255
-rw-r--r--phpBB/phpbb/db/driver/driver_interface.php453
-rw-r--r--phpBB/phpbb/db/driver/factory.php443
-rw-r--r--phpBB/phpbb/db/driver/firebird.php532
-rw-r--r--phpBB/phpbb/db/driver/mssql.php56
-rw-r--r--phpBB/phpbb/db/driver/mssql_base.php22
-rw-r--r--phpBB/phpbb/db/driver/mssql_odbc.php44
-rw-r--r--phpBB/phpbb/db/driver/mssqlnative.php53
-rw-r--r--phpBB/phpbb/db/driver/mysql.php69
-rw-r--r--phpBB/phpbb/db/driver/mysql_base.php37
-rw-r--r--phpBB/phpbb/db/driver/mysqli.php91
-rw-r--r--phpBB/phpbb/db/driver/oracle.php56
-rw-r--r--phpBB/phpbb/db/driver/postgres.php69
-rw-r--r--phpBB/phpbb/db/driver/sqlite.php69
-rw-r--r--phpBB/phpbb/db/driver/sqlite3.php404
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/local_url_bbcode.php23
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_0.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php12
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php12
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php12
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/acp_style_components_module.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/allow_cdn.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/alpha1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/alpha2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/alpha3.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php44
-rw-r--r--phpBB/phpbb/db/migration/data/v310/avatar_types.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/avatars.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/beta1.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/beta2.php33
-rw-r--r--phpBB/phpbb/db/migration/data/v310/beta3.php36
-rw-r--r--phpBB/phpbb/db/migration/data/v310/beta4.php33
-rw-r--r--phpBB/phpbb/db/migration/data/v310/board_contact_name.php34
-rw-r--r--phpBB/phpbb/db/migration/data/v310/boardindex.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/captcha_plugins.php44
-rw-r--r--phpBB/phpbb/db/migration/data/v310/config_db_text.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/contact_admin_acp_module.php31
-rw-r--r--phpBB/phpbb/db/migration/data/v310/contact_admin_form.php41
-rw-r--r--phpBB/phpbb/db/migration/data/v310/dev.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/extensions.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/extensions_version_check_force_unstable.php29
-rw-r--r--phpBB/phpbb/db/migration/data/v310/forgot_password.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/jquery_update.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/jquery_update2.php37
-rw-r--r--phpBB/phpbb/db/migration/data/v310/live_searches_config.php29
-rw-r--r--phpBB/phpbb/db/migration/data/v310/migrations_table.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/mod_rewrite.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php12
-rw-r--r--phpBB/phpbb/db/migration/data/v310/namespaces.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/notification_options_reconvert.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/notifications.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/notifications_cron.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/notifications_cron_p2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/notifications_use_full_name.php184
-rw-r--r--phpBB/phpbb/db/migration/data/v310/passwords.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/passwords_convert_p1.php84
-rw-r--r--phpBB/phpbb/db/migration/data/v310/passwords_convert_p2.php49
-rw-r--r--phpBB/phpbb/db/migration/data/v310/passwords_p2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/plupload.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php12
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_aol.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_aol_cleanup.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_change_load_settings.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_contact_field.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php61
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_field_validation_length.php90
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php61
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_icq.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_icq_cleanup.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_interests.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_location.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_location_cleanup.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_show_novalue.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_skype.php61
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php61
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_types.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_website.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_website_cleanup.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_wlm.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_wlm_cleanup.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_yahoo.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_yahoo_cleanup.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php61
-rw-r--r--phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php50
-rw-r--r--phpBB/phpbb/db/migration/data/v310/rc1.php39
-rw-r--r--phpBB/phpbb/db/migration/data/v310/rc2.php31
-rw-r--r--phpBB/phpbb/db/migration/data/v310/rc3.php35
-rw-r--r--phpBB/phpbb/db/migration/data/v310/rc4.php32
-rw-r--r--phpBB/phpbb/db/migration/data/v310/rc5.php33
-rw-r--r--phpBB/phpbb/db/migration/data/v310/remove_acp_styles_cache.php51
-rw-r--r--phpBB/phpbb/db/migration/data/v310/rename_too_long_indexes.php38
-rw-r--r--phpBB/phpbb/db/migration/data/v310/reported_posts_display.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php37
-rw-r--r--phpBB/phpbb/db/migration/data/v310/search_type.php34
-rw-r--r--phpBB/phpbb/db/migration/data/v310/signature_module_auth.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php13
-rw-r--r--phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/softdelete_p1.php19
-rw-r--r--phpBB/phpbb/db/migration/data/v310/softdelete_p2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/style_update_p1.php12
-rw-r--r--phpBB/phpbb/db/migration/data/v310/style_update_p2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/teampage.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/timezone.php55
-rw-r--r--phpBB/phpbb/db/migration/data/v310/timezone_p2.php10
-rw-r--r--phpBB/phpbb/db/migration/data/v310/topic_sort_username.php44
-rw-r--r--phpBB/phpbb/db/migration/data/v310/ucp_popuppm_module.php10
-rw-r--r--phpBB/phpbb/db/migration/exception.php12
-rw-r--r--phpBB/phpbb/db/migration/helper.php12
-rw-r--r--phpBB/phpbb/db/migration/migration.php24
-rw-r--r--phpBB/phpbb/db/migration/profilefield_base_migration.php104
-rw-r--r--phpBB/phpbb/db/migration/schema_generator.php72
-rw-r--r--phpBB/phpbb/db/migration/tool/config.php14
-rw-r--r--phpBB/phpbb/db/migration/tool/config_text.php125
-rw-r--r--phpBB/phpbb/db/migration/tool/module.php21
-rw-r--r--phpBB/phpbb/db/migration/tool/permission.php26
-rw-r--r--phpBB/phpbb/db/migration/tool/tool_interface.php12
-rw-r--r--phpBB/phpbb/db/migrator.php103
-rw-r--r--phpBB/phpbb/db/sql_insert_buffer.php20
-rw-r--r--phpBB/phpbb/db/tools.php1003
-rw-r--r--phpBB/phpbb/di/container_builder.php405
-rw-r--r--phpBB/phpbb/di/extension/config.php43
-rw-r--r--phpBB/phpbb/di/extension/core.php12
-rw-r--r--phpBB/phpbb/di/extension/ext.php12
-rw-r--r--phpBB/phpbb/di/pass/collection_pass.php10
-rw-r--r--phpBB/phpbb/di/pass/kernel_pass.php62
-rw-r--r--phpBB/phpbb/di/service_collection.php52
-rw-r--r--phpBB/phpbb/di/service_collection_iterator.php46
-rw-r--r--phpBB/phpbb/error_collector.php10
-rw-r--r--phpBB/phpbb/event/data.php10
-rw-r--r--phpBB/phpbb/event/dispatcher.php15
-rw-r--r--phpBB/phpbb/event/dispatcher_interface.php40
-rw-r--r--phpBB/phpbb/event/extension_subscriber_loader.php35
-rw-r--r--phpBB/phpbb/event/kernel_exception_subscriber.php10
-rw-r--r--phpBB/phpbb/event/kernel_request_subscriber.php29
-rw-r--r--phpBB/phpbb/event/kernel_terminate_subscriber.php10
-rw-r--r--phpBB/phpbb/event/md_exporter.php440
-rw-r--r--phpBB/phpbb/event/php_exporter.php610
-rw-r--r--phpBB/phpbb/event/recursive_event_filter_iterator.php71
-rw-r--r--phpBB/phpbb/extension/base.php37
-rw-r--r--phpBB/phpbb/extension/exception.php10
-rw-r--r--phpBB/phpbb/extension/extension_interface.php19
-rw-r--r--phpBB/phpbb/extension/manager.php119
-rw-r--r--phpBB/phpbb/extension/metadata_manager.php148
-rw-r--r--phpBB/phpbb/extension/provider.php14
-rw-r--r--phpBB/phpbb/feed/attachments_base.php85
-rw-r--r--phpBB/phpbb/feed/base.php39
-rw-r--r--phpBB/phpbb/feed/factory.php26
-rw-r--r--phpBB/phpbb/feed/forum.php19
-rw-r--r--phpBB/phpbb/feed/forums.php12
-rw-r--r--phpBB/phpbb/feed/helper.php13
-rw-r--r--phpBB/phpbb/feed/news.php21
-rw-r--r--phpBB/phpbb/feed/overall.php16
-rw-r--r--phpBB/phpbb/feed/post_base.php54
-rw-r--r--phpBB/phpbb/feed/topic.php23
-rw-r--r--phpBB/phpbb/feed/topic_base.php35
-rw-r--r--phpBB/phpbb/feed/topics.php21
-rw-r--r--phpBB/phpbb/feed/topics_active.php23
-rw-r--r--phpBB/phpbb/filesystem.php13
-rw-r--r--phpBB/phpbb/finder.php (renamed from phpBB/phpbb/extension/finder.php)187
-rw-r--r--phpBB/phpbb/groupposition/exception.php13
-rw-r--r--phpBB/phpbb/groupposition/groupposition_interface.php12
-rw-r--r--phpBB/phpbb/groupposition/legend.php36
-rw-r--r--phpBB/phpbb/groupposition/teampage.php45
-rw-r--r--phpBB/phpbb/hook/finder.php12
-rw-r--r--phpBB/phpbb/json_response.php11
-rw-r--r--phpBB/phpbb/lock/db.php21
-rw-r--r--phpBB/phpbb/lock/flock.php11
-rw-r--r--phpBB/phpbb/log/log.php228
-rw-r--r--phpBB/phpbb/log/log_interface.php24
-rw-r--r--phpBB/phpbb/log/null.php19
-rw-r--r--phpBB/phpbb/message/admin_form.php191
-rw-r--r--phpBB/phpbb/message/form.php175
-rw-r--r--phpBB/phpbb/message/message.php282
-rw-r--r--phpBB/phpbb/message/topic_form.php158
-rw-r--r--phpBB/phpbb/message/user_form.php136
-rw-r--r--phpBB/phpbb/mimetype/content_guesser.php20
-rw-r--r--phpBB/phpbb/mimetype/extension_guesser.php18
-rw-r--r--phpBB/phpbb/mimetype/guesser.php56
-rw-r--r--phpBB/phpbb/mimetype/guesser_base.php18
-rw-r--r--phpBB/phpbb/mimetype/guesser_interface.php15
-rw-r--r--phpBB/phpbb/notification/exception.php13
-rw-r--r--phpBB/phpbb/notification/manager.php115
-rw-r--r--phpBB/phpbb/notification/method/base.php17
-rw-r--r--phpBB/phpbb/notification/method/email.php15
-rw-r--r--phpBB/phpbb/notification/method/jabber.php15
-rw-r--r--phpBB/phpbb/notification/method/messenger_base.php12
-rw-r--r--phpBB/phpbb/notification/method/method_interface.php11
-rw-r--r--phpBB/phpbb/notification/type/admin_activate_user.php17
-rw-r--r--phpBB/phpbb/notification/type/approve_post.php35
-rw-r--r--phpBB/phpbb/notification/type/approve_topic.php27
-rw-r--r--phpBB/phpbb/notification/type/base.php110
-rw-r--r--phpBB/phpbb/notification/type/bookmark.php42
-rw-r--r--phpBB/phpbb/notification/type/disapprove_post.php51
-rw-r--r--phpBB/phpbb/notification/type/disapprove_topic.php51
-rw-r--r--phpBB/phpbb/notification/type/group_request.php12
-rw-r--r--phpBB/phpbb/notification/type/group_request_approved.php12
-rw-r--r--phpBB/phpbb/notification/type/pm.php35
-rw-r--r--phpBB/phpbb/notification/type/post.php95
-rw-r--r--phpBB/phpbb/notification/type/post_in_queue.php26
-rw-r--r--phpBB/phpbb/notification/type/quote.php68
-rw-r--r--phpBB/phpbb/notification/type/report_pm.php66
-rw-r--r--phpBB/phpbb/notification/type/report_pm_closed.php32
-rw-r--r--phpBB/phpbb/notification/type/report_post.php65
-rw-r--r--phpBB/phpbb/notification/type/report_post_closed.php32
-rw-r--r--phpBB/phpbb/notification/type/topic.php58
-rw-r--r--phpBB/phpbb/notification/type/topic_in_queue.php18
-rw-r--r--phpBB/phpbb/notification/type/type_interface.php39
-rw-r--r--phpBB/phpbb/pagination.php62
-rw-r--r--phpBB/phpbb/passwords/driver/base.php35
-rw-r--r--phpBB/phpbb/passwords/driver/bcrypt.php25
-rw-r--r--phpBB/phpbb/passwords/driver/bcrypt_2y.php17
-rw-r--r--phpBB/phpbb/passwords/driver/bcrypt_wcf2.php84
-rw-r--r--phpBB/phpbb/passwords/driver/convert_password.php43
-rw-r--r--phpBB/phpbb/passwords/driver/driver_interface.php23
-rw-r--r--phpBB/phpbb/passwords/driver/helper.php37
-rw-r--r--phpBB/phpbb/passwords/driver/md5_mybb.php60
-rw-r--r--phpBB/phpbb/passwords/driver/md5_phpbb2.php123
-rw-r--r--phpBB/phpbb/passwords/driver/md5_vb.php60
-rw-r--r--phpBB/phpbb/passwords/driver/phpass.php15
-rw-r--r--phpBB/phpbb/passwords/driver/salted_md5.php33
-rw-r--r--phpBB/phpbb/passwords/driver/sha1.php52
-rw-r--r--phpBB/phpbb/passwords/driver/sha1_smf.php51
-rw-r--r--phpBB/phpbb/passwords/driver/sha1_wcf1.php60
-rw-r--r--phpBB/phpbb/passwords/driver/sha_xf1.php68
-rw-r--r--phpBB/phpbb/passwords/helper.php15
-rw-r--r--phpBB/phpbb/passwords/manager.php53
-rw-r--r--phpBB/phpbb/path_helper.php287
-rw-r--r--phpBB/phpbb/permissions.php19
-rw-r--r--phpBB/phpbb/php/ini.php12
-rw-r--r--phpBB/phpbb/plupload/plupload.php51
-rw-r--r--phpBB/phpbb/profilefields/lang_helper.php76
-rw-r--r--phpBB/phpbb/profilefields/manager.php98
-rw-r--r--phpBB/phpbb/profilefields/type/type_base.php13
-rw-r--r--phpBB/phpbb/profilefields/type/type_bool.php40
-rw-r--r--phpBB/phpbb/profilefields/type/type_date.php24
-rw-r--r--phpBB/phpbb/profilefields/type/type_dropdown.php42
-rw-r--r--phpBB/phpbb/profilefields/type/type_googleplus.php66
-rw-r--r--phpBB/phpbb/profilefields/type/type_int.php23
-rw-r--r--phpBB/phpbb/profilefields/type/type_interface.php21
-rw-r--r--phpBB/phpbb/profilefields/type/type_string.php11
-rw-r--r--phpBB/phpbb/profilefields/type/type_string_common.php35
-rw-r--r--phpBB/phpbb/profilefields/type/type_text.php11
-rw-r--r--phpBB/phpbb/profilefields/type/type_url.php10
-rw-r--r--phpBB/phpbb/recursive_dot_prefix_filter_iterator.php12
-rw-r--r--phpBB/phpbb/request/deactivated_super_global.php12
-rw-r--r--phpBB/phpbb/request/request.php12
-rw-r--r--phpBB/phpbb/request/request_interface.php12
-rw-r--r--phpBB/phpbb/request/type_cast_helper.php12
-rw-r--r--phpBB/phpbb/request/type_cast_helper_interface.php12
-rw-r--r--phpBB/phpbb/search/base.php34
-rw-r--r--phpBB/phpbb/search/fulltext_mysql.php28
-rw-r--r--phpBB/phpbb/search/fulltext_native.php27
-rw-r--r--phpBB/phpbb/search/fulltext_postgres.php59
-rw-r--r--phpBB/phpbb/search/fulltext_sphinx.php35
-rw-r--r--phpBB/phpbb/search/sphinx/config.php12
-rw-r--r--phpBB/phpbb/search/sphinx/config_comment.php10
-rw-r--r--phpBB/phpbb/search/sphinx/config_section.php10
-rw-r--r--phpBB/phpbb/search/sphinx/config_variable.php10
-rw-r--r--phpBB/phpbb/session.php118
-rw-r--r--phpBB/phpbb/symfony_request.php12
-rw-r--r--phpBB/phpbb/template/asset.php11
-rw-r--r--phpBB/phpbb/template/base.php16
-rw-r--r--phpBB/phpbb/template/context.php95
-rw-r--r--phpBB/phpbb/template/template.php11
-rw-r--r--phpBB/phpbb/template/twig/definition.php12
-rw-r--r--phpBB/phpbb/template/twig/environment.php47
-rw-r--r--phpBB/phpbb/template/twig/extension.php13
-rw-r--r--phpBB/phpbb/template/twig/lexer.php27
-rw-r--r--phpBB/phpbb/template/twig/loader.php17
-rw-r--r--phpBB/phpbb/template/twig/node/definenode.php19
-rw-r--r--phpBB/phpbb/template/twig/node/event.php26
-rw-r--r--phpBB/phpbb/template/twig/node/expression/binary/equalequal.php10
-rw-r--r--phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php10
-rw-r--r--phpBB/phpbb/template/twig/node/includeasset.php22
-rw-r--r--phpBB/phpbb/template/twig/node/includecss.php10
-rw-r--r--phpBB/phpbb/template/twig/node/includejs.php10
-rw-r--r--phpBB/phpbb/template/twig/node/includenode.php18
-rw-r--r--phpBB/phpbb/template/twig/node/includephp.php21
-rw-r--r--phpBB/phpbb/template/twig/node/php.php20
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/defineparser.php33
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/event.php30
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includecss.php30
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includejs.php30
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includeparser.php31
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includephp.php31
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/php.php30
-rw-r--r--phpBB/phpbb/template/twig/twig.php53
-rw-r--r--phpBB/phpbb/tree/nestedset.php39
-rw-r--r--phpBB/phpbb/tree/nestedset_forum.php14
-rw-r--r--phpBB/phpbb/tree/tree_interface.php12
-rw-r--r--phpBB/phpbb/user.php73
-rw-r--r--phpBB/phpbb/user_loader.php23
-rw-r--r--phpBB/phpbb/version_helper.php87
-rw-r--r--phpBB/phpbb/viewonline_helper.php54
430 files changed, 20341 insertions, 4665 deletions
diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php
index 81676e75fc..38755ccf99 100644
--- a/phpBB/phpbb/auth/auth.php
+++ b/phpBB/phpbb/auth/auth.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\auth;
/**
* Permission/Auth class
-* @package phpBB3
*/
class auth
{
@@ -205,9 +208,12 @@ class auth
/**
* Get forums with the specified permission setting
- * if the option is prefixed with !, then the result becomes negated
*
- * @param bool $clean set to true if only values needs to be returned which are set/unset
+ * @param string $opt The permission name to lookup. If prefixed with !, the result is negated.
+ * @param bool $clean set to true if only values needs to be returned which are set/unset
+ *
+ * @return array Contains the forum ids with the specified permission set to true.
+ This is a nested array: array => forum_id => permission => true
*/
function acl_getf($opt, $clean = false)
{
@@ -1040,7 +1046,7 @@ class auth
{
if (strpos($auth_options, '%') !== false)
{
- $sql_opts = "AND $key " . $db->sql_like_expression(str_replace('%', $db->any_char, $auth_options));
+ $sql_opts = "AND $key " . $db->sql_like_expression(str_replace('%', $db->get_any_char(), $auth_options));
}
else
{
@@ -1071,7 +1077,7 @@ class auth
{
if (strpos($option, '%') !== false)
{
- $sql[] = $key . ' ' . $db->sql_like_expression(str_replace('%', $db->any_char, $option));
+ $sql[] = $key . ' ' . $db->sql_like_expression(str_replace('%', $db->get_any_char(), $option));
}
else
{
diff --git a/phpBB/phpbb/auth/provider/apache.php b/phpBB/phpbb/auth/provider/apache.php
index 23cdc89829..9137a77210 100644
--- a/phpBB/phpbb/auth/provider/apache.php
+++ b/phpBB/phpbb/auth/provider/apache.php
@@ -1,19 +1,21 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\auth\provider;
/**
- * Apache authentication provider for phpBB3
- *
- * @package auth
- */
+* Apache authentication provider for phpBB3
+*/
class apache extends \phpbb\auth\provider\base
{
/**
@@ -26,15 +28,15 @@ class apache extends \phpbb\auth\provider\base
/**
* Apache Authentication Constructor
*
- * @param \phpbb\db\driver\driver $db
- * @param \phpbb\config\config $config
- * @param \phpbb\passwords\manager $passwords_manager
- * @param \phpbb\request\request $request
- * @param \phpbb\user $user
- * @param string $phpbb_root_path
- * @param string $php_ext
+ * @param \phpbb\db\driver\driver_interface $db Database object
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\passwords\manager $passwords_manager Passwords Manager object
+ * @param \phpbb\request\request $request Request object
+ * @param \phpbb\user $user User object
+ * @param string $phpbb_root_path Relative path to phpBB root
+ * @param string $php_ext PHP file extension
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext)
{
$this->db = $db;
$this->config = $config;
diff --git a/phpBB/phpbb/auth/provider/base.php b/phpBB/phpbb/auth/provider/base.php
index 78a3289356..4c49070eaf 100644
--- a/phpBB/phpbb/auth/provider/base.php
+++ b/phpBB/phpbb/auth/provider/base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\auth\provider;
/**
* Base authentication provider class that all other providers should implement
-*
-* @package auth
*/
abstract class base implements \phpbb\auth\provider\provider_interface
{
diff --git a/phpBB/phpbb/auth/provider/db.php b/phpBB/phpbb/auth/provider/db.php
index 6bbbc0be16..722eeffa9a 100644
--- a/phpBB/phpbb/auth/provider/db.php
+++ b/phpBB/phpbb/auth/provider/db.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,10 +15,7 @@ namespace phpbb\auth\provider;
/**
* Database authentication provider for phpBB3
- *
* This is for authentication via the integrated user table
- *
- * @package auth
*/
class db extends \phpbb\auth\provider\base
{
@@ -26,17 +27,25 @@ class db extends \phpbb\auth\provider\base
protected $passwords_manager;
/**
+ * DI container
+ *
+ * @var \Symfony\Component\DependencyInjection\ContainerInterface
+ */
+ protected $phpbb_container;
+
+ /**
* Database Authentication Constructor
*
- * @param \phpbb\db\driver\driver $db
+ * @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\config\config $config
* @param \phpbb\passwords\manager $passwords_manager
* @param \phpbb\request\request $request
* @param \phpbb\user $user
+ * @param \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container DI container
* @param string $phpbb_root_path
* @param string $php_ext
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, $phpbb_root_path, $php_ext)
{
$this->db = $db;
$this->config = $config;
@@ -45,6 +54,7 @@ class db extends \phpbb\auth\provider\base
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
+ $this->phpbb_container = $phpbb_container;
}
/**
@@ -77,7 +87,7 @@ class db extends \phpbb\auth\provider\base
$username_clean = utf8_clean_string($username);
- $sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts
+ $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type, user_login_attempts
FROM ' . USERS_TABLE . "
WHERE username_clean = '" . $this->db->sql_escape($username_clean) . "'";
$result = $this->db->sql_query($sql);
@@ -145,13 +155,8 @@ class db extends \phpbb\auth\provider\base
// Every auth module is able to define what to do by itself...
if ($show_captcha)
{
- // Visual Confirmation handling
- if (!class_exists('phpbb_captcha_factory', false))
- {
- include ($this->phpbb_root_path . 'includes/captcha/captcha_factory.' . $this->php_ext);
- }
-
- $captcha = \phpbb_captcha_factory::get_instance($this->config['captcha_plugin']);
+ $captcha_factory = $this->phpbb_container->get('captcha.factory');
+ $captcha = $captcha_factory->get_instance($this->config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
$vc_response = $captcha->validate($row);
if ($vc_response)
@@ -169,72 +174,8 @@ class db extends \phpbb\auth\provider\base
}
- // If the password convert flag is set we need to convert it
- if ($row['user_pass_convert'])
- {
- // enable super globals to get literal value
- // this is needed to prevent unicode normalization
- $super_globals_disabled = $this->request->super_globals_disabled();
- if ($super_globals_disabled)
- {
- $this->request->enable_super_globals();
- }
-
- // in phpBB2 passwords were used exactly as they were sent, with addslashes applied
- $password_old_format = isset($_REQUEST['password']) ? (string) $_REQUEST['password'] : '';
- $password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format;
- $password_new_format = $this->request->variable('password', '', true);
-
- if ($super_globals_disabled)
- {
- $this->request->disable_super_globals();
- }
-
- if ($password == $password_new_format)
- {
- if (!function_exists('utf8_to_cp1252'))
- {
- include($this->phpbb_root_path . 'includes/utf/data/recode_basic.' . $this->php_ext);
- }
-
- // cp1252 is phpBB2's default encoding, characters outside ASCII range might work when converted into that encoding
- // plain md5 support left in for conversions from other systems.
- if ((strlen($row['user_password']) == 34 && ($this->passwords_manager->check(md5($password_old_format), $row['user_password']) || $this->passwords_manager->check(md5(utf8_to_cp1252($password_old_format)), $row['user_password'])))
- || (strlen($row['user_password']) == 32 && (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password'])))
- {
- $hash = $this->passwords_manager->hash($password_new_format);
-
- // Update the password in the users table to the new format and remove user_pass_convert flag
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_password = \'' . $this->db->sql_escape($hash) . '\',
- user_pass_convert = 0
- WHERE user_id = ' . $row['user_id'];
- $this->db->sql_query($sql);
-
- $row['user_pass_convert'] = 0;
- $row['user_password'] = $hash;
- }
- else
- {
- // Although we weren't able to convert this password we have to
- // increase login attempt count to make sure this cannot be exploited
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_login_attempts = user_login_attempts + 1
- WHERE user_id = ' . (int) $row['user_id'] . '
- AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
- $this->db->sql_query($sql);
-
- return array(
- 'status' => LOGIN_ERROR_PASSWORD_CONVERT,
- 'error_msg' => 'LOGIN_ERROR_PASSWORD_CONVERT',
- 'user_row' => $row,
- );
- }
- }
- }
-
// Check password ...
- if (!$row['user_pass_convert'] && $this->passwords_manager->check($password, $row['user_password']))
+ if ($this->passwords_manager->check($password, $row['user_password']))
{
// Check for old password hash...
if ($this->passwords_manager->convert_flag || strlen($row['user_password']) == 32)
@@ -243,8 +184,7 @@ class db extends \phpbb\auth\provider\base
// Update the password in the users table to the new format
$sql = 'UPDATE ' . USERS_TABLE . "
- SET user_password = '" . $this->db->sql_escape($hash) . "',
- user_pass_convert = 0
+ SET user_password = '" . $this->db->sql_escape($hash) . "'
WHERE user_id = {$row['user_id']}";
$this->db->sql_query($sql);
diff --git a/phpBB/phpbb/auth/provider/ldap.php b/phpBB/phpbb/auth/provider/ldap.php
index e92a227e16..d32e7504eb 100644
--- a/phpBB/phpbb/auth/provider/ldap.php
+++ b/phpBB/phpbb/auth/provider/ldap.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,10 +15,7 @@ namespace phpbb\auth\provider;
/**
* Database authentication provider for phpBB3
- *
* This is for authentication via the integrated user table
- *
- * @package auth
*/
class ldap extends \phpbb\auth\provider\base
{
@@ -28,12 +29,12 @@ class ldap extends \phpbb\auth\provider\base
/**
* LDAP Authentication Constructor
*
- * @param \phpbb\db\driver\driver $db
- * @param \phpbb\config\config $config
- * @param \phpbb\passwords\manager $passwords_manager
- * @param \phpbb\user $user
+ * @param \phpbb\db\driver\driver_interface $db Database object
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\passwords\manager $passwords_manager Passwords manager object
+ * @param \phpbb\user $user User object
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\user $user)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\user $user)
{
$this->db = $db;
$this->config = $config;
diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php
index 0128c89248..c0ce3f1fba 100644
--- a/phpBB/phpbb/auth/provider/oauth/oauth.php
+++ b/phpBB/phpbb/auth/provider/oauth/oauth.php
@@ -1,28 +1,29 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\auth\provider\oauth;
use OAuth\Common\Consumer\Credentials;
-use OAuth\Common\Http\Uri\Uri;
/**
* OAuth authentication provider for phpBB3
-*
-* @package auth
*/
class oauth extends \phpbb\auth\provider\base
{
/**
* Database driver
*
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -90,6 +91,13 @@ class oauth extends \phpbb\auth\provider\base
protected $current_uri;
/**
+ * DI container
+ *
+ * @var \Symfony\Component\DependencyInjection\ContainerInterface
+ */
+ protected $phpbb_container;
+
+ /**
* phpBB root path
*
* @var string
@@ -97,7 +105,7 @@ class oauth extends \phpbb\auth\provider\base
protected $phpbb_root_path;
/**
- * PHP extenstion
+ * PHP file extension
*
* @var string
*/
@@ -106,7 +114,7 @@ class oauth extends \phpbb\auth\provider\base
/**
* OAuth Authentication Constructor
*
- * @param \phpbb\db\driver\driver $db
+ * @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\config\config $config
* @param \phpbb\passwords\manager $passwords_manager
* @param \phpbb\request\request_interface $request
@@ -115,10 +123,11 @@ class oauth extends \phpbb\auth\provider\base
* @param string $auth_provider_oauth_token_account_assoc
* @param \phpbb\di\service_collection $service_providers Contains \phpbb\auth\provider\oauth\service_interface
* @param string $users_table
+ * @param \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container DI container
* @param string $phpbb_root_path
* @param string $php_ext
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, $phpbb_root_path, $php_ext)
{
$this->db = $db;
$this->config = $config;
@@ -129,6 +138,7 @@ class oauth extends \phpbb\auth\provider\base
$this->auth_provider_oauth_token_account_assoc = $auth_provider_oauth_token_account_assoc;
$this->service_providers = $service_providers;
$this->users_table = $users_table;
+ $this->phpbb_container = $phpbb_container;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
}
@@ -159,7 +169,7 @@ class oauth extends \phpbb\auth\provider\base
// Temporary workaround for only having one authentication provider available
if (!$this->request->is_set('oauth_service'))
{
- $provider = new \phpbb\auth\provider\db($this->db, $this->config, $this->passwords_manager, $this->request, $this->user, $this->phpbb_root_path, $this->php_ext);
+ $provider = new \phpbb\auth\provider\db($this->db, $this->config, $this->passwords_manager, $this->request, $this->user, $this->phpbb_container, $this->phpbb_root_path, $this->php_ext);
return $provider->login($username, $password);
}
@@ -213,7 +223,7 @@ class oauth extends \phpbb\auth\provider\base
}
// Retrieve the user's account
- $sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts
+ $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type, user_login_attempts
FROM ' . $this->users_table . '
WHERE user_id = ' . (int) $row['user_id'];
$result = $this->db->sql_query($sql);
@@ -222,7 +232,7 @@ class oauth extends \phpbb\auth\provider\base
if (!$row)
{
- throw new Exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY');
+ throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY');
}
// Update token storage to store the user_id
@@ -276,9 +286,10 @@ class oauth extends \phpbb\auth\provider\base
* @param array $service_credentials {@see \phpbb\auth\provider\oauth\oauth::get_service_credentials}
* @param string $query The query string of the
* current_uri used in redirection
- * @param array $scope The scope of the request against
+ * @param array $scopes The scope of the request against
* the api.
* @return \OAuth\Common\Service\ServiceInterface
+ * @throws \Exception
*/
protected function get_service($service_name, \phpbb\auth\provider\oauth\token_storage $storage, array $service_credentials, $query, array $scopes = array())
{
@@ -296,7 +307,7 @@ class oauth extends \phpbb\auth\provider\base
if (!$service)
{
- throw new Exception('AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED');
+ throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED');
}
return $service;
@@ -615,7 +626,5 @@ class oauth extends \phpbb\auth\provider\base
$service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']);
$storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table);
$storage->clearToken($service_name);
-
- return;
}
}
diff --git a/phpBB/phpbb/auth/provider/oauth/service/base.php b/phpBB/phpbb/auth/provider/oauth/service/base.php
index 7a144d2f51..6adf64aa30 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/base.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\auth\provider\oauth\service;
/**
* Base OAuth abstract class that all OAuth services should implement
-*
-* @package auth
*/
abstract class base implements \phpbb\auth\provider\oauth\service\service_interface
{
diff --git a/phpBB/phpbb/auth/provider/oauth/service/bitly.php b/phpBB/phpbb/auth/provider/oauth/service/bitly.php
index b4050033a6..25e731a02c 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/bitly.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/bitly.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\auth\provider\oauth\service;
/**
* Bitly OAuth service
-*
-* @package auth
*/
class bitly extends \phpbb\auth\provider\oauth\service\base
{
diff --git a/phpBB/phpbb/auth/provider/oauth/service/exception.php b/phpBB/phpbb/auth/provider/oauth/service/exception.php
index 3bc93be01e..d3e95bef0d 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/exception.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/exception.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\auth\provider\oauth\service;
/**
* OAuth service exception class
-*
-* @package auth
*/
class exception extends \RuntimeException
{
diff --git a/phpBB/phpbb/auth/provider/oauth/service/facebook.php b/phpBB/phpbb/auth/provider/oauth/service/facebook.php
index 2698be8b18..bb98835e07 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/facebook.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/facebook.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,30 +15,28 @@ namespace phpbb\auth\provider\oauth\service;
/**
* Facebook OAuth service
-*
-* @package auth
*/
class facebook extends base
{
/**
* phpBB config
*
- * @var phpbb\config\config
+ * @var \phpbb\config\config
*/
protected $config;
/**
* phpBB request
*
- * @var phpbb\request\request_interface
+ * @var \phpbb\request\request_interface
*/
protected $request;
/**
* Constructor
*
- * @param phpbb\config\config $config
- * @param phpbb\request\request_interface $request
+ * @param \phpbb\config\config $config
+ * @param \phpbb\request\request_interface $request
*/
public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
{
diff --git a/phpBB/phpbb/auth/provider/oauth/service/google.php b/phpBB/phpbb/auth/provider/oauth/service/google.php
index 08cb025c2d..cb9f83a94f 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/google.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/google.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,30 +15,28 @@ namespace phpbb\auth\provider\oauth\service;
/**
* Google OAuth service
-*
-* @package auth
*/
class google extends base
{
/**
* phpBB config
*
- * @var phpbb\config\config
+ * @var \phpbb\config\config
*/
protected $config;
/**
* phpBB request
*
- * @var phpbb\request\request_interface
+ * @var \phpbb\request\request_interface
*/
protected $request;
/**
* Constructor
*
- * @param phpbb\config\config $config
- * @param phpbb\request\request_interface $request
+ * @param \phpbb\config\config $config
+ * @param \phpbb\request\request_interface $request
*/
public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
{
diff --git a/phpBB/phpbb/auth/provider/oauth/service/service_interface.php b/phpBB/phpbb/auth/provider/oauth/service/service_interface.php
index eee3a51cac..e84eb247b6 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/service_interface.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/service_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\auth\provider\oauth\service;
/**
* OAuth service interface
-*
-* @package auth
*/
interface service_interface
{
@@ -65,7 +67,7 @@ interface service_interface
/**
* Sets the external library service provider
*
- * @param \OAuth\Common\Service\ServiceInterface $service
+ * @param \OAuth\Common\Service\ServiceInterface $service_provider
*/
public function set_external_service_provider(\OAuth\Common\Service\ServiceInterface $service_provider);
}
diff --git a/phpBB/phpbb/auth/provider/oauth/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php
index 43574288dc..023cf402ca 100644
--- a/phpBB/phpbb/auth/provider/oauth/token_storage.php
+++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,20 +17,17 @@ namespace phpbb\auth\provider\oauth;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Storage\TokenStorageInterface;
-use OAuth\Common\Storage\Exception\StorageException;
use OAuth\Common\Storage\Exception\TokenNotFoundException;
/**
* OAuth storage wrapper for phpbb's cache
-*
-* @package auth
*/
class token_storage implements TokenStorageInterface
{
/**
* Cache driver.
*
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -52,11 +53,11 @@ class token_storage implements TokenStorageInterface
/**
* Creates token storage for phpBB.
*
- * @param \phpbb\db\driver\driver $db
+ * @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\user $user
* @param string $auth_provider_oauth_table
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\user $user, $auth_provider_oauth_table)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $auth_provider_oauth_table)
{
$this->db = $db;
$this->user = $user;
@@ -196,6 +197,7 @@ class token_storage implements TokenStorageInterface
/**
* Checks to see if an access token exists solely by the session_id of the user
*
+ * @param string $service The name of the OAuth service
* @return bool true if they have token, false if they don't
*/
public function has_access_token_by_session($service)
@@ -248,6 +250,7 @@ class token_storage implements TokenStorageInterface
*
* @param array $data
* @return mixed
+ * @throws \OAuth\Common\Storage\Exception\TokenNotFoundException
*/
protected function _retrieve_access_token($data)
{
@@ -263,7 +266,7 @@ class token_storage implements TokenStorageInterface
// Ensure that the token was serialized/unserialized correctly
if (!($token instanceof TokenInterface))
{
- $this->clearToken();
+ $this->clearToken($data['provider']);
throw new TokenNotFoundException('AUTH_PROVIDER_OAUTH_TOKEN_ERROR_INCORRECTLY_STORED');
}
diff --git a/phpBB/phpbb/auth/provider/provider_interface.php b/phpBB/phpbb/auth/provider/provider_interface.php
index 946731f52d..613297cefc 100644
--- a/phpBB/phpbb/auth/provider/provider_interface.php
+++ b/phpBB/phpbb/auth/provider/provider_interface.php
@@ -1,19 +1,21 @@
<?php
/**
*
-* @package auth
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\auth\provider;
/**
- * The interface authentication provider classes have to implement.
- *
- * @package auth
- */
+* The interface authentication provider classes have to implement.
+*/
interface provider_interface
{
/**
@@ -146,7 +148,7 @@ interface provider_interface
* user_id of an account needed to successfully link an external account to
* a forum account.
*
- * @param array $link_data Any data needed to link a phpBB account to
+ * @param array $login_link_data Any data needed to link a phpBB account to
* an external account.
* @return string|null Returns a string with a language constant if there
* is data missing or null if there is no error.
diff --git a/phpBB/phpbb/auth/provider_collection.php b/phpBB/phpbb/auth/provider_collection.php
new file mode 100644
index 0000000000..a74a2135dc
--- /dev/null
+++ b/phpBB/phpbb/auth/provider_collection.php
@@ -0,0 +1,65 @@
+<?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\auth;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+* Collection of auth providers to be configured at container compile time.
+*/
+class provider_collection extends \phpbb\di\service_collection
+{
+ /** @var \phpbb\config\config phpBB Config */
+ protected $config;
+
+ /**
+ * Constructor
+ *
+ * @param ContainerInterface $container Container object
+ * @param \phpbb\config\config $config phpBB config
+ */
+ public function __construct(ContainerInterface $container, \phpbb\config\config $config)
+ {
+ $this->container = $container;
+ $this->config = $config;
+ }
+
+ /**
+ * Get an auth provider.
+ *
+ * @return object Default auth provider selected in config if it
+ * does exist. Otherwise the standard db auth
+ * provider.
+ * @throws \RuntimeException If neither the auth provider that
+ * is specified by the phpBB config nor the db
+ * auth provider exist. The db auth provider
+ * should always exist in a phpBB installation.
+ */
+ public function get_provider()
+ {
+ if ($this->offsetExists('auth.provider.' . basename(trim($this->config['auth_method']))))
+ {
+ return $this->offsetGet('auth.provider.' . basename(trim($this->config['auth_method'])));
+ }
+ // Revert to db auth provider if selected method does not exist
+ else if ($this->offsetExists('auth.provider.db'))
+ {
+ return $this->offsetGet('auth.provider.db');
+ }
+ else
+ {
+ throw new \RuntimeException(sprintf('The authentication provider for the authentication method "%1$s" does not exist. It was not possible to recover from this by reverting to the database authentication provider.', $this->config['auth_method']));
+ }
+ }
+}
diff --git a/phpBB/phpbb/avatar/driver/driver.php b/phpBB/phpbb/avatar/driver/driver.php
index dd55f09119..b3ced7edf7 100644
--- a/phpBB/phpbb/avatar/driver/driver.php
+++ b/phpBB/phpbb/avatar/driver/driver.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\avatar\driver;
/**
* Base class for avatar drivers
-* @package phpBB3
*/
abstract class driver implements \phpbb\avatar\driver\driver_interface
{
@@ -70,10 +73,9 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface
* Construct a driver object
*
* @param \phpbb\config\config $config phpBB configuration
- * @param \phpbb\request\request $request Request object
* @param string $phpbb_root_path Path to the phpBB root
* @param string $php_ext PHP file extension
- * @param \phpbb_path_helper $path_helper phpBB path helper
+ * @param \phpbb\path_helper $path_helper phpBB path helper
* @param \phpbb\cache\driver\driver_interface $cache Cache driver
*/
public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface $cache = null)
@@ -86,7 +88,7 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_custom_html($user, $row, $alt = '')
{
@@ -94,7 +96,7 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function prepare_form_acp($user)
{
@@ -102,7 +104,7 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function delete($row)
{
@@ -110,7 +112,7 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_name()
{
diff --git a/phpBB/phpbb/avatar/driver/driver_interface.php b/phpBB/phpbb/avatar/driver/driver_interface.php
index 7f049469a2..835609745a 100644
--- a/phpBB/phpbb/avatar/driver/driver_interface.php
+++ b/phpBB/phpbb/avatar/driver/driver_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\avatar\driver;
/**
* Interface for avatar drivers
-* @package phpBB3
*/
interface driver_interface
{
diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php
index 9f14b7f468..2082e0fd02 100644
--- a/phpBB/phpbb/avatar/driver/gravatar.php
+++ b/phpBB/phpbb/avatar/driver/gravatar.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\avatar\driver;
/**
* Handles avatars hosted at gravatar.com
-* @package phpBB3
*/
class gravatar extends \phpbb\avatar\driver\driver
{
@@ -21,7 +24,7 @@ class gravatar extends \phpbb\avatar\driver\driver
const GRAVATAR_URL = '//secure.gravatar.com/avatar/';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_data($row)
{
@@ -33,7 +36,7 @@ class gravatar extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_custom_html($user, $row, $alt = '')
{
@@ -44,7 +47,7 @@ class gravatar extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function prepare_form($request, $template, $user, $row, &$error)
{
@@ -58,7 +61,7 @@ class gravatar extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function process_form($request, $template, $user, $row, &$error)
{
@@ -66,6 +69,11 @@ class gravatar extends \phpbb\avatar\driver\driver
$row['avatar_width'] = $request->variable('avatar_gravatar_width', 0);
$row['avatar_height'] = $request->variable('avatar_gravatar_height', 0);
+ if (empty($row['avatar']))
+ {
+ return false;
+ }
+
if (!function_exists('validate_data'))
{
require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
@@ -78,7 +86,8 @@ class gravatar extends \phpbb\avatar\driver\driver
array(
'email' => array(
array('string', false, 6, 60),
- array('email'))
+ array('email'),
+ ),
)
);
@@ -147,7 +156,7 @@ class gravatar extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_template_name()
{
@@ -157,6 +166,8 @@ class gravatar extends \phpbb\avatar\driver\driver
/**
* Build gravatar URL for output on page
*
+ * @param array $row User data or group data that has been cleaned with
+ * \phpbb\avatar\manager::clean_row
* @return string Gravatar URL
*/
protected function get_gravatar_url($row)
diff --git a/phpBB/phpbb/avatar/driver/local.php b/phpBB/phpbb/avatar/driver/local.php
index 611a44cb3d..07b3ed59de 100644
--- a/phpBB/phpbb/avatar/driver/local.php
+++ b/phpBB/phpbb/avatar/driver/local.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,12 +15,11 @@ namespace phpbb\avatar\driver;
/**
* Handles avatars selected from the board gallery
-* @package phpBB3
*/
class local extends \phpbb\avatar\driver\driver
{
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_data($row)
{
@@ -28,12 +31,12 @@ class local extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function prepare_form($request, $template, $user, $row, &$error)
{
$avatar_list = $this->get_avatar_list($user);
- $category = $request->variable('avatar_local_cat', '');
+ $category = $request->variable('avatar_local_cat', key($avatar_list));
foreach ($avatar_list as $cat => $null)
{
@@ -96,7 +99,7 @@ class local extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function prepare_form_acp($user)
{
@@ -106,7 +109,7 @@ class local extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function process_form($request, $template, $user, $row, &$error)
{
@@ -117,7 +120,6 @@ class local extends \phpbb\avatar\driver\driver
if (empty($category) || empty($file))
{
- $error[] = 'NO_AVATAR_SELECTED';
return false;
}
@@ -128,14 +130,14 @@ class local extends \phpbb\avatar\driver\driver
}
return array(
- 'avatar' => ($category != $user->lang['MAIN']) ? $category . '/' . $file : $file,
+ 'avatar' => ($category != $user->lang['NO_AVATAR_CATEGORY']) ? $category . '/' . $file : $file,
'avatar_width' => $avatar_list[$category][urldecode($file)]['width'],
'avatar_height' => $avatar_list[$category][urldecode($file)]['height'],
);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_template_name()
{
@@ -176,9 +178,9 @@ class local extends \phpbb\avatar\driver\driver
{
$dims = array(0, 0);
}
- $cat = ($path == $file_path) ? $user->lang['MAIN'] : str_replace("$path/", '', $file_path);
+ $cat = ($path == $file_path) ? $user->lang['NO_AVATAR_CATEGORY'] : str_replace("$path/", '', $file_path);
$avatar_list[$cat][$image] = array(
- 'file' => ($cat != $user->lang['MAIN']) ? rawurlencode($cat) . '/' . rawurlencode($image) : rawurlencode($image),
+ 'file' => ($cat != $user->lang['NO_AVATAR_CATEGORY']) ? 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/avatar/driver/remote.php b/phpBB/phpbb/avatar/driver/remote.php
index 36623942df..1bd7f6c927 100644
--- a/phpBB/phpbb/avatar/driver/remote.php
+++ b/phpBB/phpbb/avatar/driver/remote.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,12 +15,11 @@ namespace phpbb\avatar\driver;
/**
* Handles avatars hosted remotely
-* @package phpBB3
*/
class remote extends \phpbb\avatar\driver\driver
{
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_data($row)
{
@@ -28,7 +31,7 @@ class remote extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function prepare_form($request, $template, $user, $row, &$error)
{
@@ -42,7 +45,7 @@ class remote extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function process_form($request, $template, $user, $row, &$error)
{
@@ -50,6 +53,11 @@ class remote extends \phpbb\avatar\driver\driver
$width = $request->variable('avatar_remote_width', 0);
$height = $request->variable('avatar_remote_height', 0);
+ if (empty($url))
+ {
+ return false;
+ }
+
if (!preg_match('#^(http|https|ftp)://#i', $url))
{
$url = 'http://' . $url;
@@ -188,7 +196,7 @@ class remote extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_template_name()
{
diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php
index 1e50e135e4..003b23659f 100644
--- a/phpBB/phpbb/avatar/driver/upload.php
+++ b/phpBB/phpbb/avatar/driver/upload.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,12 +15,36 @@ namespace phpbb\avatar\driver;
/**
* Handles avatars uploaded to the board
-* @package phpBB3
*/
class upload extends \phpbb\avatar\driver\driver
{
/**
- * @inheritdoc
+ * @var \phpbb\mimetype\guesser
+ */
+ protected $mimetype_guesser;
+
+ /**
+ * Construct a driver object
+ *
+ * @param \phpbb\config\config $config phpBB configuration
+ * @param string $phpbb_root_path Path to the phpBB root
+ * @param string $php_ext PHP file extension
+ * @param \phpbb_path_helper $path_helper phpBB path helper
+ * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser
+ * @param \phpbb\cache\driver\driver_interface $cache Cache driver
+ */
+ public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\cache\driver\driver_interface $cache = null)
+ {
+ $this->config = $config;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ $this->path_helper = $path_helper;
+ $this->mimetype_guesser = $mimetype_guesser;
+ $this->cache = $cache;
+ }
+
+ /**
+ * {@inheritdoc}
*/
public function get_data($row, $ignore_config = false)
{
@@ -28,7 +56,7 @@ class upload extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function prepare_form($request, $template, $user, $row, &$error)
{
@@ -46,7 +74,7 @@ class upload extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function process_form($request, $template, $user, $row, &$error)
{
@@ -67,9 +95,9 @@ class upload extends \phpbb\avatar\driver\driver
if (!empty($upload_file['name']))
{
- $file = $upload->form_upload('avatar_upload_file');
+ $file = $upload->form_upload('avatar_upload_file', $this->mimetype_guesser);
}
- elseif (!empty($this->config['allow_avatar_remote_upload']) && !empty($url))
+ else if (!empty($this->config['allow_avatar_remote_upload']) && !empty($url))
{
if (!preg_match('#^(http|https|ftp)://#i', $url))
{
@@ -97,11 +125,10 @@ class upload extends \phpbb\avatar\driver\driver
return false;
}
- $file = $upload->remote_upload($url);
+ $file = $upload->remote_upload($url, $this->mimetype_guesser);
}
else
{
- $error[] = 'NO_AVATAR_SELECTED';
return false;
}
@@ -140,19 +167,19 @@ class upload extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function prepare_form_acp($user)
{
return array(
'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
- 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true),
+ 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true),
);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function delete($row)
{
@@ -168,7 +195,7 @@ class upload extends \phpbb\avatar\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_template_name()
{
diff --git a/phpBB/phpbb/avatar/manager.php b/phpBB/phpbb/avatar/manager.php
index 6ce924d2eb..42ae61a9a2 100644
--- a/phpBB/phpbb/avatar/manager.php
+++ b/phpBB/phpbb/avatar/manager.php
@@ -1,17 +1,18 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\avatar;
-/**
-* @package avatar
-*/
class manager
{
/**
@@ -40,8 +41,8 @@ class manager
static protected $default_row = array(
'avatar' => '',
'avatar_type' => '',
- 'avatar_width' => '',
- 'avatar_height' => '',
+ 'avatar_width' => 0,
+ 'avatar_height' => 0,
);
/**
@@ -306,4 +307,36 @@ class manager
return $error;
}
+
+ /**
+ * Handle deleting avatars
+ *
+ * @param \phpbb\db\driver\driver_interface $db phpBB dbal
+ * @param \phpbb\user $user phpBB user object
+ * @param array $avatar_data Cleaned user data containing the user's
+ * avatar data
+ * @param string $table Database table from which the avatar should be deleted
+ * @param string $prefix Prefix of user data columns in database
+ * @return null
+ */
+ public function handle_avatar_delete(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $avatar_data, $table, $prefix)
+ {
+ if ($driver = $this->get_driver($avatar_data['avatar_type']))
+ {
+ $driver->delete($avatar_data);
+ }
+
+ $result = self::$default_row;
+
+ foreach ($result as $key => $value)
+ {
+ $result[$prefix . $key] = $value;
+ unset($result[$key]);
+ }
+
+ $sql = 'UPDATE ' . $table . '
+ SET ' . $db->sql_build_array('UPDATE', $result) . '
+ WHERE ' . $prefix . 'id = ' . (int) $avatar_data['id'];
+ $db->sql_query($sql);
+ }
}
diff --git a/phpBB/phpbb/cache/driver/apc.php b/phpBB/phpbb/cache/driver/apc.php
index 77b7b11181..521d5d41ea 100644
--- a/phpBB/phpbb/cache/driver/apc.php
+++ b/phpBB/phpbb/cache/driver/apc.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2005, 2009 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\cache\driver;
/**
* ACM for APC
-* @package acm
*/
class apc extends \phpbb\cache\driver\memory
{
diff --git a/phpBB/phpbb/cache/driver/base.php b/phpBB/phpbb/cache/driver/base.php
index feaca25a5b..4c20ad916d 100644
--- a/phpBB/phpbb/cache/driver/base.php
+++ b/phpBB/phpbb/cache/driver/base.php
@@ -1,17 +1,231 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\cache\driver;
-/**
-* @package acm
-*/
abstract class base implements \phpbb\cache\driver\driver_interface
{
+ var $vars = array();
+ var $is_modified = false;
+
+ var $sql_rowset = array();
+ var $sql_row_pointer = array();
+ var $cache_dir = '';
+
+ /**
+ * {@inheritDoc}
+ */
+ function purge()
+ {
+ // Purge all phpbb cache files
+ try
+ {
+ $iterator = new \DirectoryIterator($this->cache_dir);
+ }
+ catch (\Exception $e)
+ {
+ return;
+ }
+
+ foreach ($iterator as $fileInfo)
+ {
+ if ($fileInfo->isDot())
+ {
+ continue;
+ }
+ $filename = $fileInfo->getFilename();
+ if ($fileInfo->isDir())
+ {
+ $this->remove_dir($fileInfo->getPathname());
+ }
+ else if (strpos($filename, 'container_') === 0 ||
+ strpos($filename, 'url_matcher') === 0 ||
+ strpos($filename, 'sql_') === 0 ||
+ strpos($filename, 'data_') === 0)
+ {
+ $this->remove_file($fileInfo->getPathname());
+ }
+ }
+
+ unset($this->vars);
+ unset($this->sql_rowset);
+ unset($this->sql_row_pointer);
+
+ $this->vars = array();
+ $this->sql_rowset = array();
+ $this->sql_row_pointer = array();
+
+ $this->is_modified = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ function unload()
+ {
+ $this->save();
+ unset($this->vars);
+ unset($this->sql_rowset);
+ unset($this->sql_row_pointer);
+
+ $this->vars = array();
+ $this->sql_rowset = array();
+ $this->sql_row_pointer = array();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ function sql_load($query)
+ {
+ // Remove extra spaces and tabs
+ $query = preg_replace('/[\n\r\s\t]+/', ' ', $query);
+
+ if (($rowset = $this->_read('sql_' . md5($query))) === false)
+ {
+ return false;
+ }
+
+ $query_id = sizeof($this->sql_rowset);
+ $this->sql_rowset[$query_id] = $rowset;
+ $this->sql_row_pointer[$query_id] = 0;
+
+ return $query_id;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ function sql_exists($query_id)
+ {
+ return isset($this->sql_rowset[$query_id]);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ function sql_fetchrow($query_id)
+ {
+ if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id]))
+ {
+ return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++];
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ function sql_fetchfield($query_id, $field)
+ {
+ if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id]))
+ {
+ return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false;
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ function sql_rowseek($rownum, $query_id)
+ {
+ if ($rownum >= sizeof($this->sql_rowset[$query_id]))
+ {
+ return false;
+ }
+
+ $this->sql_row_pointer[$query_id] = $rownum;
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ function sql_freeresult($query_id)
+ {
+ if (!isset($this->sql_rowset[$query_id]))
+ {
+ return false;
+ }
+
+ unset($this->sql_rowset[$query_id]);
+ unset($this->sql_row_pointer[$query_id]);
+
+ return true;
+ }
+
+ /**
+ * Removes/unlinks file
+ *
+ * @param string $filename Filename to remove
+ * @param bool $check Check file permissions
+ * @return bool True if the file was successfully removed, otherwise false
+ */
+ function remove_file($filename, $check = false)
+ {
+ if (!function_exists('phpbb_is_writable'))
+ {
+ global $phpbb_root_path, $phpEx;
+ include($phpbb_root_path . 'includes/functions.' . $phpEx);
+ }
+
+ if ($check && !phpbb_is_writable($this->cache_dir))
+ {
+ // E_USER_ERROR - not using language entry - intended.
+ trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR);
+ }
+
+ return @unlink($filename);
+ }
+
+ /**
+ * Remove directory
+ *
+ * @param string $dir Directory to remove
+ *
+ * @return null
+ */
+ protected function remove_dir($dir)
+ {
+ try
+ {
+ $iterator = new \DirectoryIterator($dir);
+ }
+ catch (\Exception $e)
+ {
+ return;
+ }
+
+ foreach ($iterator as $fileInfo)
+ {
+ if ($fileInfo->isDot())
+ {
+ continue;
+ }
+
+ if ($fileInfo->isDir())
+ {
+ $this->remove_dir($fileInfo->getPathname());
+ }
+ else
+ {
+ $this->remove_file($fileInfo->getPathname());
+ }
+ }
+
+ @rmdir($dir);
+ }
}
diff --git a/phpBB/phpbb/cache/driver/driver_interface.php b/phpBB/phpbb/cache/driver/driver_interface.php
index 8444028115..9ac9ca0c59 100644
--- a/phpBB/phpbb/cache/driver/driver_interface.php
+++ b/phpBB/phpbb/cache/driver/driver_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\cache\driver;
/**
* An interface that all cache drivers must implement
-*
-* @package acm
*/
interface driver_interface
{
@@ -106,7 +108,7 @@ interface driver_interface
* result to persistent storage. In other words, there is no need
* to call save() afterwards.
*
- * @param \phpbb\db\driver\driver $db Database connection
+ * @param \phpbb\db\driver\driver_interface $db Database connection
* @param string $query SQL query, should be used for generating storage key
* @param mixed $query_result The result from \dbal::sql_query, to be passed to
* \dbal::sql_fetchrow to get all rows and store them
@@ -117,7 +119,7 @@ interface driver_interface
* representing the query should be returned. Otherwise
* the original $query_result should be returned.
*/
- public function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl);
+ public function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl);
/**
* Check if result for a given SQL query exists in cache.
@@ -140,7 +142,7 @@ interface driver_interface
* Fetch a field from the current row of a cached database result (database)
*
* @param int $query_id
- * @param $field The name of the column.
+ * @param string $field The name of the column.
* @return string|bool The field of the query result if found in the cache,
* otherwise false.
*/
diff --git a/phpBB/phpbb/cache/driver/eaccelerator.php b/phpBB/phpbb/cache/driver/eaccelerator.php
index d1ad69ef6d..1697758acc 100644
--- a/phpBB/phpbb/cache/driver/eaccelerator.php
+++ b/phpBB/phpbb/cache/driver/eaccelerator.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2005, 2009 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\cache\driver;
/**
* ACM for eAccelerator
-* @package acm
* @todo Missing locks from destroy() talk with David
*/
class eaccelerator extends \phpbb\cache\driver\memory
diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php
index a57a805193..fd5bce4515 100644
--- a/phpBB/phpbb/cache/driver/file.php
+++ b/phpBB/phpbb/cache/driver/file.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2005, 2009 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,20 +15,15 @@ namespace phpbb\cache\driver;
/**
* ACM File Based Caching
-* @package acm
*/
class file extends \phpbb\cache\driver\base
{
- var $vars = array();
var $var_expires = array();
- var $is_modified = false;
-
- var $sql_rowset = array();
- var $sql_row_pointer = array();
- var $cache_dir = '';
/**
* Set cache path
+ *
+ * @param string $cache_dir Define the path to the cache directory (default: $phpbb_root_path . 'cache/')
*/
function __construct($cache_dir = null)
{
@@ -45,16 +44,9 @@ class file extends \phpbb\cache\driver\base
*/
function unload()
{
- $this->save();
- unset($this->vars);
+ parent::unload();
unset($this->var_expires);
- unset($this->sql_rowset);
- unset($this->sql_row_pointer);
-
- $this->vars = array();
$this->var_expires = array();
- $this->sql_rowset = array();
- $this->sql_row_pointer = array();
}
/**
@@ -161,8 +153,6 @@ class file extends \phpbb\cache\driver\base
{
if ($var_name[0] == '_')
{
- global $phpEx;
-
if (!$this->_exists($var_name))
{
return false;
@@ -198,85 +188,8 @@ class file extends \phpbb\cache\driver\base
*/
function purge()
{
- // Purge all phpbb cache files
- try
- {
- $iterator = new \DirectoryIterator($this->cache_dir);
- }
- catch (Exception $e)
- {
- return;
- }
-
- foreach ($iterator as $fileInfo)
- {
- if ($fileInfo->isDot())
- {
- continue;
- }
- $filename = $fileInfo->getFilename();
- if ($fileInfo->isDir())
- {
- $this->remove_dir($fileInfo->getPathname());
- }
- elseif (strpos($filename, 'container_') === 0 ||
- strpos($filename, 'url_matcher') === 0 ||
- strpos($filename, 'sql_') === 0 ||
- strpos($filename, 'data_') === 0)
- {
- $this->remove_file($fileInfo->getPathname());
- }
- }
-
- unset($this->vars);
- unset($this->var_expires);
- unset($this->sql_rowset);
- unset($this->sql_row_pointer);
-
- $this->vars = array();
+ parent::purge();
$this->var_expires = array();
- $this->sql_rowset = array();
- $this->sql_row_pointer = array();
-
- $this->is_modified = false;
- }
-
- /**
- * Remove directory
- *
- * @param string $dir Directory to remove
- *
- * @return null
- */
- protected function remove_dir($dir)
- {
- try
- {
- $iterator = new \DirectoryIterator($dir);
- }
- catch (Exception $e)
- {
- return;
- }
-
- foreach ($iterator as $fileInfo)
- {
- if ($fileInfo->isDot())
- {
- continue;
- }
-
- if ($fileInfo->isDir())
- {
- $this->remove_dir($fileInfo->getPathname());
- }
- else
- {
- $this->remove_file($fileInfo->getPathname());
- }
- }
-
- @rmdir($dir);
}
/**
@@ -387,27 +300,7 @@ class file extends \phpbb\cache\driver\base
/**
* {@inheritDoc}
*/
- function sql_load($query)
- {
- // Remove extra spaces and tabs
- $query = preg_replace('/[\n\r\s\t]+/', ' ', $query);
-
- if (($rowset = $this->_read('sql_' . md5($query))) === false)
- {
- return false;
- }
-
- $query_id = sizeof($this->sql_rowset);
- $this->sql_rowset[$query_id] = $rowset;
- $this->sql_row_pointer[$query_id] = 0;
-
- return $query_id;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl)
+ function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl)
{
// Remove extra spaces and tabs
$query = preg_replace('/[\n\r\s\t]+/', ' ', $query);
@@ -431,70 +324,6 @@ class file extends \phpbb\cache\driver\base
}
/**
- * {@inheritDoc}
- */
- function sql_exists($query_id)
- {
- return isset($this->sql_rowset[$query_id]);
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_fetchrow($query_id)
- {
- if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id]))
- {
- return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++];
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_fetchfield($query_id, $field)
- {
- if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id]))
- {
- return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false;
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_rowseek($rownum, $query_id)
- {
- if ($rownum >= sizeof($this->sql_rowset[$query_id]))
- {
- return false;
- }
-
- $this->sql_row_pointer[$query_id] = $rownum;
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_freeresult($query_id)
- {
- if (!isset($this->sql_rowset[$query_id]))
- {
- return false;
- }
-
- unset($this->sql_rowset[$query_id]);
- unset($this->sql_row_pointer[$query_id]);
-
- return true;
- }
-
- /**
* Read cached data from a specified file
*
* @access private
@@ -755,28 +584,4 @@ class file extends \phpbb\cache\driver\base
return $return_value;
}
-
- /**
- * Removes/unlinks file
- *
- * @param string $filename Filename to remove
- * @param bool $check Check file permissions
- * @return bool True if the file was successfully removed, otherwise false
- */
- function remove_file($filename, $check = false)
- {
- if (!function_exists('phpbb_is_writable'))
- {
- global $phpbb_root_path, $phpEx;
- include($phpbb_root_path . 'includes/functions.' . $phpEx);
- }
-
- if ($check && !phpbb_is_writable($this->cache_dir))
- {
- // E_USER_ERROR - not using language entry - intended.
- trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR);
- }
-
- return @unlink($filename);
- }
}
diff --git a/phpBB/phpbb/cache/driver/memcache.php b/phpBB/phpbb/cache/driver/memcache.php
index eb3fced973..406ab11ddd 100644
--- a/phpBB/phpbb/cache/driver/memcache.php
+++ b/phpBB/phpbb/cache/driver/memcache.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2005, 2009 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -32,7 +36,6 @@ if (!defined('PHPBB_ACM_MEMCACHE'))
/**
* ACM for Memcached
-* @package acm
*/
class memcache extends \phpbb\cache\driver\memory
{
diff --git a/phpBB/phpbb/cache/driver/memory.php b/phpBB/phpbb/cache/driver/memory.php
index b618b0f3e6..0b0e323e3d 100644
--- a/phpBB/phpbb/cache/driver/memory.php
+++ b/phpBB/phpbb/cache/driver/memory.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,19 +15,11 @@ namespace phpbb\cache\driver;
/**
* ACM Abstract Memory Class
-* @package acm
*/
abstract class memory extends \phpbb\cache\driver\base
{
var $key_prefix;
- var $vars = array();
- var $is_modified = false;
-
- var $sql_rowset = array();
- var $sql_row_pointer = array();
- var $cache_dir = '';
-
/**
* Set cache path
*/
@@ -68,21 +64,6 @@ abstract class memory extends \phpbb\cache\driver\base
/**
* {@inheritDoc}
*/
- function unload()
- {
- $this->save();
- unset($this->vars);
- unset($this->sql_rowset);
- unset($this->sql_row_pointer);
-
- $this->vars = array();
- $this->sql_rowset = array();
- $this->sql_row_pointer = array();
- }
-
- /**
- * {@inheritDoc}
- */
function save()
{
if (!$this->is_modified)
@@ -144,47 +125,6 @@ abstract class memory extends \phpbb\cache\driver\base
/**
* {@inheritDoc}
*/
- function purge()
- {
- // Purge all phpbb cache files
- $dir = @opendir($this->cache_dir);
-
- if (!$dir)
- {
- return;
- }
-
- while (($entry = readdir($dir)) !== false)
- {
- if (strpos($entry, 'container_') !== 0 &&
- strpos($entry, 'url_matcher') !== 0 &&
- strpos($entry, 'sql_') !== 0 &&
- strpos($entry, 'data_') !== 0 &&
- strpos($entry, 'ctpl_') !== 0 &&
- strpos($entry, 'tpl_') !== 0)
- {
- continue;
- }
-
- $this->remove_file($this->cache_dir . $entry);
- }
- closedir($dir);
-
- unset($this->vars);
- unset($this->sql_rowset);
- unset($this->sql_row_pointer);
-
- $this->vars = array();
- $this->sql_rowset = array();
- $this->sql_row_pointer = array();
-
- $this->is_modified = false;
- }
-
-
- /**
- * {@inheritDoc}
- */
function destroy($var_name, $table = '')
{
if ($var_name == 'sql' && !empty($table))
@@ -259,27 +199,7 @@ abstract class memory extends \phpbb\cache\driver\base
/**
* {@inheritDoc}
*/
- function sql_load($query)
- {
- // Remove extra spaces and tabs
- $query = preg_replace('/[\n\r\s\t]+/', ' ', $query);
- $query_id = sizeof($this->sql_rowset);
-
- if (($result = $this->_read('sql_' . md5($query))) === false)
- {
- return false;
- }
-
- $this->sql_rowset[$query_id] = $result;
- $this->sql_row_pointer[$query_id] = 0;
-
- return $query_id;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl)
+ function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl)
{
// Remove extra spaces and tabs
$query = preg_replace('/[\n\r\s\t]+/', ' ', $query);
@@ -288,12 +208,24 @@ abstract class memory extends \phpbb\cache\driver\base
// determine which tables this query belongs to
// Some queries use backticks, namely the get_database_size() query
// don't check for conformity, the SQL would error and not reach here.
- if (!preg_match('/FROM \\(?(`?\\w+`?(?: \\w+)?(?:, ?`?\\w+`?(?: \\w+)?)*)\\)?/', $query, $regs))
+ if (!preg_match_all('/(?:FROM \\(?(`?\\w+`?(?: \\w+)?(?:, ?`?\\w+`?(?: \\w+)?)*)\\)?)|(?:JOIN (`?\\w+`?(?: \\w+)?))/', $query, $regs, PREG_SET_ORDER))
{
// Bail out if the match fails.
return $query_result;
}
- $tables = array_map('trim', explode(',', $regs[1]));
+
+ $tables = array();
+ foreach ($regs as $match)
+ {
+ if ($match[0][0] == 'F')
+ {
+ $tables = array_merge($tables, array_map('trim', explode(',', $match[1])));
+ }
+ else
+ {
+ $tables[] = $match[2];
+ }
+ }
foreach ($tables as $table_name)
{
@@ -335,94 +267,6 @@ abstract class memory extends \phpbb\cache\driver\base
}
/**
- * {@inheritDoc}
- */
- function sql_exists($query_id)
- {
- return isset($this->sql_rowset[$query_id]);
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_fetchrow($query_id)
- {
- if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id]))
- {
- return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++];
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_fetchfield($query_id, $field)
- {
- if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id]))
- {
- return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false;
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_rowseek($rownum, $query_id)
- {
- if ($rownum >= sizeof($this->sql_rowset[$query_id]))
- {
- return false;
- }
-
- $this->sql_row_pointer[$query_id] = $rownum;
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_freeresult($query_id)
- {
- if (!isset($this->sql_rowset[$query_id]))
- {
- return false;
- }
-
- unset($this->sql_rowset[$query_id]);
- unset($this->sql_row_pointer[$query_id]);
-
- return true;
- }
-
- /**
- * Removes/unlinks file
- *
- * @param string $filename Filename to remove
- * @param bool $check Check file permissions
- * @return bool True if the file was successfully removed, otherwise false
- */
- function remove_file($filename, $check = false)
- {
- if (!function_exists('phpbb_is_writable'))
- {
- global $phpbb_root_path, $phpEx;
- include($phpbb_root_path . 'includes/functions.' . $phpEx);
- }
-
- if ($check && !phpbb_is_writable($this->cache_dir))
- {
- // E_USER_ERROR - not using language entry - intended.
- trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR);
- }
-
- return @unlink($filename);
- }
-
- /**
* Check if a cache var exists
*
* @access protected
diff --git a/phpBB/phpbb/cache/driver/null.php b/phpBB/phpbb/cache/driver/null.php
index 8af63eb725..a45cf97862 100644
--- a/phpBB/phpbb/cache/driver/null.php
+++ b/phpBB/phpbb/cache/driver/null.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2005, 2009 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\cache\driver;
/**
* ACM Null Caching
-* @package acm
*/
class null extends \phpbb\cache\driver\base
{
@@ -101,7 +104,7 @@ class null extends \phpbb\cache\driver\base
/**
* {@inheritDoc}
*/
- function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl)
+ function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl)
{
return $query_result;
}
diff --git a/phpBB/phpbb/cache/driver/redis.php b/phpBB/phpbb/cache/driver/redis.php
index 2f2a32a12d..eda774491c 100644
--- a/phpBB/phpbb/cache/driver/redis.php
+++ b/phpBB/phpbb/cache/driver/redis.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -25,7 +29,6 @@ if (!defined('PHPBB_ACM_REDIS_HOST'))
* Compatible with the php extension phpredis available
* at https://github.com/nicolasff/phpredis
*
-* @package acm
*/
class redis extends \phpbb\cache\driver\memory
{
diff --git a/phpBB/phpbb/cache/driver/wincache.php b/phpBB/phpbb/cache/driver/wincache.php
index d0f636d9cb..632b534362 100644
--- a/phpBB/phpbb/cache/driver/wincache.php
+++ b/phpBB/phpbb/cache/driver/wincache.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\cache\driver;
/**
* ACM for WinCache
-* @package acm
*/
class wincache extends \phpbb\cache\driver\memory
{
diff --git a/phpBB/phpbb/cache/driver/xcache.php b/phpBB/phpbb/cache/driver/xcache.php
index 6c9323ec83..0c845a6a8d 100644
--- a/phpBB/phpbb/cache/driver/xcache.php
+++ b/phpBB/phpbb/cache/driver/xcache.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2005, 2009 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\cache\driver;
/**
* ACM for XCache
-* @package acm
*
* To use this module you need ini_get() enabled and the following INI settings configured as follows:
* - xcache.var_size > 0
diff --git a/phpBB/phpbb/cache/service.php b/phpBB/phpbb/cache/service.php
index ebbcfb8cdb..56727c2ad5 100644
--- a/phpBB/phpbb/cache/service.php
+++ b/phpBB/phpbb/cache/service.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package acm
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\cache;
/**
* Class for grabbing/handling cached entries
-* @package acm
*/
class service
{
@@ -32,7 +35,7 @@ class service
/**
* Database connection.
*
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -44,7 +47,7 @@ class service
protected $phpbb_root_path;
/**
- * PHP extension.
+ * PHP file extension.
*
* @var string
*/
@@ -55,11 +58,11 @@ class service
*
* @param \phpbb\cache\driver\driver_interface $driver The cache driver
* @param \phpbb\config\config $config The config
- * @param \phpbb\db\driver\driver $db Database connection
+ * @param \phpbb\db\driver\driver_interface $db Database connection
* @param string $phpbb_root_path Root path
- * @param string $php_ext PHP extension
+ * @param string $php_ext PHP file extension
*/
- public function __construct(\phpbb\cache\driver\driver_interface $driver, \phpbb\config\config $config, \phpbb\db\driver\driver $db, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\cache\driver\driver_interface $driver, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, $phpbb_root_path, $php_ext)
{
$this->set_driver($driver);
$this->config = $config;
@@ -165,18 +168,12 @@ class service
{
if ($row['rank_special'])
{
- $ranks['special'][$row['rank_id']] = array(
- 'rank_title' => $row['rank_title'],
- 'rank_image' => $row['rank_image']
- );
+ unset($row['rank_min']);
+ $ranks['special'][$row['rank_id']] = $row;
}
else
{
- $ranks['normal'][] = array(
- 'rank_title' => $row['rank_title'],
- 'rank_min' => $row['rank_min'],
- 'rank_image' => $row['rank_image']
- );
+ $ranks['normal'][$row['rank_id']] = $row;
}
}
$this->db->sql_freeresult($result);
@@ -302,7 +299,7 @@ class service
{
if (($bots = $this->driver->get('_bots')) === false)
{
- switch ($this->db->sql_layer)
+ switch ($this->db->get_sql_layer())
{
case 'mssql':
case 'mssql_odbc':
@@ -313,13 +310,6 @@ class service
ORDER BY LEN(bot_agent) DESC';
break;
- case 'firebird':
- $sql = 'SELECT user_id, bot_agent, bot_ip
- FROM ' . BOTS_TABLE . '
- WHERE bot_active = 1
- ORDER BY CHAR_LENGTH(bot_agent) DESC';
- break;
-
// LENGTH supported by MySQL, IBM DB2 and Oracle for sure...
default:
$sql = 'SELECT user_id, bot_agent, bot_ip
diff --git a/phpBB/phpbb/captcha/char_cube3d.php b/phpBB/phpbb/captcha/char_cube3d.php
new file mode 100644
index 0000000000..a712b16dce
--- /dev/null
+++ b/phpBB/phpbb/captcha/char_cube3d.php
@@ -0,0 +1,277 @@
+<?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\captcha;
+
+class char_cube3d
+{
+ var $bitmap;
+ var $bitmap_width;
+ var $bitmap_height;
+
+ var $basis_matrix = array(array(1, 0, 0), array(0, 1, 0), array(0, 0, 1));
+ var $abs_x = array(1, 0);
+ var $abs_y = array(0, 1);
+ var $x = 0;
+ var $y = 1;
+ var $z = 2;
+ var $letter = '';
+
+ /**
+ */
+ function __construct(&$bitmaps, $letter)
+ {
+ $this->bitmap = $bitmaps['data'][$letter];
+ $this->bitmap_width = $bitmaps['width'];
+ $this->bitmap_height = $bitmaps['height'];
+
+ $this->basis_matrix[0][0] = mt_rand(-600, 600);
+ $this->basis_matrix[0][1] = mt_rand(-600, 600);
+ $this->basis_matrix[0][2] = (mt_rand(0, 1) * 2000) - 1000;
+ $this->basis_matrix[1][0] = mt_rand(-1000, 1000);
+ $this->basis_matrix[1][1] = mt_rand(-1000, 1000);
+ $this->basis_matrix[1][2] = mt_rand(-1000, 1000);
+
+ $this->normalize($this->basis_matrix[0]);
+ $this->normalize($this->basis_matrix[1]);
+ $this->basis_matrix[2] = $this->cross_product($this->basis_matrix[0], $this->basis_matrix[1]);
+ $this->normalize($this->basis_matrix[2]);
+
+ // $this->basis_matrix[1] might not be (probably isn't) orthogonal to $basis_matrix[0]
+ $this->basis_matrix[1] = $this->cross_product($this->basis_matrix[0], $this->basis_matrix[2]);
+ $this->normalize($this->basis_matrix[1]);
+
+ // Make sure our cube is facing into the canvas (assuming +z == in)
+ for ($i = 0; $i < 3; ++$i)
+ {
+ if ($this->basis_matrix[$i][2] < 0)
+ {
+ $this->basis_matrix[$i][0] *= -1;
+ $this->basis_matrix[$i][1] *= -1;
+ $this->basis_matrix[$i][2] *= -1;
+ }
+ }
+
+ // Force our "z" basis vector to be the one with greatest absolute z value
+ $this->x = 0;
+ $this->y = 1;
+ $this->z = 2;
+
+ // Swap "y" with "z"
+ if ($this->basis_matrix[1][2] > $this->basis_matrix[2][2])
+ {
+ $this->z = 1;
+ $this->y = 2;
+ }
+
+ // Swap "x" with "z"
+ if ($this->basis_matrix[0][2] > $this->basis_matrix[$this->z][2])
+ {
+ $this->x = $this->z;
+ $this->z = 0;
+ }
+
+ // Still need to determine which of $x,$y are which.
+ // wrong orientation if y's y-component is less than it's x-component
+ // likewise if x's x-component is less than it's y-component
+ // if they disagree, go with the one with the greater weight difference.
+ // rotate if positive
+ $weight = (abs($this->basis_matrix[$this->x][1]) - abs($this->basis_matrix[$this->x][0])) + (abs($this->basis_matrix[$this->y][0]) - abs($this->basis_matrix[$this->y][1]));
+
+ // Swap "x" with "y"
+ if ($weight > 0)
+ {
+ list($this->x, $this->y) = array($this->y, $this->x);
+ }
+
+ $this->abs_x = array($this->basis_matrix[$this->x][0], $this->basis_matrix[$this->x][1]);
+ $this->abs_y = array($this->basis_matrix[$this->y][0], $this->basis_matrix[$this->y][1]);
+
+ if ($this->abs_x[0] < 0)
+ {
+ $this->abs_x[0] *= -1;
+ $this->abs_x[1] *= -1;
+ }
+
+ if ($this->abs_y[1] > 0)
+ {
+ $this->abs_y[0] *= -1;
+ $this->abs_y[1] *= -1;
+ }
+
+ $this->letter = $letter;
+ }
+
+ /**
+ * Draw a character
+ */
+ function drawchar($scale, $xoff, $yoff, $img, $background, $colours)
+ {
+ $width = $this->bitmap_width;
+ $height = $this->bitmap_height;
+ $bitmap = $this->bitmap;
+
+ $colour1 = $colours[array_rand($colours)];
+ $colour2 = $colours[array_rand($colours)];
+
+ $swapx = ($this->basis_matrix[$this->x][0] > 0);
+ $swapy = ($this->basis_matrix[$this->y][1] < 0);
+
+ for ($y = 0; $y < $height; ++$y)
+ {
+ for ($x = 0; $x < $width; ++$x)
+ {
+ $xp = ($swapx) ? ($width - $x - 1) : $x;
+ $yp = ($swapy) ? ($height - $y - 1) : $y;
+
+ if ($bitmap[$height - $yp - 1][$xp])
+ {
+ $dx = $this->scale($this->abs_x, ($xp - ($swapx ? ($width / 2) : ($width / 2) - 1)) * $scale);
+ $dy = $this->scale($this->abs_y, ($yp - ($swapy ? ($height / 2) : ($height / 2) - 1)) * $scale);
+ $xo = $xoff + $dx[0] + $dy[0];
+ $yo = $yoff + $dx[1] + $dy[1];
+
+ $origin = array(0, 0, 0);
+ $xvec = $this->scale($this->basis_matrix[$this->x], $scale);
+ $yvec = $this->scale($this->basis_matrix[$this->y], $scale);
+ $face_corner = $this->sum2($xvec, $yvec);
+
+ $zvec = $this->scale($this->basis_matrix[$this->z], $scale);
+ $x_corner = $this->sum2($xvec, $zvec);
+ $y_corner = $this->sum2($yvec, $zvec);
+
+ imagefilledpolygon($img, $this->gen_poly($xo, $yo, $origin, $xvec, $x_corner,$zvec), 4, $colour1);
+ imagefilledpolygon($img, $this->gen_poly($xo, $yo, $origin, $yvec, $y_corner,$zvec), 4, $colour2);
+
+ $face = $this->gen_poly($xo, $yo, $origin, $xvec, $face_corner, $yvec);
+
+ imagefilledpolygon($img, $face, 4, $background);
+ imagepolygon($img, $face, 4, $colour1);
+ }
+ }
+ }
+ }
+
+ /*
+ * return a roughly acceptable range of sizes for rendering with this texttype
+ */
+ function range()
+ {
+ return array(3, 4);
+ }
+
+ /**
+ * Vector length
+ */
+ function vectorlen($vector)
+ {
+ return sqrt(pow($vector[0], 2) + pow($vector[1], 2) + pow($vector[2], 2));
+ }
+
+ /**
+ * Normalize
+ */
+ function normalize(&$vector, $length = 1)
+ {
+ $length = (( $length < 1) ? 1 : $length);
+ $length /= $this->vectorlen($vector);
+ $vector[0] *= $length;
+ $vector[1] *= $length;
+ $vector[2] *= $length;
+ }
+
+ /**
+ */
+ function cross_product($vector1, $vector2)
+ {
+ $retval = array(0, 0, 0);
+ $retval[0] = (($vector1[1] * $vector2[2]) - ($vector1[2] * $vector2[1]));
+ $retval[1] = -(($vector1[0] * $vector2[2]) - ($vector1[2] * $vector2[0]));
+ $retval[2] = (($vector1[0] * $vector2[1]) - ($vector1[1] * $vector2[0]));
+
+ return $retval;
+ }
+
+ /**
+ */
+ function sum($vector1, $vector2)
+ {
+ return array($vector1[0] + $vector2[0], $vector1[1] + $vector2[1], $vector1[2] + $vector2[2]);
+ }
+
+ /**
+ */
+ function sum2($vector1, $vector2)
+ {
+ return array($vector1[0] + $vector2[0], $vector1[1] + $vector2[1]);
+ }
+
+ /**
+ */
+ function scale($vector, $length)
+ {
+ if (sizeof($vector) == 2)
+ {
+ return array($vector[0] * $length, $vector[1] * $length);
+ }
+
+ return array($vector[0] * $length, $vector[1] * $length, $vector[2] * $length);
+ }
+
+ /**
+ */
+ function gen_poly($xoff, $yoff, &$vec1, &$vec2, &$vec3, &$vec4)
+ {
+ $poly = array();
+ $poly[0] = $xoff + $vec1[0];
+ $poly[1] = $yoff + $vec1[1];
+ $poly[2] = $xoff + $vec2[0];
+ $poly[3] = $yoff + $vec2[1];
+ $poly[4] = $xoff + $vec3[0];
+ $poly[5] = $yoff + $vec3[1];
+ $poly[6] = $xoff + $vec4[0];
+ $poly[7] = $yoff + $vec4[1];
+
+ return $poly;
+ }
+
+ /**
+ * dimensions
+ */
+ function dimensions($size)
+ {
+ $xn = $this->scale($this->basis_matrix[$this->x], -($this->bitmap_width / 2) * $size);
+ $xp = $this->scale($this->basis_matrix[$this->x], ($this->bitmap_width / 2) * $size);
+ $yn = $this->scale($this->basis_matrix[$this->y], -($this->bitmap_height / 2) * $size);
+ $yp = $this->scale($this->basis_matrix[$this->y], ($this->bitmap_height / 2) * $size);
+
+ $p = array();
+ $p[0] = $this->sum2($xn, $yn);
+ $p[1] = $this->sum2($xp, $yn);
+ $p[2] = $this->sum2($xp, $yp);
+ $p[3] = $this->sum2($xn, $yp);
+
+ $min_x = $max_x = $p[0][0];
+ $min_y = $max_y = $p[0][1];
+
+ for ($i = 1; $i < 4; ++$i)
+ {
+ $min_x = ($min_x > $p[$i][0]) ? $p[$i][0] : $min_x;
+ $min_y = ($min_y > $p[$i][1]) ? $p[$i][1] : $min_y;
+ $max_x = ($max_x < $p[$i][0]) ? $p[$i][0] : $max_x;
+ $max_y = ($max_y < $p[$i][1]) ? $p[$i][1] : $max_y;
+ }
+
+ return array($min_x, $min_y, $max_x, $max_y);
+ }
+}
diff --git a/phpBB/phpbb/captcha/colour_manager.php b/phpBB/phpbb/captcha/colour_manager.php
new file mode 100644
index 0000000000..6ca3c3fd2c
--- /dev/null
+++ b/phpBB/phpbb/captcha/colour_manager.php
@@ -0,0 +1,527 @@
+<?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\captcha;
+
+class colour_manager
+{
+ var $img;
+ var $mode;
+ var $colours;
+ var $named_colours;
+
+ /**
+ * Create the colour manager, link it to the image resource
+ */
+ function __construct($img, $background = false, $mode = 'ahsv')
+ {
+ $this->img = $img;
+ $this->mode = $mode;
+ $this->colours = array();
+ $this->named_colours = array();
+
+ if ($background !== false)
+ {
+ $bg = $this->allocate_named('background', $background);
+ imagefill($this->img, 0, 0, $bg);
+ }
+ }
+
+ /**
+ * Lookup a named colour resource
+ */
+ function get_resource($named_colour)
+ {
+ if (isset($this->named_colours[$named_colour]))
+ {
+ return $this->named_colours[$named_colour];
+ }
+
+ if (isset($this->named_rgb[$named_colour]))
+ {
+ return $this->allocate_named($named_colour, $this->named_rgb[$named_colour], 'rgb');
+ }
+
+ return false;
+ }
+
+ /**
+ * Assign a name to a colour resource
+ */
+ function name_colour($name, $resource)
+ {
+ $this->named_colours[$name] = $resource;
+ }
+
+ /**
+ * names and allocates a colour resource
+ */
+ function allocate_named($name, $colour, $mode = false)
+ {
+ $resource = $this->allocate($colour, $mode);
+
+ if ($resource !== false)
+ {
+ $this->name_colour($name, $resource);
+ }
+ return $resource;
+ }
+
+ /**
+ * allocates a specified colour into the image
+ */
+ function allocate($colour, $mode = false)
+ {
+ if ($mode === false)
+ {
+ $mode = $this->mode;
+ }
+
+ if (!is_array($colour))
+ {
+ if (isset($this->named_rgb[$colour]))
+ {
+ return $this->allocate_named($colour, $this->named_rgb[$colour], 'rgb');
+ }
+
+ if (!is_int($colour))
+ {
+ return false;
+ }
+
+ $mode = 'rgb';
+ $colour = array(255 & ($colour >> 16), 255 & ($colour >> 8), 255 & $colour);
+ }
+
+ if (isset($colour['mode']))
+ {
+ $mode = $colour['mode'];
+ unset($colour['mode']);
+ }
+
+ if (isset($colour['random']))
+ {
+ unset($colour['random']);
+ // everything else is params
+ return $this->random_colour($colour, $mode);
+ }
+
+ $rgb = $this->model_convert($colour, $mode, 'rgb');
+ $store = ($this->mode == 'rgb') ? $rgb : $this->model_convert($colour, $mode, $this->mode);
+ $resource = imagecolorallocate($this->img, $rgb[0], $rgb[1], $rgb[2]);
+ $this->colours[$resource] = $store;
+
+ return $resource;
+ }
+
+ /**
+ * randomly generates a colour, with optional params
+ */
+ function random_colour($params = array(), $mode = false)
+ {
+ if ($mode === false)
+ {
+ $mode = $this->mode;
+ }
+
+ switch ($mode)
+ {
+ case 'rgb':
+ // @TODO random rgb generation. do we intend to do this, or is it just too tedious?
+ break;
+
+ case 'ahsv':
+ case 'hsv':
+ default:
+
+ $default_params = array(
+ 'hue_bias' => false, // degree / 'r'/'g'/'b'/'c'/'m'/'y' /'o'
+ 'hue_range' => false, // if hue bias, then difference range +/- from bias
+ 'min_saturation' => 30, // 0 - 100
+ 'max_saturation' => 80, // 0 - 100
+ 'min_value' => 30, // 0 - 100
+ 'max_value' => 80, // 0 - 100
+ );
+
+ $alt = ($mode == 'ahsv') ? true : false;
+ $params = array_merge($default_params, $params);
+
+ $min_hue = 0;
+ $max_hue = 359;
+ $min_saturation = max(0, $params['min_saturation']);
+ $max_saturation = min(100, $params['max_saturation']);
+ $min_value = max(0, $params['min_value']);
+ $max_value = min(100, $params['max_value']);
+
+ if ($params['hue_bias'] !== false)
+ {
+ if (is_numeric($params['hue_bias']))
+ {
+ $h = intval($params['hue_bias']) % 360;
+ }
+ else
+ {
+ switch ($params['hue_bias'])
+ {
+ case 'o':
+ $h = $alt ? 60 : 30;
+ break;
+
+ case 'y':
+ $h = $alt ? 120 : 60;
+ break;
+
+ case 'g':
+ $h = $alt ? 180 : 120;
+ break;
+
+ case 'c':
+ $h = $alt ? 210 : 180;
+ break;
+
+ case 'b':
+ $h = 240;
+ break;
+
+ case 'm':
+ $h = 300;
+ break;
+
+ case 'r':
+ default:
+ $h = 0;
+ break;
+ }
+ }
+
+ $min_hue = $h + 360;
+ $max_hue = $h + 360;
+
+ if ($params['hue_range'])
+ {
+ $min_hue -= min(180, $params['hue_range']);
+ $max_hue += min(180, $params['hue_range']);
+ }
+ }
+
+ $h = mt_rand($min_hue, $max_hue);
+ $s = mt_rand($min_saturation, $max_saturation);
+ $v = mt_rand($min_value, $max_value);
+
+ return $this->allocate(array($h, $s, $v), $mode);
+
+ break;
+ }
+ }
+
+ /**
+ */
+ function colour_scheme($resource, $include_original = true)
+ {
+ $mode = 'hsv';
+
+ if (($pre = $this->get_resource($resource)) !== false)
+ {
+ $resource = $pre;
+ }
+
+ $colour = $this->model_convert($this->colours[$resource], $this->mode, $mode);
+ $results = ($include_original) ? array($resource) : array();
+ $colour2 = $colour3 = $colour4 = $colour;
+ $colour2[0] += 150;
+ $colour3[0] += 180;
+ $colour4[0] += 210;
+
+ $results[] = $this->allocate($colour2, $mode);
+ $results[] = $this->allocate($colour3, $mode);
+ $results[] = $this->allocate($colour4, $mode);
+
+ return $results;
+ }
+
+ /**
+ */
+ function mono_range($resource, $count = 5, $include_original = true)
+ {
+ if (is_array($resource))
+ {
+ $results = array();
+ for ($i = 0, $size = sizeof($resource); $i < $size; ++$i)
+ {
+ $results = array_merge($results, $this->mono_range($resource[$i], $count, $include_original));
+ }
+ return $results;
+ }
+
+ $mode = (in_array($this->mode, array('hsv', 'ahsv'), true) ? $this->mode : 'ahsv');
+ if (($pre = $this->get_resource($resource)) !== false)
+ {
+ $resource = $pre;
+ }
+
+ $colour = $this->model_convert($this->colours[$resource], $this->mode, $mode);
+
+ $results = array();
+ if ($include_original)
+ {
+ $results[] = $resource;
+ $count--;
+ }
+
+ // This is a hard problem. I chicken out and try to maintain readability at the cost of less randomness.
+
+ while ($count > 0)
+ {
+ $colour[1] = ($colour[1] + mt_rand(40,60)) % 99;
+ $colour[2] = ($colour[2] + mt_rand(40,60));
+ $results[] = $this->allocate($colour, $mode);
+ $count--;
+ }
+ return $results;
+ }
+
+ /**
+ * Convert from one colour model to another
+ */
+ function model_convert($colour, $from_model, $to_model)
+ {
+ if ($from_model == $to_model)
+ {
+ return $colour;
+ }
+
+ switch ($to_model)
+ {
+ case 'hsv':
+
+ switch ($from_model)
+ {
+ case 'ahsv':
+ return $this->ah2h($colour);
+ break;
+
+ case 'rgb':
+ return $this->rgb2hsv($colour);
+ break;
+ }
+ break;
+
+ case 'ahsv':
+
+ switch ($from_model)
+ {
+ case 'hsv':
+ return $this->h2ah($colour);
+ break;
+
+ case 'rgb':
+ return $this->h2ah($this->rgb2hsv($colour));
+ break;
+ }
+ break;
+
+ case 'rgb':
+ switch ($from_model)
+ {
+ case 'hsv':
+ return $this->hsv2rgb($colour);
+ break;
+
+ case 'ahsv':
+ return $this->hsv2rgb($this->ah2h($colour));
+ break;
+ }
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * Slightly altered from wikipedia's algorithm
+ */
+ function hsv2rgb($hsv)
+ {
+ $this->normalize_hue($hsv[0]);
+
+ $h = $hsv[0];
+ $s = min(1, max(0, $hsv[1] / 100));
+ $v = min(1, max(0, $hsv[2] / 100));
+
+ // calculate hue sector
+ $hi = floor($hsv[0] / 60);
+
+ // calculate opposite colour
+ $p = $v * (1 - $s);
+
+ // calculate distance between hex vertices
+ $f = ($h / 60) - $hi;
+
+ // coming in or going out?
+ if (!($hi & 1))
+ {
+ $f = 1 - $f;
+ }
+
+ // calculate adjacent colour
+ $q = $v * (1 - ($f * $s));
+
+ switch ($hi)
+ {
+ case 0:
+ $rgb = array($v, $q, $p);
+ break;
+
+ case 1:
+ $rgb = array($q, $v, $p);
+ break;
+
+ case 2:
+ $rgb = array($p, $v, $q);
+ break;
+
+ case 3:
+ $rgb = array($p, $q, $v);
+ break;
+
+ case 4:
+ $rgb = array($q, $p, $v);
+ break;
+
+ case 5:
+ $rgb = array($v, $p, $q);
+ break;
+
+ default:
+ return array(0, 0, 0);
+ break;
+ }
+
+ return array(255 * $rgb[0], 255 * $rgb[1], 255 * $rgb[2]);
+ }
+
+ /**
+ * (more than) Slightly altered from wikipedia's algorithm
+ */
+ function rgb2hsv($rgb)
+ {
+ $r = min(255, max(0, $rgb[0]));
+ $g = min(255, max(0, $rgb[1]));
+ $b = min(255, max(0, $rgb[2]));
+ $max = max($r, $g, $b);
+ $min = min($r, $g, $b);
+
+ $v = $max / 255;
+ $s = (!$max) ? 0 : 1 - ($min / $max);
+
+ // if max - min is 0, we want hue to be 0 anyway.
+ $h = $max - $min;
+
+ if ($h)
+ {
+ switch ($max)
+ {
+ case $g:
+ $h = 120 + (60 * ($b - $r) / $h);
+ break;
+
+ case $b:
+ $h = 240 + (60 * ($r - $g) / $h);
+ break;
+
+ case $r:
+ $h = 360 + (60 * ($g - $b) / $h);
+ break;
+ }
+ }
+ $this->normalize_hue($h);
+
+ return array($h, $s * 100, $v * 100);
+ }
+
+ /**
+ */
+ function normalize_hue(&$hue)
+ {
+ $hue %= 360;
+
+ if ($hue < 0)
+ {
+ $hue += 360;
+ }
+ }
+
+ /**
+ * Alternate hue to hue
+ */
+ function ah2h($ahue)
+ {
+ if (is_array($ahue))
+ {
+ $ahue[0] = $this->ah2h($ahue[0]);
+ return $ahue;
+ }
+ $this->normalize_hue($ahue);
+
+ // blue through red is already ok
+ if ($ahue >= 240)
+ {
+ return $ahue;
+ }
+
+ // ahue green is at 180
+ if ($ahue >= 180)
+ {
+ // return (240 - (2 * (240 - $ahue)));
+ return (2 * $ahue) - 240; // equivalent
+ }
+
+ // ahue yellow is at 120 (RYB rather than RGB)
+ if ($ahue >= 120)
+ {
+ return $ahue - 60;
+ }
+
+ return $ahue / 2;
+ }
+
+ /**
+ * hue to Alternate hue
+ */
+ function h2ah($hue)
+ {
+ if (is_array($hue))
+ {
+ $hue[0] = $this->h2ah($hue[0]);
+ return $hue;
+ }
+ $this->normalize_hue($hue);
+
+ // blue through red is already ok
+ if ($hue >= 240)
+ {
+ return $hue;
+ }
+ else if ($hue <= 60)
+ {
+ return $hue * 2;
+ }
+ else if ($hue <= 120)
+ {
+ return $hue + 60;
+ }
+ else
+ {
+ return ($hue + 240) / 2;
+ }
+ }
+}
diff --git a/phpBB/phpbb/captcha/factory.php b/phpBB/phpbb/captcha/factory.php
new file mode 100644
index 0000000000..dd44aca8bb
--- /dev/null
+++ b/phpBB/phpbb/captcha/factory.php
@@ -0,0 +1,88 @@
+<?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\captcha;
+
+class factory
+{
+ /**
+ * @var \Symfony\Component\DependencyInjection\ContainerInterface
+ */
+ private $container;
+
+ /**
+ * @var \phpbb\di\service_collection
+ */
+ private $plugins;
+
+ /**
+ * Constructor
+ *
+ * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
+ * @param \phpbb\di\service_collection $plugins
+ */
+ public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container, \phpbb\di\service_collection $plugins)
+ {
+ $this->container = $container;
+ $this->plugins = $plugins;
+ }
+
+ /**
+ * Return a new instance of a given plugin
+ *
+ * @param $name
+ * @return object
+ */
+ public function get_instance($name)
+ {
+ return $this->container->get($name);
+ }
+
+ /**
+ * Call the garbage collector
+ *
+ * @param string $name The name to the captcha service.
+ */
+ function garbage_collect($name)
+ {
+ $captcha = $this->get_instance($name);
+ $captcha->garbage_collect(0);
+ }
+
+ /**
+ * Return a list of all registered CAPTCHA plugins
+ *
+ * @returns array
+ */
+ function get_captcha_types()
+ {
+ $captchas = array(
+ 'available' => array(),
+ 'unavailable' => array(),
+ );
+
+ foreach ($this->plugins as $plugin => $plugin_instance)
+ {
+ if ($plugin_instance->is_available())
+ {
+ $captchas['available'][$plugin] = $plugin_instance->get_name();
+ }
+ else
+ {
+ $captchas['unavailable'][$plugin] = $plugin_instance->get_name();
+ }
+ }
+
+ return $captchas;
+ }
+}
diff --git a/phpBB/phpbb/captcha/gd.php b/phpBB/phpbb/captcha/gd.php
new file mode 100644
index 0000000000..652df28f8a
--- /dev/null
+++ b/phpBB/phpbb/captcha/gd.php
@@ -0,0 +1,1847 @@
+<?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\captcha;
+
+class gd
+{
+ var $width = 360;
+ var $height = 96;
+
+ /**
+ * Create the image containing $code with a seed of $seed
+ */
+ function execute($code, $seed)
+ {
+ global $config;
+
+ mt_srand($seed);
+
+ // Create image
+ $img = imagecreatetruecolor($this->width, $this->height);
+
+ // Generate colours
+ $colour = new colour_manager($img, array(
+ 'random' => true,
+ 'min_value' => 60,
+ ), 'hsv');
+
+ $scheme = $colour->colour_scheme('background', false);
+ $scheme = $colour->mono_range($scheme, 10, false);
+ shuffle($scheme);
+
+ $bg_colours = array_splice($scheme, mt_rand(6, 12));
+
+ // Generate code characters
+ $characters = $sizes = $bounding_boxes = $noise = array();
+ $width_avail = $this->width - 15;
+ $code_len = strlen($code);
+ $captcha_bitmaps = $this->captcha_bitmaps();
+
+ for ($i = 0; $i < $code_len; ++$i)
+ {
+ $characters[$i] = new char_cube3d($captcha_bitmaps, $code[$i]);
+
+ list($min, $max) = $characters[$i]->range();
+ $sizes[$i] = mt_rand($min, $max);
+
+ $box = $characters[$i]->dimensions($sizes[$i]);
+ $width_avail -= ($box[2] - $box[0]);
+ $bounding_boxes[$i] = $box;
+ }
+
+ // Redistribute leftover x-space
+ $offset = array();
+ for ($i = 0; $i < $code_len; ++$i)
+ {
+ $denom = ($code_len - $i);
+ $denom = max(1.3, $denom);
+ $offset[$i] = phpbb_mt_rand(0, (int) round((1.5 * $width_avail) / $denom));
+ $width_avail -= $offset[$i];
+ }
+
+ if ($config['captcha_gd_x_grid'])
+ {
+ $grid = (int) $config['captcha_gd_x_grid'];
+ for ($y = 0; $y < $this->height; $y += mt_rand($grid - 2, $grid + 2))
+ {
+ $current_colour = $scheme[array_rand($scheme)];
+ imageline($img, mt_rand(0,4), mt_rand($y - 3, $y), mt_rand($this->width - 5, $this->width), mt_rand($y - 3, $y), $current_colour);
+ }
+ }
+
+ if ($config['captcha_gd_y_grid'])
+ {
+ $grid = (int) $config['captcha_gd_y_grid'];
+ for ($x = 0; $x < $this->width; $x += mt_rand($grid - 2, $grid + 2))
+ {
+ $current_colour = $scheme[array_rand($scheme)];
+ imagedashedline($img, mt_rand($x -3, $x + 3), mt_rand(0, 4), mt_rand($x -3, $x + 3), mt_rand($this->height - 5, $this->height), $current_colour);
+ }
+ }
+
+ if ($config['captcha_gd_wave'] && ($config['captcha_gd_y_grid'] || $config['captcha_gd_y_grid']))
+ {
+ $this->wave($img);
+ }
+
+ if ($config['captcha_gd_3d_noise'])
+ {
+ $xoffset = mt_rand(0,9);
+ $noise_bitmaps = $this->captcha_noise_bg_bitmaps();
+ for ($i = 0; $i < $code_len; ++$i)
+ {
+ $noise[$i] = new char_cube3d($noise_bitmaps, mt_rand(1, sizeof($noise_bitmaps['data'])));
+
+ list($min, $max) = $noise[$i]->range();
+ //$box = $noise[$i]->dimensions($sizes[$i]);
+ }
+ $xoffset = 0;
+ for ($i = 0; $i < $code_len; ++$i)
+ {
+ $dimm = $bounding_boxes[$i];
+ $xoffset += ($offset[$i] - $dimm[0]);
+ $yoffset = mt_rand(-$dimm[1], $this->height - $dimm[3]);
+
+ $noise[$i]->drawchar($sizes[$i], $xoffset, $yoffset, $img, $colour->get_resource('background'), $scheme);
+ $xoffset += $dimm[2];
+ }
+ }
+
+ $xoffset = 5;
+ for ($i = 0; $i < $code_len; ++$i)
+ {
+ $dimm = $bounding_boxes[$i];
+ $xoffset += ($offset[$i] - $dimm[0]);
+ $yoffset = mt_rand(-$dimm[1], $this->height - $dimm[3]);
+
+ $characters[$i]->drawchar($sizes[$i], $xoffset, $yoffset, $img, $colour->get_resource('background'), $scheme);
+ $xoffset += $dimm[2];
+ }
+
+ if ($config['captcha_gd_wave'])
+ {
+ $this->wave($img);
+ }
+
+ if ($config['captcha_gd_foreground_noise'])
+ {
+ $this->noise_line($img, 0, 0, $this->width, $this->height, $colour->get_resource('background'), $scheme, $bg_colours);
+ }
+
+ // Send image
+ header('Content-Type: image/png');
+ header('Cache-control: no-cache, no-store');
+ imagepng($img);
+ imagedestroy($img);
+ }
+
+ /**
+ * Sinus
+ */
+ function wave($img)
+ {
+ global $config;
+
+ $period_x = mt_rand(12,18);
+ $period_y = mt_rand(7,14);
+ $amp_x = mt_rand(5,10);
+ $amp_y = mt_rand(2,4);
+ $socket = mt_rand(0,100);
+
+ $dampen_x = mt_rand($this->width/5, $this->width/2);
+ $dampen_y = mt_rand($this->height/5, $this->height/2);
+ $direction_x = (mt_rand (0, 1));
+ $direction_y = (mt_rand (0, 1));
+
+ for ($i = 0; $i < $this->width; $i++)
+ {
+ $dir = ($direction_x) ? $i : ($this->width - $i);
+ imagecopy($img, $img, $i-1, sin($socket+ $i/($period_x + $dir/$dampen_x)) * $amp_x, $i, 0, 1, $this->height);
+ }
+ $socket = mt_rand(0,100);
+ for ($i = 0; $i < $this->height; $i++)
+ {
+ $dir = ($direction_y) ? $i : ($this->height - $i);
+ imagecopy($img, $img ,sin($socket + $i/($period_y + ($dir)/$dampen_y)) * $amp_y, $i-1, 0, $i, $this->width, 1);
+ }
+ return $img;
+ }
+
+ /**
+ * Noise line
+ */
+ function noise_line($img, $min_x, $min_y, $max_x, $max_y, $bg, $font, $non_font)
+ {
+ imagesetthickness($img, 2);
+
+ $x1 = $min_x;
+ $x2 = $max_x;
+ $y1 = $min_y;
+ $y2 = $min_y;
+
+ do
+ {
+ $line = array_merge(
+ array_fill(0, mt_rand(30, 60), $non_font[array_rand($non_font)]),
+ array_fill(0, mt_rand(30, 60), $bg)
+ );
+
+ imagesetstyle($img, $line);
+ imageline($img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
+
+ $y1 += mt_rand(12, 35);
+ $y2 += mt_rand(12, 35);
+ }
+ while ($y1 < $max_y && $y2 < $max_y);
+
+ $x1 = $min_x;
+ $x2 = $min_x;
+ $y1 = $min_y;
+ $y2 = $max_y;
+
+ do
+ {
+ $line = array_merge(
+ array_fill(0, mt_rand(30, 60), $non_font[array_rand($non_font)]),
+ array_fill(0, mt_rand(30, 60), $bg)
+ );
+
+ imagesetstyle($img, $line);
+ imageline($img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
+
+ $x1 += mt_rand(20, 35);
+ $x2 += mt_rand(20, 35);
+ }
+ while ($x1 < $max_x && $x2 < $max_x);
+ imagesetthickness($img, 1);
+ }
+
+ function captcha_noise_bg_bitmaps()
+ {
+ return array(
+ 'width' => 15,
+ 'height' => 5,
+ 'data' => array(
+
+ 1 => array(
+ array(1,0,0,0,1,0,0,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,1,0,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,1,0,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0,0,0,1,0,0,0),
+ ),
+ 2 => array(
+ array(1,1,mt_rand(0,1),1,0,1,1,1,1,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,1,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0,1,1,0,1,1,1),
+ ),
+ 3 => array(
+ array(1,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,1,0,0,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
+ ),
+ 4 => array(
+ array(1,0,1,0,1,0,0,1,1,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,1,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ array(1,0,1,0,0,0,0,0,0,0,0,0,0,0,0),
+ ),
+ 5 => array(
+ array(1,1,1,1,0,0,0,1,1,1,0,0,1,0,1),
+ array(0,0,0,0,0,0,0,1,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ array(1,0,1,0,0,0,0,0,0,0,0,0,0,0,0),
+ ),
+ 6 => array(
+ array(mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),0,mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),0,mt_rand(0,1),mt_rand(0,1),mt_rand(0,1)),
+ array(0,0,0,0,0,0,0,mt_rand(0,1),0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ array(mt_rand(0,1),0,mt_rand(0,1),0,0,0,0,0,0,0,0,0,0,0,0),
+ ),
+ 7 => array(
+ array(0,0,0,0,0,0,0,0,0,0,1,1,0,1,1),
+ array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ array(0,0,1,1,0,0,0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,1,0,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
+ ),
+ ));
+ }
+
+ /**
+ * Return bitmaps
+ */
+ function captcha_bitmaps()
+ {
+ global $config;
+
+ $chars = array(
+ 'A' => array(
+ array(
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,1,1,1,1,1,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,1,1,0,1,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,1,1,1,1,1,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,1,0,0,0,1,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,1),
+ array(0,0,0,0,0,1,1,1,1),
+ array(0,0,0,1,1,1,0,0,1),
+ array(0,1,1,1,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,1,0,0,0,0,1,1,1),
+ array(0,1,1,1,1,1,1,0,1),
+ ),
+ ),
+ 'B' => array(
+ array(
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(1,1,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,1,1,1,1,1,0,0),
+ ),
+ ),
+ 'C' => array(
+ array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(0,0,1,1,1,1,1,0,1),
+ array(0,1,0,0,0,0,0,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,1),
+ array(0,0,1,1,1,1,1,0,1),
+ ),
+ ),
+ 'D' => array(
+ array(
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(1,1,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,1,1,1,1,1,0,1),
+ array(0,1,1,0,0,0,1,1,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,1,0,0,0,1,1,1),
+ array(0,0,1,1,1,1,1,0,1),
+ ),
+ ),
+ 'E' => array(
+ array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,1,1,1,1,1,1,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,1,1,1,1,1,1,1),
+ ),
+ array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,1,1,1,1,1,1,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(0,1,1,1,1,1,1,1,0),
+ ),
+ ),
+ 'F' => array(
+ array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ ),
+ array(
+ array(0,1,1,1,1,1,1,1,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,1,1,0,0,0,0,0,0),
+ ),
+ array(
+ array(0,0,0,1,1,0,0,0,0),
+ array(0,0,1,1,0,0,0,0,0),
+ array(0,1,1,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,1,1,1,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ ),
+ ),
+ 'G' => array(
+ array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,1,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(0,0,1,1,1,1,1,0,1),
+ array(0,1,0,0,0,0,0,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,1,1,1,1,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,1),
+ array(0,0,1,1,1,1,1,0,1),
+ ),
+ array(
+ array(0,0,1,1,1,1,1,0,1),
+ array(0,1,1,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,1,1,0,0,0,0,0,1),
+ array(0,0,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,1),
+ array(1,1,1,1,1,1,1,1,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ ),
+ 'H' => array(
+ array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ ),
+ array(
+ array(1,1,1,0,0,0,1,1,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,1,1,1,1,1,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,1,0,0,0,1,1,1),
+ ),
+ array(
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,1,1,1,0,0,0),
+ array(1,1,1,1,0,1,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ ),
+ ),
+ 'I' => array(
+ array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(1,1,1,1,1,1,1,1,1),
+ ),
+ array(
+ array(0,0,0,1,1,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,1,1,0,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,1,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,1,1,0,0,0),
+ ),
+ ),
+ 'J' => array(
+ array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(0,1,0,0,1,0,0,0,0),
+ array(0,0,1,1,0,0,0,0,0),
+ ),
+ array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,1,0,0,1,0,0,0,0),
+ array(1,0,1,1,0,0,0,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(0,1,0,0,1,0,0,0,0),
+ array(0,0,1,1,0,0,0,0,0),
+ ),
+ ),
+ 'K' => array(
+ array( // New 'K', supplied by NeoThermic
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,1,0,0,0,0),
+ array(1,0,0,1,0,0,0,0,0),
+ array(1,0,1,0,0,0,0,0,0),
+ array(1,1,0,0,0,0,0,0,0),
+ array(1,0,1,0,0,0,0,0,0),
+ array(1,0,0,1,0,0,0,0,0),
+ array(1,0,0,0,1,0,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ ),
+ array(
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,1,0,0),
+ array(0,1,0,0,0,1,0,0,0),
+ array(0,1,0,0,1,0,0,0,0),
+ array(0,1,0,1,0,0,0,0,0),
+ array(0,1,1,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,1,0,0,0,0,0,0),
+ array(0,1,0,1,0,0,0,0,0),
+ array(0,1,0,0,1,0,0,0,0),
+ array(0,1,0,0,0,1,0,0,0),
+ array(0,1,0,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,1,0,0,0,1,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,1,0,0,0),
+ array(0,1,0,0,1,0,0,0,0),
+ array(0,1,0,1,0,0,0,0,0),
+ array(0,1,1,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,1,0,0,0,0,0,0),
+ array(0,1,0,1,0,0,0,0,0),
+ array(0,1,0,0,1,0,0,0,0),
+ array(0,1,0,0,0,1,0,0,0),
+ array(0,1,0,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ ),
+ ),
+ 'L' => array(
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,1,1,1,1,1,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,1),
+ array(1,1,1,1,1,1,1,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,1,0,0,0,0,0,0),
+ array(0,0,1,1,1,0,0,0,0),
+ ),
+ ),
+ 'M' => array(
+ array(
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,0,1,0,0,0,1,0,1),
+ array(1,0,1,0,0,0,1,0,1),
+ array(1,0,1,0,0,0,1,0,1),
+ array(1,0,0,1,0,1,0,0,1),
+ array(1,0,0,1,0,1,0,0,1),
+ array(1,0,0,1,0,1,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(0,1,0,1,0,1,0,1,0),
+ array(0,1,0,1,0,1,0,1,0),
+ array(0,1,0,1,0,1,0,1,0),
+ array(0,1,0,0,1,0,0,1,0),
+ array(0,1,0,0,1,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,1,0,0,0,1,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,1,1,0,1,1,1,0),
+ array(1,1,0,1,1,1,0,1,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ ),
+ ),
+ 'N' => array(
+ array(
+ array(1,1,0,0,0,0,0,0,1),
+ array(1,1,0,0,0,0,0,0,1),
+ array(1,0,1,0,0,0,0,0,1),
+ array(1,0,1,0,0,0,0,0,1),
+ array(1,0,0,1,0,0,0,0,1),
+ array(1,0,0,1,0,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,0,1,0,0,1),
+ array(1,0,0,0,0,1,0,0,1),
+ array(1,0,0,0,0,0,1,0,1),
+ array(1,0,0,0,0,0,1,0,1),
+ array(1,0,0,0,0,0,0,1,1),
+ array(1,0,0,0,0,0,0,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,1,0,0,0,0,1,0),
+ array(0,1,1,0,0,0,0,1,0),
+ array(0,1,1,0,0,0,0,1,0),
+ array(0,1,0,1,0,0,0,1,0),
+ array(0,1,0,1,0,0,0,1,0),
+ array(0,1,0,1,0,0,0,1,0),
+ array(0,1,0,0,1,0,0,1,0),
+ array(0,1,0,0,1,1,0,1,0),
+ array(0,1,0,0,0,1,0,1,0),
+ array(0,1,0,0,0,1,1,1,0),
+ array(0,1,0,0,0,0,1,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,1,0,0,0,1,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(1,0,1,1,1,1,0,0,0),
+ array(1,1,1,0,0,1,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ ),
+ ),
+ 'O' => array(
+ array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,1,1,1,1,0,0,0),
+ array(1,1,1,0,0,1,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,1,0,0,0,1,1,0,0),
+ array(0,1,1,1,1,1,0,0,0),
+ ),
+ ),
+ 'P' => array(
+ array(
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ ),
+ array(
+ array(1,1,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,1,1,0,0,0,0,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,1,1,0,0,0,0,0),
+ array(1,1,0,1,1,0,0,0,0),
+ array(1,0,0,0,1,0,0,0,0),
+ array(1,0,0,0,1,0,0,0,0),
+ array(1,0,0,1,1,0,0,0,0),
+ array(1,1,1,1,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ ),
+ ),
+ 'Q' => array(
+ array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,1,0,0,1),
+ array(1,0,0,0,0,0,1,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,1),
+ ),
+ array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,1,0,0,1,1,0,1,1),
+ array(0,1,1,1,1,1,1,1,0),
+ array(0,0,0,0,0,0,1,1,0),
+ array(0,0,0,0,0,0,0,1,1),
+ array(0,0,0,0,0,0,0,0,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,1,1,1,1),
+ array(0,0,0,0,1,1,0,0,1),
+ array(0,0,0,0,1,0,0,0,1),
+ array(0,0,0,0,1,0,0,0,1),
+ array(0,0,0,0,1,1,0,1,1),
+ array(0,0,0,0,0,1,1,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ ),
+ ),
+ 'R' => array(
+ array(
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,1,1,0,0,0,0,0,0),
+ array(1,0,0,1,0,0,0,0,0),
+ array(1,0,0,0,1,0,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ ),
+ array(
+ array(1,1,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(0,1,1,0,0,0,0,0,0),
+ array(0,1,1,1,0,0,0,0,0),
+ array(0,1,0,1,1,0,0,0,0),
+ array(0,1,0,0,1,1,0,0,0),
+ array(0,1,0,0,0,1,1,0,0),
+ array(0,1,0,0,0,0,1,1,0),
+ array(1,1,1,0,0,0,1,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,1,1,1,0,0,0,0),
+ array(1,1,0,0,1,1,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ ),
+ ),
+ 'S' => array(
+ array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(0,0,1,1,1,1,1,0,1),
+ array(0,1,0,0,0,0,0,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,1,0,0,0,0,0,1,0),
+ array(1,0,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,1,1,1,0,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,0,0,0,0,0,0,0),
+ array(0,1,1,1,1,0,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,1,1,0,0,0),
+ array(0,1,1,1,1,0,0,0,0),
+ ),
+ ),
+ 'T' => array(
+ array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ ),
+ array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,1,1,0,0,0),
+ ),
+ array(
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,1,1,1,1,1,1,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,1,0,0,0),
+ array(0,0,0,0,0,1,1,1,0),
+ ),
+ ),
+ 'U' => array(
+ array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,1,0,0,0,1,1,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,1,0,0,0,0,0,1),
+ array(0,0,1,0,0,0,0,0,1),
+ array(0,0,1,0,0,0,0,0,1),
+ array(0,0,1,0,0,0,0,0,1),
+ array(0,0,1,0,0,0,0,0,1),
+ array(0,0,1,0,0,0,0,1,1),
+ array(0,0,1,1,0,0,1,1,1),
+ array(0,0,0,1,1,1,1,0,1),
+ ),
+ ),
+ 'V' => array(
+ array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(1,1,1,0,0,0,1,1,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ ),
+ ),
+ 'W' => array(
+ array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,1,0,1,0,0,1),
+ array(1,0,0,1,0,1,0,0,1),
+ array(1,0,0,1,0,1,0,0,1),
+ array(1,0,1,0,0,0,1,0,1),
+ array(1,0,1,0,0,0,1,0,1),
+ array(1,0,1,0,0,0,1,0,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,1,0,0,0,0,0,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(1,1,1,0,0,0,1,1,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,1,0,0,1,0),
+ array(0,1,0,0,1,0,0,1,0),
+ array(0,1,0,1,1,1,0,1,0),
+ array(0,1,0,1,0,1,0,1,0),
+ array(0,1,1,1,0,1,1,1,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,1,0,0,1,0),
+ array(0,1,0,0,1,0,0,1,0),
+ array(0,1,0,1,1,1,0,1,0),
+ array(0,1,0,1,0,1,0,1,0),
+ array(0,1,1,1,0,1,1,1,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ ),
+ 'X' => array(
+ array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(1,1,1,0,0,0,1,1,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,1,1,0,0,0,1,1,1),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(0,0,1,1,0,1,1,0,0),
+ array(0,0,0,1,1,1,0,0,0),
+ array(0,0,0,1,1,1,0,0,0),
+ array(0,0,1,1,0,1,1,0,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ ),
+ 'Y' => array(
+ array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(1,1,1,0,0,0,1,1,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,1,1,0,0,0),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,1,0,0,0,0,1),
+ array(0,0,0,1,1,0,0,0,1),
+ array(0,0,0,0,1,0,0,1,1),
+ array(0,0,0,0,1,1,0,1,0),
+ array(0,0,0,0,0,1,1,1,0),
+ array(0,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,1,1,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,1,1,0,0,0),
+ array(0,0,1,1,1,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ ),
+ 'Z' => array(
+ array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,0,0,0,0,0),
+ array(0,0,0,1,0,0,0,0,0),
+ array(0,0,1,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,1,1,1,1,1,1,1,1),
+ ),
+ array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,1,0,0,0,0,0),
+ array(0,0,0,1,0,0,0,0,0),
+ array(0,0,1,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,1,1,1,1,1,1,1),
+ ),
+ array(
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,1,1,1,1,1,1,1,0),
+ array(0,0,0,0,0,1,1,0,0),
+ array(0,0,0,0,1,1,0,0,0),
+ array(0,0,0,1,1,0,0,0,0),
+ array(0,0,1,1,0,0,0,0,0),
+ array(0,0,1,0,0,0,0,0,0),
+ array(0,1,1,1,1,1,1,1,0),
+ ),
+ ),
+ );
+ return array(
+ 'width' => 9,
+ 'height' => 15,
+ 'data' => array(
+
+ 'A' => $chars['A'][mt_rand(0, min(sizeof($chars['A']), $config['captcha_gd_fonts']) -1)],
+ 'B' => $chars['B'][mt_rand(0, min(sizeof($chars['B']), $config['captcha_gd_fonts']) -1)],
+ 'C' => $chars['C'][mt_rand(0, min(sizeof($chars['C']), $config['captcha_gd_fonts']) -1)],
+ 'D' => $chars['D'][mt_rand(0, min(sizeof($chars['D']), $config['captcha_gd_fonts']) -1)],
+ 'E' => $chars['E'][mt_rand(0, min(sizeof($chars['E']), $config['captcha_gd_fonts']) -1)],
+ 'F' => $chars['F'][mt_rand(0, min(sizeof($chars['F']), $config['captcha_gd_fonts']) -1)],
+ 'G' => $chars['G'][mt_rand(0, min(sizeof($chars['G']), $config['captcha_gd_fonts']) -1)],
+ 'H' => $chars['H'][mt_rand(0, min(sizeof($chars['H']), $config['captcha_gd_fonts']) -1)],
+ 'I' => $chars['I'][mt_rand(0, min(sizeof($chars['I']), $config['captcha_gd_fonts']) -1)],
+ 'J' => $chars['J'][mt_rand(0, min(sizeof($chars['J']), $config['captcha_gd_fonts']) -1)],
+ 'K' => $chars['K'][mt_rand(0, min(sizeof($chars['K']), $config['captcha_gd_fonts']) -1)],
+ 'L' => $chars['L'][mt_rand(0, min(sizeof($chars['L']), $config['captcha_gd_fonts']) -1)],
+ 'M' => $chars['M'][mt_rand(0, min(sizeof($chars['M']), $config['captcha_gd_fonts']) -1)],
+ 'N' => $chars['N'][mt_rand(0, min(sizeof($chars['N']), $config['captcha_gd_fonts']) -1)],
+ 'O' => $chars['O'][mt_rand(0, min(sizeof($chars['O']), $config['captcha_gd_fonts']) -1)],
+ 'P' => $chars['P'][mt_rand(0, min(sizeof($chars['P']), $config['captcha_gd_fonts']) -1)],
+ 'Q' => $chars['Q'][mt_rand(0, min(sizeof($chars['Q']), $config['captcha_gd_fonts']) -1)],
+ 'R' => $chars['R'][mt_rand(0, min(sizeof($chars['R']), $config['captcha_gd_fonts']) -1)],
+ 'S' => $chars['S'][mt_rand(0, min(sizeof($chars['S']), $config['captcha_gd_fonts']) -1)],
+ 'T' => $chars['T'][mt_rand(0, min(sizeof($chars['T']), $config['captcha_gd_fonts']) -1)],
+ 'U' => $chars['U'][mt_rand(0, min(sizeof($chars['U']), $config['captcha_gd_fonts']) -1)],
+ 'V' => $chars['V'][mt_rand(0, min(sizeof($chars['V']), $config['captcha_gd_fonts']) -1)],
+ 'W' => $chars['W'][mt_rand(0, min(sizeof($chars['W']), $config['captcha_gd_fonts']) -1)],
+ 'X' => $chars['X'][mt_rand(0, min(sizeof($chars['X']), $config['captcha_gd_fonts']) -1)],
+ 'Y' => $chars['Y'][mt_rand(0, min(sizeof($chars['Y']), $config['captcha_gd_fonts']) -1)],
+ 'Z' => $chars['Z'][mt_rand(0, min(sizeof($chars['Z']), $config['captcha_gd_fonts']) -1)],
+
+ '1' => array(
+ array(0,0,0,1,1,0,0,0,0),
+ array(0,0,1,0,1,0,0,0,0),
+ array(0,1,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,1,1,1,1,1,1,1,0),
+ ),
+ '2' => array( // New '2' supplied by Anon
+ array(0,0,0,1,1,1,0,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,1,1,0),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,0,0,0,0,0),
+ array(0,0,1,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ '3' => array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,1,1,0,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ '4' => array(
+ array(0,0,0,0,0,0,1,1,0),
+ array(0,0,0,0,0,1,0,1,0),
+ array(0,0,0,0,1,0,0,1,0),
+ array(0,0,0,1,0,0,0,1,0),
+ array(0,0,1,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,1,0),
+ ),
+ '5' => array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ '6' => array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,1,1,1,1,0,0),
+ array(1,0,1,0,0,0,0,1,0),
+ array(1,1,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ '7' => array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,0,0,0,0,0),
+ array(0,0,0,1,0,0,0,0,0),
+ array(0,0,1,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ ),
+ '8' => array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ '9' => array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,1,1),
+ array(0,1,0,0,0,0,1,0,1),
+ array(0,0,1,1,1,1,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ ),
+ )
+ );
+ }
+}
diff --git a/phpBB/phpbb/captcha/gd_wave.php b/phpBB/phpbb/captcha/gd_wave.php
new file mode 100644
index 0000000000..d48fc753a5
--- /dev/null
+++ b/phpBB/phpbb/captcha/gd_wave.php
@@ -0,0 +1,845 @@
+<?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\captcha;
+
+/**
+* Wave3D CAPTCHA
+*/
+class gd_wave
+{
+ var $width = 360;
+ var $height = 96;
+
+ function execute($code, $seed)
+ {
+ global $starttime;
+
+ // seed the random generator
+ mt_srand($seed);
+
+ // set height and width
+ $img_x = $this->width;
+ $img_y = $this->height;
+
+ // Generate image
+ $img = imagecreatetruecolor($img_x, $img_y);
+ $x_grid = mt_rand(6, 10);
+ $y_grid = mt_rand(6, 10);
+
+ // Ok, so lets cut to the chase. We could accurately represent this in 3d and
+ // do all the appropriate linear transforms. my questions is... why bother?
+ // The computational overhead is unnecessary when you consider the simple fact:
+ // we're not here to accurately represent a model, but to just show off some random-ish
+ // polygons
+
+ // Conceive of 3 spaces.
+ // 1) planar-space (discrete "pixel" grid)
+ // 2) 3-space. (planar-space with z/height aspect)
+ // 3) image space (pixels on the screen)
+ // resolution of the planar-space we're embedding the text code in
+ $plane_x = 100;
+ $plane_y = 30;
+
+ $subdivision_factor = 3;
+
+ // $box is the 4 points in img_space that correspond to the corners of the plane in 3-space
+ $box = array(
+ 'upper_left' => array(
+ 'x' => mt_rand(5, 15),
+ 'y' => mt_rand(10, 15)
+ ),
+ 'upper_right' => array(
+ 'x' => mt_rand($img_x - 35, $img_x - 19),
+ 'y' => mt_rand(10, 17)
+ ),
+ 'lower_left' => array(
+ 'x' => mt_rand($img_x - 45, $img_x - 5),
+ 'y' => mt_rand($img_y - 15, $img_y - 0),
+ ),
+ );
+
+ $box['lower_right'] = array(
+ 'x' => $box['lower_left']['x'] + $box['upper_left']['x'] - $box['upper_right']['x'],
+ 'y' => $box['lower_left']['y'] + $box['upper_left']['y'] - $box['upper_right']['y'],
+ );
+
+ // TODO
+ $background = imagecolorallocate($img, mt_rand(155, 255), mt_rand(155, 255), mt_rand(155, 255));
+ imagefill($img, 0, 0, $background);
+ $black = imagecolorallocate($img, 0, 0, 0);
+
+ $random = array();
+ $fontcolors = array();
+
+ for ($i = 0; $i < 15; ++$i)
+ {
+ $random[$i] = imagecolorallocate($img, mt_rand(120, 255), mt_rand(120, 255), mt_rand(120, 255));
+ }
+
+ $fontcolors[0] = imagecolorallocate($img, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120));
+
+ $colors = array();
+
+ $minr = mt_rand(20, 30);
+ $ming = mt_rand(20, 30);
+ $minb = mt_rand(20, 30);
+
+ $maxr = mt_rand(150, 230);
+ $maxg = mt_rand(150, 230);
+ $maxb = mt_rand(150, 230);
+
+ for ($i = -30; $i <= 30; ++$i)
+ {
+ $coeff1 = ($i + 12) / 45;
+ $coeff2 = 1 - $coeff1;
+ $colors[$i] = imagecolorallocate($img, ($coeff2 * $maxr) + ($coeff1 * $minr), ($coeff2 * $maxg) + ($coeff1 * $ming), ($coeff2 * $maxb) + ($coeff1 * $minb));
+ }
+
+ // $img_buffer is the last row of 3-space positions (converted to img-space), cached
+ // (using this means we don't need to recalculate all 4 positions for each new polygon,
+ // merely the newest point that we're adding, which is then cached.
+ $img_buffer = array(array(), array());
+
+ // In image-space, the x- and y-offset necessary to move one unit in the x-direction in planar-space
+ $dxx = ($box['upper_right']['x'] - $box['upper_left']['x']) / ($subdivision_factor * $plane_x);
+ $dxy = ($box['upper_right']['y'] - $box['upper_left']['y']) / ($subdivision_factor * $plane_x);
+
+ // In image-space, the x- and y-offset necessary to move one unit in the y-direction in planar-space
+ $dyx = ($box['lower_right']['x'] - $box['upper_left']['x']) / ($subdivision_factor * $plane_y);
+ $dyy = ($box['lower_right']['y'] - $box['upper_left']['y']) / ($subdivision_factor * $plane_y);
+
+ // Initial captcha-letter offset in planar-space
+ $plane_offset_x = mt_rand(3, 8);
+ $plane_offset_y = mt_rand( 12, 15);
+
+ // character map
+ $map = $this->captcha_bitmaps();
+
+ // matrix
+ $plane = array();
+
+ // for each character, we'll silkscreen it into our boolean pixel plane
+ for ($c = 0, $code_num = strlen($code); $c < $code_num; ++$c)
+ {
+ $letter = $code[$c];
+
+ for ($x = $map['width'] - 1; $x >= 0; --$x)
+ {
+ for ($y = $map['height'] - 1; $y >= 0; --$y)
+ {
+ if ($map['data'][$letter][$y][$x])
+ {
+ $plane[$y + $plane_offset_y + (($c & 1) ? 1 : -1)][$x + $plane_offset_x] = true;
+ }
+ }
+ }
+ $plane_offset_x += 11;
+ }
+
+ // calculate our first buffer, we can't actually draw polys with these yet
+ // img_pos_prev == screen x,y location to our immediate left.
+ // img_pos_cur == current screen x,y location
+ // we calculate screen position of our
+ // current cell based on the difference from the previous cell
+ // rather than recalculating from absolute coordinates
+ // What we cache into the $img_buffer contains the raised text coordinates.
+ $img_pos_prev = $img_buffer[0][0] = array($box['upper_left']['x'], $box['upper_left']['y']);
+ $cur_height = $prev_height = $this->wave_height(0, 0, $subdivision_factor);
+ $full_x = $plane_x * $subdivision_factor;
+ $full_y = $plane_y * $subdivision_factor;
+
+ for ($x = 1; $x <= $full_x; ++$x)
+ {
+ $cur_height = $this->wave_height($x, 0, $subdivision_factor);
+ $offset = $cur_height - $prev_height;
+ $img_pos_cur = array($img_pos_prev[0] + $dxx, $img_pos_prev[1] + $dxy + $offset);
+
+ $img_buffer[0][$x] = $img_pos_cur;
+ $img_pos_prev = $img_pos_cur;
+ $prev_height = $cur_height;
+ }
+
+ for ($y = 1; $y <= $full_y; ++$y)
+ {
+ // swap buffers
+ $buffer_cur = $y & 1;
+ $buffer_prev = 1 - $buffer_cur;
+
+ $prev_height = $this->wave_height(0, $y, $subdivision_factor);
+ $offset = $prev_height - $this->wave_height(0, $y - 1, $subdivision_factor);
+ $img_pos_cur = array($img_buffer[$buffer_prev][0][0] + $dyx, min($img_buffer[$buffer_prev][0][1] + $dyy + $offset, $img_y - 1));
+
+ // make sure we don't try to write off the page
+ $img_pos_prev = $img_pos_cur;
+
+ $img_buffer[$buffer_cur][0] = $img_pos_cur;
+
+ for ($x = 1; $x <= $full_x; ++$x)
+ {
+ $cur_height = $this->wave_height($x, $y, $subdivision_factor) + $this->grid_height($x, $y, $x_grid, $y_grid, 1);
+
+ // height is a z-factor, not a y-factor
+ $offset = $cur_height - $prev_height;
+ $img_pos_cur = array($img_pos_prev[0] + $dxx, $img_pos_prev[1] + $dxy + $offset);
+
+ // height is float, index it to an int, get closest color
+ $color = $colors[intval($cur_height)];
+ $img_pos_prev = $img_pos_cur;
+ $prev_height = $cur_height;
+
+ $y_index_old = intval(($y - 1) / $subdivision_factor);
+ $y_index_new = intval($y / $subdivision_factor);
+ $x_index_old = intval(($x - 1) / $subdivision_factor);
+ $x_index_new = intval($x / $subdivision_factor);
+
+ if (!empty($plane[$y_index_new][$x_index_new]))
+ {
+ $img_pos_cur[1] += $this->wave_height($x, $y, $subdivision_factor, 1) - 30 - $cur_height;
+ $color = $colors[20];
+ }
+ $img_pos_cur[1] = min($img_pos_cur[1], $img_y - 1);
+ $img_buffer[$buffer_cur][$x] = $img_pos_cur;
+
+ // Smooth the edges as much as possible by having not more than one low<->high traingle per square
+ // Otherwise, just
+ $diag_down = (empty($plane[$y_index_old][$x_index_old]) == empty($plane[$y_index_new][$x_index_new]));
+ $diag_up = (empty($plane[$y_index_old][$x_index_new]) == empty($plane[$y_index_new][$x_index_old]));
+
+ // natural switching
+ $mode = ($x + $y) & 1;
+
+ // override if it requires it
+ if ($diag_down != $diag_up)
+ {
+ $mode = $diag_up;
+ }
+
+ if ($mode)
+ {
+ // +-/ /
+ // 1 |/ 2 /|
+ // / /-+
+ $poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x]);
+ $poly2 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_cur][$x], $img_buffer[$buffer_prev][$x]);
+ }
+ else
+ {
+ // \ \-+
+ // 1 |\ 2 \|
+ // +-\ \
+ $poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_cur][$x]);
+ $poly2 = array_merge($img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x], $img_buffer[$buffer_cur][$x]);
+ }
+
+ imagefilledpolygon($img, $poly1, 3, $color);
+ imagefilledpolygon($img, $poly2, 3, $color);
+ }
+ }
+
+ // Output image
+ header('Content-Type: image/png');
+ header('Cache-control: no-cache, no-store');
+ //$mtime = explode(' ', microtime());
+ //$totaltime = $mtime[0] + $mtime[1] - $starttime;
+
+ //echo $totaltime . "<br />\n";
+ //echo memory_get_usage() - $tmp;
+ imagepng($img);
+ imagedestroy($img);
+ }
+
+ function wave_height($x, $y, $factor = 1, $tweak = 0.7)
+ {
+ // stretch the wave. TODO: pretty it up
+ $x = $x/5 + 180;
+ $y = $y/4;
+ return ((sin($x / (3 * $factor)) + sin($y / (3 * $factor))) * 10 * $tweak);
+ }
+
+ function grid_height($x, $y, $x_grid, $y_grid, $factor = 1)
+ {
+ return ((!($x % ($x_grid * $factor)) || !($y % ($y_grid * $factor))) ? 3 : 0);
+ }
+
+ function captcha_bitmaps()
+ {
+ return array(
+ 'width' => 9,
+ 'height' => 13,
+ 'data' => array(
+ 'A' => array(
+ array(0,0,1,1,1,1,0,0,0),
+ array(0,1,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'B' => array(
+ array(1,1,1,1,1,1,0,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,1,1,1,1,1,0,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,1,1,1,1,1,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'C' => array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'D' => array(
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'E' => array(
+ array(0,0,1,1,1,1,1,1,1),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,0,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'F' => array(
+ array(0,0,1,1,1,1,1,1,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,1,1,1,1,1,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'G' => array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'H' => array(
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'I' => array(
+ array(0,1,1,1,1,1,1,1,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,1,1,1,1,1,1,1,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'J' => array(
+ array(0,0,0,0,0,0,1,1,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,0,1,0,0,0,0,1,0),
+ array(0,0,0,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'K' => array(
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,1,0,0,0,0),
+ array(1,0,0,1,0,0,0,0,0),
+ array(1,0,1,0,0,0,0,0,0),
+ array(1,1,0,0,0,0,0,0,0),
+ array(1,0,1,0,0,0,0,0,0),
+ array(1,0,0,1,0,0,0,0,0),
+ array(1,0,0,0,1,0,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'L' => array(
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,0,1,1,1,1,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'M' => array(
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,1,0,0,0,1,1,0),
+ array(0,1,0,1,0,1,0,1,0),
+ array(0,1,0,0,1,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'N' => array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,1,0,0,0,0,0,0,1),
+ array(1,0,1,0,0,0,0,0,1),
+ array(1,0,0,1,0,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,0,0,1,0,0,1),
+ array(1,0,0,0,0,0,1,0,1),
+ array(1,0,0,0,0,0,0,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'O' => array(
+ array(0,0,0,1,1,1,0,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,1,1,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'P' => array(
+ array(1,1,1,1,1,1,0,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,1,1,1,1,1,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'Q' => array(
+ array(0,0,1,1,1,1,0,0,0),
+ array(0,1,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,1,0,0,1,0),
+ array(1,0,0,0,0,1,0,1,0),
+ array(0,1,0,0,0,0,1,0,0),
+ array(0,0,1,1,1,1,0,1,0),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'R' => array(
+ array(1,1,1,1,1,1,0,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(1,1,1,1,1,1,0,0,0),
+ array(1,0,1,0,0,0,0,0,0),
+ array(1,0,0,1,0,0,0,0,0),
+ array(1,0,0,0,1,0,0,0,0),
+ array(1,0,0,0,0,1,0,0,0),
+ array(1,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'S' => array(
+ array(0,0,1,1,1,1,1,1,1),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(1,1,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'T' => array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'U' => array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'V' => array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'W' => array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,1,0,0,0,1),
+ array(1,0,0,1,0,1,0,0,1),
+ array(1,0,1,0,0,0,1,0,1),
+ array(1,1,0,0,0,0,0,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'X' => array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'Y' => array(
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,0,0,1,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ 'Z' => array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,0,0,0,0,0),
+ array(0,0,1,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ '1' => array(
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,1,0,0,0,0),
+ array(0,0,1,0,1,0,0,0,0),
+ array(0,1,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,1,1,1,1,1,1,1,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ '2' => array(
+ array(0,0,0,1,1,1,0,0,0),
+ array(0,0,1,0,0,0,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,1,0,0,0,0,0),
+ array(0,0,1,0,0,0,0,0,0),
+ array(0,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ '3' => array(
+ array(0,0,0,1,1,1,1,0,0),
+ array(0,0,1,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,1,1,0,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,0,1,0,0,0,0,1,0),
+ array(0,0,0,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ '4' => array(
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,1,1,0),
+ array(0,0,0,0,0,1,0,1,0),
+ array(0,0,0,0,1,0,0,1,0),
+ array(0,0,0,1,0,0,0,1,0),
+ array(0,0,1,0,0,0,0,1,0),
+ array(0,1,1,1,1,1,1,1,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ '5' => array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(0,1,0,0,0,0,0,0,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ '6' => array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,0,0,0,0,0,0),
+ array(1,0,0,1,1,1,1,0,0),
+ array(1,0,1,0,0,0,0,1,0),
+ array(1,1,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ '7' => array(
+ array(1,1,1,1,1,1,1,1,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,1,0),
+ array(0,0,0,0,0,0,1,0,0),
+ array(0,0,0,0,0,1,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,1,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ '8' => array(
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,1,0,0,0,0,0,1,0),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(1,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,0),
+ array(0,0,1,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ '9' => array(
+ array(0,0,0,1,1,1,1,0,0),
+ array(0,0,1,0,0,0,0,1,0),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,1,1),
+ array(0,0,1,1,1,1,1,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,0,0,0,0,0,0,0,1),
+ array(0,1,0,0,0,0,0,0,1),
+ array(0,0,1,0,0,0,0,1,0),
+ array(0,0,0,1,1,1,1,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ array(0,0,0,0,0,0,0,0,0),
+ ),
+ )
+ );
+ }
+}
diff --git a/phpBB/phpbb/captcha/non_gd.php b/phpBB/phpbb/captcha/non_gd.php
new file mode 100644
index 0000000000..3818672f17
--- /dev/null
+++ b/phpBB/phpbb/captcha/non_gd.php
@@ -0,0 +1,386 @@
+<?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\captcha;
+
+/**
+* Main non-gd captcha class
+* @ignore
+*/
+class non_gd
+{
+ var $filtered_pngs;
+ var $width = 320;
+ var $height = 50;
+
+ /**
+ * Define filtered pngs on init
+ */
+ function __construct()
+ {
+ // If we can we will generate a single filtered png, we avoid nastiness via emulation of some Zlib stuff
+ $this->define_filtered_pngs();
+ }
+
+ /**
+ * Create the image containing $code with a seed of $seed
+ */
+ function execute($code, $seed)
+ {
+ $img_height = $this->height - 10;
+ $img_width = 0;
+
+ mt_srand($seed);
+
+ $char_widths = $hold_chars = array();
+ $code_len = strlen($code);
+
+ for ($i = 0; $i < $code_len; $i++)
+ {
+ $char = $code[$i];
+
+ $width = mt_rand(0, 4);
+ $raw_width = $this->filtered_pngs[$char]['width'];
+ $char_widths[$i] = $width;
+ $img_width += $raw_width - $width;
+
+ // Split the char into chunks of $raw_width + 1 length
+ if (empty($hold_chars[$char]))
+ {
+ $hold_chars[$char] = str_split(base64_decode($this->filtered_pngs[$char]['data']), $raw_width + 1);
+ }
+ }
+
+ $offset_x = mt_rand(0, $this->width - $img_width);
+ $offset_y = mt_rand(0, $this->height - $img_height);
+
+ $image = '';
+ for ($i = 0; $i < $this->height; $i++)
+ {
+ $image .= chr(0);
+
+ if ($i > $offset_y && $i < $offset_y + $img_height)
+ {
+ for ($j = 0; $j < $offset_x; $j++)
+ {
+ $image .= chr(mt_rand(140, 255));
+ }
+
+ for ($j = 0; $j < $code_len; $j++)
+ {
+ $image .= $this->randomise(substr($hold_chars[$code{$j}][$i - $offset_y - 1], 1), $char_widths[$j]);
+ }
+
+ for ($j = $offset_x + $img_width; $j < $this->width; $j++)
+ {
+ $image .= chr(mt_rand(140, 255));
+ }
+ }
+ else
+ {
+ for ($j = 0; $j < $this->width; $j++)
+ {
+ $image .= chr(mt_rand(140, 255));
+ }
+ }
+ }
+ unset($hold_chars);
+
+ $image = $this->create_png($image, $this->width, $this->height);
+
+ // Output image
+ header('Content-Type: image/png');
+ header('Cache-control: no-cache, no-store');
+ echo $image;
+ exit;
+ }
+
+ /**
+ * This is designed to randomise the pixels of the image data within
+ * certain limits so as to keep it readable. It also varies the image
+ * width a little
+ */
+ function randomise($scanline, $width)
+ {
+ $new_line = '';
+
+ $end = strlen($scanline) - ceil($width/2);
+ for ($i = (int) floor($width / 2); $i < $end; $i++)
+ {
+ $pixel = ord($scanline{$i});
+
+ if ($pixel < 190)
+ {
+ $new_line .= chr(mt_rand(0, 205));
+ }
+ else if ($pixel > 190)
+ {
+ $new_line .= chr(mt_rand(145, 255));
+ }
+ else
+ {
+ $new_line .= $scanline{$i};
+ }
+ }
+
+ return $new_line;
+ }
+
+ /**
+ * This creates a chunk of the given type, with the given data
+ * of the given length adding the relevant crc
+ */
+ function png_chunk($length, $type, $data)
+ {
+ $raw = $type . $data;
+
+ return pack('N', $length) . $raw . pack('N', crc32($raw));
+ }
+
+ /**
+ * Creates greyscale 8bit png - The PNG spec can be found at
+ * http://www.libpng.org/pub/png/spec/PNG-Contents.html we use
+ * png because it's a fully recognised open standard and supported
+ * by practically all modern browsers and OSs
+ */
+ function create_png($raw_image, $width, $height)
+ {
+ // SIG
+ $image = pack('C8', 137, 80, 78, 71, 13, 10, 26, 10);
+
+ // IHDR
+ $raw = pack('N2', $width, $height);
+ $raw .= pack('C5', 8, 0, 0, 0, 0);
+ $image .= $this->png_chunk(13, 'IHDR', $raw);
+
+ // IDAT
+ if (@extension_loaded('zlib'))
+ {
+ $raw_image = gzcompress($raw_image);
+ $length = strlen($raw_image);
+ }
+ else
+ {
+ // The total length of this image, uncompressed, is just a calculation of pixels
+ $length = ($width + 1) * $height;
+
+ // Adler-32 hash generation
+ // Note: The hash is _backwards_ so we must reverse it
+
+ if (@extension_loaded('hash'))
+ {
+ $adler_hash = strrev(hash('adler32', $raw_image, true));
+ }
+ else if (@extension_loaded('mhash'))
+ {
+ $adler_hash = strrev(mhash(MHASH_ADLER32, $raw_image));
+ }
+ else
+ {
+ // Optimized Adler-32 loop ported from the GNU Classpath project
+ $temp_length = $length;
+ $s1 = 1;
+ $s2 = $index = 0;
+
+ while ($temp_length > 0)
+ {
+ // We can defer the modulo operation:
+ // s1 maximally grows from 65521 to 65521 + 255 * 3800
+ // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
+ $substract_value = ($temp_length < 3800) ? $temp_length : 3800;
+ $temp_length -= $substract_value;
+
+ while (--$substract_value >= 0)
+ {
+ $s1 += ord($raw_image[$index]);
+ $s2 += $s1;
+
+ $index++;
+ }
+
+ $s1 %= 65521;
+ $s2 %= 65521;
+ }
+ $adler_hash = pack('N', ($s2 << 16) | $s1);
+ }
+
+ // This is the same thing as gzcompress($raw_image, 0) but does not need zlib
+ $raw_image = pack('C3v2', 0x78, 0x01, 0x01, $length, ~$length) . $raw_image . $adler_hash;
+
+ // The Zlib header + Adler hash make us add on 11
+ $length += 11;
+ }
+
+ // IDAT
+ $image .= $this->png_chunk($length, 'IDAT', $raw_image);
+
+ // IEND
+ $image .= $this->png_chunk(0, 'IEND', '');
+
+ return $image;
+ }
+
+ /**
+ * png image data
+ * Each 'data' element is base64_encoded uncompressed IDAT
+ */
+ function define_filtered_pngs()
+ {
+ $this->filtered_pngs = array(
+ '0' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////olFAkBAAAGDyA4P///M31/////////////wD////////////////0dAgAAAAAAAAAAAAEcPipFGHn////////////AP//////////////6DAAAAAAAAAAAAAAAAAALSEAN+T///////////8A//////////////xAAAAAAAAAAAAAAAAAAAAAACPA/////////////wD/////////////oAAAAAAAAAAAAAAAAAAAAAAAev//////////////AP////////////8oAAAAAAAAPNj/zDAAAAAAAABD//////////////8A////////////1AAAAAAAABjw////5BAAAAAAAADo/////////////wD///////////+QAAAAAAAAbP//////QgAAAAAAAKj/////////////AP///////////1wAAAAAAACs/////8AXAAAAAAAAcP////////////8A////////////OAAAAAAAAND////dNwAAAAAAAABI/////////////wD///////////8gAAAAAAAA4P//7koACwAAAAAAACT/////////////AP///////////wgAAAAAAAD///VqAwaPAAAAAAAAEP////////////8A////////////AAAAAAAAAP/8kQYDavUAAAAAAAAA/////////////wD///////////8AAAAAAAAA/6kNAEru/wAAAAAAAAD/////////////AP///////////wAAAAAAAADAIwA33f//AAAAAAAAAP////////////8A////////////FAAAAAAAADYAI8D///8AAAAAAAAQ/////////////wD///////////8kAAAAAAAAAA2p////5AAAAAAAACD/////////////AP///////////0gAAAAAAAAFkfz////UAAAAAAAAQP////////////8A////////////cAAAAAAAAET1/////7AAAAAAAABo/////////////wD///////////+oAAAAAAAAXfX/////sAAAAAAAAGj/////////////AAAAALgAAAAAAAAwAAAAAAAAAAAAAAD////////////oAAAAAAAACOT////oEAAAAAAAAOD/////////////AP////////////8+AAAAAAAAKMz/zDQAAAAAAAA0//////////////8A////////////7jgAAAAAAAAAAAAAAAAAAAAAAKT//////////////wD///////////VqAwIAAAAAAAAAAAAAAAAAAAA8////////////////AP//////////rQcDaVEAAAAAAAAAAAAAAAAAKOj///////////////8A///////////nblnu/IAIAAAAAAAAAAAAAFzw/////////////////wD////////////79////+iITCAAAAAgSITg////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////w==',
+ 'width' => 40
+ ),
+ '1' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////8BAAAAAAAP//////////////////AP////////////////////////9sAAAAAAAA//////////////////8A////////////////////////pAAAAAAAAAD//////////////////wD//////////////////////6wEAAAAAAAAAP//////////////////AP////////////////////h4AAAAAAAAAAAA//////////////////8A//////////////////ygJAAAAAAAAAAAAAD//////////////////wD//////////////9x8HAAAAAAAAAAAAAAAAP//////////////////AP//////////////AAAAAAAAAAAAAAAAAAAA//////////////////8A//////////////8AAAAAAAAAAAAAAAAAAAD//////////////////wD//////////////wAAAAAAAAR4AAAAAAAAAP//////////////////AP//////////////AAAAAAA4zP8AAAAAAAAA//////////////////8A//////////////8AAAA4sP///wAAAAAAAAD//////////////////wD//////////////yR80P//////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ '2' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////okFAkCAAABCBIfNT///////////////////8A///////////////8hAgAAAAAAAAAAAAAAFTo/////////////////wD//////////////1QAAAAAAAAAAAAAAAAAACjo////////////////AP////////////+MAAAAAAAAAAAAAAAAAAAAADj///////////////8A////////////9BAAAAAAAAAAAAAAAAAAAAAAALD//////////////wD///////////+gAAAAAAAAAHjs+KwMAAAAAAAAVP//////////////AP///////////1gAAAAAAABM/////6QAAAAAAAAU//////////////8A////////////KAAAAAAAALj/////+AAAAAAAAAD//////////////wD///////////+MfGBMOCAI8P/////wAAAAAAAACP//////////////AP///////////////////////////5wAAAAAAAAw//////////////8A///////////////////////////oFAAAAAAAAHz//////////////wD/////////////////////////6CgAAAAAAAAE3P//////////////AP///////////////////////9ggAAAAAAAAAHT///////////////8A//////////////////////+0DAAAAAAAAAA8+P///////////////wD/////////////////////gAAAAAAAAAAAKOj/////////////////AP//////////////////9FAAAAAAAAAAADzw//////////////////8A/////////////////+g4AAAAAAAAAABk/P///////////////////wD////////////////oKAAAAAAAAAAMqP//////////////////////AP//////////////6CgAAAAAAAAAMNz///////////////////////8A//////////////g4AAAAAAAAAFT0/////////////////////////wD/////////////bAAAAAAAAABU/P//////////////////////////AP///////////8wAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A////////////SAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////9AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////xAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ '3' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////8sGg0FAAAACA4cLz8////////////////////AP//////////////rBgAAAAAAAAAAAAAACTA//////////////////8A/////////////3QAAAAAAAAAAAAAAAAAAASs/////////////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAjc////////////////AP//////////6AwAAAAAAAAAAAAAAAAAAAAAAGT///////////////8A//////////94AAAAAAAABJDw/8g4AAAAAAAAHP///////////////wD//////////yAAAAAAAACE/////9gAAAAAAAAA////////////////AP///////////NSwiGQ4FOT//////AAAAAAAABD///////////////8A//////////////////////////+YAAAAAAAAVP///////////////wD//////////////////////P/ggAQAAAAAAATM////////////////AP////////////////////9gAAAAAAAAAAAElP////////////////8A/////////////////////0AAAAAAAAAAHLj//////////////////wD/////////////////////OAAAAAAAAAAwkPj/////////////////AP////////////////////8gAAAAAAAAAAAAINj///////////////8A/////////////////////xAAAAAAAAAAAAAAIPD//////////////wD/////////////////////uOz/4HgEAAAAAAAAhP//////////////AP///////////////////////////3wAAAAAAAAw//////////////8A////////////////////////////6AAAAAAAAAj//////////////wD/////////////////////////////AAAAAAAAAP//////////////AP//////////tJh8YEQoDNz//////+AAAAAAAAAY//////////////8A//////////88AAAAAAAAaP//////dAAAAAAAAEz//////////////wD//////////6QAAAAAAAAAdOD/5HQAAAAAAAAApP//////////////AP///////////CgAAAAAAAAAAAAAAAAAAAAAACD4//////////////8A////////////yAQAAAAAAAAAAAAAAAAAAAAEuP///////////////wD/////////////rAQAAAAAAAAAAAAAAAAABJD/////////////////AP//////////////zDQAAAAAAAAAAAAAACTA//////////////////8A/////////////////8BwOCAAAAAUNGi0/P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ '4' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////////////nAAAAAAAAAD///////////////8A/////////////////////////8AEAAAAAAAAAP///////////////wD////////////////////////gGAAAAAAAAAAA////////////////AP//////////////////////9DAAAAAAAAAAAAD///////////////8A//////////////////////9UAAAAAAAAAAAAAP///////////////wD/////////////////////hAAAAAAAAAAAAAAA////////////////AP///////////////////7QAAAAAAAAAAAAAAAD///////////////8A///////////////////UDAAAAAAUAAAAAAAAAP///////////////wD/////////////////7CQAAAAABMAAAAAAAAAA////////////////AP////////////////xEAAAAAACU/wAAAAAAAAD///////////////8A////////////////cAAAAAAAZP//AAAAAAAAAP///////////////wD//////////////6AAAAAAADz8//8AAAAAAAAA////////////////AP/////////////IBAAAAAAc6P///wAAAAAAAAD///////////////8A////////////5BgAAAAADMz/////AAAAAAAAAP///////////////wD///////////g0AAAAAACk//////8AAAAAAAAA////////////////AP//////////XAAAAAAAfP///////wAAAAAAAAD///////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP///////////////////////////wAAAAAAAAD///////////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ '5' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////8AAAAAAAAAAAAAAAAAAAAAAA//////////////8A///////////////MAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////6wAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////iAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////////9kAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////0QAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////IAAAAAAAYP////////////////////////////8A//////////////wAAAAAAAB8/////////////////////////////wD/////////////3AAAAAAAAIj/////////////////////////////AP////////////+4AAAAAAAAoLRYHAAEKGTE//////////////////8A/////////////5QAAAAAAAAQAAAAAAAAAABY9P///////////////wD/////////////dAAAAAAAAAAAAAAAAAAAAAA89P//////////////AP////////////9QAAAAAAAAAAAAAAAAAAAAAABg//////////////8A/////////////zAAAAAAAAAAAAAAAAAAAAAAAADQ/////////////wD/////////////IAAAAAAAAGjY/+h4BAAAAAAAAGz/////////////AP//////////////9NS0lHSc//////90AAAAAAAALP////////////8A/////////////////////////////9QAAAAAAAAE/////////////wD//////////////////////////////wAAAAAAAAD/////////////AP/////////////////////////////8AAAAAAAAEP////////////8A////////////pIRwWEAgDOD//////8wAAAAAAAA8/////////////wD///////////9EAAAAAAAAaP//////ZAAAAAAAAHz/////////////AP///////////6QAAAAAAAAAaOD/4GQAAAAAAAAE4P////////////8A/////////////CQAAAAAAAAAAAAAAAAAAAAAAGD//////////////wD/////////////yAQAAAAAAAAAAAAAAAAAAAAc7P//////////////AP//////////////rAwAAAAAAAAAAAAAAAAAGNj///////////////8A////////////////0EAAAAAAAAAAAAAAAFTo/////////////////wD//////////////////8h4QCAAAAAcQHzU////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ '6' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////+0ZCwMAAAUNGjI////////////////////AP/////////////////EMAAAAAAAAAAAAABM6P////////////////8A////////////////lAQAAAAAAAAAAAAAAAAo6P///////////////wD//////////////6wAAAAAAAAAAAAAAAAAAABI////////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAACw//////////////8A/////////////3AAAAAAAAAoxP/YPAAAAAAAAEj//////////////wD////////////4EAAAAAAACOD////YDCBAVGiAoP//////////////AP///////////7gAAAAAAABY//////////////////////////////8A////////////eAAAAAAAAJT//////////////////////////////wD///////////9MAAAAAAAAvP/IXBgABCx03P//////////////////AP///////////ygAAAAAAADcdAAAAAAAAAAEiP////////////////8A////////////FAAAAAAAAFAAAAAAAAAAAAAAcP///////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAlP//////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAQ8P////////////8A////////////AAAAAAAAAABAyP/kZAAAAAAAAACQ/////////////wD///////////8MAAAAAAAALPj/////WAAAAAAAAET/////////////AP///////////yQAAAAAAACY///////MAAAAAAAAFP////////////8A////////////SAAAAAAAAMD///////wAAAAAAAAA/////////////wD///////////9wAAAAAAAAvP///////wAAAAAAAAD/////////////AP///////////7QAAAAAAACI///////UAAAAAAAAJP////////////8A////////////+AwAAAAAACDw/////2wAAAAAAABY/////////////wD/////////////cAAAAAAAADC8/Ox4AAAAAAAAAKj/////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAAAk/P////////////8A//////////////+oAAAAAAAAAAAAAAAAAAAABLj//////////////wD///////////////+QAAAAAAAAAAAAAAAAAACQ////////////////AP////////////////+0JAAAAAAAAAAAAAAkuP////////////////8A///////////////////8sGg0FAAADCxgqPz//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ '7' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAABP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAy4/////////////wD//////////////////////////+QUAAAAAAAEuP//////////////AP/////////////////////////8QAAAAAAAAKT///////////////8A/////////////////////////4wAAAAAAAB0/////////////////wD////////////////////////cCAAAAAAANPz/////////////////AP///////////////////////0QAAAAAAATY//////////////////8A//////////////////////+0AAAAAAAAeP///////////////////wD//////////////////////CQAAAAAABTw////////////////////AP////////////////////+gAAAAAAAAkP////////////////////8A/////////////////////ywAAAAAABDw/////////////////////wD///////////////////+4AAAAAAAAbP//////////////////////AP///////////////////1wAAAAAAADQ//////////////////////8A///////////////////4DAAAAAAAMP///////////////////////wD//////////////////7QAAAAAAAB8////////////////////////AP//////////////////aAAAAAAAAMj///////////////////////8A//////////////////8oAAAAAAAM/P///////////////////////wD/////////////////8AAAAAAAAET/////////////////////////AP////////////////+0AAAAAAAAcP////////////////////////8A/////////////////4wAAAAAAACY/////////////////////////wD/////////////////WAAAAAAAAMD/////////////////////////AP////////////////80AAAAAAAA4P////////////////////////8A/////////////////xAAAAAAAAD4/////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ '8' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////////IdDQUAAAEIEiA1P//////////////////AP/////////////////gRAAAAAAAAAAAAAAAROD///////////////8A////////////////0BgAAAAAAAAAAAAAAAAAEMj//////////////wD///////////////AcAAAAAAAAAAAAAAAAAAAAHPD/////////////AP//////////////hAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A//////////////8sAAAAAAAAKMz/zCgAAAAAAAAs/////////////wD//////////////wAAAAAAAADM////zAAAAAAAAAD/////////////AP//////////////BAAAAAAAAP//////AAAAAAAABP////////////8A//////////////8sAAAAAAAAzP///9QAAAAAAAAw/////////////wD//////////////3wAAAAAAAAoyP/YNAAAAAAAAIT/////////////AP//////////////7BgAAAAAAAAAAAAAAAAAAAAc8P////////////8A////////////////xBgAAAAAAAAAAAAAAAAAGNj//////////////wD/////////////////tAQAAAAAAAAAAAAAAACo////////////////AP///////////////HAAAAAAAAAAAAAAAAAAAAB8//////////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB8/////////////wD/////////////wAAAAAAAAABk4P/UWAAAAAAAAATQ////////////AP////////////9UAAAAAAAAaP//////XAAAAAAAAGT///////////8A/////////////xgAAAAAAADg///////cAAAAAAAAJP///////////wD/////////////AAAAAAAAAP////////8AAAAAAAAA////////////AP////////////8AAAAAAAAA4P//////3AAAAAAAAAT///////////8A/////////////ygAAAAAAABg//////9cAAAAAAAALP///////////wD/////////////ZAAAAAAAAABY1P/cXAAAAAAAAABw////////////AP/////////////QAAAAAAAAAAAAAAAAAAAAAAAABNz///////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB0/////////////wD///////////////Q8AAAAAAAAAAAAAAAAAAAAUPz/////////////AP////////////////x4CAAAAAAAAAAAAAAAEIT8//////////////8A///////////////////smFQwGAAAABg0ZKT0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ '9' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////ysYCwMAAAUNGiw/P//////////////////AP////////////////+4JAAAAAAAAAAAAAAkuP////////////////8A////////////////lAQAAAAAAAAAAAAAAAAAkP///////////////wD//////////////8AEAAAAAAAAAAAAAAAAAAAAqP//////////////AP/////////////8JAAAAAAAAAAAAAAAAAAAAAAQ7P////////////8A/////////////6wAAAAAAAAAfOz8vCwAAAAAAABw/////////////wD/////////////WAAAAAAAAHD/////7BgAAAAAAAz4////////////AP////////////8kAAAAAAAA1P//////hAAAAAAAALT///////////8A/////////////wAAAAAAAAD///////+4AAAAAAAAcP///////////wD/////////////AAAAAAAAAPz//////8AAAAAAAABI////////////AP////////////8UAAAAAAAAzP//////lAAAAAAAACT///////////8A/////////////0QAAAAAAABY//////gsAAAAAAAADP///////////wD/////////////kAAAAAAAAABw5P/IPAAAAAAAAAAA////////////AP/////////////wEAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////////+UAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////9wAAAAAAAAAAAAAFAAAAAAAAAU////////////AP////////////////+IBAAAAAAAAABw3AAAAAAAACj///////////8A///////////////////cdCwEABhcxP+8AAAAAAAATP///////////wD//////////////////////////////5AAAAAAAAB4////////////AP//////////////////////////////UAAAAAAAALj///////////8A//////////////+kgGxUQCAM2P///+AIAAAAAAAQ+P///////////wD//////////////0gAAAAAAAA42P/EKAAAAAAAAHD/////////////AP//////////////sAAAAAAAAAAAAAAAAAAAAAAQ6P////////////8A////////////////TAAAAAAAAAAAAAAAAAAAAKz//////////////wD////////////////oKAAAAAAAAAAAAAAAAASU////////////////AP/////////////////sUAAAAAAAAAAAAAAwxP////////////////8A////////////////////yHA0FAAADCxktP///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'A' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////+QAAAAAAAAAAAAAAOT/////////////////AP//////////////////kAAAAAAAAAAAAAAAkP////////////////8A//////////////////88AAAAAAAAAAAAAAA8/////////////////wD/////////////////5AAAAAAAAAAAAAAAAADk////////////////AP////////////////+QAAAAAAAAAAAAAAAAAJD///////////////8A/////////////////zwAAAAAAAAAAAAAAAAAPP///////////////wD////////////////kAAAAAAAAAAgAAAAAAAAA5P//////////////AP///////////////5AAAAAAAAAAgAAAAAAAAACQ//////////////8A////////////////PAAAAAAAAAz8HAAAAAAAADz//////////////wD//////////////+QAAAAAAAAAWP9kAAAAAAAAANz/////////////AP//////////////kAAAAAAAAACk/7wAAAAAAAAAhP////////////8A//////////////88AAAAAAAABOz//BQAAAAAAAAw/////////////wD/////////////4AAAAAAAAAA8////ZAAAAAAAAADc////////////AP////////////+EAAAAAAAAAIj///+8AAAAAAAAAIT///////////8A/////////////zAAAAAAAAAA2P////wQAAAAAAAAMP///////////wD////////////cAAAAAAAAACT//////1wAAAAAAAAA3P//////////AP///////////4QAAAAAAAAAAAAAAAAAAAAAAAAAAACE//////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAAAAAADD//////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANz/////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhP////////8A//////////8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/////////wD/////////3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc////////AP////////+EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIT///////8A/////////zAAAAAAAAAAhP///////////2QAAAAAAAAAMP///////wD////////cAAAAAAAAAADM////////////vAAAAAAAAAAA3P//////AP///////4QAAAAAAAAAHP/////////////4DAAAAAAAAACE//////8A////////MAAAAAAAAABk//////////////9cAAAAAAAAADD//////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'B' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAEDh83P///////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAEhP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAeP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAABY////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAABT///////////8A//////////8AAAAAAAAAAP/////4zEwAAAAAAAAAAP///////////wD//////////wAAAAAAAAAA////////7AAAAAAAAAAQ////////////AP//////////AAAAAAAAAAD////////sAAAAAAAAAEj///////////8A//////////8AAAAAAAAAAP/////4zEQAAAAAAAAAtP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAFz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAiA/P////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAIjPj//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAGKz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJT///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAABNz//////////wD//////////wAAAAAAAAAA///////sqCAAAAAAAAAAbP//////////AP//////////AAAAAAAAAAD/////////yAAAAAAAAAAs//////////8A//////////8AAAAAAAAAAP//////////AAAAAAAAAAT//////////wD//////////wAAAAAAAAAA/////////7wAAAAAAAAAAP//////////AP//////////AAAAAAAAAAD//////+ikGAAAAAAAAAAY//////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFT//////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsP//////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAADj///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAc6P///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAATOj/////////////AP//////////AAAAAAAAAAAAAAAAAAAEIEBkkNj///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'C' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////5JRULBAAAAgkTIDQ//////////////////8A////////////////1FAAAAAAAAAAAAAAAABAyP///////////////wD//////////////4gEAAAAAAAAAAAAAAAAAAAElP//////////////AP////////////9wAAAAAAAAAAAAAAAAAAAAAAAAlP////////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAEyP///////////wD//////////9wIAAAAAAAAAAAAAAAAAAAAAAAAAAAw////////////AP//////////WAAAAAAAAAAAWMz/8JwQAAAAAAAAAACw//////////8A/////////+wEAAAAAAAAAID//////9QMAAAAAAAAAET//////////wD/////////nAAAAAAAAAAo/P///////3wAAAAABDBspP//////////AP////////9gAAAAAAAAAIz/////////3BxQjMT0//////////////8A/////////zQAAAAAAAAAzP///////////////////////////////wD/////////GAAAAAAAAADo////////////////////////////////AP////////8AAAAAAAAAAP////////////////////////////////8A/////////wAAAAAAAAAA/////////////////////////////////wD/////////AAAAAAAAAAD/////////////////////////////////AP////////8cAAAAAAAAAOj///////////////////////////////8A/////////zgAAAAAAAAA0P/////////kIGio7P///////////////wD/////////bAAAAAAAAACg/////////5wAAAAAMHS49P//////////AP////////+oAAAAAAAAAEz/////////PAAAAAAAAAAc//////////8A//////////QIAAAAAAAAALz//////6QAAAAAAAAAAGT//////////wD//////////3AAAAAAAAAADIzo/+SEBAAAAAAAAAAAyP//////////AP//////////7BAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////rAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD/////////////fAAAAAAAAAAAAAAAAAAAAAAAAJz/////////////AP//////////////iAQAAAAAAAAAAAAAAAAAAASY//////////////8A////////////////yEAAAAAAAAAAAAAAAAA8yP///////////////wD//////////////////9yIUCwQAAAAIEB4yP//////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'D' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAADChQkOT/////////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAABGjw//////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAACDY/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAABjk////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKj//////////wD///////////8AAAAAAAAAAP///+isSAAAAAAAAAAANP//////////AP///////////wAAAAAAAAAA////////hAAAAAAAAAAA2P////////8A////////////AAAAAAAAAAD/////////MAAAAAAAAACQ/////////wD///////////8AAAAAAAAAAP////////+MAAAAAAAAAFj/////////AP///////////wAAAAAAAAAA/////////8gAAAAAAAAAMP////////8A////////////AAAAAAAAAAD/////////5AAAAAAAAAAY/////////wD///////////8AAAAAAAAAAP//////////AAAAAAAAAAD/////////AP///////////wAAAAAAAAAA//////////8AAAAAAAAAAP////////8A////////////AAAAAAAAAAD//////////wAAAAAAAAAA/////////wD///////////8AAAAAAAAAAP/////////wAAAAAAAAABD/////////AP///////////wAAAAAAAAAA/////////9QAAAAAAAAAJP////////8A////////////AAAAAAAAAAD/////////qAAAAAAAAABI/////////wD///////////8AAAAAAAAAAP////////9QAAAAAAAAAHj/////////AP///////////wAAAAAAAAAA////////uAAAAAAAAAAAvP////////8A////////////AAAAAAAAAAD////w0HwEAAAAAAAAACT8/////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAADz8//////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAY6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAKNz/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAACHT0//////////////8A////////////AAAAAAAAAAAAAAAAABg4bKj0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'E' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'F' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'G' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////MB8TCgQAAAACCA4YJzs////////////////AP///////////////JQcAAAAAAAAAAAAAAAAAAhw8P////////////8A/////////////9gwAAAAAAAAAAAAAAAAAAAAAAAk2P///////////wD////////////EDAAAAAAAAAAAAAAAAAAAAAAAAAAc7P//////////AP//////////2AwAAAAAAAAAAAAAAAAAAAAAAAAAAABY//////////8A//////////wwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ/////////wD/////////kAAAAAAAAAAAEHzQ/P/gmCAAAAAAAAAAAFz/////////AP////////wcAAAAAAAAACjg////////8CwAAAAAAAAgWP////////8A////////vAAAAAAAAAAI2P//////////yBRAcJjI8P///////////wD///////94AAAAAAAAAGD/////////////////////////////////AP///////0AAAAAAAAAAsP////////////////////////////////8A////////IAAAAAAAAADc/////////////////////////////////wD///////8AAAAAAAAAAP///////wAAAAAAAAAAAAAAAAD/////////AP///////wAAAAAAAAAA////////AAAAAAAAAAAAAAAAAP////////8A////////AAAAAAAAAAD///////8AAAAAAAAAAAAAAAAA/////////wD///////8gAAAAAAAAAOD//////wAAAAAAAAAAAAAAAAD/////////AP///////0AAAAAAAAAAtP//////AAAAAAAAAAAAAAAAAP////////8A////////cAAAAAAAAABw//////8AAAAAAAAAAAAAAAAA/////////wD///////+8AAAAAAAAABDs////////////AAAAAAAAAAD/////////AP////////wYAAAAAAAAADz0//////////AAAAAAAAAAAP////////8A/////////5AAAAAAAAAAACCY4P//3KhcCAAAAAAAAAAA/////////wD/////////+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////AP//////////xAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIP////////8A////////////rAQAAAAAAAAAAAAAAAAAAAAAAAAAAGTw/////////wD/////////////vBQAAAAAAAAAAAAAAAAAAAAAADjI////////////AP//////////////8HAQAAAAAAAAAAAAAAAAAEiw//////////////8A//////////////////iwcEAgBAAABCA4aKDk/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'H' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'I' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'J' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAj//////////////wD//////////+zMrIxwUDAQ//////wAAAAAAAAAIP//////////////AP//////////DAAAAAAAAADo////2AAAAAAAAAA0//////////////8A//////////8wAAAAAAAAAKj///+YAAAAAAAAAFj//////////////wD//////////2gAAAAAAAAAIND/yBgAAAAAAAAAkP//////////////AP//////////vAAAAAAAAAAAAAAAAAAAAAAAAADc//////////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAUP///////////////wD////////////EBAAAAAAAAAAAAAAAAAAAABjk////////////////AP////////////+sBAAAAAAAAAAAAAAAAAAY2P////////////////8A///////////////EMAAAAAAAAAAAAAAAVOj//////////////////wD/////////////////vHBAIAAAABg8fNT/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'K' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////8AAAAAAAAAAP//////////wAQAAAAAAAAAAABw////////AP///////wAAAAAAAAAA/////////9AMAAAAAAAAAAAAcP////////8A////////AAAAAAAAAAD////////cGAAAAAAAAAAAAHD//////////wD///////8AAAAAAAAAAP//////6CgAAAAAAAAAAABs////////////AP///////wAAAAAAAAAA//////Q0AAAAAAAAAAAAVPz///////////8A////////AAAAAAAAAAD////8RAAAAAAAAAAAAFT8/////////////wD///////8AAAAAAAAAAP///1gAAAAAAAAAAABU/P//////////////AP///////wAAAAAAAAAA//9wAAAAAAAAAAAASPz///////////////8A////////AAAAAAAAAAD/jAAAAAAAAAAAADz0/////////////////wD///////8AAAAAAAAAAKQAAAAAAAAAAAA89P//////////////////AP///////wAAAAAAAAAABAAAAAAAAAAAFPT///////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAApP///////////////////wD///////8AAAAAAAAAAAAAAAAAAAAAAAAU8P//////////////////AP///////wAAAAAAAAAAAAAAAAAAAAAAAABk//////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAAAADE/////////////////wD///////8AAAAAAAAAAAAAAAAoEAAAAAAAACz8////////////////AP///////wAAAAAAAAAAAAAAGNiAAAAAAAAAAIj///////////////8A////////AAAAAAAAAAAAABjY//gYAAAAAAAACOD//////////////wD///////8AAAAAAAAAAAAY2P///5wAAAAAAAAASP//////////////AP///////wAAAAAAAAAAGNj//////CgAAAAAAAAAqP////////////8A////////AAAAAAAAAADI////////sAAAAAAAAAAc8P///////////wD///////8AAAAAAAAAAP//////////QAAAAAAAAABs////////////AP///////wAAAAAAAAAA///////////IAAAAAAAAAATI//////////8A////////AAAAAAAAAAD///////////9YAAAAAAAAADD8/////////wD///////8AAAAAAAAAAP///////////9wEAAAAAAAAAJD/////////AP///////wAAAAAAAAAA/////////////3AAAAAAAAAADOT///////8A////////AAAAAAAAAAD/////////////7BAAAAAAAAAAUP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'L' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'M' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////8AAAAAAAAAAAAAAHz//////3wAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAATP//////UAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAc//////8cAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAADw////8AAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAAALz////AAAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAAkP///5AAAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAABc////ZAAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAoAAAAADD///8wAAAAACQAAAAAAAAA////////AP//////AAAAAAAAAFwAAAAABPz//AgAAAAAXAAAAAAAAAD///////8A//////8AAAAAAAAAkAAAAAAA0P/UAAAAAACQAAAAAAAAAP///////wD//////wAAAAAAAADMAAAAAACg/6gAAAAAAMQAAAAAAAAA////////AP//////AAAAAAAAAPgEAAAAAHD/dAAAAAAE+AAAAAAAAAD///////8A//////8AAAAAAAAA/zQAAAAAQP9IAAAAADD/AAAAAAAAAP///////wD//////wAAAAAAAAD/bAAAAAAQ/xQAAAAAaP8AAAAAAAAA////////AP//////AAAAAAAAAP+gAAAAAADQAAAAAACc/wAAAAAAAAD///////8A//////8AAAAAAAAA/9QAAAAAAGgAAAAAAND/AAAAAAAAAP///////wD//////wAAAAAAAAD//wwAAAAAFAAAAAAM/P8AAAAAAAAA////////AP//////AAAAAAAAAP//RAAAAAAAAAAAADz//wAAAAAAAAD///////8A//////8AAAAAAAAA//94AAAAAAAAAAAAcP//AAAAAAAAAP///////wD//////wAAAAAAAAD//7AAAAAAAAAAAACo//8AAAAAAAAA////////AP//////AAAAAAAAAP//5AAAAAAAAAAAANz//wAAAAAAAAD///////8A//////8AAAAAAAAA////HAAAAAAAAAAQ////AAAAAAAAAP///////wD//////wAAAAAAAAD///9QAAAAAAAAAEz///8AAAAAAAAA////////AP//////AAAAAAAAAP///4gAAAAAAAAAfP///wAAAAAAAAD///////8A//////8AAAAAAAAA////vAAAAAAAAACw////AAAAAAAAAP///////wD//////wAAAAAAAAD////wAAAAAAAAAOz///8AAAAAAAAA////////AP//////AAAAAAAAAP////8sAAAAAAAc/////wAAAAAAAAD///////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'N' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAALD/////////////AAAAAAAAAP//////////AP////////8AAAAAAAAAFOj///////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAASP///////////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAkP//////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAI1P////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAw+P///////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAABw////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAC8//////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAABzs/////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAFD/////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAJz///8AAAAAAAAA//////////8A/////////wAAAAAAAAAUAAAAAAAADNz//wAAAAAAAAD//////////wD/////////AAAAAAAAALQAAAAAAAAANPz/AAAAAAAAAP//////////AP////////8AAAAAAAAA/2wAAAAAAAAAfP8AAAAAAAAA//////////8A/////////wAAAAAAAAD/+CwAAAAAAAAExAAAAAAAAAD//////////wD/////////AAAAAAAAAP//0AQAAAAAAAAgAAAAAAAAAP//////////AP////////8AAAAAAAAA////jAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////RAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP/////kFAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA//////+sAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD///////9kAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP////////QkAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA/////////8wEAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD//////////4QAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP///////////DwAAAAAAAAAAP//////////AP////////8AAAAAAAAA////////////4BAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////////////qAAAAAAAAAD//////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'O' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////0qGw4HAAAABw4aKT0/////////////////wD////////////////wcAwAAAAAAAAAAAAAAAho6P//////////////AP//////////////uBQAAAAAAAAAAAAAAAAAAAAMoP////////////8A/////////////6AEAAAAAAAAAAAAAAAAAAAAAAAAkP///////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP//////////8BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAM5P////////8A//////////9wAAAAAAAAAAAsrPD/7KQsAAAAAAAAAABg/////////wD/////////+BAAAAAAAAAAUPj///////hQAAAAAAAAAAjs////////AP////////+sAAAAAAAAABDw//////////AYAAAAAAAAAKD///////8A/////////2wAAAAAAAAAdP///////////3wAAAAAAAAAYP///////wD/////////OAAAAAAAAAC4////////////xAAAAAAAAAAw////////AP////////8cAAAAAAAAAOD////////////oAAAAAAAAABT///////8A/////////wAAAAAAAAAA//////////////8AAAAAAAAAAP///////wD/////////AAAAAAAAAAD//////////////wAAAAAAAAAA////////AP////////8AAAAAAAAAAP/////////////8AAAAAAAAAAD///////8A/////////xwAAAAAAAAA5P///////////+AAAAAAAAAAHP///////wD/////////NAAAAAAAAAC8////////////uAAAAAAAAAA4////////AP////////9oAAAAAAAAAHj///////////98AAAAAAAAAGT///////8A/////////6gAAAAAAAAAGPD/////////+BgAAAAAAAAApP///////wD/////////9AwAAAAAAAAAUPz///////xcAAAAAAAAAAjs////////AP//////////cAAAAAAAAAAALKjs//CwOAAAAAAAAAAAYP////////8A///////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzk/////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP////////////+QAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A//////////////+sEAAAAAAAAAAAAAAAAAAAAAyg/////////////wD////////////////oZAgAAAAAAAAAAAAAAARg4P//////////////AP//////////////////9KhsOCAAAAAUMFyc7P////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'P' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////wAAAAAAAAAAAAAAAAAACCxguP////////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAOOD//////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAGOD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAARP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAABo////////////AP///////////wAAAAAAAAAA////6JwMAAAAAAAAADD///////////8A////////////AAAAAAAAAAD//////6AAAAAAAAAADP///////////wD///////////8AAAAAAAAAAP//////9AAAAAAAAAAA////////////AP///////////wAAAAAAAAAA///////0AAAAAAAAAAD///////////8A////////////AAAAAAAAAAD//////5gAAAAAAAAAHP///////////wD///////////8AAAAAAAAAAP///9iICAAAAAAAAABI////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAIT/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAABU/P////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAIhPz//////////////wD///////////8AAAAAAAAAAAAAAAAABCRMkOz/////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'Q' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////SoaDQcAAAAHDhoqPT///////////////////8A//////////////BwDAAAAAAAAAAAAAAACHDo/////////////////wD///////////+4FAAAAAAAAAAAAAAAAAAAABCo////////////////AP//////////nAQAAAAAAAAAAAAAAAAAAAAAAACQ//////////////8A/////////7gEAAAAAAAAAAAAAAAAAAAAAAAAAACg/////////////wD////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzo////////////AP///////3AAAAAAAAAAACyo8P/sqCwAAAAAAAAAAGT///////////8A///////4EAAAAAAAAABM+P///////FQAAAAAAAAACPT//////////wD//////7AAAAAAAAAAFPD/////////9BgAAAAAAAAApP//////////AP//////bAAAAAAAAAB4////////////fAAAAAAAAABk//////////8A//////84AAAAAAAAALz///////////+8AAAAAAAAADT//////////wD//////xwAAAAAAAAA6P///////////+QAAAAAAAAAHP//////////AP//////AAAAAAAAAAD//////////////wAAAAAAAAAA//////////8A//////8AAAAAAAAAAP//////////////AAAAAAAAAAD//////////wD//////wAAAAAAAAAA/P////////////8AAAAAAAAAAP//////////AP//////GAAAAAAAAADg////////////4AAAAAAAAAAc//////////8A//////84AAAAAAAAALT////MJHTo//+8AAAAAAAAADT//////////wD//////2wAAAAAAAAAdP///2AAABCg/3wAAAAAAAAAZP//////////AP//////rAAAAAAAAAAY9P/sCAAAAABMGAAAAAAAAACk//////////8A///////4EAAAAAAAAABU/P+0OAAAAAAAAAAAAAAACPT//////////wD///////94AAAAAAAAAAA4sPD/gAAAAAAAAAAAAABk////////////AP////////AcAAAAAAAAAAAAAAAAAAAAAAAAAAAADOT///////////8A/////////7wEAAAAAAAAAAAAAAAAAAAAAAAAAACQ/////////////wD//////////6wEAAAAAAAAAAAAAAAAAAAAAAAAABSs////////////AP///////////7gUAAAAAAAAAAAAAAAAAAAAAAAAAABAwP////////8A//////////////BwDAAAAAAAAAAAAAAABAgAAAAAAAA8/////////wD////////////////0qGg0GAAAABgwXJjkxBgAAAAAALD/////////AP//////////////////////////////////5DQAAAAk/P////////8A////////////////////////////////////+GwAAJD//////////wD//////////////////////////////////////8A49P//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'R' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////wAAAAAAAAAAAAAAAAAAAAQgOGSk+P///////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAcuP//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAEsP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ6P///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADD///////////8A/////////wAAAAAAAAAA///////svDgAAAAAAAAACP///////////wD/////////AAAAAAAAAAD/////////7AAAAAAAAAAA////////////AP////////8AAAAAAAAAAP/////////cAAAAAAAAABD///////////8A/////////wAAAAAAAAAA//////DQoCQAAAAAAAAAQP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACU////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIPj///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAzU/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAA02P//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAxctPz///////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAEDY/////////////////wD/////////AAAAAAAAAAD/9LAsAAAAAAAAAAzc////////////////AP////////8AAAAAAAAAAP///+wkAAAAAAAAADD8//////////////8A/////////wAAAAAAAAAA/////8QAAAAAAAAAAJD//////////////wD/////////AAAAAAAAAAD//////1QAAAAAAAAAFPD/////////////AP////////8AAAAAAAAAAP//////3AQAAAAAAAAAgP////////////8A/////////wAAAAAAAAAA////////aAAAAAAAAAAM6P///////////wD/////////AAAAAAAAAAD////////oCAAAAAAAAABs////////////AP////////8AAAAAAAAAAP////////+AAAAAAAAAAATc//////////8A/////////wAAAAAAAAAA//////////AUAAAAAAAAAFj//////////wD/////////AAAAAAAAAAD//////////5AAAAAAAAAAAND/////////AP////////8AAAAAAAAAAP//////////+CQAAAAAAAAAQP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'S' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////8vHBEIAgAAAQgQHC8/P////////////////8A////////////////pCQAAAAAAAAAAAAAAAAcoP///////////////wD//////////////FwAAAAAAAAAAAAAAAAAAAAAXP//////////////AP////////////9oAAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A////////////zAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////9cAAAAAAAAAAAAAAAAAAAAAAAAAACA////////////AP///////////xgAAAAAAAAAUOD/8KwkAAAAAAAAADj///////////8A////////////AAAAAAAAAAD0/////8wABCAgICxASP///////////wD///////////8MAAAAAAAAAMz/////////////////////////////AP///////////0AAAAAAAAAACFiQxPT///////////////////////8A////////////oAAAAAAAAAAAAAAAADBwtPT//////////////////wD////////////8QAAAAAAAAAAAAAAAAAAACFTA////////////////AP/////////////oOAAAAAAAAAAAAAAAAAAAAABM6P////////////8A///////////////4fAgAAAAAAAAAAAAAAAAAAAAY2P///////////wD/////////////////7IwwAAAAAAAAAAAAAAAAAAAo+P//////////AP/////////////////////koGw0BAAAAAAAAAAAAACU//////////8A///////////////////////////4uFgAAAAAAAAAADz//////////wD//////////2BgSEA0IBwA6P///////5QAAAAAAAAADP//////////AP//////////JAAAAAAAAACc/////////AAAAAAAAAAA//////////8A//////////9YAAAAAAAAACDo///////AAAAAAAAAABT//////////wD//////////6QAAAAAAAAAACCk7P/snBQAAAAAAAAAUP//////////AP//////////+BAAAAAAAAAAAAAAAAAAAAAAAAAAAACs//////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAAOP///////////wD////////////8RAAAAAAAAAAAAAAAAAAAAAAAABjc////////////AP/////////////0PAAAAAAAAAAAAAAAAAAAAAAg2P////////////8A///////////////8hBQAAAAAAAAAAAAAAAAMdPT//////////////wD/////////////////+LRwSCAMAAAAHDhoqPT/////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'T' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'U' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////JAAAAAAAAADk/////////+gAAAAAAAAAHP//////////AP////////9MAAAAAAAAAJz/////////nAAAAAAAAABE//////////8A/////////4gAAAAAAAAAHOj//////+ggAAAAAAAAAHz//////////wD/////////0AAAAAAAAAAAIJzs/+ykIAAAAAAAAAAA0P//////////AP//////////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A///////////IBAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAAAAJj/////////////AP////////////+UBAAAAAAAAAAAAAAAAAAAAASU//////////////8A///////////////IPAAAAAAAAAAAAAAAAAAwyP///////////////wD/////////////////0IxYOCAIAAAEIEiAyP//////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'V' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////zAAAAAAAAAAYP//////////////ZAAAAAAAAAAw////////AP//////kAAAAAAAAAAU/P////////////8UAAAAAAAAAJD///////8A///////oBAAAAAAAAADE////////////xAAAAAAAAAAE7P///////wD///////9MAAAAAAAAAHD///////////94AAAAAAAAAEz/////////AP///////6gAAAAAAAAAJP///////////yQAAAAAAAAArP////////8A////////+BAAAAAAAAAA1P/////////YAAAAAAAAABT4/////////wD/////////aAAAAAAAAACE/////////4QAAAAAAAAAbP//////////AP/////////EAAAAAAAAADT/////////OAAAAAAAAADM//////////8A//////////8kAAAAAAAAAOT//////+QAAAAAAAAAKP///////////wD//////////4QAAAAAAAAAmP//////nAAAAAAAAACI////////////AP//////////5AAAAAAAAABE//////9EAAAAAAAABOT///////////8A////////////QAAAAAAAAAT0////9AgAAAAAAABI/////////////wD///////////+gAAAAAAAAAKT///+kAAAAAAAAAKj/////////////AP////////////QIAAAAAAAAXP///1wAAAAAAAAM+P////////////8A/////////////1wAAAAAAAAM+P/8DAAAAAAAAGT//////////////wD/////////////vAAAAAAAAAC8/7wAAAAAAAAAxP//////////////AP//////////////HAAAAAAAAGj/aAAAAAAAACT///////////////8A//////////////94AAAAAAAAHP8cAAAAAAAAhP///////////////wD//////////////9gAAAAAAAAAkAAAAAAAAADk////////////////AP///////////////zgAAAAAAAAQAAAAAAAAQP////////////////8A////////////////lAAAAAAAAAAAAAAAAACg/////////////////wD////////////////sCAAAAAAAAAAAAAAADPT/////////////////AP////////////////9QAAAAAAAAAAAAAABg//////////////////8A/////////////////7AAAAAAAAAAAAAAAMD//////////////////wD//////////////////BQAAAAAAAAAAAAc////////////////////AP//////////////////cAAAAAAAAAAAAHz///////////////////8A///////////////////MAAAAAAAAAAAA3P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'W' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//8cAAAAAAAAALz/////4AAAAAAAAAAA6P////+8AAAAAAAAABz//wD//1QAAAAAAAAAjP////+gAAAAAAAAAACo/////4wAAAAAAAAAUP//AP//jAAAAAAAAABU/////2AAAAAAAAAAAGj/////VAAAAAAAAACM//8A///EAAAAAAAAACT/////IAAAAAAAAAAAKP////8kAAAAAAAAAMT//wD///gEAAAAAAAAAPD//+AAAAAAAAAAAAAA6P//8AAAAAAAAAAE9P//AP///zAAAAAAAAAAvP//oAAAAAAAAAAAAACo//+8AAAAAAAAADD///8A////bAAAAAAAAACM//9gAAAAAAAAAAAAAGT//4wAAAAAAAAAaP///wD///+kAAAAAAAAAFT//yAAAAAAAAAAAAAAIP//VAAAAAAAAACc////AP///9gAAAAAAAAAJP/gAAAAAAAAAAAAAAAA4P8kAAAAAAAAANT///8A/////xAAAAAAAAAA8KAAAAAAAAAAAAAAAACg8AAAAAAAAAAQ/////wD/////TAAAAAAAAAC8YAAAAAAAAAAAAAAAAGC8AAAAAAAAAET/////AP////+AAAAAAAAAAIwgAAAAAAAAAAAAAAAAIIwAAAAAAAAAfP////8A/////7gAAAAAAAAANAAAAAAAACwwAAAAAAAANAAAAAAAAACw/////wD/////8AAAAAAAAAAAAAAAAAAAdHgAAAAAAAAAAAAAAAAAAOz/////AP//////KAAAAAAAAAAAAAAAAAC4vAAAAAAAAAAAAAAAAAAg//////8A//////9gAAAAAAAAAAAAAAAACPj4CAAAAAAAAAAAAAAAAFj//////wD//////5QAAAAAAAAAAAAAAABE//9IAAAAAAAAAAAAAAAAkP//////AP//////0AAAAAAAAAAAAAAAAIj//4wAAAAAAAAAAAAAAADI//////8A///////8DAAAAAAAAAAAAAAAzP//1AAAAAAAAAAAAAAABPj//////wD///////88AAAAAAAAAAAAABT/////GAAAAAAAAAAAAAA0////////AP///////3QAAAAAAAAAAAAAWP////9gAAAAAAAAAAAAAHD///////8A////////sAAAAAAAAAAAAACg/////6QAAAAAAAAAAAAApP///////wD////////kAAAAAAAAAAAAAOT/////6AAAAAAAAAAAAADc////////AP////////8cAAAAAAAAAAAo////////MAAAAAAAAAAAEP////////8A/////////1QAAAAAAAAAAHD///////94AAAAAAAAAABM/////////wD/////////jAAAAAAAAAAAtP///////7wAAAAAAAAAAID/////////AP/////////EAAAAAAAAAAT0////////+AgAAAAAAAAAuP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'X' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////9UAAAAAAAAAKz///////////+sAAAAAAAAAFD/////////AP///////+QQAAAAAAAAFOT/////////8BwAAAAAAAAM5P////////8A/////////5gAAAAAAAAATP////////9kAAAAAAAAAJD//////////wD//////////0AAAAAAAAAAoP//////wAAAAAAAAAA0/P//////////AP//////////2AgAAAAAAAAQ4P////gkAAAAAAAABMz///////////8A////////////iAAAAAAAAABA////dAAAAAAAAABw/////////////wD////////////8MAAAAAAAAACU/9AEAAAAAAAAHPD/////////////AP/////////////IBAAAAAAAAAzYMAAAAAAAAACs//////////////8A//////////////90AAAAAAAAABAAAAAAAAAATP///////////////wD///////////////QgAAAAAAAAAAAAAAAAAAzg////////////////AP///////////////7wAAAAAAAAAAAAAAAAAjP////////////////8A/////////////////2AAAAAAAAAAAAAAADD8/////////////////wD/////////////////7BQAAAAAAAAAAAAEyP//////////////////AP/////////////////gDAAAAAAAAAAAAAjY//////////////////8A/////////////////0AAAAAAAAAAAAAAADj8/////////////////wD///////////////+UAAAAAAAAAAAAAAAAAJD/////////////////AP//////////////4AwAAAAAAAAAAAAAAAAADOD///////////////8A//////////////9AAAAAAAAAAAAAAAAAAAAAQP///////////////wD/////////////nAAAAAAAAAAAWAAAAAAAAAAAlP//////////////AP///////////+QQAAAAAAAAAGD/YAAAAAAAAAAM4P////////////8A////////////TAAAAAAAAAAs9P/0LAAAAAAAAABM/////////////wD//////////6AAAAAAAAAADNT////UDAAAAAAAAACg////////////AP/////////kEAAAAAAAAACg//////+gAAAAAAAAABDk//////////8A/////////0wAAAAAAAAAYP////////9gAAAAAAAAAEz//////////wD///////+oAAAAAAAAACz0//////////QsAAAAAAAAAKT/////////AP//////7BQAAAAAAAAM1P///////////9QMAAAAAAAAFOz///////8A//////9UAAAAAAAAAKD//////////////6AAAAAAAAAAVP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'Y' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////1QAAAAAAAAAAGj//////////2gAAAAAAAAAAFT///////8A////////5BAAAAAAAAAAAMT////////EAAAAAAAAAAAQ5P///////wD/////////mAAAAAAAAAAAKPj/////+CgAAAAAAAAAAJj/////////AP//////////PAAAAAAAAAAAgP////+AAAAAAAAAAAA8//////////8A///////////YCAAAAAAAAAAE2P//2AQAAAAAAAAACNj//////////wD///////////+AAAAAAAAAAAA4//84AAAAAAAAAACA////////////AP////////////woAAAAAAAAAACUlAAAAAAAAAAAKPz///////////8A/////////////8gAAAAAAAAAABAQAAAAAAAAAADI/////////////wD//////////////2wAAAAAAAAAAAAAAAAAAAAAbP//////////////AP//////////////8BwAAAAAAAAAAAAAAAAAABzw//////////////8A////////////////tAAAAAAAAAAAAAAAAAAAtP///////////////wD/////////////////VAAAAAAAAAAAAAAAAFT/////////////////AP/////////////////oEAAAAAAAAAAAAAAQ6P////////////////8A//////////////////+cAAAAAAAAAAAAAJz//////////////////wD///////////////////9AAAAAAAAAAABA////////////////////AP///////////////////9gAAAAAAAAAANj///////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ 'Z' => array(
+ 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAQ//////////////8A/////////////////////////1AAAAAAAAAABLz//////////////wD///////////////////////98AAAAAAAAAACY////////////////AP//////////////////////pAAAAAAAAAAAaP////////////////8A/////////////////////8QIAAAAAAAAAET8/////////////////wD////////////////////gGAAAAAAAAAAo9P//////////////////AP//////////////////9CwAAAAAAAAAFNz///////////////////8A//////////////////xMAAAAAAAAAATA/////////////////////wD/////////////////eAAAAAAAAAAAnP//////////////////////AP///////////////5wAAAAAAAAAAHT///////////////////////8A///////////////ABAAAAAAAAABM/P///////////////////////wD/////////////3BQAAAAAAAAALPT/////////////////////////AP////////////QoAAAAAAAAABjg//////////////////////////8A///////////8SAAAAAAAAAAExP///////////////////////////wD//////////2wAAAAAAAAAAKD/////////////////////////////AP////////+YAAAAAAAAAAB8//////////////////////////////8A/////////wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
+ 'width' => 40
+ ),
+ );
+ }
+}
diff --git a/phpBB/phpbb/captcha/plugins/captcha_abstract.php b/phpBB/phpbb/captcha/plugins/captcha_abstract.php
new file mode 100644
index 0000000000..24ed7f939d
--- /dev/null
+++ b/phpBB/phpbb/captcha/plugins/captcha_abstract.php
@@ -0,0 +1,390 @@
+<?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\captcha\plugins;
+
+/**
+* This class holds the code shared by the two default 3.0.x CAPTCHAs.
+*/
+abstract class captcha_abstract
+{
+ var $confirm_id;
+ var $confirm_code;
+ var $code;
+ var $seed;
+ var $attempts = 0;
+ var $type;
+ var $solved = 0;
+ var $captcha_vars = false;
+
+ /**
+ * @var string name of the service.
+ */
+ protected $service_name;
+
+ function init($type)
+ {
+ global $config, $db, $user;
+
+ // read input
+ $this->confirm_id = request_var('confirm_id', '');
+ $this->confirm_code = request_var('confirm_code', '');
+ $refresh = request_var('refresh_vc', false) && $config['confirm_refresh'];
+
+ $this->type = (int) $type;
+
+ if (!strlen($this->confirm_id) || !$this->load_code())
+ {
+ // we have no confirm ID, better get ready to display something
+ $this->generate_code();
+ }
+ else if ($refresh)
+ {
+ $this->regenerate_code();
+ }
+ }
+
+ function execute_demo()
+ {
+ global $user;
+
+ $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
+ $this->seed = hexdec(substr(unique_id(), 4, 10));
+
+ // compute $seed % 0x7fffffff
+ $this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff);
+
+ $generator = $this->get_generator_class();
+ $captcha = new $generator();
+ define('IMAGE_OUTPUT', 1);
+ $captcha->execute($this->code, $this->seed);
+ }
+
+ function execute()
+ {
+ if (empty($this->code))
+ {
+ if (!$this->load_code())
+ {
+ // invalid request, bail out
+ return false;
+ }
+ }
+ $generator = $this->get_generator_class();
+ $captcha = new $generator();
+ define('IMAGE_OUTPUT', 1);
+ $captcha->execute($this->code, $this->seed);
+ }
+
+ function get_template()
+ {
+ global $config, $user, $template, $phpEx, $phpbb_root_path;
+
+ if ($this->is_solved())
+ {
+ return false;
+ }
+ else
+ {
+ $link = append_sid($phpbb_root_path . 'ucp.' . $phpEx, 'mode=confirm&amp;confirm_id=' . $this->confirm_id . '&amp;type=' . $this->type);
+ $contact_link = phpbb_get_board_contact_link($config, $phpbb_root_path, $phpEx);
+ $explain = $user->lang(($this->type != CONFIRM_POST) ? 'CONFIRM_EXPLAIN' : 'POST_CONFIRM_EXPLAIN', '<a href="' . $contact_link . '">', '</a>');
+
+ $template->assign_vars(array(
+ 'CONFIRM_IMAGE_LINK' => $link,
+ 'CONFIRM_IMAGE' => '<img src="' . $link . '" />',
+ 'CONFIRM_IMG' => '<img src="' . $link . '" />',
+ 'CONFIRM_ID' => $this->confirm_id,
+ 'S_CONFIRM_CODE' => true,
+ 'S_TYPE' => $this->type,
+ 'S_CONFIRM_REFRESH' => ($config['enable_confirm'] && $config['confirm_refresh'] && $this->type == CONFIRM_REG) ? true : false,
+ 'L_CONFIRM_EXPLAIN' => $explain,
+ ));
+
+ return 'captcha_default.html';
+ }
+ }
+
+ function get_demo_template($id)
+ {
+ global $config, $user, $template, $phpbb_admin_path, $phpEx;
+
+ $variables = '';
+
+ if (is_array($this->captcha_vars))
+ {
+ foreach ($this->captcha_vars as $captcha_var => $template_var)
+ {
+ $variables .= '&amp;' . rawurlencode($captcha_var) . '=' . request_var($captcha_var, (int) $config[$captcha_var]);
+ }
+ }
+
+ // acp_captcha has a delivery function; let's use it
+ $template->assign_vars(array(
+ 'CONFIRM_IMAGE' => append_sid($phpbb_admin_path . 'index.' . $phpEx, 'captcha_demo=1&amp;mode=visual&amp;i=' . $id . '&amp;select_captcha=' . $this->get_service_name()) . $variables,
+ 'CONFIRM_ID' => $this->confirm_id,
+ ));
+
+ return 'captcha_default_acp_demo.html';
+ }
+
+ function get_hidden_fields()
+ {
+ $hidden_fields = array();
+
+ // this is required for posting.php - otherwise we would forget about the captcha being already solved
+ if ($this->solved)
+ {
+ $hidden_fields['confirm_code'] = $this->confirm_code;
+ }
+ $hidden_fields['confirm_id'] = $this->confirm_id;
+ return $hidden_fields;
+ }
+
+ function garbage_collect($type)
+ {
+ global $db, $config;
+
+ $sql = 'SELECT DISTINCT c.session_id
+ FROM ' . CONFIRM_TABLE . ' c
+ LEFT JOIN ' . SESSIONS_TABLE . ' s ON (c.session_id = s.session_id)
+ WHERE s.session_id IS NULL' .
+ ((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type);
+ $result = $db->sql_query($sql);
+
+ if ($row = $db->sql_fetchrow($result))
+ {
+ $sql_in = array();
+ do
+ {
+ $sql_in[] = (string) $row['session_id'];
+ }
+ while ($row = $db->sql_fetchrow($result));
+
+ if (sizeof($sql_in))
+ {
+ $sql = 'DELETE FROM ' . CONFIRM_TABLE . '
+ WHERE ' . $db->sql_in_set('session_id', $sql_in);
+ $db->sql_query($sql);
+ }
+ }
+ $db->sql_freeresult($result);
+ }
+
+ function uninstall()
+ {
+ $this->garbage_collect(0);
+ }
+
+ function install()
+ {
+ return;
+ }
+
+ function validate()
+ {
+ global $config, $db, $user;
+
+ if (empty($user->lang))
+ {
+ $user->setup();
+ }
+
+ $error = '';
+ if (!$this->confirm_id)
+ {
+ $error = $user->lang['CONFIRM_CODE_WRONG'];
+ }
+ else
+ {
+ if ($this->check_code())
+ {
+ $this->solved = true;
+ }
+ else
+ {
+ $error = $user->lang['CONFIRM_CODE_WRONG'];
+ }
+ }
+
+ if (strlen($error))
+ {
+ // okay, incorrect answer. Let's ask a new question.
+ $this->new_attempt();
+ return $error;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * The old way to generate code, suitable for GD and non-GD. Resets the internal state.
+ */
+ function generate_code()
+ {
+ global $db, $user;
+
+ $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
+ $this->confirm_id = md5(unique_id($user->ip));
+ $this->seed = hexdec(substr(unique_id(), 4, 10));
+ $this->solved = 0;
+ // compute $seed % 0x7fffffff
+ $this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff);
+
+ $sql = 'INSERT INTO ' . CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array(
+ 'confirm_id' => (string) $this->confirm_id,
+ 'session_id' => (string) $user->session_id,
+ 'confirm_type' => (int) $this->type,
+ 'code' => (string) $this->code,
+ 'seed' => (int) $this->seed)
+ );
+ $db->sql_query($sql);
+ }
+
+ /**
+ * New Question, if desired.
+ */
+ function regenerate_code()
+ {
+ global $db, $user;
+
+ $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
+ $this->seed = hexdec(substr(unique_id(), 4, 10));
+ $this->solved = 0;
+ // compute $seed % 0x7fffffff
+ $this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff);
+
+ $sql = 'UPDATE ' . CONFIRM_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array(
+ 'code' => (string) $this->code,
+ 'seed' => (int) $this->seed)) . '
+ WHERE
+ confirm_id = \'' . $db->sql_escape($this->confirm_id) . '\'
+ AND session_id = \'' . $db->sql_escape($user->session_id) . '\'';
+ $db->sql_query($sql);
+ }
+
+ /**
+ * New Question, if desired.
+ */
+ function new_attempt()
+ {
+ global $db, $user;
+
+ $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
+ $this->seed = hexdec(substr(unique_id(), 4, 10));
+ $this->solved = 0;
+ // compute $seed % 0x7fffffff
+ $this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff);
+
+ $sql = 'UPDATE ' . CONFIRM_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array(
+ 'code' => (string) $this->code,
+ 'seed' => (int) $this->seed)) . '
+ , attempts = attempts + 1
+ WHERE
+ confirm_id = \'' . $db->sql_escape($this->confirm_id) . '\'
+ AND session_id = \'' . $db->sql_escape($user->session_id) . '\'';
+ $db->sql_query($sql);
+ }
+
+ /**
+ * Look up everything we need for painting&checking.
+ */
+ function load_code()
+ {
+ global $db, $user;
+
+ $sql = 'SELECT code, seed, attempts
+ FROM ' . CONFIRM_TABLE . "
+ WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "'
+ AND session_id = '" . $db->sql_escape($user->session_id) . "'
+ AND confirm_type = " . $this->type;
+ $result = $db->sql_query($sql);
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ if ($row)
+ {
+ $this->code = $row['code'];
+ $this->seed = $row['seed'];
+ $this->attempts = $row['attempts'];
+ return true;
+ }
+
+ return false;
+ }
+
+ function check_code()
+ {
+ return (strcasecmp($this->code, $this->confirm_code) === 0);
+ }
+
+ function get_attempt_count()
+ {
+ return $this->attempts;
+ }
+
+ function reset()
+ {
+ global $db, $user;
+
+ $sql = 'DELETE FROM ' . CONFIRM_TABLE . "
+ WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
+ AND confirm_type = " . (int) $this->type;
+ $db->sql_query($sql);
+
+ // we leave the class usable by generating a new question
+ $this->generate_code();
+ }
+
+ function is_solved()
+ {
+ if (request_var('confirm_code', false) && $this->solved === 0)
+ {
+ $this->validate();
+ }
+ return (bool) $this->solved;
+ }
+
+ /**
+ * API function
+ */
+ function has_config()
+ {
+ return false;
+ }
+
+ /**
+ * @return string the name of the service corresponding to the plugin
+ */
+ function get_service_name()
+ {
+ return $this->service_name;
+ }
+
+ /**
+ * Set the name of the plugin
+ *
+ * @param string $name
+ */
+ public function set_name($name)
+ {
+ $this->service_name = $name;
+ }
+
+ /**
+ * @return string the name of the class used to generate the captcha
+ */
+ abstract function get_generator_class();
+}
diff --git a/phpBB/phpbb/captcha/plugins/gd.php b/phpBB/phpbb/captcha/plugins/gd.php
new file mode 100644
index 0000000000..f6200b5b2f
--- /dev/null
+++ b/phpBB/phpbb/captcha/plugins/gd.php
@@ -0,0 +1,130 @@
+<?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\captcha\plugins;
+
+class gd extends captcha_abstract
+{
+ var $captcha_vars = array(
+ 'captcha_gd_x_grid' => 'CAPTCHA_GD_X_GRID',
+ 'captcha_gd_y_grid' => 'CAPTCHA_GD_Y_GRID',
+ 'captcha_gd_foreground_noise' => 'CAPTCHA_GD_FOREGROUND_NOISE',
+// 'captcha_gd' => 'CAPTCHA_GD_PREVIEWED',
+ 'captcha_gd_wave' => 'CAPTCHA_GD_WAVE',
+ 'captcha_gd_3d_noise' => 'CAPTCHA_GD_3D_NOISE',
+ 'captcha_gd_fonts' => 'CAPTCHA_GD_FONTS',
+ );
+
+ public function is_available()
+ {
+ return @extension_loaded('gd');
+ }
+
+ /**
+ * @return string the name of the class used to generate the captcha
+ */
+ function get_generator_class()
+ {
+ return '\\phpbb\\captcha\\gd';
+ }
+
+ /**
+ * API function
+ */
+ function has_config()
+ {
+ return true;
+ }
+
+ public function get_name()
+ {
+ return 'CAPTCHA_GD';
+ }
+
+ function acp_page($id, &$module)
+ {
+ global $db, $user, $auth, $template;
+ global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
+
+ $user->add_lang('acp/board');
+
+ $config_vars = array(
+ 'enable_confirm' => 'REG_ENABLE',
+ 'enable_post_confirm' => 'POST_ENABLE',
+ 'confirm_refresh' => 'CONFIRM_REFRESH',
+ 'captcha_gd' => 'CAPTCHA_GD',
+ );
+
+ $module->tpl_name = 'captcha_gd_acp';
+ $module->page_title = 'ACP_VC_SETTINGS';
+ $form_key = 'acp_captcha';
+ add_form_key($form_key);
+
+ $submit = request_var('submit', '');
+
+ if ($submit && check_form_key($form_key))
+ {
+ $captcha_vars = array_keys($this->captcha_vars);
+ foreach ($captcha_vars as $captcha_var)
+ {
+ $value = request_var($captcha_var, 0);
+ if ($value >= 0)
+ {
+ set_config($captcha_var, $value);
+ }
+ }
+
+ add_log('admin', 'LOG_CONFIG_VISUAL');
+ trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action));
+ }
+ else if ($submit)
+ {
+ trigger_error($user->lang['FORM_INVALID'] . adm_back_link($module->u_action));
+ }
+ else
+ {
+ foreach ($this->captcha_vars as $captcha_var => $template_var)
+ {
+ $var = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, 0) : $config[$captcha_var];
+ $template->assign_var($template_var, $var);
+ }
+
+ $template->assign_vars(array(
+ 'CAPTCHA_PREVIEW' => $this->get_demo_template($id),
+ 'CAPTCHA_NAME' => $this->get_service_name(),
+ 'U_ACTION' => $module->u_action,
+ ));
+ }
+ }
+
+ function execute_demo()
+ {
+ global $config;
+
+ $config_old = $config;
+
+ $config = new \phpbb\config\config(array());
+ foreach ($config_old as $key => $value)
+ {
+ $config->set($key, $value);
+ }
+
+ foreach ($this->captcha_vars as $captcha_var => $template_var)
+ {
+ $config->set($captcha_var, request_var($captcha_var, (int) $config[$captcha_var]));
+ }
+ parent::execute_demo();
+ $config = $config_old;
+ }
+
+}
diff --git a/phpBB/phpbb/captcha/plugins/gd_wave.php b/phpBB/phpbb/captcha/plugins/gd_wave.php
new file mode 100644
index 0000000000..e1d44df778
--- /dev/null
+++ b/phpBB/phpbb/captcha/plugins/gd_wave.php
@@ -0,0 +1,42 @@
+<?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\captcha\plugins;
+
+class gd_wave extends captcha_abstract
+{
+ public function is_available()
+ {
+ return @extension_loaded('gd');
+ }
+
+ public function get_name()
+ {
+ return 'CAPTCHA_GD_3D';
+ }
+
+ /**
+ * @return string the name of the class used to generate the captcha
+ */
+ function get_generator_class()
+ {
+ return '\\phpbb\\captcha\\gd_wave';
+ }
+
+ function acp_page($id, &$module)
+ {
+ global $config, $db, $template, $user;
+
+ trigger_error($user->lang['CAPTCHA_NO_OPTIONS'] . adm_back_link($module->u_action));
+ }
+}
diff --git a/phpBB/phpbb/captcha/plugins/nogd.php b/phpBB/phpbb/captcha/plugins/nogd.php
new file mode 100644
index 0000000000..6845e5935c
--- /dev/null
+++ b/phpBB/phpbb/captcha/plugins/nogd.php
@@ -0,0 +1,42 @@
+<?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\captcha\plugins;
+
+class nogd extends captcha_abstract
+{
+ public function is_available()
+ {
+ return true;
+ }
+
+ public function get_name()
+ {
+ return 'CAPTCHA_NO_GD';
+ }
+
+ /**
+ * @return string the name of the class used to generate the captcha
+ */
+ function get_generator_class()
+ {
+ return '\\phpbb\\captcha\\non_gd';
+ }
+
+ function acp_page($id, &$module)
+ {
+ global $user;
+
+ trigger_error($user->lang['CAPTCHA_NO_OPTIONS'] . adm_back_link($module->u_action));
+ }
+}
diff --git a/phpBB/phpbb/captcha/plugins/qa.php b/phpBB/phpbb/captcha/plugins/qa.php
new file mode 100644
index 0000000000..a7ba994cc3
--- /dev/null
+++ b/phpBB/phpbb/captcha/plugins/qa.php
@@ -0,0 +1,1009 @@
+<?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\captcha\plugins;
+
+/**
+* And now to something completely different. Let's make a captcha without extending the abstract class.
+* QA CAPTCHA sample implementation
+*/
+class qa
+{
+ var $confirm_id;
+ var $answer;
+ var $question_ids;
+ var $question_text;
+ var $question_lang;
+ var $question_strict;
+ var $attempts = 0;
+ var $type;
+ // dirty trick: 0 is false, but can still encode that the captcha is not yet validated
+ var $solved = 0;
+
+ protected $table_captcha_questions;
+ protected $table_captcha_answers;
+ protected $table_qa_confirm;
+
+ /**
+ * @var string name of the service.
+ */
+ protected $service_name;
+
+ /**
+ * Constructor
+ *
+ * @param string $table_captcha_questions
+ * @param string $table_captcha_answers
+ * @param string $table_qa_confirm
+ */
+ function __construct($table_captcha_questions, $table_captcha_answers, $table_qa_confirm)
+ {
+ $this->table_captcha_questions = $table_captcha_questions;
+ $this->table_captcha_answers = $table_captcha_answers;
+ $this->table_qa_confirm = $table_qa_confirm;
+ }
+
+ /**
+ * @param int $type as per the CAPTCHA API docs, the type
+ */
+ function init($type)
+ {
+ global $config, $db, $user;
+
+ // load our language file
+ $user->add_lang('captcha_qa');
+
+ // read input
+ $this->confirm_id = request_var('qa_confirm_id', '');
+ $this->answer = utf8_normalize_nfc(request_var('qa_answer', '', true));
+
+ $this->type = (int) $type;
+ $this->question_lang = $user->lang_name;
+
+ // we need all defined questions - shouldn't be too many, so we can just grab them
+ // try the user's lang first
+ $sql = 'SELECT question_id
+ FROM ' . $this->table_captcha_questions . "
+ WHERE lang_iso = '" . $db->sql_escape($user->lang_name) . "'";
+ $result = $db->sql_query($sql, 3600);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $this->question_ids[$row['question_id']] = $row['question_id'];
+ }
+ $db->sql_freeresult($result);
+
+ // fallback to the board default lang
+ if (!sizeof($this->question_ids))
+ {
+ $this->question_lang = $config['default_lang'];
+
+ $sql = 'SELECT question_id
+ FROM ' . $this->table_captcha_questions . "
+ WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'";
+ $result = $db->sql_query($sql, 7200);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $this->question_ids[$row['question_id']] = $row['question_id'];
+ }
+ $db->sql_freeresult($result);
+ }
+
+ // okay, if there is a confirm_id, we try to load that confirm's state. If not, we try to find one
+ if (!$this->load_answer() && (!$this->load_confirm_id() || !$this->load_answer()))
+ {
+ // we have no valid confirm ID, better get ready to ask something
+ $this->select_question();
+ }
+ }
+
+ /**
+ * See if the captcha has created its tables.
+ */
+ public function is_installed()
+ {
+ global $db;
+
+ $db_tool = new \phpbb\db\tools($db);
+
+ return $db_tool->sql_table_exists($this->table_captcha_questions);
+ }
+
+ /**
+ * API function - for the captcha to be available, it must have installed itself and there has to be at least one question in the board's default lang
+ */
+ public function is_available()
+ {
+ global $config, $db, $phpbb_root_path, $phpEx, $user;
+
+ // load language file for pretty display in the ACP dropdown
+ $user->add_lang('captcha_qa');
+
+ if (!$this->is_installed())
+ {
+ return false;
+ }
+
+ $sql = 'SELECT COUNT(question_id) AS question_count
+ FROM ' . $this->table_captcha_questions . "
+ WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'";
+ $result = $db->sql_query($sql);
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ return ((bool) $row['question_count']);
+ }
+
+ /**
+ * API function
+ */
+ function has_config()
+ {
+ return true;
+ }
+
+ /**
+ * API function
+ */
+ static public function get_name()
+ {
+ return 'CAPTCHA_QA';
+ }
+
+ /**
+ * @return string the name of the service corresponding to the plugin
+ */
+ function get_service_name()
+ {
+ return $this->service_name;
+ }
+
+ /**
+ * Set the name of the plugin
+ *
+ * @param string $name
+ */
+ public function set_name($name)
+ {
+ $this->service_name = $name;
+ }
+
+ /**
+ * API function - not needed as we don't display an image
+ */
+ function execute_demo()
+ {
+ }
+
+ /**
+ * API function - not needed as we don't display an image
+ */
+ function execute()
+ {
+ }
+
+ /**
+ * API function - send the question to the template
+ */
+ function get_template()
+ {
+ global $template;
+
+ if ($this->is_solved())
+ {
+ return false;
+ }
+ else
+ {
+ $template->assign_vars(array(
+ 'QA_CONFIRM_QUESTION' => $this->question_text,
+ 'QA_CONFIRM_ID' => $this->confirm_id,
+ 'S_CONFIRM_CODE' => true,
+ 'S_TYPE' => $this->type,
+ ));
+
+ return 'captcha_qa.html';
+ }
+ }
+
+ /**
+ * API function - we just display a mockup so that the captcha doesn't need to be installed
+ */
+ function get_demo_template()
+ {
+ global $config, $db, $template;
+
+ if ($this->is_available())
+ {
+ $sql = 'SELECT question_text
+ FROM ' . $this->table_captcha_questions . "
+ WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'";
+ $result = $db->sql_query_limit($sql, 1);
+ if ($row = $db->sql_fetchrow($result))
+ {
+ $template->assign_vars(array(
+ 'QA_CONFIRM_QUESTION' => $row['question_text'],
+ ));
+ }
+ $db->sql_freeresult($result);
+ }
+ return 'captcha_qa_acp_demo.html';
+ }
+
+ /**
+ * API function
+ */
+ function get_hidden_fields()
+ {
+ $hidden_fields = array();
+
+ // this is required - otherwise we would forget about the captcha being already solved
+ if ($this->solved)
+ {
+ $hidden_fields['qa_answer'] = $this->answer;
+ }
+ $hidden_fields['qa_confirm_id'] = $this->confirm_id;
+
+ return $hidden_fields;
+ }
+
+ /**
+ * API function
+ */
+ function garbage_collect($type = 0)
+ {
+ global $db, $config;
+
+ $sql = 'SELECT c.confirm_id
+ FROM ' . $this->table_qa_confirm . ' c
+ LEFT JOIN ' . SESSIONS_TABLE . ' s
+ ON (c.session_id = s.session_id)
+ WHERE s.session_id IS NULL' .
+ ((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type);
+ $result = $db->sql_query($sql);
+
+ if ($row = $db->sql_fetchrow($result))
+ {
+ $sql_in = array();
+
+ do
+ {
+ $sql_in[] = (string) $row['confirm_id'];
+ }
+ while ($row = $db->sql_fetchrow($result));
+
+ if (sizeof($sql_in))
+ {
+ $sql = 'DELETE FROM ' . $this->table_qa_confirm . '
+ WHERE ' . $db->sql_in_set('confirm_id', $sql_in);
+ $db->sql_query($sql);
+ }
+ }
+ $db->sql_freeresult($result);
+ }
+
+ /**
+ * API function - we don't drop the tables here, as that would cause the loss of all entered questions.
+ */
+ function uninstall()
+ {
+ $this->garbage_collect(0);
+ }
+
+ /**
+ * API function - set up shop
+ */
+ function install()
+ {
+ global $db;
+
+ $db_tool = new \phpbb\db\tools($db);
+
+ $tables = array($this->table_captcha_questions, $this->table_captcha_answers, $this->table_qa_confirm);
+
+ $schemas = array(
+ $this->table_captcha_questions => array (
+ 'COLUMNS' => array(
+ 'question_id' => array('UINT', null, 'auto_increment'),
+ 'strict' => array('BOOL', 0),
+ 'lang_id' => array('UINT', 0),
+ 'lang_iso' => array('VCHAR:30', ''),
+ 'question_text' => array('TEXT_UNI', ''),
+ ),
+ 'PRIMARY_KEY' => 'question_id',
+ 'KEYS' => array(
+ 'lang' => array('INDEX', 'lang_iso'),
+ ),
+ ),
+ $this->table_captcha_answers => array (
+ 'COLUMNS' => array(
+ 'question_id' => array('UINT', 0),
+ 'answer_text' => array('STEXT_UNI', ''),
+ ),
+ 'KEYS' => array(
+ 'qid' => array('INDEX', 'question_id'),
+ ),
+ ),
+ $this->table_qa_confirm => array (
+ 'COLUMNS' => array(
+ 'session_id' => array('CHAR:32', ''),
+ 'confirm_id' => array('CHAR:32', ''),
+ 'lang_iso' => array('VCHAR:30', ''),
+ 'question_id' => array('UINT', 0),
+ 'attempts' => array('UINT', 0),
+ 'confirm_type' => array('USINT', 0),
+ ),
+ 'KEYS' => array(
+ 'session_id' => array('INDEX', 'session_id'),
+ 'lookup' => array('INDEX', array('confirm_id', 'session_id', 'lang_iso')),
+ ),
+ 'PRIMARY_KEY' => 'confirm_id',
+ ),
+ );
+
+ foreach($schemas as $table => $schema)
+ {
+ if (!$db_tool->sql_table_exists($table))
+ {
+ $db_tool->sql_create_table($table, $schema);
+ }
+ }
+ }
+
+ /**
+ * API function - see what has to be done to validate
+ */
+ function validate()
+ {
+ global $config, $db, $user;
+
+ $error = '';
+
+ if (!sizeof($this->question_ids))
+ {
+ return false;
+ }
+
+ if (!$this->confirm_id)
+ {
+ $error = $user->lang['CONFIRM_QUESTION_WRONG'];
+ }
+ else
+ {
+ if ($this->check_answer())
+ {
+ $this->solved = true;
+ }
+ else
+ {
+ $error = $user->lang['CONFIRM_QUESTION_WRONG'];
+ }
+ }
+
+ if (strlen($error))
+ {
+ // okay, incorrect answer. Let's ask a new question.
+ $this->new_attempt();
+ $this->solved = false;
+
+ return $error;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Select a question
+ */
+ function select_question()
+ {
+ global $db, $user;
+
+ if (!sizeof($this->question_ids))
+ {
+ return false;
+ }
+ $this->confirm_id = md5(unique_id($user->ip));
+ $this->question = (int) array_rand($this->question_ids);
+
+ $sql = 'INSERT INTO ' . $this->table_qa_confirm . ' ' . $db->sql_build_array('INSERT', array(
+ 'confirm_id' => (string) $this->confirm_id,
+ 'session_id' => (string) $user->session_id,
+ 'lang_iso' => (string) $this->question_lang,
+ 'confirm_type' => (int) $this->type,
+ 'question_id' => (int) $this->question,
+ ));
+ $db->sql_query($sql);
+
+ $this->load_answer();
+ }
+
+ /**
+ * New Question, if desired.
+ */
+ function reselect_question()
+ {
+ global $db, $user;
+
+ if (!sizeof($this->question_ids))
+ {
+ return false;
+ }
+
+ $this->question = (int) array_rand($this->question_ids);
+ $this->solved = 0;
+
+ $sql = 'UPDATE ' . $this->table_qa_confirm . '
+ SET question_id = ' . (int) $this->question . "
+ WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "'
+ AND session_id = '" . $db->sql_escape($user->session_id) . "'";
+ $db->sql_query($sql);
+
+ $this->load_answer();
+ }
+
+ /**
+ * Wrong answer, so we increase the attempts and use a different question.
+ */
+ function new_attempt()
+ {
+ global $db, $user;
+
+ // yah, I would prefer a stronger rand, but this should work
+ $this->question = (int) array_rand($this->question_ids);
+ $this->solved = 0;
+
+ $sql = 'UPDATE ' . $this->table_qa_confirm . '
+ SET question_id = ' . (int) $this->question . ",
+ attempts = attempts + 1
+ WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "'
+ AND session_id = '" . $db->sql_escape($user->session_id) . "'";
+ $db->sql_query($sql);
+
+ $this->load_answer();
+ }
+
+
+ /**
+ * See if there is already an entry for the current session.
+ */
+ function load_confirm_id()
+ {
+ global $db, $user;
+
+ $sql = 'SELECT confirm_id
+ FROM ' . $this->table_qa_confirm . "
+ WHERE
+ session_id = '" . $db->sql_escape($user->session_id) . "'
+ AND lang_iso = '" . $db->sql_escape($this->question_lang) . "'
+ AND confirm_type = " . $this->type;
+ $result = $db->sql_query_limit($sql, 1);
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ if ($row)
+ {
+ $this->confirm_id = $row['confirm_id'];
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Look up everything we need and populate the instance variables.
+ */
+ function load_answer()
+ {
+ global $db, $user;
+
+ if (!strlen($this->confirm_id) || !sizeof($this->question_ids))
+ {
+ return false;
+ }
+
+ $sql = 'SELECT con.question_id, attempts, question_text, strict
+ FROM ' . $this->table_qa_confirm . ' con, ' . $this->table_captcha_questions . " qes
+ WHERE con.question_id = qes.question_id
+ AND confirm_id = '" . $db->sql_escape($this->confirm_id) . "'
+ AND session_id = '" . $db->sql_escape($user->session_id) . "'
+ AND qes.lang_iso = '" . $db->sql_escape($this->question_lang) . "'
+ AND confirm_type = " . $this->type;
+ $result = $db->sql_query($sql);
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ if ($row)
+ {
+ $this->question = $row['question_id'];
+
+ $this->attempts = $row['attempts'];
+ $this->question_strict = $row['strict'];
+ $this->question_text = $row['question_text'];
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * The actual validation
+ */
+ function check_answer()
+ {
+ global $db;
+
+ $answer = ($this->question_strict) ? utf8_normalize_nfc(request_var('qa_answer', '', true)) : utf8_clean_string(utf8_normalize_nfc(request_var('qa_answer', '', true)));
+
+ $sql = 'SELECT answer_text
+ FROM ' . $this->table_captcha_answers . '
+ WHERE question_id = ' . (int) $this->question;
+ $result = $db->sql_query($sql);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $solution = ($this->question_strict) ? $row['answer_text'] : utf8_clean_string($row['answer_text']);
+
+ if ($solution === $answer)
+ {
+ $this->solved = true;
+
+ break;
+ }
+ }
+ $db->sql_freeresult($result);
+
+ return $this->solved;
+ }
+
+ /**
+ * API function
+ */
+ function get_attempt_count()
+ {
+ return $this->attempts;
+ }
+
+ /**
+ * API function
+ */
+ function reset()
+ {
+ global $db, $user;
+
+ $sql = 'DELETE FROM ' . $this->table_qa_confirm . "
+ WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
+ AND confirm_type = " . (int) $this->type;
+ $db->sql_query($sql);
+
+ // we leave the class usable by generating a new question
+ $this->select_question();
+ }
+
+ /**
+ * API function
+ */
+ function is_solved()
+ {
+ if (request_var('qa_answer', false) && $this->solved === 0)
+ {
+ $this->validate();
+ }
+
+ return (bool) $this->solved;
+ }
+
+ /**
+ * API function - The ACP backend, this marks the end of the easy methods
+ */
+ function acp_page($id, &$module)
+ {
+ global $db, $user, $auth, $template;
+ global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
+
+ $user->add_lang('acp/board');
+ $user->add_lang('captcha_qa');
+
+ if (!self::is_installed())
+ {
+ $this->install();
+ }
+
+ $module->tpl_name = 'captcha_qa_acp';
+ $module->page_title = 'ACP_VC_SETTINGS';
+ $form_key = 'acp_captcha';
+ add_form_key($form_key);
+
+ $submit = request_var('submit', false);
+ $question_id = request_var('question_id', 0);
+ $action = request_var('action', '');
+
+ // we have two pages, so users might want to navigate from one to the other
+ $list_url = $module->u_action . "&amp;configure=1&amp;select_captcha=" . $this->get_service_name();
+
+ $template->assign_vars(array(
+ 'U_ACTION' => $module->u_action,
+ 'QUESTION_ID' => $question_id ,
+ 'CLASS' => $this->get_service_name(),
+ ));
+
+ // show the list?
+ if (!$question_id && $action != 'add')
+ {
+ $this->acp_question_list($module);
+ }
+ else if ($question_id && $action == 'delete')
+ {
+ if ($this->get_service_name() !== $config['captcha_plugin'] || !$this->acp_is_last($question_id))
+ {
+ if (confirm_box(true))
+ {
+ $this->acp_delete_question($question_id);
+
+ trigger_error($user->lang['QUESTION_DELETED'] . adm_back_link($list_url));
+ }
+ else
+ {
+ confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
+ 'question_id' => $question_id,
+ 'action' => $action,
+ 'configure' => 1,
+ 'select_captcha' => $this->get_service_name(),
+ ))
+ );
+ }
+ }
+ else
+ {
+ trigger_error($user->lang['QA_LAST_QUESTION'] . adm_back_link($list_url), E_USER_WARNING);
+ }
+ }
+ else
+ {
+ // okay, show the editor
+ $error = false;
+ $input_question = request_var('question_text', '', true);
+ $input_answers = request_var('answers', '', true);
+ $input_lang = request_var('lang_iso', '', true);
+ $input_strict = request_var('strict', false);
+ $langs = $this->get_languages();
+
+ foreach ($langs as $lang => $entry)
+ {
+ $template->assign_block_vars('langs', array(
+ 'ISO' => $lang,
+ 'NAME' => $entry['name'],
+ ));
+ }
+
+ $template->assign_vars(array(
+ 'U_LIST' => $list_url,
+ ));
+
+ if ($question_id)
+ {
+ if ($question = $this->acp_get_question_data($question_id))
+ {
+ $answers = (isset($input_answers[$lang])) ? $input_answers[$lang] : implode("\n", $question['answers']);
+
+ $template->assign_vars(array(
+ 'QUESTION_TEXT' => ($input_question) ? $input_question : $question['question_text'],
+ 'LANG_ISO' => ($input_lang) ? $input_lang : $question['lang_iso'],
+ 'STRICT' => (isset($_REQUEST['strict'])) ? $input_strict : $question['strict'],
+ 'ANSWERS' => $answers,
+ ));
+ }
+ else
+ {
+ trigger_error($user->lang['FORM_INVALID'] . adm_back_link($list_url));
+ }
+ }
+ else
+ {
+ $template->assign_vars(array(
+ 'QUESTION_TEXT' => $input_question,
+ 'LANG_ISO' => $input_lang,
+ 'STRICT' => $input_strict,
+ 'ANSWERS' => $input_answers,
+ ));
+ }
+
+ if ($submit && check_form_key($form_key))
+ {
+ $data = $this->acp_get_question_input();
+
+ if (!$this->validate_input($data))
+ {
+ $template->assign_vars(array(
+ 'S_ERROR' => true,
+ ));
+ }
+ else
+ {
+ if ($question_id)
+ {
+ $this->acp_update_question($data, $question_id);
+ }
+ else
+ {
+ $this->acp_add_question($data);
+ }
+
+ add_log('admin', 'LOG_CONFIG_VISUAL');
+ trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($list_url));
+ }
+ }
+ else if ($submit)
+ {
+ trigger_error($user->lang['FORM_INVALID'] . adm_back_link($list_url), E_USER_WARNING);
+ }
+ }
+ }
+
+ /**
+ * This handles the list overview
+ */
+ function acp_question_list(&$module)
+ {
+ global $db, $template;
+
+ $sql = 'SELECT *
+ FROM ' . $this->table_captcha_questions;
+ $result = $db->sql_query($sql);
+
+ $template->assign_vars(array(
+ 'S_LIST' => true,
+ ));
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $url = $module->u_action . "&amp;question_id={$row['question_id']}&amp;configure=1&amp;select_captcha=" . $this->get_service_name() . '&amp;';
+
+ $template->assign_block_vars('questions', array(
+ 'QUESTION_TEXT' => $row['question_text'],
+ 'QUESTION_ID' => $row['question_id'],
+ 'QUESTION_LANG' => $row['lang_iso'],
+ 'U_DELETE' => "{$url}action=delete",
+ 'U_EDIT' => "{$url}action=edit",
+ ));
+ }
+ $db->sql_freeresult($result);
+ }
+
+ /**
+ * Grab a question and bring it into a format the editor understands
+ */
+ function acp_get_question_data($question_id)
+ {
+ global $db;
+
+ if ($question_id)
+ {
+ $sql = 'SELECT *
+ FROM ' . $this->table_captcha_questions . '
+ WHERE question_id = ' . $question_id;
+ $result = $db->sql_query($sql);
+ $question = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ if (!$question)
+ {
+ return false;
+ }
+
+ $question['answers'] = array();
+
+ $sql = 'SELECT *
+ FROM ' . $this->table_captcha_answers . '
+ WHERE question_id = ' . $question_id;
+ $result = $db->sql_query($sql);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $question['answers'][] = $row['answer_text'];
+ }
+ $db->sql_freeresult($result);
+
+ return $question;
+ }
+ }
+
+ /**
+ * Grab a question from input and bring it into a format the editor understands
+ */
+ function acp_get_question_input()
+ {
+ $answers = utf8_normalize_nfc(request_var('answers', '', true));
+ $question = array(
+ 'question_text' => request_var('question_text', '', true),
+ 'strict' => request_var('strict', false),
+ 'lang_iso' => request_var('lang_iso', ''),
+ 'answers' => (strlen($answers)) ? explode("\n", $answers) : '',
+ );
+
+ return $question;
+ }
+
+ /**
+ * Update a question.
+ * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data
+ */
+ function acp_update_question($data, $question_id)
+ {
+ global $db, $cache;
+
+ // easier to delete all answers than to figure out which to update
+ $sql = 'DELETE FROM ' . $this->table_captcha_answers . " WHERE question_id = $question_id";
+ $db->sql_query($sql);
+
+ $langs = $this->get_languages();
+ $question_ary = $data;
+ $question_ary['lang_id'] = $langs[$question_ary['lang_iso']]['id'];
+ unset($question_ary['answers']);
+
+ $sql = 'UPDATE ' . $this->table_captcha_questions . '
+ SET ' . $db->sql_build_array('UPDATE', $question_ary) . "
+ WHERE question_id = $question_id";
+ $db->sql_query($sql);
+
+ $this->acp_insert_answers($data, $question_id);
+
+ $cache->destroy('sql', $this->table_captcha_questions);
+ }
+
+ /**
+ * Insert a question.
+ * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data
+ */
+ function acp_add_question($data)
+ {
+ global $db, $cache;
+
+ $langs = $this->get_languages();
+ $question_ary = $data;
+
+ $question_ary['lang_id'] = $langs[$data['lang_iso']]['id'];
+ unset($question_ary['answers']);
+
+ $sql = 'INSERT INTO ' . $this->table_captcha_questions . ' ' . $db->sql_build_array('INSERT', $question_ary);
+ $db->sql_query($sql);
+
+ $question_id = $db->sql_nextid();
+
+ $this->acp_insert_answers($data, $question_id);
+
+ $cache->destroy('sql', $this->table_captcha_questions);
+ }
+
+ /**
+ * Insert the answers.
+ * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data
+ */
+ function acp_insert_answers($data, $question_id)
+ {
+ global $db, $cache;
+
+ foreach ($data['answers'] as $answer)
+ {
+ $answer_ary = array(
+ 'question_id' => $question_id,
+ 'answer_text' => $answer,
+ );
+
+ $sql = 'INSERT INTO ' . $this->table_captcha_answers . ' ' . $db->sql_build_array('INSERT', $answer_ary);
+ $db->sql_query($sql);
+ }
+
+ $cache->destroy('sql', $this->table_captcha_answers);
+ }
+
+ /**
+ * Delete a question.
+ */
+ function acp_delete_question($question_id)
+ {
+ global $db, $cache;
+
+ $tables = array($this->table_captcha_questions, $this->table_captcha_answers);
+
+ foreach ($tables as $table)
+ {
+ $sql = "DELETE FROM $table
+ WHERE question_id = $question_id";
+ $db->sql_query($sql);
+ }
+
+ $cache->destroy('sql', $tables);
+ }
+
+ /**
+ * Check if the entered data can be inserted/used
+ * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data
+ */
+ function validate_input($question_data)
+ {
+ $langs = $this->get_languages();
+
+ if (!isset($question_data['lang_iso']) ||
+ !isset($question_data['question_text']) ||
+ !isset($question_data['strict']) ||
+ !isset($question_data['answers']))
+ {
+ return false;
+ }
+
+ if (!isset($langs[$question_data['lang_iso']]) ||
+ !strlen($question_data['question_text']) ||
+ !sizeof($question_data['answers']) ||
+ !is_array($question_data['answers']))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * List the installed language packs
+ */
+ function get_languages()
+ {
+ global $db;
+
+ $sql = 'SELECT *
+ FROM ' . LANG_TABLE;
+ $result = $db->sql_query($sql);
+
+ $langs = array();
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $langs[$row['lang_iso']] = array(
+ 'name' => $row['lang_local_name'],
+ 'id' => (int) $row['lang_id'],
+ );
+ }
+ $db->sql_freeresult($result);
+
+ return $langs;
+ }
+
+
+
+ /**
+ * See if there is a question other than the one we have
+ */
+ function acp_is_last($question_id)
+ {
+ global $config, $db;
+
+ if ($question_id)
+ {
+ $sql = 'SELECT question_id
+ FROM ' . $this->table_captcha_questions . "
+ WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'
+ AND question_id <> " . (int) $question_id;
+ $result = $db->sql_query_limit($sql, 1);
+ $question = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ if (!$question)
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/phpBB/phpbb/captcha/plugins/recaptcha.php b/phpBB/phpbb/captcha/plugins/recaptcha.php
new file mode 100644
index 0000000000..ea446d7bc3
--- /dev/null
+++ b/phpBB/phpbb/captcha/plugins/recaptcha.php
@@ -0,0 +1,330 @@
+<?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\captcha\plugins;
+
+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;
+
+ // PHP4 Constructor
+ function phpbb_recaptcha()
+ {
+ global $request;
+ $this->recaptcha_server = $request->is_secure() ? $this->recaptcha_server_secure : $this->recaptcha_server;
+ }
+
+ function init($type)
+ {
+ global $config, $db, $user;
+
+ $user->add_lang('captcha_recaptcha');
+ parent::init($type);
+ $this->challenge = request_var('recaptcha_challenge_field', '');
+ $this->response = request_var('recaptcha_response_field', '');
+ }
+
+ public function is_available()
+ {
+ global $config, $user;
+ $user->add_lang('captcha_recaptcha');
+ return (isset($config['recaptcha_pubkey']) && !empty($config['recaptcha_pubkey']));
+ }
+
+ /**
+ * API function
+ */
+ function has_config()
+ {
+ return true;
+ }
+
+ static public function get_name()
+ {
+ return 'CAPTCHA_RECAPTCHA';
+ }
+
+ /**
+ * This function is implemented because required by the upper class, but is never used for reCaptcha.
+ */
+ function get_generator_class()
+ {
+ throw new \Exception('No generator class given.');
+ }
+
+ function acp_page($id, &$module)
+ {
+ global $config, $db, $template, $user;
+
+ $captcha_vars = array(
+ 'recaptcha_pubkey' => 'RECAPTCHA_PUBKEY',
+ 'recaptcha_privkey' => 'RECAPTCHA_PRIVKEY',
+ );
+
+ $module->tpl_name = 'captcha_recaptcha_acp';
+ $module->page_title = 'ACP_VC_SETTINGS';
+ $form_key = 'acp_captcha';
+ add_form_key($form_key);
+
+ $submit = request_var('submit', '');
+
+ if ($submit && check_form_key($form_key))
+ {
+ $captcha_vars = array_keys($captcha_vars);
+ foreach ($captcha_vars as $captcha_var)
+ {
+ $value = request_var($captcha_var, '');
+ if ($value)
+ {
+ set_config($captcha_var, $value);
+ }
+ }
+
+ add_log('admin', 'LOG_CONFIG_VISUAL');
+ trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action));
+ }
+ else if ($submit)
+ {
+ trigger_error($user->lang['FORM_INVALID'] . adm_back_link($module->u_action));
+ }
+ else
+ {
+ foreach ($captcha_vars as $captcha_var => $template_var)
+ {
+ $var = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, '') : ((isset($config[$captcha_var])) ? $config[$captcha_var] : '');
+ $template->assign_var($template_var, $var);
+ }
+
+ $template->assign_vars(array(
+ 'CAPTCHA_PREVIEW' => $this->get_demo_template($id),
+ 'CAPTCHA_NAME' => $this->get_service_name(),
+ 'U_ACTION' => $module->u_action,
+ ));
+
+ }
+ }
+
+ // not needed
+ function execute_demo()
+ {
+ }
+
+ // not needed
+ function execute()
+ {
+ }
+
+ function get_template()
+ {
+ global $config, $user, $template, $phpbb_root_path, $phpEx;
+
+ if ($this->is_solved())
+ {
+ return false;
+ }
+ else
+ {
+ $contact_link = phpbb_get_board_contact_link($config, $phpbb_root_path, $phpEx);
+ $explain = $user->lang(($this->type != CONFIRM_POST) ? 'CONFIRM_EXPLAIN' : 'POST_CONFIRM_EXPLAIN', '<a href="' . $contact_link . '">', '</a>');
+
+ $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,
+ 'L_CONFIRM_EXPLAIN' => $explain,
+ ));
+
+ return 'captcha_recaptcha.html';
+ }
+ }
+
+ function get_demo_template($id)
+ {
+ return $this->get_template();
+ }
+
+ function get_hidden_fields()
+ {
+ $hidden_fields = array();
+
+ // this is required for posting.php - otherwise we would forget about the captcha being already solved
+ if ($this->solved)
+ {
+ $hidden_fields['confirm_code'] = $this->code;
+ }
+ $hidden_fields['confirm_id'] = $this->confirm_id;
+ return $hidden_fields;
+ }
+
+ function uninstall()
+ {
+ $this->garbage_collect(0);
+ }
+
+ function install()
+ {
+ return;
+ }
+
+ function validate()
+ {
+ if (!parent::validate())
+ {
+ return false;
+ }
+ else
+ {
+ return $this->recaptcha_check_answer();
+ }
+ }
+
+// 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
+ */
+ function recaptcha_check_answer($extra_params = array())
+ {
+ global $config, $user;
+
+ //discard spam submissions
+ if ($this->challenge == null || strlen($this->challenge) == 0 || $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]);
+
+ if (trim($answers[0]) === 'true')
+ {
+ $this->solved = true;
+ return false;
+ }
+ else
+ {
+ 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/class_loader.php b/phpBB/phpbb/class_loader.php
index ee9767148b..cfdcc2af0b 100644
--- a/phpBB/phpbb/class_loader.php
+++ b/phpBB/phpbb/class_loader.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -19,8 +23,6 @@ namespace phpbb;
*
* If every part of the class name is a directory, the last directory name is
* also used as the filename, e.g. phpbb_dir would resolve to dir/dir.php.
-*
-* @package phpBB3
*/
class class_loader
{
diff --git a/phpBB/phpbb/composer.json b/phpBB/phpbb/composer.json
new file mode 100644
index 0000000000..513d7e4559
--- /dev/null
+++ b/phpBB/phpbb/composer.json
@@ -0,0 +1,27 @@
+{
+ "name": "phpbb/phpbb-core",
+ "description": "Collection of core phpBB libraries",
+ "type": "library",
+ "keywords": ["phpbb", "forum"],
+ "homepage": "https://www.phpbb.com",
+ "license": "GPL-2.0",
+ "authors": [
+ {
+ "name": "phpBB Limited",
+ "email": "operations@phpbb.com",
+ "homepage": "https://www.phpbb.com/go/authors"
+ }
+ ],
+ "support": {
+ "issues": "https://tracker.phpbb.com",
+ "forum": "https://www.phpbb.com/community/",
+ "wiki": "https://wiki.phpbb.com",
+ "irc": "irc://irc.freenode.org/phpbb"
+ },
+ "autoload": {
+ "classmap": [""]
+ },
+ "require": {
+ "php": ">=5.3.3"
+ }
+}
diff --git a/phpBB/phpbb/config/config.php b/phpBB/phpbb/config/config.php
index d37922acf1..aaad333006 100644
--- a/phpBB/phpbb/config/config.php
+++ b/phpBB/phpbb/config/config.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\config;
/**
* Configuration container class
-* @package phpBB3
*/
class config implements \ArrayAccess, \IteratorAggregate, \Countable
{
@@ -34,7 +37,7 @@ class config implements \ArrayAccess, \IteratorAggregate, \Countable
/**
* Retrieves an ArrayIterator over the configuration values.
*
- * @return ArrayIterator An iterator over all config data
+ * @return \ArrayIterator An iterator over all config data
*/
public function getIterator()
{
diff --git a/phpBB/phpbb/config/db.php b/phpBB/phpbb/config/db.php
index c1a3630a14..ef20ebf62a 100644
--- a/phpBB/phpbb/config/db.php
+++ b/phpBB/phpbb/config/db.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\config;
/**
* Configuration container class
-* @package phpBB3
*/
class db extends \phpbb\config\config
{
@@ -23,7 +26,7 @@ class db extends \phpbb\config\config
/**
* Database connection
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -36,11 +39,11 @@ class db extends \phpbb\config\config
/**
* Creates a configuration container with a default set of values
*
- * @param \phpbb\db\driver\driver $db Database connection
+ * @param \phpbb\db\driver\driver_interface $db Database connection
* @param \phpbb\cache\driver\driver_interface $cache Cache instance
* @param string $table Configuration table name
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, $table)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $table)
{
$this->db = $db;
$this->cache = $cache;
diff --git a/phpBB/phpbb/config/db_text.php b/phpBB/phpbb/config/db_text.php
index b1ea112b53..b1e3ef5da4 100644
--- a/phpBB/phpbb/config/db_text.php
+++ b/phpBB/phpbb/config/db_text.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,14 +17,12 @@ namespace phpbb\config;
* Manages configuration options with an arbitrary length value stored in a TEXT
* column. In constrast to class \phpbb\config\db, values are never cached and
* prefetched, but every get operation sends a query to the database.
-*
-* @package phpBB3
*/
class db_text
{
/**
* Database connection
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -31,10 +33,10 @@ class db_text
protected $table;
/**
- * @param \phpbb\db\driver\driver $db Database connection
+ * @param \phpbb\db\driver\driver_interface $db Database connection
* @param string $table Table name
*/
- public function __construct(\phpbb\db\driver\driver $db, $table)
+ public function __construct(\phpbb\db\driver\driver_interface $db, $table)
{
$this->db = $db;
$this->table = $this->db->sql_escape($table);
@@ -103,8 +105,8 @@ class db_text
if (!$this->db->sql_affectedrows($result))
{
$sql = 'INSERT INTO ' . $this->table . ' ' . $this->db->sql_build_array('INSERT', array(
- 'config_name' => $key,
- 'config_value' => $value,
+ 'config_name' => (string) $key,
+ 'config_value' => (string) $value,
));
$this->db->sql_query($sql);
}
diff --git a/phpBB/phpbb/config_php_file.php b/phpBB/phpbb/config_php_file.php
new file mode 100644
index 0000000000..7445e7df22
--- /dev/null
+++ b/phpBB/phpbb/config_php_file.php
@@ -0,0 +1,160 @@
+<?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;
+
+class config_php_file
+{
+ /** @var string phpBB Root Path */
+ protected $phpbb_root_path;
+
+ /** @var string php file extension */
+ protected $php_ext;
+
+ /**
+ * Indicates whether the php config file has been loaded.
+ *
+ * @var bool
+ */
+ protected $config_loaded = false;
+
+ /**
+ * The content of the php config file
+ *
+ * @var array
+ */
+ protected $config_data = array();
+
+ /**
+ * The path to the config file. (Default: $phpbb_root_path . 'config.' . $php_ext)
+ *
+ * @var string
+ */
+ protected $config_file;
+
+ private $defined_vars;
+
+ /**
+ * Constructor
+ *
+ * @param string $phpbb_root_path phpBB Root Path
+ * @param string $php_ext php file extension
+ */
+ function __construct($phpbb_root_path, $php_ext)
+ {
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ $this->config_file = $this->phpbb_root_path . 'config.' . $this->php_ext;
+ }
+
+ /**
+ * Set the path to the config file.
+ *
+ * @param string $config_file
+ */
+ public function set_config_file($config_file)
+ {
+ $this->config_file = $config_file;
+ $this->config_loaded = false;
+ }
+
+ /**
+ * Returns an associative array containing the variables defined by the config file.
+ *
+ * @return array Return the content of the config file or an empty array if the file does not exists.
+ */
+ public function get_all()
+ {
+ $this->load_config_file();
+
+ return $this->config_data;
+ }
+
+ /**
+ * Return the value of a variable defined into the config.php file or null if the variable does not exist.
+ *
+ * @param string $variable The name of the variable
+ * @return mixed Value of the variable or null if the variable is not defined.
+ */
+ public function get($variable)
+ {
+ $this->load_config_file();
+
+ return isset($this->config_data[$variable]) ? $this->config_data[$variable] : null;
+ }
+
+ /**
+ * Load the config file and store the information.
+ *
+ * @return null
+ */
+ protected function load_config_file()
+ {
+ if (!$this->config_loaded && file_exists($this->config_file))
+ {
+ $this->defined_vars = get_defined_vars();
+
+ require($this->config_file);
+ $this->config_data = array_diff_key(get_defined_vars(), $this->defined_vars);
+
+ $this->config_loaded = true;
+ }
+ }
+
+ /**
+ * Convert either 3.0 dbms or 3.1 db driver class name to 3.1 db driver class name.
+ *
+ * If $dbms is a valid 3.1 db driver class name, returns it unchanged.
+ * Otherwise prepends phpbb\db\driver\ to the dbms to convert a 3.0 dbms
+ * to 3.1 db driver class name.
+ *
+ * @param string $dbms dbms parameter
+ * @return string driver class
+ * @throws \RuntimeException
+ */
+ public function convert_30_dbms_to_31($dbms)
+ {
+ // Note: this check is done first because mysqli extension
+ // supplies a mysqli class, and class_exists($dbms) would return
+ // true for mysqli class.
+ // However, per the docblock any valid 3.1 driver name should be
+ // recognized by this function, and have priority over 3.0 dbms.
+ if (strpos($dbms, 'phpbb\db\driver') === false && class_exists('phpbb\db\driver\\' . $dbms))
+ {
+ return 'phpbb\db\driver\\' . $dbms;
+ }
+
+ if (class_exists($dbms))
+ {
+ // Additionally we could check that $dbms extends phpbb\db\driver\driver.
+ // http://php.net/manual/en/class.reflectionclass.php
+ // Beware of possible performance issues:
+ // http://stackoverflow.com/questions/294582/php-5-reflection-api-performance
+ // We could check for interface implementation in all paths or
+ // only when we do not prepend phpbb\db\driver\.
+
+ /*
+ $reflection = new \ReflectionClass($dbms);
+
+ if ($reflection->isSubclassOf('phpbb\db\driver\driver'))
+ {
+ return $dbms;
+ }
+ */
+
+ return $dbms;
+ }
+
+ throw new \RuntimeException("You have specified an invalid dbms driver: $dbms");
+ }
+}
diff --git a/phpBB/phpbb/console/application.php b/phpBB/phpbb/console/application.php
index fdcd9d42f6..bc4897af18 100644
--- a/phpBB/phpbb/console/application.php
+++ b/phpBB/phpbb/console/application.php
@@ -1,23 +1,120 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console;
-use Symfony\Component\DependencyInjection\TaggedContainerInterface;
+use Symfony\Component\Console\Shell;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
class application extends \Symfony\Component\Console\Application
{
- function register_container_commands(TaggedContainerInterface $container, $tag = 'console.command')
+ /**
+ * @var bool Indicates whether or not we are in a shell
+ */
+ protected $in_shell = false;
+
+ /**
+ * @var \phpbb\user User object
+ */
+ protected $user;
+
+ /**
+ * @param string $name The name of the application
+ * @param string $version The version of the application
+ * @param \phpbb\user $user The user which runs the application (used for translation)
+ */
+ public function __construct($name, $version, \phpbb\user $user)
+ {
+ $this->user = $user;
+
+ parent::__construct($name, $version);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getDefaultInputDefinition()
{
- foreach($container->findTaggedServiceIds($tag) as $id => $void)
+ $input_definition = parent::getDefaultInputDefinition();
+
+ $input_definition->addOption(new InputOption(
+ 'safe-mode',
+ null,
+ InputOption::VALUE_NONE,
+ $this->user->lang('CLI_DESCRIPTION_OPTION_SAFE_MODE')
+ ));
+
+ return $input_definition;
+ }
+
+ /**
+ * Gets the help message.
+ *
+ * It's a hack of the default help message to display the --shell
+ * option only for the application and not for all the commands.
+ *
+ * @return string A help message.
+ */
+ public function getHelp()
+ {
+ // If we are already in a shell
+ // we do not want to have the --shell option available
+ if ($this->in_shell)
{
- $this->add($container->get($id));
+ return parent::getHelp();
}
+
+ $this->getDefinition()->addOption(new InputOption(
+ '--shell',
+ '-s',
+ InputOption::VALUE_NONE,
+ $this->user->lang('CLI_DESCRIPTION_OPTION_SHELL')
+ ));
+
+ return parent::getHelp();
+ }
+
+ /**
+ * Register a set of commands from the container
+ *
+ * @param \phpbb\di\service_collection $command_collection The console service collection
+ */
+ public function register_container_commands(\phpbb\di\service_collection $command_collection)
+ {
+ foreach ($command_collection as $service_command)
+ {
+ $this->add($service_command);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function doRun(InputInterface $input, OutputInterface $output)
+ {
+ // Run a shell if the --shell (or -s) option is set and if no command name is specified
+ // Also, we do not want to have the --shell option available if we are already in a shell
+ if (!$this->in_shell && $this->getCommandName($input) === null && $input->hasParameterOption(array('--shell', '-s')))
+ {
+ $shell = new Shell($this);
+ $this->in_shell = true;
+ $shell->run();
+
+ return 0;
+ }
+
+ return parent::doRun($input, $output);
}
}
diff --git a/phpBB/phpbb/console/command/cache/purge.php b/phpBB/phpbb/console/command/cache/purge.php
new file mode 100644
index 0000000000..d0c2ef6f72
--- /dev/null
+++ b/phpBB/phpbb/console/command/cache/purge.php
@@ -0,0 +1,89 @@
+<?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\console\command\cache;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class purge extends \phpbb\console\command\command
+{
+ /** @var \phpbb\cache\driver\driver_interface */
+ protected $cache;
+
+ /** @var \phpbb\db\driver\driver_interface */
+ protected $db;
+
+ /** @var \phpbb\auth\auth */
+ protected $auth;
+
+ /** @var \phpbb\log\log_interface */
+ protected $log;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\user $user User instance
+ * @param \phpbb\cache\driver\driver_interface $cache Cache instance
+ * @param \phpbb\db\driver\driver_interface $db Database connection
+ * @param \phpbb\auth\auth $auth Auth instance
+ * @param \phpbb\log\log $log Logger instance
+ * @param \phpbb\config\config $config Config instance
+ */
+ public function __construct(\phpbb\user $user, \phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\auth\auth $auth, \phpbb\log\log_interface $log, \phpbb\config\config $config)
+ {
+ $this->cache = $cache;
+ $this->db = $db;
+ $this->auth = $auth;
+ $this->log = $log;
+ $this->config = $config;
+ parent::__construct($user);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('cache:purge')
+ ->setDescription($this->user->lang('PURGE_CACHE'))
+ ;
+ }
+
+ /**
+ * Executes the command cache:purge.
+ *
+ * Purge the cache (including permissions) and increment the asset_version number
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return null
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->config->increment('assets_version', 1);
+ $this->cache->purge();
+
+ // Clear permissions
+ $this->auth->acl_clear_prefetch();
+ phpbb_cache_moderators($this->db, $this->cache, $this->auth);
+
+ $this->log->add('admin', ANONYMOUS, '', 'LOG_PURGE_CACHE', time(), array());
+
+ $output->writeln($this->user->lang('PURGE_CACHE_SUCCESS'));
+ }
+}
diff --git a/phpBB/phpbb/console/command/command.php b/phpBB/phpbb/console/command/command.php
index 6abbdd203c..638c989da2 100644
--- a/phpBB/phpbb/console/command/command.php
+++ b/phpBB/phpbb/console/command/command.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,4 +15,17 @@ namespace phpbb\console\command;
abstract class command extends \Symfony\Component\Console\Command\Command
{
+ /** @var \phpbb\user */
+ protected $user;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\user $user User instance (mostly for translation)
+ */
+ public function __construct(\phpbb\user $user)
+ {
+ $this->user = $user;
+ parent::__construct();
+ }
}
diff --git a/phpBB/phpbb/console/command/config/command.php b/phpBB/phpbb/console/command/config/command.php
index b105bc826d..f0ad5d4d19 100644
--- a/phpBB/phpbb/console/command/config/command.php
+++ b/phpBB/phpbb/console/command/config/command.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\config;
@@ -13,10 +17,10 @@ abstract class command extends \phpbb\console\command\command
/** @var \phpbb\config\config */
protected $config;
- function __construct(\phpbb\config\config $config)
+ function __construct(\phpbb\user $user, \phpbb\config\config $config)
{
$this->config = $config;
- parent::__construct();
+ parent::__construct($user);
}
}
diff --git a/phpBB/phpbb/console/command/config/delete.php b/phpBB/phpbb/console/command/config/delete.php
index 9a2d00561d..efd276d7e3 100644
--- a/phpBB/phpbb/console/command/config/delete.php
+++ b/phpBB/phpbb/console/command/config/delete.php
@@ -1,33 +1,50 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\config;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class delete extends command
{
+ /**
+ * {@inheritdoc}
+ */
protected function configure()
{
$this
->setName('config:delete')
- ->setDescription('Deletes a configuration option')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_DELETE_CONFIG'))
->addArgument(
'key',
InputArgument::REQUIRED,
- "The configuration option's name"
+ $this->user->lang('CLI_CONFIG_OPTION_NAME')
)
;
}
+ /**
+ * Executes the command config:delete.
+ *
+ * Removes a configuration option
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return null
+ * @see \phpbb\config\config::delete()
+ */
protected function execute(InputInterface $input, OutputInterface $output)
{
$key = $input->getArgument('key');
@@ -36,11 +53,11 @@ class delete extends command
{
$this->config->delete($key);
- $output->writeln("<info>Successfully deleted config $key</info>");
+ $output->writeln('<info>' . $this->user->lang('CLI_CONFIG_DELETE_SUCCESS', $key) . '</info>');
}
else
{
- $output->writeln("<error>Config $key does not exist</error>");
+ $output->writeln('<error>' . $this->user->lang('CLI_CONFIG_NOT_EXISTS', $key) . '</error>');
}
}
}
diff --git a/phpBB/phpbb/console/command/config/get.php b/phpBB/phpbb/console/command/config/get.php
index 275c82b53f..9c03b49a3d 100644
--- a/phpBB/phpbb/console/command/config/get.php
+++ b/phpBB/phpbb/console/command/config/get.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\config;
@@ -15,25 +19,39 @@ use Symfony\Component\Console\Output\OutputInterface;
class get extends command
{
+ /**
+ * {@inheritdoc}
+ */
protected function configure()
{
$this
->setName('config:get')
- ->setDescription("Gets a configuration option's value")
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_GET_CONFIG'))
->addArgument(
'key',
InputArgument::REQUIRED,
- "The configuration option's name"
+ $this->user->lang('CLI_CONFIG_OPTION_NAME')
)
->addOption(
'no-newline',
null,
InputOption::VALUE_NONE,
- 'Set this option if the value should be printed without a new line at the end.'
+ $this->user->lang('CLI_CONFIG_PRINT_WITHOUT_NEWLINE')
)
;
}
+ /**
+ * Executes the command config:get.
+ *
+ * Retrieves a configuration value.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return null
+ * @see \phpbb\config\config::offsetGet()
+ */
protected function execute(InputInterface $input, OutputInterface $output)
{
$key = $input->getArgument('key');
@@ -42,13 +60,13 @@ class get extends command
{
$output->write($this->config[$key]);
}
- elseif (isset($this->config[$key]))
+ else if (isset($this->config[$key]))
{
$output->writeln($this->config[$key]);
}
else
{
- $output->writeln("<error>Could not get config $key</error>");
+ $output->writeln('<error>' . $this->user->lang('CLI_CONFIG_NOT_EXISTS', $key) . '</error>');
}
}
}
diff --git a/phpBB/phpbb/console/command/config/increment.php b/phpBB/phpbb/console/command/config/increment.php
index bc6b63c6ff..b4d7438b66 100644
--- a/phpBB/phpbb/console/command/config/increment.php
+++ b/phpBB/phpbb/console/command/config/increment.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\config;
@@ -15,30 +19,44 @@ use Symfony\Component\Console\Output\OutputInterface;
class increment extends command
{
+ /**
+ * {@inheritdoc}
+ */
protected function configure()
{
$this
->setName('config:increment')
- ->setDescription("Increments a configuration option's value")
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_INCREMENT_CONFIG'))
->addArgument(
'key',
InputArgument::REQUIRED,
- "The configuration option's name"
+ $this->user->lang('CLI_CONFIG_OPTION_NAME')
)
->addArgument(
'increment',
InputArgument::REQUIRED,
- 'Amount to increment by'
+ $this->user->lang('CLI_CONFIG_INCREMENT_BY')
)
->addOption(
'dynamic',
'd',
InputOption::VALUE_NONE,
- 'Set this option if the configuration option changes too frequently to be efficiently cached.'
+ $this->user->lang('CLI_CONFIG_CANNOT_CACHED')
)
;
}
+ /**
+ * Executes the command config:increment.
+ *
+ * Increments an integer configuration value.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return null
+ * @see \phpbb\config\config::increment()
+ */
protected function execute(InputInterface $input, OutputInterface $output)
{
$key = $input->getArgument('key');
@@ -47,6 +65,6 @@ class increment extends command
$this->config->increment($key, $increment, $use_cache);
- $output->writeln("<info>Successfully incremented config $key</info>");
+ $output->writeln('<info>' . $this->user->lang('CLI_CONFIG_INCREMENT_SUCCESS', $key) . '</info>');
}
}
diff --git a/phpBB/phpbb/console/command/config/set.php b/phpBB/phpbb/console/command/config/set.php
index 9d471a96ad..695de31013 100644
--- a/phpBB/phpbb/console/command/config/set.php
+++ b/phpBB/phpbb/console/command/config/set.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\config;
@@ -15,30 +19,44 @@ use Symfony\Component\Console\Output\OutputInterface;
class set extends command
{
+ /**
+ * {@inheritdoc}
+ */
protected function configure()
{
$this
->setName('config:set')
- ->setDescription("Sets a configuration option's value")
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_SET_CONFIG'))
->addArgument(
'key',
InputArgument::REQUIRED,
- "The configuration option's name"
+ $this->user->lang('CLI_CONFIG_OPTION_NAME')
)
->addArgument(
'value',
InputArgument::REQUIRED,
- 'New configuration value, use 0 and 1 to specify boolean values'
+ $this->user->lang('CLI_CONFIG_NEW')
)
->addOption(
'dynamic',
'd',
InputOption::VALUE_NONE,
- 'Set this option if the configuration option changes too frequently to be efficiently cached.'
+ $this->user->lang('CLI_CONFIG_CANNOT_CACHED')
)
;
}
+ /**
+ * Executes the command config:set.
+ *
+ * Sets a configuration option's value.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return null
+ * @see \phpbb\config\config::set()
+ */
protected function execute(InputInterface $input, OutputInterface $output)
{
$key = $input->getArgument('key');
@@ -47,6 +65,6 @@ class set extends command
$this->config->set($key, $value, $use_cache);
- $output->writeln("<info>Successfully set config $key</info>");
+ $output->writeln('<info>' . $this->user->lang('CLI_CONFIG_SET_SUCCESS', $key) . '</info>');
}
}
diff --git a/phpBB/phpbb/console/command/config/set_atomic.php b/phpBB/phpbb/console/command/config/set_atomic.php
index 03e7a60210..e8c69a0885 100644
--- a/phpBB/phpbb/console/command/config/set_atomic.php
+++ b/phpBB/phpbb/console/command/config/set_atomic.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\config;
@@ -15,35 +19,50 @@ use Symfony\Component\Console\Output\OutputInterface;
class set_atomic extends command
{
+ /**
+ * {@inheritdoc}
+ */
protected function configure()
{
$this
->setName('config:set-atomic')
- ->setDescription("Sets a configuration option's value only if the old matches the current value.")
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_SET_ATOMIC_CONFIG'))
->addArgument(
'key',
InputArgument::REQUIRED,
- "The configuration option's name"
+ $this->user->lang('CLI_CONFIG_OPTION_NAME')
)
->addArgument(
'old',
InputArgument::REQUIRED,
- 'Current configuration value, use 0 and 1 to specify boolean values'
+ $this->user->lang('CLI_CONFIG_CURRENT')
)
->addArgument(
'new',
InputArgument::REQUIRED,
- 'New configuration value, use 0 and 1 to specify boolean values'
+ $this->user->lang('CLI_CONFIG_NEW')
)
->addOption(
'dynamic',
'd',
InputOption::VALUE_NONE,
- 'Set this option if the configuration option changes too frequently to be efficiently cached.'
+ $this->user->lang('CLI_CONFIG_CANNOT_CACHED')
)
;
}
+ /**
+ * Executes the command config:set-atomic.
+ *
+ * Sets a configuration option's value only if the old_value matches the
+ * current configuration value or the configuration value does not exist yet.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return bool True if the value was changed, false otherwise.
+ * @see \phpbb\config\config::set_atomic()
+ */
protected function execute(InputInterface $input, OutputInterface $output)
{
$key = $input->getArgument('key');
@@ -53,12 +72,12 @@ class set_atomic extends command
if ($this->config->set_atomic($key, $old_value, $new_value, $use_cache))
{
- $output->writeln("<info>Successfully set config $key</info>");
+ $output->writeln('<info>' . $this->user->lang('CLI_CONFIG_SET_SUCCESS', $key) . '</info>');
return 0;
}
else
{
- $output->writeln("<error>Could not set config $key</error>");
+ $output->writeln('<error>' . $this->user->lang('CLI_CONFIG_SET_FAILURE', $key) . '</error>');
return 1;
}
}
diff --git a/phpBB/phpbb/console/command/cron/cron_list.php b/phpBB/phpbb/console/command/cron/cron_list.php
new file mode 100644
index 0000000000..c515fd9e80
--- /dev/null
+++ b/phpBB/phpbb/console/command/cron/cron_list.php
@@ -0,0 +1,111 @@
+<?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\console\command\cron;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class cron_list extends \phpbb\console\command\command
+{
+ /** @var \phpbb\cron\manager */
+ protected $cron_manager;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\user $user User instance
+ * @param \phpbb\cron\manager $cron_manager Cron manager
+ */
+ public function __construct(\phpbb\user $user, \phpbb\cron\manager $cron_manager)
+ {
+ $this->cron_manager = $cron_manager;
+ parent::__construct($user);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('cron:list')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_CRON_LIST'))
+ ;
+ }
+
+ /**
+ * Executes the command cron:list.
+ *
+ * Prints a list of ready and unready cron jobs.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return null
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $tasks = $this->cron_manager->get_tasks();
+
+ if (empty($tasks))
+ {
+ $output->writeln($this->user->lang('CRON_NO_TASKS'));
+ return;
+ }
+
+ $ready_tasks = array();
+ $not_ready_tasks = array();
+ foreach ($tasks as $task)
+ {
+ if ($task->is_ready())
+ {
+ $ready_tasks[] = $task;
+ }
+ else
+ {
+ $not_ready_tasks[] = $task;
+ }
+ }
+
+ if (!empty($ready_tasks))
+ {
+ $output->writeln('<info>' . $this->user->lang('TASKS_READY') . '</info>');
+ $this->print_tasks_names($ready_tasks, $output);
+ }
+
+ if (!empty($ready_tasks) && !empty($not_ready_tasks))
+ {
+ $output->writeln('');
+ }
+
+ if (!empty($not_ready_tasks))
+ {
+ $output->writeln('<info>' . $this->user->lang('TASKS_NOT_READY') . '</info>');
+ $this->print_tasks_names($not_ready_tasks, $output);
+ }
+ }
+
+ /**
+ * Print a list of cron jobs
+ *
+ * @param array $tasks A list of task to display
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ protected function print_tasks_names(array $tasks, OutputInterface $output)
+ {
+ foreach ($tasks as $task)
+ {
+ $output->writeln($task->get_name());
+ }
+ }
+}
diff --git a/phpBB/phpbb/console/command/cron/run.php b/phpBB/phpbb/console/command/cron/run.php
new file mode 100644
index 0000000000..72ad1205ef
--- /dev/null
+++ b/phpBB/phpbb/console/command/cron/run.php
@@ -0,0 +1,171 @@
+<?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\console\command\cron;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class run extends \phpbb\console\command\command
+{
+ /** @var \phpbb\cron\manager */
+ protected $cron_manager;
+
+ /** @var \phpbb\lock\db */
+ protected $lock_db;
+
+ /**
+ * Construct method
+ *
+ * @param \phpbb\user $user The user object (used to get language information)
+ * @param \phpbb\cron\manager $cron_manager The cron manager containing
+ * the cron tasks to be executed.
+ * @param \phpbb\lock\db $lock_db The lock for accessing database.
+ */
+ public function __construct(\phpbb\user $user, \phpbb\cron\manager $cron_manager, \phpbb\lock\db $lock_db)
+ {
+ $this->cron_manager = $cron_manager;
+ $this->lock_db = $lock_db;
+ parent::__construct($user);
+ }
+
+ /**
+ * Sets the command name and description
+ *
+ * @return null
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('cron:run')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_CRON_RUN'))
+ ->addArgument('name', InputArgument::OPTIONAL, $this->user->lang('CLI_DESCRIPTION_CRON_RUN_ARGUMENT_1'))
+ ;
+ }
+
+ /**
+ * Executes the command cron:run.
+ *
+ * Tries to acquire the cron lock, then if no argument has been given runs all ready cron tasks.
+ * If the cron lock can not be obtained, an error message is printed
+ * and the exit status is set to 1.
+ * If the verbose option is specified, each start of a task is printed.
+ * Otherwise there is no output.
+ * If an argument is given to the command, only the task whose name matches the
+ * argument will be started. If verbose option is specified,
+ * an info message containing the name of the task is printed.
+ * If no task matches the argument given, an error message is printed
+ * and the exit status is set to 2.
+ *
+ * @param InputInterface $input The input stream used to get the argument and verboe option.
+ * @param OutputInterface $output The output stream, used for printing verbose-mode and error information.
+ *
+ * @return int 0 if all is ok, 1 if a lock error occured and 2 if no task matching the argument was found.
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ if ($this->lock_db->acquire())
+ {
+ $task_name = $input->getArgument('name');
+ if ($task_name)
+ {
+ $exit_status = $this->run_one($input, $output, $task_name);
+ }
+ else
+ {
+ $exit_status = $this->run_all($input, $output);
+ }
+
+ $this->lock_db->release();
+ return $exit_status;
+ }
+ else
+ {
+ $output->writeln('<error>' . $this->user->lang('CRON_LOCK_ERROR') . '</error>');
+ return 1;
+ }
+ }
+
+ /**
+ * Executes all ready cron tasks.
+ *
+ * If verbose mode is set, an info message will be printed if there is no task to
+ * be run, or else for each starting task.
+ *
+ * @see execute
+ * @param InputInterface $input The input stream used to get the argument and verbose option.
+ * @param OutputInterface $output The output stream, used for printing verbose-mode and error information.
+ * @return int 0
+ */
+ protected function run_all(InputInterface $input, OutputInterface $output)
+ {
+ $run_tasks = $this->cron_manager->find_all_ready_tasks();
+
+ if ($run_tasks)
+ {
+ foreach ($run_tasks as $task)
+ {
+ if ($input->getOption('verbose'))
+ {
+ $output->writeln('<info>' . $this->user->lang('RUNNING_TASK', $task->get_name()) . '</info>');
+ }
+
+ $task->run();
+ }
+ }
+ else
+ {
+ if ($input->getOption('verbose'))
+ {
+ $output->writeln('<info>' . $this->user->lang('CRON_NO_TASK') . '</info>');
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * Executes a given cron task, if it is ready.
+ *
+ * If there is a task whose name matches $task_name, it is run and 0 is returned.
+ * and if verbose mode is set, print an info message with the name of the task.
+ * If there is no task matching $task_name, the function prints an error message
+ * and returns with status 2.
+ *
+ * @see execute
+ * @param string $task_name The name of the task that should be run.
+ * @param InputInterface $input The input stream used to get the argument and verbose option.
+ * @param OutputInterface $output The output stream, used for printing verbose-mode and error information.
+ * @return int 0 if all is well, 2 if no task matches $task_name.
+ */
+ protected function run_one(InputInterface $input, OutputInterface $output, $task_name)
+ {
+ $task = $this->cron_manager->find_task($task_name);
+ if ($task)
+ {
+ if ($input->getOption('verbose'))
+ {
+ $output->writeln('<info>' . $this->user->lang('RUNNING_TASK', $task_name) . '</info>');
+ }
+
+ $task->run();
+ return 0;
+ }
+ else
+ {
+ $output->writeln('<error>' . $this->user->lang('CRON_NO_SUCH_TASK', $task_name) . '</error>');
+ return 2;
+ }
+ }
+}
diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php
new file mode 100644
index 0000000000..c760cde5b5
--- /dev/null
+++ b/phpBB/phpbb/console/command/db/migrate.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\console\command\db;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class migrate extends \phpbb\console\command\command
+{
+ /** @var \phpbb\db\migrator */
+ protected $migrator;
+
+ /** @var \phpbb\extension\manager */
+ protected $extension_manager;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ /** @var \phpbb\cache\service */
+ protected $cache;
+
+ /** @var \phpbb\log\log */
+ protected $log;
+
+ function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log)
+ {
+ $this->migrator = $migrator;
+ $this->extension_manager = $extension_manager;
+ $this->config = $config;
+ $this->cache = $cache;
+ $this->log = $log;
+ parent::__construct($user);
+ $this->user->add_lang(array('common', 'install', 'migrator'));
+ }
+
+ protected function configure()
+ {
+ $this
+ ->setName('db:migrate')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_DB_MIGRATE'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->migrator->create_migrations_table();
+
+ $this->cache->purge();
+
+ $this->load_migrations();
+ $orig_version = $this->config['version'];
+ while (!$this->migrator->finished())
+ {
+ $migration_start_time = microtime(true);
+
+ try
+ {
+ $this->migrator->update();
+ }
+ catch (\phpbb\db\migration\exception $e)
+ {
+ $output->writeln('<error>' . $e->getLocalisedMessage($this->user) . '</error>');
+ $this->finalise_update();
+ return 1;
+ }
+
+ $migration_stop_time = microtime(true) - $migration_start_time;
+
+ $state = array_merge(
+ array(
+ 'migration_schema_done' => false,
+ 'migration_data_done' => false,
+ ),
+ $this->migrator->last_run_migration['state']
+ );
+
+ if (!empty($this->migrator->last_run_migration['effectively_installed']))
+ {
+ $msg = $this->user->lang('MIGRATION_EFFECTIVELY_INSTALLED', $this->migrator->last_run_migration['name']);
+ $output->writeln("<comment>$msg</comment>");
+ }
+ else if ($this->migrator->last_run_migration['task'] == 'process_data_step' && $state['migration_data_done'])
+ {
+ $msg = $this->user->lang('MIGRATION_DATA_DONE', $this->migrator->last_run_migration['name'], $migration_stop_time);
+ $output->writeln("<info>$msg</info>");
+ }
+ else if ($this->migrator->last_run_migration['task'] == 'process_data_step')
+ {
+ $output->writeln($this->user->lang('MIGRATION_DATA_IN_PROGRESS', $this->migrator->last_run_migration['name'], $migration_stop_time));
+ }
+ else if ($state['migration_schema_done'])
+ {
+ $msg = $this->user->lang('MIGRATION_SCHEMA_DONE', $this->migrator->last_run_migration['name'], $migration_stop_time);
+ $output->writeln("<info>$msg</info>");
+ }
+ }
+
+ if ($orig_version != $this->config['version'])
+ {
+ $this->log->add('admin', ANONYMOUS, '', 'LOG_UPDATE_DATABASE', time(), array($orig_version, $this->config['version']));
+ }
+
+ $this->finalise_update();
+ $output->writeln($this->user->lang['DATABASE_UPDATE_COMPLETE']);
+ }
+
+ protected function load_migrations()
+ {
+ $migrations = $this->extension_manager
+ ->get_finder()
+ ->core_path('phpbb/db/migration/data/')
+ ->extension_directory('/migrations')
+ ->get_classes();
+
+ $this->migrator->set_migrations($migrations);
+ }
+
+ protected function finalise_update()
+ {
+ $this->cache->purge();
+ $this->config->increment('assets_version', 1);
+ }
+}
diff --git a/phpBB/phpbb/console/command/dev/migration_tips.php b/phpBB/phpbb/console/command/dev/migration_tips.php
new file mode 100644
index 0000000000..f9047bdac8
--- /dev/null
+++ b/phpBB/phpbb/console/command/dev/migration_tips.php
@@ -0,0 +1,64 @@
+<?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\console\command\dev;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class migration_tips extends \phpbb\console\command\command
+{
+ /** @var \phpbb\extension\manager */
+ protected $extension_manager;
+
+ function __construct(\phpbb\user $user, \phpbb\extension\manager $extension_manager)
+ {
+ $this->extension_manager = $extension_manager;
+ parent::__construct($user);
+ }
+
+ protected function configure()
+ {
+ $this
+ ->setName('dev:migration-tips')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_FIND_MIGRATIONS'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $migrations = $this->extension_manager->get_finder()
+ ->set_extensions(array())
+ ->core_path('phpbb/db/migration/data/')
+ ->get_classes();
+ $tips = $migrations;
+
+ foreach ($migrations as $migration_class)
+ {
+ foreach ($migration_class::depends_on() as $dependency)
+ {
+ $tips_key = array_search($dependency, $tips);
+ if ($tips_key !== false)
+ {
+ unset($tips[$tips_key]);
+ }
+ }
+ }
+
+ $output->writeln("\t\tarray(");
+ foreach ($tips as $migration)
+ {
+ $output->writeln("\t\t\t'{$migration}',");
+ }
+ $output->writeln("\t\t);");
+ }
+}
diff --git a/phpBB/phpbb/console/command/extension/command.php b/phpBB/phpbb/console/command/extension/command.php
index edde7ce2e2..364d954082 100644
--- a/phpBB/phpbb/console/command/extension/command.php
+++ b/phpBB/phpbb/console/command/extension/command.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\extension;
@@ -13,10 +17,14 @@ abstract class command extends \phpbb\console\command\command
/** @var \phpbb\extension\manager */
protected $manager;
- function __construct(\phpbb\extension\manager $manager)
+ /** @var \phpbb\log\log */
+ protected $log;
+
+ public function __construct(\phpbb\user $user, \phpbb\extension\manager $manager, \phpbb\log\log $log)
{
$this->manager = $manager;
+ $this->log = $log;
- parent::__construct();
+ parent::__construct($user);
}
}
diff --git a/phpBB/phpbb/console/command/extension/disable.php b/phpBB/phpbb/console/command/extension/disable.php
index e4de70ca34..1eee16cbd9 100644
--- a/phpBB/phpbb/console/command/extension/disable.php
+++ b/phpBB/phpbb/console/command/extension/disable.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\extension;
@@ -18,11 +22,11 @@ class disable extends command
{
$this
->setName('extension:disable')
- ->setDescription('Disables the specified extension.')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_DISABLE_EXTENSION'))
->addArgument(
'extension-name',
InputArgument::REQUIRED,
- 'Name of the extension'
+ $this->user->lang('CLI_EXTENSION_NAME')
)
;
}
@@ -33,14 +37,15 @@ class disable extends command
$this->manager->disable($name);
$this->manager->load_extensions();
- if ($this->manager->enabled($name))
+ if ($this->manager->is_enabled($name))
{
- $output->writeln("<error>Could not disable extension $name</error>");
+ $output->writeln('<error>' . $this->user->lang('CLI_EXTENSION_DISABLE_FAILURE', $name) . '</error>');
return 1;
}
else
{
- $output->writeln("<info>Successfully disabled extension $name</info>");
+ $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_DISABLE', time(), array($name));
+ $output->writeln('<info>' . $this->user->lang('CLI_EXTENSION_DISABLE_SUCCESS', $name) . '</info>');
return 0;
}
}
diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php
index ee7dae76aa..59ff11e9b7 100644
--- a/phpBB/phpbb/console/command/extension/enable.php
+++ b/phpBB/phpbb/console/command/extension/enable.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\extension;
@@ -18,11 +22,11 @@ class enable extends command
{
$this
->setName('extension:enable')
- ->setDescription('Enables the specified extension.')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_ENABLE_EXTENSION'))
->addArgument(
'extension-name',
InputArgument::REQUIRED,
- 'Name of the extension'
+ $this->user->lang('CLI_EXTENSION_NAME')
)
;
}
@@ -33,14 +37,15 @@ class enable extends command
$this->manager->enable($name);
$this->manager->load_extensions();
- if ($this->manager->enabled($name))
+ if ($this->manager->is_enabled($name))
{
- $output->writeln("<info>Successfully enabled extension $name</info>");
+ $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($name));
+ $output->writeln('<info>' . $this->user->lang('CLI_EXTENSION_ENABLE_SUCCESS', $name) . '</info>');
return 0;
}
else
{
- $output->writeln("<error>Could not enable extension $name</error>");
+ $output->writeln('<error>' . $this->user->lang('CLI_EXTENSION_ENABLE_FAILURE', $name) . '</error>');
return 1;
}
}
diff --git a/phpBB/phpbb/console/command/extension/purge.php b/phpBB/phpbb/console/command/extension/purge.php
index c2e1d2928c..517e9a74c9 100644
--- a/phpBB/phpbb/console/command/extension/purge.php
+++ b/phpBB/phpbb/console/command/extension/purge.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\extension;
@@ -18,11 +22,11 @@ class purge extends command
{
$this
->setName('extension:purge')
- ->setDescription('Purges the specified extension.')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_PURGE_EXTENSION'))
->addArgument(
'extension-name',
InputArgument::REQUIRED,
- 'Name of the extension'
+ $this->user->lang('CLI_EXTENSION_NAME')
)
;
}
@@ -33,14 +37,15 @@ class purge extends command
$this->manager->purge($name);
$this->manager->load_extensions();
- if ($this->manager->enabled($name))
+ if ($this->manager->is_enabled($name))
{
- $output->writeln("<error>Could not purge extension $name</error>");
+ $output->writeln('<error>' . $this->user->lang('CLI_EXTENSION_PURGE_FAILURE', $name) . '</error>');
return 1;
}
else
{
- $output->writeln("<info>Successfully purge extension $name</info>");
+ $this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_PURGE', time(), array($name));
+ $output->writeln('<info>' . $this->user->lang('CLI_EXTENSION_PURGE_SUCCESS', $name) . '</info>');
return 0;
}
}
diff --git a/phpBB/phpbb/console/command/extension/show.php b/phpBB/phpbb/console/command/extension/show.php
index 0f48ac2379..f9322034d7 100644
--- a/phpBB/phpbb/console/command/extension/show.php
+++ b/phpBB/phpbb/console/command/extension/show.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\extension;
@@ -17,7 +21,7 @@ class show extends command
{
$this
->setName('extension:show')
- ->setDescription('Lists all extensions in the database and on the filesystem.')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_LIST_EXTENSIONS'))
;
}
@@ -28,27 +32,27 @@ class show extends command
if (empty($all))
{
- $output->writeln('<comment>No extensions were found.</comment>');
+ $output->writeln('<comment>' . $this->user->lang('CLI_EXTENSION_NOT_FOUND') . '</comment>');
return 3;
}
$enabled = array_keys($this->manager->all_enabled());
- $this->print_extension_list($output, 'Enabled', $enabled);
+ $this->print_extension_list($output, $this->user->lang('CLI_EXTENSIONS_ENABLED') . $this->user->lang('COLON'), $enabled);
$output->writeln('');
$disabled = array_keys($this->manager->all_disabled());
- $this->print_extension_list($output, 'Disabled', $disabled);
+ $this->print_extension_list($output, $this->user->lang('CLI_EXTENSIONS_DISABLED') . $this->user->lang('COLON'), $disabled);
$output->writeln('');
$purged = array_diff($all, $enabled, $disabled);
- $this->print_extension_list($output, 'Available', $purged);
+ $this->print_extension_list($output, $this->user->lang('CLI_EXTENSIONS_AVAILABLE') . $this->user->lang('COLON'), $purged);
}
protected function print_extension_list(OutputInterface $output, $type, array $extensions)
{
- $output->writeln("<info>$type:</info>");
+ $output->writeln("<info>$type</info>");
foreach ($extensions as $extension)
{
diff --git a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
index 04db880091..ec4e1b0ee7 100644
--- a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
+++ b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\console\command\fixup;
@@ -13,21 +17,21 @@ use Symfony\Component\Console\Output\OutputInterface;
class recalculate_email_hash extends \phpbb\console\command\command
{
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
- function __construct(\phpbb\db\driver\driver $db)
+ function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db)
{
$this->db = $db;
- parent::__construct();
+ parent::__construct($user);
}
protected function configure()
{
$this
->setName('fixup:recalculate-email-hash')
- ->setDescription('Recalculates the user_email_hash column of the users table.')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_RECALCULATE_EMAIL_HASH'))
;
}
@@ -66,6 +70,6 @@ class recalculate_email_hash extends \phpbb\console\command\command
}
$this->db->sql_freeresult($result);
- $output->writeln('<info>Successfully recalculated all email hashes.</info>');
+ $output->writeln('<info>' . $this->user->lang('CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS') . '</info>');
}
}
diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php
index f18ee0fd73..8bd537586e 100644
--- a/phpBB/phpbb/content_visibility.php
+++ b/phpBB/phpbb/content_visibility.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpbb
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,13 +16,12 @@ namespace phpbb;
/**
* phpbb_visibility
* Handle fetching and setting the visibility for topics and posts
-* @package phpbb
*/
class content_visibility
{
/**
* Database object
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -35,6 +38,12 @@ class content_visibility
protected $auth;
/**
+ * config object
+ * @var \phpbb\config\config
+ */
+ protected $config;
+
+ /**
* phpBB root path
* @var string
*/
@@ -50,15 +59,20 @@ class content_visibility
* Constructor
*
* @param \phpbb\auth\auth $auth Auth object
- * @param \phpbb\db\driver\driver $db Database object
- * @param \phpbb\user $user User object
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\db\driver\driver_interface $db Database object
+ * @param \phpbb\user $user User object
* @param string $phpbb_root_path Root path
* @param string $php_ext PHP Extension
- * @return null
+ * @param string $forums_table Forums table name
+ * @param string $posts_table Posts table name
+ * @param string $topics_table Topics table name
+ * @param string $users_table Users table name
*/
- public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver $db, \phpbb\user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table)
+ public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table)
{
$this->auth = $auth;
+ $this->config = $config;
$this->db = $db;
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
@@ -215,23 +229,23 @@ class content_visibility
/**
* Change visibility status of one post or all posts of a topic
*
- * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED}
+ * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE}
* @param $post_id mixed Post ID or array of post IDs to act on,
* if it is empty, all posts of topic_id will be modified
* @param $topic_id int Topic where $post_id is found
* @param $forum_id int Forum where $topic_id is found
* @param $user_id int User performing the action
* @param $time int Timestamp when the action is performed
- * @param $reason string Reason why the visibilty was changed.
+ * @param $reason string Reason why the visibility was changed.
* @param $is_starter bool Is this the first post of the topic changed?
* @param $is_latest bool Is this the last post of the topic changed?
* @param $limit_visibility mixed Limit updating per topic_id to a certain visibility
* @param $limit_delete_time mixed Limit updating per topic_id to a certain deletion time
- * @return array Changed post data, empty array if an error occured.
+ * @return array Changed post data, empty array if an error occurred.
*/
public function set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest, $limit_visibility = false, $limit_delete_time = false)
{
- if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED)))
+ if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE)))
{
return array();
}
@@ -326,7 +340,7 @@ class content_visibility
// Update users postcounts
foreach ($postcounts as $num_posts => $poster_ids)
{
- if ($visibility == ITEM_DELETED)
+ if (in_array($visibility, array(ITEM_REAPPROVE, ITEM_DELETED)))
{
$sql = 'UPDATE ' . $this->users_table . '
SET user_posts = 0
@@ -384,75 +398,52 @@ class content_visibility
$update_topic_postcount = false;
}
+ $topic_update_array = array();
// Update the topic's reply count and the forum's post count
if ($update_topic_postcount)
{
- $cur_posts = $cur_unapproved_posts = $cur_softdeleted_posts = 0;
+ $field_alias = array(
+ ITEM_APPROVED => 'posts_approved',
+ ITEM_UNAPPROVED => 'posts_unapproved',
+ ITEM_DELETED => 'posts_softdeleted',
+ ITEM_REAPPROVE => 'posts_unapproved',
+ );
+ $cur_posts = array_fill_keys($field_alias, 0);
+
foreach ($postcount_visibility as $post_visibility => $visibility_posts)
{
- // We need to substract the posts from the counters ...
- if ($post_visibility == ITEM_APPROVED)
- {
- $cur_posts += $visibility_posts;
- }
- else if ($post_visibility == ITEM_UNAPPROVED)
- {
- $cur_unapproved_posts += $visibility_posts;
- }
- else if ($post_visibility == ITEM_DELETED)
- {
- $cur_softdeleted_posts += $visibility_posts;
- }
+ $cur_posts[$field_alias[(int) $post_visibility]] += $visibility_posts;
}
$sql_ary = array();
- if ($visibility == ITEM_DELETED)
+ $recipient_field = $field_alias[$visibility];
+
+ foreach ($cur_posts as $field => $count)
{
- if ($cur_posts)
+ // Decrease the count for the old statuses.
+ if ($count && $field != $recipient_field)
{
- $sql_ary['posts_approved'] = ' - ' . $cur_posts;
- }
- if ($cur_unapproved_posts)
- {
- $sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts;
- }
- if ($cur_posts + $cur_unapproved_posts)
- {
- $sql_ary['posts_softdeleted'] = ' + ' . ($cur_posts + $cur_unapproved_posts);
+ $sql_ary[$field] = " - $count";
}
}
- else
+ // Add up the count from all statuses excluding the recipient status.
+ $count_increase = array_sum(array_diff($cur_posts, array($recipient_field)));
+
+ if ($count_increase)
{
- if ($cur_unapproved_posts)
- {
- $sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts;
- }
- if ($cur_softdeleted_posts)
- {
- $sql_ary['posts_softdeleted'] = ' - ' . $cur_softdeleted_posts;
- }
- if ($cur_softdeleted_posts + $cur_unapproved_posts)
- {
- $sql_ary['posts_approved'] = ' + ' . ($cur_softdeleted_posts + $cur_unapproved_posts);
- }
+ $sql_ary[$recipient_field] = " + $count_increase";
}
if (sizeof($sql_ary))
{
- $topic_sql = $forum_sql = array();
+ $forum_sql = array();
foreach ($sql_ary as $field => $value_change)
{
- $topic_sql[] = 'topic_' . $field . ' = topic_' . $field . $value_change;
+ $topic_update_array[] = 'topic_' . $field . ' = topic_' . $field . $value_change;
$forum_sql[] = 'forum_' . $field . ' = forum_' . $field . $value_change;
}
- // Update the number for replies and posts
- $sql = 'UPDATE ' . $this->topics_table . '
- SET ' . implode(', ', $topic_sql) . '
- WHERE topic_id = ' . (int) $topic_id;
- $this->db->sql_query($sql);
-
$sql = 'UPDATE ' . $this->forums_table . '
SET ' . implode(', ', $forum_sql) . '
WHERE forum_id = ' . (int) $forum_id;
@@ -460,6 +451,38 @@ class content_visibility
}
}
+ if ($post_id)
+ {
+ $sql = 'SELECT 1 AS has_attachments
+ FROM ' . POSTS_TABLE . '
+ WHERE topic_id = ' . (int) $topic_id . '
+ AND post_attachment = 1
+ AND post_visibility = ' . ITEM_APPROVED . '
+ AND ' . $this->db->sql_in_set('post_id', $post_id, true);
+ $result = $this->db->sql_query_limit($sql, 1);
+
+ $has_attachment = (bool) $this->db->sql_fetchfield('has_attachments');
+ $this->db->sql_freeresult($result);
+
+ if ($has_attachment && $visibility == ITEM_APPROVED)
+ {
+ $topic_update_array[] = 'topic_attachment = 1';
+ }
+ else if (!$has_attachment && $visibility != ITEM_APPROVED)
+ {
+ $topic_update_array[] = 'topic_attachment = 0';
+ }
+ }
+
+ if (!empty($topic_update_array))
+ {
+ // Update the number for replies and posts, and update the attachments flag
+ $sql = 'UPDATE ' . $this->topics_table . '
+ SET ' . implode(', ', $topic_update_array) . '
+ WHERE topic_id = ' . (int) $topic_id;
+ $this->db->sql_query($sql);
+ }
+
return $data;
}
@@ -475,7 +498,7 @@ class content_visibility
* as soft deleted.
* If you want to update all posts, use the force option.
*
- * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED}
+ * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE}
* @param $topic_id mixed Topic ID to act on
* @param $forum_id int Forum where $topic_id is found
* @param $user_id int User performing the action
@@ -486,7 +509,7 @@ class content_visibility
*/
public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false)
{
- if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED)))
+ if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE)))
{
return array();
}
@@ -532,7 +555,7 @@ class content_visibility
}
else if (!$force_update_all && $original_topic_data['topic_visibility'] == ITEM_APPROVED && $visibility == ITEM_DELETED)
{
- // If we're soft deleting a topic we only approved posts are soft deleted.
+ // If we're soft deleting a topic we only mark approved posts as soft deleted.
$this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility']);
}
else
@@ -547,7 +570,7 @@ class content_visibility
* Add post to topic and forum statistics
*
* @param $data array Contains information from the topics table about given topic
- * @param $sql_data array Populated with the SQL changes, may be empty at call time
+ * @param &$sql_data array Populated with the SQL changes, may be empty at call time
* @return null
*/
public function add_post_to_statistic($data, &$sql_data)
@@ -561,90 +584,68 @@ class content_visibility
$sql_data[$this->users_table] = (($sql_data[$this->users_table]) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts + 1';
}
- set_config_count('num_posts', 1, true);
+ $this->config->increment('num_posts', 1, false);
}
/**
* Remove post from topic and forum statistics
*
* @param $data array Contains information from the topics table about given topic
- * @param $sql_data array Populated with the SQL changes, may be empty at call time
+ * @param &$sql_data array Populated with the SQL changes, may be empty at call time
* @return null
*/
public function remove_post_from_statistic($data, &$sql_data)
{
- $sql_data[$this->topics_table] = ((!empty($sql_data[$this->topics_table])) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved - 1';
- $sql_data[$this->forums_table] = ((!empty($sql_data[$this->forums_table])) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved - 1';
+ if ($data['post_visibility'] == ITEM_APPROVED)
+ {
+ $sql_data[$this->topics_table] = ((!empty($sql_data[$this->topics_table])) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved - 1';
+ $sql_data[$this->forums_table] = ((!empty($sql_data[$this->forums_table])) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved - 1';
- if ($data['post_postcount'])
+ if ($data['post_postcount'])
+ {
+ $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1';
+ }
+
+ $this->config->increment('num_posts', -1, false);
+ }
+ else if ($data['post_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE)
{
- $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1';
+ $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_unapproved = forum_posts_unapproved - 1';
+ $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_unapproved = topic_posts_unapproved - 1';
+ }
+ else if ($data['post_visibility'] == ITEM_DELETED)
+ {
+ $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_softdeleted = forum_posts_softdeleted - 1';
+ $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_softdeleted = topic_posts_softdeleted - 1';
}
-
- set_config_count('num_posts', -1, true);
}
/**
* Remove topic from forum statistics
*
- * @param $topic_id int The topic to act on
- * @param $forum_id int Forum where the topic is found
- * @param $topic_row array Contains information from the topic, may be empty at call time
- * @param $sql_data array Populated with the SQL changes, may be empty at call time
+ * @param $data array Post and topic data
+ * @param &$sql_data array Populated with the SQL changes, may be empty at call time
* @return null
*/
- public function remove_topic_from_statistic($topic_id, $forum_id, &$topic_row, &$sql_data)
+ public function remove_topic_from_statistic($data, &$sql_data)
{
- // Do we need to grab some topic informations?
- if (!sizeof($topic_row))
+ if ($data['topic_visibility'] == ITEM_APPROVED)
{
- $sql = 'SELECT topic_type, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, topic_visibility
- FROM ' . $this->topics_table . '
- WHERE topic_id = ' . (int) $topic_id;
- $result = $this->db->sql_query($sql);
- $topic_row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
- }
-
- // If this is an edited topic or the first post the topic gets completely disapproved later on...
- $sql_data[$this->forums_table] = (($sql_data[$this->forums_table]) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_topics_approved = forum_topics_approved - 1';
- $sql_data[$this->forums_table] .= ', forum_posts_approved = forum_posts_approved - ' . $topic_row['topic_posts_approved'];
- $sql_data[$this->forums_table] .= ', forum_posts_unapproved = forum_posts_unapproved - ' . $topic_row['topic_posts_unapproved'];
- $sql_data[$this->forums_table] .= ', forum_posts_softdeleted = forum_posts_softdeleted - ' . $topic_row['topic_posts_softdeleted'];
+ $sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1';
- set_config_count('num_topics', -1, true);
- set_config_count('num_posts', $topic_row['topic_posts_approved'] * (-1), true);
-
- // Get user post count information
- $sql = 'SELECT poster_id, COUNT(post_id) AS num_posts
- FROM ' . $this->posts_table . '
- WHERE topic_id = ' . (int) $topic_id . '
- AND post_postcount = 1
- AND post_visibility = ' . ITEM_APPROVED . '
- GROUP BY poster_id';
- $result = $this->db->sql_query($sql);
-
- $postcounts = array();
- while ($row = $this->db->sql_fetchrow($result))
+ if ($data['post_postcount'])
+ {
+ $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1';
+ }
+ }
+ else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE)
{
- $postcounts[(int) $row['num_posts']][] = (int) $row['poster_id'];
+ $sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1';
}
- $this->db->sql_freeresult($result);
-
- // Decrement users post count
- foreach ($postcounts as $num_posts => $poster_ids)
+ else if ($data['topic_visibility'] == ITEM_DELETED)
{
- $sql = 'UPDATE ' . $this->users_table . '
- SET user_posts = 0
- WHERE user_posts < ' . $num_posts . '
- AND ' . $this->db->sql_in_set('user_id', $poster_ids);
- $this->db->sql_query($sql);
-
- $sql = 'UPDATE ' . $this->users_table . '
- SET user_posts = user_posts - ' . $num_posts . '
- WHERE user_posts >= ' . $num_posts . '
- AND ' . $this->db->sql_in_set('user_id', $poster_ids);
- $this->db->sql_query($sql);
+ $sql_data[FORUMS_TABLE] .= 'forum_posts_softdeleted = forum_posts_softdeleted - 1, forum_topics_softdeleted = forum_topics_softdeleted - 1';
}
+
}
}
diff --git a/phpBB/phpbb/controller/exception.php b/phpBB/phpbb/controller/exception.php
index 06ece8d1d5..437558b06a 100644
--- a/phpBB/phpbb/controller/exception.php
+++ b/phpBB/phpbb/controller/exception.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package controller
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\controller;
/**
* Controller exception class
-* @package phpBB3
*/
class exception extends \RuntimeException
{
diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php
index 54c30c93fc..187e455d48 100644
--- a/phpBB/phpbb/controller/helper.php
+++ b/phpBB/phpbb/controller/helper.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package controller
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,11 +15,11 @@ namespace phpbb\controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGenerator;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RequestContext;
/**
* Controller helper class, contains methods that do things for controllers
-* @package phpBB3
*/
class helper
{
@@ -37,6 +41,14 @@ class helper
*/
protected $config;
+ /* @var \phpbb\symfony_request */
+ protected $symfony_request;
+
+ /**
+ * @var \phpbb\filesystem The filesystem object
+ */
+ protected $filesystem;
+
/**
* phpBB root path
* @var string
@@ -44,7 +56,7 @@ class helper
protected $phpbb_root_path;
/**
- * PHP extension
+ * PHP file extension
* @var string
*/
protected $php_ext;
@@ -56,25 +68,33 @@ class helper
* @param \phpbb\user $user User object
* @param \phpbb\config\config $config Config object
* @param \phpbb\controller\provider $provider Path provider
+ * @param \phpbb\extension\manager $manager Extension manager object
+ * @param \phpbb\symfony_request $symfony_request Symfony Request object
+ * @param \phpbb\filesystem $filesystem The filesystem object
* @param string $phpbb_root_path phpBB root path
- * @param string $php_ext PHP extension
+ * @param string $php_ext PHP file extension
*/
- public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext)
{
$this->template = $template;
$this->user = $user;
$this->config = $config;
+ $this->symfony_request = $symfony_request;
+ $this->filesystem = $filesystem;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
- $this->route_collection = $provider->get_routes();
+ $provider->find_routing_files($manager->get_finder());
+ $this->route_collection = $provider->find($phpbb_root_path)->get_routes();
}
/**
* Automate setting up the page and creating the response object.
*
- * @param string $handle The template handle to render
+ * @param string $template_file The template handle to render
* @param string $page_title The title of the page to output
* @param int $status_code The status code to be sent to the page header
+ * @param bool $display_online_list Do we display online users list
+ *
* @return Response object containing rendered page
*/
public function render($template_file, $page_title = '', $status_code = 200, $display_online_list = false)
@@ -96,10 +116,11 @@ class helper
* @param string $route Name of the route to travel
* @param array $params String or array of additional url parameters
* @param bool $is_amp Is url using &amp; (true) or & (false)
- * @param string $session_id Possibility to use a custom session id instead of the global one
+ * @param string|bool $session_id Possibility to use a custom session id instead of the global one
+ * @param bool|string $reference_type The type of reference to be generated (one of the constants)
* @return string The URL already passed through append_sid()
*/
- public function route($route, array $params = array(), $is_amp = true, $session_id = false)
+ public function route($route, array $params = array(), $is_amp = true, $session_id = false, $reference_type = UrlGeneratorInterface::ABSOLUTE_PATH)
{
$anchor = '';
if (isset($params['#']))
@@ -107,35 +128,57 @@ class helper
$anchor = '#' . $params['#'];
unset($params['#']);
}
- $url_generator = new UrlGenerator($this->route_collection, new RequestContext());
- $route_url = $url_generator->generate($route, $params);
- if (strpos($route_url, '/') === 0)
+ $context = new RequestContext();
+ $context->fromRequest($this->symfony_request);
+
+ $script_name = $this->symfony_request->getScriptName();
+ $page_name = substr($script_name, -1, 1) == '/' ? '' : utf8_basename($script_name);
+
+ $base_url = $context->getBaseUrl();
+
+ // If enable_mod_rewrite is false we need to replace the current front-end by app.php, otherwise we need to remove it.
+ $base_url = str_replace('/' . $page_name, empty($this->config['enable_mod_rewrite']) ? '/app.' . $this->php_ext : '', $base_url);
+
+ // We need to update the base url to move to the directory of the app.php file if the current script is not app.php
+ if ($page_name !== 'app.php')
{
- $route_url = substr($route_url, 1);
+ if (empty($this->config['enable_mod_rewrite']))
+ {
+ $base_url = str_replace('/app.' . $this->php_ext, '/' . $this->phpbb_root_path . 'app.' . $this->php_ext, $base_url);
+ }
+ else
+ {
+ $base_url .= preg_replace(get_preg_expression('path_remove_dot_trailing_slash'), '$2', $this->phpbb_root_path);
+ }
}
+ $base_url = $this->filesystem->clean_path($base_url);
+
+ $context->setBaseUrl($base_url);
+
+ $url_generator = new UrlGenerator($this->route_collection, $context);
+ $route_url = $url_generator->generate($route, $params, $reference_type);
+
if ($is_amp)
{
$route_url = str_replace(array('&amp;', '&'), array('&', '&amp;'), $route_url);
}
- // If enable_mod_rewrite is false, we need to include app.php
- $route_prefix = $this->phpbb_root_path;
- if (empty($this->config['enable_mod_rewrite']))
+ if ($reference_type === UrlGeneratorInterface::RELATIVE_PATH && empty($this->config['enable_mod_rewrite']))
{
- $route_prefix .= 'app.' . $this->php_ext . '/';
+ $route_url = 'app.' . $this->php_ext . '/' . $route_url;
}
- return append_sid($route_prefix . $route_url . $anchor, false, $is_amp, $session_id);
+ return append_sid($route_url . $anchor, false, $is_amp, $session_id, true);
}
/**
* Output an error, effectively the same thing as trigger_error
*
* @param string $message The error message
- * @param string $code The error code (e.g. 404, 500, 503, etc.)
- * @return Response A Reponse instance
+ * @param int $code The error code (e.g. 404, 500, 503, etc.)
+ * @return Response A Response instance
*/
public function error($message, $code = 500)
{
@@ -146,4 +189,14 @@ class helper
return $this->render('message_body.html', $this->user->lang('INFORMATION'), $code);
}
+
+ /**
+ * Return the current url
+ *
+ * @return string
+ */
+ public function get_current_url()
+ {
+ return generate_board_url(true) . $this->symfony_request->getRequestUri();
+ }
}
diff --git a/phpBB/phpbb/controller/provider.php b/phpBB/phpbb/controller/provider.php
index 9df8130210..7e26848290 100644
--- a/phpBB/phpbb/controller/provider.php
+++ b/phpBB/phpbb/controller/provider.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package controller
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -15,7 +19,6 @@ use Symfony\Component\Config\FileLocator;
/**
* Controller interface
-* @package phpBB3
*/
class provider
{
@@ -34,37 +37,43 @@ class provider
/**
* Construct method
*
- * @param array() $routing_files Array of strings containing paths
+ * @param array $routing_files Array of strings containing paths
* to YAML files holding route information
*/
- public function __construct(\phpbb\extension\finder $finder = null, $routing_files = array())
+ public function __construct($routing_files = array())
{
$this->routing_files = $routing_files;
+ }
- if ($finder)
- {
- // We hardcode the path to the core config directory
- // because the finder cannot find it
- $this->routing_files = array_merge($this->routing_files, array('config/routing.yml'), array_keys($finder
- ->directory('config')
- ->suffix('routing.yml')
- ->find()
- ));
- }
+ /**
+ * Find the list of routing files
+ *
+ * @param \phpbb\finder $finder
+ * @return null
+ */
+ public function find_routing_files(\phpbb\finder $finder)
+ {
+ // We hardcode the path to the core config directory
+ // because the finder cannot find it
+ $this->routing_files = array_merge($this->routing_files, array('config/routing.yml'), array_keys($finder
+ ->directory('/config')
+ ->suffix('routing.yml')
+ ->find()
+ ));
}
/**
- * Find a list of controllers and return it
+ * Find a list of controllers
*
* @param string $base_path Base path to prepend to file paths
- * @return null
+ * @return provider
*/
public function find($base_path = '')
{
$this->routes = new RouteCollection;
foreach ($this->routing_files as $file_path)
{
- $loader = new YamlFileLoader(new FileLocator($base_path));
+ $loader = new YamlFileLoader(new FileLocator(phpbb_realpath($base_path)));
$this->routes->addCollection($loader->load($file_path));
}
diff --git a/phpBB/phpbb/controller/resolver.php b/phpBB/phpbb/controller/resolver.php
index 233179e343..948a6a218c 100644
--- a/phpBB/phpbb/controller/resolver.php
+++ b/phpBB/phpbb/controller/resolver.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package controller
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -15,7 +19,6 @@ use Symfony\Component\HttpFoundation\Request;
/**
* Controller manager class
-* @package phpBB3
*/
class resolver implements ControllerResolverInterface
{
@@ -33,28 +36,43 @@ class resolver implements ControllerResolverInterface
/**
* phpbb\template\template object
- * @var phpbb\template\template
+ * @var \phpbb\template\template
*/
protected $template;
/**
+ * Request type cast helper object
+ * @var \phpbb\request\type_cast_helper
+ */
+ protected $type_cast_helper;
+
+ /**
+ * phpBB root path
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
* Construct method
*
* @param \phpbb\user $user User Object
* @param ContainerInterface $container ContainerInterface object
+ * @param string $phpbb_root_path Relative path to phpBB root
* @param \phpbb\template\template $template
*/
- public function __construct(\phpbb\user $user, ContainerInterface $container, \phpbb\template\template $template = null)
+ public function __construct(\phpbb\user $user, ContainerInterface $container, $phpbb_root_path, \phpbb\template\template $template = null)
{
$this->user = $user;
$this->container = $container;
$this->template = $template;
+ $this->type_cast_helper = new \phpbb\request\type_cast_helper();
+ $this->phpbb_root_path = $phpbb_root_path;
}
/**
* Load a controller callable
*
- * @param Symfony\Component\HttpFoundation\Request $request Symfony Request object
+ * @param \Symfony\Component\HttpFoundation\Request $request Symfony Request object
* @return bool|Callable Callable or false
* @throws \phpbb\controller\exception
*/
@@ -94,7 +112,7 @@ class resolver implements ControllerResolverInterface
{
$controller_style_dir = 'ext/' . $controller_dir[0] . '/' . $controller_dir[1] . '/styles';
- if (is_dir($controller_style_dir))
+ if (is_dir($this->phpbb_root_path . $controller_style_dir))
{
$this->template->set_style(array($controller_style_dir, 'styles'));
}
@@ -109,9 +127,9 @@ class resolver implements ControllerResolverInterface
* and should match the parameters of the method you are using as your
* controller.
*
- * @param Symfony\Component\HttpFoundation\Request $request Symfony Request object
+ * @param \Symfony\Component\HttpFoundation\Request $request Symfony Request object
* @param mixed $controller A callable (controller class, method)
- * @return bool False
+ * @return array An array of arguments to pass to the controller
* @throws \phpbb\controller\exception
*/
public function getArguments(Request $request, $controller)
@@ -127,7 +145,16 @@ class resolver implements ControllerResolverInterface
{
if (array_key_exists($param->name, $attributes))
{
- $arguments[] = $attributes[$param->name];
+ if (is_string($attributes[$param->name]))
+ {
+ $value = $attributes[$param->name];
+ $this->type_cast_helper->set_var($value, $attributes[$param->name], 'string', true, false);
+ $arguments[] = $value;
+ }
+ else
+ {
+ $arguments[] = $attributes[$param->name];
+ }
}
else if ($param->getClass() && $param->getClass()->isInstance($request))
{
diff --git a/phpBB/phpbb/cron/manager.php b/phpBB/phpbb/cron/manager.php
index b6af07aff7..5c8ac04b77 100644
--- a/phpBB/phpbb/cron/manager.php
+++ b/phpBB/phpbb/cron/manager.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,8 +17,6 @@ namespace phpbb\cron;
* Cron manager class.
*
* Finds installed cron tasks, stores task objects, provides task selection.
-*
-* @package phpBB3
*/
class manager
{
@@ -32,7 +34,9 @@ class manager
/**
* Constructor. Loads all available tasks.
*
- * @param array|Traversable $tasks Provides an iterable set of task names
+ * @param array|\Traversable $tasks Provides an iterable set of task names
+ * @param string $phpbb_root_path Relative path to phpBB root
+ * @param string $php_ext PHP file extension
*/
public function __construct($tasks, $phpbb_root_path, $php_ext)
{
@@ -46,7 +50,7 @@ class manager
* Loads tasks given by name, wraps them
* and puts them into $this->tasks.
*
- * @param array|Traversable $tasks Array of instances of \phpbb\cron\task\task
+ * @param array|\Traversable $tasks Array of instances of \phpbb\cron\task\task
*
* @return null
*/
@@ -120,6 +124,16 @@ class manager
}
/**
+ * Find all tasks and return them.
+ *
+ * @return array List of all tasks.
+ */
+ public function get_tasks()
+ {
+ return $this->tasks;
+ }
+
+ /**
* Wraps a task inside an instance of \phpbb\cron\task\wrapper.
*
* @param \phpbb\cron\task\task $task The task.
diff --git a/phpBB/phpbb/cron/task/base.php b/phpBB/phpbb/cron/task/base.php
index 63f0407bcd..57c9912d31 100644
--- a/phpBB/phpbb/cron/task/base.php
+++ b/phpBB/phpbb/cron/task/base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -17,8 +21,6 @@ namespace phpbb\cron\task;
*
* Cron tasks need not inherit from this base class. If desired,
* they may implement cron task interface directly.
-*
-* @package phpBB3
*/
abstract class base implements \phpbb\cron\task\task
{
diff --git a/phpBB/phpbb/cron/task/core/prune_all_forums.php b/phpBB/phpbb/cron/task/core/prune_all_forums.php
index 90b9a5914b..b47939ccbe 100644
--- a/phpBB/phpbb/cron/task/core/prune_all_forums.php
+++ b/phpBB/phpbb/cron/task/core/prune_all_forums.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -15,8 +19,6 @@ namespace phpbb\cron\task\core;
* It is intended to be invoked from system cron.
* This task will find all forums for which pruning is enabled, and will
* prune all forums as necessary.
-*
-* @package phpBB3
*/
class prune_all_forums extends \phpbb\cron\task\base
{
@@ -29,11 +31,11 @@ class prune_all_forums extends \phpbb\cron\task\base
* Constructor.
*
* @param string $phpbb_root_path The root path
- * @param string $php_ext The PHP extension
+ * @param string $php_ext The PHP file extension
* @param \phpbb\config\config $config The config
- * @param \phpbb\db\driver\driver $db The db connection
+ * @param \phpbb\db\driver\driver_interface $db The db connection
*/
- public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver $db)
+ public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db)
{
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
diff --git a/phpBB/phpbb/cron/task/core/prune_forum.php b/phpBB/phpbb/cron/task/core/prune_forum.php
index e0d8b067c5..ba68565197 100644
--- a/phpBB/phpbb/cron/task/core/prune_forum.php
+++ b/phpBB/phpbb/cron/task/core/prune_forum.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -15,8 +19,6 @@ namespace phpbb\cron\task\core;
* It is intended to be used when cron is invoked via web.
* This task can decide whether it should be run using data obtained by viewforum
* code, without making additional database queries.
-*
-* @package phpBB3
*/
class prune_forum extends \phpbb\cron\task\base implements \phpbb\cron\task\parametrized
{
@@ -39,11 +41,11 @@ class prune_forum extends \phpbb\cron\task\base implements \phpbb\cron\task\para
* Constructor.
*
* @param string $phpbb_root_path The root path
- * @param string $php_ext The PHP extension
+ * @param string $php_ext PHP file extension
* @param \phpbb\config\config $config The config
- * @param \phpbb\db\driver\driver $db The db connection
+ * @param \phpbb\db\driver\driver_interface $db The db connection
*/
- public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver $db)
+ public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db)
{
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
diff --git a/phpBB/phpbb/cron/task/core/prune_notifications.php b/phpBB/phpbb/cron/task/core/prune_notifications.php
index 9f67c54e1c..ffa7e17970 100644
--- a/phpBB/phpbb/cron/task/core/prune_notifications.php
+++ b/phpBB/phpbb/cron/task/core/prune_notifications.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\cron\task\core;
/**
* Prune notifications cron task.
-*
-* @package phpBB3
*/
class prune_notifications extends \phpbb\cron\task\base
{
diff --git a/phpBB/phpbb/cron/task/core/prune_shadow_topics.php b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php
new file mode 100644
index 0000000000..97a4b0ea86
--- /dev/null
+++ b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php
@@ -0,0 +1,200 @@
+<?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\cron\task\core;
+
+/**
+* Prune one forum of its shadow topics cron task.
+*
+* It is intended to be used when cron is invoked via web.
+* This task can decide whether it should be run using data obtained by viewforum
+* code, without making additional database queries.
+*/
+class prune_shadow_topics extends \phpbb\cron\task\base implements \phpbb\cron\task\parametrized
+{
+ protected $phpbb_root_path;
+ protected $php_ext;
+ protected $config;
+ protected $db;
+ protected $log;
+ protected $user;
+
+ /**
+ * If $forum_data is given, it is assumed to contain necessary information
+ * about a single forum that is to be pruned.
+ *
+ * If $forum_data is not given, forum id will be retrieved via request_var
+ * and a database query will be performed to load the necessary information
+ * about the forum.
+ */
+ protected $forum_data;
+
+ /**
+ * Constructor.
+ *
+ * @param string $phpbb_root_path The root path
+ * @param string $php_ext PHP file extension
+ * @param \phpbb\config\config $config The config
+ * @param \phpbb\db\driver\driver_interface $db The db connection
+ * @param \phpbb\log\log $log The phpBB log system
+ * @param \phpbb\user $user The phpBB user object
+ */
+ public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\log\log $log, \phpbb\user $user)
+ {
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ $this->config = $config;
+ $this->db = $db;
+ $this->log = $log;
+ $this->user = $user;
+ }
+
+ /**
+ * Manually set forum data.
+ *
+ * @param array $forum_data Information about a forum to be pruned.
+ */
+ public function set_forum_data($forum_data)
+ {
+ $this->forum_data = $forum_data;
+ }
+
+ /**
+ * Runs this cron task.
+ *
+ * @return null
+ */
+ public function run()
+ {
+ if (!function_exists('auto_prune'))
+ {
+ include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext);
+ }
+
+ if ($this->forum_data['prune_shadow_days'])
+ {
+ $this->auto_prune_shadow_topics($this->forum_data['forum_id'], 'shadow', $this->forum_data['forum_flags'], $this->forum_data['prune_shadow_days'], $this->forum_data['prune_shadow_freq']);
+ }
+ }
+
+ /**
+ * Returns whether this cron task can run, given current board configuration.
+ *
+ * This cron task will not run when system cron is utilised, as in
+ * such cases prune_all_forums task would run instead.
+ *
+ * Additionally, this task must be given the forum data, either via
+ * the constructor or parse_parameters method.
+ *
+ * @return bool
+ */
+ public function is_runnable()
+ {
+ return !$this->config['use_system_cron'] && $this->forum_data;
+ }
+
+ /**
+ * Returns whether this cron task should run now, because enough time
+ * has passed since it was last run.
+ *
+ * Forum pruning interval is specified in the forum data.
+ *
+ * @return bool
+ */
+ public function should_run()
+ {
+ return $this->forum_data['enable_shadow_prune'] && $this->forum_data['prune_shadow_next'] < time();
+ }
+
+ /**
+ * Returns parameters of this cron task as an array.
+ * The array has one key, f, whose value is id of the forum to be pruned.
+ *
+ * @return array
+ */
+ public function get_parameters()
+ {
+ return array('f' => $this->forum_data['forum_id']);
+ }
+
+ /**
+ * Parses parameters found in $request, which is an instance of
+ * \phpbb\request\request_interface.
+ *
+ * It is expected to have a key f whose value is id of the forum to be pruned.
+ *
+ * @param \phpbb\request\request_interface $request Request object.
+ *
+ * @return null
+ */
+ public function parse_parameters(\phpbb\request\request_interface $request)
+ {
+ $this->forum_data = null;
+ if ($request->is_set('f'))
+ {
+ $forum_id = $request->variable('f', 0);
+
+ $sql = 'SELECT forum_id, prune_shadow_next, enable_shadow_prune, prune_shadow_days, forum_flags, prune_shadow_freq
+ FROM ' . FORUMS_TABLE . "
+ WHERE forum_id = $forum_id";
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if ($row)
+ {
+ $this->forum_data = $row;
+ }
+ }
+ }
+
+ /**
+ * Automatically prune shadow topics
+ * Based on fuunction auto_prune()
+ * @param int $forum_id Forum ID of forum that should be pruned
+ * @param string $prune_mode Prune mode
+ * @param int $prune_flags Prune flags
+ * @param int $prune_days Prune date in days
+ * @param int $prune_freq Prune frequency
+ * @return null
+ */
+ protected function auto_prune_shadow_topics($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_freq)
+ {
+ $sql = 'SELECT forum_name
+ FROM ' . FORUMS_TABLE . "
+ WHERE forum_id = $forum_id";
+ $result = $this->db->sql_query($sql, 3600);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if ($row)
+ {
+ $prune_date = time() - ($prune_days * 86400);
+ $next_prune = time() + ($prune_freq * 86400);
+
+ prune($forum_id, $prune_mode, $prune_date, $prune_flags, true);
+
+ $sql = 'UPDATE ' . FORUMS_TABLE . "
+ SET prune_shadow_next = $next_prune
+ WHERE forum_id = $forum_id";
+ $this->db->sql_query($sql);
+
+ $user_id = (empty($this->user->data)) ? ANONYMOUS : $this->user->data['user_id'];
+ $user_ip = (empty($this->user->ip)) ? '' : $this->user->ip;
+
+ $this->log->add('admin', $user_id, $user_ip, 'LOG_PRUNE_SHADOW', false, array($row['forum_name']));
+ }
+
+ return;
+ }
+}
diff --git a/phpBB/phpbb/cron/task/core/queue.php b/phpBB/phpbb/cron/task/core/queue.php
index cd799b8024..796a96d7f5 100644
--- a/phpBB/phpbb/cron/task/core/queue.php
+++ b/phpBB/phpbb/cron/task/core/queue.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\cron\task\core;
/**
* Queue cron task. Sends email and jabber messages queued by other scripts.
-*
-* @package phpBB3
*/
class queue extends \phpbb\cron\task\base
{
@@ -24,7 +26,7 @@ class queue extends \phpbb\cron\task\base
* Constructor.
*
* @param string $phpbb_root_path The root path
- * @param string $php_ext The PHP extension
+ * @param string $php_ext PHP file extension
* @param \phpbb\config\config $config The config
*/
public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config)
diff --git a/phpBB/phpbb/cron/task/core/tidy_cache.php b/phpBB/phpbb/cron/task/core/tidy_cache.php
index a94a85db53..506a245f0f 100644
--- a/phpBB/phpbb/cron/task/core/tidy_cache.php
+++ b/phpBB/phpbb/cron/task/core/tidy_cache.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\cron\task\core;
/**
* Tidy cache cron task.
-*
-* @package phpBB3
*/
class tidy_cache extends \phpbb\cron\task\base
{
diff --git a/phpBB/phpbb/cron/task/core/tidy_database.php b/phpBB/phpbb/cron/task/core/tidy_database.php
index f712a5047c..949bba8012 100644
--- a/phpBB/phpbb/cron/task/core/tidy_database.php
+++ b/phpBB/phpbb/cron/task/core/tidy_database.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\cron\task\core;
/**
* Tidy database cron task.
-*
-* @package phpBB3
*/
class tidy_database extends \phpbb\cron\task\base
{
@@ -24,7 +26,7 @@ class tidy_database extends \phpbb\cron\task\base
* Constructor.
*
* @param string $phpbb_root_path The root path
- * @param string $php_ext The PHP extension
+ * @param string $php_ext The PHP file extension
* @param \phpbb\config\config $config The config
*/
public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config)
diff --git a/phpBB/phpbb/cron/task/core/tidy_plupload.php b/phpBB/phpbb/cron/task/core/tidy_plupload.php
index 5a98e0bd7b..b6aeecf4b4 100644
--- a/phpBB/phpbb/cron/task/core/tidy_plupload.php
+++ b/phpBB/phpbb/cron/task/core/tidy_plupload.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\cron\task\core;
/**
* Cron task for cleaning plupload's temporary upload directory.
-*
-* @package phpBB3
*/
class tidy_plupload extends \phpbb\cron\task\base
{
diff --git a/phpBB/phpbb/cron/task/core/tidy_search.php b/phpBB/phpbb/cron/task/core/tidy_search.php
index 42f7df308f..ce16b3f988 100644
--- a/phpBB/phpbb/cron/task/core/tidy_search.php
+++ b/phpBB/phpbb/cron/task/core/tidy_search.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,8 +17,6 @@ namespace phpbb\cron\task\core;
* Tidy search cron task.
*
* Will only run when the currently selected search backend supports tidying.
-*
-* @package phpBB3
*/
class tidy_search extends \phpbb\cron\task\base
{
@@ -29,13 +31,13 @@ class tidy_search extends \phpbb\cron\task\base
* Constructor.
*
* @param string $phpbb_root_path The root path
- * @param string $php_ext The PHP extension
+ * @param string $php_ext The PHP file extension
* @param \phpbb\auth\auth $auth The auth
* @param \phpbb\config\config $config The config
- * @param \phpbb\db\driver\driver $db The db connection
+ * @param \phpbb\db\driver\driver_interface $db The db connection
* @param \phpbb\user $user The user
*/
- public function __construct($phpbb_root_path, $php_ext, \phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\user $user)
+ public function __construct($phpbb_root_path, $php_ext, \phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\user $user)
{
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
@@ -52,8 +54,7 @@ class tidy_search extends \phpbb\cron\task\base
*/
public function run()
{
- // Select the search method
- $search_type = basename($this->config['search_type']);
+ $search_type = $this->config['search_type'];
// We do some additional checks in the module to ensure it can actually be utilised
$error = false;
@@ -76,10 +77,7 @@ class tidy_search extends \phpbb\cron\task\base
*/
public function is_runnable()
{
- // Select the search method
- $search_type = basename($this->config['search_type']);
-
- return class_exists($search_type);
+ return class_exists($this->config['search_type']);
}
/**
diff --git a/phpBB/phpbb/cron/task/core/tidy_sessions.php b/phpBB/phpbb/cron/task/core/tidy_sessions.php
index 68094af1f7..5e6dabdabf 100644
--- a/phpBB/phpbb/cron/task/core/tidy_sessions.php
+++ b/phpBB/phpbb/cron/task/core/tidy_sessions.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\cron\task\core;
/**
* Tidy sessions cron task.
-*
-* @package phpBB3
*/
class tidy_sessions extends \phpbb\cron\task\base
{
diff --git a/phpBB/phpbb/cron/task/core/tidy_warnings.php b/phpBB/phpbb/cron/task/core/tidy_warnings.php
index a0ff23fc57..7b67eae6ef 100644
--- a/phpBB/phpbb/cron/task/core/tidy_warnings.php
+++ b/phpBB/phpbb/cron/task/core/tidy_warnings.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,8 +17,6 @@ namespace phpbb\cron\task\core;
* Tidy warnings cron task.
*
* Will only run when warnings are configured to expire.
-*
-* @package phpBB3
*/
class tidy_warnings extends \phpbb\cron\task\base
{
@@ -26,7 +28,7 @@ class tidy_warnings extends \phpbb\cron\task\base
* Constructor.
*
* @param string $phpbb_root_path The root path
- * @param string $php_ext The PHP extension
+ * @param string $php_ext PHP file extension
* @param \phpbb\config\config $config The config
*/
public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config)
diff --git a/phpBB/phpbb/cron/task/parametrized.php b/phpBB/phpbb/cron/task/parametrized.php
index 1aeead0399..7e190b9b86 100644
--- a/phpBB/phpbb/cron/task/parametrized.php
+++ b/phpBB/phpbb/cron/task/parametrized.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -17,8 +21,6 @@ namespace phpbb\cron\task;
* parametrized cron tasks perform actions on a particular object (or objects).
* Parametrized cron tasks do not make sense and are not usable without
* specifying these objects.
-*
-* @package phpBB3
*/
interface parametrized extends \phpbb\cron\task\task
{
diff --git a/phpBB/phpbb/cron/task/task.php b/phpBB/phpbb/cron/task/task.php
index 3ce3de9598..6d5a383d2d 100644
--- a/phpBB/phpbb/cron/task/task.php
+++ b/phpBB/phpbb/cron/task/task.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\cron\task;
/**
* Cron task interface
-* @package phpBB3
*/
interface task
{
diff --git a/phpBB/phpbb/cron/task/wrapper.php b/phpBB/phpbb/cron/task/wrapper.php
index fc3f897206..8a4a8b1f0c 100644
--- a/phpBB/phpbb/cron/task/wrapper.php
+++ b/phpBB/phpbb/cron/task/wrapper.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,8 +16,6 @@ namespace phpbb\cron\task;
/**
* Cron task wrapper class.
* Enhances cron tasks with convenience methods that work identically for all tasks.
-*
-* @package phpBB3
*/
class wrapper
{
@@ -27,6 +29,8 @@ class wrapper
* Wraps a task $task, which must implement cron_task interface.
*
* @param \phpbb\cron\task\task $task The cron task to wrap.
+ * @param string $phpbb_root_path Relative path to phpBB root
+ * @param string $php_ext PHP file extension
*/
public function __construct(\phpbb\cron\task\task $task, $phpbb_root_path, $php_ext)
{
diff --git a/phpBB/phpbb/datetime.php b/phpBB/phpbb/datetime.php
index dfa21976e0..63cdba90fd 100644
--- a/phpBB/phpbb/datetime.php
+++ b/phpBB/phpbb/datetime.php
@@ -1,9 +1,14 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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;
@@ -33,9 +38,9 @@ class datetime extends \DateTime
* Constructs a new instance of \phpbb\datetime, expanded to include an argument to inject
* the user context and modify the timezone to the users selected timezone if one is not set.
*
+ * @param user $user object for context.
* @param string $time String in a format accepted by strtotime().
- * @param DateTimeZone $timezone Time zone of the time.
- * @param user User object for context.
+ * @param \DateTimeZone $timezone Time zone of the time.
*/
public function __construct($user, $time = 'now', \DateTimeZone $timezone = null)
{
@@ -86,25 +91,28 @@ class datetime extends \DateTime
$midnight = $midnight->getTimestamp();
- $day = false;
-
- if ($timestamp > $midnight + 86400)
- {
- $day = 'TOMORROW';
- }
- else if ($timestamp > $midnight)
- {
- $day = 'TODAY';
- }
- else if ($timestamp > $midnight - 86400)
- {
- $day = 'YESTERDAY';
- }
-
- if ($day !== false)
+ if ($timestamp <= $midnight + 2 * 86400)
{
- // Format using the short formatting and finally swap out the relative token placeholder with the correct value
- return str_replace(self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER, $this->user->lang['datetime'][$day], strtr(parent::format($format['format_short']), $format['lang']));
+ $day = false;
+
+ if ($timestamp > $midnight + 86400)
+ {
+ $day = 'TOMORROW';
+ }
+ else if ($timestamp > $midnight)
+ {
+ $day = 'TODAY';
+ }
+ else if ($timestamp > $midnight - 86400)
+ {
+ $day = 'YESTERDAY';
+ }
+
+ if ($day !== false)
+ {
+ // Format using the short formatting and finally swap out the relative token placeholder with the correct value
+ return str_replace(self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER, $this->user->lang['datetime'][$day], strtr(parent::format($format['format_short']), $format['lang']));
+ }
}
}
}
@@ -115,7 +123,7 @@ class datetime extends \DateTime
/**
* Magic method to convert DateTime object to string
*
- * @return Formatted date time, according to the users default settings.
+ * @return string Formatted date time, according to the users default settings.
*/
public function __toString()
{
diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php
index b61800006f..9fc04d47a1 100644
--- a/phpBB/phpbb/db/driver/driver.php
+++ b/phpBB/phpbb/db/driver/driver.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,9 +15,8 @@ namespace phpbb\db\driver;
/**
* Database Abstraction Layer
-* @package dbal
*/
-class driver
+abstract class driver implements driver_interface
{
var $db_connect_id;
var $query_result;
@@ -84,7 +87,103 @@ class driver
}
/**
- * return on error or display error message
+ * {@inheritdoc}
+ */
+ public function get_sql_layer()
+ {
+ return $this->sql_layer;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_db_name()
+ {
+ return $this->dbname;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_any_char()
+ {
+ return $this->any_char;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_one_char()
+ {
+ return $this->one_char;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_db_connect_id()
+ {
+ return $this->db_connect_id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_sql_error_triggered()
+ {
+ return $this->sql_error_triggered;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_sql_error_sql()
+ {
+ return $this->sql_error_sql;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_transaction()
+ {
+ return $this->transaction;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_sql_time()
+ {
+ return $this->sql_time;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_sql_error_returned()
+ {
+ return $this->sql_error_returned;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_multi_insert()
+ {
+ return $this->multi_insert;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set_multi_insert($multi_insert)
+ {
+ $this->multi_insert = $multi_insert;
+ }
+
+ /**
+ * {@inheritDoc}
*/
function sql_return_on_error($fail = false)
{
@@ -95,7 +194,7 @@ class driver
}
/**
- * Return number of sql queries and cached sql queries used
+ * {@inheritDoc}
*/
function sql_num_queries($cached = false)
{
@@ -103,7 +202,7 @@ class driver
}
/**
- * Add to query count
+ * {@inheritDoc}
*/
function sql_add_num_queries($cached = false)
{
@@ -113,7 +212,7 @@ class driver
}
/**
- * DBAL garbage collection, close sql connection
+ * {@inheritDoc}
*/
function sql_close()
{
@@ -146,8 +245,7 @@ class driver
}
/**
- * Build LIMIT query
- * Doing some validation here.
+ * {@inheritDoc}
*/
function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
{
@@ -164,7 +262,7 @@ class driver
}
/**
- * Fetch all rows
+ * {@inheritDoc}
*/
function sql_fetchrowset($query_id = false)
{
@@ -188,8 +286,7 @@ class driver
}
/**
- * Seek to given row number
- * rownum is zero-based
+ * {@inheritDoc}
*/
function sql_rowseek($rownum, &$query_id)
{
@@ -231,8 +328,7 @@ class driver
}
/**
- * Fetch field
- * if rownum is false, the current row is used, else it is pointing to the row (zero-based)
+ * {@inheritDoc}
*/
function sql_fetchfield($field, $rownum = false, $query_id = false)
{
@@ -263,11 +359,7 @@ class driver
}
/**
- * Correctly adjust LIKE expression for special characters
- * Some DBMS are handling them in a different way
- *
- * @param string $expression The expression to use. Every wildcard is escaped, except $this->any_char and $this->one_char
- * @return string LIKE expression including the keyword!
+ * {@inheritDoc}
*/
function sql_like_expression($expression)
{
@@ -278,14 +370,18 @@ class driver
}
/**
- * Build a case expression
- *
- * Note: The two statements action_true and action_false must have the same data type (int, vchar, ...) in the database!
- *
- * @param string $condition The condition which must be true, to use action_true rather then action_else
- * @param string $action_true SQL expression that is used, if the condition is true
- * @param string $action_else SQL expression that is used, if the condition is false, optional
- * @return string CASE expression including the condition and statements
+ * {@inheritDoc}
+ */
+ function sql_not_like_expression($expression)
+ {
+ $expression = utf8_str_replace(array('_', '%'), array("\_", "\%"), $expression);
+ $expression = utf8_str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $expression);
+
+ return $this->_sql_not_like_expression('NOT LIKE \'' . $this->sql_escape($expression) . '\'');
+ }
+
+ /**
+ * {@inheritDoc}
*/
public function sql_case($condition, $action_true, $action_false = false)
{
@@ -297,11 +393,7 @@ class driver
}
/**
- * Build a concatenated expression
- *
- * @param string $expr1 Base SQL expression where we append the second one
- * @param string $expr2 SQL expression that is appended to the first expression
- * @return string Concatenated string
+ * {@inheritDoc}
*/
public function sql_concatenate($expr1, $expr2)
{
@@ -309,9 +401,7 @@ class driver
}
/**
- * Returns whether results of a query need to be buffered to run a transaction while iterating over them.
- *
- * @return bool Whether buffering is required.
+ * {@inheritDoc}
*/
function sql_buffer_nested_transactions()
{
@@ -319,15 +409,14 @@ class driver
}
/**
- * SQL Transaction
- * @access private
+ * {@inheritDoc}
*/
function sql_transaction($status = 'begin')
{
switch ($status)
{
case 'begin':
- // If we are within a transaction we will not open another one, but enclose the current one to not loose data (prevening auto commit)
+ // If we are within a transaction we will not open another one, but enclose the current one to not loose data (preventing auto commit)
if ($this->transaction)
{
$this->transactions++;
@@ -345,14 +434,16 @@ class driver
break;
case 'commit':
- // If there was a previously opened transaction we do not commit yet... but count back the number of inner transactions
+ // If there was a previously opened transaction we do not commit yet...
+ // but count back the number of inner transactions
if ($this->transaction && $this->transactions)
{
$this->transactions--;
return true;
}
- // Check if there is a transaction (no transaction can happen if there was an error, with a combined rollback and error returning enabled)
+ // Check if there is a transaction (no transaction can happen if
+ // there was an error, with a combined rollback and error returning enabled)
// This implies we have transaction always set for autocommit db's
if (!$this->transaction)
{
@@ -385,11 +476,7 @@ class driver
}
/**
- * Build sql statement from array for insert/update/select statements
- *
- * Idea for this from Ikonboard
- * Possible query values: INSERT, INSERT_SELECT, UPDATE, SELECT, DELETE
- *
+ * {@inheritDoc}
*/
function sql_build_array($query, $assoc_ary = false)
{
@@ -437,14 +524,7 @@ class driver
}
/**
- * Build IN or NOT IN sql comparison string, uses <> or = on single element
- * arrays to improve comparison speed
- *
- * @access public
- * @param string $field name of the sql column that shall be compared
- * @param array $array array of values that are allowed (IN) or not allowed (NOT IN)
- * @param bool $negate true for NOT IN (), false for IN () (default)
- * @param bool $allow_empty_set If true, allow $array to be empty, this function will return 1=1 or 1=0 then. Default to false.
+ * {@inheritDoc}
*/
function sql_in_set($field, $array, $negate = false, $allow_empty_set = false)
{
@@ -489,12 +569,7 @@ class driver
}
/**
- * Run binary AND operator on DB column.
- * Results in sql statement: "{$column_name} & (1 << {$bit}) {$compare}"
- *
- * @param string $column_name The column name to use
- * @param int $bit The value to use for the AND operator, will be converted to (1 << $bit). Is used by options, using the number schema... 0, 1, 2...29
- * @param string $compare Any custom SQL code after the check (for example "= 0")
+ * {@inheritDoc}
*/
function sql_bit_and($column_name, $bit, $compare = '')
{
@@ -507,12 +582,7 @@ class driver
}
/**
- * Run binary OR operator on DB column.
- * Results in sql statement: "{$column_name} | (1 << {$bit}) {$compare}"
- *
- * @param string $column_name The column name to use
- * @param int $bit The value to use for the OR operator, will be converted to (1 << $bit). Is used by options, using the number schema... 0, 1, 2...29
- * @param string $compare Any custom SQL code after the check (for example "= 0")
+ * {@inheritDoc}
*/
function sql_bit_or($column_name, $bit, $compare = '')
{
@@ -525,10 +595,7 @@ class driver
}
/**
- * Returns SQL string to cast a string expression to an int.
- *
- * @param string $expression An expression evaluating to string
- * @return string Expression returning an int
+ * {@inheritDoc}
*/
function cast_expr_to_bigint($expression)
{
@@ -536,10 +603,7 @@ class driver
}
/**
- * Returns SQL string to cast an integer expression to a string.
- *
- * @param string $expression An expression evaluating to int
- * @return string Expression returning a string
+ * {@inheritDoc}
*/
function cast_expr_to_string($expression)
{
@@ -547,11 +611,7 @@ class driver
}
/**
- * Run LOWER() on DB column of type text (i.e. neither varchar nor char).
- *
- * @param string $column_name The column name to use
- *
- * @return string A SQL statement like "LOWER($column_name)"
+ * {@inheritDoc}
*/
function sql_lower_text($column_name)
{
@@ -559,13 +619,7 @@ class driver
}
/**
- * Run more than one insert statement.
- *
- * @param string $table table name to run the statements on
- * @param array $sql_ary multi-dimensional array holding the statement data.
- *
- * @return bool false if no statements were executed.
- * @access public
+ * {@inheritDoc}
*/
function sql_multi_insert($table, $sql_ary)
{
@@ -637,9 +691,7 @@ class driver
}
/**
- * Build sql statement from array for select and select distinct statements
- *
- * Possible query values: SELECT, SELECT_DISTINCT
+ * {@inheritDoc}
*/
function sql_build_query($query, $array)
{
@@ -742,7 +794,7 @@ class driver
}
/**
- * display sql error page
+ * {@inheritDoc}
*/
function sql_error($sql = '')
{
@@ -812,7 +864,7 @@ class driver
}
/**
- * Explain queries
+ * {@inheritDoc}
*/
function sql_report($mode, $query = '')
{
@@ -872,7 +924,7 @@ class driver
</div>
</div>
<div id="page-footer">
- Powered by <a href="https://www.phpbb.com/">phpBB</a>&reg; Forum Software &copy; phpBB Group
+ Powered by <a href="https://www.phpbb.com/">phpBB</a>&reg; Forum Software &copy; phpBB Limited
</div>
</div>
</body>
@@ -1002,14 +1054,7 @@ class driver
}
/**
- * Gets the estimated number of rows in a specified table.
- *
- * @param string $table_name Table name
- *
- * @return string Number of rows in $table_name.
- * Prefixed with ~ if estimated (otherwise exact).
- *
- * @access public
+ * {@inheritDoc}
*/
function get_estimated_row_count($table_name)
{
@@ -1017,13 +1062,7 @@ class driver
}
/**
- * Gets the exact number of rows in a specified table.
- *
- * @param string $table_name Table name
- *
- * @return string Exact number of rows in $table_name.
- *
- * @access public
+ * {@inheritDoc}
*/
function get_row_count($table_name)
{
diff --git a/phpBB/phpbb/db/driver/driver_interface.php b/phpBB/phpbb/db/driver/driver_interface.php
new file mode 100644
index 0000000000..8b487c5d42
--- /dev/null
+++ b/phpBB/phpbb/db/driver/driver_interface.php
@@ -0,0 +1,453 @@
+<?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\driver;
+
+interface driver_interface
+{
+ /**
+ * Gets the name of the sql layer.
+ *
+ * @return string
+ */
+ public function get_sql_layer();
+
+ /**
+ * Gets the name of the database.
+ *
+ * @return string
+ */
+ public function get_db_name();
+
+ /**
+ * Wildcards for matching any (%) character within LIKE expressions
+ *
+ * @return string
+ */
+ public function get_any_char();
+
+ /**
+ * Wildcards for matching exactly one (_) character within LIKE expressions
+ *
+ * @return string
+ */
+ public function get_one_char();
+
+ /**
+ * Gets the time spent into the queries
+ *
+ * @return int
+ */
+ public function get_sql_time();
+
+ /**
+ * Gets the connect ID.
+ *
+ * @return mixed
+ */
+ public function get_db_connect_id();
+
+ /**
+ * Indicates if an error was triggered.
+ *
+ * @return bool
+ */
+ public function get_sql_error_triggered();
+
+ /**
+ * Gets the last faulty query
+ *
+ * @return string
+ */
+ public function get_sql_error_sql();
+
+ /**
+ * Indicates if we are in a transaction.
+ *
+ * @return bool
+ */
+ public function get_transaction();
+
+ /**
+ * Gets the returned error.
+ *
+ * @return array
+ */
+ public function get_sql_error_returned();
+
+ /**
+ * Indicates if multiple insertion can be used
+ *
+ * @return bool
+ */
+ public function get_multi_insert();
+
+ /**
+ * Set if multiple insertion can be used
+ *
+ * @param bool $multi_insert
+ */
+ public function set_multi_insert($multi_insert);
+
+ /**
+ * Gets the exact number of rows in a specified table.
+ *
+ * @param string $table_name Table name
+ * @return string Exact number of rows in $table_name.
+ */
+ public function get_row_count($table_name);
+
+ /**
+ * Gets the estimated number of rows in a specified table.
+ *
+ * @param string $table_name Table name
+ * @return string Number of rows in $table_name.
+ * Prefixed with ~ if estimated (otherwise exact).
+ */
+ public function get_estimated_row_count($table_name);
+
+ /**
+ * Run LOWER() on DB column of type text (i.e. neither varchar nor char).
+ *
+ * @param string $column_name The column name to use
+ * @return string A SQL statement like "LOWER($column_name)"
+ */
+ public function sql_lower_text($column_name);
+
+ /**
+ * Display sql error page
+ *
+ * @param string $sql The SQL query causing the error
+ * @return mixed Returns the full error message, if $this->return_on_error
+ * is set, null otherwise
+ */
+ public function sql_error($sql = '');
+
+ /**
+ * Returns whether results of a query need to be buffered to run a
+ * transaction while iterating over them.
+ *
+ * @return bool Whether buffering is required.
+ */
+ public function sql_buffer_nested_transactions();
+
+ /**
+ * Run binary OR operator on DB column.
+ *
+ * @param string $column_name The column name to use
+ * @param int $bit The value to use for the OR operator,
+ * will be converted to (1 << $bit). Is used by options,
+ * using the number schema... 0, 1, 2...29
+ * @param string $compare Any custom SQL code after the check (e.g. "= 0")
+ * @return string A SQL statement like "$column | (1 << $bit) {$compare}"
+ */
+ public function sql_bit_or($column_name, $bit, $compare = '');
+
+ /**
+ * Version information about used database
+ *
+ * @param bool $raw Only return the fetched sql_server_version
+ * @param bool $use_cache Is it safe to retrieve the value from the cache
+ * @return string sql server version
+ */
+ public function sql_server_info($raw = false, $use_cache = true);
+
+ /**
+ * Return on error or display error message
+ *
+ * @param bool $fail Should we return on errors, or stop
+ * @return null
+ */
+ public function sql_return_on_error($fail = false);
+
+ /**
+ * Build sql statement from an array
+ *
+ * @param string $query Should be on of the following strings:
+ * INSERT, INSERT_SELECT, UPDATE, SELECT, DELETE
+ * @param array $assoc_ary Array with "column => value" pairs
+ * @return string A SQL statement like "c1 = 'a' AND c2 = 'b'"
+ */
+ public function sql_build_array($query, $assoc_ary = array());
+
+ /**
+ * Fetch all rows
+ *
+ * @param mixed $query_id Already executed query to get the rows from,
+ * if false, the last query will be used.
+ * @return mixed Nested array if the query had rows, false otherwise
+ */
+ public function sql_fetchrowset($query_id = false);
+
+ /**
+ * SQL Transaction
+ *
+ * @param string $status Should be one of the following strings:
+ * begin, commit, rollback
+ * @return mixed Buffered, seekable result handle, false on error
+ */
+ public function sql_transaction($status = 'begin');
+
+ /**
+ * Build a concatenated expression
+ *
+ * @param string $expr1 Base SQL expression where we append the second one
+ * @param string $expr2 SQL expression that is appended to the first expression
+ * @return string Concatenated string
+ */
+ public function sql_concatenate($expr1, $expr2);
+
+ /**
+ * Build a case expression
+ *
+ * Note: The two statements action_true and action_false must have the same
+ * data type (int, vchar, ...) in the database!
+ *
+ * @param string $condition The condition which must be true,
+ * to use action_true rather then action_else
+ * @param string $action_true SQL expression that is used, if the condition is true
+ * @param mixed $action_false SQL expression that is used, if the condition is false
+ * @return string CASE expression including the condition and statements
+ */
+ public function sql_case($condition, $action_true, $action_false = false);
+
+ /**
+ * Build sql statement from array for select and select distinct statements
+ *
+ * Possible query values: SELECT, SELECT_DISTINCT
+ *
+ * @param string $query Should be one of: SELECT, SELECT_DISTINCT
+ * @param array $array Array with the query data:
+ * SELECT A comma imploded list of columns to select
+ * FROM Array with "table => alias" pairs,
+ * (alias can also be an array)
+ * Optional: LEFT_JOIN Array of join entries:
+ * FROM Table that should be joined
+ * ON Condition for the join
+ * Optional: WHERE Where SQL statement
+ * Optional: GROUP_BY Group by SQL statement
+ * Optional: ORDER_BY Order by SQL statement
+ * @return string A SQL statement ready for execution
+ */
+ public function sql_build_query($query, $array);
+
+ /**
+ * Fetch field
+ * if rownum is false, the current row is used, else it is pointing to the row (zero-based)
+ *
+ * @param string $field Name of the column
+ * @param mixed $rownum Row number, if false the current row will be used
+ * and the row curser will point to the next row
+ * Note: $rownum is 0 based
+ * @param mixed $query_id Already executed query to get the rows from,
+ * if false, the last query will be used.
+ * @return mixed String value of the field in the selected row,
+ * false, if the row does not exist
+ */
+ public function sql_fetchfield($field, $rownum = false, $query_id = false);
+
+ /**
+ * Fetch current row
+ *
+ * @param mixed $query_id Already executed query to get the rows from,
+ * if false, the last query will be used.
+ * @return mixed Array with the current row,
+ * false, if the row does not exist
+ */
+ public function sql_fetchrow($query_id = false);
+
+ /**
+ * Returns SQL string to cast a string expression to an int.
+ *
+ * @param string $expression An expression evaluating to string
+ * @return string Expression returning an int
+ */
+ public function cast_expr_to_bigint($expression);
+
+ /**
+ * Get last inserted id after insert statement
+ *
+ * @return string Autoincrement value of the last inserted row
+ */
+ public function sql_nextid();
+
+ /**
+ * Add to query count
+ *
+ * @param bool $cached Is this query cached?
+ * @return null
+ */
+ public function sql_add_num_queries($cached = false);
+
+ /**
+ * Build LIMIT query
+ *
+ * @param string $query The SQL query to execute
+ * @param int $total The number of rows to select
+ * @param int $offset
+ * @param int $cache_ttl Either 0 to avoid caching or
+ * the time in seconds which the result shall be kept in cache
+ * @return mixed Buffered, seekable result handle, false on error
+ */
+ public function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0);
+
+ /**
+ * Base query method
+ *
+ * @param string $query The SQL query to execute
+ * @param int $cache_ttl Either 0 to avoid caching or
+ * the time in seconds which the result shall be kept in cache
+ * @return mixed Buffered, seekable result handle, false on error
+ */
+ public function sql_query($query = '', $cache_ttl = 0);
+
+ /**
+ * Returns SQL string to cast an integer expression to a string.
+ *
+ * @param string $expression An expression evaluating to int
+ * @return string Expression returning a string
+ */
+ public function cast_expr_to_string($expression);
+
+ /**
+ * Connect to server
+ *
+ * @param string $sqlserver Address of the database server
+ * @param string $sqluser User name of the SQL user
+ * @param string $sqlpassword Password of the SQL user
+ * @param string $database Name of the database
+ * @param mixed $port Port of the database server
+ * @param bool $persistency
+ * @param bool $new_link Should a new connection be established
+ * @return mixed Connection ID on success, string error message otherwise
+ */
+ public function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false);
+
+ /**
+ * Run binary AND operator on DB column.
+ * Results in sql statement: "{$column_name} & (1 << {$bit}) {$compare}"
+ *
+ * @param string $column_name The column name to use
+ * @param int $bit The value to use for the AND operator,
+ * will be converted to (1 << $bit). Is used by
+ * options, using the number schema: 0, 1, 2...29
+ * @param string $compare Any custom SQL code after the check (for example "= 0")
+ * @return string A SQL statement like: "{$column} & (1 << {$bit}) {$compare}"
+ */
+ public function sql_bit_and($column_name, $bit, $compare = '');
+
+ /**
+ * Free sql result
+ *
+ * @param mixed $query_id Already executed query result,
+ * if false, the last query will be used.
+ * @return null
+ */
+ public function sql_freeresult($query_id = false);
+
+ /**
+ * Return number of sql queries and cached sql queries used
+ *
+ * @param bool $cached Should we return the number of cached or normal queries?
+ * @return int Number of queries that have been executed
+ */
+ public function sql_num_queries($cached = false);
+
+ /**
+ * Run more than one insert statement.
+ *
+ * @param string $table Table name to run the statements on
+ * @param array $sql_ary Multi-dimensional array holding the statement data
+ * @return bool false if no statements were executed.
+ */
+ public function sql_multi_insert($table, $sql_ary);
+
+ /**
+ * Return number of affected rows
+ *
+ * @return mixed Number of the affected rows by the last query
+ * false if no query has been run before
+ */
+ public function sql_affectedrows();
+
+ /**
+ * DBAL garbage collection, close SQL connection
+ *
+ * @return mixed False if no connection was opened before,
+ * Server response otherwise
+ */
+ public function sql_close();
+
+ /**
+ * Seek to given row number
+ *
+ * @param mixed $rownum Row number the curser should point to
+ * Note: $rownum is 0 based
+ * @param mixed $query_id ID of the query to set the row cursor on
+ * if false, the last query will be used.
+ * $query_id will then be set correctly
+ * @return bool False if something went wrong
+ */
+ public function sql_rowseek($rownum, &$query_id);
+
+ /**
+ * Escape string used in sql query
+ *
+ * @param string $msg String to be escaped
+ * @return string Escaped version of $msg
+ */
+ public function sql_escape($msg);
+
+ /**
+ * Correctly adjust LIKE expression for special characters
+ * Some DBMS are handling them in a different way
+ *
+ * @param string $expression The expression to use. Every wildcard is
+ * escaped, except $this->any_char and $this->one_char
+ * @return string A SQL statement like: "LIKE 'bertie_%'"
+ */
+ public function sql_like_expression($expression);
+
+ /**
+ * Correctly adjust NOT LIKE expression for special characters
+ * Some DBMS are handling them in a different way
+ *
+ * @param string $expression The expression to use. Every wildcard is
+ * escaped, except $this->any_char and $this->one_char
+ * @return string A SQL statement like: "NOT LIKE 'bertie_%'"
+ */
+ public function sql_not_like_expression($expression);
+
+ /**
+ * Explain queries
+ *
+ * @param string $mode Available modes: display, start, stop,
+ * add_select_row, fromcache, record_fromcache
+ * @param string $query The Query that should be explained
+ * @return mixed Either a full HTML page, boolean or null
+ */
+ public function sql_report($mode, $query = '');
+
+ /**
+ * Build IN or NOT IN sql comparison string, uses <> or = on single element
+ * arrays to improve comparison speed
+ *
+ * @param string $field Name of the sql column that shall be compared
+ * @param array $array Array of values that are (not) allowed
+ * @param bool $negate true for NOT IN (), false for IN ()
+ * @param bool $allow_empty_set If true, allow $array to be empty,
+ * this function will return 1=1 or 1=0 then.
+ * @return string A SQL statement like: "IN (1, 2, 3, 4)" or "= 1"
+ */
+ public function sql_in_set($field, $array, $negate = false, $allow_empty_set = false);
+}
diff --git a/phpBB/phpbb/db/driver/factory.php b/phpBB/phpbb/db/driver/factory.php
new file mode 100644
index 0000000000..fb3a826254
--- /dev/null
+++ b/phpBB/phpbb/db/driver/factory.php
@@ -0,0 +1,443 @@
+<?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\driver;
+
+use \Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+* Database Abstraction Layer
+*/
+class factory implements driver_interface
+{
+ /**
+ * @var driver_interface
+ */
+ protected $driver = null;
+
+ /**
+ * @var ContainerInterface
+ */
+ protected $container;
+
+ /**
+ * Constructor.
+ *
+ * @param ContainerInterface $container A ContainerInterface instance
+ */
+ public function __construct(ContainerInterface $container)
+ {
+ $this->container = $container;
+ }
+
+ /**
+ * Return the current driver (and retrieved it from the container if necessary)
+ *
+ * @return driver_interface
+ */
+ protected function get_driver()
+ {
+ if ($this->driver === null)
+ {
+ $this->driver = $this->container->get('dbal.conn.driver');
+ }
+
+ return $this->driver;
+ }
+
+ /**
+ * Set the current driver
+ *
+ * @param driver_interface $driver
+ */
+ public function set_driver(driver_interface $driver)
+ {
+ $this->driver = $driver;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_sql_layer()
+ {
+ return $this->get_driver()->get_sql_layer();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_db_name()
+ {
+ return $this->get_driver()->get_db_name();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_any_char()
+ {
+ return $this->get_driver()->get_any_char();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_one_char()
+ {
+ return $this->get_driver()->get_one_char();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_db_connect_id()
+ {
+ return $this->get_driver()->get_db_connect_id();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_sql_error_triggered()
+ {
+ return $this->get_driver()->get_sql_error_triggered();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_sql_error_sql()
+ {
+ return $this->get_driver()->get_sql_error_sql();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_transaction()
+ {
+ return $this->get_driver()->get_transaction();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_sql_time()
+ {
+ return $this->get_driver()->get_sql_time();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_sql_error_returned()
+ {
+ return $this->get_driver()->get_sql_error_returned();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_multi_insert()
+ {
+ return $this->get_driver()->get_multi_insert();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set_multi_insert($multi_insert)
+ {
+ $this->get_driver()->set_multi_insert($multi_insert);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_row_count($table_name)
+ {
+ return $this->get_driver()->get_row_count($table_name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_estimated_row_count($table_name)
+ {
+ return $this->get_driver()->get_estimated_row_count($table_name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_lower_text($column_name)
+ {
+ return $this->get_driver()->sql_lower_text($column_name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_error($sql = '')
+ {
+ return $this->get_driver()->sql_error($sql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_buffer_nested_transactions()
+ {
+ return $this->get_driver()->sql_buffer_nested_transactions();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_bit_or($column_name, $bit, $compare = '')
+ {
+ return $this->get_driver()->sql_bit_or($column_name, $bit, $compare);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_server_info($raw = false, $use_cache = true)
+ {
+ return $this->get_driver()->sql_server_info($raw, $use_cache);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_return_on_error($fail = false)
+ {
+ return $this->get_driver()->sql_return_on_error($fail);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_build_array($query, $assoc_ary = array())
+ {
+ return $this->get_driver()->sql_build_array($query, $assoc_ary);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_fetchrowset($query_id = false)
+ {
+ return $this->get_driver()->sql_fetchrowset($query_id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_transaction($status = 'begin')
+ {
+ return $this->get_driver()->sql_transaction($status);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_concatenate($expr1, $expr2)
+ {
+ return $this->get_driver()->sql_concatenate($expr1, $expr2);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_case($condition, $action_true, $action_false = false)
+ {
+ return $this->get_driver()->sql_case($condition, $action_true, $action_false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_build_query($query, $array)
+ {
+ return $this->get_driver()->sql_build_query($query, $array);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_fetchfield($field, $rownum = false, $query_id = false)
+ {
+ return $this->get_driver()->sql_fetchfield($field, $rownum, $query_id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_fetchrow($query_id = false)
+ {
+ return $this->get_driver()->sql_fetchrow($query_id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function cast_expr_to_bigint($expression)
+ {
+ return $this->get_driver()->cast_expr_to_bigint($expression);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_nextid()
+ {
+ return $this->get_driver()->sql_nextid();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_add_num_queries($cached = false)
+ {
+ return $this->get_driver()->sql_add_num_queries($cached);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
+ {
+ return $this->get_driver()->sql_query_limit($query, $total, $offset, $cache_ttl);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_query($query = '', $cache_ttl = 0)
+ {
+ return $this->get_driver()->sql_query($query, $cache_ttl);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function cast_expr_to_string($expression)
+ {
+ return $this->get_driver()->cast_expr_to_string($expression);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
+ {
+ throw new \Exception('Disabled method.');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_bit_and($column_name, $bit, $compare = '')
+ {
+ return $this->get_driver()->sql_bit_and($column_name, $bit, $compare);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_freeresult($query_id = false)
+ {
+ return $this->get_driver()->sql_freeresult($query_id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_num_queries($cached = false)
+ {
+ return $this->get_driver()->sql_num_queries($cached);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_multi_insert($table, $sql_ary)
+ {
+ return $this->get_driver()->sql_multi_insert($table, $sql_ary);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_affectedrows()
+ {
+ return $this->get_driver()->sql_affectedrows();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_close()
+ {
+ return $this->get_driver()->sql_close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_rowseek($rownum, &$query_id)
+ {
+ return $this->get_driver()->sql_rowseek($rownum, $query_id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_escape($msg)
+ {
+ return $this->get_driver()->sql_escape($msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_like_expression($expression)
+ {
+ return $this->get_driver()->sql_like_expression($expression);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_not_like_expression($expression)
+ {
+ return $this->get_driver()->sql_not_like_expression($expression);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_report($mode, $query = '')
+ {
+ return $this->get_driver()->sql_report($mode, $query);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sql_in_set($field, $array, $negate = false, $allow_empty_set = false)
+ {
+ return $this->get_driver()->sql_in_set($field, $array, $negate, $allow_empty_set);
+ }
+}
diff --git a/phpBB/phpbb/db/driver/firebird.php b/phpBB/phpbb/db/driver/firebird.php
deleted file mode 100644
index ed56a5d154..0000000000
--- a/phpBB/phpbb/db/driver/firebird.php
+++ /dev/null
@@ -1,532 +0,0 @@
-<?php
-/**
-*
-* @package dbal
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
-*
-*/
-
-namespace phpbb\db\driver;
-
-/**
-* Firebird/Interbase Database Abstraction Layer
-* Minimum Requirement is Firebird 2.1
-* @package dbal
-*/
-class firebird extends \phpbb\db\driver\driver
-{
- var $last_query_text = '';
- var $service_handle = false;
- var $affected_rows = 0;
- var $connect_error = '';
-
- /**
- * Connect to server
- */
- function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
- {
- $this->persistency = $persistency;
- $this->user = $sqluser;
- $this->server = $sqlserver . (($port) ? ':' . $port : '');
- $this->dbname = str_replace('\\', '/', $database);
-
- // There are three possibilities to connect to an interbase db
- if (!$this->server)
- {
- $use_database = $this->dbname;
- }
- else if (strpos($this->server, '//') === 0)
- {
- $use_database = $this->server . $this->dbname;
- }
- else
- {
- $use_database = $this->server . ':' . $this->dbname;
- }
-
- if ($this->persistency)
- {
- if (!function_exists('ibase_pconnect'))
- {
- $this->connect_error = 'ibase_pconnect function does not exist, is interbase extension installed?';
- return $this->sql_error('');
- }
- $this->db_connect_id = @ibase_pconnect($use_database, $this->user, $sqlpassword, false, false, 3);
- }
- else
- {
- if (!function_exists('ibase_connect'))
- {
- $this->connect_error = 'ibase_connect function does not exist, is interbase extension installed?';
- return $this->sql_error('');
- }
- $this->db_connect_id = @ibase_connect($use_database, $this->user, $sqlpassword, false, false, 3);
- }
-
- // Do not call ibase_service_attach if connection failed,
- // otherwise error message from ibase_(p)connect call will be clobbered.
- if ($this->db_connect_id && function_exists('ibase_service_attach') && $this->server)
- {
- $this->service_handle = @ibase_service_attach($this->server, $this->user, $sqlpassword);
- }
- else
- {
- $this->service_handle = false;
- }
-
- return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
- }
-
- /**
- * Version information about used database
- * @param bool $raw if true, only return the fetched sql_server_version
- * @param bool $use_cache forced to false for Interbase
- * @return string sql server version
- */
- function sql_server_info($raw = false, $use_cache = true)
- {
- /**
- * force $use_cache false. I didn't research why the caching code there is no caching code
- * but I assume its because the IB extension provides a direct method to access it
- * without a query.
- */
-
- $use_cache = false;
-
- if ($this->service_handle !== false && function_exists('ibase_server_info'))
- {
- return @ibase_server_info($this->service_handle, IBASE_SVC_SERVER_VERSION);
- }
-
- return ($raw) ? '2.1' : 'Firebird/Interbase';
- }
-
- /**
- * SQL Transaction
- * @access private
- */
- function _sql_transaction($status = 'begin')
- {
- switch ($status)
- {
- case 'begin':
- return true;
- break;
-
- case 'commit':
- return @ibase_commit();
- break;
-
- case 'rollback':
- return @ibase_rollback();
- break;
- }
-
- return true;
- }
-
- /**
- * Base query method
- *
- * @param string $query Contains the SQL query which shall be executed
- * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
- * @return mixed When casted to bool the returned value returns true on success and false on failure
- *
- * @access public
- */
- function sql_query($query = '', $cache_ttl = 0)
- {
- if ($query != '')
- {
- global $cache;
-
- // EXPLAIN only in extra debug mode
- if (defined('DEBUG'))
- {
- $this->sql_report('start', $query);
- }
-
- $this->last_query_text = $query;
- $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
- $this->sql_add_num_queries($this->query_result);
-
- if ($this->query_result === false)
- {
- $array = array();
- // We overcome Firebird's 32767 char limit by binding vars
- if (strlen($query) > 32767)
- {
- if (preg_match('/^(INSERT INTO[^(]++)\\(([^()]+)\\) VALUES[^(]++\\((.*?)\\)$/s', $query, $regs))
- {
- if (strlen($regs[3]) > 32767)
- {
- preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER);
-
- $inserts = $vals[0];
- unset($vals);
-
- foreach ($inserts as $key => $value)
- {
- if (!empty($value) && $value[0] === "'" && strlen($value) > 32769) // check to see if this thing is greater than the max + 'x2
- {
- $inserts[$key] = '?';
- $array[] = str_replace("''", "'", substr($value, 1, -1));
- }
- }
-
- $query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')';
- }
- }
- else if (preg_match('/^(UPDATE ([\\w_]++)\\s+SET )([\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|\\d+)(?:,\\s*[\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+))*+)\\s+(WHERE.*)$/s', $query, $data))
- {
- if (strlen($data[3]) > 32767)
- {
- $update = $data[1];
- $where = $data[4];
- preg_match_all('/(\\w++)\\s*=\\s*(\'(?:[^\']++|\'\')*+\'|[\d-.]++)/', $data[3], $temp, PREG_SET_ORDER);
- unset($data);
-
- $cols = array();
- foreach ($temp as $value)
- {
- if (!empty($value[2]) && $value[2][0] === "'" && strlen($value[2]) > 32769) // check to see if this thing is greater than the max + 'x2
- {
- $array[] = str_replace("''", "'", substr($value[2], 1, -1));
- $cols[] = $value[1] . '=?';
- }
- else
- {
- $cols[] = $value[1] . '=' . $value[2];
- }
- }
-
- $query = $update . implode(', ', $cols) . ' ' . $where;
- unset($cols);
- }
- }
- }
-
- if (!function_exists('ibase_affected_rows') && (preg_match('/^UPDATE ([\w_]++)\s+SET [\w_]++\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+)(?:,\s*[\w_]++\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+))*+\s+(WHERE.*)?$/s', $query, $regs) || preg_match('/^DELETE FROM ([\w_]++)\s*(WHERE\s*.*)?$/s', $query, $regs)))
- {
- $affected_sql = 'SELECT COUNT(*) as num_rows_affected FROM ' . $regs[1];
- if (!empty($regs[2]))
- {
- $affected_sql .= ' ' . $regs[2];
- }
-
- if (!($temp_q_id = @ibase_query($this->db_connect_id, $affected_sql)))
- {
- return false;
- }
-
- $temp_result = @ibase_fetch_assoc($temp_q_id);
- @ibase_free_result($temp_q_id);
-
- $this->affected_rows = ($temp_result) ? $temp_result['NUM_ROWS_AFFECTED'] : false;
- }
-
- if (sizeof($array))
- {
- $p_query = @ibase_prepare($this->db_connect_id, $query);
- array_unshift($array, $p_query);
- $this->query_result = call_user_func_array('ibase_execute', $array);
- unset($array);
-
- if ($this->query_result === false)
- {
- $this->sql_error($query);
- }
- }
- else if (($this->query_result = @ibase_query($this->db_connect_id, $query)) === false)
- {
- $this->sql_error($query);
- }
-
- if (defined('DEBUG'))
- {
- $this->sql_report('stop', $query);
- }
-
- if (!$this->transaction)
- {
- if (function_exists('ibase_commit_ret'))
- {
- @ibase_commit_ret();
- }
- else
- {
- // way cooler than ibase_commit_ret :D
- @ibase_query('COMMIT RETAIN;');
- }
- }
-
- if ($cache && $cache_ttl)
- {
- $this->open_queries[(int) $this->query_result] = $this->query_result;
- $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
- }
- else if (strpos($query, 'SELECT') === 0 && $this->query_result)
- {
- $this->open_queries[(int) $this->query_result] = $this->query_result;
- }
- }
- else if (defined('DEBUG'))
- {
- $this->sql_report('fromcache', $query);
- }
- }
- else
- {
- return false;
- }
-
- return $this->query_result;
- }
-
- /**
- * Build LIMIT query
- */
- function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
- {
- $this->query_result = false;
-
- $query = 'SELECT FIRST ' . $total . ((!empty($offset)) ? ' SKIP ' . $offset : '') . substr($query, 6);
-
- return $this->sql_query($query, $cache_ttl);
- }
-
- /**
- * Return number of affected rows
- */
- function sql_affectedrows()
- {
- // PHP 5+ function
- if (function_exists('ibase_affected_rows'))
- {
- return ($this->db_connect_id) ? @ibase_affected_rows($this->db_connect_id) : false;
- }
- else
- {
- return $this->affected_rows;
- }
- }
-
- /**
- * Fetch current row
- */
- function sql_fetchrow($query_id = false)
- {
- global $cache;
-
- if ($query_id === false)
- {
- $query_id = $this->query_result;
- }
-
- if ($cache && $cache->sql_exists($query_id))
- {
- return $cache->sql_fetchrow($query_id);
- }
-
- if ($query_id === false)
- {
- return false;
- }
-
- $row = array();
- $cur_row = @ibase_fetch_object($query_id, IBASE_TEXT);
-
- if (!$cur_row)
- {
- return false;
- }
-
- foreach (get_object_vars($cur_row) as $key => $value)
- {
- $row[strtolower($key)] = (is_string($value)) ? trim(str_replace(array("\\0", "\\n"), array("\0", "\n"), $value)) : $value;
- }
-
- return (sizeof($row)) ? $row : false;
- }
-
- /**
- * Get last inserted id after insert statement
- */
- function sql_nextid()
- {
- $query_id = $this->query_result;
-
- if ($query_id !== false && $this->last_query_text != '')
- {
- if ($this->query_result && preg_match('#^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)#i', $this->last_query_text, $tablename))
- {
- $sql = 'SELECT GEN_ID(' . $tablename[1] . '_gen, 0) AS new_id FROM RDB$DATABASE';
-
- if (!($temp_q_id = @ibase_query($this->db_connect_id, $sql)))
- {
- return false;
- }
-
- $temp_result = @ibase_fetch_assoc($temp_q_id);
- @ibase_free_result($temp_q_id);
-
- return ($temp_result) ? $temp_result['NEW_ID'] : false;
- }
- }
-
- return false;
- }
-
- /**
- * Free sql result
- */
- function sql_freeresult($query_id = false)
- {
- global $cache;
-
- if ($query_id === false)
- {
- $query_id = $this->query_result;
- }
-
- if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
- {
- return $cache->sql_freeresult($query_id);
- }
-
- if (isset($this->open_queries[(int) $query_id]))
- {
- unset($this->open_queries[(int) $query_id]);
- return @ibase_free_result($query_id);
- }
-
- return false;
- }
-
- /**
- * Escape string used in sql query
- */
- function sql_escape($msg)
- {
- return str_replace(array("'", "\0"), array("''", ''), $msg);
- }
-
- /**
- * Build LIKE expression
- * @access private
- */
- function _sql_like_expression($expression)
- {
- return $expression . " ESCAPE '\\'";
- }
-
- /**
- * Build db-specific query data
- * @access private
- */
- function _sql_custom_build($stage, $data)
- {
- return $data;
- }
-
- function _sql_bit_and($column_name, $bit, $compare = '')
- {
- return 'BIN_AND(' . $column_name . ', ' . (1 << $bit) . ')' . (($compare) ? ' ' . $compare : '');
- }
-
- function _sql_bit_or($column_name, $bit, $compare = '')
- {
- return 'BIN_OR(' . $column_name . ', ' . (1 << $bit) . ')' . (($compare) ? ' ' . $compare : '');
- }
-
- /**
- * @inheritdoc
- */
- function cast_expr_to_bigint($expression)
- {
- // Precision must be from 1 to 18
- return 'CAST(' . $expression . ' as DECIMAL(18, 0))';
- }
-
- /**
- * @inheritdoc
- */
- function cast_expr_to_string($expression)
- {
- return 'CAST(' . $expression . ' as VARCHAR(255))';
- }
-
- /**
- * return sql error array
- * @access private
- */
- function _sql_error()
- {
- // Need special handling here because ibase_errmsg returns
- // connection errors, however if the interbase extension
- // is not installed then ibase_errmsg does not exist and
- // we cannot call it.
- if (function_exists('ibase_errmsg'))
- {
- $msg = @ibase_errmsg();
- if (!$msg)
- {
- $msg = $this->connect_error;
- }
- }
- else
- {
- $msg = $this->connect_error;
- }
- return array(
- 'message' => $msg,
- 'code' => (@function_exists('ibase_errcode') ? @ibase_errcode() : '')
- );
- }
-
- /**
- * Close sql connection
- * @access private
- */
- function _sql_close()
- {
- if ($this->service_handle !== false)
- {
- @ibase_service_detach($this->service_handle);
- }
-
- return @ibase_close($this->db_connect_id);
- }
-
- /**
- * Build db-specific report
- * @access private
- */
- function _sql_report($mode, $query = '')
- {
- switch ($mode)
- {
- case 'start':
- break;
-
- case 'fromcache':
- $endtime = explode(' ', microtime());
- $endtime = $endtime[0] + $endtime[1];
-
- $result = @ibase_query($this->db_connect_id, $query);
- while ($void = @ibase_fetch_object($result, IBASE_TEXT))
- {
- // Take the time spent on parsing rows into account
- }
- @ibase_free_result($result);
-
- $splittime = explode(' ', microtime());
- $splittime = $splittime[0] + $splittime[1];
-
- $this->sql_report('record_fromcache', $query, $endtime, $splittime);
-
- break;
- }
- }
-}
diff --git a/phpBB/phpbb/db/driver/mssql.php b/phpBB/phpbb/db/driver/mssql.php
index 6ebc891673..f9ea884ce2 100644
--- a/phpBB/phpbb/db/driver/mssql.php
+++ b/phpBB/phpbb/db/driver/mssql.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,14 +16,13 @@ namespace phpbb\db\driver;
/**
* MSSQL Database Abstraction Layer
* Minimum Requirement is MSSQL 2000+
-* @package dbal
*/
class mssql extends \phpbb\db\driver\driver
{
var $connect_error = '';
/**
- * Connect to server
+ * {@inheritDoc}
*/
function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
{
@@ -55,10 +58,7 @@ class mssql extends \phpbb\db\driver\driver
}
/**
- * Version information about used database
- * @param bool $raw if true, only return the fetched sql_server_version
- * @param bool $use_cache If true, it is safe to retrieve the value from the cache
- * @return string sql server version
+ * {@inheritDoc}
*/
function sql_server_info($raw = false, $use_cache = true)
{
@@ -124,13 +124,7 @@ class mssql extends \phpbb\db\driver\driver
}
/**
- * Base query method
- *
- * @param string $query Contains the SQL query which shall be executed
- * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
- * @return mixed When casted to bool the returned value returns true on success and false on failure
- *
- * @access public
+ * {@inheritDoc}
*/
function sql_query($query = '', $cache_ttl = 0)
{
@@ -143,6 +137,10 @@ class mssql extends \phpbb\db\driver\driver
{
$this->sql_report('start', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->curtime = microtime(true);
+ }
$this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
$this->sql_add_num_queries($this->query_result);
@@ -158,6 +156,10 @@ class mssql extends \phpbb\db\driver\driver
{
$this->sql_report('stop', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->sql_time += microtime(true) - $this->curtime;
+ }
if ($cache && $cache_ttl)
{
@@ -215,7 +217,7 @@ class mssql extends \phpbb\db\driver\driver
}
/**
- * Return number of affected rows
+ * {@inheritDoc}
*/
function sql_affectedrows()
{
@@ -223,7 +225,7 @@ class mssql extends \phpbb\db\driver\driver
}
/**
- * Fetch current row
+ * {@inheritDoc}
*/
function sql_fetchrow($query_id = false)
{
@@ -259,8 +261,7 @@ class mssql extends \phpbb\db\driver\driver
}
/**
- * Seek to given row number
- * rownum is zero-based
+ * {@inheritDoc}
*/
function sql_rowseek($rownum, &$query_id)
{
@@ -280,7 +281,7 @@ class mssql extends \phpbb\db\driver\driver
}
/**
- * Get last inserted id after insert statement
+ * {@inheritDoc}
*/
function sql_nextid()
{
@@ -299,7 +300,7 @@ class mssql extends \phpbb\db\driver\driver
}
/**
- * Free sql result
+ * {@inheritDoc}
*/
function sql_freeresult($query_id = false)
{
@@ -325,7 +326,7 @@ class mssql extends \phpbb\db\driver\driver
}
/**
- * Escape string used in sql query
+ * {@inheritDoc}
*/
function sql_escape($msg)
{
@@ -350,6 +351,15 @@ class mssql extends \phpbb\db\driver\driver
}
/**
+ * Build NOT LIKE expression
+ * @access private
+ */
+ function _sql_not_like_expression($expression)
+ {
+ return $expression . " ESCAPE '\\'";
+ }
+
+ /**
* return sql error array
* @access private
*/
diff --git a/phpBB/phpbb/db/driver/mssql_base.php b/phpBB/phpbb/db/driver/mssql_base.php
index 113f1c6902..514df9eaca 100644
--- a/phpBB/phpbb/db/driver/mssql_base.php
+++ b/phpBB/phpbb/db/driver/mssql_base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\db\driver;
/**
* MSSQL Database Base Abstraction Layer
-* @package dbal
*/
abstract class mssql_base extends \phpbb\db\driver\driver
{
@@ -24,7 +27,7 @@ abstract class mssql_base extends \phpbb\db\driver\driver
}
/**
- * Escape string used in sql query
+ * {@inheritDoc}
*/
function sql_escape($msg)
{
@@ -49,6 +52,15 @@ abstract class mssql_base extends \phpbb\db\driver\driver
}
/**
+ * Build NOT LIKE expression
+ * @access private
+ */
+ function _sql_not_like_expression($expression)
+ {
+ return $expression . " ESCAPE '\\'";
+ }
+
+ /**
* Build db-specific query data
* @access private
*/
diff --git a/phpBB/phpbb/db/driver/mssql_odbc.php b/phpBB/phpbb/db/driver/mssql_odbc.php
index f8c70f1cd7..8e5d4c7a4c 100644
--- a/phpBB/phpbb/db/driver/mssql_odbc.php
+++ b/phpBB/phpbb/db/driver/mssql_odbc.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -17,8 +21,6 @@ namespace phpbb\db\driver;
* @note number of bytes returned for returning data depends on odbc.defaultlrl php.ini setting.
* If it is limited to 4K for example only 4K of data is returned max, resulting in incomplete theme data for example.
* @note odbc.defaultbinmode may affect UTF8 characters
-*
-* @package dbal
*/
class mssql_odbc extends \phpbb\db\driver\mssql_base
{
@@ -26,7 +28,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
var $connect_error = '';
/**
- * Connect to server
+ * {@inheritDoc}
*/
function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
{
@@ -83,10 +85,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
}
/**
- * Version information about used database
- * @param bool $raw if true, only return the fetched sql_server_version
- * @param bool $use_cache If true, it is safe to retrieve the value from the cache
- * @return string sql server version
+ * {@inheritDoc}
*/
function sql_server_info($raw = false, $use_cache = true)
{
@@ -144,13 +143,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
}
/**
- * Base query method
- *
- * @param string $query Contains the SQL query which shall be executed
- * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
- * @return mixed When casted to bool the returned value returns true on success and false on failure
- *
- * @access public
+ * {@inheritDoc}
*/
function sql_query($query = '', $cache_ttl = 0)
{
@@ -163,6 +156,10 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
{
$this->sql_report('start', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->curtime = microtime(true);
+ }
$this->last_query_text = $query;
$this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
@@ -179,6 +176,10 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
{
$this->sql_report('stop', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->sql_time += microtime(true) - $this->curtime;
+ }
if ($cache && $cache_ttl)
{
@@ -236,7 +237,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
}
/**
- * Return number of affected rows
+ * {@inheritDoc}
*/
function sql_affectedrows()
{
@@ -244,8 +245,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
}
/**
- * Fetch current row
- * @note number of bytes returned depends on odbc.defaultlrl php.ini setting. If it is limited to 4K for example only 4K of data is returned max.
+ * {@inheritDoc}
*/
function sql_fetchrow($query_id = false)
{
@@ -265,7 +265,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
}
/**
- * Get last inserted id after insert statement
+ * {@inheritDoc}
*/
function sql_nextid()
{
@@ -286,7 +286,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
}
/**
- * Free sql result
+ * {@inheritDoc}
*/
function sql_freeresult($query_id = false)
{
diff --git a/phpBB/phpbb/db/driver/mssqlnative.php b/phpBB/phpbb/db/driver/mssqlnative.php
index 125db9c8d4..46a9b3a477 100644
--- a/phpBB/phpbb/db/driver/mssqlnative.php
+++ b/phpBB/phpbb/db/driver/mssqlnative.php
@@ -1,10 +1,17 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
+*
+*/
+
+/**
* This is the MS SQL Server Native database abstraction layer.
* PHP mssql native driver required.
* @author Chris Pucci
@@ -13,9 +20,6 @@
namespace phpbb\db\driver;
-/**
-* @package dbal
-*/
class mssqlnative extends \phpbb\db\driver\mssql_base
{
var $m_insert_id = null;
@@ -24,7 +28,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
var $connect_error = '';
/**
- * Connect to server
+ * {@inheritDoc}
*/
function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
{
@@ -53,10 +57,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
}
/**
- * Version information about used database
- * @param bool $raw if true, only return the fetched sql_server_version
- * @param bool $use_cache If true, it is safe to retrieve the value from the cache
- * @return string sql server version
+ * {@inheritDoc}
*/
function sql_server_info($raw = false, $use_cache = true)
{
@@ -113,13 +114,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
}
/**
- * Base query method
- *
- * @param string $query Contains the SQL query which shall be executed
- * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
- * @return mixed When casted to bool the returned value returns true on success and false on failure
- *
- * @access public
+ * {@inheritDoc}
*/
function sql_query($query = '', $cache_ttl = 0)
{
@@ -132,6 +127,10 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
{
$this->sql_report('start', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->curtime = microtime(true);
+ }
$this->last_query_text = $query;
$this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
@@ -150,6 +149,10 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
{
$this->sql_report('stop', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->sql_time += microtime(true) - $this->curtime;
+ }
if ($cache && $cache_ttl)
{
@@ -215,7 +218,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
}
/**
- * Return number of affected rows
+ * {@inheritDoc}
*/
function sql_affectedrows()
{
@@ -223,7 +226,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
}
/**
- * Fetch current row
+ * {@inheritDoc}
*/
function sql_fetchrow($query_id = false)
{
@@ -263,7 +266,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
}
/**
- * Get last inserted id after insert statement
+ * {@inheritDoc}
*/
function sql_nextid()
{
@@ -283,7 +286,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
}
/**
- * Free sql result
+ * {@inheritDoc}
*/
function sql_freeresult($query_id = false)
{
@@ -324,10 +327,10 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
{
foreach ($errors as $error)
{
- $error_message .= "SQLSTATE: " . $error[ 'SQLSTATE'] . "\n";
- $error_message .= "code: " . $error[ 'code'] . "\n";
+ $error_message .= "SQLSTATE: " . $error['SQLSTATE'] . "\n";
+ $error_message .= "code: " . $error['code'] . "\n";
$code = $error['code'];
- $error_message .= "message: " . $error[ 'message'] . "\n";
+ $error_message .= "message: " . $error['message'] . "\n";
}
$this->last_error_result = $error_message;
$error = $this->last_error_result;
diff --git a/phpBB/phpbb/db/driver/mysql.php b/phpBB/phpbb/db/driver/mysql.php
index e311f0dd74..e93c7239e8 100644
--- a/phpBB/phpbb/db/driver/mysql.php
+++ b/phpBB/phpbb/db/driver/mysql.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -16,7 +20,6 @@ namespace phpbb\db\driver;
* MySQL 4.0+
* MySQL 4.1+
* MySQL 5.0+
-* @package dbal
*/
class mysql extends \phpbb\db\driver\mysql_base
{
@@ -24,8 +27,7 @@ class mysql extends \phpbb\db\driver\mysql_base
var $connect_error = '';
/**
- * Connect to server
- * @access public
+ * {@inheritDoc}
*/
function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
{
@@ -103,10 +105,7 @@ class mysql extends \phpbb\db\driver\mysql_base
}
/**
- * Version information about used database
- * @param bool $raw if true, only return the fetched sql_server_version
- * @param bool $use_cache If true, it is safe to retrieve the value from the cache
- * @return string sql server version
+ * {@inheritDoc}
*/
function sql_server_info($raw = false, $use_cache = true)
{
@@ -154,13 +153,7 @@ class mysql extends \phpbb\db\driver\mysql_base
}
/**
- * Base query method
- *
- * @param string $query Contains the SQL query which shall be executed
- * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
- * @return mixed When casted to bool the returned value returns true on success and false on failure
- *
- * @access public
+ * {@inheritDoc}
*/
function sql_query($query = '', $cache_ttl = 0)
{
@@ -173,6 +166,10 @@ class mysql extends \phpbb\db\driver\mysql_base
{
$this->sql_report('start', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->curtime = microtime(true);
+ }
$this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
$this->sql_add_num_queries($this->query_result);
@@ -188,6 +185,10 @@ class mysql extends \phpbb\db\driver\mysql_base
{
$this->sql_report('stop', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->sql_time += microtime(true) - $this->curtime;
+ }
if ($cache && $cache_ttl)
{
@@ -213,15 +214,34 @@ class mysql extends \phpbb\db\driver\mysql_base
}
/**
- * Return number of affected rows
+ * {@inheritDoc}
*/
function sql_affectedrows()
{
- return ($this->db_connect_id) ? @mysql_affected_rows($this->db_connect_id) : false;
+ if ($this->db_connect_id)
+ {
+ // We always want the number of matched rows
+ // instead of changed rows, when running an update.
+ // So when mysql_info() returns the number of matched rows
+ // we return that one instead of mysql_affected_rows()
+ $mysql_info = @mysql_info($this->db_connect_id);
+ if ($mysql_info !== false)
+ {
+ $match = array();
+ preg_match('#^Rows matched: (\d)+ Changed: (\d)+ Warnings: (\d)+$#', $mysql_info, $match);
+ if (isset($match[1]))
+ {
+ return $match[1];
+ }
+ }
+
+ return @mysql_affected_rows($this->db_connect_id);
+ }
+ return false;
}
/**
- * Fetch current row
+ * {@inheritDoc}
*/
function sql_fetchrow($query_id = false)
{
@@ -241,8 +261,7 @@ class mysql extends \phpbb\db\driver\mysql_base
}
/**
- * Seek to given row number
- * rownum is zero-based
+ * {@inheritDoc}
*/
function sql_rowseek($rownum, &$query_id)
{
@@ -262,7 +281,7 @@ class mysql extends \phpbb\db\driver\mysql_base
}
/**
- * Get last inserted id after insert statement
+ * {@inheritDoc}
*/
function sql_nextid()
{
@@ -270,7 +289,7 @@ class mysql extends \phpbb\db\driver\mysql_base
}
/**
- * Free sql result
+ * {@inheritDoc}
*/
function sql_freeresult($query_id = false)
{
@@ -296,7 +315,7 @@ class mysql extends \phpbb\db\driver\mysql_base
}
/**
- * Escape string used in sql query
+ * {@inheritDoc}
*/
function sql_escape($msg)
{
diff --git a/phpBB/phpbb/db/driver/mysql_base.php b/phpBB/phpbb/db/driver/mysql_base.php
index 87b6d153a9..5e0b359134 100644
--- a/phpBB/phpbb/db/driver/mysql_base.php
+++ b/phpBB/phpbb/db/driver/mysql_base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\db\driver;
/**
* Abstract MySQL Database Base Abstraction Layer
-* @package dbal
*/
abstract class mysql_base extends \phpbb\db\driver\driver
{
@@ -43,14 +46,7 @@ abstract class mysql_base extends \phpbb\db\driver\driver
}
/**
- * Gets the estimated number of rows in a specified table.
- *
- * @param string $table_name Table name
- *
- * @return string Number of rows in $table_name.
- * Prefixed with ~ if estimated (otherwise exact).
- *
- * @access public
+ * {@inheritDoc}
*/
function get_estimated_row_count($table_name)
{
@@ -72,13 +68,7 @@ abstract class mysql_base extends \phpbb\db\driver\driver
}
/**
- * Gets the exact number of rows in a specified table.
- *
- * @param string $table_name Table name
- *
- * @return string Exact number of rows in $table_name.
- *
- * @access public
+ * {@inheritDoc}
*/
function get_row_count($table_name)
{
@@ -122,6 +112,15 @@ abstract class mysql_base extends \phpbb\db\driver\driver
}
/**
+ * Build NOT LIKE expression
+ * @access private
+ */
+ function _sql_not_like_expression($expression)
+ {
+ return $expression;
+ }
+
+ /**
* Build db-specific query data
* @access private
*/
diff --git a/phpBB/phpbb/db/driver/mysqli.php b/phpBB/phpbb/db/driver/mysqli.php
index adc8f96302..2ed08211ad 100644
--- a/phpBB/phpbb/db/driver/mysqli.php
+++ b/phpBB/phpbb/db/driver/mysqli.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,7 +17,6 @@ namespace phpbb\db\driver;
* MySQLi Database Abstraction Layer
* mysqli-extension has to be compiled with:
* MySQL 4.1+ or MySQL 5.0+
-* @package dbal
*/
class mysqli extends \phpbb\db\driver\mysql_base
{
@@ -21,7 +24,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
var $connect_error = '';
/**
- * Connect to server
+ * {@inheritDoc}
*/
function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
{
@@ -57,7 +60,12 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
}
- $this->db_connect_id = @mysqli_connect($this->server, $this->user, $sqlpassword, $this->dbname, $port, $socket);
+ $this->db_connect_id = mysqli_init();
+
+ if (!@mysqli_real_connect($this->db_connect_id, $this->server, $this->user, $sqlpassword, $this->dbname, $port, $socket, MYSQLI_CLIENT_FOUND_ROWS))
+ {
+ $this->db_connect_id = '';
+ }
if ($this->db_connect_id && $this->dbname != '')
{
@@ -67,10 +75,17 @@ class mysqli extends \phpbb\db\driver\mysql_base
if (version_compare($this->sql_server_info(true), '5.0.2', '>='))
{
$result = @mysqli_query($this->db_connect_id, 'SELECT @@session.sql_mode AS sql_mode');
- $row = @mysqli_fetch_assoc($result);
- @mysqli_free_result($result);
+ if ($result !== null)
+ {
+ $row = @mysqli_fetch_assoc($result);
- $modes = array_map('trim', explode(',', $row['sql_mode']));
+ $modes = array_map('trim', explode(',', $row['sql_mode']));
+ }
+ else
+ {
+ $modes = array();
+ }
+ @mysqli_free_result($result);
// TRADITIONAL includes STRICT_ALL_TABLES and STRICT_TRANS_TABLES
if (!in_array('TRADITIONAL', $modes))
@@ -96,10 +111,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
/**
- * Version information about used database
- * @param bool $raw if true, only return the fetched sql_server_version
- * @param bool $use_cache If true, it is safe to retrieve the value from the cache
- * @return string sql server version
+ * {@inheritDoc}
*/
function sql_server_info($raw = false, $use_cache = true)
{
@@ -108,15 +120,18 @@ class mysqli extends \phpbb\db\driver\mysql_base
if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mysqli_version')) === false)
{
$result = @mysqli_query($this->db_connect_id, 'SELECT VERSION() AS version');
- $row = @mysqli_fetch_assoc($result);
- @mysqli_free_result($result);
+ if ($result !== null)
+ {
+ $row = @mysqli_fetch_assoc($result);
- $this->sql_server_version = $row['version'];
+ $this->sql_server_version = $row['version'];
- if (!empty($cache) && $use_cache)
- {
- $cache->put('mysqli_version', $this->sql_server_version);
+ if (!empty($cache) && $use_cache)
+ {
+ $cache->put('mysqli_version', $this->sql_server_version);
+ }
}
+ @mysqli_free_result($result);
}
return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version;
@@ -151,13 +166,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
/**
- * Base query method
- *
- * @param string $query Contains the SQL query which shall be executed
- * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
- * @return mixed When casted to bool the returned value returns true on success and false on failure
- *
- * @access public
+ * {@inheritDoc}
*/
function sql_query($query = '', $cache_ttl = 0)
{
@@ -170,6 +179,10 @@ class mysqli extends \phpbb\db\driver\mysql_base
{
$this->sql_report('start', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->curtime = microtime(true);
+ }
$this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
$this->sql_add_num_queries($this->query_result);
@@ -185,6 +198,10 @@ class mysqli extends \phpbb\db\driver\mysql_base
{
$this->sql_report('stop', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->sql_time += microtime(true) - $this->curtime;
+ }
if ($cache && $cache_ttl)
{
@@ -205,7 +222,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
/**
- * Return number of affected rows
+ * {@inheritDoc}
*/
function sql_affectedrows()
{
@@ -213,7 +230,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
/**
- * Fetch current row
+ * {@inheritDoc}
*/
function sql_fetchrow($query_id = false)
{
@@ -229,7 +246,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
return $cache->sql_fetchrow($query_id);
}
- if ($query_id !== false)
+ if ($query_id !== false && $query_id !== null)
{
$result = @mysqli_fetch_assoc($query_id);
return $result !== null ? $result : false;
@@ -239,8 +256,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
/**
- * Seek to given row number
- * rownum is zero-based
+ * {@inheritDoc}
*/
function sql_rowseek($rownum, &$query_id)
{
@@ -260,7 +276,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
/**
- * Get last inserted id after insert statement
+ * {@inheritDoc}
*/
function sql_nextid()
{
@@ -268,7 +284,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
/**
- * Free sql result
+ * {@inheritDoc}
*/
function sql_freeresult($query_id = false)
{
@@ -288,7 +304,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
/**
- * Escape string used in sql query
+ * {@inheritDoc}
*/
function sql_escape($msg)
{
@@ -440,9 +456,12 @@ class mysqli extends \phpbb\db\driver\mysql_base
$endtime = $endtime[0] + $endtime[1];
$result = @mysqli_query($this->db_connect_id, $query);
- while ($void = @mysqli_fetch_assoc($result))
+ if ($result !== null)
{
- // Take the time spent on parsing rows into account
+ while ($void = @mysqli_fetch_assoc($result))
+ {
+ // Take the time spent on parsing rows into account
+ }
}
@mysqli_free_result($result);
diff --git a/phpBB/phpbb/db/driver/oracle.php b/phpBB/phpbb/db/driver/oracle.php
index 36ed43d4a7..6dcab5dd7d 100644
--- a/phpBB/phpbb/db/driver/oracle.php
+++ b/phpBB/phpbb/db/driver/oracle.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\db\driver;
/**
* Oracle Database Abstraction Layer
-* @package dbal
*/
class oracle extends \phpbb\db\driver\driver
{
@@ -19,7 +22,7 @@ class oracle extends \phpbb\db\driver\driver
var $connect_error = '';
/**
- * Connect to server
+ * {@inheritDoc}
*/
function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
{
@@ -72,10 +75,7 @@ class oracle extends \phpbb\db\driver\driver
}
/**
- * Version information about used database
- * @param bool $raw if true, only return the fetched sql_server_version
- * @param bool $use_cache forced to false for Oracle
- * @return string sql server version
+ * {@inheritDoc}
*/
function sql_server_info($raw = false, $use_cache = true)
{
@@ -240,13 +240,7 @@ class oracle extends \phpbb\db\driver\driver
}
/**
- * Base query method
- *
- * @param string $query Contains the SQL query which shall be executed
- * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
- * @return mixed When casted to bool the returned value returns true on success and false on failure
- *
- * @access public
+ * {@inheritDoc}
*/
function sql_query($query = '', $cache_ttl = 0)
{
@@ -259,6 +253,10 @@ class oracle extends \phpbb\db\driver\driver
{
$this->sql_report('start', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->curtime = microtime(true);
+ }
$this->last_query_text = $query;
$this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
@@ -436,6 +434,10 @@ class oracle extends \phpbb\db\driver\driver
{
$this->sql_report('stop', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->sql_time += microtime(true) - $this->curtime;
+ }
if ($cache && $cache_ttl)
{
@@ -473,7 +475,7 @@ class oracle extends \phpbb\db\driver\driver
}
/**
- * Return number of affected rows
+ * {@inheritDoc}
*/
function sql_affectedrows()
{
@@ -481,7 +483,7 @@ class oracle extends \phpbb\db\driver\driver
}
/**
- * Fetch current row
+ * {@inheritDoc}
*/
function sql_fetchrow($query_id = false)
{
@@ -532,8 +534,7 @@ class oracle extends \phpbb\db\driver\driver
}
/**
- * Seek to given row number
- * rownum is zero-based
+ * {@inheritDoc}
*/
function sql_rowseek($rownum, &$query_id)
{
@@ -570,7 +571,7 @@ class oracle extends \phpbb\db\driver\driver
}
/**
- * Get last inserted id after insert statement
+ * {@inheritDoc}
*/
function sql_nextid()
{
@@ -602,7 +603,7 @@ class oracle extends \phpbb\db\driver\driver
}
/**
- * Free sql result
+ * {@inheritDoc}
*/
function sql_freeresult($query_id = false)
{
@@ -628,7 +629,7 @@ class oracle extends \phpbb\db\driver\driver
}
/**
- * Escape string used in sql query
+ * {@inheritDoc}
*/
function sql_escape($msg)
{
@@ -644,6 +645,15 @@ class oracle extends \phpbb\db\driver\driver
return $expression . " ESCAPE '\\'";
}
+ /**
+ * Build NOT LIKE expression
+ * @access private
+ */
+ function _sql_not_like_expression($expression)
+ {
+ return $expression . " ESCAPE '\\'";
+ }
+
function _sql_custom_build($stage, $data)
{
return $data;
diff --git a/phpBB/phpbb/db/driver/postgres.php b/phpBB/phpbb/db/driver/postgres.php
index 5dbd1ca74f..a3b9aa4c6b 100644
--- a/phpBB/phpbb/db/driver/postgres.php
+++ b/phpBB/phpbb/db/driver/postgres.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,16 +15,16 @@ namespace phpbb\db\driver;
/**
* PostgreSQL Database Abstraction Layer
-* Minimum Requirement is Version 7.3+
-* @package dbal
+* Minimum Requirement is Version 8.3+
*/
class postgres extends \phpbb\db\driver\driver
{
+ var $multi_insert = true;
var $last_query_text = '';
var $connect_error = '';
/**
- * Connect to server
+ * {@inheritDoc}
*/
function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
{
@@ -98,11 +102,6 @@ class postgres extends \phpbb\db\driver\driver
if ($this->db_connect_id)
{
- if (version_compare($this->sql_server_info(true), '8.2', '>='))
- {
- $this->multi_insert = true;
- }
-
if ($schema !== '')
{
@pg_query($this->db_connect_id, 'SET search_path TO ' . $schema);
@@ -115,10 +114,7 @@ class postgres extends \phpbb\db\driver\driver
}
/**
- * Version information about used database
- * @param bool $raw if true, only return the fetched sql_server_version
- * @param bool $use_cache If true, it is safe to retrieve the value from the cache
- * @return string sql server version
+ * {@inheritDoc}
*/
function sql_server_info($raw = false, $use_cache = true)
{
@@ -166,13 +162,7 @@ class postgres extends \phpbb\db\driver\driver
}
/**
- * Base query method
- *
- * @param string $query Contains the SQL query which shall be executed
- * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
- * @return mixed When casted to bool the returned value returns true on success and false on failure
- *
- * @access public
+ * {@inheritDoc}
*/
function sql_query($query = '', $cache_ttl = 0)
{
@@ -185,6 +175,10 @@ class postgres extends \phpbb\db\driver\driver
{
$this->sql_report('start', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->curtime = microtime(true);
+ }
$this->last_query_text = $query;
$this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
@@ -201,6 +195,10 @@ class postgres extends \phpbb\db\driver\driver
{
$this->sql_report('stop', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->sql_time += microtime(true) - $this->curtime;
+ }
if ($cache && $cache_ttl)
{
@@ -253,7 +251,7 @@ class postgres extends \phpbb\db\driver\driver
}
/**
- * Return number of affected rows
+ * {@inheritDoc}
*/
function sql_affectedrows()
{
@@ -261,7 +259,7 @@ class postgres extends \phpbb\db\driver\driver
}
/**
- * Fetch current row
+ * {@inheritDoc}
*/
function sql_fetchrow($query_id = false)
{
@@ -281,8 +279,7 @@ class postgres extends \phpbb\db\driver\driver
}
/**
- * Seek to given row number
- * rownum is zero-based
+ * {@inheritDoc}
*/
function sql_rowseek($rownum, &$query_id)
{
@@ -302,7 +299,7 @@ class postgres extends \phpbb\db\driver\driver
}
/**
- * Get last inserted id after insert statement
+ * {@inheritDoc}
*/
function sql_nextid()
{
@@ -331,7 +328,7 @@ class postgres extends \phpbb\db\driver\driver
}
/**
- * Free sql result
+ * {@inheritDoc}
*/
function sql_freeresult($query_id = false)
{
@@ -357,8 +354,7 @@ class postgres extends \phpbb\db\driver\driver
}
/**
- * Escape string used in sql query
- * Note: Do not use for bytea values if we may use them at a later stage
+ * {@inheritDoc}
*/
function sql_escape($msg)
{
@@ -375,7 +371,16 @@ class postgres extends \phpbb\db\driver\driver
}
/**
- * @inheritdoc
+ * Build NOT LIKE expression
+ * @access private
+ */
+ function _sql_not_like_expression($expression)
+ {
+ return $expression;
+ }
+
+ /**
+ * {@inheritDoc}
*/
function cast_expr_to_bigint($expression)
{
@@ -383,7 +388,7 @@ class postgres extends \phpbb\db\driver\driver
}
/**
- * @inheritdoc
+ * {@inheritDoc}
*/
function cast_expr_to_string($expression)
{
diff --git a/phpBB/phpbb/db/driver/sqlite.php b/phpBB/phpbb/db/driver/sqlite.php
index 59ec895c0f..d5da0e2438 100644
--- a/phpBB/phpbb/db/driver/sqlite.php
+++ b/phpBB/phpbb/db/driver/sqlite.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,14 +16,13 @@ namespace phpbb\db\driver;
/**
* Sqlite Database Abstraction Layer
* Minimum Requirement: 2.8.2+
-* @package dbal
*/
class sqlite extends \phpbb\db\driver\driver
{
var $connect_error = '';
/**
- * Connect to server
+ * {@inheritDoc}
*/
function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
{
@@ -58,10 +61,7 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
- * Version information about used database
- * @param bool $raw if true, only return the fetched sql_server_version
- * @param bool $use_cache if true, it is safe to retrieve the stored value from the cache
- * @return string sql server version
+ * {@inheritDoc}
*/
function sql_server_info($raw = false, $use_cache = true)
{
@@ -108,13 +108,7 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
- * Base query method
- *
- * @param string $query Contains the SQL query which shall be executed
- * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
- * @return mixed When casted to bool the returned value returns true on success and false on failure
- *
- * @access public
+ * {@inheritDoc}
*/
function sql_query($query = '', $cache_ttl = 0)
{
@@ -127,6 +121,10 @@ class sqlite extends \phpbb\db\driver\driver
{
$this->sql_report('start', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->curtime = microtime(true);
+ }
$this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
$this->sql_add_num_queries($this->query_result);
@@ -142,6 +140,10 @@ class sqlite extends \phpbb\db\driver\driver
{
$this->sql_report('stop', $query);
}
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->sql_time += microtime(true) - $this->curtime;
+ }
if ($cache && $cache_ttl)
{
@@ -185,7 +187,7 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
- * Return number of affected rows
+ * {@inheritDoc}
*/
function sql_affectedrows()
{
@@ -193,7 +195,7 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
- * Fetch current row
+ * {@inheritDoc}
*/
function sql_fetchrow($query_id = false)
{
@@ -213,8 +215,7 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
- * Seek to given row number
- * rownum is zero-based
+ * {@inheritDoc}
*/
function sql_rowseek($rownum, &$query_id)
{
@@ -234,7 +235,7 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
- * Get last inserted id after insert statement
+ * {@inheritDoc}
*/
function sql_nextid()
{
@@ -242,7 +243,7 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
- * Free sql result
+ * {@inheritDoc}
*/
function sql_freeresult($query_id = false)
{
@@ -262,7 +263,7 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
- * Escape string used in sql query
+ * {@inheritDoc}
*/
function sql_escape($msg)
{
@@ -270,12 +271,13 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
- * Correctly adjust LIKE expression for special characters
+ * {@inheritDoc}
+ *
* For SQLite an underscore is a not-known character... this may change with SQLite3
*/
function sql_like_expression($expression)
{
- // Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it!
+ // Unlike LIKE, GLOB is unfortunately case sensitive.
// We only catch * and ? here, not the character map possible on file globbing.
$expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
@@ -286,6 +288,23 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
+ * {@inheritDoc}
+ *
+ * For SQLite an underscore is a not-known character...
+ */
+ function sql_not_like_expression($expression)
+ {
+ // Unlike NOT LIKE, NOT GLOB is unfortunately case sensitive.
+ // We only catch * and ? here, not the character map possible on file globbing.
+ $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
+
+ $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
+ $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
+
+ return 'NOT GLOB \'' . $this->sql_escape($expression) . '\'';
+ }
+
+ /**
* return sql error array
* @access private
*/
diff --git a/phpBB/phpbb/db/driver/sqlite3.php b/phpBB/phpbb/db/driver/sqlite3.php
new file mode 100644
index 0000000000..4e3e0d3329
--- /dev/null
+++ b/phpBB/phpbb/db/driver/sqlite3.php
@@ -0,0 +1,404 @@
+<?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\driver;
+
+/**
+* SQLite3 Database Abstraction Layer
+* Minimum Requirement: 3.6.15+
+*/
+class sqlite3 extends \phpbb\db\driver\driver
+{
+ /**
+ * @var string Stores errors during connection setup in case the driver is not available
+ */
+ protected $connect_error = '';
+
+ /**
+ * @var \SQLite3 The SQLite3 database object to operate against
+ */
+ protected $dbo = null;
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
+ {
+ $this->persistency = false;
+ $this->user = $sqluser;
+ $this->server = $sqlserver . (($port) ? ':' . $port : '');
+ $this->dbname = $database;
+
+ if (!class_exists('SQLite3', false))
+ {
+ $this->connect_error = 'SQLite3 not found, is the extension installed?';
+ return $this->sql_error('');
+ }
+
+ try
+ {
+ $this->dbo = new \SQLite3($this->server, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);
+ $this->db_connect_id = true;
+ }
+ catch (\Exception $e)
+ {
+ $this->connect_error = $e->getMessage();
+ return array('message' => $this->connect_error);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_server_info($raw = false, $use_cache = true)
+ {
+ global $cache;
+
+ if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite_version')) === false)
+ {
+ $version = \SQLite3::version();
+
+ $this->sql_server_version = $version['versionString'];
+
+ if (!empty($cache) && $use_cache)
+ {
+ $cache->put('sqlite_version', $this->sql_server_version);
+ }
+ }
+
+ return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version;
+ }
+
+ /**
+ * SQL Transaction
+ *
+ * @param string $status Should be one of the following strings:
+ * begin, commit, rollback
+ * @return bool Success/failure of the transaction query
+ */
+ protected function _sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ return $this->dbo->exec('BEGIN IMMEDIATE');
+ break;
+
+ case 'commit':
+ return $this->dbo->exec('COMMIT');
+ break;
+
+ case 'rollback':
+ return $this->dbo->exec('ROLLBACK');
+ break;
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_query($query = '', $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ global $cache;
+
+ // EXPLAIN only in extra debug mode
+ if (defined('DEBUG'))
+ {
+ $this->sql_report('start', $query);
+ }
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->curtime = microtime(true);
+ }
+
+ $this->last_query_text = $query;
+ $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
+ $this->sql_add_num_queries($this->query_result);
+
+ if ($this->query_result === false)
+ {
+ if (($this->query_result = @$this->dbo->query($query)) === false)
+ {
+ $this->sql_error($query);
+ }
+
+ if (defined('DEBUG'))
+ {
+ $this->sql_report('stop', $query);
+ }
+ else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ $this->sql_time += microtime(true) - $this->curtime;
+ }
+
+ if ($cache && $cache_ttl)
+ {
+ $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
+ }
+ }
+ else if (defined('DEBUG'))
+ {
+ $this->sql_report('fromcache', $query);
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return $this->query_result;
+ }
+
+ /**
+ * Build LIMIT query
+ *
+ * @param string $query The SQL query to execute
+ * @param int $total The number of rows to select
+ * @param int $offset
+ * @param int $cache_ttl Either 0 to avoid caching or
+ * the time in seconds which the result shall be kept in cache
+ * @return mixed Buffered, seekable result handle, false on error
+ */
+ protected function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
+ {
+ $this->query_result = false;
+
+ // if $total is set to 0 we do not want to limit the number of rows
+ if ($total == 0)
+ {
+ $total = -1;
+ }
+
+ $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
+
+ return $this->sql_query($query, $cache_ttl);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_affectedrows()
+ {
+ return ($this->db_connect_id) ? $this->dbo->changes() : false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_fetchrow($query_id = false)
+ {
+ global $cache;
+
+ if ($query_id === false)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
+ {
+ return $cache->sql_fetchrow($query_id);
+ }
+
+ return is_object($query_id) ? $query_id->fetchArray(SQLITE3_ASSOC) : false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_nextid()
+ {
+ return ($this->db_connect_id) ? $this->dbo->lastInsertRowID() : false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_freeresult($query_id = false)
+ {
+ global $cache;
+
+ if ($query_id === false)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
+ {
+ return $cache->sql_freeresult($query_id);
+ }
+
+ if ($query_id)
+ {
+ return @$query_id->finalize();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_escape($msg)
+ {
+ return \SQLite3::escapeString($msg);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For SQLite an underscore is an unknown character.
+ */
+ public function sql_like_expression($expression)
+ {
+ // Unlike LIKE, GLOB is unfortunately case sensitive.
+ // We only catch * and ? here, not the character map possible on file globbing.
+ $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
+
+ $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
+ $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
+
+ return 'GLOB \'' . $this->sql_escape($expression) . '\'';
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For SQLite an underscore is an unknown character.
+ */
+ public function sql_not_like_expression($expression)
+ {
+ // Unlike NOT LIKE, NOT GLOB is unfortunately case sensitive
+ // We only catch * and ? here, not the character map possible on file globbing.
+ $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
+
+ $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
+ $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
+
+ return 'NOT GLOB \'' . $this->sql_escape($expression) . '\'';
+ }
+
+ /**
+ * return sql error array
+ *
+ * @return array
+ */
+ protected function _sql_error()
+ {
+ if (class_exists('SQLite3', false) && isset($this->dbo))
+ {
+ $error = array(
+ 'message' => $this->dbo->lastErrorMsg(),
+ 'code' => $this->dbo->lastErrorCode(),
+ );
+ }
+ else
+ {
+ $error = array(
+ 'message' => $this->connect_error,
+ 'code' => '',
+ );
+ }
+
+ return $error;
+ }
+
+ /**
+ * Build db-specific query data
+ *
+ * @param string $stage Available stages: FROM, WHERE
+ * @param mixed $data A string containing the CROSS JOIN query or an array of WHERE clauses
+ *
+ * @return string The db-specific query fragment
+ */
+ protected function _sql_custom_build($stage, $data)
+ {
+ return $data;
+ }
+
+ /**
+ * Close sql connection
+ *
+ * @return bool False if failure
+ */
+ protected function _sql_close()
+ {
+ return $this->dbo->close();
+ }
+
+ /**
+ * Build db-specific report
+ *
+ * @param string $mode Available modes: display, start, stop,
+ * add_select_row, fromcache, record_fromcache
+ * @param string $query The Query that should be explained
+ * @return mixed Either a full HTML page, boolean or null
+ */
+ protected function _sql_report($mode, $query = '')
+ {
+ switch ($mode)
+ {
+ case 'start':
+
+ $explain_query = $query;
+ if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
+ {
+ $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
+ }
+ else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
+ {
+ $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
+ }
+
+ if (preg_match('/^SELECT/', $explain_query))
+ {
+ $html_table = false;
+
+ if ($result = $this->dbo->query("EXPLAIN QUERY PLAN $explain_query"))
+ {
+ while ($row = $result->fetchArray(SQLITE3_ASSOC))
+ {
+ $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
+ }
+ }
+
+ if ($html_table)
+ {
+ $this->html_hold .= '</table>';
+ }
+ }
+
+ break;
+
+ case 'fromcache':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $result = $this->dbo->query($query);
+ while ($void = $result->fetchArray(SQLITE3_ASSOC))
+ {
+ // Take the time spent on parsing rows into account
+ }
+
+ $splittime = explode(' ', microtime());
+ $splittime = $splittime[0] + $splittime[1];
+
+ $this->sql_report('record_fromcache', $query, $endtime, $splittime);
+
+ break;
+ }
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v30x/local_url_bbcode.php b/phpBB/phpbb/db/migration/data/v30x/local_url_bbcode.php
index 5e6ba90336..648ae9ce96 100644
--- a/phpBB/phpbb/db/migration/data/v30x/local_url_bbcode.php
+++ b/phpBB/phpbb/db/migration/data/v30x/local_url_bbcode.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -33,16 +37,23 @@ class local_url_bbcode extends \phpbb\db\migration\migration
{
$sql = 'SELECT *
FROM ' . BBCODES_TABLE . '
- WHERE bbcode_match ' . $this->db->sql_like_expression($this->db->any_char . 'LOCAL_URL' . $this->db->any_char);
+ WHERE bbcode_match ' . $this->db->sql_like_expression($this->db->get_any_char() . 'LOCAL_URL' . $this->db->get_any_char());
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
if (!class_exists('acp_bbcodes'))
{
- global $phpEx;
- phpbb_require_updated('includes/acp/acp_bbcodes.' . $phpEx);
+ if (function_exists('phpbb_require_updated'))
+ {
+ phpbb_require_updated('includes/acp/acp_bbcodes.' . $this->php_ext);
+ }
+ else
+ {
+ require($this->phpbb_root_path . 'includes/acp/acp_bbcodes.' . $this->php_ext);
+ }
}
+
$bbcode_match = $row['bbcode_match'];
$bbcode_tpl = $row['bbcode_tpl'];
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_0.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_0.php
index 41ade22a29..26937d6d80 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_0.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_0.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php
index aed0f2784b..f5c7e56a81 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php
index 305309c3bd..0d3a1ca80b 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php
index fb50d67fb5..293c46cb06 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php
index 63ba1e8fc2..f2889120e6 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php
index 7055063032..9d6697ab7f 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php
index 1246597efb..e77b54a1b5 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php
index 7e284235e1..ed2dabf51c 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php
index 017038855d..45d88708bd 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php
index 5a2d569724..c489c0c0e8 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php
index 35a3015959..8600472cca 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php
index 3edb578fc8..8fac273073 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php
index 510693a5b7..fb1b8014a4 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php
index c8273c0801..d1ae0b9cbc 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php
index 7e2a08590e..c08f01dbeb 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php
index 7a856383e2..2e7f141a9b 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php
index 61562575eb..bde5febc59 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php
index b2adbeaa43..c277da224c 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php
index 57bd59bba3..530eaf47e6 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php
index 5d6140393b..9b08da0125 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -32,7 +36,7 @@ class release_3_0_4 extends \phpbb\db\migration\migration
public function rename_log_delete_topic()
{
- if ($this->db->sql_layer == 'oracle')
+ if ($this->db->get_sql_layer() == 'oracle')
{
// log_operation is CLOB - but we can change this later
$sql = 'UPDATE ' . $this->table_prefix . "log
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php
index a8af4dd76c..10343438b3 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php
index 7bbe7ffed9..09c2bfea50 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php
index ffe2c6a44d..f593c32181 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php
index 04b14b5189..a9041ef354 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php
index 85ea2e9d20..74c338a9c5 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php
index 87d5e490f8..faef68121d 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php
index 7a0ef28601..c52b71d8fa 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php
index 73a1fe9e6a..2db3341b0a 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php
index b6e5be2c2f..5734db25e6 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php
index 2b0da30bc6..d1d602819d 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php
index 3547ee77e1..784e810f14 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php
index de4d772808..1843c3f262 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -72,7 +76,7 @@ class release_3_0_7_rc1 extends \phpbb\db\migration\migration
{
// Delete all text-templates from the template_data
$sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . '
- WHERE template_filename ' . $this->db->sql_like_expression($this->db->any_char . '.txt');
+ WHERE template_filename ' . $this->db->sql_like_expression($this->db->get_any_char() . '.txt');
$this->sql_query($sql);
}
}
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php
index 800803a753..e497a38765 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php
index 6c8b1df6fc..04b5bd4a13 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php
index 1a14e5c961..4e863fa143 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php
index 9af2fce971..e69134c538 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php
index 3fb790bc0d..06e46d522f 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -85,7 +89,7 @@ class release_3_0_9_rc1 extends \phpbb\db\migration\migration
// Update file extension group names to use language strings, again.
$sql = 'SELECT group_id, group_name
FROM ' . EXTENSION_GROUPS_TABLE . '
- WHERE group_name ' . $this->db->sql_like_expression('EXT_GROUP_' . $this->db->any_char);
+ WHERE group_name ' . $this->db->sql_like_expression('EXT_GROUP_' . $this->db->get_any_char());
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php
index cd79d24ade..46fd51e7fe 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php
index 7e59b8f9e8..1696060735 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php
index e71d9defa6..fdc92b52f9 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php b/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php
index ab5b1a535b..0ca4f2f19c 100644
--- a/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php
+++ b/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/acp_style_components_module.php b/phpBB/phpbb/db/migration/data/v310/acp_style_components_module.php
index 9f168f4fd6..4bd29f87d7 100644
--- a/phpBB/phpbb/db/migration/data/v310/acp_style_components_module.php
+++ b/phpBB/phpbb/db/migration/data/v310/acp_style_components_module.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/allow_cdn.php b/phpBB/phpbb/db/migration/data/v310/allow_cdn.php
index aa471df6e7..286d20e20b 100644
--- a/phpBB/phpbb/db/migration/data/v310/allow_cdn.php
+++ b/phpBB/phpbb/db/migration/data/v310/allow_cdn.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/alpha1.php b/phpBB/phpbb/db/migration/data/v310/alpha1.php
index 403e301e64..1df85bc64c 100644
--- a/phpBB/phpbb/db/migration/data/v310/alpha1.php
+++ b/phpBB/phpbb/db/migration/data/v310/alpha1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/alpha2.php b/phpBB/phpbb/db/migration/data/v310/alpha2.php
index 3c0853f924..78bc755ec9 100644
--- a/phpBB/phpbb/db/migration/data/v310/alpha2.php
+++ b/phpBB/phpbb/db/migration/data/v310/alpha2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/alpha3.php b/phpBB/phpbb/db/migration/data/v310/alpha3.php
index 4bd2231bb9..574d19d2f4 100644
--- a/phpBB/phpbb/db/migration/data/v310/alpha3.php
+++ b/phpBB/phpbb/db/migration/data/v310/alpha3.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php
index 971a7e8504..2d51bd53e4 100644
--- a/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php
+++ b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php
new file mode 100644
index 0000000000..e9e726ae20
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php
@@ -0,0 +1,44 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class auth_provider_oauth2 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\auth_provider_oauth',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(
+ array($this, 'update_auth_link_module_auth'),
+ )),
+ );
+ }
+
+ public function update_auth_link_module_auth()
+ {
+ $sql = 'UPDATE ' . MODULES_TABLE . "
+ SET module_auth = 'authmethod_oauth'
+ WHERE module_class = 'ucp'
+ AND module_basename = 'ucp_auth_link'
+ AND module_mode = 'auth_link'
+ AND module_auth = ''";
+ $this->db->sql_query($sql);
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/avatar_types.php b/phpBB/phpbb/db/migration/data/v310/avatar_types.php
index bdbdccf0c5..117e93239d 100644
--- a/phpBB/phpbb/db/migration/data/v310/avatar_types.php
+++ b/phpBB/phpbb/db/migration/data/v310/avatar_types.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/avatars.php b/phpBB/phpbb/db/migration/data/v310/avatars.php
index 80ce606f29..2698adeed5 100644
--- a/phpBB/phpbb/db/migration/data/v310/avatars.php
+++ b/phpBB/phpbb/db/migration/data/v310/avatars.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/beta1.php b/phpBB/phpbb/db/migration/data/v310/beta1.php
index 36d0c62b6f..84887bd58e 100644
--- a/phpBB/phpbb/db/migration/data/v310/beta1.php
+++ b/phpBB/phpbb/db/migration/data/v310/beta1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/beta2.php b/phpBB/phpbb/db/migration/data/v310/beta2.php
new file mode 100644
index 0000000000..458e305c7b
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/beta2.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\db\migration\data\v310;
+
+class beta2 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\beta1',
+ '\phpbb\db\migration\data\v310\acp_prune_users_module',
+ '\phpbb\db\migration\data\v310\profilefield_location_cleanup',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0-b2')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/beta3.php b/phpBB/phpbb/db/migration/data/v310/beta3.php
new file mode 100644
index 0000000000..a6c62bf936
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/beta3.php
@@ -0,0 +1,36 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class beta3 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\beta2',
+ '\phpbb\db\migration\data\v310\auth_provider_oauth2',
+ '\phpbb\db\migration\data\v310\board_contact_name',
+ '\phpbb\db\migration\data\v310\jquery_update2',
+ '\phpbb\db\migration\data\v310\live_searches_config',
+ '\phpbb\db\migration\data\v310\prune_shadow_topics',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0-b3')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/beta4.php b/phpBB/phpbb/db/migration/data/v310/beta4.php
new file mode 100644
index 0000000000..3e91d95178
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/beta4.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\db\migration\data\v310;
+
+class beta4 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\beta3',
+ '\phpbb\db\migration\data\v310\extensions_version_check_force_unstable',
+ '\phpbb\db\migration\data\v310\reset_missing_captcha_plugin',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0-b4')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/board_contact_name.php b/phpBB/phpbb/db/migration/data/v310/board_contact_name.php
new file mode 100644
index 0000000000..6f5188720b
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/board_contact_name.php
@@ -0,0 +1,34 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class board_contact_name extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return isset($this->config['board_contact_name']);
+ }
+
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\beta2');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.add', array('board_contact_name', '')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/boardindex.php b/phpBB/phpbb/db/migration/data/v310/boardindex.php
index 27492f2d0d..77a8558f21 100644
--- a/phpBB/phpbb/db/migration/data/v310/boardindex.php
+++ b/phpBB/phpbb/db/migration/data/v310/boardindex.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/captcha_plugins.php b/phpBB/phpbb/db/migration/data/v310/captcha_plugins.php
new file mode 100644
index 0000000000..13071e9891
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/captcha_plugins.php
@@ -0,0 +1,44 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class captcha_plugins extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\rc2',
+ );
+ }
+
+ public function update_data()
+ {
+ $captcha_plugin = $this->config['captcha_plugin'];
+ if (strpos($this->config['captcha_plugin'], 'phpbb_captcha_') === 0)
+ {
+ $captcha_plugin = substr($this->config['captcha_plugin'], strlen('phpbb_captcha_'));
+ }
+
+ return array(
+ array('if', array(
+ (is_file($this->phpbb_root_path . 'phpbb/captcha/plugins/' . $captcha_plugin . '.' . $this->php_ext)),
+ array('config.update', array('captcha_plugin', 'core.captcha.plugins.' . $captcha_plugin)),
+ )),
+ array('if', array(
+ (!is_file($this->phpbb_root_path . 'phpbb/captcha/plugins/' . $captcha_plugin . '.' . $this->php_ext)),
+ array('config.update', array('captcha_plugin', 'core.captcha.plugins.nogd')),
+ )),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/config_db_text.php b/phpBB/phpbb/db/migration/data/v310/config_db_text.php
index 1a7ee7a9a6..438883c438 100644
--- a/phpBB/phpbb/db/migration/data/v310/config_db_text.php
+++ b/phpBB/phpbb/db/migration/data/v310/config_db_text.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/contact_admin_acp_module.php b/phpBB/phpbb/db/migration/data/v310/contact_admin_acp_module.php
new file mode 100644
index 0000000000..20bd547ac3
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/contact_admin_acp_module.php
@@ -0,0 +1,31 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class contact_admin_acp_module extends \phpbb\db\migration\migration
+{
+ public function update_data()
+ {
+ return array(
+ array('module.add', array(
+ 'acp',
+ 'ACP_BOARD_CONFIGURATION',
+ array(
+ 'module_basename' => 'acp_contact',
+ 'modes' => array('contact'),
+ ),
+ )),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php b/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php
new file mode 100644
index 0000000000..c2dd09ddf6
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php
@@ -0,0 +1,41 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class contact_admin_form extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return isset($this->config['contact_admin_form_enable']);
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.add', array('contact_admin_form_enable', 1)),
+ array('custom', array(array($this, 'contact_admin_info'))),
+ );
+ }
+
+ public function contact_admin_info()
+ {
+ $text_config = new \phpbb\config\db_text($this->db, $this->table_prefix . 'config_text');
+ $text_config->set_array(array(
+ 'contact_admin_info' => '',
+ 'contact_admin_info_uid' => '',
+ 'contact_admin_info_bitfield' => '',
+ 'contact_admin_info_flags' => OPTION_FLAG_BBCODE + OPTION_FLAG_SMILIES + OPTION_FLAG_LINKS,
+ ));
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/dev.php b/phpBB/phpbb/db/migration/data/v310/dev.php
index 83611d3731..f037191c2a 100644
--- a/phpBB/phpbb/db/migration/data/v310/dev.php
+++ b/phpBB/phpbb/db/migration/data/v310/dev.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/extensions.php b/phpBB/phpbb/db/migration/data/v310/extensions.php
index d8b38dbc9e..3171435482 100644
--- a/phpBB/phpbb/db/migration/data/v310/extensions.php
+++ b/phpBB/phpbb/db/migration/data/v310/extensions.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/extensions_version_check_force_unstable.php b/phpBB/phpbb/db/migration/data/v310/extensions_version_check_force_unstable.php
new file mode 100644
index 0000000000..1d6276f484
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/extensions_version_check_force_unstable.php
@@ -0,0 +1,29 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class extensions_version_check_force_unstable extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\dev');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.add', array('extension_force_unstable', false)),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/forgot_password.php b/phpBB/phpbb/db/migration/data/v310/forgot_password.php
index 814093caa9..362457cf23 100644
--- a/phpBB/phpbb/db/migration/data/v310/forgot_password.php
+++ b/phpBB/phpbb/db/migration/data/v310/forgot_password.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/jquery_update.php b/phpBB/phpbb/db/migration/data/v310/jquery_update.php
index bd2de2b4d4..8011331e80 100644
--- a/phpBB/phpbb/db/migration/data/v310/jquery_update.php
+++ b/phpBB/phpbb/db/migration/data/v310/jquery_update.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/jquery_update2.php b/phpBB/phpbb/db/migration/data/v310/jquery_update2.php
new file mode 100644
index 0000000000..4061be5940
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/jquery_update2.php
@@ -0,0 +1,37 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class jquery_update2 extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return $this->config['load_jquery_url'] !== '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js';
+ }
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\jquery_update',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js')),
+ );
+ }
+
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/live_searches_config.php b/phpBB/phpbb/db/migration/data/v310/live_searches_config.php
new file mode 100644
index 0000000000..3d87e04ac2
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/live_searches_config.php
@@ -0,0 +1,29 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class live_searches_config extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return isset($this->config['allow_live_searches']);
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.add', array('allow_live_searches', '1')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/migrations_table.php b/phpBB/phpbb/db/migration/data/v310/migrations_table.php
index e70fd35819..48508b05c2 100644
--- a/phpBB/phpbb/db/migration/data/v310/migrations_table.php
+++ b/phpBB/phpbb/db/migration/data/v310/migrations_table.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php b/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php
index ffb790b135..85e479db59 100644
--- a/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php
+++ b/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php b/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php
index 97d174d4bc..4530ebe285 100644
--- a/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php
+++ b/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,7 +18,7 @@ class mysql_fulltext_drop extends \phpbb\db\migration\migration
public function effectively_installed()
{
// This migration is irrelevant for all non-MySQL DBMSes.
- return strpos($this->db->sql_layer, 'mysql') === false;
+ return strpos($this->db->get_sql_layer(), 'mysql') === false;
}
static public function depends_on()
diff --git a/phpBB/phpbb/db/migration/data/v310/namespaces.php b/phpBB/phpbb/db/migration/data/v310/namespaces.php
index f74ecbd874..2a4935395e 100644
--- a/phpBB/phpbb/db/migration/data/v310/namespaces.php
+++ b/phpBB/phpbb/db/migration/data/v310/namespaces.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/notification_options_reconvert.php b/phpBB/phpbb/db/migration/data/v310/notification_options_reconvert.php
index 4195623618..2d4d26ae61 100644
--- a/phpBB/phpbb/db/migration/data/v310/notification_options_reconvert.php
+++ b/phpBB/phpbb/db/migration/data/v310/notification_options_reconvert.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/notifications.php b/phpBB/phpbb/db/migration/data/v310/notifications.php
index 61be25bb5f..f4d012b5ac 100644
--- a/phpBB/phpbb/db/migration/data/v310/notifications.php
+++ b/phpBB/phpbb/db/migration/data/v310/notifications.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/notifications_cron.php b/phpBB/phpbb/db/migration/data/v310/notifications_cron.php
index d5fa9c58a5..ba600f7bf5 100644
--- a/phpBB/phpbb/db/migration/data/v310/notifications_cron.php
+++ b/phpBB/phpbb/db/migration/data/v310/notifications_cron.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/notifications_cron_p2.php b/phpBB/phpbb/db/migration/data/v310/notifications_cron_p2.php
index 050e679cc0..263584b343 100644
--- a/phpBB/phpbb/db/migration/data/v310/notifications_cron_p2.php
+++ b/phpBB/phpbb/db/migration/data/v310/notifications_cron_p2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php b/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php
index eb2eb361ee..21a39a7c91 100644
--- a/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php
+++ b/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/notifications_use_full_name.php b/phpBB/phpbb/db/migration/data/v310/notifications_use_full_name.php
new file mode 100644
index 0000000000..112c1e85e8
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/notifications_use_full_name.php
@@ -0,0 +1,184 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class notifications_use_full_name extends \phpbb\db\migration\migration
+{
+ protected $notification_types = array(
+ 'admin_activate_user',
+ 'approve_post',
+ 'approve_topic',
+ 'bookmark',
+ 'disapprove_post',
+ 'disapprove_topic',
+ 'group_request',
+ 'group_request_approved',
+ 'pm',
+ 'post',
+ 'post_in_queue',
+ 'quote',
+ 'report_pm',
+ 'report_pm_closed',
+ 'report_post',
+ 'report_post_closed',
+ 'topic',
+ 'topic_in_queue');
+
+ protected $notification_methods = array(
+ 'email',
+ 'jabber',
+ );
+
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\rc3');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'update_notifications_name'))),
+ array('custom', array(array($this, 'update_notifications_method_name'))),
+ );
+ }
+
+ public function revert_data()
+ {
+ return array(
+ array('custom', array(array($this, 'revert_notifications_name'))),
+ array('custom', array(array($this, 'revert_notifications_method_name'))),
+ );
+ }
+
+ public function update_notifications_method_name()
+ {
+ foreach ($this->notification_methods as $notification_method)
+ {
+ $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . "
+ SET method = 'notification.method.{$notification_method}'
+ WHERE method = '{$notification_method}'";
+ $this->db->sql_query($sql);
+ }
+ }
+
+ public function revert_notifications_method_name()
+ {
+ foreach ($this->notification_methods as $notification_method)
+ {
+ $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . "
+ SET method = '{$notification_method}'
+ WHERE method = 'notification.method.{$notification_method}'";
+ $this->db->sql_query($sql);
+ }
+ }
+
+ public function update_notifications_name()
+ {
+ $sql = 'UPDATE ' . NOTIFICATION_TYPES_TABLE . '
+ SET notification_type_enabled = 0
+ WHERE ' . $this->db->sql_in_set('notification_type_name', $this->notification_types, true);
+ $this->db->sql_query($sql);
+
+ foreach ($this->notification_types as $notification_type)
+ {
+ $sql = 'SELECT notification_type_id
+ FROM ' . NOTIFICATION_TYPES_TABLE . "
+ WHERE notification_type_name = 'notification.type.{$notification_type}'";
+ $result = $this->db->sql_query($sql);
+ $new_type_id = (int) $this->db->sql_fetchfield('notification_type_id');
+ $this->db->sql_freeresult($result);
+
+ if ($new_type_id)
+ {
+ // New type name already exists,
+ // so we delete the old type and update the type id of existing entries.
+ $sql = 'SELECT notification_type_id
+ FROM ' . NOTIFICATION_TYPES_TABLE . "
+ WHERE notification_type_name = '{$notification_type}'";
+ $result = $this->db->sql_query($sql);
+ $old_type_id = (int) $this->db->sql_fetchfield('notification_type_id');
+ $this->db->sql_freeresult($result);
+
+ $sql = 'UPDATE ' . NOTIFICATIONS_TABLE . '
+ SET notification_type_id = ' . (int) $new_type_id . '
+ WHERE notification_type_id = ' . (int) $old_type_id;
+ $this->db->sql_query($sql);
+
+ $sql = 'DELETE FROM ' . NOTIFICATION_TYPES_TABLE . "
+ WHERE notification_type_name = '{$notification_type}'";
+ $this->db->sql_query($sql);
+ }
+ else
+ {
+ // Otherwise we just update the name
+ $sql = 'UPDATE ' . NOTIFICATION_TYPES_TABLE . "
+ SET notification_type_name = 'notification.type.{$notification_type}'
+ WHERE notification_type_name = '{$notification_type}'";
+ $this->db->sql_query($sql);
+ }
+
+ $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . "
+ SET item_type = 'notification.type.{$notification_type}'
+ WHERE item_type = '{$notification_type}'";
+ $this->db->sql_query($sql);
+ }
+ }
+
+ public function revert_notifications_name()
+ {
+ foreach ($this->notification_types as $notification_type)
+ {
+ $sql = 'SELECT notification_type_id
+ FROM ' . NOTIFICATION_TYPES_TABLE . "
+ WHERE notification_type_name = '{$notification_type}'";
+ $result = $this->db->sql_query($sql);
+ $new_type_id = (int) $this->db->sql_fetchfield('notification_type_id');
+ $this->db->sql_freeresult($result);
+
+ if ($new_type_id)
+ {
+ // New type name already exists,
+ // so we delete the old type and update the type id of existing entries.
+ $sql = 'SELECT notification_type_id
+ FROM ' . NOTIFICATION_TYPES_TABLE . "
+ WHERE notification_type_name = 'notification.type.{$notification_type}'";
+ $result = $this->db->sql_query($sql);
+ $old_type_id = (int) $this->db->sql_fetchfield('notification_type_id');
+ $this->db->sql_freeresult($result);
+
+ $sql = 'UPDATE ' . NOTIFICATIONS_TABLE . '
+ SET notification_type_id = ' . (int) $new_type_id . '
+ WHERE notification_type_id = ' . (int) $old_type_id;
+ $this->db->sql_query($sql);
+
+ $sql = 'DELETE FROM ' . NOTIFICATION_TYPES_TABLE . "
+ WHERE notification_type_name = 'notification.type.{$notification_type}'";
+ $this->db->sql_query($sql);
+ }
+ else
+ {
+ // Otherwise we just update the name
+ $sql = 'UPDATE ' . NOTIFICATION_TYPES_TABLE . "
+ SET notification_type_name = '{$notification_type}'
+ WHERE notification_type_name = 'notification.type.{$notification_type}'";
+ $this->db->sql_query($sql);
+ }
+
+ $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . "
+ SET item_type = '{$notification_type}'
+ WHERE item_type = 'notification.type.{$notification_type}'";
+ $this->db->sql_query($sql);
+ }
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/passwords.php b/phpBB/phpbb/db/migration/data/v310/passwords.php
index 3422f75917..adee44147f 100644
--- a/phpBB/phpbb/db/migration/data/v310/passwords.php
+++ b/phpBB/phpbb/db/migration/data/v310/passwords.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/passwords_convert_p1.php b/phpBB/phpbb/db/migration/data/v310/passwords_convert_p1.php
new file mode 100644
index 0000000000..aad8e44681
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/passwords_convert_p1.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.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class passwords_convert_p1 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\passwords_p2');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'update_passwords'))),
+ );
+ }
+
+ public function update_passwords($start)
+ {
+ // Nothing to do if user_pass_convert column doesn't exist
+ if (!$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_pass_convert'))
+ {
+ return;
+ }
+
+ $start = (int) $start;
+ $limit = 1000;
+ $converted_users = 0;
+
+ $sql = 'SELECT user_password, user_id
+ FROM ' . $this->table_prefix . 'users
+ WHERE user_pass_convert = 1
+ ORDER BY user_id';
+ $result = $this->db->sql_query_limit($sql, $limit, $start);
+
+ $update_users = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $converted_users++;
+
+ $user_id = (int) $row['user_id'];
+ // Only prefix passwords without proper prefix
+ if (!isset($update_users[$user_id]) && !preg_match('#^\$([a-zA-Z0-9\\\]*?)\$#', $row['user_password']))
+ {
+ // Use $CP$ prefix for passwords that need to
+ // be converted and set pass convert to false.
+ $update_users[$user_id] = array(
+ 'user_password' => '$CP$' . $row['user_password'],
+ 'user_pass_convert' => 0,
+ );
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ foreach ($update_users as $user_id => $user_data)
+ {
+ $sql = 'UPDATE ' . $this->table_prefix . 'users
+ SET ' . $this->db->sql_build_array('UPDATE', $user_data) . '
+ WHERE user_id = ' . $user_id;
+ $this->sql_query($sql);
+ }
+
+ if ($converted_users < $limit)
+ {
+ // There are no more users to be converted
+ return;
+ }
+
+ // There are still more users to query, return the next start value
+ return $start + $limit;
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/passwords_convert_p2.php b/phpBB/phpbb/db/migration/data/v310/passwords_convert_p2.php
new file mode 100644
index 0000000000..26a99184a6
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/passwords_convert_p2.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\db\migration\data\v310;
+
+class passwords_convert_p2 extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_pass_convert');
+ }
+
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\passwords_convert_p1');
+ }
+
+ public function update_schema()
+ {
+ return array(
+ 'drop_columns' => array(
+ $this->table_prefix . 'users' => array(
+ 'user_pass_convert',
+ ),
+ ),
+ );
+ }
+
+ public function revert_schema()
+ {
+ return array(
+ 'add_columns' => array(
+ $this->table_prefix . 'users' => array(
+ 'user_pass_convert' => array('BOOL', 0, 'after' => 'user_passchg'),
+ ),
+ ),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/passwords_p2.php b/phpBB/phpbb/db/migration/data/v310/passwords_p2.php
index 553e79403d..afc7ba2813 100644
--- a/phpBB/phpbb/db/migration/data/v310/passwords_p2.php
+++ b/phpBB/phpbb/db/migration/data/v310/passwords_p2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/plupload.php b/phpBB/phpbb/db/migration/data/v310/plupload.php
index 7cdba507a2..69367f86a9 100644
--- a/phpBB/phpbb/db/migration/data/v310/plupload.php
+++ b/phpBB/phpbb/db/migration/data/v310/plupload.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php b/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php
index 7d4aea3c95..ea442dfb1b 100644
--- a/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php
+++ b/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,7 +18,7 @@ class postgres_fulltext_drop extends \phpbb\db\migration\migration
public function effectively_installed()
{
// This migration is irrelevant for all non-PostgreSQL DBMSes.
- return strpos($this->db->sql_layer, 'postgres') === false;
+ return strpos($this->db->get_sql_layer(), 'postgres') === false;
}
static public function depends_on()
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_aol.php b/phpBB/phpbb/db/migration/data/v310/profilefield_aol.php
index 87574cb858..65d4fe1078 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_aol.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_aol.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_aol_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_aol_cleanup.php
index a7088c6a7a..f884d83d26 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_aol_cleanup.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_aol_cleanup.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
- * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_change_load_settings.php b/phpBB/phpbb/db/migration/data/v310/profilefield_change_load_settings.php
index 7d09d8149a..7cc4fd8daa 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_change_load_settings.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_change_load_settings.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php
index 9e7ba68327..c44167dbfe 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_contact_field.php b/phpBB/phpbb/db/migration/data/v310/profilefield_contact_field.php
index c7617813eb..02cd420c0f 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_contact_field.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_contact_field.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php b/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php
new file mode 100644
index 0000000000..7324b893cc
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php
@@ -0,0 +1,61 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class profilefield_facebook extends \phpbb\db\migration\profilefield_base_migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\profilefield_contact_field',
+ '\phpbb\db\migration\data\v310\profilefield_show_novalue',
+ '\phpbb\db\migration\data\v310\profilefield_types',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'create_custom_field'))),
+ );
+ }
+
+ protected $profilefield_name = 'phpbb_facebook';
+
+ protected $profilefield_database_type = array('VCHAR', '');
+
+ protected $profilefield_data = array(
+ 'field_name' => 'phpbb_facebook',
+ 'field_type' => 'profilefields.type.string',
+ 'field_ident' => 'phpbb_facebook',
+ 'field_length' => '20',
+ 'field_minlen' => '5',
+ 'field_maxlen' => '50',
+ 'field_novalue' => '',
+ 'field_default_value' => '',
+ 'field_validation' => '[\w.]+',
+ 'field_required' => 0,
+ 'field_show_novalue' => 0,
+ 'field_show_on_reg' => 0,
+ 'field_show_on_pm' => 1,
+ 'field_show_on_vt' => 1,
+ 'field_show_profile' => 1,
+ 'field_hide' => 0,
+ 'field_no_view' => 0,
+ 'field_active' => 1,
+ 'field_is_contact' => 1,
+ 'field_contact_desc' => 'VIEW_FACEBOOK_PROFILE',
+ 'field_contact_url' => 'http://facebook.com/%s/',
+ );
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_field_validation_length.php b/phpBB/phpbb/db/migration/data/v310/profilefield_field_validation_length.php
new file mode 100644
index 0000000000..c7d8b2dc91
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_field_validation_length.php
@@ -0,0 +1,90 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class profilefield_field_validation_length extends \phpbb\db\migration\migration
+{
+ protected $validation_options_old = array(
+ 'ALPHA_SPACERS' => '[\w_\+\. \-\[\]]+',
+ );
+
+ protected $validation_options_new = array(
+ 'ALPHA_SPACERS' => '[\w\x20_+\-\[\]]+',
+ );
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\rc3',
+ );
+ }
+
+ public function update_schema()
+ {
+ return array(
+ 'change_columns' => array(
+ $this->table_prefix . 'profile_fields' => array(
+ 'field_validation' => array('VCHAR_UNI:64', ''),
+ ),
+ ),
+ );
+ }
+
+ public function revert_schema()
+ {
+ return array(
+ 'change_columns' => array(
+ $this->table_prefix . 'profile_fields' => array(
+ 'field_validation' => array('VCHAR_UNI:20', ''),
+ ),
+ ),
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'update_profile_fields_validation'))),
+ );
+ }
+
+ public function revert_data()
+ {
+ return array(
+ array('custom', array(array($this, 'revert_profile_fields_validation'))),
+ );
+ }
+
+ public function update_profile_fields_validation()
+ {
+ foreach ($this->validation_options_new as $validation_type => $regex)
+ {
+ $sql = 'UPDATE ' . $this->table_prefix . "profile_fields
+ SET field_validation = '" . $this->db->sql_escape($this->validation_options_new[$validation_type]) . "'
+ WHERE field_validation = '" . $this->db->sql_escape($this->validation_options_old[$validation_type]) . "'";
+ $this->sql_query($sql);
+ }
+ }
+
+ public function revert_profile_fields_validation()
+ {
+ foreach ($this->validation_options_new as $validation_type => $regex)
+ {
+ $sql = 'UPDATE ' . $this->table_prefix . "profile_fields
+ SET field_validation = '" . $this->db->sql_escape($this->validation_options_old[$validation_type]) . "'
+ WHERE field_validation = '" . $this->db->sql_escape($this->validation_options_new[$validation_type]) . "'";
+ $this->sql_query($sql);
+ }
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php b/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php
new file mode 100644
index 0000000000..3b0963fc19
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php
@@ -0,0 +1,61 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class profilefield_googleplus extends \phpbb\db\migration\profilefield_base_migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\profilefield_contact_field',
+ '\phpbb\db\migration\data\v310\profilefield_show_novalue',
+ '\phpbb\db\migration\data\v310\profilefield_types',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'create_custom_field'))),
+ );
+ }
+
+ protected $profilefield_name = 'phpbb_googleplus';
+
+ protected $profilefield_database_type = array('VCHAR', '');
+
+ protected $profilefield_data = array(
+ 'field_name' => 'phpbb_googleplus',
+ 'field_type' => 'profilefields.type.googleplus',
+ 'field_ident' => 'phpbb_googleplus',
+ 'field_length' => '20',
+ 'field_minlen' => '3',
+ 'field_maxlen' => '255',
+ 'field_novalue' => '',
+ 'field_default_value' => '',
+ 'field_validation' => '[\w]+',
+ 'field_required' => 0,
+ 'field_show_novalue' => 0,
+ 'field_show_on_reg' => 0,
+ 'field_show_on_pm' => 1,
+ 'field_show_on_vt' => 1,
+ 'field_show_profile' => 1,
+ 'field_hide' => 0,
+ 'field_no_view' => 0,
+ 'field_active' => 1,
+ 'field_is_contact' => 1,
+ 'field_contact_desc' => 'VIEW_GOOGLEPLUS_PROFILE',
+ 'field_contact_url' => 'http://plus.google.com/%s',
+ );
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_icq.php b/phpBB/phpbb/db/migration/data/v310/profilefield_icq.php
index 2c8c8c511f..e61653f3db 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_icq.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_icq.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_icq_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_icq_cleanup.php
index 0129a7248f..516c690093 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_icq_cleanup.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_icq_cleanup.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php b/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php
index 2b943c5e53..33a5ba15ae 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_location.php b/phpBB/phpbb/db/migration/data/v310/profilefield_location.php
index 4e62eab2d7..2d27c09e68 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_location.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_location.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_location_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_location_cleanup.php
index 54ff2a31eb..b824e3406a 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_location_cleanup.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_location_cleanup.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php b/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php
index b0ea961c08..75df2bcdee 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php b/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php
index ce51944c3e..7ce5de0f00 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_show_novalue.php b/phpBB/phpbb/db/migration/data/v310/profilefield_show_novalue.php
index d37103e2ce..5fc88b6809 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_show_novalue.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_show_novalue.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php b/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php
new file mode 100644
index 0000000000..0dbe9041bb
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php
@@ -0,0 +1,61 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class profilefield_skype extends \phpbb\db\migration\profilefield_base_migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\profilefield_contact_field',
+ '\phpbb\db\migration\data\v310\profilefield_show_novalue',
+ '\phpbb\db\migration\data\v310\profilefield_types',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'create_custom_field'))),
+ );
+ }
+
+ protected $profilefield_name = 'phpbb_skype';
+
+ protected $profilefield_database_type = array('VCHAR', '');
+
+ protected $profilefield_data = array(
+ 'field_name' => 'phpbb_skype',
+ 'field_type' => 'profilefields.type.string',
+ 'field_ident' => 'phpbb_skype',
+ 'field_length' => '20',
+ 'field_minlen' => '6',
+ 'field_maxlen' => '32',
+ 'field_novalue' => '',
+ 'field_default_value' => '',
+ 'field_validation' => '[a-zA-Z][\w\.,\-_]+',
+ 'field_required' => 0,
+ 'field_show_novalue' => 0,
+ 'field_show_on_reg' => 0,
+ 'field_show_on_pm' => 1,
+ 'field_show_on_vt' => 1,
+ 'field_show_profile' => 1,
+ 'field_hide' => 0,
+ 'field_no_view' => 0,
+ 'field_active' => 1,
+ 'field_is_contact' => 1,
+ 'field_contact_desc' => 'VIEW_SKYPE_PROFILE',
+ 'field_contact_url' => 'skype:%s?userinfo',
+ );
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php b/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php
new file mode 100644
index 0000000000..850e096439
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php
@@ -0,0 +1,61 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class profilefield_twitter extends \phpbb\db\migration\profilefield_base_migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\profilefield_contact_field',
+ '\phpbb\db\migration\data\v310\profilefield_show_novalue',
+ '\phpbb\db\migration\data\v310\profilefield_types',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'create_custom_field'))),
+ );
+ }
+
+ protected $profilefield_name = 'phpbb_twitter';
+
+ protected $profilefield_database_type = array('VCHAR', '');
+
+ protected $profilefield_data = array(
+ 'field_name' => 'phpbb_twitter',
+ 'field_type' => 'profilefields.type.string',
+ 'field_ident' => 'phpbb_twitter',
+ 'field_length' => '20',
+ 'field_minlen' => '1',
+ 'field_maxlen' => '15',
+ 'field_novalue' => '',
+ 'field_default_value' => '',
+ 'field_validation' => '[\w_]+',
+ 'field_required' => 0,
+ 'field_show_novalue' => 0,
+ 'field_show_on_reg' => 0,
+ 'field_show_on_pm' => 1,
+ 'field_show_on_vt' => 1,
+ 'field_show_profile' => 1,
+ 'field_hide' => 0,
+ 'field_no_view' => 0,
+ 'field_active' => 1,
+ 'field_is_contact' => 1,
+ 'field_contact_desc' => 'VIEW_TWITTER_PROFILE',
+ 'field_contact_url' => 'http://twitter.com/%s',
+ );
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_types.php b/phpBB/phpbb/db/migration/data/v310/profilefield_types.php
index 2152aaee20..5045eb8807 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_types.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_types.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_website.php b/phpBB/phpbb/db/migration/data/v310/profilefield_website.php
index 818b66d2e4..e1e10f09f4 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_website.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_website.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_website_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_website_cleanup.php
index 35cc92199e..94442f0497 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_website_cleanup.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_website_cleanup.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_wlm.php b/phpBB/phpbb/db/migration/data/v310/profilefield_wlm.php
index 8a42f1fea1..2cd333fcbd 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_wlm.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_wlm.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_wlm_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_wlm_cleanup.php
index 98b92eb188..7ef9e44020 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_wlm_cleanup.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_wlm_cleanup.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo.php b/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo.php
index 808aec8099..e269f88420 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo_cleanup.php
index c11d06576f..bd724ff7db 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo_cleanup.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo_cleanup.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php b/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php
new file mode 100644
index 0000000000..40a569d2a2
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php
@@ -0,0 +1,61 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class profilefield_youtube extends \phpbb\db\migration\profilefield_base_migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\profilefield_contact_field',
+ '\phpbb\db\migration\data\v310\profilefield_show_novalue',
+ '\phpbb\db\migration\data\v310\profilefield_types',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'create_custom_field'))),
+ );
+ }
+
+ protected $profilefield_name = 'phpbb_youtube';
+
+ protected $profilefield_database_type = array('VCHAR', '');
+
+ protected $profilefield_data = array(
+ 'field_name' => 'phpbb_youtube',
+ 'field_type' => 'profilefields.type.string',
+ 'field_ident' => 'phpbb_youtube',
+ 'field_length' => '20',
+ 'field_minlen' => '3',
+ 'field_maxlen' => '60',
+ 'field_novalue' => '',
+ 'field_default_value' => '',
+ 'field_validation' => '[a-zA-Z][\w\.,\-_]+',
+ 'field_required' => 0,
+ 'field_show_novalue' => 0,
+ 'field_show_on_reg' => 0,
+ 'field_show_on_pm' => 1,
+ 'field_show_on_vt' => 1,
+ 'field_show_profile' => 1,
+ 'field_hide' => 0,
+ 'field_no_view' => 0,
+ 'field_active' => 1,
+ 'field_is_contact' => 1,
+ 'field_contact_desc' => 'VIEW_YOUTUBE_CHANNEL',
+ 'field_contact_url' => 'http://youtube.com/user/%s',
+ );
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php b/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php
new file mode 100644
index 0000000000..f6d27d385e
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php
@@ -0,0 +1,50 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class prune_shadow_topics extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\dev');
+ }
+
+ public function update_schema()
+ {
+ return array(
+ 'add_columns' => array(
+ $this->table_prefix . 'forums' => array(
+ 'enable_shadow_prune' => array('BOOL', 0),
+ 'prune_shadow_days' => array('UINT', 7),
+ 'prune_shadow_freq' => array('UINT', 1),
+ 'prune_shadow_next' => array('INT:11', 0),
+ ),
+ ),
+ );
+ }
+
+ public function revert_schema()
+ {
+ return array(
+ 'drop_columns' => array(
+ $this->table_prefix . 'forums' => array(
+ 'enable_shadow_prune',
+ 'prune_shadow_days',
+ 'prune_shadow_freq',
+ 'prune_shadow_next',
+ ),
+ ),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/rc1.php b/phpBB/phpbb/db/migration/data/v310/rc1.php
new file mode 100644
index 0000000000..10ba7fefff
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/rc1.php
@@ -0,0 +1,39 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class rc1 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\beta4',
+ '\phpbb\db\migration\data\v310\contact_admin_acp_module',
+ '\phpbb\db\migration\data\v310\contact_admin_form',
+ '\phpbb\db\migration\data\v310\passwords_convert_p2',
+ '\phpbb\db\migration\data\v310\profilefield_facebook',
+ '\phpbb\db\migration\data\v310\profilefield_googleplus',
+ '\phpbb\db\migration\data\v310\profilefield_skype',
+ '\phpbb\db\migration\data\v310\profilefield_twitter',
+ '\phpbb\db\migration\data\v310\profilefield_youtube',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0-RC1')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/rc2.php b/phpBB/phpbb/db/migration/data/v310/rc2.php
new file mode 100644
index 0000000000..e1323659da
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/rc2.php
@@ -0,0 +1,31 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class rc2 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\rc1',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0-RC2')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/rc3.php b/phpBB/phpbb/db/migration/data/v310/rc3.php
new file mode 100644
index 0000000000..0e6a452251
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/rc3.php
@@ -0,0 +1,35 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class rc3 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\rc2',
+ '\phpbb\db\migration\data\v310\captcha_plugins',
+ '\phpbb\db\migration\data\v310\rename_too_long_indexes',
+ '\phpbb\db\migration\data\v310\search_type',
+ '\phpbb\db\migration\data\v310\topic_sort_username',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0-RC3')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/rc4.php b/phpBB/phpbb/db/migration/data/v310/rc4.php
new file mode 100644
index 0000000000..47de8291c1
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/rc4.php
@@ -0,0 +1,32 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class rc4 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\rc3',
+ '\phpbb\db\migration\data\v310\notifications_use_full_name',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0-RC4')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/rc5.php b/phpBB/phpbb/db/migration/data/v310/rc5.php
new file mode 100644
index 0000000000..5b6f70e32e
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/rc5.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\db\migration\data\v310;
+
+class rc5 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\rc4',
+ '\phpbb\db\migration\data\v310\profilefield_field_validation_length',
+ '\phpbb\db\migration\data\v310\remove_acp_styles_cache',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0-RC5')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/remove_acp_styles_cache.php b/phpBB/phpbb/db/migration/data/v310/remove_acp_styles_cache.php
new file mode 100644
index 0000000000..7b84539814
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/remove_acp_styles_cache.php
@@ -0,0 +1,51 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class remove_acp_styles_cache extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ $sql = 'SELECT module_id
+ FROM ' . MODULES_TABLE . "
+ WHERE module_class = 'acp'
+ AND module_langname = 'ACP_STYLES_CACHE'";
+ $result = $this->db->sql_query($sql);
+ $module_id = $this->db->sql_fetchfield('module_id');
+ $this->db->sql_freeresult($result);
+
+ return !$module_id;
+ }
+
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\rc4');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('module.remove', array(
+ 'acp',
+ 'ACP_STYLE_MANAGEMENT',
+ array(
+ 'module_basename' => 'acp_styles',
+ 'module_langname' => 'ACP_STYLES_CACHE',
+ 'module_mode' => 'cache',
+ 'module_auth' => 'acl_a_styles',
+ ),
+ )),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/rename_too_long_indexes.php b/phpBB/phpbb/db/migration/data/v310/rename_too_long_indexes.php
new file mode 100644
index 0000000000..8d2a15d8ea
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/rename_too_long_indexes.php
@@ -0,0 +1,38 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class rename_too_long_indexes extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v30x\release_3_0_0');
+ }
+
+ public function update_schema()
+ {
+ return array(
+ 'drop_keys' => array(
+ $this->table_prefix . 'search_wordmatch' => array(
+ 'unq_mtch',
+ ),
+ ),
+ 'add_unique_index' => array(
+ $this->table_prefix . 'search_wordmatch' => array(
+ 'un_mtch' => array('word_id', 'post_id', 'title_match'),
+ ),
+ ),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php b/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php
index 56b7a0916c..575a65d9dd 100644
--- a/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php
+++ b/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php b/phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php
new file mode 100644
index 0000000000..d5f9076196
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php
@@ -0,0 +1,37 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+/**
+* Class captcha_plugin
+*
+* Reset the captcha setting to the default plugin if the defined 'captcha_plugin' is missing.
+*/
+class reset_missing_captcha_plugin extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\dev');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('if', array(
+ (!is_file($this->phpbb_root_path . "includes/captcha/plugins/{$this->config['captcha_plugin']}_plugin." . $this->php_ext)),
+ array('config.update', array('captcha_plugin', 'phpbb_captcha_nogd')),
+ )),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/search_type.php b/phpBB/phpbb/db/migration/data/v310/search_type.php
new file mode 100644
index 0000000000..f89456ae19
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/search_type.php
@@ -0,0 +1,34 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class search_type extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\dev',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('if', array(
+ (is_file($this->phpbb_root_path . 'phpbb/search/' . $this->config['search_type'] . $this->php_ext)),
+ array('config.update', array('search_type', '\\phpbb\\search\\' . $this->config['search_type'])),
+ )),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/signature_module_auth.php b/phpBB/phpbb/db/migration/data/v310/signature_module_auth.php
index 6da1cb8009..e50f5e53a0 100644
--- a/phpBB/phpbb/db/migration/data/v310/signature_module_auth.php
+++ b/phpBB/phpbb/db/migration/data/v310/signature_module_auth.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php
index c9255d88ee..58845b88ec 100644
--- a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php
+++ b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -115,8 +119,9 @@ class soft_delete_mod_convert extends \phpbb\db\migration\migration
{
return new \phpbb\content_visibility(
new \phpbb\auth\auth(),
+ $this->config,
$this->db,
- new \phpbb\user(),
+ new \phpbb\user('\phpbb\datetime'),
$this->phpbb_root_path,
$this->php_ext,
$this->table_prefix . 'forums',
diff --git a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php
index ab4be269e6..246a267a8c 100644
--- a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php
+++ b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php b/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php
index d1a31815b2..5e68db5889 100644
--- a/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php
+++ b/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php b/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php
index f080c78c50..b1e7486e24 100644
--- a/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php
+++ b/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -149,6 +153,15 @@ class softdelete_p1 extends \phpbb\db\migration\migration
$limit = 10;
$converted_forums = 0;
+ if (!$start)
+ {
+ // Preserve the forum_posts value for link forums as it represents redirects.
+ $sql = 'UPDATE ' . $this->table_prefix . 'forums
+ SET forum_posts_approved = forum_posts
+ WHERE forum_type = ' . FORUM_LINK;
+ $this->db->sql_query($sql);
+ }
+
$sql = 'SELECT forum_id, topic_visibility, COUNT(topic_id) AS sum_topics, SUM(topic_posts_approved) AS sum_posts_approved, SUM(topic_posts_unapproved) AS sum_posts_unapproved
FROM ' . $this->table_prefix . 'topics
GROUP BY forum_id, topic_visibility
diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php b/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php
index 38b190c766..849a996c1b 100644
--- a/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php
+++ b/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php
index 26f1046287..5a3a1d5de7 100644
--- a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php
+++ b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -136,7 +140,7 @@ class style_update_p1 extends \phpbb\db\migration\migration
$sql_ary = array(
'style_name' => 'prosilver',
- 'style_copyright' => '&copy; phpBB Group',
+ 'style_copyright' => '&copy; phpBB Limited',
'style_active' => 1,
'style_path' => 'prosilver',
'bbcode_bitfield' => 'lNg=',
diff --git a/phpBB/phpbb/db/migration/data/v310/style_update_p2.php b/phpBB/phpbb/db/migration/data/v310/style_update_p2.php
index 40d6a4dbbd..52c8ffb2e2 100644
--- a/phpBB/phpbb/db/migration/data/v310/style_update_p2.php
+++ b/phpBB/phpbb/db/migration/data/v310/style_update_p2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/teampage.php b/phpBB/phpbb/db/migration/data/v310/teampage.php
index 172435c672..f8edbc3492 100644
--- a/phpBB/phpbb/db/migration/data/v310/teampage.php
+++ b/phpBB/phpbb/db/migration/data/v310/teampage.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/timezone.php b/phpBB/phpbb/db/migration/data/v310/timezone.php
index dd0c6a2093..1f6b47ad50 100644
--- a/phpBB/phpbb/db/migration/data/v310/timezone.php
+++ b/phpBB/phpbb/db/migration/data/v310/timezone.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -39,23 +43,48 @@ class timezone extends \phpbb\db\migration\migration
);
}
- public function update_timezones()
+ public function update_timezones($start)
{
- // Update user timezones
- $sql = 'SELECT user_dst, user_timezone
- FROM ' . $this->table_prefix . 'users
- GROUP BY user_timezone, user_dst';
- $result = $this->db->sql_query($sql);
+ $start = (int) $start;
+ $limit = 500;
+ $converted = 0;
+
+ $update_blocks = array();
+ $sql = 'SELECT user_id, user_timezone, user_dst
+ FROM ' . $this->table_prefix . 'users
+ ORDER BY user_id ASC';
+ $result = $this->db->sql_query_limit($sql, $limit, $start);
while ($row = $this->db->sql_fetchrow($result))
{
+ $converted++;
+
+ // In case this is somehow run twice on a row.
+ // Otherwise it would just end up as UTC on the second run
+ if (is_numeric($row['user_timezone']))
+ {
+ $update_blocks[$row['user_timezone'] . ':' . $row['user_dst']][] = (int) $row['user_id'];
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ // Update blocks of users who share the same timezone/dst
+ foreach ($update_blocks as $timezone => $user_ids)
+ {
+ $timezone = explode(':', $timezone);
+ $converted_timezone = $this->convert_phpbb30_timezone($timezone[0], $timezone[1]);
+
$sql = 'UPDATE ' . $this->table_prefix . "users
- SET user_timezone = '" . $this->db->sql_escape($this->convert_phpbb30_timezone($row['user_timezone'], $row['user_dst'])) . "'
- WHERE user_timezone = '" . $this->db->sql_escape($row['user_timezone']) . "'
- AND user_dst = " . (int) $row['user_dst'];
+ SET user_timezone = '" . $this->db->sql_escape($converted_timezone) . "'
+ WHERE " . $this->db->sql_in_set('user_id', $user_ids);
$this->sql_query($sql);
}
- $this->db->sql_freeresult($result);
+
+ if ($converted == $limit)
+ {
+ // There are still more to convert
+ return $start + $limit;
+ }
// Update board default timezone
$sql = 'UPDATE ' . $this->table_prefix . "config
diff --git a/phpBB/phpbb/db/migration/data/v310/timezone_p2.php b/phpBB/phpbb/db/migration/data/v310/timezone_p2.php
index 1066ab8571..3ac7ab3c51 100644
--- a/phpBB/phpbb/db/migration/data/v310/timezone_p2.php
+++ b/phpBB/phpbb/db/migration/data/v310/timezone_p2.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php b/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php
new file mode 100644
index 0000000000..527da20590
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php
@@ -0,0 +1,44 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class topic_sort_username extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\dev');
+ }
+
+ public function update_schema()
+ {
+ return array(
+ 'change_columns' => array(
+ $this->table_prefix . 'topics' => array(
+ 'topic_first_poster_name' => array('VCHAR_UNI:255', '', 'true_sort'),
+ ),
+ ),
+ );
+ }
+
+ public function revert_schema()
+ {
+ return array(
+ 'change_columns' => array(
+ $this->table_prefix . 'topics' => array(
+ 'topic_first_poster_name' => array('VCHAR_UNI:255', ''),
+ ),
+ ),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/ucp_popuppm_module.php b/phpBB/phpbb/db/migration/data/v310/ucp_popuppm_module.php
index f8ada6c6f5..8600f6ee27 100644
--- a/phpBB/phpbb/db/migration/data/v310/ucp_popuppm_module.php
+++ b/phpBB/phpbb/db/migration/data/v310/ucp_popuppm_module.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/db/migration/exception.php b/phpBB/phpbb/db/migration/exception.php
index cfe546d1ab..7990e85f2d 100644
--- a/phpBB/phpbb/db/migration/exception.php
+++ b/phpBB/phpbb/db/migration/exception.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package db
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\db\migration;
/**
* The migrator is responsible for applying new migrations in the correct order.
-*
-* @package db
*/
class exception extends \Exception
{
diff --git a/phpBB/phpbb/db/migration/helper.php b/phpBB/phpbb/db/migration/helper.php
index 009ad1da9f..e40deeb37b 100644
--- a/phpBB/phpbb/db/migration/helper.php
+++ b/phpBB/phpbb/db/migration/helper.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package db
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\db\migration;
/**
* The migrator is responsible for applying new migrations in the correct order.
-*
-* @package db
*/
class helper
{
diff --git a/phpBB/phpbb/db/migration/migration.php b/phpBB/phpbb/db/migration/migration.php
index b32de00871..5f120333e1 100644
--- a/phpBB/phpbb/db/migration/migration.php
+++ b/phpBB/phpbb/db/migration/migration.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package db
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -15,15 +19,13 @@ namespace phpbb\db\migration;
* Each migration consists of a set of schema and data changes to be implemented
* in a subclass. This class provides various utility methods to simplify editing
* a phpBB.
-*
-* @package db
*/
abstract class migration
{
/** @var \phpbb\config\config */
protected $config;
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\db\tools */
@@ -48,13 +50,13 @@ abstract class migration
* Constructor
*
* @param \phpbb\config\config $config
- * @param \phpbb\db\driver\driver $db
+ * @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\db\tools $db_tools
* @param string $phpbb_root_path
* @param string $php_ext
* @param string $table_prefix
*/
- public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix)
+ public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix)
{
$this->config = $config;
$this->db = $db;
@@ -158,11 +160,11 @@ abstract class migration
else
{
$result = $this->db->sql_query($sql);
- if ($this->db->sql_error_triggered)
+ if ($this->db->get_sql_error_triggered())
{
$this->errors[] = array(
- 'sql' => $this->db->sql_error_sql,
- 'code' => $this->db->sql_error_returned,
+ 'sql' => $this->db->get_sql_error_sql(),
+ 'code' => $this->db->get_sql_error_returned(),
);
}
}
diff --git a/phpBB/phpbb/db/migration/profilefield_base_migration.php b/phpBB/phpbb/db/migration/profilefield_base_migration.php
index dec7a4c2bb..9000949a7d 100644
--- a/phpBB/phpbb/db/migration/profilefield_base_migration.php
+++ b/phpBB/phpbb/db/migration/profilefield_base_migration.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -17,6 +21,23 @@ abstract class profilefield_base_migration extends \phpbb\db\migration\migration
protected $profilefield_data;
+ /**
+ * Language data should be in array -> each language_data in separate key
+ * array(
+ * array(
+ * 'option_id' => value,
+ * 'field_type' => value,
+ * 'lang_value' => value,
+ * ),
+ * array(
+ * 'option_id' => value,
+ * 'field_type' => value,
+ * 'lang_value' => value,
+ * ),
+ * )
+ */
+ protected $profilefield_language_data;
+
protected $user_column_name;
public function effectively_installed()
@@ -54,6 +75,13 @@ abstract class profilefield_base_migration extends \phpbb\db\migration\migration
);
}
+ public function revert_data()
+ {
+ return array(
+ array('custom', array(array($this, 'delete_custom_profile_field_data'))),
+ );
+ }
+
public function create_custom_field()
{
$sql = 'SELECT MAX(field_order) as max_field_order
@@ -75,12 +103,13 @@ abstract class profilefield_base_migration extends \phpbb\db\migration\migration
$sql = 'SELECT lang_id
FROM ' . LANG_TABLE;
$result = $this->db->sql_query($sql);
+ $lang_name = (strpos($this->profilefield_name, 'phpbb_') === 0) ? strtoupper(substr($this->profilefield_name, 6)) : strtoupper($this->profilefield_name);
while ($lang_id = (int) $this->db->sql_fetchfield('lang_id'))
{
$insert_buffer->insert(array(
- 'field_id' => $field_id,
- 'lang_id' => $lang_id,
- 'lang_name' => strtoupper(substr($this->profilefield_name, 6)),// Remove phpbb_ from field name
+ 'field_id' => (int) $field_id,
+ 'lang_id' => (int) $lang_id,
+ 'lang_name' => $lang_name,
'lang_explain' => '',
'lang_default_value' => '',
));
@@ -91,6 +120,69 @@ abstract class profilefield_base_migration extends \phpbb\db\migration\migration
}
/**
+ * Create Custom profile fields languguage entries
+ */
+ public function create_language_entries()
+ {
+ $field_id = $this->get_custom_profile_field_id();
+
+ $insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, PROFILE_FIELDS_LANG_TABLE);
+
+ $sql = 'SELECT lang_id
+ FROM ' . LANG_TABLE;
+ $result = $this->db->sql_query($sql);
+ while ($lang_id = (int) $this->db->sql_fetchfield('lang_id'))
+ {
+ foreach ($this->profilefield_language_data as $language_data)
+ {
+ $insert_buffer->insert(array_merge(array(
+ 'field_id' => (int) $field_id,
+ 'lang_id' => (int) $lang_id,
+ ), $language_data));
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ $insert_buffer->flush();
+ }
+
+ /**
+ * Clean database when reverting the migration
+ */
+ public function delete_custom_profile_field_data()
+ {
+ $field_id = $this->get_custom_profile_field_id();
+
+ $sql = 'DELETE FROM ' . PROFILE_FIELDS_TABLE . '
+ WHERE field_id = ' . (int) $field_id;
+ $this->db->sql_query($sql);
+
+ $sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . '
+ WHERE field_id = ' . (int) $field_id;
+ $this->db->sql_query($sql);
+
+ $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . '
+ WHERE field_id = ' . (int) $field_id;
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * Get custom profile field id
+ * @return int custom profile filed id
+ */
+ public function get_custom_profile_field_id()
+ {
+ $sql = 'SELECT field_id
+ FROM ' . PROFILE_FIELDS_TABLE . "
+ WHERE field_name = '" . $this->profilefield_name . "'";
+ $result = $this->db->sql_query($sql);
+ $field_id = (int) $this->db->sql_fetchfield('field_id');
+ $this->db->sql_freeresult($result);
+
+ return $field_id;
+ }
+
+ /**
* @param int $start Start of staggering step
* @return mixed int start of the next step, null if the end was reached
*/
diff --git a/phpBB/phpbb/db/migration/schema_generator.php b/phpBB/phpbb/db/migration/schema_generator.php
index a7e2fa8f06..91d8307d91 100644
--- a/phpBB/phpbb/db/migration/schema_generator.php
+++ b/phpBB/phpbb/db/migration/schema_generator.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package db
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,15 +15,13 @@ namespace phpbb\db\migration;
/**
* The schema generator generates the schema based on the existing migrations
-*
-* @package db
*/
class schema_generator
{
/** @var \phpbb\config\config */
protected $config;
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\db\tools */
@@ -40,10 +42,13 @@ class schema_generator
/** @var array */
protected $tables;
+ /** @var array */
+ protected $dependencies = array();
+
/**
* Constructor
*/
- public function __construct(array $class_names, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix)
+ public function __construct(array $class_names, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix)
{
$this->config = $config;
$this->db = $db;
@@ -69,11 +74,13 @@ class schema_generator
$migrations = $this->class_names;
$tree = array();
+ $check_dependencies = true;
while (!empty($migrations))
{
foreach ($migrations as $migration_class)
{
$open_dependencies = array_diff($migration_class::depends_on(), $tree);
+
if (empty($open_dependencies))
{
$migration = new $migration_class($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix);
@@ -102,7 +109,25 @@ class schema_generator
{
foreach ($add_columns as $column => $column_data)
{
- $this->tables[$table]['COLUMNS'][$column] = $column_data;
+ if (isset($column_data['after']))
+ {
+ $columns = $this->tables[$table]['COLUMNS'];
+ $offset = array_search($column_data['after'], array_keys($columns));
+ unset($column_data['after']);
+
+ if ($offset === false)
+ {
+ $this->tables[$table]['COLUMNS'][$column] = array_values($column_data);
+ }
+ else
+ {
+ $this->tables[$table]['COLUMNS'] = array_merge(array_slice($columns, 0, $offset + 1, true), array($column => array_values($column_data)), array_slice($columns, $offset));
+ }
+ }
+ else
+ {
+ $this->tables[$table]['COLUMNS'][$column] = $column_data;
+ }
}
}
}
@@ -170,10 +195,41 @@ class schema_generator
}
unset($migrations[$migration_key]);
}
+ else if ($check_dependencies)
+ {
+ $this->dependencies = array_merge($this->dependencies, $open_dependencies);
+ }
+ }
+
+ // Only run this check after the first run
+ if ($check_dependencies)
+ {
+ $this->check_dependencies();
+ $check_dependencies = false;
}
}
ksort($this->tables);
return $this->tables;
}
+
+ /**
+ * Check if one of the migrations files' dependencies can't be resolved
+ * by the supplied list of migrations
+ *
+ * @throws \UnexpectedValueException If a dependency can't be resolved
+ */
+ protected function check_dependencies()
+ {
+ // Strip duplicate values from array
+ $this->dependencies = array_unique($this->dependencies);
+
+ foreach ($this->dependencies as $dependency)
+ {
+ if (!in_array($dependency, $this->class_names))
+ {
+ throw new \UnexpectedValueException("Unable to resolve the dependency '$dependency'");
+ }
+ }
+ }
}
diff --git a/phpBB/phpbb/db/migration/tool/config.php b/phpBB/phpbb/db/migration/tool/config.php
index 36a1931f4e..f93e7118c4 100644
--- a/phpBB/phpbb/db/migration/tool/config.php
+++ b/phpBB/phpbb/db/migration/tool/config.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\db\migration\tool;
/**
* Migration config tool
-*
-* @package db
*/
class config implements \phpbb\db\migration\tool\tool_interface
{
@@ -64,6 +66,7 @@ class config implements \phpbb\db\migration\tool\tool_interface
* like to update
* @param mixed $config_value The value of the config setting
* @return null
+ * @throws \phpbb\db\migration\exception
*/
public function update($config_name, $config_value)
{
@@ -85,6 +88,7 @@ class config implements \phpbb\db\migration\tool\tool_interface
* like to update
* @param mixed $config_value The value of the config setting
* @return null
+ * @throws \phpbb\db\migration\exception
*/
public function update_if_equals($compare, $config_name, $config_value)
{
diff --git a/phpBB/phpbb/db/migration/tool/config_text.php b/phpBB/phpbb/db/migration/tool/config_text.php
new file mode 100644
index 0000000000..bf8ac55023
--- /dev/null
+++ b/phpBB/phpbb/db/migration/tool/config_text.php
@@ -0,0 +1,125 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\tool;
+
+/**
+* Migration config_text tool
+*/
+class config_text implements \phpbb\db\migration\tool\tool_interface
+{
+ /** @var \phpbb\config\db_text */
+ protected $config_text;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\config\db_text $config_text
+ */
+ public function __construct(\phpbb\config\db_text $config_text)
+ {
+ $this->config_text = $config_text;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_name()
+ {
+ return 'config_text';
+ }
+
+ /**
+ * Add a config_text setting.
+ *
+ * @param string $config_name The name of the config_text setting
+ * you would like to add
+ * @param mixed $config_value The value of the config_text setting
+ * @return null
+ */
+ public function add($config_name, $config_value)
+ {
+ if (!is_null($this->config_text->get($config_name)))
+ {
+ return;
+ }
+
+ $this->config_text->set($config_name, $config_value);
+ }
+
+ /**
+ * Update an existing config_text setting.
+ *
+ * @param string $config_name The name of the config_text setting you would
+ * like to update
+ * @param mixed $config_value The value of the config_text setting
+ * @return null
+ * @throws \phpbb\db\migration\exception
+ */
+ public function update($config_name, $config_value)
+ {
+ if (is_null($this->config_text->get($config_name)))
+ {
+ throw new \phpbb\db\migration\exception('CONFIG_NOT_EXIST', $config_name);
+ }
+
+ $this->config_text->set($config_name, $config_value);
+ }
+
+ /**
+ * Remove an existing config_text setting.
+ *
+ * @param string $config_name The name of the config_text setting you would
+ * like to remove
+ * @return null
+ */
+ public function remove($config_name)
+ {
+ if (is_null($this->config_text->get($config_name)))
+ {
+ return;
+ }
+
+ $this->config_text->delete($config_name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reverse()
+ {
+ $arguments = func_get_args();
+ $original_call = array_shift($arguments);
+
+ $call = false;
+ switch ($original_call)
+ {
+ case 'add':
+ $call = 'remove';
+ break;
+
+ case 'remove':
+ $call = 'add';
+ if (sizeof($arguments) == 1)
+ {
+ $arguments[] = '';
+ }
+ break;
+ }
+
+ if ($call)
+ {
+ return call_user_func_array(array(&$this, $call), $arguments);
+ }
+ }
+}
diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php
index ebbcbae301..db43046a95 100644
--- a/phpBB/phpbb/db/migration/tool/module.php
+++ b/phpBB/phpbb/db/migration/tool/module.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -11,15 +15,13 @@ namespace phpbb\db\migration\tool;
/**
* Migration module management tool
-*
-* @package db
*/
class module implements \phpbb\db\migration\tool\tool_interface
{
/** @var \phpbb\cache\service */
protected $cache;
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\user */
@@ -37,14 +39,14 @@ class module implements \phpbb\db\migration\tool\tool_interface
/**
* Constructor
*
- * @param \phpbb\db\driver\driver $db
+ * @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\cache\service $cache
* @param \phpbb\user $user
* @param string $phpbb_root_path
* @param string $php_ext
* @param string $modules_table
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\cache\service $cache, \phpbb\user $user, $phpbb_root_path, $php_ext, $modules_table)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\user $user, $phpbb_root_path, $php_ext, $modules_table)
{
$this->db = $db;
$this->cache = $cache;
@@ -165,6 +167,7 @@ class module implements \phpbb\db\migration\tool\tool_interface
* modules in that info file.
* path, specify that here
* @return null
+ * @throws \phpbb\db\migration\exception
*/
public function add($class, $parent = 0, $data = array())
{
@@ -329,6 +332,7 @@ class module implements \phpbb\db\migration\tool\tool_interface
* @param int|string $module The module id|module_langname
* specify that here
* @return null
+ * @throws \phpbb\db\migration\exception
*/
public function remove($class, $parent = 0, $module = '')
{
@@ -464,6 +468,7 @@ class module implements \phpbb\db\migration\tool\tool_interface
* @param string $class Module Class
* @param string $basename Module Basename
* @return array Module Information
+ * @throws \phpbb\db\migration\exception
*/
protected function get_module_info($class, $basename)
{
diff --git a/phpBB/phpbb/db/migration/tool/permission.php b/phpBB/phpbb/db/migration/tool/permission.php
index 38fcbd2952..5cfbc5ca00 100644
--- a/phpBB/phpbb/db/migration/tool/permission.php
+++ b/phpBB/phpbb/db/migration/tool/permission.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\db\migration\tool;
/**
* Migration permission management tool
-*
-* @package db
*/
class permission implements \phpbb\db\migration\tool\tool_interface
{
@@ -22,7 +24,7 @@ class permission implements \phpbb\db\migration\tool\tool_interface
/** @var \phpbb\cache\service */
protected $cache;
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var string */
@@ -34,13 +36,13 @@ class permission implements \phpbb\db\migration\tool\tool_interface
/**
* Constructor
*
- * @param \phpbb\db\driver\driver $db
+ * @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\cache\service $cache
* @param \phpbb\auth\auth $auth
* @param string $phpbb_root_path
* @param string $php_ext
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\cache\service $cache, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext)
{
$this->db = $db;
$this->cache = $cache;
@@ -103,6 +105,7 @@ class permission implements \phpbb\db\migration\tool\tool_interface
* @param string $auth_option The name of the permission (auth) option
* @param bool $global True for checking a global permission setting,
* False for a local permission setting
+ * @param int|false $copy_from If set, contains the id of the permission from which to copy the new one.
* @return null
*/
public function add($auth_option, $global = true, $copy_from = false)
@@ -241,7 +244,9 @@ class permission implements \phpbb\db\migration\tool\tool_interface
* Add a new permission role
*
* @param string $role_name The new role name
- * @param sting $role_type The type (u_, m_, a_)
+ * @param string $role_type The type (u_, m_, a_)
+ * @param string $role_description Description of the new role
+ *
* @return null
*/
public function role_add($role_name, $role_type, $role_description = '')
@@ -281,6 +286,7 @@ class permission implements \phpbb\db\migration\tool\tool_interface
* @param string $old_role_name The old role name
* @param string $new_role_name The new role name
* @return null
+ * @throws \phpbb\db\migration\exception
*/
public function role_update($old_role_name, $new_role_name)
{
@@ -343,6 +349,7 @@ class permission implements \phpbb\db\migration\tool\tool_interface
* @param bool $has_permission True if you want to give them permission,
* false if you want to deny them permission
* @return null
+ * @throws \phpbb\db\migration\exception
*/
public function permission_set($name, $auth_option, $type = 'role', $has_permission = true)
{
@@ -488,6 +495,7 @@ class permission implements \phpbb\db\migration\tool\tool_interface
* auth_options you would like to set
* @param string $type The type (role|group)
* @return null
+ * @throws \phpbb\db\migration\exception
*/
public function permission_unset($name, $auth_option, $type = 'role')
{
diff --git a/phpBB/phpbb/db/migration/tool/tool_interface.php b/phpBB/phpbb/db/migration/tool/tool_interface.php
index e7b89d8858..07cd2435e4 100644
--- a/phpBB/phpbb/db/migration/tool/tool_interface.php
+++ b/phpBB/phpbb/db/migration/tool/tool_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package migration
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\db\migration\tool;
/**
* Migration tool interface
-*
-* @package db
*/
interface tool_interface
{
diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php
index 4fb3f1a241..44bea3c5d2 100644
--- a/phpBB/phpbb/db/migrator.php
+++ b/phpBB/phpbb/db/migrator.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package db
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+* 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.
*
*/
@@ -11,15 +15,13 @@ namespace phpbb\db;
/**
* The migrator is responsible for applying new migrations in the correct order.
-*
-* @package db
*/
class migrator
{
/** @var \phpbb\config\config */
protected $config;
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\db\tools */
@@ -68,7 +70,7 @@ class migrator
/**
* Constructor of the database migrator
*/
- public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\db\tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper)
+ public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper)
{
$this->config = $config;
$this->db = $db;
@@ -108,7 +110,7 @@ class migrator
FROM " . $this->migrations_table;
$result = $this->db->sql_query($sql);
- if (!$this->db->sql_error_triggered)
+ if (!$this->db->get_sql_error_triggered())
{
while ($migration = $this->db->sql_fetchrow($result))
{
@@ -165,8 +167,9 @@ class migrator
/**
* Attempts to apply a step of the given migration or one of its dependencies
*
- * @param string The class name of the migration
+ * @param string $name The class name of the migration
* @return bool Whether any update step was successfully run
+ * @throws \phpbb\db\migration\exception
*/
protected function try_apply($name)
{
@@ -300,7 +303,7 @@ class migrator
/**
* Attempts to revert a step of the given migration or one of its dependencies
*
- * @param string The class name of the migration
+ * @param string $name The class name of the migration
* @return bool Whether any update step was successfully run
*/
protected function try_revert($name)
@@ -366,6 +369,7 @@ class migrator
* @param bool|string $state Current state of the migration
* @param bool $revert true to revert a data step
* @return bool|string migration state. True if completed, serialized array if not finished
+ * @throws \phpbb\db\migration\exception
*/
protected function process_data_step($steps, $state, $revert = false)
{
@@ -462,6 +466,7 @@ class migrator
* @param mixed $last_result Result to pass to the callable (only for 'custom' method)
* @param bool $reverse False to install, True to attempt uninstallation by reversing the call
* @return array Array with parameters for call_user_func_array(), 0 is the callable, 1 is parameters
+ * @throws \phpbb\db\migration\exception
*/
protected function get_callable_from_step(array $step, $last_result = 0, $reverse = false)
{
@@ -509,10 +514,17 @@ class migrator
throw new \phpbb\db\migration\exception('MIGRATION_INVALID_DATA_CUSTOM_NOT_CALLABLE', $step);
}
- return array(
- $parameters[0],
- array($last_result),
- );
+ if ($reverse)
+ {
+ return false;
+ }
+ else
+ {
+ return array(
+ $parameters[0],
+ array($last_result),
+ );
+ }
break;
default:
@@ -703,55 +715,26 @@ class migrator
}
/**
- * Load migration data files from a directory
- *
- * @param \phpbb\extension\finder $finder
- * @param string $path Path to migration data files
- * @param bool $check_fulfillable If TRUE (default), we will check
- * if all of the migrations are fulfillable after loading them.
- * If FALSE, we will not check. You SHOULD check at least once
- * to prevent errors (if including multiple directories, check
- * with the last call to prevent throwing errors unnecessarily).
- * @return array Array of migration names
+ * Creates the migrations table if it does not exist.
+ * @return null
*/
- public function load_migrations(\phpbb\extension\finder $finder, $path, $check_fulfillable = true)
+ public function create_migrations_table()
{
- if (!is_dir($path))
+ // Make sure migrations have been installed.
+ if (!$this->db_tools->sql_table_exists($this->table_prefix . 'migrations'))
{
- throw new \phpbb\db\migration\exception('DIRECTORY INVALID', $path);
+ $this->db_tools->sql_create_table($this->table_prefix . 'migrations', array(
+ 'COLUMNS' => array(
+ 'migration_name' => array('VCHAR', ''),
+ 'migration_depends_on' => array('TEXT', ''),
+ 'migration_schema_done' => array('BOOL', 0),
+ 'migration_data_done' => array('BOOL', 0),
+ 'migration_data_state' => array('TEXT', ''),
+ 'migration_start_time' => array('TIMESTAMP', 0),
+ 'migration_end_time' => array('TIMESTAMP', 0),
+ ),
+ 'PRIMARY_KEY' => 'migration_name',
+ ));
}
-
- $migrations = array();
-
- $files = $finder
- ->extension_directory("/")
- ->find_from_paths(array('/' => $path));
- foreach ($files as $file)
- {
- $migrations[$file['path'] . $file['filename']] = '';
- }
- $migrations = $finder->get_classes_from_files($migrations);
-
- foreach ($migrations as $migration)
- {
- if (!in_array($migration, $this->migrations))
- {
- $this->migrations[] = $migration;
- }
- }
-
- if ($check_fulfillable)
- {
- foreach ($this->migrations as $name)
- {
- $unfulfillable = $this->unfulfillable($name);
- if ($unfulfillable !== false)
- {
- throw new \phpbb\db\migration\exception('MIGRATION_NOT_FULFILLABLE', $name, $unfulfillable);
- }
- }
- }
-
- return $this->migrations;
}
}
diff --git a/phpBB/phpbb/db/sql_insert_buffer.php b/phpBB/phpbb/db/sql_insert_buffer.php
index 41026ad425..14e3c54f09 100644
--- a/phpBB/phpbb/db/sql_insert_buffer.php
+++ b/phpBB/phpbb/db/sql_insert_buffer.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -44,12 +48,10 @@ namespace phpbb\db;
*
* $buffer->flush();
* </code>
-*
-* @package dbal
*/
class sql_insert_buffer
{
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var string */
@@ -62,11 +64,11 @@ class sql_insert_buffer
protected $buffer = array();
/**
- * @param \phpbb\db\driver\driver $db
+ * @param \phpbb\db\driver\driver_interface $db
* @param string $table_name
* @param int $max_buffered_rows
*/
- public function __construct(\phpbb\db\driver\driver $db, $table_name, $max_buffered_rows = 500)
+ public function __construct(\phpbb\db\driver\driver_interface $db, $table_name, $max_buffered_rows = 500)
{
$this->db = $db;
$this->table_name = $table_name;
@@ -90,7 +92,7 @@ class sql_insert_buffer
// Flush buffer if it is full or when DB does not support multi inserts.
// In the later case, the buffer will always only contain one row.
- if (!$this->db->multi_insert || sizeof($this->buffer) >= $this->max_buffered_rows)
+ if (!$this->db->get_multi_insert() || sizeof($this->buffer) >= $this->max_buffered_rows)
{
return $this->flush();
}
diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php
index 8631c11d0e..0781d7425e 100644
--- a/phpBB/phpbb/db/tools.php
+++ b/phpBB/phpbb/db/tools.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package dbal
-* @copyright (c) 2007 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,8 +16,6 @@ namespace phpbb\db;
/**
* Database Tools for handling cross-db actions such as altering columns, etc.
* Currently not supported is returning SQL for creating tables.
-*
-* @package dbal
*/
class tools
{
@@ -34,6 +36,12 @@ class tools
var $dbms_type_map = array();
/**
+ * Is the used MS SQL Server a SQL Server 2000?
+ * @var bool
+ */
+ protected $is_sql_server_2000;
+
+ /**
* Get the column types for every database we support
*
* @return array
@@ -101,36 +109,6 @@ class tools
'VARBINARY' => 'varbinary(255)',
),
- 'firebird' => array(
- 'INT:' => 'INTEGER',
- 'BINT' => 'DOUBLE PRECISION',
- 'UINT' => 'INTEGER',
- 'UINT:' => 'INTEGER',
- 'TINT:' => 'INTEGER',
- 'USINT' => 'INTEGER',
- 'BOOL' => 'INTEGER',
- 'VCHAR' => 'VARCHAR(255) CHARACTER SET NONE',
- 'VCHAR:' => 'VARCHAR(%d) CHARACTER SET NONE',
- 'CHAR:' => 'CHAR(%d) CHARACTER SET NONE',
- 'XSTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
- 'STEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
- 'TEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
- 'MTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
- 'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8',
- 'STEXT_UNI' => 'VARCHAR(255) CHARACTER SET UTF8',
- 'TEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
- 'MTEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
- 'TIMESTAMP' => 'INTEGER',
- 'DECIMAL' => 'DOUBLE PRECISION',
- 'DECIMAL:' => 'DOUBLE PRECISION',
- 'PDECIMAL' => 'DOUBLE PRECISION',
- 'PDECIMAL:' => 'DOUBLE PRECISION',
- 'VCHAR_UNI' => 'VARCHAR(255) CHARACTER SET UTF8',
- 'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8',
- 'VCHAR_CI' => 'VARCHAR(255) CHARACTER SET UTF8',
- 'VARBINARY' => 'CHAR(255) CHARACTER SET NONE',
- ),
-
'mssql' => array(
'INT:' => '[int]',
'BINT' => '[float]',
@@ -251,6 +229,36 @@ class tools
'VARBINARY' => 'blob',
),
+ 'sqlite3' => array(
+ 'INT:' => 'INT(%d)',
+ 'BINT' => 'BIGINT(20)',
+ 'UINT' => 'INTEGER UNSIGNED',
+ 'UINT:' => 'INTEGER UNSIGNED',
+ 'TINT:' => 'TINYINT(%d)',
+ 'USINT' => 'INTEGER UNSIGNED',
+ 'BOOL' => 'INTEGER UNSIGNED',
+ 'VCHAR' => 'VARCHAR(255)',
+ 'VCHAR:' => 'VARCHAR(%d)',
+ 'CHAR:' => 'CHAR(%d)',
+ 'XSTEXT' => 'TEXT(65535)',
+ 'STEXT' => 'TEXT(65535)',
+ 'TEXT' => 'TEXT(65535)',
+ 'MTEXT' => 'MEDIUMTEXT(16777215)',
+ 'XSTEXT_UNI'=> 'TEXT(65535)',
+ 'STEXT_UNI' => 'TEXT(65535)',
+ 'TEXT_UNI' => 'TEXT(65535)',
+ 'MTEXT_UNI' => 'MEDIUMTEXT(16777215)',
+ 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED',
+ 'DECIMAL' => 'DECIMAL(5,2)',
+ 'DECIMAL:' => 'DECIMAL(%d,2)',
+ 'PDECIMAL' => 'DECIMAL(6,3)',
+ 'PDECIMAL:' => 'DECIMAL(%d,3)',
+ 'VCHAR_UNI' => 'VARCHAR(255)',
+ 'VCHAR_UNI:'=> 'VARCHAR(%d)',
+ 'VCHAR_CI' => 'VARCHAR(255)',
+ 'VARBINARY' => 'BLOB',
+ ),
+
'postgres' => array(
'INT:' => 'INT4',
'BINT' => 'INT8',
@@ -293,7 +301,7 @@ class tools
* A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules.
* @var array
*/
- var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite');
+ var $supported_dbms = array('mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite', 'sqlite3');
/**
* This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array).
@@ -304,10 +312,10 @@ class tools
/**
* Constructor. Set DB Object and set {@link $return_statements return_statements}.
*
- * @param \phpbb\db\driver\driver $db Database connection
+ * @param \phpbb\db\driver\driver_interface $db Database connection
* @param bool $return_statements True if only statements should be returned and no SQL being executed
*/
- public function __construct(\phpbb\db\driver\driver $db, $return_statements = false)
+ public function __construct(\phpbb\db\driver\driver_interface $db, $return_statements = false)
{
$this->db = $db;
$this->return_statements = $return_statements;
@@ -315,7 +323,7 @@ class tools
$this->dbms_type_map = self::get_dbms_type_map();
// Determine mapping database type
- switch ($this->db->sql_layer)
+ switch ($this->db->get_sql_layer())
{
case 'mysql':
$this->sql_layer = 'mysql_40';
@@ -346,7 +354,7 @@ class tools
break;
default:
- $this->sql_layer = $this->db->sql_layer;
+ $this->sql_layer = $this->db->get_sql_layer();
break;
}
}
@@ -369,7 +377,7 @@ class tools
*/
function sql_list_tables()
{
- switch ($this->db->sql_layer)
+ switch ($this->db->get_sql_layer())
{
case 'mysql':
case 'mysql4':
@@ -383,6 +391,13 @@ class tools
WHERE type = "table"';
break;
+ case 'sqlite3':
+ $sql = 'SELECT name
+ FROM sqlite_master
+ WHERE type = "table"
+ AND name <> "sqlite_sequence"';
+ break;
+
case 'mssql':
case 'mssql_odbc':
case 'mssqlnative':
@@ -396,13 +411,6 @@ class tools
FROM pg_stat_user_tables';
break;
- case 'firebird':
- $sql = 'SELECT rdb$relation_name
- FROM rdb$relations
- WHERE rdb$view_source is null
- AND rdb$system_flag = 0';
- break;
-
case 'oracle':
$sql = 'SELECT table_name
FROM USER_TABLES';
@@ -535,7 +543,6 @@ class tools
// Close the table for two DBMS and add to the statements
switch ($this->sql_layer)
{
- case 'firebird':
case 'mssql':
case 'mssqlnative':
$table_sql .= "\n);";
@@ -561,10 +568,10 @@ class tools
case 'mysql_41':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')';
break;
- case 'firebird':
case 'mssql':
case 'mssqlnative':
// We need the data here
@@ -598,6 +605,7 @@ class tools
case 'mysql_40':
case 'sqlite':
+ case 'sqlite3':
$table_sql .= "\n);";
$statements[] = $table_sql;
break;
@@ -638,19 +646,6 @@ class tools
$statements[] = $trigger;
}
break;
-
- case 'firebird':
- if ($create_sequence)
- {
- $statements[] = "CREATE GENERATOR {$table_name}_gen;";
- $statements[] = "SET GENERATOR {$table_name}_gen TO 0;";
-
- $trigger = "CREATE TRIGGER t_$table_name FOR $table_name\n";
- $trigger .= "BEFORE INSERT\nAS\nBEGIN\n";
- $trigger .= "\tNEW.{$create_sequence} = GEN_ID({$table_name}_gen, 1);\nEND;";
- $statements[] = $trigger;
- }
- break;
}
// Write Keys
@@ -716,7 +711,7 @@ class tools
$sqlite = false;
// For SQLite we need to perform the schema changes in a much more different way
- if ($this->db->sql_layer == 'sqlite' && $this->return_statements)
+ if (($this->db->get_sql_layer() == 'sqlite' || $this->db->get_sql_layer() == 'sqlite3') && $this->return_statements)
{
$sqlite_data = array();
$sqlite = true;
@@ -892,7 +887,7 @@ class tools
}
}
- // Add unqiue indexes?
+ // Add unique indexes?
if (!empty($schema_changes['add_unique_index']))
{
foreach ($schema_changes['add_unique_index'] as $table => $index_array)
@@ -1127,13 +1122,8 @@ class tools
WHERE LOWER(table_name) = '" . strtolower($table) . "'";
break;
- case 'firebird':
- $sql = "SELECT RDB\$FIELD_NAME as FNAME
- FROM RDB\$RELATION_FIELDS
- WHERE RDB\$RELATION_NAME = '" . strtoupper($table) . "'";
- break;
-
case 'sqlite':
+ case 'sqlite3':
$sql = "SELECT sql
FROM sqlite_master
WHERE type = 'table'
@@ -1230,15 +1220,6 @@ class tools
switch ($this->sql_layer)
{
- case 'firebird':
- $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
- FROM RDB\$INDICES
- WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "'
- AND RDB\$UNIQUE_FLAG IS NULL
- AND RDB\$FOREIGN_KEY IS NULL";
- $col = 'index_name';
- break;
-
case 'postgres':
$sql = "SELECT ic.relname as index_name
FROM pg_class bc, pg_class ic, pg_index i
@@ -1267,6 +1248,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "PRAGMA index_list('" . $table_name . "');";
$col = 'name';
break;
@@ -1283,10 +1265,10 @@ class tools
// These DBMS prefix index name with the table name
switch ($this->sql_layer)
{
- case 'firebird':
case 'oracle':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
@@ -1303,7 +1285,7 @@ class tools
}
/**
- * Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes.
+ * Check if a specified index exists in table. Does not return PRIMARY KEY indexes.
*
* @param string $table_name Table to check the index at
* @param string $index_name The index name to check
@@ -1335,15 +1317,6 @@ class tools
switch ($this->sql_layer)
{
- case 'firebird':
- $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
- FROM RDB\$INDICES
- WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "'
- AND RDB\$UNIQUE_FLAG IS NOT NULL
- AND RDB\$FOREIGN_KEY IS NULL";
- $col = 'index_name';
- break;
-
case 'postgres':
$sql = "SELECT ic.relname as index_name, i.indisunique
FROM pg_class bc, pg_class ic, pg_index i
@@ -1371,6 +1344,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "PRAGMA index_list('" . $table_name . "');";
$col = 'name';
break;
@@ -1384,7 +1358,7 @@ class tools
continue;
}
- if ($this->sql_layer == 'sqlite' && !$row['unique'])
+ if (($this->sql_layer == 'sqlite' || $this->sql_layer == 'sqlite3') && !$row['unique'])
{
continue;
}
@@ -1409,9 +1383,9 @@ class tools
}
break;
- case 'firebird':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
@@ -1484,32 +1458,6 @@ class tools
switch ($this->sql_layer)
{
- case 'firebird':
- $sql .= " {$column_type} ";
- $return_array['column_type_sql_type'] = " {$column_type} ";
-
- if (!is_null($column_data[1]))
- {
- $sql .= 'DEFAULT ' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' ';
- $return_array['column_type_sql_default'] = ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' ';
- }
-
- $sql .= 'NOT NULL';
-
- // This is a UNICODE column and thus should be given it's fair share
- if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0]))
- {
- $sql .= ' COLLATE UNICODE';
- }
-
- $return_array['auto_increment'] = false;
- if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
- {
- $return_array['auto_increment'] = true;
- }
-
- break;
-
case 'mssql':
case 'mssqlnative':
$sql .= " {$column_type} ";
@@ -1539,8 +1487,16 @@ class tools
$return_array['textimage'] = $column_type === '[text]';
- $sql .= 'NOT NULL';
- $sql_default .= 'NOT NULL';
+ if (!is_null($column_data[1]) || (isset($column_data[2]) && $column_data[2] == 'auto_increment'))
+ {
+ $sql .= 'NOT NULL';
+ $sql_default .= 'NOT NULL';
+ }
+ else
+ {
+ $sql .= 'NULL';
+ $sql_default .= 'NULL';
+ }
$return_array['column_type_sql_default'] = $sql_default;
@@ -1555,7 +1511,15 @@ class tools
{
$sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' ";
}
- $sql .= 'NOT NULL';
+
+ if (!is_null($column_data[1]) || (isset($column_data[2]) && $column_data[2] == 'auto_increment'))
+ {
+ $sql .= 'NOT NULL';
+ }
+ else
+ {
+ $sql .= 'NULL';
+ }
if (isset($column_data[2]))
{
@@ -1580,7 +1544,7 @@ class tools
// Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields)
if (!preg_match('/number/i', $column_type))
{
- $sql .= ($column_data[1] === '') ? '' : 'NOT NULL';
+ $sql .= ($column_data[1] === '' || $column_data[1] === null) ? '' : 'NOT NULL';
}
$return_array['auto_increment'] = false;
@@ -1608,6 +1572,12 @@ class tools
$return_array['null'] = 'NOT NULL';
$sql .= 'NOT NULL ';
}
+ else
+ {
+ $default_val = "'" . $column_data[1] . "'";
+ $return_array['null'] = 'NULL';
+ $sql .= 'NULL ';
+ }
$return_array['default'] = $default_val;
@@ -1623,19 +1593,28 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$return_array['primary_key_set'] = false;
if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
{
$sql .= ' INTEGER PRIMARY KEY';
$return_array['primary_key_set'] = true;
+
+ if ($this->sql_layer === 'sqlite3')
+ {
+ $sql .= ' AUTOINCREMENT';
+ }
}
else
{
$sql .= ' ' . $column_type;
}
- $sql .= ' NOT NULL ';
- $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : '';
+ if (!is_null($column_data[1]))
+ {
+ $sql .= ' NOT NULL ';
+ $sql .= "DEFAULT '{$column_data[1]}'";
+ }
break;
}
@@ -1714,11 +1693,6 @@ class tools
switch ($this->sql_layer)
{
- case 'firebird':
- // Does not support AFTER statement, only POSITION (and there you need the column position)
- $statements[] = 'ALTER TABLE ' . $table_name . ' ADD "' . strtoupper($column_name) . '" ' . $column_data['column_type_sql'];
- break;
-
case 'mssql':
case 'mssqlnative':
// Does not support AFTER, only through temporary table
@@ -1764,67 +1738,63 @@ class tools
break;
case 'sqlite':
-
if ($inline && $this->return_statements)
{
return $column_name . ' ' . $column_data['column_type_sql'];
}
- if (version_compare(sqlite_libversion(), '3.0') == -1)
+ $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name);
+ if (empty($recreate_queries))
{
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = $this->db->sql_query($sql);
-
- if (!$result)
- {
- break;
- }
+ break;
+ }
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
+ $statements[] = 'begin';
- $statements[] = 'begin';
+ $sql_create_table = array_shift($recreate_queries);
- // Create a backup table and populate it, destroy the existing one
- $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
- $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
- $statements[] = 'DROP TABLE ' . $table_name;
+ // Create a backup table and populate it, destroy the existing one
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table);
+ $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
+ $statements[] = 'DROP TABLE ' . $table_name;
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ preg_match('#\((.*)\)#s', $sql_create_table, $matches);
- $new_table_cols = trim($matches[1]);
- $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
- $column_list = array();
+ $new_table_cols = trim($matches[1]);
+ $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
+ $column_list = array();
- foreach ($old_table_cols as $declaration)
+ foreach ($old_table_cols as $declaration)
+ {
+ $entities = preg_split('#\s+#', trim($declaration));
+ if ($entities[0] == 'PRIMARY')
{
- $entities = preg_split('#\s+#', trim($declaration));
- if ($entities[0] == 'PRIMARY')
- {
- continue;
- }
- $column_list[] = $entities[0];
+ continue;
}
+ $column_list[] = $entities[0];
+ }
- $columns = implode(',', $column_list);
+ $columns = implode(',', $column_list);
- $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols;
+ $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols;
- // create a new table and fill it up. destroy the temp one
- $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
- $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
- $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+ // create a new table and fill it up. destroy the temp one
+ $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
+ $statements = array_merge($statements, $recreate_queries);
- $statements[] = 'commit';
- }
- else
+ $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
+ $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+
+ $statements[] = 'commit';
+ break;
+
+ case 'sqlite3':
+ if ($inline && $this->return_statements)
{
- $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']';
+ return $column_name . ' ' . $column_data['column_type_sql'];
}
+
+ $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql'];
break;
}
@@ -1840,56 +1810,49 @@ class tools
switch ($this->sql_layer)
{
- case 'firebird':
- $statements[] = 'ALTER TABLE ' . $table_name . ' DROP "' . strtoupper($column_name) . '"';
- break;
-
case 'mssql':
case 'mssqlnative':
- $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version";
- $result = $this->db->sql_query($sql);
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
+ // We need the data here
+ $old_return_statements = $this->return_statements;
+ $this->return_statements = true;
- // Remove default constraints
- if ($row['mssql_version'][0] == '8') // SQL Server 2000
+ $indexes = $this->get_existing_indexes($table_name, $column_name);
+ $indexes = array_merge($indexes, $this->get_existing_indexes($table_name, $column_name, true));
+
+ // Drop any indexes
+ $recreate_indexes = array();
+ if (!empty($indexes))
{
- // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx
- // Deprecated in SQL Server 2005
- $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000)
- SET @drop_default_name =
- (SELECT so.name FROM sysobjects so
- JOIN sysconstraints sc ON so.id = sc.constid
- WHERE object_name(so.parent_obj) = '{$table_name}'
- AND so.xtype = 'D'
- AND sc.colid = (SELECT colid FROM syscolumns
- WHERE id = object_id('{$table_name}')
- AND name = '{$column_name}'))
- IF @drop_default_name <> ''
- BEGIN
- SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']'
- EXEC(@cmd)
- END";
+ foreach ($indexes as $index_name => $index_data)
+ {
+ $result = $this->sql_index_drop($table_name, $index_name);
+ $statements = array_merge($statements, $result);
+ if (sizeof($index_data) > 1)
+ {
+ // Remove this column from the index and recreate it
+ $recreate_indexes[$index_name] = array_diff($index_data, array($column_name));
+ }
+ }
}
- else
- {
- $sql = "SELECT dobj.name AS def_name
- FROM sys.columns col
- LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D')
- WHERE col.object_id = object_id('{$table_name}')
- AND col.name = '{$column_name}'
- AND dobj.name IS NOT NULL";
- $result = $this->db->sql_query($sql);
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
- if ($row)
+ // Drop default value constraint
+ $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name);
+ $statements = array_merge($statements, $result);
+
+ // Remove the column
+ $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']';
+
+ if (!empty($recreate_indexes))
+ {
+ // Recreate indexes after we removed the column
+ foreach ($recreate_indexes as $index_name => $index_data)
{
- $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']';
+ $result = $this->sql_create_index($table_name, $index_name, $index_data);
+ $statements = array_merge($statements, $result);
}
}
- $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']';
+ $this->return_statements = $old_return_statements;
break;
case 'mysql_40':
@@ -1906,67 +1869,61 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
if ($inline && $this->return_statements)
{
return $column_name;
}
- if (version_compare(sqlite_libversion(), '3.0') == -1)
+ $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name, $column_name);
+ if (empty($recreate_queries))
{
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = $this->db->sql_query($sql);
-
- if (!$result)
- {
- break;
- }
+ break;
+ }
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
+ $statements[] = 'begin';
- $statements[] = 'begin';
+ $sql_create_table = array_shift($recreate_queries);
- // Create a backup table and populate it, destroy the existing one
- $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
- $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
- $statements[] = 'DROP TABLE ' . $table_name;
+ // Create a backup table and populate it, destroy the existing one
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table);
+ $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
+ $statements[] = 'DROP TABLE ' . $table_name;
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ preg_match('#\((.*)\)#s', $sql_create_table, $matches);
- $new_table_cols = trim($matches[1]);
- $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
- $column_list = array();
+ $new_table_cols = trim($matches[1]);
+ $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
+ $column_list = array();
- foreach ($old_table_cols as $declaration)
+ foreach ($old_table_cols as $declaration)
+ {
+ $entities = preg_split('#\s+#', trim($declaration));
+ if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name)
{
- $entities = preg_split('#\s+#', trim($declaration));
- if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name)
- {
- continue;
- }
- $column_list[] = $entities[0];
+ continue;
}
+ $column_list[] = $entities[0];
+ }
- $columns = implode(',', $column_list);
-
- $new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols);
-
- // create a new table and fill it up. destroy the temp one
- $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
- $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
- $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+ $columns = implode(',', $column_list);
- $statements[] = 'commit';
- }
- else
+ $new_table_cols = trim(preg_replace('/' . $column_name . '\b[^,]+(?:,|$)/m', '', $new_table_cols));
+ if (substr($new_table_cols, -1) === ',')
{
- $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name;
+ // Remove the comma from the last entry again
+ $new_table_cols = substr($new_table_cols, 0, -1);
}
+
+ // create a new table and fill it up. destroy the temp one
+ $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
+ $statements = array_merge($statements, $recreate_queries);
+
+ $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
+ $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+
+ $statements[] = 'commit';
break;
}
@@ -1992,10 +1949,10 @@ class tools
$statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name;
break;
- case 'firebird':
case 'oracle':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name;
break;
}
@@ -2020,21 +1977,6 @@ class tools
switch ($this->sql_layer)
{
- case 'firebird':
- $sql = 'SELECT RDB$GENERATOR_NAME as gen
- FROM RDB$GENERATORS
- WHERE RDB$SYSTEM_FLAG = 0
- AND RDB$GENERATOR_NAME = \'' . strtoupper($table_name) . "_GEN'";
- $result = $this->db->sql_query($sql);
-
- // does a generator exist?
- if ($row = $this->db->sql_fetchrow($result))
- {
- $statements[] = "DROP GENERATOR {$row['gen']};";
- }
- $this->db->sql_freeresult($result);
- break;
-
case 'oracle':
$sql = 'SELECT A.REFERENCED_NAME
FROM USER_DEPENDENCIES A, USER_TRIGGERS B
@@ -2080,7 +2022,6 @@ class tools
switch ($this->sql_layer)
{
- case 'firebird':
case 'postgres':
case 'mysql_40':
case 'mysql_41':
@@ -2098,39 +2039,33 @@ class tools
break;
case 'oracle':
- $statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')';
+ $statements[] = 'ALTER TABLE ' . $table_name . ' add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')';
break;
case 'sqlite':
+ case 'sqlite3':
if ($inline && $this->return_statements)
{
return $column;
}
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = $this->db->sql_query($sql);
-
- if (!$result)
+ $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name);
+ if (empty($recreate_queries))
{
break;
}
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
-
$statements[] = 'begin';
+ $sql_create_table = array_shift($recreate_queries);
+
// Create a backup table and populate it, destroy the existing one
- $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table);
$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
$statements[] = 'DROP TABLE ' . $table_name;
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ preg_match('#\((.*)\)#s', $sql_create_table, $matches);
$new_table_cols = trim($matches[1]);
$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
@@ -2150,6 +2085,8 @@ class tools
// create a new table and fill it up. destroy the temp one
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));';
+ $statements = array_merge($statements, $recreate_queries);
+
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
@@ -2168,7 +2105,7 @@ class tools
$statements = array();
$table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config)
- if (strlen($table_name . $index_name) - strlen($table_prefix) > 24)
+ if (strlen($table_name . '_' . $index_name) - strlen($table_prefix) > 24)
{
$max_length = strlen($table_prefix) + 24;
trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR);
@@ -2176,10 +2113,10 @@ class tools
switch ($this->sql_layer)
{
- case 'firebird':
case 'postgres':
case 'oracle':
case 'sqlite':
+ case 'sqlite3':
$statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
break;
@@ -2190,7 +2127,7 @@ class tools
case 'mssql':
case 'mssqlnative':
- $statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
+ $statements[] = 'CREATE UNIQUE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])';
break;
}
@@ -2219,10 +2156,10 @@ class tools
switch ($this->sql_layer)
{
- case 'firebird':
case 'postgres':
case 'oracle':
case 'sqlite':
+ case 'sqlite3':
$statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
break;
@@ -2243,7 +2180,7 @@ class tools
case 'mssql':
case 'mssqlnative':
- $statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
+ $statements[] = 'CREATE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])';
break;
}
@@ -2277,15 +2214,6 @@ class tools
{
switch ($this->sql_layer)
{
- case 'firebird':
- $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
- FROM RDB\$INDICES
- WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "'
- AND RDB\$UNIQUE_FLAG IS NULL
- AND RDB\$FOREIGN_KEY IS NULL";
- $col = 'index_name';
- break;
-
case 'postgres':
$sql = "SELECT ic.relname as index_name
FROM pg_class bc, pg_class ic, pg_index i
@@ -2314,6 +2242,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "PRAGMA index_info('" . $table_name . "');";
$col = 'name';
break;
@@ -2329,10 +2258,10 @@ class tools
switch ($this->sql_layer)
{
- case 'firebird':
case 'oracle':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
@@ -2346,78 +2275,82 @@ class tools
}
/**
+ * Removes table_name from the index_name if it is at the beginning
+ *
+ * @param $table_name
+ * @param $index_name
+ * @return string
+ */
+ protected function strip_table_name_from_index_name($table_name, $index_name)
+ {
+ return (strpos(strtoupper($index_name), strtoupper($table_name)) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name;
+ }
+
+ /**
* Change column type (not name!)
*/
function sql_column_change($table_name, $column_name, $column_data, $inline = false)
{
+ $original_column_data = $column_data;
$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
$statements = array();
switch ($this->sql_layer)
{
- case 'firebird':
- // Change type...
- if (!empty($column_data['column_type_sql_default']))
- {
- $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql_type'];
- $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" SET DEFAULT ' . ' ' . $column_data['column_type_sql_default'];
- }
- else
+ case 'mssql':
+ case 'mssqlnative':
+ // We need the data here
+ $old_return_statements = $this->return_statements;
+ $this->return_statements = true;
+
+ $indexes = $this->get_existing_indexes($table_name, $column_name);
+ $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true);
+
+ // Drop any indexes
+ if (!empty($indexes) || !empty($unique_indexes))
{
- // TODO: try to change pkey without removing trigger, generator or constraints. ATM this query may fail.
- $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql_type'];
+ $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes));
+ foreach ($drop_indexes as $index_name)
+ {
+ $result = $this->sql_index_drop($table_name, $index_name);
+ $statements = array_merge($statements, $result);
+ }
}
- break;
- case 'mssql':
- case 'mssqlnative':
+ // Drop default value constraint
+ $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name);
+ $statements = array_merge($statements, $result);
+
+ // Change the column
$statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql'];
if (!empty($column_data['default']))
{
- $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version";
- $result = $this->db->sql_query($sql);
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
+ // Add new default value constraint
+ $statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $this->db->sql_escape($column_data['default']) . ' FOR [' . $column_name . ']';
+ }
- // Using TRANSACT-SQL for this statement because we do not want to have colliding data if statements are executed at a later stage
- if ($row['mssql_version'][0] == '8') // SQL Server 2000
+ if (!empty($indexes))
+ {
+ // Recreate indexes after we changed the column
+ foreach ($indexes as $index_name => $index_data)
{
- $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000)
- SET @drop_default_name =
- (SELECT so.name FROM sysobjects so
- JOIN sysconstraints sc ON so.id = sc.constid
- WHERE object_name(so.parent_obj) = '{$table_name}'
- AND so.xtype = 'D'
- AND sc.colid = (SELECT colid FROM syscolumns
- WHERE id = object_id('{$table_name}')
- AND name = '{$column_name}'))
- IF @drop_default_name <> ''
- BEGIN
- SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']'
- EXEC(@cmd)
- END
- SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]'
- EXEC(@cmd)";
+ $result = $this->sql_create_index($table_name, $index_name, $index_data);
+ $statements = array_merge($statements, $result);
}
- else
+ }
+
+ if (!empty($unique_indexes))
+ {
+ // Recreate unique indexes after we changed the column
+ foreach ($unique_indexes as $index_name => $index_data)
{
- $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000)
- SET @drop_default_name =
- (SELECT dobj.name FROM sys.columns col
- LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D')
- WHERE col.object_id = object_id('{$table_name}')
- AND col.name = '{$column_name}'
- AND dobj.name IS NOT NULL)
- IF @drop_default_name <> ''
- BEGIN
- SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']'
- EXEC(@cmd)
- END
- SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]'
- EXEC(@cmd)";
+ $result = $this->sql_create_unique_index($table_name, $index_name, $index_data);
+ $statements = array_merge($statements, $result);
}
}
+
+ $this->return_statements = $old_return_statements;
break;
case 'mysql_40':
@@ -2426,7 +2359,69 @@ class tools
break;
case 'oracle':
- $statements[] = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql'];
+ // We need the data here
+ $old_return_statements = $this->return_statements;
+ $this->return_statements = true;
+
+ // Get list of existing indexes
+ $indexes = $this->get_existing_indexes($table_name, $column_name);
+ $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true);
+
+ // Drop any indexes
+ if (!empty($indexes) || !empty($unique_indexes))
+ {
+ $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes));
+ foreach ($drop_indexes as $index_name)
+ {
+ $result = $this->sql_index_drop($table_name, $this->strip_table_name_from_index_name($table_name, $index_name));
+ $statements = array_merge($statements, $result);
+ }
+ }
+
+ $temp_column_name = 'temp_' . substr(md5($column_name), 0, 25);
+ // Add a temporary table with the new type
+ $result = $this->sql_column_add($table_name, $temp_column_name, $original_column_data);
+ $statements = array_merge($statements, $result);
+
+ // Copy the data to the new column
+ $statements[] = 'UPDATE ' . $table_name . ' SET ' . $temp_column_name . ' = ' . $column_name;
+
+ // Drop the original column
+ $result = $this->sql_column_remove($table_name, $column_name);
+ $statements = array_merge($statements, $result);
+
+ // Recreate the original column with the new type
+ $result = $this->sql_column_add($table_name, $column_name, $original_column_data);
+ $statements = array_merge($statements, $result);
+
+ if (!empty($indexes))
+ {
+ // Recreate indexes after we changed the column
+ foreach ($indexes as $index_name => $index_data)
+ {
+ $result = $this->sql_create_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data);
+ $statements = array_merge($statements, $result);
+ }
+ }
+
+ if (!empty($unique_indexes))
+ {
+ // Recreate unique indexes after we changed the column
+ foreach ($unique_indexes as $index_name => $index_data)
+ {
+ $result = $this->sql_create_unique_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data);
+ $statements = array_merge($statements, $result);
+ }
+ }
+
+ // Copy the data to the original column
+ $statements[] = 'UPDATE ' . $table_name . ' SET ' . $column_name . ' = ' . $temp_column_name;
+
+ // Drop the temporary column again
+ $result = $this->sql_column_remove($table_name, $temp_column_name);
+ $statements = array_merge($statements, $result);
+
+ $this->return_statements = $old_return_statements;
break;
case 'postgres':
@@ -2493,35 +2488,29 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
if ($inline && $this->return_statements)
{
return $column_name . ' ' . $column_data['column_type_sql'];
}
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = $this->db->sql_query($sql);
-
- if (!$result)
+ $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name);
+ if (empty($recreate_queries))
{
break;
}
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
-
$statements[] = 'begin';
+ $sql_create_table = array_shift($recreate_queries);
+
// Create a temp table and populate it, destroy the existing one
- $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table);
$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
$statements[] = 'DROP TABLE ' . $table_name;
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ preg_match('#\((.*)\)#s', $sql_create_table, $matches);
$new_table_cols = trim($matches[1]);
$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
@@ -2529,7 +2518,18 @@ class tools
foreach ($old_table_cols as $key => $declaration)
{
- $entities = preg_split('#\s+#', trim($declaration));
+ $declaration = trim($declaration);
+
+ // Check for the beginning of the constraint section and stop
+ if (preg_match('/[^\(]*\s*PRIMARY KEY\s+\(/', $declaration) ||
+ preg_match('/[^\(]*\s*UNIQUE\s+\(/', $declaration) ||
+ preg_match('/[^\(]*\s*FOREIGN KEY\s+\(/', $declaration) ||
+ preg_match('/[^\(]*\s*CHECK\s+\(/', $declaration))
+ {
+ break;
+ }
+
+ $entities = preg_split('#\s+#', $declaration);
$column_list[] = $entities[0];
if ($entities[0] == $column_name)
{
@@ -2539,8 +2539,10 @@ class tools
$columns = implode(',', $column_list);
- // create a new table and fill it up. destroy the temp one
+ // Create a new table and fill it up. destroy the temp one
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');';
+ $statements = array_merge($statements, $recreate_queries);
+
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
@@ -2551,4 +2553,275 @@ class tools
return $this->_sql_run_sql($statements);
}
+
+ /**
+ * Get queries to drop the default constraints of a column
+ *
+ * We need to drop the default constraints of a column,
+ * before being able to change their type or deleting them.
+ *
+ * @param string $table_name
+ * @param string $column_name
+ * @return array Array with SQL statements
+ */
+ protected function mssql_get_drop_default_constraints_queries($table_name, $column_name)
+ {
+ $statements = array();
+ if ($this->mssql_is_sql_server_2000())
+ {
+ // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx
+ // Deprecated in SQL Server 2005
+ $sql = "SELECT so.name AS def_name
+ FROM sysobjects so
+ JOIN sysconstraints sc ON so.id = sc.constid
+ WHERE object_name(so.parent_obj) = '{$table_name}'
+ AND so.xtype = 'D'
+ AND sc.colid = (SELECT colid FROM syscolumns
+ WHERE id = object_id('{$table_name}')
+ AND name = '{$column_name}')";
+ }
+ else
+ {
+ $sql = "SELECT dobj.name AS def_name
+ FROM sys.columns col
+ LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D')
+ WHERE col.object_id = object_id('{$table_name}')
+ AND col.name = '{$column_name}'
+ AND dobj.name IS NOT NULL";
+ }
+
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']';
+ }
+ $this->db->sql_freeresult($result);
+
+ return $statements;
+ }
+
+ /**
+ * Get a list with existing indexes for the column
+ *
+ * @param string $table_name
+ * @param string $column_name
+ * @param bool $unique Should we get unique indexes or normal ones
+ * @return array Array with Index name => columns
+ */
+ public function get_existing_indexes($table_name, $column_name, $unique = false)
+ {
+ switch ($this->sql_layer)
+ {
+ case 'mysql_40':
+ case 'mysql_41':
+ case 'postgres':
+ case 'sqlite':
+ case 'sqlite3':
+ // Not supported
+ throw new \Exception('DBMS is not supported');
+ break;
+ }
+
+ $sql = '';
+ $existing_indexes = array();
+
+ switch ($this->sql_layer)
+ {
+ case 'mssql':
+ case 'mssqlnative':
+ if ($this->mssql_is_sql_server_2000())
+ {
+ // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx
+ // Deprecated in SQL Server 2005
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name
+ FROM sysindexes ix
+ INNER JOIN sysindexkeys ixc
+ ON ixc.id = ix.id
+ AND ixc.indid = ix.indid
+ INNER JOIN syscolumns cols
+ ON cols.colid = ixc.colid
+ AND cols.id = ix.id
+ WHERE ix.id = object_id('{$table_name}')
+ AND cols.name = '{$column_name}'
+ AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique) ? '1' : '0';
+ }
+ else
+ {
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name
+ FROM sys.indexes ix
+ INNER JOIN sys.index_columns ixc
+ ON ixc.object_id = ix.object_id
+ AND ixc.index_id = ix.index_id
+ INNER JOIN sys.columns cols
+ ON cols.column_id = ixc.column_id
+ AND cols.object_id = ix.object_id
+ WHERE ix.object_id = object_id('{$table_name}')
+ AND cols.name = '{$column_name}'
+ AND ix.is_unique = " . ($unique) ? '1' : '0';
+ }
+ break;
+
+ case 'oracle':
+ $sql = "SELECT ix.index_name AS phpbb_index_name, ix.uniqueness AS is_unique
+ FROM all_ind_columns ixc, all_indexes ix
+ WHERE ix.index_name = ixc.index_name
+ AND ixc.table_name = '" . strtoupper($table_name) . "'
+ AND ixc.column_name = '" . strtoupper($column_name) . "'";
+ break;
+ }
+
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ if (!isset($row['is_unique']) || ($unique && $row['is_unique'] == 'UNIQUE') || (!$unique && $row['is_unique'] == 'NONUNIQUE'))
+ {
+ $existing_indexes[$row['phpbb_index_name']] = array();
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ if (empty($existing_indexes))
+ {
+ return array();
+ }
+
+ switch ($this->sql_layer)
+ {
+ case 'mssql':
+ case 'mssqlnative':
+ if ($this->mssql_is_sql_server_2000())
+ {
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name
+ FROM sysindexes ix
+ INNER JOIN sysindexkeys ixc
+ ON ixc.id = ix.id
+ AND ixc.indid = ix.indid
+ INNER JOIN syscolumns cols
+ ON cols.colid = ixc.colid
+ AND cols.id = ix.id
+ WHERE ix.id = object_id('{$table_name}')
+ AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes));
+ }
+ else
+ {
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name
+ FROM sys.indexes ix
+ INNER JOIN sys.index_columns ixc
+ ON ixc.object_id = ix.object_id
+ AND ixc.index_id = ix.index_id
+ INNER JOIN sys.columns cols
+ ON cols.column_id = ixc.column_id
+ AND cols.object_id = ix.object_id
+ WHERE ix.object_id = object_id('{$table_name}')
+ AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes));
+ }
+ break;
+
+ case 'oracle':
+ $sql = "SELECT index_name AS phpbb_index_name, column_name AS phpbb_column_name
+ FROM all_ind_columns
+ WHERE table_name = '" . strtoupper($table_name) . "'
+ AND " . $this->db->sql_in_set('index_name', array_keys($existing_indexes));
+ break;
+ }
+
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name'];
+ }
+ $this->db->sql_freeresult($result);
+
+ return $existing_indexes;
+ }
+
+ /**
+ * Is the used MS SQL Server a SQL Server 2000?
+ *
+ * @return bool
+ */
+ protected function mssql_is_sql_server_2000()
+ {
+ if ($this->is_sql_server_2000 === null)
+ {
+ $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version";
+ $result = $this->db->sql_query($sql);
+ $properties = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+ $this->is_sql_server_2000 = $properties['mssql_version'][0] == '8';
+ }
+
+ return $this->is_sql_server_2000;
+ }
+
+ /**
+ * Returns the Queries which are required to recreate a table including indexes
+ *
+ * @param string $table_name
+ * @param string $remove_column When we drop a column, we remove the column
+ * from all indexes. If the index has no other
+ * column, we drop it completly.
+ * @return array
+ */
+ protected function sqlite_get_recreate_table_queries($table_name, $remove_column = '')
+ {
+ $queries = array();
+
+ $sql = "SELECT sql
+ FROM sqlite_master
+ WHERE type = 'table'
+ AND name = '{$table_name}'";
+ $result = $this->db->sql_query($sql);
+ $sql_create_table = $this->db->sql_fetchfield('sql');
+ $this->db->sql_freeresult($result);
+
+ if (!$sql_create_table)
+ {
+ return array();
+ }
+ $queries[] = $sql_create_table;
+
+ $sql = "SELECT sql
+ FROM sqlite_master
+ WHERE type = 'index'
+ AND tbl_name = '{$table_name}'";
+ $result = $this->db->sql_query($sql);
+ while ($sql_create_index = $this->db->sql_fetchfield('sql'))
+ {
+ if ($remove_column)
+ {
+ $match = array();
+ preg_match('#(?:[\w ]+)\((.*)\)#', $sql_create_index, $match);
+ if (!isset($match[1]))
+ {
+ continue;
+ }
+
+ // Find and remove $remove_column from the index
+ $columns = explode(', ', $match[1]);
+ $found_column = array_search($remove_column, $columns);
+ if ($found_column !== false)
+ {
+ unset($columns[$found_column]);
+
+ // If the column list is not empty add the index to the list
+ if (!empty($columns))
+ {
+ $queries[] = str_replace($match[1], implode(', ', $columns), $sql_create_index);
+ }
+ }
+ else
+ {
+ $queries[] = $sql_create_index;
+ }
+ }
+ else
+ {
+ $queries[] = $sql_create_index;
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ return $queries;
+ }
}
diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php
new file mode 100644
index 0000000000..638c13e86d
--- /dev/null
+++ b/phpBB/phpbb/di/container_builder.php
@@ -0,0 +1,405 @@
+<?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\di;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
+use Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass;
+
+class container_builder
+{
+ /** @var string phpBB Root Path */
+ protected $phpbb_root_path;
+
+ /** @var string php file extension */
+ protected $php_ext;
+
+ /**
+ * The container under construction
+ *
+ * @var ContainerBuilder
+ */
+ protected $container;
+
+ /**
+ * @var \phpbb\db\driver\driver_interface
+ */
+ protected $dbal_connection = null;
+
+ /**
+ * @var array the installed extensions
+ */
+ protected $installed_exts = null;
+
+ /**
+ * Indicates whether the php config file should be injected into the container (default to true).
+ *
+ * @var bool
+ */
+ protected $inject_config = true;
+
+ /**
+ * Indicates whether extensions should be used (default to true).
+ *
+ * @var bool
+ */
+ protected $use_extensions = true;
+
+ /**
+ * Defines a custom path to find the configuration of the container (default to $this->phpbb_root_path . 'config')
+ *
+ * @var string
+ */
+ protected $config_path = null;
+
+ /**
+ * Indicates whether the phpBB compile pass should be used (default to true).
+ *
+ * @var bool
+ */
+ protected $use_custom_pass = true;
+
+ /**
+ * Indicates whether the kernel compile pass should be used (default to true).
+ *
+ * @var bool
+ */
+ protected $use_kernel_pass = true;
+
+ /**
+ * Indicates whether the container should be dumped to the filesystem (default to true).
+ *
+ * If DEBUG_CONTAINER is set this option is ignored and a new container is build.
+ *
+ * @var bool
+ */
+ protected $dump_container = true;
+
+ /**
+ * Indicates if the container should be compiled automatically (default to true).
+ *
+ * @var bool
+ */
+ protected $compile_container = true;
+
+ /**
+ * Custom parameters to inject into the container.
+ *
+ * Default to true:
+ * array(
+ * 'core.root_path', $this->phpbb_root_path,
+ * 'core.php_ext', $this->php_ext,
+ * );
+ *
+ * @var array
+ */
+ protected $custom_parameters = null;
+
+ /**
+ * @var \phpbb\config_php_file
+ */
+ protected $config_php_file;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\config_php_file $config_php_file
+ * @param string $phpbb_root_path Path to the phpbb includes directory.
+ * @param string $php_ext php file extension
+ */
+ function __construct(\phpbb\config_php_file $config_php_file, $phpbb_root_path, $php_ext)
+ {
+ $this->config_php_file = $config_php_file;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ }
+
+ /**
+ * Build and return a new Container respecting the current configuration
+ *
+ * @return \phpbb_cache_container|ContainerBuilder
+ */
+ public function get_container()
+ {
+ $container_filename = $this->get_container_filename();
+ if (!defined('DEBUG_CONTAINER') && $this->dump_container && file_exists($container_filename))
+ {
+ require($container_filename);
+ $this->container = new \phpbb_cache_container();
+ }
+ else
+ {
+ if ($this->config_path === null)
+ {
+ $this->config_path = $this->phpbb_root_path . 'config';
+ }
+ $container_extensions = array(new \phpbb\di\extension\core($this->config_path));
+
+ if ($this->use_extensions)
+ {
+ $installed_exts = $this->get_installed_extensions();
+ $container_extensions[] = new \phpbb\di\extension\ext($installed_exts);
+ }
+
+ if ($this->inject_config)
+ {
+ $container_extensions[] = new \phpbb\di\extension\config($this->config_php_file);
+ }
+
+ $this->container = $this->create_container($container_extensions);
+
+ if ($this->use_custom_pass)
+ {
+ // Symfony Kernel Listeners
+ $this->container->addCompilerPass(new \phpbb\di\pass\collection_pass());
+ $this->container->addCompilerPass(new RegisterListenersPass('dispatcher', 'event.listener_listener', 'event.listener'));
+
+ if ($this->use_kernel_pass)
+ {
+ $this->container->addCompilerPass(new RegisterListenersPass('dispatcher'));
+ }
+ }
+
+ $this->inject_custom_parameters();
+
+ if ($this->compile_container)
+ {
+ $this->container->compile();
+ }
+
+ if ($this->dump_container && !defined('DEBUG_CONTAINER'))
+ {
+ $this->dump_container($container_filename);
+ }
+ }
+
+ $this->container->set('config.php', $this->config_php_file);
+
+ if ($this->compile_container)
+ {
+ $this->inject_dbal();
+ }
+
+ return $this->container;
+ }
+
+ /**
+ * Set if the extensions should be used.
+ *
+ * @param bool $use_extensions
+ */
+ public function set_use_extensions($use_extensions)
+ {
+ $this->use_extensions = $use_extensions;
+ }
+
+ /**
+ * Set if the phpBB compile pass have to be used.
+ *
+ * @param bool $use_custom_pass
+ */
+ public function set_use_custom_pass($use_custom_pass)
+ {
+ $this->use_custom_pass = $use_custom_pass;
+ }
+
+ /**
+ * Set if the kernel compile pass have to be used.
+ *
+ * @param bool $use_kernel_pass
+ */
+ public function set_use_kernel_pass($use_kernel_pass)
+ {
+ $this->use_kernel_pass = $use_kernel_pass;
+ }
+
+ /**
+ * Set if the php config file should be injecting into the container.
+ *
+ * @param bool $inject_config
+ */
+ public function set_inject_config($inject_config)
+ {
+ $this->inject_config = $inject_config;
+ }
+
+ /**
+ * Set if a dump container should be used.
+ *
+ * If DEBUG_CONTAINER is set this option is ignored and a new container is build.
+ *
+ * @var bool $dump_container
+ */
+ public function set_dump_container($dump_container)
+ {
+ $this->dump_container = $dump_container;
+ }
+
+ /**
+ * Set if the container should be compiled automatically (default to true).
+ *
+ * @var bool $dump_container
+ */
+ public function set_compile_container($compile_container)
+ {
+ $this->compile_container = $compile_container;
+ }
+
+ /**
+ * Set a custom path to find the configuration of the container
+ *
+ * @param string $config_path
+ */
+ public function set_config_path($config_path)
+ {
+ $this->config_path = $config_path;
+ }
+
+ /**
+ * Set custom parameters to inject into the container.
+ *
+ * @param array $custom_parameters
+ */
+ public function set_custom_parameters($custom_parameters)
+ {
+ $this->custom_parameters = $custom_parameters;
+ }
+
+ /**
+ * Dump the container to the disk.
+ *
+ * @param string $container_filename The name of the file.
+ */
+ protected function dump_container($container_filename)
+ {
+ $dumper = new PhpDumper($this->container);
+ $cached_container_dump = $dumper->dump(array(
+ 'class' => 'phpbb_cache_container',
+ 'base_class' => 'Symfony\\Component\\DependencyInjection\\ContainerBuilder',
+ ));
+
+ file_put_contents($container_filename, $cached_container_dump);
+ }
+
+ /**
+ * Inject the connection into the container if one was opened.
+ */
+ protected function inject_dbal()
+ {
+ if ($this->dbal_connection !== null)
+ {
+ $this->container->get('dbal.conn')->set_driver($this->dbal_connection);
+ }
+ }
+
+ /**
+ * Get DB connection.
+ *
+ * @return \phpbb\db\driver\driver_interface
+ */
+ protected function get_dbal_connection()
+ {
+ if ($this->dbal_connection === null)
+ {
+ $dbal_driver_class = $this->config_php_file->convert_30_dbms_to_31($this->config_php_file->get('dbms'));
+ $this->dbal_connection = new $dbal_driver_class();
+ $this->dbal_connection->sql_connect(
+ $this->config_php_file->get('dbhost'),
+ $this->config_php_file->get('dbuser'),
+ $this->config_php_file->get('dbpasswd'),
+ $this->config_php_file->get('dbname'),
+ $this->config_php_file->get('dbport'),
+ defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK
+ );
+ }
+
+ return $this->dbal_connection;
+ }
+
+ /**
+ * Get enabled extensions.
+ *
+ * @return array enabled extensions
+ */
+ protected function get_installed_extensions()
+ {
+ $db = $this->get_dbal_connection();
+ $extension_table = $this->config_php_file->get('table_prefix') . 'ext';
+
+ $sql = 'SELECT *
+ FROM ' . $extension_table . '
+ WHERE ext_active = 1';
+
+ $result = $db->sql_query($sql);
+ $rows = $db->sql_fetchrowset($result);
+ $db->sql_freeresult($result);
+
+ $exts = array();
+ foreach ($rows as $row)
+ {
+ $exts[$row['ext_name']] = $this->phpbb_root_path . 'ext/' . $row['ext_name'] . '/';
+ }
+
+ return $exts;
+ }
+
+ /**
+ * Create the ContainerBuilder object
+ *
+ * @param array $extensions Array of Container extension objects
+ * @return ContainerBuilder object
+ */
+ protected function create_container(array $extensions)
+ {
+ $container = new ContainerBuilder();
+
+ foreach ($extensions as $extension)
+ {
+ $container->registerExtension($extension);
+ $container->loadFromExtension($extension->getAlias());
+ }
+
+ return $container;
+ }
+
+ /**
+ * Inject the customs parameters into the container
+ */
+ protected function inject_custom_parameters()
+ {
+ if ($this->custom_parameters === null)
+ {
+ $this->custom_parameters = array(
+ 'core.root_path' => $this->phpbb_root_path,
+ 'core.php_ext' => $this->php_ext,
+ );
+ }
+
+ foreach ($this->custom_parameters as $key => $value)
+ {
+ $this->container->setParameter($key, $value);
+ }
+ }
+
+ /**
+ * Get the filename under which the dumped container will be stored.
+ *
+ * @return string Path for dumped container
+ */
+ protected function get_container_filename()
+ {
+ $filename = str_replace(array('/', '.'), array('slash', 'dot'), $this->phpbb_root_path);
+ return $this->phpbb_root_path . 'cache/container_' . $filename . '.' . $this->php_ext;
+ }
+}
diff --git a/phpBB/phpbb/di/extension/config.php b/phpBB/phpbb/di/extension/config.php
index 2603e7b358..27ebc94bae 100644
--- a/phpBB/phpbb/di/extension/config.php
+++ b/phpBB/phpbb/di/extension/config.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,17 +15,18 @@ namespace phpbb\di\extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
-use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
-use Symfony\Component\Config\FileLocator;
/**
* Container config extension
*/
class config extends Extension
{
- public function __construct($config_file)
+ /** @var array */
+ protected $config_php;
+
+ public function __construct(\phpbb\config_php_file $config_php)
{
- $this->config_file = $config_file;
+ $this->config_php = $config_php;
}
/**
@@ -30,21 +35,19 @@ class config extends Extension
* @param array $config An array of configuration values
* @param ContainerBuilder $container A ContainerBuilder instance
*
- * @throws InvalidArgumentException When provided tag is not defined in this extension
+ * @throws \InvalidArgumentException When provided tag is not defined in this extension
*/
public function load(array $config, ContainerBuilder $container)
{
- require($this->config_file);
-
- $container->setParameter('core.adm_relative_path', (isset($phpbb_adm_relative_path) ? $phpbb_adm_relative_path : 'adm/'));
- $container->setParameter('core.table_prefix', $table_prefix);
- $container->setParameter('cache.driver.class', $this->convert_30_acm_type($acm_type));
- $container->setParameter('dbal.driver.class', phpbb_convert_30_dbms_to_31($dbms));
- $container->setParameter('dbal.dbhost', $dbhost);
- $container->setParameter('dbal.dbuser', $dbuser);
- $container->setParameter('dbal.dbpasswd', $dbpasswd);
- $container->setParameter('dbal.dbname', $dbname);
- $container->setParameter('dbal.dbport', $dbport);
+ $container->setParameter('core.adm_relative_path', ($this->config_php->get('phpbb_adm_relative_path') ? $this->config_php->get('phpbb_adm_relative_path') : 'adm/'));
+ $container->setParameter('core.table_prefix', $this->config_php->get('table_prefix'));
+ $container->setParameter('cache.driver.class', $this->convert_30_acm_type($this->config_php->get('acm_type')));
+ $container->setParameter('dbal.driver.class', $this->config_php->convert_30_dbms_to_31($this->config_php->get('dbms')));
+ $container->setParameter('dbal.dbhost', $this->config_php->get('dbhost'));
+ $container->setParameter('dbal.dbuser', $this->config_php->get('dbuser'));
+ $container->setParameter('dbal.dbpasswd', $this->config_php->get('dbpasswd'));
+ $container->setParameter('dbal.dbname', $this->config_php->get('dbname'));
+ $container->setParameter('dbal.dbport', $this->config_php->get('dbport'));
$container->setParameter('dbal.new_link', defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK);
}
@@ -64,7 +67,7 @@ class config extends Extension
* Convert 3.0 ACM type to 3.1 cache driver class name
*
* @param string $acm_type ACM type
- * @return cache driver class
+ * @return string cache driver class
*/
protected function convert_30_acm_type($acm_type)
{
diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php
index 455dfa7ecd..ca4fa5c082 100644
--- a/phpBB/phpbb/di/extension/core.php
+++ b/phpBB/phpbb/di/extension/core.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -41,7 +45,7 @@ class core extends Extension
* @param array $config An array of configuration values
* @param ContainerBuilder $container A ContainerBuilder instance
*
- * @throws InvalidArgumentException When provided tag is not defined in this extension
+ * @throws \InvalidArgumentException When provided tag is not defined in this extension
*/
public function load(array $config, ContainerBuilder $container)
{
diff --git a/phpBB/phpbb/di/extension/ext.php b/phpBB/phpbb/di/extension/ext.php
index 4f2f24cb1a..718c992d2e 100644
--- a/phpBB/phpbb/di/extension/ext.php
+++ b/phpBB/phpbb/di/extension/ext.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -35,7 +39,7 @@ class ext extends Extension
* @param array $config An array of configuration values
* @param ContainerBuilder $container A ContainerBuilder instance
*
- * @throws InvalidArgumentException When provided tag is not defined in this extension
+ * @throws \InvalidArgumentException When provided tag is not defined in this extension
*/
public function load(array $config, ContainerBuilder $container)
{
diff --git a/phpBB/phpbb/di/pass/collection_pass.php b/phpBB/phpbb/di/pass/collection_pass.php
index 507271de3e..a5c054674e 100644
--- a/phpBB/phpbb/di/pass/collection_pass.php
+++ b/phpBB/phpbb/di/pass/collection_pass.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/di/pass/kernel_pass.php b/phpBB/phpbb/di/pass/kernel_pass.php
deleted file mode 100644
index 9c2b193361..0000000000
--- a/phpBB/phpbb/di/pass/kernel_pass.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-/**
-*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
-*
-*/
-
-namespace phpbb\di\pass;
-
-use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
-
-class kernel_pass implements CompilerPassInterface
-{
- /**
- * Modify the container before it is passed to the rest of the code
- *
- * @param ContainerBuilder $container ContainerBuilder object
- * @return null
- */
- public function process(ContainerBuilder $container)
- {
- $definition = $container->getDefinition('dispatcher');
-
- foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events)
- {
- foreach ($events as $event)
- {
- $priority = isset($event['priority']) ? $event['priority'] : 0;
-
- if (!isset($event['event']))
- {
- throw new \InvalidArgumentException(sprintf('Service "%1$s" must define the "event" attribute on "kernel.event_listener" tags.', $id));
- }
-
- if (!isset($event['method']))
- {
- throw new \InvalidArgumentException(sprintf('Service "%1$s" must define the "method" attribute on "kernel.event_listener" tags.', $id));
- }
-
- $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority));
- }
- }
-
- foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes)
- {
- // We must assume that the class value has been correctly filled, even if the service is created by a factory
- $class = $container->getDefinition($id)->getClass();
-
- $refClass = new \ReflectionClass($class);
- $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
- if (!$refClass->implementsInterface($interface))
- {
- throw new \InvalidArgumentException(sprintf('Service "%1$s" must implement interface "%2$s".', $id, $interface));
- }
-
- $definition->addMethodCall('addSubscriberService', array($id, $class));
- }
- }
-}
diff --git a/phpBB/phpbb/di/service_collection.php b/phpBB/phpbb/di/service_collection.php
index 65df9ab1d1..82ca9bf679 100644
--- a/phpBB/phpbb/di/service_collection.php
+++ b/phpBB/phpbb/di/service_collection.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,12 +17,15 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Collection of services to be configured at container compile time.
-*
-* @package phpBB3
*/
class service_collection extends \ArrayObject
{
/**
+ * @var \Symfony\Component\DependencyInjection\ContainerInterface
+ */
+ protected $container;
+
+ /**
* Constructor
*
* @param ContainerInterface $container Container object
@@ -29,6 +36,37 @@ class service_collection extends \ArrayObject
}
/**
+ * {@inheritdoc}
+ */
+ public function getIterator()
+ {
+ return new service_collection_iterator($this);
+ }
+
+ // Because of a PHP issue we have to redefine offsetExists
+ // (even with a call to the parent):
+ // https://bugs.php.net/bug.php?id=66834
+ // https://bugs.php.net/bug.php?id=67067
+ // But it triggers a sniffer issue that we have to skip
+ // @codingStandardsIgnoreStart
+ /**
+ * {@inheritdoc}
+ */
+ public function offsetExists($index)
+ {
+ return parent::offsetExists($index);
+ }
+ // @codingStandardsIgnoreEnd
+
+ /**
+ * {@inheritdoc}
+ */
+ public function offsetGet($index)
+ {
+ return $this->container->get($index);
+ }
+
+ /**
* Add a service to the collection
*
* @param string $name The service name
@@ -36,8 +74,6 @@ class service_collection extends \ArrayObject
*/
public function add($name)
{
- $task = $this->container->get($name);
-
- $this->offsetSet($name, $task);
+ $this->offsetSet($name, null);
}
}
diff --git a/phpBB/phpbb/di/service_collection_iterator.php b/phpBB/phpbb/di/service_collection_iterator.php
new file mode 100644
index 0000000000..0d031ab52d
--- /dev/null
+++ b/phpBB/phpbb/di/service_collection_iterator.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\di;
+
+/**
+* Iterator which loads the services when they are requested
+*/
+class service_collection_iterator extends \ArrayIterator
+{
+ /**
+ * @var \phpbb\di\service_collection
+ */
+ protected $collection;
+
+ /**
+ * Construct an ArrayIterator for service_collection
+ *
+ * @param \phpbb\di\service_collection $collection The collection to iterate over
+ * @param int $flags Flags to control the behaviour of the ArrayObject object.
+ * @see ArrayObject::setFlags()
+ */
+ public function __construct(service_collection $collection, $flags = 0)
+ {
+ parent::__construct($collection, $flags);
+ $this->collection = $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function current()
+ {
+ return $this->collection->offsetGet($this->key());
+ }
+}
diff --git a/phpBB/phpbb/error_collector.php b/phpBB/phpbb/error_collector.php
index 297972c6b8..7141f83174 100644
--- a/phpBB/phpbb/error_collector.php
+++ b/phpBB/phpbb/error_collector.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/event/data.php b/phpBB/phpbb/event/data.php
index fbb16574ed..c7365aee35 100644
--- a/phpBB/phpbb/event/data.php
+++ b/phpBB/phpbb/event/data.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/event/dispatcher.php b/phpBB/phpbb/event/dispatcher.php
index 74b35eb78d..9a786022c2 100644
--- a/phpBB/phpbb/event/dispatcher.php
+++ b/phpBB/phpbb/event/dispatcher.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -25,8 +29,11 @@ use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher;
* extract($phpbb_dispatcher->trigger_event('core.index', compact($vars)));
*
*/
-class dispatcher extends ContainerAwareEventDispatcher
+class dispatcher extends ContainerAwareEventDispatcher implements dispatcher_interface
{
+ /**
+ * {@inheritdoc}
+ */
public function trigger_event($eventName, $data = array())
{
$event = new \phpbb\event\data($data);
diff --git a/phpBB/phpbb/event/dispatcher_interface.php b/phpBB/phpbb/event/dispatcher_interface.php
new file mode 100644
index 0000000000..50a3ef9101
--- /dev/null
+++ b/phpBB/phpbb/event/dispatcher_interface.php
@@ -0,0 +1,40 @@
+<?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\event;
+
+/**
+* Extension of the Symfony2 EventDispatcher
+*
+* It provides an additional `trigger_event` method, which
+* gives some syntactic sugar for dispatching events. Instead
+* of creating the event object, the method will do that for
+* you.
+*
+* Example:
+*
+* $vars = array('page_title');
+* extract($phpbb_dispatcher->trigger_event('core.index', compact($vars)));
+*
+*/
+interface dispatcher_interface extends \Symfony\Component\EventDispatcher\EventDispatcherInterface
+{
+ /**
+ * Construct and dispatch an event
+ *
+ * @param string $eventName The event name
+ * @param array $data An array containing the variables sending with the event
+ * @return mixed
+ */
+ public function trigger_event($eventName, $data = array());
+}
diff --git a/phpBB/phpbb/event/extension_subscriber_loader.php b/phpBB/phpbb/event/extension_subscriber_loader.php
deleted file mode 100644
index 6408f93e2a..0000000000
--- a/phpBB/phpbb/event/extension_subscriber_loader.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/**
-*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
-*
-*/
-
-namespace phpbb\event;
-
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-
-class extension_subscriber_loader
-{
- private $dispatcher;
- private $listener_collection;
-
- public function __construct(EventDispatcherInterface $dispatcher, \phpbb\di\service_collection $listener_collection)
- {
- $this->dispatcher = $dispatcher;
- $this->listener_collection = $listener_collection;
- }
-
- public function load()
- {
- if (!empty($this->listener_collection))
- {
- foreach ($this->listener_collection as $listener)
- {
- $this->dispatcher->addSubscriber($listener);
- }
- }
- }
-}
diff --git a/phpBB/phpbb/event/kernel_exception_subscriber.php b/phpBB/phpbb/event/kernel_exception_subscriber.php
index 8a4de1fbad..44e87507f9 100644
--- a/phpBB/phpbb/event/kernel_exception_subscriber.php
+++ b/phpBB/phpbb/event/kernel_exception_subscriber.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/event/kernel_request_subscriber.php b/phpBB/phpbb/event/kernel_request_subscriber.php
index 7d5418498b..ee9f29a59d 100644
--- a/phpBB/phpbb/event/kernel_request_subscriber.php
+++ b/phpBB/phpbb/event/kernel_request_subscriber.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -18,13 +22,13 @@ use Symfony\Component\Routing\RequestContext;
class kernel_request_subscriber implements EventSubscriberInterface
{
/**
- * Extension finder object
- * @var \phpbb\extension\finder
+ * Extension manager object
+ * @var \phpbb\extension\manager
*/
- protected $finder;
+ protected $manager;
/**
- * PHP extension
+ * PHP file extension
* @var string
*/
protected $php_ext;
@@ -38,15 +42,15 @@ class kernel_request_subscriber implements EventSubscriberInterface
/**
* Construct method
*
- * @param \phpbb\extension\finder $finder Extension finder object
+ * @param \phpbb\extension\manager $manager Extension manager object
* @param string $root_path Root path
- * @param string $php_ext PHP extension
+ * @param string $php_ext PHP file extension
*/
- public function __construct(\phpbb\extension\finder $finder, $root_path, $php_ext)
+ public function __construct(\phpbb\extension\manager $manager, $root_path, $php_ext)
{
- $this->finder = $finder;
$this->root_path = $root_path;
$this->php_ext = $php_ext;
+ $this->manager = $manager;
}
/**
@@ -55,6 +59,7 @@ class kernel_request_subscriber implements EventSubscriberInterface
* This is responsible for setting up the routing information
*
* @param GetResponseEvent $event
+ * @throws \BadMethodCallException
* @return null
*/
public function on_kernel_request(GetResponseEvent $event)
@@ -63,7 +68,7 @@ class kernel_request_subscriber implements EventSubscriberInterface
$context = new RequestContext();
$context->fromRequest($request);
- $matcher = phpbb_get_url_matcher($this->finder, $context, $this->root_path, $this->php_ext);
+ $matcher = phpbb_get_url_matcher($this->manager, $context, $this->root_path, $this->php_ext);
$router_listener = new RouterListener($matcher, $context);
$router_listener->onKernelRequest($event);
}
diff --git a/phpBB/phpbb/event/kernel_terminate_subscriber.php b/phpBB/phpbb/event/kernel_terminate_subscriber.php
index 32dba322d1..57e4840380 100644
--- a/phpBB/phpbb/event/kernel_terminate_subscriber.php
+++ b/phpBB/phpbb/event/kernel_terminate_subscriber.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/event/md_exporter.php b/phpBB/phpbb/event/md_exporter.php
new file mode 100644
index 0000000000..f7021875f3
--- /dev/null
+++ b/phpBB/phpbb/event/md_exporter.php
@@ -0,0 +1,440 @@
+<?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\event;
+
+/**
+* Crawls through a markdown file and grabs all events
+*/
+class md_exporter
+{
+ /** @var string Path where we look for files*/
+ protected $path;
+
+ /** @var string phpBB Root Path */
+ protected $root_path;
+
+ /** @var string */
+ protected $filter;
+
+ /** @var string */
+ protected $current_event;
+
+ /** @var array */
+ protected $events;
+
+ /**
+ * @param string $phpbb_root_path
+ * @param mixed $extension String 'vendor/ext' to filter, null for phpBB core
+ */
+ public function __construct($phpbb_root_path, $extension = null)
+ {
+ $this->root_path = $phpbb_root_path;
+ $this->path = $this->root_path;
+ if ($extension)
+ {
+ $this->path .= 'ext/' . $extension . '/';
+ }
+
+ $this->events = array();
+ $this->events_by_file = array();
+ $this->filter = $this->current_event = '';
+ }
+
+ /**
+ * Get the list of all events
+ *
+ * @return array Array with events: name => details
+ */
+ public function get_events()
+ {
+ return $this->events;
+ }
+
+ /**
+ * @param string $md_file Relative from phpBB root
+ * @return int Number of events found
+ * @throws \LogicException
+ */
+ public function crawl_phpbb_directory_adm($md_file)
+ {
+ $this->crawl_eventsmd($md_file, 'adm');
+
+ $file_list = $this->get_recursive_file_list($this->path . 'adm/style/');
+ foreach ($file_list as $file)
+ {
+ $file_name = 'adm/style/' . $file;
+ $this->validate_events_from_file($file_name, $this->crawl_file_for_events($file_name));
+ }
+
+ return sizeof($this->events);
+ }
+
+ /**
+ * @param string $md_file Relative from phpBB root
+ * @return int Number of events found
+ * @throws \LogicException
+ */
+ public function crawl_phpbb_directory_styles($md_file)
+ {
+ $this->crawl_eventsmd($md_file, 'styles');
+
+ $styles = array('prosilver', 'subsilver2');
+ foreach ($styles as $style)
+ {
+ $file_list = $this->get_recursive_file_list(
+ $this->path . 'styles/' . $style . '/template/'
+ );
+
+ foreach ($file_list as $file)
+ {
+ $file_name = 'styles/' . $style . '/template/' . $file;
+ $this->validate_events_from_file($file_name, $this->crawl_file_for_events($file_name));
+ }
+ }
+
+ return sizeof($this->events);
+ }
+
+ /**
+ * @param string $md_file Relative from phpBB root
+ * @param string $filter Should be 'styles' or 'adm'
+ * @return int Number of events found
+ * @throws \LogicException
+ */
+ public function crawl_eventsmd($md_file, $filter)
+ {
+ if (!file_exists($this->path . $md_file))
+ {
+ throw new \LogicException("The event docs file '{$md_file}' could not be found");
+ }
+
+ $file_content = file_get_contents($this->path . $md_file);
+ $this->filter = $filter;
+
+ $events = explode("\n\n", $file_content);
+ foreach ($events as $event)
+ {
+ // Last row of the file
+ if (strpos($event, "\n===\n") === false)
+ {
+ continue;
+ }
+
+ list($event_name, $details) = explode("\n===\n", $event, 2);
+ $this->validate_event_name($event_name);
+ $this->current_event = $event_name;
+
+ if (isset($this->events[$this->current_event]))
+ {
+ throw new \LogicException("The event '{$this->current_event}' is defined multiple times");
+ }
+
+ if (($this->filter == 'adm' && strpos($this->current_event, 'acp_') !== 0)
+ || ($this->filter == 'styles' && strpos($this->current_event, 'acp_') === 0))
+ {
+ continue;
+ }
+
+ list($file_details, $details) = explode("\n* Since: ", $details, 2);
+ list($since, $description) = explode("\n* Purpose: ", $details, 2);
+
+ $files = $this->validate_file_list($file_details);
+ $since = $this->validate_since($since);
+
+ $this->events[$event_name] = array(
+ 'event' => $this->current_event,
+ 'files' => $files,
+ 'since' => $since,
+ 'description' => $description,
+ );
+ }
+
+ return sizeof($this->events);
+ }
+
+ /**
+ * Format the php events as a wiki table
+ * @return string Number of events found
+ */
+ public function export_events_for_wiki()
+ {
+ if ($this->filter === 'adm')
+ {
+ $wiki_page = '= ACP Template Events =' . "\n";
+ $wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n";
+ $wiki_page .= '! Identifier !! Placement !! Added in Release !! Explanation' . "\n";
+ }
+ else
+ {
+ $wiki_page = '= Template Events =' . "\n";
+ $wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n";
+ $wiki_page .= '! Identifier !! Prosilver Placement (If applicable) !! Subsilver Placement (If applicable) !! Added in Release !! Explanation' . "\n";
+ }
+
+ foreach ($this->events as $event_name => $event)
+ {
+ $wiki_page .= "|- id=\"{$event_name}\"\n";
+ $wiki_page .= "| [[#{$event_name}|{$event_name}]] || ";
+
+ if ($this->filter === 'adm')
+ {
+ $wiki_page .= implode(', ', $event['files']['adm']);
+ }
+ else
+ {
+ $wiki_page .= implode(', ', $event['files']['prosilver']) . ' || ' . implode(', ', $event['files']['subsilver2']);
+ }
+
+ $wiki_page .= " || {$event['since']} || " . str_replace("\n", ' ', $event['description']) . "\n";
+ }
+ $wiki_page .= '|}' . "\n";
+
+ return $wiki_page;
+ }
+
+ /**
+ * Validates a template event name
+ *
+ * @param $event_name
+ * @return null
+ * @throws \LogicException
+ */
+ public function validate_event_name($event_name)
+ {
+ if (!preg_match('#^([a-z][a-z0-9]*(?:_[a-z][a-z0-9]*)+)$#', $event_name))
+ {
+ throw new \LogicException("Invalid event name '{$event_name}'");
+ }
+ }
+
+ /**
+ * Validate "Since" Information
+ *
+ * @param string $since
+ * @return string
+ * @throws \LogicException
+ */
+ public function validate_since($since)
+ {
+ if (!preg_match('#^\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?$#', $since))
+ {
+ throw new \LogicException("Invalid since information found for event '{$this->current_event}'");
+ }
+
+ return $since;
+ }
+
+ /**
+ * Validate the files list
+ *
+ * @param string $file_details
+ * @return array
+ * @throws \LogicException
+ */
+ public function validate_file_list($file_details)
+ {
+ $files_list = array(
+ 'prosilver' => array(),
+ 'subsilver2' => array(),
+ 'adm' => array(),
+ );
+
+ // Multi file list
+ if (strpos($file_details, "* Locations:\n + ") === 0)
+ {
+ $file_details = substr($file_details, strlen("* Locations:\n + "));
+ $files = explode("\n + ", $file_details);
+ foreach ($files as $file)
+ {
+ if (!file_exists($this->path . $file) || substr($file, -5) !== '.html')
+ {
+ throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 1);
+ }
+
+ if (($this->filter !== 'adm') && strpos($file, 'styles/prosilver/template/') === 0)
+ {
+ $files_list['prosilver'][] = substr($file, strlen('styles/prosilver/template/'));
+ }
+ else if (($this->filter !== 'adm') && strpos($file, 'styles/subsilver2/template/') === 0)
+ {
+ $files_list['subsilver2'][] = substr($file, strlen('styles/subsilver2/template/'));
+ }
+ else if (($this->filter === 'adm') && strpos($file, 'adm/style/') === 0)
+ {
+ $files_list['adm'][] = substr($file, strlen('adm/style/'));
+ }
+ else
+ {
+ throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 2);
+ }
+
+ $this->events_by_file[$file][] = $this->current_event;
+ }
+ }
+ else if ($this->filter == 'adm')
+ {
+ $file = substr($file_details, strlen('* Location: '));
+ if (!file_exists($this->path . $file) || substr($file, -5) !== '.html')
+ {
+ throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 1);
+ }
+
+ $files_list['adm'][] = substr($file, strlen('adm/style/'));
+
+ $this->events_by_file[$file][] = $this->current_event;
+ }
+ else
+ {
+ throw new \LogicException("Invalid file list found for event '{$this->current_event}'", 2);
+ }
+
+ return $files_list;
+ }
+
+ /**
+ * Get all template events in a template file
+ *
+ * @param string $file
+ * @return array
+ * @throws \LogicException
+ */
+ public function crawl_file_for_events($file)
+ {
+ if (!file_exists($this->path . $file))
+ {
+ throw new \LogicException("File '{$file}' does not exist", 1);
+ }
+
+ $event_list = array();
+ $file_content = file_get_contents($this->path . $file);
+
+ $events = explode('<!-- EVENT ', $file_content);
+ // Remove the code before the first event
+ array_shift($events);
+ foreach ($events as $event)
+ {
+ $event = explode(' -->', $event, 2);
+ $event_list[] = array_shift($event);
+ }
+
+ return $event_list;
+ }
+
+ /**
+ * Validates whether all events from $file are in the md file and vice-versa
+ *
+ * @param string $file
+ * @param array $events
+ * @return true
+ * @throws \LogicException
+ */
+ public function validate_events_from_file($file, array $events)
+ {
+ if (empty($this->events_by_file[$file]) && empty($events))
+ {
+ return true;
+ }
+ else if (empty($this->events_by_file[$file]))
+ {
+ $event_list = implode("', '", $events);
+ throw new \LogicException("File '{$file}' should not contain events, but contains: "
+ . "'{$event_list}'", 1);
+ }
+ else if (empty($events))
+ {
+ $event_list = implode("', '", $this->events_by_file[$file]);
+ throw new \LogicException("File '{$file}' contains no events, but should contain: "
+ . "'{$event_list}'", 1);
+ }
+
+ $missing_events_from_file = array();
+ foreach ($this->events_by_file[$file] as $event)
+ {
+ if (!in_array($event, $events))
+ {
+ $missing_events_from_file[] = $event;
+ }
+ }
+
+ if (!empty($missing_events_from_file))
+ {
+ $event_list = implode("', '", $missing_events_from_file);
+ throw new \LogicException("File '{$file}' does not contain events: '{$event_list}'", 2);
+ }
+
+ $missing_events_from_md = array();
+ foreach ($events as $event)
+ {
+ if (!in_array($event, $this->events_by_file[$file]))
+ {
+ $missing_events_from_md[] = $event;
+ }
+ }
+
+ if (!empty($missing_events_from_md))
+ {
+ $event_list = implode("', '", $missing_events_from_md);
+ throw new \LogicException("File '{$file}' contains additional events: '{$event_list}'", 3);
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of files in $dir
+ *
+ * Works recursive with any depth
+ *
+ * @param string $dir Directory to go through
+ * @return array List of files (including directories)
+ */
+ public function get_recursive_file_list($dir)
+ {
+ try
+ {
+ $iterator = new \RecursiveIteratorIterator(
+ new \phpbb\recursive_dot_prefix_filter_iterator(
+ new \RecursiveDirectoryIterator(
+ $dir,
+ \FilesystemIterator::SKIP_DOTS
+ )
+ ),
+ \RecursiveIteratorIterator::SELF_FIRST
+ );
+ }
+ catch (\Exception $e)
+ {
+ return array();
+ }
+
+ $files = array();
+ foreach ($iterator as $file_info)
+ {
+ /** @var \RecursiveDirectoryIterator $file_info */
+ if ($file_info->isDir())
+ {
+ continue;
+ }
+
+ $relative_path = $iterator->getInnerIterator()->getSubPathname();
+
+ if (substr($relative_path, -5) == '.html')
+ {
+ $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $relative_path);
+ }
+ }
+
+ return $files;
+ }
+}
diff --git a/phpBB/phpbb/event/php_exporter.php b/phpBB/phpbb/event/php_exporter.php
new file mode 100644
index 0000000000..35144eeeec
--- /dev/null
+++ b/phpBB/phpbb/event/php_exporter.php
@@ -0,0 +1,610 @@
+<?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\event;
+
+/**
+* Class php_exporter
+* Crawls through a list of files and grabs all php-events
+*/
+class php_exporter
+{
+ /** @var string Path where we look for files*/
+ protected $path;
+
+ /** @var string phpBB Root Path */
+ protected $root_path;
+
+ /** @var string */
+ protected $current_file;
+
+ /** @var string */
+ protected $current_event;
+
+ /** @var int */
+ protected $current_event_line;
+
+ /** @var array */
+ protected $events;
+
+ /** @var array */
+ protected $file_lines;
+
+ /**
+ * @param string $phpbb_root_path
+ * @param mixed $extension String 'vendor/ext' to filter, null for phpBB core
+ */
+ public function __construct($phpbb_root_path, $extension = null)
+ {
+ $this->root_path = $phpbb_root_path;
+ $this->path = $phpbb_root_path;
+ $this->events = $this->file_lines = array();
+ $this->current_file = $this->current_event = '';
+ $this->current_event_line = 0;
+
+ $this->path = $this->root_path;
+ if ($extension)
+ {
+ $this->path .= 'ext/' . $extension . '/';
+ }
+ }
+
+ /**
+ * Get the list of all events
+ *
+ * @return array Array with events: name => details
+ */
+ public function get_events()
+ {
+ return $this->events;
+ }
+
+ /**
+ * Set current event data
+ *
+ * @param string $name Name of the current event (used for error messages)
+ * @param int $line Line where the current event is placed in
+ * @return null
+ */
+ public function set_current_event($name, $line)
+ {
+ $this->current_event = $name;
+ $this->current_event_line = $line;
+ }
+
+ /**
+ * Set the content of this file
+ *
+ * @param array $content Array with the lines of the file
+ * @return null
+ */
+ public function set_content($content)
+ {
+ $this->file_lines = $content;
+ }
+
+ /**
+ * Crawl the phpBB/ directory for php events
+ * @return int The number of events found
+ */
+ public function crawl_phpbb_directory_php()
+ {
+ $files = $this->get_recursive_file_list();
+ $this->events = array();
+ foreach ($files as $file)
+ {
+ $this->crawl_php_file($file);
+ }
+ ksort($this->events);
+
+ return sizeof($this->events);
+ }
+
+ /**
+ * Returns a list of files in $dir
+ *
+ * @return array List of files (including the path)
+ */
+ public function get_recursive_file_list()
+ {
+ try
+ {
+ $iterator = new \RecursiveIteratorIterator(
+ new \phpbb\event\recursive_event_filter_iterator(
+ new \RecursiveDirectoryIterator(
+ $this->path,
+ \FilesystemIterator::SKIP_DOTS
+ ),
+ $this->path
+ ),
+ \RecursiveIteratorIterator::LEAVES_ONLY
+ );
+ }
+ catch (\Exception $e)
+ {
+ return array();
+ }
+
+ $files = array();
+ foreach ($iterator as $file_info)
+ {
+ /** @var \RecursiveDirectoryIterator $file_info */
+ $relative_path = $iterator->getInnerIterator()->getSubPathname();
+ $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $relative_path);
+ }
+
+ return $files;
+ }
+
+ /**
+ * Format the php events as a wiki table
+ * @return string
+ */
+ public function export_events_for_wiki()
+ {
+ $wiki_page = '= PHP Events (Hook Locations) =' . "\n";
+ $wiki_page .= '{| class="sortable zebra" cellspacing="0" cellpadding="5"' . "\n";
+ $wiki_page .= '! Identifier !! Placement !! Arguments !! Added in Release !! Explanation' . "\n";
+ foreach ($this->events as $event)
+ {
+ $wiki_page .= '|- id="' . $event['event'] . '"' . "\n";
+ $wiki_page .= '| [[#' . $event['event'] . '|' . $event['event'] . ']] || ' . $event['file'] . ' || ' . implode(', ', $event['arguments']) . ' || ' . $event['since'] . ' || ' . $event['description'] . "\n";
+ }
+ $wiki_page .= '|}' . "\n";
+
+ return $wiki_page;
+ }
+
+ /**
+ * @param string $file
+ * @return int Number of events found in this file
+ * @throws \LogicException
+ */
+ public function crawl_php_file($file)
+ {
+ $this->current_file = $file;
+ $this->file_lines = array();
+ $content = file_get_contents($this->path . $this->current_file);
+ $num_events_found = 0;
+
+ if (strpos($content, "dispatcher->trigger_event('") || strpos($content, "dispatcher->dispatch('"))
+ {
+ $this->set_content(explode("\n", $content));
+ for ($i = 0, $num_lines = sizeof($this->file_lines); $i < $num_lines; $i++)
+ {
+ $event_line = false;
+ $found_trigger_event = strpos($this->file_lines[$i], "dispatcher->trigger_event('");
+ $arguments = array();
+ if ($found_trigger_event !== false)
+ {
+ $event_line = $i;
+ $this->set_current_event($this->get_event_name($event_line, false), $event_line);
+
+ // Find variables of the event
+ $arguments = $this->get_vars_from_array();
+ $doc_vars = $this->get_vars_from_docblock();
+ $this->validate_vars_docblock_array($arguments, $doc_vars);
+ }
+ else
+ {
+ $found_dispatch = strpos($this->file_lines[$i], "dispatcher->dispatch('");
+ if ($found_dispatch !== false)
+ {
+ $event_line = $i;
+ $this->set_current_event($this->get_event_name($event_line, true), $event_line);
+ }
+ }
+
+ if ($event_line)
+ {
+ // Validate @event
+ $event_line_num = $this->find_event();
+ $this->validate_event($this->current_event, $this->file_lines[$event_line_num]);
+
+ // Validate @since
+ $since_line_num = $this->find_since();
+ $since = $this->validate_since($this->file_lines[$since_line_num]);
+
+ // Find event description line
+ $description_line_num = $this->find_description();
+ $description = substr(trim($this->file_lines[$description_line_num]), strlen('* '));
+
+ if (isset($this->events[$this->current_event]))
+ {
+ throw new \LogicException("The event '{$this->current_event}' from file "
+ . "'{$this->current_file}:{$event_line_num}' already exists in file "
+ . "'{$this->events[$this->current_event]['file']}'", 10);
+ }
+
+ sort($arguments);
+ $this->events[$this->current_event] = array(
+ 'event' => $this->current_event,
+ 'file' => $this->current_file,
+ 'arguments' => $arguments,
+ 'since' => $since,
+ 'description' => $description,
+ );
+ $num_events_found++;
+ }
+ }
+ }
+
+ return $num_events_found;
+ }
+
+ /**
+ * Find the name of the event inside the dispatch() line
+ *
+ * @param int $event_line
+ * @param bool $is_dispatch Do we look for dispatch() or trigger_event() ?
+ * @return string Name of the event
+ * @throws \LogicException
+ */
+ public function get_event_name($event_line, $is_dispatch)
+ {
+ $event_text_line = $this->file_lines[$event_line];
+ $event_text_line = ltrim($event_text_line, "\t ");
+
+ if ($is_dispatch)
+ {
+ $regex = '#\$([a-z](?:[a-z0-9_]|->)*)';
+ $regex .= '->dispatch\(';
+ $regex .= '\'' . $this->preg_match_event_name() . '\'';
+ $regex .= '\);#';
+ }
+ else
+ {
+ $regex = '#extract\(\$([a-z](?:[a-z0-9_]|->)*)';
+ $regex .= '->trigger_event\(';
+ $regex .= '\'' . $this->preg_match_event_name() . '\'';
+ $regex .= ', compact\(\$vars\)\)\);#';
+ }
+
+ $match = array();
+ preg_match($regex, $event_text_line, $match);
+ if (!isset($match[2]))
+ {
+ throw new \LogicException("Can not find event name in line '{$event_text_line}' "
+ . "in file '{$this->current_file}:{$event_line}'", 1);
+ }
+
+ return $match[2];
+ }
+
+ /**
+ * Returns a regex match for the event name
+ *
+ * @return string
+ */
+ protected function preg_match_event_name()
+ {
+ return '([a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+)';
+ }
+
+ /**
+ * Find the $vars array
+ *
+ * @return array List of variables
+ * @throws \LogicException
+ */
+ public function get_vars_from_array()
+ {
+ $line = ltrim($this->file_lines[$this->current_event_line - 1], "\t");
+ if ($line === ');')
+ {
+ $vars_array = $this->get_vars_from_multi_line_array();
+ }
+ else
+ {
+ $vars_array = $this->get_vars_from_single_line_array($line);
+ }
+
+ foreach ($vars_array as $var)
+ {
+ if (!preg_match('#^([a-zA-Z_][a-zA-Z0-9_]*)$#', $var))
+ {
+ throw new \LogicException("Found invalid var '{$var}' in array for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3);
+ }
+ }
+
+ sort($vars_array);
+ return $vars_array;
+ }
+
+ /**
+ * Find the variables in single line array
+ *
+ * @param string $line
+ * @param bool $throw_multiline Throw an exception when there are too
+ * many arguments in one line.
+ * @return array List of variables
+ * @throws \LogicException
+ */
+ public function get_vars_from_single_line_array($line, $throw_multiline = true)
+ {
+ $match = array();
+ preg_match('#^\$vars = array\(\'([a-zA-Z0-9_\' ,]+)\'\);$#', $line, $match);
+
+ if (isset($match[1]))
+ {
+ $vars_array = explode("', '", $match[1]);
+ if ($throw_multiline && sizeof($vars_array) > 6)
+ {
+ throw new \LogicException('Should use multiple lines for $vars definition '
+ . "for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+ return $vars_array;
+ }
+ else
+ {
+ throw new \LogicException("Can not find '\$vars = array();'-line for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
+ }
+ }
+
+ /**
+ * Find the variables in single line array
+ *
+ * @return array List of variables
+ * @throws \LogicException
+ */
+ public function get_vars_from_multi_line_array()
+ {
+ $current_vars_line = 2;
+ $var_lines = array();
+ while (ltrim($this->file_lines[$this->current_event_line - $current_vars_line], "\t") !== '$vars = array(')
+ {
+ $var_lines[] = substr(trim($this->file_lines[$this->current_event_line - $current_vars_line]), 0, -1);
+
+ $current_vars_line++;
+ if ($current_vars_line > $this->current_event_line)
+ {
+ // Reached the start of the file
+ throw new \LogicException("Can not find end of \$vars array for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+ }
+
+ return $this->get_vars_from_single_line_array('$vars = array(' . implode(", ", $var_lines) . ');', false);
+ }
+
+ /**
+ * Find the $vars array
+ *
+ * @return array List of variables
+ * @throws \LogicException
+ */
+ public function get_vars_from_docblock()
+ {
+ $doc_vars = array();
+ $current_doc_line = 1;
+ $found_comment_end = false;
+ while (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t") !== '/**')
+ {
+ if (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t ") === '*/')
+ {
+ $found_comment_end = true;
+ }
+
+ if ($found_comment_end)
+ {
+ $var_line = trim($this->file_lines[$this->current_event_line - $current_doc_line]);
+ $var_line = preg_replace('!\s+!', ' ', $var_line);
+ if (strpos($var_line, '* @var ') === 0)
+ {
+ $doc_line = explode(' ', $var_line, 5);
+ if (sizeof($doc_line) !== 5)
+ {
+ throw new \LogicException("Found invalid line '{$this->file_lines[$this->current_event_line - $current_doc_line]}' "
+ . "for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
+ }
+ $doc_vars[] = $doc_line[3];
+ }
+ }
+
+ $current_doc_line++;
+ if ($current_doc_line > $this->current_event_line)
+ {
+ // Reached the start of the file
+ throw new \LogicException("Can not find end of docblock for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+ }
+
+ if (empty($doc_vars))
+ {
+ // Reached the start of the file
+ throw new \LogicException("Can not find @var lines for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3);
+ }
+
+ foreach ($doc_vars as $var)
+ {
+ if (!preg_match('#^([a-zA-Z_][a-zA-Z0-9_]*)$#', $var))
+ {
+ throw new \LogicException("Found invalid @var '{$var}' in docblock for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 4);
+ }
+ }
+
+ sort($doc_vars);
+ return $doc_vars;
+ }
+
+ /**
+ * Find the "@since" Information line
+ *
+ * @return int Absolute line number
+ * @throws \LogicException
+ */
+ public function find_since()
+ {
+ return $this->find_tag('since', array('event', 'var'));
+ }
+
+ /**
+ * Find the "@event" Information line
+ *
+ * @return int Absolute line number
+ */
+ public function find_event()
+ {
+ return $this->find_tag('event', array());
+ }
+
+ /**
+ * Find a "@*" Information line
+ *
+ * @param string $find_tag Name of the tag we are trying to find
+ * @param array $disallowed_tags List of tags that must not appear between
+ * the tag and the actual event
+ * @return int Absolute line number
+ * @throws \LogicException
+ */
+ public function find_tag($find_tag, $disallowed_tags)
+ {
+ $find_tag_line = 0;
+ $found_comment_end = false;
+ while (strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t "), '* @' . $find_tag . ' ') !== 0)
+ {
+ if ($found_comment_end && ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '/**')
+ {
+ // Reached the start of this doc block
+ throw new \LogicException("Can not find '@{$find_tag}' information for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
+ }
+
+ foreach ($disallowed_tags as $disallowed_tag)
+ {
+ if ($found_comment_end && strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t "), '* @' . $disallowed_tag) === 0)
+ {
+ // Found @var after the @since
+ throw new \LogicException("Found '@{$disallowed_tag}' information after '@{$find_tag}' for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3);
+ }
+ }
+
+ if (ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t ") === '*/')
+ {
+ $found_comment_end = true;
+ }
+
+ $find_tag_line++;
+ if ($find_tag_line >= $this->current_event_line)
+ {
+ // Reached the start of the file
+ throw new \LogicException("Can not find '@{$find_tag}' information for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+ }
+
+ return $this->current_event_line - $find_tag_line;
+ }
+
+ /**
+ * Find a "@*" Information line
+ *
+ * @return int Absolute line number
+ * @throws \LogicException
+ */
+ public function find_description()
+ {
+ $find_desc_line = 0;
+ while (ltrim($this->file_lines[$this->current_event_line - $find_desc_line], "\t") !== '/**')
+ {
+ $find_desc_line++;
+ if ($find_desc_line > $this->current_event_line)
+ {
+ // Reached the start of the file
+ throw new \LogicException("Can not find a description for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
+ }
+ }
+
+ $find_desc_line = $this->current_event_line - $find_desc_line + 1;
+
+ $desc = trim($this->file_lines[$find_desc_line]);
+ if (strpos($desc, '* @') === 0 || $desc[0] !== '*' || substr($desc, 1) == '')
+ {
+ // First line of the doc block is a @-line, empty or only contains "*"
+ throw new \LogicException("Can not find a description for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+
+ return $find_desc_line;
+ }
+
+ /**
+ * Validate "@since" Information
+ *
+ * @param string $line
+ * @return string
+ * @throws \LogicException
+ */
+ public function validate_since($line)
+ {
+ $match = array();
+ preg_match('#^\* @since (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)$#', ltrim($line, "\t "), $match);
+ if (!isset($match[1]))
+ {
+ throw new \LogicException("Invalid '@since' information for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'");
+ }
+
+ return $match[1];
+ }
+
+ /**
+ * Validate "@event" Information
+ *
+ * @param string $event_name
+ * @param string $line
+ * @return string
+ * @throws \LogicException
+ */
+ public function validate_event($event_name, $line)
+ {
+ $event = substr(ltrim($line, "\t "), strlen('* @event '));
+
+ if ($event !== trim($event))
+ {
+ throw new \LogicException("Invalid '@event' information for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
+ }
+
+ if ($event !== $event_name)
+ {
+ throw new \LogicException("Event name does not match '@event' tag for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+
+ return $event;
+ }
+
+ /**
+ * Validates that two arrays contain the same strings
+ *
+ * @param array $vars_array Variables found in the array line
+ * @param array $vars_docblock Variables found in the doc block
+ * @return null
+ * @throws \LogicException
+ */
+ public function validate_vars_docblock_array($vars_array, $vars_docblock)
+ {
+ $vars_array = array_unique($vars_array);
+ $vars_docblock = array_unique($vars_docblock);
+ $sizeof_vars_array = sizeof($vars_array);
+
+ if ($sizeof_vars_array !== sizeof($vars_docblock) || $sizeof_vars_array !== sizeof(array_intersect($vars_array, $vars_docblock)))
+ {
+ throw new \LogicException("\$vars array does not match the list of '@var' tags for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'");
+ }
+ }
+}
diff --git a/phpBB/phpbb/event/recursive_event_filter_iterator.php b/phpBB/phpbb/event/recursive_event_filter_iterator.php
new file mode 100644
index 0000000000..64e2e56f6a
--- /dev/null
+++ b/phpBB/phpbb/event/recursive_event_filter_iterator.php
@@ -0,0 +1,71 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\event;
+
+/**
+* This filter ignores directories and files starting with a dot.
+* It also skips some directories that do not contain events anyway,
+* such as e.g. files/, store/ and vendor/
+*/
+class recursive_event_filter_iterator extends \RecursiveFilterIterator
+{
+ protected $root_path;
+
+ /**
+ * Construct
+ *
+ * @param \RecursiveIterator $iterator
+ * @param string $root_path
+ */
+ public function __construct(\RecursiveIterator $iterator, $root_path)
+ {
+ $this->root_path = str_replace(DIRECTORY_SEPARATOR, '/', $root_path);
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Return the inner iterator's children contained in a recursive_event_filter_iterator
+ *
+ * @return recursive_event_filter_iterator
+ */
+ public function getChildren()
+ {
+ return new self($this->getInnerIterator()->getChildren(), $this->root_path);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function accept()
+ {
+ $relative_path = str_replace(DIRECTORY_SEPARATOR, '/', $this->current());
+ $filename = $this->current()->getFilename();
+
+ return (substr($relative_path, -4) === '.php' || $this->current()->isDir())
+ && $filename[0] !== '.'
+ && strpos($relative_path, $this->root_path . 'cache/') !== 0
+ && strpos($relative_path, $this->root_path . 'develop/') !== 0
+ && strpos($relative_path, $this->root_path . 'docs/') !== 0
+ && strpos($relative_path, $this->root_path . 'ext/') !== 0
+ && strpos($relative_path, $this->root_path . 'files/') !== 0
+ && strpos($relative_path, $this->root_path . 'includes/utf/') !== 0
+ && strpos($relative_path, $this->root_path . 'language/') !== 0
+ && strpos($relative_path, $this->root_path . 'phpbb/db/migration/data/') !== 0
+ && strpos($relative_path, $this->root_path . 'phpbb/event/') !== 0
+ && strpos($relative_path, $this->root_path . 'store/') !== 0
+ && strpos($relative_path, $this->root_path . 'tests/') !== 0
+ && strpos($relative_path, $this->root_path . 'vendor/') !== 0
+ ;
+ }
+}
diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php
index 1f871750e0..5bb530bad4 100644
--- a/phpBB/phpbb/extension/base.php
+++ b/phpBB/phpbb/extension/base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package extension
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,15 +17,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* A base class for extensions without custom enable/disable/purge code.
-*
-* @package extension
*/
class base implements \phpbb\extension\extension_interface
{
/** @var ContainerInterface */
protected $container;
- /** @var \phpbb\extension\finder */
+ /** @var \phpbb\finder */
protected $finder;
/** @var \phpbb\db\migrator */
@@ -33,15 +35,19 @@ class base implements \phpbb\extension\extension_interface
/** @var string */
protected $extension_path;
+ /** @var string[] */
+ private $migrations = false;
+
/**
* Constructor
*
* @param ContainerInterface $container Container object
- * @param \phpbb\extension\finder $extension_finder
+ * @param \phpbb\finder $extension_finder
+ * @param \phpbb\db\migrator $migrator
* @param string $extension_name Name of this extension (from ext.manager)
* @param string $extension_path Relative path to this extension
*/
- public function __construct(ContainerInterface $container, \phpbb\extension\finder $extension_finder, \phpbb\db\migrator $migrator, $extension_name, $extension_path)
+ public function __construct(ContainerInterface $container, \phpbb\finder $extension_finder, \phpbb\db\migrator $migrator, $extension_name, $extension_path)
{
$this->container = $container;
$this->extension_finder = $extension_finder;
@@ -52,6 +58,14 @@ class base implements \phpbb\extension\extension_interface
}
/**
+ * {@inheritdoc}
+ */
+ public function is_enableable()
+ {
+ return true;
+ }
+
+ /**
* Single enable step that installs any included migrations
*
* @param mixed $old_state State returned by previous call of this method
@@ -111,17 +125,16 @@ class base implements \phpbb\extension\extension_interface
*/
protected function get_migration_file_list()
{
- static $migrations = false;
-
- if ($migrations !== false)
+ if ($this->migrations !== false)
{
- return $migrations;
+ return $this->migrations;
}
// Only have the finder search in this extension path directory
$migrations = $this->extension_finder
->extension_directory('/migrations')
->find_from_extension($this->extension_name, $this->extension_path);
+
$migrations = $this->extension_finder->get_classes_from_files($migrations);
return $migrations;
diff --git a/phpBB/phpbb/extension/exception.php b/phpBB/phpbb/extension/exception.php
index 82327c9d5e..3f7d251a4e 100644
--- a/phpBB/phpbb/extension/exception.php
+++ b/phpBB/phpbb/extension/exception.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package extension
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/extension/extension_interface.php b/phpBB/phpbb/extension/extension_interface.php
index bddff51b5a..6a6b6adb8f 100644
--- a/phpBB/phpbb/extension/extension_interface.php
+++ b/phpBB/phpbb/extension/extension_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package extension
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,12 +16,17 @@ namespace phpbb\extension;
/**
* The interface extension meta classes have to implement to run custom code
* on enable/disable/purge.
-*
-* @package extension
*/
interface extension_interface
{
/**
+ * Indicate whether or not the extension can be enabled.
+ *
+ * @return bool
+ */
+ public function is_enableable();
+
+ /**
* enable_step is executed on enabling an extension until it returns false.
*
* Calls to this function can be made in subsequent requests, when the
diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php
index 993bd1b925..76f0e3558e 100644
--- a/phpBB/phpbb/extension/manager.php
+++ b/phpBB/phpbb/extension/manager.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package extension
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,8 +17,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* The extension manager provides means to activate/deactivate extensions.
-*
-* @package extension
*/
class manager
{
@@ -24,6 +26,7 @@ class manager
protected $db;
protected $config;
protected $cache;
+ protected $user;
protected $php_ext;
protected $extensions;
protected $extension_table;
@@ -34,26 +37,28 @@ class manager
* Creates a manager and loads information from database
*
* @param ContainerInterface $container A container
- * @param \phpbb\db\driver\driver $db A database connection
- * @param \phpbb\config\config $config \phpbb\config\config
+ * @param \phpbb\db\driver\driver_interface $db A database connection
+ * @param \phpbb\config\config $config Config object
* @param \phpbb\filesystem $filesystem
+ * @param \phpbb\user $user User object
* @param string $extension_table The name of the table holding extensions
* @param string $phpbb_root_path Path to the phpbb includes directory.
- * @param string $php_ext php file extension
+ * @param string $php_ext php file extension, defaults to php
* @param \phpbb\cache\driver\driver_interface $cache A cache instance or null
* @param string $cache_name The name of the cache variable, defaults to _ext
*/
- public function __construct(ContainerInterface $container, \phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext')
+ public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem $filesystem, \phpbb\user $user, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext')
{
+ $this->cache = $cache;
+ $this->cache_name = $cache_name;
+ $this->config = $config;
$this->container = $container;
- $this->phpbb_root_path = $phpbb_root_path;
$this->db = $db;
- $this->config = $config;
- $this->cache = $cache;
+ $this->extension_table = $extension_table;
$this->filesystem = $filesystem;
+ $this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
- $this->extension_table = $extension_table;
- $this->cache_name = $cache_name;
+ $this->user = $user;
$this->extensions = ($this->cache) ? $this->cache->get($this->cache_name) : false;
@@ -72,11 +77,12 @@ class manager
{
$this->extensions = array();
- // Do not try to load any extensions when installing or updating
+ // Do not try to load any extensions if the extension table
+ // does not exist or when installing or updating.
// Note: database updater invokes this code, and in 3.0
// there is no extension table therefore the rest of this function
// fails
- if (defined('IN_INSTALL'))
+ if (defined('IN_INSTALL') || version_compare($this->config['version'], '3.1.0-dev', '<'))
{
return;
}
@@ -143,12 +149,12 @@ class manager
* Instantiates the metadata manager for the extension with the given name
*
* @param string $name The extension name
- * @param string $template The template manager
+ * @param \phpbb\template\template $template The template manager
* @return \phpbb\extension\metadata_manager Instance of the metadata manager
*/
public function create_extension_metadata_manager($name, \phpbb\template\template $template)
{
- return new \phpbb\extension\metadata_manager($name, $this->config, $this, $template, $this->phpbb_root_path);
+ return new \phpbb\extension\metadata_manager($name, $this->config, $this, $template, $this->user, $this->phpbb_root_path);
}
/**
@@ -172,6 +178,12 @@ class manager
$old_state = (isset($this->extensions[$name]['ext_state'])) ? unserialize($this->extensions[$name]['ext_state']) : false;
$extension = $this->get_extension($name);
+
+ if (!$extension->is_enableable())
+ {
+ return false;
+ }
+
$state = $extension->enable_step($old_state);
$active = ($state === false);
@@ -409,11 +421,16 @@ class manager
}
$iterator = new \RecursiveIteratorIterator(
- new \RecursiveDirectoryIterator($this->phpbb_root_path . 'ext/', \FilesystemIterator::NEW_CURRENT_AND_KEY | \FilesystemIterator::FOLLOW_SYMLINKS),
- \RecursiveIteratorIterator::SELF_FIRST);
+ new \phpbb\recursive_dot_prefix_filter_iterator(
+ new \RecursiveDirectoryIterator($this->phpbb_root_path . 'ext/', \FilesystemIterator::NEW_CURRENT_AND_KEY | \FilesystemIterator::FOLLOW_SYMLINKS)
+ ),
+ \RecursiveIteratorIterator::SELF_FIRST
+ );
+ $iterator->setMaxDepth(2);
+
foreach ($iterator as $file_info)
{
- if ($file_info->isFile() && $file_info->getFilename() == 'ext.' . $this->php_ext)
+ if ($file_info->isFile() && $file_info->getFilename() == 'composer.json')
{
$ext_name = $iterator->getInnerIterator()->getSubPath();
$composer_file = $iterator->getPath() . '/composer.json';
@@ -505,7 +522,7 @@ class manager
* @param string $name Extension name to check NOTE: Can be user input
* @return bool Depending on whether or not the extension is available
*/
- public function available($name)
+ public function is_available($name)
{
return file_exists($this->get_extension_path($name, true));
}
@@ -516,18 +533,66 @@ class manager
* @param string $name Extension name to check
* @return bool Depending on whether or not the extension is enabled
*/
- public function enabled($name)
+ public function is_enabled($name)
{
return isset($this->extensions[$name]) && $this->extensions[$name]['ext_active'];
}
/**
- * Instantiates a \phpbb\extension\finder.
+ * Check to see if a given extension is disabled
+ *
+ * @param string $name Extension name to check
+ * @return bool Depending on whether or not the extension is disabled
+ */
+ public function is_disabled($name)
+ {
+ return isset($this->extensions[$name]) && !$this->extensions[$name]['ext_active'];
+ }
+
+ /**
+ * Check to see if a given extension is configured
*
- * @return \phpbb\extension\finder An extension finder instance
+ * All enabled and disabled extensions are considered configured. A purged
+ * extension that is no longer in the database is not configured.
+ *
+ * @param string $name Extension name to check
+ * @return bool Depending on whether or not the extension is configured
*/
- public function get_finder()
+ public function is_configured($name)
{
- return new \phpbb\extension\finder($this, $this->filesystem, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder');
+ return isset($this->extensions[$name]);
+ }
+
+ /**
+ * Check to see if a given extension is purged
+ *
+ * An extension is purged if it is available, not enabled and not disabled.
+ *
+ * @param string $name Extension name to check
+ * @return bool Depending on whether or not the extension is purged
+ */
+ public function is_purged($name)
+ {
+ return $this->is_available($name) && !$this->is_configured($name);
+ }
+
+ /**
+ * Instantiates a \phpbb\finder.
+ *
+ * @param bool $use_all_available Should we load all extensions, or just enabled ones
+ * @return \phpbb\finder An extension finder instance
+ */
+ public function get_finder($use_all_available = false)
+ {
+ $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder');
+ if ($use_all_available)
+ {
+ $finder->set_extensions(array_keys($this->all_available()));
+ }
+ else
+ {
+ $finder->set_extensions(array_keys($this->all_enabled()));
+ }
+ return $finder;
}
}
diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php
index c90445ee09..edca8ee1af 100644
--- a/phpBB/phpbb/extension/metadata_manager.php
+++ b/phpBB/phpbb/extension/metadata_manager.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package extension
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\extension;
/**
* The extension metadata manager validates and gets meta-data for extensions
-*
-* @package extension
*/
class metadata_manager
{
@@ -35,6 +37,12 @@ class metadata_manager
protected $template;
/**
+ * phpBB User instance
+ * @var \phpbb\user
+ */
+ protected $user;
+
+ /**
* phpBB root path
* @var string
*/
@@ -63,15 +71,17 @@ class metadata_manager
*
* @param string $ext_name Name (including vendor) of the extension
* @param \phpbb\config\config $config phpBB Config instance
- * @param \phpbb\extension\manager $extension_manager An instance of the phpBBb extension manager
- * @param \phpbb\template\template $template phpBB Template instance
+ * @param \phpbb\extension\manager $extension_manager An instance of the phpBB extension manager
+ * @param \phpbb\template\template $template phpBB Template instance
+ * @param \phpbb\user $user User instance
* @param string $phpbb_root_path Path to the phpbb includes directory.
*/
- public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, $phpbb_root_path)
+ public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, \phpbb\user $user, $phpbb_root_path)
{
$this->config = $config;
$this->extension_manager = $extension_manager;
$this->template = $template;
+ $this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
$this->ext_name = $ext_name;
@@ -80,11 +90,11 @@ class metadata_manager
}
/**
- * Processes and gets the metadata requested
- *
- * @param string $element All for all metadata that it has and is valid, otherwise specify which section you want by its shorthand term.
- * @return array Contains all of the requested metadata, throws an exception on failure
- */
+ * Processes and gets the metadata requested
+ *
+ * @param string $element All for all metadata that it has and is valid, otherwise specify which section you want by its shorthand term.
+ * @return array Contains all of the requested metadata, throws an exception on failure
+ */
public function get_metadata($element = 'all')
{
$this->set_metadata_file();
@@ -126,10 +136,10 @@ class metadata_manager
}
/**
- * Sets the filepath of the metadata file
- *
- * @return boolean Set to true if it exists, throws an exception on failure
- */
+ * Sets the filepath of the metadata file
+ *
+ * @throws \phpbb\extension\exception
+ */
private function set_metadata_file()
{
$ext_filepath = $this->extension_manager->get_extension_path($this->ext_name);
@@ -139,31 +149,32 @@ class metadata_manager
if (!file_exists($this->metadata_file))
{
- throw new \phpbb\extension\exception('The required file does not exist: ' . $this->metadata_file);
+ throw new \phpbb\extension\exception($this->user->lang('FILE_NOT_FOUND', $this->metadata_file));
}
}
/**
- * Gets the contents of the composer.json file
- *
- * @return bool True if success, throws an exception on failure
- */
+ * Gets the contents of the composer.json file
+ *
+ * @return bool True if success, throws an exception on failure
+ * @throws \phpbb\extension\exception
+ */
private function fetch_metadata()
{
if (!file_exists($this->metadata_file))
{
- throw new \phpbb\extension\exception('The required file does not exist: ' . $this->metadata_file);
+ throw new \phpbb\extension\exception($this->user->lang('FILE_NOT_FOUND', $this->metadata_file));
}
else
{
if (!($file_contents = file_get_contents($this->metadata_file)))
{
- throw new \phpbb\extension\exception('file_get_contents failed on ' . $this->metadata_file);
+ throw new \phpbb\extension\exception($this->user->lang('FILE_CONTENT_ERR', $this->metadata_file));
}
if (($metadata = json_decode($file_contents, true)) === null)
{
- throw new \phpbb\extension\exception('json_decode failed on ' . $this->metadata_file);
+ throw new \phpbb\extension\exception($this->user->lang('FILE_JSON_DECODE_ERR', $this->metadata_file));
}
$this->metadata = $metadata;
@@ -173,10 +184,10 @@ class metadata_manager
}
/**
- * This array handles the cleaning of the array
- *
- * @return array Contains the cleaned metadata array
- */
+ * This array handles the cleaning of the array
+ *
+ * @return array Contains the cleaned metadata array
+ */
private function clean_metadata_array()
{
return $this->metadata;
@@ -189,6 +200,7 @@ class metadata_manager
* "display" for name, type, and authors
* "name", "type")
* @return Bool True if valid, throws an exception if invalid
+ * @throws \phpbb\extension\exception
*/
public function validate($name = 'display')
{
@@ -222,12 +234,12 @@ class metadata_manager
{
if (!isset($this->metadata[$name]))
{
- throw new \phpbb\extension\exception("Required meta field '$name' has not been set.");
+ throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', $name));
}
if (!preg_match($fields[$name], $this->metadata[$name]))
{
- throw new \phpbb\extension\exception("Meta field '$name' is invalid.");
+ throw new \phpbb\extension\exception($this->user->lang('META_FIELD_INVALID', $name));
}
}
break;
@@ -237,22 +249,23 @@ class metadata_manager
}
/**
- * Validates the contents of the authors field
- *
- * @return boolean True when passes validation, throws exception if invalid
- */
+ * Validates the contents of the authors field
+ *
+ * @return boolean True when passes validation, throws exception if invalid
+ * @throws \phpbb\extension\exception
+ */
public function validate_authors()
{
if (empty($this->metadata['authors']))
{
- throw new \phpbb\extension\exception("Required meta field 'authors' has not been set.");
+ throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'authors'));
}
foreach ($this->metadata['authors'] as $author)
{
if (!isset($author['name']))
{
- throw new \phpbb\extension\exception("Required meta field 'author name' has not been set.");
+ throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'author name'));
}
}
@@ -260,10 +273,10 @@ class metadata_manager
}
/**
- * This array handles the verification that this extension can be enabled on this board
- *
- * @return bool True if validation succeeded, False if failed
- */
+ * This array handles the verification that this extension can be enabled on this board
+ *
+ * @return bool True if validation succeeded, False if failed
+ */
public function validate_enable()
{
// Check for valid directory & phpBB, PHP versions
@@ -276,10 +289,10 @@ class metadata_manager
}
/**
- * Validates the most basic directory structure to ensure it follows <vendor>/<ext> convention.
- *
- * @return boolean True when passes validation
- */
+ * Validates the most basic directory structure to ensure it follows <vendor>/<ext> convention.
+ *
+ * @return boolean True when passes validation
+ */
public function validate_dir()
{
return (substr_count($this->ext_name, '/') === 1 && $this->ext_name == $this->get_metadata('name'));
@@ -287,13 +300,13 @@ class metadata_manager
/**
- * Validates the contents of the phpbb requirement field
- *
- * @return boolean True when passes validation
- */
+ * Validates the contents of the phpbb requirement field
+ *
+ * @return boolean True when passes validation
+ */
public function validate_require_phpbb()
{
- if (!isset($this->metadata['require']['phpbb/phpbb']))
+ if (!isset($this->metadata['extra']['soft-require']['phpbb/phpbb']))
{
return false;
}
@@ -302,10 +315,10 @@ class metadata_manager
}
/**
- * Validates the contents of the php requirement field
- *
- * @return boolean True when passes validation
- */
+ * Validates the contents of the php requirement field
+ *
+ * @return boolean True when passes validation
+ */
public function validate_require_php()
{
if (!isset($this->metadata['require']['php']))
@@ -317,31 +330,10 @@ class metadata_manager
}
/**
- * Version validation helper
+ * Outputs the metadata into the template
*
- * @param string $string The string for comparing to a version
- * @param string $current_version The version to compare to
- * @return bool True/False if meets version requirements
+ * @return null
*/
- private function _validate_version($string, $current_version)
- {
- // Allow them to specify their own comparison operator (ex: <3.1.2, >=3.1.0)
- $comparison_matches = false;
- preg_match('#[=<>]+#', $string, $comparison_matches);
-
- if (!empty($comparison_matches))
- {
- return version_compare($current_version, str_replace(array($comparison_matches[0], ' '), '', $string), $comparison_matches[0]);
- }
-
- return version_compare($current_version, $string, '>=');
- }
-
- /**
- * Outputs the metadata into the template
- *
- * @return null
- */
public function output_template_data()
{
$this->template->assign_vars(array(
@@ -356,7 +348,7 @@ class metadata_manager
'META_REQUIRE_PHP' => (isset($this->metadata['require']['php'])) ? htmlspecialchars($this->metadata['require']['php']) : '',
'META_REQUIRE_PHP_FAIL' => !$this->validate_require_php(),
- 'META_REQUIRE_PHPBB' => (isset($this->metadata['require']['phpbb/phpbb'])) ? htmlspecialchars($this->metadata['require']['phpbb/phpbb']) : '',
+ 'META_REQUIRE_PHPBB' => (isset($this->metadata['extra']['soft-require']['phpbb/phpbb'])) ? htmlspecialchars($this->metadata['extra']['soft-require']['phpbb/phpbb']) : '',
'META_REQUIRE_PHPBB_FAIL' => !$this->validate_require_phpbb(),
'META_DISPLAY_NAME' => (isset($this->metadata['extra']['display-name'])) ? htmlspecialchars($this->metadata['extra']['display-name']) : '',
diff --git a/phpBB/phpbb/extension/provider.php b/phpBB/phpbb/extension/provider.php
index bfdc2b66b9..1c42cf7b5e 100644
--- a/phpBB/phpbb/extension/provider.php
+++ b/phpBB/phpbb/extension/provider.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package extension
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -19,8 +23,6 @@ namespace phpbb\extension;
*
* Items could be anything, for example template paths or cron task names.
* Derived classes completely define what the items are.
-*
-* @package extension
*/
abstract class provider implements \IteratorAggregate
{
@@ -56,7 +58,7 @@ abstract class provider implements \IteratorAggregate
/**
* Retrieve an iterator over all items
*
- * @return ArrayIterator An iterator for the array of template paths
+ * @return \ArrayIterator An iterator for the array of template paths
*/
public function getIterator()
{
diff --git a/phpBB/phpbb/feed/attachments_base.php b/phpBB/phpbb/feed/attachments_base.php
new file mode 100644
index 0000000000..04812f1570
--- /dev/null
+++ b/phpBB/phpbb/feed/attachments_base.php
@@ -0,0 +1,85 @@
+<?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\feed;
+
+/**
+* Abstract class for feeds displaying attachments
+*/
+abstract class attachments_base extends \phpbb\feed\base
+{
+ /**
+ * Attachments that may be displayed
+ */
+ protected $attachments = array();
+
+ /**
+ * Retrieve the list of attachments that may be displayed
+ */
+ protected function fetch_attachments()
+ {
+ $sql_array = array(
+ 'SELECT' => 'a.*',
+ 'FROM' => array(
+ ATTACHMENTS_TABLE => 'a'
+ ),
+ 'WHERE' => 'a.in_message = 0 ',
+ 'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC',
+ );
+
+ if (isset($this->topic_id))
+ {
+ $sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id;
+ }
+ else if (isset($this->forum_id))
+ {
+ $sql_array['LEFT_JOIN'] = array(
+ array(
+ 'FROM' => array(TOPICS_TABLE => 't'),
+ 'ON' => 'a.topic_id = t.topic_id',
+ )
+ );
+ $sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id;
+ }
+
+ $sql = $this->db->sql_build_query('SELECT', $sql_array);
+ $result = $this->db->sql_query($sql);
+
+ // Set attachments in feed items
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $this->attachments[$row['post_msg_id']][] = $row;
+ }
+ $this->db->sql_freeresult($result);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function open()
+ {
+ parent::open();
+ $this->fetch_attachments();
+ }
+
+ /**
+ * Get attachments related to a given post
+ *
+ * @param $post_id int Post id
+ * @return mixed Attachments related to $post_id
+ */
+ public function get_attachments($post_id)
+ {
+ return $this->attachments[$post_id];
+ }
+}
diff --git a/phpBB/phpbb/feed/base.php b/phpBB/phpbb/feed/base.php
index e6c1e606fa..e31854160a 100644
--- a/phpBB/phpbb/feed/base.php
+++ b/phpBB/phpbb/feed/base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\feed;
/**
* Base class with some generic functions and settings.
-*
-* @package phpBB3
*/
abstract class base
{
@@ -25,7 +27,7 @@ abstract class base
/** @var \phpbb\config\config */
protected $config;
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\cache\driver\driver_interface */
@@ -68,17 +70,16 @@ abstract class base
/**
* Constructor
*
- * @param \phpbb\feed\helper $helper Feed helper
- * @param \phpbb\config\config $config Config object
- * @param \phpbb\db\driver\driver $db Database connection
- * @param \phpbb\cache\driver\driver_interface $cache Cache object
- * @param \phpbb\user $user User object
- * @param \phpbb\auth\auth $auth Auth object
- * @param \phpbb\content_visibility $content_visibility Auth object
- * @param string $phpEx php file extension
- * @return null
+ * @param \phpbb\feed\helper $helper Feed helper
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\db\driver\driver_interface $db Database connection
+ * @param \phpbb\cache\driver\driver_interface $cache Cache object
+ * @param \phpbb\user $user User object
+ * @param \phpbb\auth\auth $auth Auth object
+ * @param \phpbb\content_visibility $content_visibility Auth object
+ * @param string $phpEx php file extension
*/
- function __construct(\phpbb\feed\helper $helper, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, \phpbb\user $user, \phpbb\auth\auth $auth, \phpbb\content_visibility $content_visibility, $phpEx)
+ function __construct(\phpbb\feed\helper $helper, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, \phpbb\user $user, \phpbb\auth\auth $auth, \phpbb\content_visibility $content_visibility, $phpEx)
{
$this->config = $config;
$this->helper = $helper;
@@ -131,6 +132,9 @@ abstract class base
/**
* Set key
+ *
+ * @param string $key Key
+ * @param mixed $value Value
*/
function set($key, $value)
{
@@ -139,6 +143,9 @@ abstract class base
/**
* Get key
+ *
+ * @param string $key Key
+ * @return mixed
*/
function get($key)
{
diff --git a/phpBB/phpbb/feed/factory.php b/phpBB/phpbb/feed/factory.php
index d370160563..f364f06d03 100644
--- a/phpBB/phpbb/feed/factory.php
+++ b/phpBB/phpbb/feed/factory.php
@@ -1,41 +1,45 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\feed;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
/**
* Factory class to return correct object
-* @package phpBB3
*/
class factory
{
/**
* Service container object
- * @var object
+ * @var ContainerInterface
*/
protected $container;
/** @var \phpbb\config\config */
protected $config;
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/**
* Constructor
*
- * @param objec $container Container object
- * @param \phpbb\config\config $config Config object
- * @param \phpbb\db\driver\driver $db Database connection
- * @return null
+ * @param ContainerInterface $container Container object
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\db\driver\driver_interface $db Database connection
*/
- public function __construct($container, \phpbb\config\config $config, \phpbb\db\driver\driver $db)
+ public function __construct(ContainerInterface $container, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db)
{
$this->container = $container;
$this->config = $config;
diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php
index 85ecb60f7e..7a2087c1cd 100644
--- a/phpBB/phpbb/feed/forum.php
+++ b/phpBB/phpbb/feed/forum.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,8 +18,6 @@ namespace phpbb\feed;
*
* This will give you the last {$this->num_items} posts made
* within a specific forum.
-*
-* @package phpBB3
*/
class forum extends \phpbb\feed\post_base
{
@@ -80,6 +82,8 @@ class forum extends \phpbb\feed\post_base
unset($forum_ids_passworded);
}
+
+ parent::open();
}
function get_sql()
@@ -90,7 +94,7 @@ class forum extends \phpbb\feed\post_base
WHERE forum_id = ' . $this->forum_id . '
AND topic_moved_id = 0
AND ' . $this->content_visibility->get_visibility_sql('topic', $this->forum_id) . '
- ORDER BY topic_last_post_time DESC';
+ ORDER BY topic_last_post_time DESC, topic_last_post_id DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
$topic_ids = array();
@@ -119,7 +123,7 @@ class forum extends \phpbb\feed\post_base
AND ' . $this->content_visibility->get_visibility_sql('post', $this->forum_id, 'p.') . '
AND p.post_time >= ' . $min_post_time . '
AND p.poster_id = u.user_id',
- 'ORDER_BY' => 'p.post_time DESC',
+ 'ORDER_BY' => 'p.post_time DESC, p.post_id DESC',
);
return true;
@@ -130,6 +134,7 @@ class forum extends \phpbb\feed\post_base
parent::adjust_item($item_row, $row);
$item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
+ $item_row['forum_id'] = $this->forum_id;
}
function get_item()
diff --git a/phpBB/phpbb/feed/forums.php b/phpBB/phpbb/feed/forums.php
index ddbb0bf7b3..ee14a5bc76 100644
--- a/phpBB/phpbb/feed/forums.php
+++ b/phpBB/phpbb/feed/forums.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,8 +18,6 @@ namespace phpbb\feed;
*
* This will give you a list of all postable forums where feeds are enabled
* including forum description, topic stats and post stats
-*
-* @package phpBB3
*/
class forums extends \phpbb\feed\base
{
diff --git a/phpBB/phpbb/feed/helper.php b/phpBB/phpbb/feed/helper.php
index 12acf997ac..198134cdcf 100644
--- a/phpBB/phpbb/feed/helper.php
+++ b/phpBB/phpbb/feed/helper.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\feed;
/**
* Class with some helpful functions used in feeds
-* @package phpBB3
*/
class helper
{
@@ -33,7 +36,7 @@ class helper
* @param \phpbb\config\config $config Config object
* @param \phpbb\user $user User object
* @param string $phpbb_root_path Root path
- * @return null
+ * @param string $phpEx PHP file extension
*/
public function __construct(\phpbb\config\config $config, \phpbb\user $user, $phpbb_root_path, $phpEx)
{
diff --git a/phpBB/phpbb/feed/news.php b/phpBB/phpbb/feed/news.php
index 1b7c452a92..a02c199d85 100644
--- a/phpBB/phpbb/feed/news.php
+++ b/phpBB/phpbb/feed/news.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,8 +18,6 @@ namespace phpbb\feed;
*
* This will give you {$this->num_items} first posts
* of all topics in the selected news forums.
-*
-* @package phpBB3
*/
class news extends \phpbb\feed\topic_base
{
@@ -64,9 +66,8 @@ class news extends \phpbb\feed\topic_base
// We really have to get the post ids first!
$sql = 'SELECT topic_first_post_id, topic_time
FROM ' . TOPICS_TABLE . '
- WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
- AND topic_moved_id = 0
- AND topic_visibility = ' . ITEM_APPROVED . '
+ WHERE topic_moved_id = 0
+ AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $in_fid_ary) . '
ORDER BY topic_time DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
@@ -85,7 +86,7 @@ class news extends \phpbb\feed\topic_base
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, t.topic_visibility',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
@@ -98,7 +99,7 @@ class news extends \phpbb\feed\topic_base
),
'WHERE' => 'p.topic_id = t.topic_id
AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
- 'ORDER_BY' => 'p.post_time DESC',
+ 'ORDER_BY' => 'p.post_time DESC, p.post_id DESC',
);
return true;
diff --git a/phpBB/phpbb/feed/overall.php b/phpBB/phpbb/feed/overall.php
index d99200475e..ab452f5386 100644
--- a/phpBB/phpbb/feed/overall.php
+++ b/phpBB/phpbb/feed/overall.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,8 +18,6 @@ namespace phpbb\feed;
*
* This will give you the newest {$this->num_items} posts
* from the whole board.
-*
-* @package phpBB3
*/
class overall extends \phpbb\feed\post_base
{
@@ -32,7 +34,7 @@ class overall extends \phpbb\feed\post_base
FROM ' . TOPICS_TABLE . '
WHERE topic_moved_id = 0
AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $forum_ids) . '
- ORDER BY topic_last_post_time DESC';
+ ORDER BY topic_last_post_time DESC, topic_last_post_id DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
$topic_ids = array();
@@ -69,7 +71,7 @@ class overall extends \phpbb\feed\post_base
AND ' . $this->content_visibility->get_forums_visibility_sql('post', $forum_ids, 'p.') . '
AND p.post_time >= ' . $min_post_time . '
AND u.user_id = p.poster_id',
- 'ORDER_BY' => 'p.post_time DESC',
+ 'ORDER_BY' => 'p.post_time DESC, p.post_id DESC',
);
return true;
diff --git a/phpBB/phpbb/feed/post_base.php b/phpBB/phpbb/feed/post_base.php
index c797d6a8ca..011775b6af 100644
--- a/phpBB/phpbb/feed/post_base.php
+++ b/phpBB/phpbb/feed/post_base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,10 +15,8 @@ namespace phpbb\feed;
/**
* Abstract class for post based feeds
-*
-* @package phpBB3
*/
-abstract class post_base extends \phpbb\feed\base
+abstract class post_base extends \phpbb\feed\attachments_base
{
var $num_items = 'feed_limit_post';
var $attachments = array();
@@ -46,44 +48,8 @@ abstract class post_base extends \phpbb\feed\base
{
$item_row['statistics'] = $this->user->lang['POSTED'] . ' ' . $this->user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row)
. ' ' . $this->separator_stats . ' ' . $this->user->format_date($row[$this->get('published')])
- . (($this->is_moderator_approve_forum($row['forum_id']) && $row['post_visibility'] !== ITEM_APPROVED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : '');
- }
- }
-
- function fetch_attachments()
- {
- $sql_array = array(
- 'SELECT' => 'a.*',
- 'FROM' => array(
- ATTACHMENTS_TABLE => 'a'
- ),
- 'WHERE' => 'a.in_message = 0 ',
- 'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC',
- );
-
- if (isset($this->topic_id))
- {
- $sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id;
- }
- else if (isset($this->forum_id))
- {
- $sql_array['LEFT_JOIN'] = array(
- array(
- 'FROM' => array(TOPICS_TABLE => 't'),
- 'ON' => 'a.topic_id = t.topic_id',
- )
- );
- $sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id;
- }
-
- $sql = $this->db->sql_build_query('SELECT', $sql_array);
- $result = $this->db->sql_query($sql);
-
- // Set attachments in feed items
- while ($row = $this->db->sql_fetchrow($result))
- {
- $this->attachments[$row['post_msg_id']][] = $row;
+ . (($this->is_moderator_approve_forum($row['forum_id']) && (int) $row['post_visibility'] === ITEM_UNAPPROVED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : '')
+ . (($this->is_moderator_approve_forum($row['forum_id']) && (int) $row['post_visibility'] === ITEM_DELETED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_DELETED'] : '');
}
- $this->db->sql_freeresult($result);
}
}
diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php
index a7acfb502f..66c49e55cf 100644
--- a/phpBB/phpbb/feed/topic.php
+++ b/phpBB/phpbb/feed/topic.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,8 +17,6 @@ namespace phpbb\feed;
* Topic feed for a specific topic
*
* This will give you the last {$this->num_items} posts made within this topic.
-*
-* @package phpBB3
*/
class topic extends \phpbb\feed\post_base
{
@@ -83,6 +85,8 @@ class topic extends \phpbb\feed\post_base
unset($forum_ids_passworded);
}
+
+ parent::open();
}
function get_sql()
@@ -97,12 +101,19 @@ class topic extends \phpbb\feed\post_base
'WHERE' => 'p.topic_id = ' . $this->topic_id . '
AND ' . $this->content_visibility->get_visibility_sql('post', $this->forum_id, 'p.') . '
AND p.poster_id = u.user_id',
- 'ORDER_BY' => 'p.post_time DESC',
+ 'ORDER_BY' => 'p.post_time DESC, p.post_id DESC',
);
return true;
}
+ function adjust_item(&$item_row, &$row)
+ {
+ parent::adjust_item($item_row, $row);
+
+ $item_row['forum_id'] = $this->forum_id;
+ }
+
function get_item()
{
return ($row = parent::get_item()) ? array_merge($this->topic_data, $row) : $row;
diff --git a/phpBB/phpbb/feed/topic_base.php b/phpBB/phpbb/feed/topic_base.php
index 7e28e67b82..f9ff368cba 100644
--- a/phpBB/phpbb/feed/topic_base.php
+++ b/phpBB/phpbb/feed/topic_base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,10 +15,8 @@ namespace phpbb\feed;
/**
* Abstract class for topic based feeds
-*
-* @package phpBB3
*/
-abstract class topic_base extends \phpbb\feed\base
+abstract class topic_base extends \phpbb\feed\attachments_base
{
var $num_items = 'feed_limit_topic';
@@ -45,9 +47,24 @@ abstract class topic_base extends \phpbb\feed\base
{
$item_row['statistics'] = $this->user->lang['POSTED'] . ' ' . $this->user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row)
. ' ' . $this->separator_stats . ' ' . $this->user->format_date($row[$this->get('published')])
- . ' ' . $this->separator_stats . ' ' . $this->user->lang['REPLIES'] . ' ' . $this->content_visibility->get_count('topic_posts', $row, $row['forum_id']) - 1
- . ' ' . $this->separator_stats . ' ' . $this->user->lang['VIEWS'] . ' ' . $row['topic_views']
- . (($this->is_moderator_approve_forum($row['forum_id']) && $row['topic_posts_unapproved']) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POSTS_UNAPPROVED'] : '');
+ . ' ' . $this->separator_stats . ' ' . $this->user->lang['REPLIES'] . ' ' . ($this->content_visibility->get_count('topic_posts', $row, $row['forum_id']) - 1)
+ . ' ' . $this->separator_stats . ' ' . $this->user->lang['VIEWS'] . ' ' . $row['topic_views'];
+
+ if ($this->is_moderator_approve_forum($row['forum_id']))
+ {
+ if ((int) $row['topic_visibility'] === ITEM_DELETED)
+ {
+ $item_row['statistics'] .= ' ' . $this->separator_stats . ' ' . $this->user->lang['TOPIC_DELETED'];
+ }
+ else if ((int) $row['topic_visibility'] === ITEM_UNAPPROVED)
+ {
+ $item_row['statistics'] .= ' ' . $this->separator_stats . ' ' . $this->user->lang['TOPIC_UNAPPROVED'];
+ }
+ else if ($row['topic_posts_unapproved'])
+ {
+ $item_row['statistics'] .= ' ' . $this->separator_stats . ' ' . $this->user->lang['POSTS_UNAPPROVED'];
+ }
+ }
}
}
}
diff --git a/phpBB/phpbb/feed/topics.php b/phpBB/phpbb/feed/topics.php
index e8b9f6de6c..2b9cb3501a 100644
--- a/phpBB/phpbb/feed/topics.php
+++ b/phpBB/phpbb/feed/topics.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,8 +18,6 @@ namespace phpbb\feed;
*
* This will give you the last {$this->num_items} created topics
* including the first post.
-*
-* @package phpBB3
*/
class topics extends \phpbb\feed\topic_base
{
@@ -36,9 +38,8 @@ class topics extends \phpbb\feed\topic_base
// We really have to get the post ids first!
$sql = 'SELECT topic_first_post_id, topic_time
FROM ' . TOPICS_TABLE . '
- WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
- AND topic_moved_id = 0
- AND topic_visibility = ' . ITEM_APPROVED . '
+ WHERE topic_moved_id = 0
+ AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $in_fid_ary) . '
ORDER BY topic_time DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
@@ -57,7 +58,7 @@ class topics extends \phpbb\feed\topic_base
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, t.topic_visibility',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
@@ -70,7 +71,7 @@ class topics extends \phpbb\feed\topic_base
),
'WHERE' => 'p.topic_id = t.topic_id
AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
- 'ORDER_BY' => 'p.post_time DESC',
+ 'ORDER_BY' => 'p.post_time DESC, p.post_id DESC',
);
return true;
diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php
index 809a536c2a..6d5eddfc16 100644
--- a/phpBB/phpbb/feed/topics_active.php
+++ b/phpBB/phpbb/feed/topics_active.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -15,8 +19,6 @@ namespace phpbb\feed;
* This will give you the last {$this->num_items} topics
* with replies made withing the last {$this->sort_days} days
* including the last post.
-*
-* @package phpBB3
*/
class topics_active extends \phpbb\feed\topic_base
{
@@ -51,11 +53,10 @@ class topics_active extends \phpbb\feed\topic_base
// We really have to get the post ids first!
$sql = 'SELECT topic_last_post_id, topic_last_post_time
FROM ' . TOPICS_TABLE . '
- WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
- AND topic_moved_id = 0
- AND topic_visibility = ' . ITEM_APPROVED . '
+ WHERE topic_moved_id = 0
+ AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $in_fid_ary) . '
' . $last_post_time_sql . '
- ORDER BY topic_last_post_time DESC';
+ ORDER BY topic_last_post_time DESC, topic_last_post_id DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
$post_ids = array();
@@ -74,7 +75,7 @@ class topics_active extends \phpbb\feed\topic_base
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views,
t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, t.topic_visibility',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
@@ -87,7 +88,7 @@ class topics_active extends \phpbb\feed\topic_base
),
'WHERE' => 'p.topic_id = t.topic_id
AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
- 'ORDER_BY' => 'p.post_time DESC',
+ 'ORDER_BY' => 'p.post_time DESC, p.post_id DESC',
);
return true;
diff --git a/phpBB/phpbb/filesystem.php b/phpBB/phpbb/filesystem.php
index 7878be0a5e..77517082e5 100644
--- a/phpBB/phpbb/filesystem.php
+++ b/phpBB/phpbb/filesystem.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb;
/**
* A class with various functions that are related to paths, files and the filesystem
-* @package phpBB3
*/
class filesystem
{
@@ -32,7 +35,7 @@ class filesystem
continue;
}
- if ($part === '..' && !empty($filtered) && $filtered[sizeof($filtered) - 1] !== '..')
+ if ($part === '..' && !empty($filtered) && $filtered[sizeof($filtered) - 1] !== '.' && $filtered[sizeof($filtered) - 1] !== '..')
{
array_pop($filtered);
}
diff --git a/phpBB/phpbb/extension/finder.php b/phpBB/phpbb/finder.php
index 6cc6e1808a..28f28825ba 100644
--- a/phpBB/phpbb/extension/finder.php
+++ b/phpBB/phpbb/finder.php
@@ -1,22 +1,24 @@
<?php
/**
*
-* @package extension
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\extension;
+namespace phpbb;
/**
-* The extension finder provides a simple way to locate files in active extensions
-*
-* @package extension
+* The finder provides a simple way to locate files in the core and a set of extensions
*/
class finder
{
- protected $extension_manager;
+ protected $extensions;
protected $filesystem;
protected $phpbb_root_path;
protected $cache;
@@ -46,9 +48,6 @@ class finder
/**
* Creates a new finder instance with its dependencies
*
- * @param \phpbb\extension\manager $extension_manager An extension manager
- * instance that provides the finder with a list of active
- * extensions and their locations
* @param \phpbb\filesystem $filesystem Filesystem instance
* @param string $phpbb_root_path Path to the phpbb root directory
* @param \phpbb\cache\driver\driver_interface $cache A cache instance or null
@@ -56,9 +55,8 @@ class finder
* @param string $cache_name The name of the cache variable, defaults to
* _ext_finder
*/
- public function __construct(\phpbb\extension\manager $extension_manager, \phpbb\filesystem $filesystem, $phpbb_root_path = '', \phpbb\cache\driver\driver_interface $cache = null, $php_ext = 'php', $cache_name = '_ext_finder')
+ public function __construct(\phpbb\filesystem $filesystem, $phpbb_root_path = '', \phpbb\cache\driver\driver_interface $cache = null, $php_ext = 'php', $cache_name = '_ext_finder')
{
- $this->extension_manager = $extension_manager;
$this->filesystem = $filesystem;
$this->phpbb_root_path = $phpbb_root_path;
$this->cache = $cache;
@@ -74,15 +72,37 @@ class finder
'extension_prefix' => false,
'extension_directory' => false,
);
+ $this->extensions = array();
$this->cached_queries = ($this->cache) ? $this->cache->get($this->cache_name) : false;
}
/**
+ * Set the array of extensions
+ *
+ * @param array $extensions A list of extensions that should be searched aswell
+ * @param bool $replace_list Should the list be emptied before adding the extensions
+ * @return \phpbb\finder This object for chaining calls
+ */
+ public function set_extensions(array $extensions, $replace_list = true)
+ {
+ if ($replace_list)
+ {
+ $this->extensions = array();
+ }
+
+ foreach ($extensions as $ext_name)
+ {
+ $this->extensions[$ext_name] = $this->phpbb_root_path . 'ext/' . $ext_name . '/';
+ }
+ return $this;
+ }
+
+ /**
* Sets a core path to be searched in addition to extensions
*
* @param string $core_path The path relative to phpbb_root_path
- * @return \phpbb\extension\finder This object for chaining calls
+ * @return \phpbb\finder This object for chaining calls
*/
public function core_path($core_path)
{
@@ -98,7 +118,7 @@ class finder
* file extension is automatically added to suffixes.
*
* @param string $suffix A filename suffix
- * @return \phpbb\extension\finder This object for chaining calls
+ * @return \phpbb\finder This object for chaining calls
*/
public function suffix($suffix)
{
@@ -115,7 +135,7 @@ class finder
* file extension is automatically added to suffixes.
*
* @param string $extension_suffix A filename suffix
- * @return \phpbb\extension\finder This object for chaining calls
+ * @return \phpbb\finder This object for chaining calls
*/
public function extension_suffix($extension_suffix)
{
@@ -131,7 +151,7 @@ class finder
* file extension is automatically added to suffixes.
*
* @param string $core_suffix A filename suffix
- * @return \phpbb\extension\finder This object for chaining calls
+ * @return \phpbb\finder This object for chaining calls
*/
public function core_suffix($core_suffix)
{
@@ -143,7 +163,7 @@ class finder
* Sets the prefix all files found in extensions and core must match
*
* @param string $prefix A filename prefix
- * @return \phpbb\extension\finder This object for chaining calls
+ * @return \phpbb\finder This object for chaining calls
*/
public function prefix($prefix)
{
@@ -156,7 +176,7 @@ class finder
* Sets a prefix all files found in extensions must match
*
* @param string $extension_prefix A filename prefix
- * @return \phpbb\extension\finder This object for chaining calls
+ * @return \phpbb\finder This object for chaining calls
*/
public function extension_prefix($extension_prefix)
{
@@ -168,7 +188,7 @@ class finder
* Sets a prefix all files found in the core path must match
*
* @param string $core_prefix A filename prefix
- * @return \phpbb\extension\finder This object for chaining calls
+ * @return \phpbb\finder This object for chaining calls
*/
public function core_prefix($core_prefix)
{
@@ -183,7 +203,7 @@ class finder
* the current directory.
*
* @param string $directory
- * @return \phpbb\extension\finder This object for chaining calls
+ * @return \phpbb\finder This object for chaining calls
*/
public function directory($directory)
{
@@ -196,7 +216,7 @@ class finder
* Sets a directory all files found in extensions must be contained in
*
* @param string $extension_directory
- * @return \phpbb\extension\finder This object for chaining calls
+ * @return \phpbb\finder This object for chaining calls
*/
public function extension_directory($extension_directory)
{
@@ -208,7 +228,7 @@ class finder
* Sets a directory all files found in the core path must be contained in
*
* @param string $core_directory
- * @return \phpbb\extension\finder This object for chaining calls
+ * @return \phpbb\finder This object for chaining calls
*/
public function core_directory($core_directory)
{
@@ -244,16 +264,14 @@ class finder
* phpBB naming rules an incorrect class name will be returned.
*
* @param bool $cache Whether the result should be cached
- * @param bool $use_all_available Use all available instead of just all
- * enabled extensions
* @return array An array of found class names
*/
- public function get_classes($cache = true, $use_all_available = false)
+ public function get_classes($cache = true)
{
$this->query['extension_suffix'] .= '.' . $this->php_ext;
$this->query['core_suffix'] .= '.' . $this->php_ext;
- $files = $this->find($cache, false, $use_all_available);
+ $files = $this->find($cache, false);
return $this->get_classes_from_files($files);
}
@@ -288,27 +306,23 @@ class finder
* Finds all directories matching the configured options
*
* @param bool $cache Whether the result should be cached
- * @param bool $use_all_available Use all available instead of just all
- * enabled extensions
* @param bool $extension_keys Whether the result should have extension name as array key
* @return array An array of paths to found directories
*/
- public function get_directories($cache = true, $use_all_available = false, $extension_keys = false)
+ public function get_directories($cache = true, $extension_keys = false)
{
- return $this->find_with_root_path($cache, true, $use_all_available, $extension_keys);
+ return $this->find_with_root_path($cache, true, $extension_keys);
}
/**
* Finds all files matching the configured options.
*
* @param bool $cache Whether the result should be cached
- * @param bool $use_all_available Use all available instead of just all
- * enabled extensions
* @return array An array of paths to found files
*/
- public function get_files($cache = true, $use_all_available = false)
+ public function get_files($cache = true)
{
- return $this->find_with_root_path($cache, false, $use_all_available);
+ return $this->find_with_root_path($cache, false);
}
/**
@@ -316,16 +330,14 @@ class finder
*
* @param bool $cache Whether the result should be cached
* @param bool $is_dir Directories will be returned when true, only files
- * otherwise
- * @param bool $use_all_available Use all available instead of just all
- * enabled extensions
+ * otherwise
* @param bool $extension_keys If true, result will be associative array
* with extension name as key
* @return array An array of paths to found items
*/
- protected function find_with_root_path($cache = true, $is_dir = false, $use_all_available = false, $extension_keys = false)
+ protected function find_with_root_path($cache = true, $is_dir = false, $extension_keys = false)
{
- $items = $this->find($cache, $is_dir, $use_all_available);
+ $items = $this->find($cache, $is_dir);
$result = array();
foreach ($items as $item => $ext_name)
@@ -349,21 +361,11 @@ class finder
* @param bool $cache Whether the result should be cached
* @param bool $is_dir Directories will be returned when true, only files
* otherwise
- * @param bool $use_all_available Use all available instead of just all
- * enabled extensions
* @return array An array of paths to found items
*/
- public function find($cache = true, $is_dir = false, $use_all_available = false)
+ public function find($cache = true, $is_dir = false)
{
- if ($use_all_available)
- {
- $extensions = $this->extension_manager->all_available();
- }
- else
- {
- $extensions = $this->extension_manager->all_enabled();
- }
-
+ $extensions = $this->extensions;
if ($this->query['core_path'])
{
$extensions['/'] = $this->phpbb_root_path . $this->query['core_path'];
@@ -463,6 +465,10 @@ class finder
}
else if ($directory && $directory[0] === '/')
{
+ if (!$is_dir)
+ {
+ $path .= substr($directory, 1);
+ }
$directory_pattern = '^' . preg_quote(str_replace('/', DIRECTORY_SEPARATOR, $directory) . DIRECTORY_SEPARATOR, '#');
}
else
@@ -475,45 +481,56 @@ class finder
}
$directory_pattern = '#' . $directory_pattern . '#';
- $iterator = new \RecursiveIteratorIterator(
- new \phpbb\recursive_dot_prefix_filter_iterator(
- new \RecursiveDirectoryIterator(
- $path,
- \FilesystemIterator::SKIP_DOTS
- )
- ),
- \RecursiveIteratorIterator::SELF_FIRST
- );
-
- foreach ($iterator as $file_info)
+ if (is_dir($path))
{
- $filename = $file_info->getFilename();
-
- if ($file_info->isDir() == $is_dir)
+ $iterator = new \RecursiveIteratorIterator(
+ new \phpbb\recursive_dot_prefix_filter_iterator(
+ new \RecursiveDirectoryIterator(
+ $path,
+ \FilesystemIterator::SKIP_DOTS
+ )
+ ),
+ \RecursiveIteratorIterator::SELF_FIRST
+ );
+
+ foreach ($iterator as $file_info)
{
- if ($is_dir)
+ $filename = $file_info->getFilename();
+
+ if ($file_info->isDir() == $is_dir)
{
- $relative_path = $iterator->getInnerIterator()->getSubPath() . DIRECTORY_SEPARATOR . basename($filename) . DIRECTORY_SEPARATOR;
- if ($relative_path[0] !== DIRECTORY_SEPARATOR)
+ if ($is_dir)
{
- $relative_path = DIRECTORY_SEPARATOR . $relative_path;
+ $relative_path = $iterator->getInnerIterator()->getSubPath() . DIRECTORY_SEPARATOR . basename($filename) . DIRECTORY_SEPARATOR;
+ if ($relative_path[0] !== DIRECTORY_SEPARATOR)
+ {
+ $relative_path = DIRECTORY_SEPARATOR . $relative_path;
+ }
+ }
+ else
+ {
+ $relative_path = $iterator->getInnerIterator()->getSubPathname();
+ if ($directory && $directory[0] === '/')
+ {
+ $relative_path = str_replace('/', DIRECTORY_SEPARATOR, $directory) . DIRECTORY_SEPARATOR . $relative_path;
+ }
+ else
+ {
+ $relative_path = DIRECTORY_SEPARATOR . $relative_path;
+ }
}
- }
- else
- {
- $relative_path = DIRECTORY_SEPARATOR . $iterator->getInnerIterator()->getSubPathname();
- }
- if ((!$suffix || substr($relative_path, -strlen($suffix)) === $suffix) &&
- (!$prefix || substr($filename, 0, strlen($prefix)) === $prefix) &&
- (!$directory || preg_match($directory_pattern, $relative_path)))
- {
- $files[] = array(
- 'named_path' => str_replace(DIRECTORY_SEPARATOR, '/', $location . $name . substr($relative_path, 1)),
- 'ext_name' => $ext_name,
- 'path' => str_replace(array(DIRECTORY_SEPARATOR, $this->phpbb_root_path), array('/', ''), $file_info->getPath()) . '/',
- 'filename' => $filename,
- );
+ if ((!$suffix || substr($relative_path, -strlen($suffix)) === $suffix) &&
+ (!$prefix || substr($filename, 0, strlen($prefix)) === $prefix) &&
+ (!$directory || preg_match($directory_pattern, $relative_path)))
+ {
+ $files[] = array(
+ 'named_path' => str_replace(DIRECTORY_SEPARATOR, '/', $location . $name . substr($relative_path, 1)),
+ 'ext_name' => $ext_name,
+ 'path' => str_replace(array(DIRECTORY_SEPARATOR, $this->phpbb_root_path), array('/', ''), $file_info->getPath()) . '/',
+ 'filename' => $filename,
+ );
+ }
}
}
}
diff --git a/phpBB/phpbb/groupposition/exception.php b/phpBB/phpbb/groupposition/exception.php
index f43502235d..956c7238f2 100644
--- a/phpBB/phpbb/groupposition/exception.php
+++ b/phpBB/phpbb/groupposition/exception.php
@@ -1,17 +1,18 @@
<?php
/**
*
-* @package groupposition
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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\groupposition;
-/**
-* @package groupposition
-*/
class exception extends \Exception
{
}
diff --git a/phpBB/phpbb/groupposition/groupposition_interface.php b/phpBB/phpbb/groupposition/groupposition_interface.php
index 9785172a00..3bd3fcce90 100644
--- a/phpBB/phpbb/groupposition/groupposition_interface.php
+++ b/phpBB/phpbb/groupposition/groupposition_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,8 +17,6 @@ namespace phpbb\groupposition;
* Interface to manage group positions in various places of phpbb
*
* The interface provides simple methods to add, delete and move a group
-*
-* @package phpBB3
*/
interface groupposition_interface
{
diff --git a/phpBB/phpbb/groupposition/legend.php b/phpBB/phpbb/groupposition/legend.php
index 47ba06c006..efea3389d4 100644
--- a/phpBB/phpbb/groupposition/legend.php
+++ b/phpBB/phpbb/groupposition/legend.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,8 +18,6 @@ namespace phpbb\groupposition;
*
* group_legend is an ascending list 1, 2, ..., n for groups which are displayed. 1 is the first group, n the last.
* If the value is 0 (self::GROUP_DISABLED) the group is not displayed.
-*
-* @package phpBB3
*/
class legend implements \phpbb\groupposition\groupposition_interface
{
@@ -26,7 +28,7 @@ class legend implements \phpbb\groupposition\groupposition_interface
/**
* Database object
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -39,10 +41,10 @@ class legend implements \phpbb\groupposition\groupposition_interface
/**
* Constructor
*
- * @param \phpbb\db\driver\driver $db Database object
+ * @param \phpbb\db\driver\driver_interface $db Database object
* @param \phpbb\user $user User object
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\user $user)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user)
{
$this->db = $db;
$this->user = $user;
@@ -51,7 +53,9 @@ class legend implements \phpbb\groupposition\groupposition_interface
/**
* Returns the group_legend for a given group, if the group exists.
*
- * {@inheritDoc}
+ * @param int $group_id group_id of the group to be selected
+ * @return int position of the group
+ * @throws \phpbb\groupposition\exception
*/
public function get_group_value($group_id)
{
@@ -74,7 +78,7 @@ class legend implements \phpbb\groupposition\groupposition_interface
/**
* Get number of groups, displayed on the legend
*
- * {@inheritDoc}
+ * @return int value of the last item displayed
*/
public function get_group_count()
{
@@ -89,8 +93,6 @@ class legend implements \phpbb\groupposition\groupposition_interface
}
/**
- * Adds a group by group_id
- *
* {@inheritDoc}
*/
public function add_group($group_id)
@@ -116,7 +118,9 @@ class legend implements \phpbb\groupposition\groupposition_interface
/**
* Deletes a group by setting the field to self::GROUP_DISABLED and closing the gap in the list.
*
- * {@inheritDoc}
+ * @param int $group_id group_id of the group to be deleted
+ * @param bool $skip_group Skip setting the value for this group, to save the query, when you need to update it anyway.
+ * @return bool True if the group was deleted successfully
*/
public function delete_group($group_id, $skip_group = false)
{
@@ -148,8 +152,6 @@ class legend implements \phpbb\groupposition\groupposition_interface
}
/**
- * Moves a group up by group_id
- *
* {@inheritDoc}
*/
public function move_up($group_id)
@@ -158,8 +160,6 @@ class legend implements \phpbb\groupposition\groupposition_interface
}
/**
- * Moves a group down by group_id
- *
* {@inheritDoc}
*/
public function move_down($group_id)
@@ -168,8 +168,6 @@ class legend implements \phpbb\groupposition\groupposition_interface
}
/**
- * Moves a group up/down
- *
* {@inheritDoc}
*/
public function move($group_id, $delta)
diff --git a/phpBB/phpbb/groupposition/teampage.php b/phpBB/phpbb/groupposition/teampage.php
index d934571ebc..2985c51525 100644
--- a/phpBB/phpbb/groupposition/teampage.php
+++ b/phpBB/phpbb/groupposition/teampage.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,8 +17,6 @@ namespace phpbb\groupposition;
* Teampage group position class
*
* Teampage position is an ascending list 1, 2, ..., n for items which are displayed. 1 is the first item, n the last.
-*
-* @package phpBB3
*/
class teampage implements \phpbb\groupposition\groupposition_interface
{
@@ -30,7 +32,7 @@ class teampage implements \phpbb\groupposition\groupposition_interface
/**
* Database object
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -49,11 +51,11 @@ class teampage implements \phpbb\groupposition\groupposition_interface
/**
* Constructor
*
- * @param \phpbb\db\driver\driver $db Database object
+ * @param \phpbb\db\driver\driver_interface $db Database object
* @param \phpbb\user $user User object
* @param \phpbb\cache\driver\driver_interface $cache Cache object
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\user $user, \phpbb\cache\driver\driver_interface $cache)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\cache\driver\driver_interface $cache)
{
$this->db = $db;
$this->user = $user;
@@ -63,7 +65,9 @@ class teampage implements \phpbb\groupposition\groupposition_interface
/**
* Returns the teampage position for a given group, if the group exists.
*
- * {@inheritDoc}
+ * @param int $group_id group_id of the group to be selected
+ * @return int position of the group
+ * @throws \phpbb\groupposition\exception
*/
public function get_group_value($group_id)
{
@@ -91,6 +95,7 @@ class teampage implements \phpbb\groupposition\groupposition_interface
*
* @param int $group_id group_id of the group to be selected
* @return array Data row of the group
+ * @throws \phpbb\groupposition\exception
*/
public function get_group_values($group_id)
{
@@ -118,6 +123,7 @@ class teampage implements \phpbb\groupposition\groupposition_interface
*
* @param int $teampage_id Teampage_id of the selected item
* @return int Teampage position of the item
+ * @throws \phpbb\groupposition\exception
*/
public function get_teampage_value($teampage_id)
{
@@ -142,6 +148,7 @@ class teampage implements \phpbb\groupposition\groupposition_interface
*
* @param int $teampage_id Teampage_id of the selected item
* @return array Teampage row of the item
+ * @throws \phpbb\groupposition\exception
*/
public function get_teampage_values($teampage_id)
{
@@ -163,8 +170,6 @@ class teampage implements \phpbb\groupposition\groupposition_interface
/**
- * Get number of items displayed
- *
* {@inheritDoc}
*/
public function get_group_count()
@@ -180,8 +185,6 @@ class teampage implements \phpbb\groupposition\groupposition_interface
}
/**
- * Adds a group by group_id
- *
* {@inheritDoc}
*/
public function add_group($group_id)
@@ -286,7 +289,9 @@ class teampage implements \phpbb\groupposition\groupposition_interface
/**
* Deletes a group from the list and closes the gap in the position list.
*
- * {@inheritDoc}
+ * @param int $group_id group_id of the group to be deleted
+ * @param bool $skip_group Skip setting the value for this group, to save the query, when you need to update it anyway.
+ * @return bool True if the group was deleted successfully
*/
public function delete_group($group_id, $skip_group = false)
{
@@ -345,8 +350,6 @@ class teampage implements \phpbb\groupposition\groupposition_interface
}
/**
- * Moves a group up by group_id
- *
* {@inheritDoc}
*/
public function move_up($group_id)
@@ -357,7 +360,7 @@ class teampage implements \phpbb\groupposition\groupposition_interface
/**
* Moves an item up by teampage_id
*
- * @param int $group_id group_id of the group to be moved
+ * @param int $teampage_id teampage_id of the item to be move
* @return bool True if the group was moved successfully
*/
public function move_up_teampage($teampage_id)
@@ -366,8 +369,6 @@ class teampage implements \phpbb\groupposition\groupposition_interface
}
/**
- * Moves a group down by group_id
- *
* {@inheritDoc}
*/
public function move_down($group_id)
@@ -376,9 +377,9 @@ class teampage implements \phpbb\groupposition\groupposition_interface
}
/**
- * Movesan item down by teampage_id
+ * Moves an item down by teampage_id
*
- * @param int $group_id group_id of the group to be moved
+ * @param int $teampage_id teampage_id of the item to be moved
* @return bool True if the group was moved successfully
*/
public function move_down_teampage($teampage_id)
@@ -387,8 +388,6 @@ class teampage implements \phpbb\groupposition\groupposition_interface
}
/**
- * Moves a group up/down
- *
* {@inheritDoc}
*/
public function move($group_id, $delta)
diff --git a/phpBB/phpbb/hook/finder.php b/phpBB/phpbb/hook/finder.php
index c8f71861d9..a3d02d3aa0 100644
--- a/phpBB/phpbb/hook/finder.php
+++ b/phpBB/phpbb/hook/finder.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package extension
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\hook;
/**
* The hook finder locates installed hooks.
-*
-* @package phpBB3
*/
class finder
{
diff --git a/phpBB/phpbb/json_response.php b/phpBB/phpbb/json_response.php
index 45c2f6cac4..5219cd0c32 100644
--- a/phpBB/phpbb/json_response.php
+++ b/phpBB/phpbb/json_response.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb;
/**
* JSON class
-* @package phpBB3
*/
class json_response
{
diff --git a/phpBB/phpbb/lock/db.php b/phpBB/phpbb/lock/db.php
index 461adda045..85ba9a7aa3 100644
--- a/phpBB/phpbb/lock/db.php
+++ b/phpBB/phpbb/lock/db.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\lock;
/**
* Database locking class
-* @package phpBB3
*/
class db
{
@@ -42,7 +45,7 @@ class db
/**
* A database connection
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
private $db;
@@ -51,11 +54,11 @@ class db
*
* You have to call acquire() to actually create the lock.
*
- * @param string $config_name A config variable to be used for locking
- * @param array $config The phpBB configuration
- * @param \phpbb\db\driver\driver $db A database connection
+ * @param string $config_name A config variable to be used for locking
+ * @param \phpbb\config\config $config The phpBB configuration
+ * @param \phpbb\db\driver\driver_interface $db A database connection
*/
- public function __construct($config_name, \phpbb\config\config $config, \phpbb\db\driver\driver $db)
+ public function __construct($config_name, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db)
{
$this->config_name = $config_name;
$this->config = $config;
diff --git a/phpBB/phpbb/lock/flock.php b/phpBB/phpbb/lock/flock.php
index 94a5895440..df88e1490a 100644
--- a/phpBB/phpbb/lock/flock.php
+++ b/phpBB/phpbb/lock/flock.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\lock;
/**
* File locking class
-* @package phpBB3
*/
class flock
{
diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php
index 68b023e244..2af8b50b54 100644
--- a/phpBB/phpbb/log/log.php
+++ b/phpBB/phpbb/log/log.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package \phpbb\log\log
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\log;
/**
* This class is used to add entries into the log table.
-*
-* @package \phpbb\log\log
*/
class log implements \phpbb\log\log_interface
{
@@ -68,7 +70,7 @@ class log implements \phpbb\log\log_interface
/**
* Event dispatcher object
- * @var phpbb_dispatcher
+ * @var \phpbb\event\dispatcher_interface
*/
protected $dispatcher;
@@ -93,15 +95,14 @@ class log implements \phpbb\log\log_interface
/**
* Constructor
*
- * @param \phpbb\db\driver\driver $db Database object
+ * @param \phpbb\db\driver\driver_interface $db Database object
* @param \phpbb\user $user User object
* @param \phpbb\auth\auth $auth Auth object
- * @param phpbb_dispatcher $phpbb_dispatcher Event dispatcher
+ * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher
* @param string $phpbb_root_path Root path
* @param string $relative_admin_path Relative admin root path
* @param string $php_ext PHP Extension
* @param string $log_table Name of the table we use to store our logs
- * @return null
*/
public function __construct($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, $relative_admin_path, $php_ext, $log_table)
{
@@ -157,8 +158,6 @@ class log implements \phpbb\log\log_interface
}
/**
- * This function returns the state of the log system.
- *
* {@inheritDoc}
*/
public function is_enabled($type = '')
@@ -171,12 +170,6 @@ class log implements \phpbb\log\log_interface
}
/**
- * Disable log
- *
- * This function allows disabling the log system or parts of it, for this
- * page call. When add_log is called and the type is disabled,
- * the log will not be added to the database.
- *
* {@inheritDoc}
*/
public function disable($type = '')
@@ -199,10 +192,6 @@ class log implements \phpbb\log\log_interface
}
/**
- * Enable log
- *
- * This function allows re-enabling the log system.
- *
* {@inheritDoc}
*/
public function enable($type = '')
@@ -225,8 +214,6 @@ class log implements \phpbb\log\log_interface
}
/**
- * Adds a log to the database
- *
* {@inheritDoc}
*/
public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array())
@@ -258,9 +245,9 @@ class log implements \phpbb\log\log_interface
break;
case 'mod':
- $forum_id = (int) $additional_data['forum_id'];
+ $forum_id = isset($additional_data['forum_id']) ? (int) $additional_data['forum_id'] : 0;
unset($additional_data['forum_id']);
- $topic_id = (int) $additional_data['topic_id'];
+ $topic_id = isset($additional_data['topic_id']) ? (int) $additional_data['topic_id'] : 0;
unset($additional_data['topic_id']);
$sql_ary += array(
'log_type' => LOG_MOD,
@@ -305,9 +292,17 @@ class log implements \phpbb\log\log_interface
* @var array sql_ary Array with log data we insert into the
* database. If sql_ary[log_type] is not set,
* we won't add the entry to the database.
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
- $vars = array('mode', 'user_id', 'log_ip', 'log_operation', 'log_time', 'additional_data', 'sql_ary');
+ $vars = array(
+ 'mode',
+ 'user_id',
+ 'log_ip',
+ 'log_operation',
+ 'log_time',
+ 'additional_data',
+ 'sql_ary',
+ );
extract($this->dispatcher->trigger_event('core.add_log', compact($vars)));
// We didn't find a log_type, so we don't save it in the database.
@@ -322,8 +317,99 @@ class log implements \phpbb\log\log_interface
}
/**
- * Grab the logs from the database
- *
+ * {@inheritDoc}
+ */
+ public function delete($mode, $conditions = array())
+ {
+ switch ($mode)
+ {
+ case 'admin':
+ $log_type = LOG_ADMIN;
+ break;
+
+ case 'mod':
+ $log_type = LOG_MOD;
+ break;
+
+ case 'user':
+ $log_type = LOG_USERS;
+ break;
+
+ case 'users':
+ $log_type = LOG_USERS;
+ break;
+
+ case 'critical':
+ $log_type = LOG_CRITICAL;
+ break;
+
+ default:
+ $log_type = false;
+ }
+
+ /**
+ * Allows to modify log data before we delete it from the database
+ *
+ * NOTE: if sql_ary does not contain a log_type value, the entry will
+ * not be deleted in the database. So ensure to set it, if needed.
+ *
+ * @event core.delete_log
+ * @var string mode Mode of the entry we log
+ * @var string log_type Type ID of the log (should be different than false)
+ * @var array conditions An array of conditions, 3 different forms are accepted
+ * 1) <key> => <value> transformed into 'AND <key> = <value>' (value should be an integer)
+ * 2) <key> => array(<operator>, <value>) transformed into 'AND <key> <operator> <value>' (values can't be an array)
+ * 3) <key> => array('IN' => array(<values>)) transformed into 'AND <key> IN <values>'
+ * A special field, keywords, can also be defined. In this case only the log entries that have the keywords in log_operation or log_data will be deleted.
+ * @since 3.1.0-b4
+ */
+ $vars = array(
+ 'mode',
+ 'log_type',
+ 'conditions',
+ );
+ extract($this->dispatcher->trigger_event('core.delete_log', compact($vars)));
+
+ if ($log_type === false)
+ {
+ return;
+ }
+
+ $sql_where = 'WHERE log_type = ' . $log_type;
+
+ if (isset($conditions['keywords']))
+ {
+ $sql_where .= $this->generate_sql_keyword($conditions['keywords'], '');
+
+ unset($conditions['keywords']);
+ }
+
+ foreach ($conditions as $field => $field_value)
+ {
+ $sql_where .= ' AND ';
+
+ if (is_array($field_value) && sizeof($field_value) == 2 && !is_array($field_value[1]))
+ {
+ $sql_where .= $field . ' ' . $field_value[0] . ' ' . $field_value[1];
+ }
+ else if (is_array($field_value) && isset($field_value['IN']) && is_array($field_value['IN']))
+ {
+ $sql_where .= $this->db->sql_in_set($field, $field_value['IN']);
+ }
+ else
+ {
+ $sql_where .= $field . ' = ' . $field_value;
+ }
+ }
+
+ $sql = 'DELETE FROM ' . LOG_TABLE . "
+ $sql_where";
+ $this->db->sql_query($sql);
+
+ $this->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_CLEAR_' . strtoupper($mode));
+ }
+
+ /**
* {@inheritDoc}
*/
public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '')
@@ -403,9 +489,23 @@ class log implements \phpbb\log\log_interface
* is false, no entries will be returned.
* @var string sql_additional Additional conditions for the entries,
* e.g.: 'AND l.forum_id = 1'
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
- $vars = array('mode', 'count_logs', 'limit', 'offset', 'forum_id', 'topic_id', 'user_id', 'log_time', 'sort_by', 'keywords', 'profile_url', 'log_type', 'sql_additional');
+ $vars = array(
+ 'mode',
+ 'count_logs',
+ 'limit',
+ 'offset',
+ 'forum_id',
+ 'topic_id',
+ 'user_id',
+ 'log_time',
+ 'sort_by',
+ 'keywords',
+ 'profile_url',
+ 'log_type',
+ 'sql_additional',
+ );
extract($this->dispatcher->trigger_event('core.get_logs_modify_type', compact($vars)));
if ($log_type === false)
@@ -490,7 +590,7 @@ class log implements \phpbb\log\log_interface
'topic_id' => (int) $row['topic_id'],
'viewforum' => ($row['forum_id'] && $this->auth->acl_get('f_read', $row['forum_id'])) ? append_sid("{$this->phpbb_root_path}viewforum.{$this->php_ext}", 'f=' . $row['forum_id']) : false,
- 'action' => (isset($this->user->lang[$row['log_operation']])) ? $this->user->lang[$row['log_operation']] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}',
+ 'action' => (isset($this->user->lang[$row['log_operation']])) ? $row['log_operation'] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}',
);
/**
@@ -499,7 +599,7 @@ class log implements \phpbb\log\log_interface
* @event core.get_logs_modify_entry_data
* @var array row Entry data from the database
* @var array log_entry_data Entry's data which is returned
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('row', 'log_entry_data');
extract($this->dispatcher->trigger_event('core.get_logs_modify_entry_data', compact($vars)));
@@ -517,12 +617,26 @@ class log implements \phpbb\log\log_interface
// arguments, if there are we fill out the arguments
// array. It doesn't matter if we add more arguments than
// placeholders.
- if ((substr_count($log[$i]['action'], '%') - sizeof($log_data_ary)) > 0)
+ $num_args = 0;
+ if (!is_array($this->user->lang[$row['log_operation']]))
+ {
+ $num_args = substr_count($this->user->lang[$row['log_operation']], '%');
+ }
+ else
+ {
+ foreach ($this->user->lang[$row['log_operation']] as $case => $plural_string)
+ {
+ $num_args = max($num_args, substr_count($plural_string, '%'));
+ }
+ }
+
+ if (($num_args - sizeof($log_data_ary)) > 0)
{
- $log_data_ary = array_merge($log_data_ary, array_fill(0, substr_count($log[$i]['action'], '%') - sizeof($log_data_ary), ''));
+ $log_data_ary = array_merge($log_data_ary, array_fill(0, $num_args - sizeof($log_data_ary), ''));
}
- $log[$i]['action'] = vsprintf($log[$i]['action'], $log_data_ary);
+ $lang_arguments = array_merge(array($log[$i]['action']), $log_data_ary);
+ $log[$i]['action'] = call_user_func_array(array($this->user, 'lang'), $lang_arguments);
// If within the admin panel we do not censor text out
if ($this->get_is_admin())
@@ -544,6 +658,10 @@ class log implements \phpbb\log\log_interface
$log[$i]['action'] = make_clickable($log[$i]['action']);
*/
}
+ else
+ {
+ $log[$i]['action'] = $this->user->lang($log[$i]['action']);
+ }
$i++;
}
@@ -558,7 +676,7 @@ class log implements \phpbb\log\log_interface
* get the permission data
* @var array reportee_id_list Array of additional user IDs we
* get the username strings for
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('log', 'topic_id_list', 'reportee_id_list');
extract($this->dispatcher->trigger_event('core.get_logs_get_additional_data', compact($vars)));
@@ -596,11 +714,13 @@ class log implements \phpbb\log\log_interface
/**
* Generates a sql condition for the specified keywords
*
- * @param string $keywords The keywords the user specified to search for
+ * @param string $keywords The keywords the user specified to search for
+ * @param string $table_alias The alias of the logs' table ('l.' by default)
+ * @param string $statement_operator The operator used to prefix the statement ('AND' by default)
*
* @return string Returns the SQL condition searching for the keywords
*/
- protected function generate_sql_keyword($keywords)
+ protected function generate_sql_keyword($keywords, $table_alias = 'l.', $statement_operator = 'AND')
{
// Use no preg_quote for $keywords because this would lead to sole
// backslashes being added. We also use an OR connection here for
@@ -617,7 +737,7 @@ class log implements \phpbb\log\log_interface
for ($i = 0, $num_keywords = sizeof($keywords); $i < $num_keywords; $i++)
{
$keywords_pattern[] = preg_quote($keywords[$i], '#');
- $keywords[$i] = $this->db->sql_like_expression($this->db->any_char . $keywords[$i] . $this->db->any_char);
+ $keywords[$i] = $this->db->sql_like_expression($this->db->get_any_char() . $keywords[$i] . $this->db->get_any_char());
}
$keywords_pattern = '#' . implode('|', $keywords_pattern) . '#ui';
@@ -625,18 +745,32 @@ class log implements \phpbb\log\log_interface
$operations = array();
foreach ($this->user->lang as $key => $value)
{
- if (substr($key, 0, 4) == 'LOG_' && preg_match($keywords_pattern, $value))
+ if (substr($key, 0, 4) == 'LOG_')
{
- $operations[] = $key;
+ if (is_array($value))
+ {
+ foreach ($value as $plural_value)
+ {
+ if (preg_match($keywords_pattern, $plural_value))
+ {
+ $operations[] = $key;
+ break;
+ }
+ }
+ }
+ else if (preg_match($keywords_pattern, $value))
+ {
+ $operations[] = $key;
+ }
}
}
- $sql_keywords = 'AND (';
+ $sql_keywords = ' ' . $statement_operator . ' (';
if (!empty($operations))
{
- $sql_keywords .= $this->db->sql_in_set('l.log_operation', $operations) . ' OR ';
+ $sql_keywords .= $this->db->sql_in_set($table_alias . 'log_operation', $operations) . ' OR ';
}
- $sql_lower = $this->db->sql_lower_text('l.log_data');
+ $sql_lower = $this->db->sql_lower_text($table_alias . 'log_data');
$sql_keywords .= " $sql_lower " . implode(" OR $sql_lower ", $keywords) . ')';
}
@@ -712,8 +846,6 @@ class log implements \phpbb\log\log_interface
}
/**
- * Get total log count
- *
* {@inheritDoc}
*/
public function get_log_count()
@@ -722,8 +854,6 @@ class log implements \phpbb\log\log_interface
}
/**
- * Get offset of the last valid log page
- *
* {@inheritDoc}
*/
public function get_valid_offset()
diff --git a/phpBB/phpbb/log/log_interface.php b/phpBB/phpbb/log/log_interface.php
index 420ba79691..5932f722aa 100644
--- a/phpBB/phpbb/log/log_interface.php
+++ b/phpBB/phpbb/log/log_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package \phpbb\log\log
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\log;
/**
* The interface for the log-system.
-*
-* @package \phpbb\log\log
*/
interface log_interface
{
@@ -67,6 +69,18 @@ interface log_interface
public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array());
/**
+ * Delete entries in the logs
+ *
+ * @param string $mode The mode defines which log_type is used and from which log the entries are deleted
+ * @param array $conditions An array of conditions, 3 different forms are accepted
+ * 1) <key> => <value> transformed into 'AND <key> = <value>' (value should be an integer)
+ * 2) <key> => array(<operator>, <value>) transformed into 'AND <key> <operator> <value>' (values can't be an array)
+ * 3) <key> => array('IN' => array(<values>)) transformed into 'AND <key> IN <values>'
+ * A special field, keywords, can also be defined. In this case only the log entries that have the keywords in log_operation or log_data will be deleted.
+ */
+ public function delete($mode, $conditions = array());
+
+ /**
* Grab the logs from the database
*
* @param string $mode The mode defines which log_type is used and ifrom which log the entry is retrieved
diff --git a/phpBB/phpbb/log/null.php b/phpBB/phpbb/log/null.php
index 77d0fbe2d7..baa78895ea 100644
--- a/phpBB/phpbb/log/null.php
+++ b/phpBB/phpbb/log/null.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpbb_log
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\log;
/**
* Null logger
-*
-* @package phpbb_log
*/
class null implements log_interface
{
@@ -49,6 +51,13 @@ class null implements log_interface
/**
* {@inheritdoc}
*/
+ public function delete($mode, $conditions = array())
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '')
{
return array();
diff --git a/phpBB/phpbb/message/admin_form.php b/phpBB/phpbb/message/admin_form.php
new file mode 100644
index 0000000000..93db59880c
--- /dev/null
+++ b/phpBB/phpbb/message/admin_form.php
@@ -0,0 +1,191 @@
+<?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\message;
+
+/**
+* Class admin_form
+* Displays a message to the user and allows him to send an email
+*/
+class admin_form extends form
+{
+ /** @var \phpbb\config\db_text */
+ protected $config_text;
+
+ /** @var string */
+ protected $subject;
+ /** @var string */
+ protected $sender_name;
+ /** @var string */
+ protected $sender_address;
+
+ /**
+ * Construct
+ *
+ * @param \phpbb\auth\auth $auth
+ * @param \phpbb\config\config $config
+ * @param \phpbb\config\db_text $config_text
+ * @param \phpbb\db\driver\driver_interface $db
+ * @param \phpbb\user $user
+ * @param string $phpbb_root_path
+ * @param string $phpEx
+ */
+ public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\config\db_text $config_text, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $phpEx)
+ {
+ parent::__construct($auth, $config, $db, $user, $phpbb_root_path, $phpEx);
+ $this->config_text = $config_text;
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function check_allow()
+ {
+ $error = parent::check_allow();
+ if ($error)
+ {
+ return $error;
+ }
+
+ if (!$this->config['contact_admin_form_enable'])
+ {
+ return 'NO_CONTACT_PAGE';
+ }
+
+ return false;
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function bind(\phpbb\request\request_interface $request)
+ {
+ parent::bind($request);
+
+ $this->subject = $request->variable('subject', '', true);
+ $this->sender_address = $request->variable('email', '');
+ $this->sender_name = $request->variable('name', '', true);
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function submit(\messenger $messenger)
+ {
+ if (!$this->subject)
+ {
+ $this->errors[] = $this->user->lang['EMPTY_SUBJECT_EMAIL'];
+ }
+ if (!$this->body)
+ {
+ $this->errors[] = $this->user->lang['EMPTY_MESSAGE_EMAIL'];
+ }
+
+ if ($this->user->data['is_registered'])
+ {
+ $this->message->set_sender_from_user($this->user);
+ $this->sender_name = $this->user->data['username'];
+ $this->sender_address = $this->user->data['user_email'];
+ }
+ else
+ {
+ if (!$this->sender_name)
+ {
+ $this->errors[] = $this->user->lang['EMPTY_SENDER_NAME'];
+ }
+
+ if (!function_exists('validate_data'))
+ {
+ require($this->phpbb_root_path . 'includes/functions_user.' . $this->phpEx);
+ }
+
+ $validate_array = validate_data(
+ array(
+ 'email' => $this->sender_address,
+ ),
+ array(
+ 'email' => array(
+ array('string', false, 6, 60),
+ array('email'),
+ ),
+ )
+ );
+
+ foreach ($validate_array as $error)
+ {
+ $this->errors[] = $this->user->lang[$error];
+ }
+
+ $this->message->set_sender($this->user->ip, $this->sender_name, $this->sender_address, $this->user->lang_name);
+ $this->message->set_sender_notify_type(NOTIFY_EMAIL);
+ }
+
+ $this->message->set_template('contact_admin');
+ $this->message->set_subject($this->subject);
+ $this->message->set_body($this->body);
+ $this->message->add_recipient(
+ $this->user->lang['ADMINISTRATOR'],
+ $this->config['board_contact'],
+ $this->config['default_lang'],
+ NOTIFY_EMAIL
+ );
+
+ $this->message->set_template_vars(array(
+ 'FROM_EMAIL_ADDRESS' => $this->sender_address,
+ 'FROM_IP_ADDRESS' => $this->user->ip,
+ 'S_IS_REGISTERED' => $this->user->data['is_registered'],
+
+ 'U_FROM_PROFILE' => generate_board_url() . '/memberlist.' . $this->phpEx . '?mode=viewprofile&u=' . $this->user->data['user_id'],
+ ));
+
+ parent::submit($messenger);
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function render(\phpbb\template\template $template)
+ {
+ $l_admin_info = $this->config_text->get('contact_admin_info');
+ if ($l_admin_info)
+ {
+ $contact_admin_data = $this->config_text->get_array(array(
+ 'contact_admin_info',
+ 'contact_admin_info_uid',
+ 'contact_admin_info_bitfield',
+ 'contact_admin_info_flags',
+ ));
+
+ $l_admin_info = generate_text_for_display(
+ $contact_admin_data['contact_admin_info'],
+ $contact_admin_data['contact_admin_info_uid'],
+ $contact_admin_data['contact_admin_info_bitfield'],
+ $contact_admin_data['contact_admin_info_flags']
+ );
+ }
+
+ $template->assign_vars(array(
+ 'S_CONTACT_ADMIN' => true,
+ 'S_CONTACT_FORM' => $this->config['contact_admin_form_enable'],
+ 'S_IS_REGISTERED' => $this->user->data['is_registered'],
+
+ 'CONTACT_INFO' => $l_admin_info,
+ 'MESSAGE' => $this->body,
+ 'SUBJECT' => $this->subject,
+ 'NAME' => $this->sender_name,
+ 'EMAIL' => $this->sender_address,
+ ));
+
+ parent::render($template);
+ }
+}
diff --git a/phpBB/phpbb/message/form.php b/phpBB/phpbb/message/form.php
new file mode 100644
index 0000000000..076b41dc07
--- /dev/null
+++ b/phpBB/phpbb/message/form.php
@@ -0,0 +1,175 @@
+<?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\message;
+
+/**
+* Abstract class form
+*/
+abstract class form
+{
+ /** @var \phpbb\auth\auth */
+ protected $auth;
+ /** @var \phpbb\config\config */
+ protected $config;
+ /** @var \phpbb\db\driver\driver_interface */
+ protected $db;
+ /** @var \phpbb\message\message */
+ protected $message;
+ /** @var \phpbb\user */
+ protected $user;
+
+ /** @var string */
+ protected $phpbb_root_path;
+ /** @var string */
+ protected $phpEx;
+
+ /** @var array */
+ protected $errors = array();
+ /** @var bool */
+ protected $cc_sender;
+ /** @var string */
+ protected $body;
+
+ /**
+ * Construct
+ *
+ * @param \phpbb\auth\auth $auth
+ * @param \phpbb\config\config $config
+ * @param \phpbb\db\driver\driver_interface $db
+ * @param \phpbb\user $user
+ * @param string $phpbb_root_path
+ * @param string $phpEx
+ */
+ public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $phpEx)
+ {
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->phpEx = $phpEx;
+ $this->user = $user;
+ $this->auth = $auth;
+ $this->config = $config;
+ $this->db = $db;
+
+ $this->message = new message($config['server_name']);
+ $this->message->set_sender_from_user($this->user);
+ }
+
+ /**
+ * Returns the title for the email form page
+ *
+ * @return string
+ */
+ public function get_page_title()
+ {
+ return $this->user->lang['SEND_EMAIL'];
+ }
+
+ /**
+ * Returns the file name of the form template
+ *
+ * @return string
+ */
+ public function get_template_file()
+ {
+ return 'memberlist_email.html';
+ }
+
+ /**
+ * Checks whether the user is allowed to use the form
+ *
+ * @return false|string Error string if not allowed, false otherwise
+ */
+ public function check_allow()
+ {
+ if (!$this->config['email_enable'])
+ {
+ return 'EMAIL_DISABLED';
+ }
+
+ if (time() - $this->user->data['user_emailtime'] < $this->config['flood_interval'])
+ {
+ return 'FLOOD_EMAIL_LIMIT';
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the return link after the message has been sent
+ *
+ * @return string
+ */
+ public function get_return_message()
+ {
+ return sprintf($this->user->lang['RETURN_INDEX'], '<a href="' . append_sid($this->phpbb_root_path . 'index.' . $this->phpEx) . '">', '</a>');
+ }
+
+ /**
+ * Bind the values of the request to the form
+ *
+ * @param \phpbb\request\request_interface $request
+ * @return null
+ */
+ public function bind(\phpbb\request\request_interface $request)
+ {
+ $this->cc_sender = $request->is_set_post('cc_sender');
+ $this->body = $request->variable('message', '', true);
+ }
+
+ /**
+ * Submit form, generate the email and send it
+ *
+ * @param \messenger $messenger
+ * @return null
+ */
+ public function submit(\messenger $messenger)
+ {
+ if (!check_form_key('memberlist_email'))
+ {
+ $this->errors[] = 'FORM_INVALID';
+ }
+
+ if (!sizeof($this->errors))
+ {
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET user_emailtime = ' . time() . '
+ WHERE user_id = ' . $this->user->data['user_id'];
+ $this->db->sql_query($sql);
+
+ if ($this->cc_sender)
+ {
+ $this->message->cc_sender();
+ }
+
+ $this->message->send($messenger, phpbb_get_board_contact($this->config, $this->phpEx));
+
+ meta_refresh(3, append_sid($this->phpbb_root_path . 'index.' . $this->phpEx));
+ trigger_error($this->user->lang['EMAIL_SENT'] . '<br /><br />' . $this->get_return_message());
+ }
+ }
+
+ /**
+ * Render the template of the form
+ *
+ * @param \phpbb\template\template $template
+ * @return null
+ */
+ public function render(\phpbb\template\template $template)
+ {
+ add_form_key('memberlist_email');
+
+ $template->assign_vars(array(
+ 'ERROR_MESSAGE' => (sizeof($this->errors)) ? implode('<br />', $this->errors) : '',
+ ));
+ }
+}
diff --git a/phpBB/phpbb/message/message.php b/phpBB/phpbb/message/message.php
new file mode 100644
index 0000000000..5fd24b542e
--- /dev/null
+++ b/phpBB/phpbb/message/message.php
@@ -0,0 +1,282 @@
+<?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\message;
+
+/**
+* Class message
+* Holds all information for an email and sends it in the end
+*/
+class message
+{
+ /** @var string */
+ protected $server_name;
+
+ /** @var string */
+ protected $subject = '';
+ /** @var string */
+ protected $body = '';
+ /** @var string */
+ protected $template = '';
+ /** @var array */
+ protected $template_vars = array();
+
+ /** @var string */
+ protected $sender_ip = '';
+ /** @var string */
+ protected $sender_name = '';
+ /** @var string */
+ protected $sender_address = '';
+ /** @var string */
+ protected $sender_lang = '';
+ /** @var string */
+ protected $sender_id = '';
+ /** @var string */
+ protected $sender_username = '';
+ /** @var string */
+ protected $sender_jabber = '';
+ /** @var int */
+ protected $sender_notify_type = NOTIFY_EMAIL;
+
+ /** @var array */
+ protected $recipients;
+
+ /**
+ * Construct
+ *
+ * @param string $server_name Used for AntiAbuse header
+ */
+ public function __construct($server_name)
+ {
+ $this->server_name = $server_name;
+ }
+
+ /**
+ * Set the subject of the email
+ *
+ * @param string $subject
+ * @return null
+ */
+ public function set_subject($subject)
+ {
+ $this->subject = $subject;
+ }
+
+ /**
+ * Set the body of the email text
+ *
+ * @param string $body
+ * @return null
+ */
+ public function set_body($body)
+ {
+ $this->body = $body;
+ }
+
+ /**
+ * Set the name of the email template to use
+ *
+ * @param string $template
+ * @return null
+ */
+ public function set_template($template)
+ {
+ $this->template = $template;
+ }
+
+ /**
+ * Set the array with the "template" data for the email
+ *
+ * @param array $template_vars
+ * @return null
+ */
+ public function set_template_vars($template_vars)
+ {
+ $this->template_vars = $template_vars;
+ }
+
+ /**
+ * Add a recipient from \phpbb\user
+ *
+ * @param array $user
+ * @return null
+ */
+ public function add_recipient_from_user_row(array $user)
+ {
+ $this->add_recipient(
+ $user['username'],
+ $user['user_email'],
+ $user['user_lang'],
+ $user['user_notify_type'],
+ $user['username'],
+ $user['user_jabber']
+ );
+ }
+
+ /**
+ * Add a recipient
+ *
+ * @param string $recipient_name Displayed sender name
+ * @param string $recipient_address Email address
+ * @param string $recipient_lang
+ * @param int $recipient_notify_type Used notification methods (Jabber, Email, ...)
+ * @param string $recipient_username User Name (used for AntiAbuse header)
+ * @param string $recipient_jabber
+ * @return null
+ */
+ public function add_recipient($recipient_name, $recipient_address, $recipient_lang, $recipient_notify_type = NOTIFY_EMAIL, $recipient_username = '', $recipient_jabber = '')
+ {
+ $this->recipients[] = array(
+ 'name' => $recipient_name,
+ 'address' => $recipient_address,
+ 'lang' => $recipient_lang,
+ 'username' => $recipient_username,
+ 'jabber' => $recipient_jabber,
+ 'notify_type' => $recipient_notify_type,
+ 'to_name' => $recipient_name,
+ );
+ }
+
+ /**
+ * Set the senders data from \phpbb\user object
+ *
+ * @param \phpbb\user $user
+ * @return null
+ */
+ public function set_sender_from_user($user)
+ {
+ $this->set_sender(
+ $user->ip,
+ $user->data['username'],
+ $user->data['user_email'],
+ $user->lang_name,
+ $user->data['user_id'],
+ $user->data['username'],
+ $user->data['user_jabber']
+ );
+
+ $this->set_sender_notify_type($user->data['user_notify_type']);
+ }
+
+ /**
+ * Set the senders data
+ *
+ * @param string $sender_ip
+ * @param string $sender_name Displayed sender name
+ * @param string $sender_address Email address
+ * @param string $sender_lang
+ * @param int $sender_id User ID
+ * @param string $sender_username User Name (used for AntiAbuse header)
+ * @param string $sender_jabber
+ * @return null
+ */
+ public function set_sender($sender_ip, $sender_name, $sender_address, $sender_lang = '', $sender_id = 0, $sender_username = '', $sender_jabber = '')
+ {
+ $this->sender_ip = $sender_ip;
+ $this->sender_name = $sender_name;
+ $this->sender_address = $sender_address;
+ $this->sender_lang = $sender_lang;
+ $this->sender_id = $sender_id;
+ $this->sender_username = $sender_username;
+ $this->sender_jabber = $sender_jabber;
+ }
+
+ /**
+ * Which notification type should be used? Jabber, Email, ...?
+ *
+ * @param int $sender_notify_type
+ * @return null
+ */
+ public function set_sender_notify_type($sender_notify_type)
+ {
+ $this->sender_notify_type = $sender_notify_type;
+ }
+
+ /**
+ * Ok, now the same email if CC specified, but without exposing the user's email address
+ *
+ * @return null
+ */
+ public function cc_sender()
+ {
+ if (!sizeof($this->recipients))
+ {
+ trigger_error('No email recipients specified');
+ }
+ if (!$this->sender_address)
+ {
+ trigger_error('No email sender specified');
+ }
+
+ $this->recipients[] = array(
+ 'lang' => $this->sender_lang,
+ 'address' => $this->sender_address,
+ 'name' => $this->sender_name,
+ 'username' => $this->sender_username,
+ 'jabber' => $this->sender_jabber,
+ 'notify_type' => $this->sender_notify_type,
+ 'to_name' => $this->recipients[0]['to_name'],
+ );
+ }
+
+ /**
+ * Send the email
+ *
+ * @param \messenger $messenger
+ * @param string $contact
+ * @return null
+ */
+ public function send(\messenger $messenger, $contact)
+ {
+ if (!sizeof($this->recipients))
+ {
+ return;
+ }
+
+ foreach ($this->recipients as $recipient)
+ {
+ $messenger->template($this->template, $recipient['lang']);
+ $messenger->replyto($this->sender_address);
+ $messenger->to($recipient['address'], $recipient['name']);
+ $messenger->im($recipient['jabber'], $recipient['username']);
+
+ $messenger->headers('X-AntiAbuse: Board servername - ' . $this->server_name);
+ $messenger->headers('X-AntiAbuse: User IP - ' . $this->sender_ip);
+
+ if ($this->sender_id)
+ {
+ $messenger->headers('X-AntiAbuse: User_id - ' . $this->sender_id);
+ }
+ if ($this->sender_username)
+ {
+ $messenger->headers('X-AntiAbuse: Username - ' . $this->sender_username);
+ }
+
+ $messenger->subject(htmlspecialchars_decode($this->subject));
+
+ $messenger->assign_vars(array(
+ 'BOARD_CONTACT' => $contact,
+ 'TO_USERNAME' => htmlspecialchars_decode($recipient['to_name']),
+ 'FROM_USERNAME' => htmlspecialchars_decode($this->sender_name),
+ 'MESSAGE' => htmlspecialchars_decode($this->body))
+ );
+
+ if (sizeof($this->template_vars))
+ {
+ $messenger->assign_vars($this->template_vars);
+ }
+
+ $messenger->send($recipient['notify_type']);
+ }
+ }
+}
diff --git a/phpBB/phpbb/message/topic_form.php b/phpBB/phpbb/message/topic_form.php
new file mode 100644
index 0000000000..1e0f2a1945
--- /dev/null
+++ b/phpBB/phpbb/message/topic_form.php
@@ -0,0 +1,158 @@
+<?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\message;
+
+/**
+* Class topic_form
+* Form used to send topics as notification emails
+*/
+class topic_form extends form
+{
+ /** @var int */
+ protected $topic_id;
+ /** @var array */
+ protected $topic_row;
+ /** @var string */
+ protected $recipient_address;
+ /** @var string */
+ protected $recipient_name;
+ /** @var string */
+ protected $recipient_lang;
+
+ /**
+ * Get the data of the topic
+ *
+ * @param int $topic_id
+ * @return false|array false if the topic does not exist, array otherwise
+ */
+ protected function get_topic_row($topic_id)
+ {
+ $sql = 'SELECT forum_id, topic_title
+ FROM ' . TOPICS_TABLE . '
+ WHERE topic_id = ' . (int) $topic_id;
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ return $row;
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function check_allow()
+ {
+ $error = parent::check_allow();
+ if ($error)
+ {
+ return $error;
+ }
+
+ if (!$this->auth->acl_get('u_sendemail'))
+ {
+ return 'NO_EMAIL';
+ }
+
+ if (!$this->topic_row)
+ {
+ return 'NO_TOPIC';
+ }
+
+ if (!$this->auth->acl_get('f_read', $this->topic_row['forum_id']))
+ {
+ return 'SORRY_AUTH_READ';
+ }
+
+ if (!$this->auth->acl_get('f_email', $this->topic_row['forum_id']))
+ {
+ return 'NO_EMAIL';
+ }
+
+ return false;
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function bind(\phpbb\request\request_interface $request)
+ {
+ parent::bind($request);
+
+ $this->topic_id = $request->variable('t', 0);
+ $this->recipient_address = $request->variable('email', '');
+ $this->recipient_name = $request->variable('name', '', true);
+ $this->recipient_lang = $request->variable('lang', $this->config['default_lang']);
+
+ $this->topic_row = $this->get_topic_row($this->topic_id);
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function submit(\messenger $messenger)
+ {
+ if (!$this->recipient_address || !preg_match('/^' . get_preg_expression('email') . '$/i', $this->recipient_address))
+ {
+ $this->errors[] = $this->user->lang['EMPTY_ADDRESS_EMAIL'];
+ }
+
+ if (!$this->recipient_name)
+ {
+ $this->errors[] = $this->user->lang['EMPTY_NAME_EMAIL'];
+ }
+
+ $this->message->set_template('email_notify');
+ $this->message->set_template_vars(array(
+ 'TOPIC_NAME' => htmlspecialchars_decode($this->topic_row['topic_title']),
+ 'U_TOPIC' => generate_board_url() . '/viewtopic.' . $this->phpEx . '?f=' . $this->topic_row['forum_id'] . '&t=' . $this->topic_id,
+ ));
+
+ $this->message->add_recipient(
+ $this->recipient_name,
+ $this->recipient_address,
+ $this->recipient_lang,
+ NOTIFY_EMAIL
+ );
+ $this->message->set_sender_notify_type(NOTIFY_EMAIL);
+
+ parent::submit($messenger);
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function get_return_message()
+ {
+ return sprintf($this->user->lang['RETURN_TOPIC'], '<a href="' . append_sid($this->phpbb_root_path . 'viewtopic.' . $this->phpEx, 'f=' . $this->topic_row['forum_id'] . '&amp;t=' . $this->topic_id) . '">', '</a>');
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function render(\phpbb\template\template $template)
+ {
+ parent::render($template);
+
+ $this->user->add_lang('viewtopic');
+ $template->assign_vars(array(
+ 'EMAIL' => $this->recipient_address,
+ 'NAME' => $this->recipient_name,
+ 'S_LANG_OPTIONS' => language_select($this->recipient_lang),
+ 'MESSAGE' => $this->body,
+
+ 'L_EMAIL_BODY_EXPLAIN' => $this->user->lang['EMAIL_TOPIC_EXPLAIN'],
+ 'S_POST_ACTION' => append_sid($this->phpbb_root_path . 'memberlist.' . $this->phpEx, 'mode=email&amp;t=' . $this->topic_id))
+ );
+ }
+}
diff --git a/phpBB/phpbb/message/user_form.php b/phpBB/phpbb/message/user_form.php
new file mode 100644
index 0000000000..007e575407
--- /dev/null
+++ b/phpBB/phpbb/message/user_form.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\message;
+
+/**
+* Class user_form
+* Allows users to send emails to other users
+*/
+class user_form extends form
+{
+ /** @var int */
+ protected $recipient_id;
+ /** @var array */
+ protected $recipient_row;
+ /** @var string */
+ protected $subject;
+
+ /**
+ * Get the data of the recipient
+ *
+ * @param int $user_id
+ * @return false|array false if the user does not exist, array otherwise
+ */
+ protected function get_user_row($user_id)
+ {
+ $sql = 'SELECT user_id, username, user_colour, user_email, user_allow_viewemail, user_lang, user_jabber, user_notify_type
+ FROM ' . USERS_TABLE . '
+ WHERE user_id = ' . (int) $user_id . '
+ AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')';
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ return $row;
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function check_allow()
+ {
+ $error = parent::check_allow();
+ if ($error)
+ {
+ return $error;
+ }
+
+ if (!$this->auth->acl_get('u_sendemail'))
+ {
+ return 'NO_EMAIL';
+ }
+
+ if ($this->recipient_id == ANONYMOUS || !$this->config['board_email_form'])
+ {
+ return 'NO_EMAIL';
+ }
+
+ if (!$this->recipient_row)
+ {
+ return 'NO_USER';
+ }
+
+ // Can we send email to this user?
+ if (!$this->recipient_row['user_allow_viewemail'] && !$this->auth->acl_get('a_user'))
+ {
+ return 'NO_EMAIL';
+ }
+
+ return false;
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function bind(\phpbb\request\request_interface $request)
+ {
+ parent::bind($request);
+
+ $this->recipient_id = $request->variable('u', 0);
+ $this->subject = $request->variable('subject', '', true);
+
+ $this->recipient_row = $this->get_user_row($this->recipient_id);
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function submit(\messenger $messenger)
+ {
+ if (!$this->subject)
+ {
+ $this->errors[] = $this->user->lang['EMPTY_SUBJECT_EMAIL'];
+ }
+
+ if (!$this->body)
+ {
+ $this->errors[] = $this->user->lang['EMPTY_MESSAGE_EMAIL'];
+ }
+
+ $this->message->set_template('profile_send_email');
+ $this->message->set_subject($this->subject);
+ $this->message->set_body($this->body);
+ $this->message->add_recipient_from_user_row($this->recipient_row);
+
+ parent::submit($messenger);
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function render(\phpbb\template\template $template)
+ {
+ parent::render($template);
+
+ $template->assign_vars(array(
+ 'S_SEND_USER' => true,
+ 'S_POST_ACTION' => append_sid($this->phpbb_root_path . 'memberlist.' . $this->phpEx, 'mode=email&amp;u=' . $this->recipient_id),
+
+ 'L_SEND_EMAIL_USER' => $this->user->lang('SEND_EMAIL_USER', $this->recipient_row['username']),
+ 'USERNAME_FULL' => get_username_string('full', $this->recipient_row['user_id'], $this->recipient_row['username'], $this->recipient_row['user_colour']),
+ 'SUBJECT' => $this->subject,
+ 'MESSAGE' => $this->body,
+ ));
+ }
+}
diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php
index 2d74582a21..f3ad7f5f41 100644
--- a/phpBB/phpbb/mimetype/content_guesser.php
+++ b/phpBB/phpbb/mimetype/content_guesser.php
@@ -1,30 +1,30 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\mimetype;
-/**
-* @package mimetype
-*/
-
class content_guesser extends guesser_base
{
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function is_supported()
{
- return function_exists('mime_content_type');
+ return function_exists('mime_content_type') && is_callable('mime_content_type');
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function guess($file, $file_name = '')
{
diff --git a/phpBB/phpbb/mimetype/extension_guesser.php b/phpBB/phpbb/mimetype/extension_guesser.php
index f6f4ae0138..9e36c07f91 100644
--- a/phpBB/phpbb/mimetype/extension_guesser.php
+++ b/phpBB/phpbb/mimetype/extension_guesser.php
@@ -1,18 +1,18 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\mimetype;
-/**
-* @package mimetype
-*/
-
class extension_guesser extends guesser_base
{
/**
@@ -470,7 +470,7 @@ class extension_guesser extends guesser_base
);
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function is_supported()
{
@@ -478,7 +478,7 @@ class extension_guesser extends guesser_base
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function guess($file, $file_name = '')
{
diff --git a/phpBB/phpbb/mimetype/guesser.php b/phpBB/phpbb/mimetype/guesser.php
index 3499b3b0f7..8baa77089b 100644
--- a/phpBB/phpbb/mimetype/guesser.php
+++ b/phpBB/phpbb/mimetype/guesser.php
@@ -1,18 +1,18 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\mimetype;
-/**
-* @package mimetype
-*/
-
class guesser
{
/**
@@ -21,7 +21,7 @@ class guesser
const PRIORITY_DEFAULT = 0;
/**
- * @var mimetype guessers
+ * @var array guessers
*/
protected $guessers;
@@ -99,6 +99,7 @@ class guesser
* Guess mimetype of supplied file
*
* @param string $file Path to file
+ * @param string $file_name The real file name
*
* @return string Guess for mimetype of file
*/
@@ -114,17 +115,42 @@ class guesser
return false;
}
+ $mimetype = 'application/octet-stream';
+
foreach ($this->guessers as $guesser)
{
- $mimetype = $guesser->guess($file, $file_name);
+ $mimetype_guess = $guesser->guess($file, $file_name);
- // Try to guess something that is not the fallback application/octet-stream
- if ($mimetype !== null && $mimetype !== 'application/octet-stream')
- {
- return $mimetype;
- }
+ $mimetype = $this->choose_mime_type($mimetype, $mimetype_guess);
}
// Return any mimetype if we got a result or the fallback value
- return (!empty($mimetype)) ? $mimetype : 'application/octet-stream';
+ return $mimetype;
+ }
+
+ /**
+ * Choose the best mime type based on the current mime type and the guess
+ * If a guesser returns nulls or application/octet-stream, we will keep
+ * the current guess. Guesses with a slash inside them will be favored over
+ * already existing ones. However, any guess that will pass the first check
+ * will always overwrite the default application/octet-stream.
+ *
+ * @param string $mime_type The current mime type
+ * @param string $guess The current mime type guess
+ *
+ * @return string The best mime type based on current mime type and guess
+ */
+ public function choose_mime_type($mime_type, $guess)
+ {
+ if ($guess === null || $guess == 'application/octet-stream')
+ {
+ return $mime_type;
+ }
+
+ if ($mime_type == 'application/octet-stream' || strpos($guess, '/') !== false)
+ {
+ $mime_type = $guess;
+ }
+
+ return $mime_type;
}
}
diff --git a/phpBB/phpbb/mimetype/guesser_base.php b/phpBB/phpbb/mimetype/guesser_base.php
index 082b098028..225dfd57dc 100644
--- a/phpBB/phpbb/mimetype/guesser_base.php
+++ b/phpBB/phpbb/mimetype/guesser_base.php
@@ -1,18 +1,18 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\mimetype;
-/**
-* @package mimetype
-*/
-
abstract class guesser_base implements guesser_interface
{
/**
@@ -21,7 +21,7 @@ abstract class guesser_base implements guesser_interface
protected $priority;
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_priority()
{
@@ -29,7 +29,7 @@ abstract class guesser_base implements guesser_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function set_priority($priority)
{
diff --git a/phpBB/phpbb/mimetype/guesser_interface.php b/phpBB/phpbb/mimetype/guesser_interface.php
index 103689765e..a4005287e4 100644
--- a/phpBB/phpbb/mimetype/guesser_interface.php
+++ b/phpBB/phpbb/mimetype/guesser_interface.php
@@ -1,18 +1,18 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\mimetype;
-/**
-* @package mimetype
-*/
-
interface guesser_interface
{
/**
@@ -26,6 +26,7 @@ interface guesser_interface
* Guess mimetype of supplied file
*
* @param string $file Path to file
+ * @param string $file_name The real file name
*
* @return string Guess for mimetype of file
*/
diff --git a/phpBB/phpbb/notification/exception.php b/phpBB/phpbb/notification/exception.php
index 6bdded3fd8..83c4526df7 100644
--- a/phpBB/phpbb/notification/exception.php
+++ b/phpBB/phpbb/notification/exception.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+* 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.
*
*/
@@ -11,9 +15,8 @@ namespace phpbb\notification;
/**
* Notifications exception
-*
-* @package notifications
*/
+
class exception extends \Exception
{
public function __toString()
diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php
index 2e8652771b..81b450ebbd 100644
--- a/phpBB/phpbb/notification/manager.php
+++ b/phpBB/phpbb/notification/manager.php
@@ -1,17 +1,22 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\notification;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
/**
* Notifications service class
-* @package notifications
*/
class manager
{
@@ -21,7 +26,7 @@ class manager
/** @var array */
protected $notification_methods;
- /** @var ContainerBuilder */
+ /** @var ContainerInterface */
protected $phpbb_container;
/** @var \phpbb\user_loader */
@@ -30,7 +35,7 @@ class manager
/** @var \phpbb\config\config */
protected $config;
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\cache\service */
@@ -59,19 +64,21 @@ class manager
*
* @param array $notification_types
* @param array $notification_methods
- * @param ContainerBuilder $phpbb_container
+ * @param ContainerInterface $phpbb_container
* @param \phpbb\user_loader $user_loader
* @param \phpbb\config\config $config
- * @param \phpbb\db\driver\driver $db
+ * @param \phpbb\db\driver\driver_interface $db
+ * @param \phpbb\cache\service $cache
* @param \phpbb\user $user
* @param string $phpbb_root_path
* @param string $php_ext
* @param string $notification_types_table
* @param string $notifications_table
* @param string $user_notifications_table
+ *
* @return \phpbb\notification\manager
*/
- public function __construct($notification_types, $notification_methods, $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\cache\service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table)
+ public function __construct($notification_types, $notification_methods, ContainerInterface $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table)
{
$this->notification_types = $notification_types;
$this->notification_methods = $notification_methods;
@@ -563,7 +570,7 @@ class manager
{
$subscription_methods[$method_name] = array(
'id' => $method->get_type(),
- 'lang' => 'NOTIFICATION_METHOD_' . strtoupper($method->get_type()),
+ 'lang' => str_replace('.', '_', strtoupper($method->get_type())),
);
}
}
@@ -571,6 +578,34 @@ class manager
return $subscription_methods;
}
+
+ /**
+ * Get user's notification data
+ *
+ * @param int $user_id The user_id of the user to get the notifications for
+ *
+ * @return array User's notification
+ */
+ protected function get_user_notifications($user_id)
+ {
+ $sql = 'SELECT method, notify, item_type
+ FROM ' . $this->user_notifications_table . '
+ WHERE user_id = ' . (int) $user_id . '
+ AND item_id = 0';
+
+ $result = $this->db->sql_query($sql);
+ $user_notifications = array();
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $user_notifications[$row['item_type']][] = $row;
+ }
+
+ $this->db->sql_freeresult($result);
+
+ return $user_notifications;
+ }
+
/**
* Get global subscriptions (item_id = 0)
*
@@ -584,28 +619,23 @@ class manager
$subscriptions = array();
- foreach ($this->get_subscription_types() as $group_name => $types)
+ $user_notifications = $this->get_user_notifications($user_id);
+
+ foreach ($this->get_subscription_types() as $types)
{
foreach ($types as $id => $type)
{
- $sql = 'SELECT method, notify
- FROM ' . $this->user_notifications_table . '
- WHERE user_id = ' . (int) $user_id . "
- AND item_type = '" . $this->db->sql_escape($id) . "'
- AND item_id = 0";
- $result = $this->db->sql_query($sql);
-
- $row = $this->db->sql_fetchrow($result);
- if (!$row)
+
+ if (empty($user_notifications[$id]))
{
// No rows at all, default to ''
$subscriptions[$id] = array('');
}
else
{
- do
+ foreach ($user_notifications[$id] as $user_notification)
{
- if (!$row['notify'])
+ if (!$user_notification['notify'])
{
continue;
}
@@ -615,12 +645,9 @@ class manager
$subscriptions[$id] = array();
}
- $subscriptions[$id][] = $row['method'];
+ $subscriptions[$id][] = $user_notification['method'];
}
- while ($row = $this->db->sql_fetchrow($result));
}
-
- $this->db->sql_freeresult($result);
}
}
@@ -760,17 +787,30 @@ class manager
*/
public function purge_notifications($notification_type_name)
{
- $notification_type_id = $this->get_notification_type_id($notification_type_name);
+ // If a notification is never used, its type will not be added to the database
+ // nor its id cached. If this method is called by an extension during the
+ // purge step, and that extension never used its notifications,
+ // get_notification_type_id() will throw an exception. However,
+ // because no notification type was added to the database,
+ // there is nothing to delete, so we can silently drop the exception.
+ try
+ {
+ $notification_type_id = $this->get_notification_type_id($notification_type_name);
- $sql = 'DELETE FROM ' . $this->notifications_table . '
- WHERE notification_type_id = ' . (int) $notification_type_id;
- $this->db->sql_query($sql);
+ $sql = 'DELETE FROM ' . $this->notifications_table . '
+ WHERE notification_type_id = ' . (int) $notification_type_id;
+ $this->db->sql_query($sql);
- $sql = 'DELETE FROM ' . $this->notification_types_table . '
- WHERE notification_type_id = ' . (int) $notification_type_id;
- $this->db->sql_query($sql);
+ $sql = 'DELETE FROM ' . $this->notification_types_table . '
+ WHERE notification_type_id = ' . (int) $notification_type_id;
+ $this->db->sql_query($sql);
- $this->cache->destroy('notification_type_ids');
+ $this->cache->destroy('notification_type_ids');
+ }
+ catch (\phpbb\notification\exception $e)
+ {
+ // Continue
+ }
}
/**
@@ -794,7 +834,7 @@ class manager
* Delete all notifications older than a certain time
*
* @param int $timestamp Unix timestamp to delete all notifications that were created before
- * @param bool $only_unread True (default) to only prune read notifications
+ * @param bool $only_read True (default) to only prune read notifications
*/
public function prune_notifications($timestamp, $only_read = true)
{
@@ -811,8 +851,6 @@ class manager
*/
public function get_item_type_class($notification_type_name, $data = array())
{
- $notification_type_name = (strpos($notification_type_name, 'notification.type.') === 0) ? $notification_type_name : 'notification.type.' . $notification_type_name;
-
$item = $this->load_object($notification_type_name);
$item->set_initial_data($data);
@@ -825,8 +863,6 @@ class manager
*/
public function get_method_class($method_name)
{
- $method_name = (strpos($method_name, 'notification.method.') === 0) ? $method_name : 'notification.method.' . $method_name;
-
return $this->load_object($method_name);
}
@@ -850,6 +886,7 @@ class manager
*
* @param string $notification_type_name The name
* @return int the notification_type_id
+ * @throws \phpbb\notification\exception
*/
public function get_notification_type_id($notification_type_name)
{
diff --git a/phpBB/phpbb/notification/method/base.php b/phpBB/phpbb/notification/method/base.php
index 4ce42de830..a0bbed6fcd 100644
--- a/phpBB/phpbb/notification/method/base.php
+++ b/phpBB/phpbb/notification/method/base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\notification\method;
/**
* Base notifications method class
-* @package notifications
*/
abstract class base implements \phpbb\notification\method\method_interface
{
@@ -21,7 +24,7 @@ abstract class base implements \phpbb\notification\method\method_interface
/** @var \phpbb\user_loader */
protected $user_loader;
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\cache\driver\driver_interface */
@@ -59,7 +62,7 @@ abstract class base implements \phpbb\notification\method\method_interface
* Notification Method Base Constructor
*
* @param \phpbb\user_loader $user_loader
- * @param \phpbb\db\driver\driver $db
+ * @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\cache\driver\driver_interface $cache
* @param \phpbb\user $user
* @param \phpbb\auth\auth $auth
@@ -68,7 +71,7 @@ abstract class base implements \phpbb\notification\method\method_interface
* @param string $php_ext
* @return \phpbb\notification\method\base
*/
- public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext)
{
$this->user_loader = $user_loader;
$this->db = $db;
diff --git a/phpBB/phpbb/notification/method/email.php b/phpBB/phpbb/notification/method/email.php
index e039fae8de..a4b93bc85c 100644
--- a/phpBB/phpbb/notification/method/email.php
+++ b/phpBB/phpbb/notification/method/email.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\method;
/**
* Email notification method class
* This class handles sending emails for notifications
-*
-* @package notifications
*/
+
class email extends \phpbb\notification\method\messenger_base
{
/**
@@ -24,7 +27,7 @@ class email extends \phpbb\notification\method\messenger_base
*/
public function get_type()
{
- return 'email';
+ return 'notification.method.email';
}
/**
diff --git a/phpBB/phpbb/notification/method/jabber.php b/phpBB/phpbb/notification/method/jabber.php
index bdfaf5a6fc..09f186e3ca 100644
--- a/phpBB/phpbb/notification/method/jabber.php
+++ b/phpBB/phpbb/notification/method/jabber.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\method;
/**
* Jabber notification method class
* This class handles sending Jabber messages for notifications
-*
-* @package notifications
*/
+
class jabber extends \phpbb\notification\method\messenger_base
{
/**
@@ -24,7 +27,7 @@ class jabber extends \phpbb\notification\method\messenger_base
*/
public function get_type()
{
- return 'jabber';
+ return 'notification.method.jabber';
}
/**
diff --git a/phpBB/phpbb/notification/method/messenger_base.php b/phpBB/phpbb/notification/method/messenger_base.php
index 7cb38eb59d..bde4573117 100644
--- a/phpBB/phpbb/notification/method/messenger_base.php
+++ b/phpBB/phpbb/notification/method/messenger_base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,8 +16,6 @@ namespace phpbb\notification\method;
/**
* Abstract notification method handling email and jabber notifications
* using the phpBB messenger.
-*
-* @package notifications
*/
abstract class messenger_base extends \phpbb\notification\method\base
{
diff --git a/phpBB/phpbb/notification/method/method_interface.php b/phpBB/phpbb/notification/method/method_interface.php
index 4830d06b86..76b0de179c 100644
--- a/phpBB/phpbb/notification/method/method_interface.php
+++ b/phpBB/phpbb/notification/method/method_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\notification\method;
/**
* Base notifications method interface
-* @package notifications
*/
interface method_interface
{
diff --git a/phpBB/phpbb/notification/type/admin_activate_user.php b/phpBB/phpbb/notification/type/admin_activate_user.php
index 426da4db03..038ca3726e 100644
--- a/phpBB/phpbb/notification/type/admin_activate_user.php
+++ b/phpBB/phpbb/notification/type/admin_activate_user.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Admin activation notifications class
* This class handles notifications for users requiring admin activation
-*
-* @package notifications
*/
+
class admin_activate_user extends \phpbb\notification\type\base
{
/**
@@ -22,7 +25,7 @@ class admin_activate_user extends \phpbb\notification\type\base
*/
public function get_type()
{
- return 'admin_activate_user';
+ return 'notification.type.admin_activate_user';
}
/**
@@ -142,7 +145,7 @@ class admin_activate_user extends \phpbb\notification\type\base
*/
public function get_url()
{
- return append_sid($this->phpbb_root_path . 'memberlist.' . $this->php_ext, "mode=viewprofile&u={$this->item_id}");
+ return $this->user_loader->get_username($this->item_id, 'profile');
}
/**
diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php
index e51ff12b3e..a9e635b41a 100644
--- a/phpBB/phpbb/notification/type/approve_post.php
+++ b/phpBB/phpbb/notification/type/approve_post.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Post approved notifications class
* This class handles notifications for posts when they are approved (to their authors)
-*
-* @package notifications
*/
+
class approve_post extends \phpbb\notification\type\post
{
/**
@@ -24,7 +27,7 @@ class approve_post extends \phpbb\notification\type\post
*/
public function get_type()
{
- return 'approve_post';
+ return 'notification.type.approve_post';
}
/**
@@ -64,7 +67,8 @@ class approve_post extends \phpbb\notification\type\post
/**
* Find the users who want to receive notifications
*
- * @param array $post Data from
+ * @param array $post Data from submit_post
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -77,14 +81,7 @@ class approve_post extends \phpbb\notification\type\post
$users = array();
$users[$post['poster_id']] = array('');
- $auth_read = $this->auth->acl_get_list(array_keys($users), 'f_read', $post['forum_id']);
-
- if (empty($auth_read))
- {
- return array();
- }
-
- return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array(
+ return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(
'item_type' => self::$notification_option['id'],
)));
}
@@ -138,4 +135,12 @@ class approve_post extends \phpbb\notification\type\post
{
return 'post_approved';
}
+
+ /**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return $this->get_url();
+ }
}
diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php
index 11a240e03d..2f4678359c 100644
--- a/phpBB/phpbb/notification/type/approve_topic.php
+++ b/phpBB/phpbb/notification/type/approve_topic.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Topic approved notifications class
* This class handles notifications for topics when they are approved (for authors)
-*
-* @package notifications
*/
+
class approve_topic extends \phpbb\notification\type\topic
{
/**
@@ -24,7 +27,7 @@ class approve_topic extends \phpbb\notification\type\topic
*/
public function get_type()
{
- return 'approve_topic';
+ return 'notification.type.approve_topic';
}
/**
@@ -64,7 +67,8 @@ class approve_topic extends \phpbb\notification\type\topic
/**
* Find the users who want to receive notifications
*
- * @param array $post Data from
+ * @param array $post Data from submit_post
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -77,14 +81,7 @@ class approve_topic extends \phpbb\notification\type\topic
$users = array();
$users[$post['poster_id']] = array('');
- $auth_read = $this->auth->acl_get_list(array_keys($users), 'f_read', $post['forum_id']);
-
- if (empty($auth_read))
- {
- return array();
- }
-
- return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array(
+ return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(
'item_type' => self::$notification_option['id'],
)));
}
diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php
index 10c876b286..4ead06071e 100644
--- a/phpBB/phpbb/notification/type/base.php
+++ b/phpBB/phpbb/notification/type/base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\notification\type;
/**
* Base notifications class
-* @package notifications
*/
abstract class base implements \phpbb\notification\type\type_interface
{
@@ -21,7 +24,7 @@ abstract class base implements \phpbb\notification\type\type_interface
/** @var \phpbb\user_loader */
protected $user_loader;
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\cache\driver\driver_interface */
@@ -89,7 +92,7 @@ abstract class base implements \phpbb\notification\type\type_interface
* Notification Type Base Constructor
*
* @param \phpbb\user_loader $user_loader
- * @param \phpbb\db\driver\driver $db
+ * @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\cache\driver\driver_interface $cache
* @param \phpbb\user $user
* @param \phpbb\auth\auth $auth
@@ -101,7 +104,7 @@ abstract class base implements \phpbb\notification\type\type_interface
* @param string $user_notifications_table
* @return \phpbb\notification\type\base
*/
- public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table)
+ public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table)
{
$this->user_loader = $user_loader;
$this->db = $db;
@@ -158,6 +161,8 @@ abstract class base implements \phpbb\notification\type\type_interface
* Magic method to set data on this notification
*
* @param mixed $name
+ * @param mixed $value
+ *
* @return null
*/
public function __set($name, $value)
@@ -171,7 +176,6 @@ abstract class base implements \phpbb\notification\type\type_interface
*
* Primarily for testing
*
- * @param string $name
* @return mixed
*/
public function __toString()
@@ -276,6 +280,14 @@ abstract class base implements \phpbb\notification\type\type_interface
}
/**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return $this->get_url();
+ }
+
+ /**
* Prepare to output the notification to the template
*
* @return array Template variables
@@ -297,16 +309,15 @@ abstract class base implements \phpbb\notification\type\type_interface
return array(
'NOTIFICATION_ID' => $this->notification_id,
-
+ 'STYLING' => $this->get_style_class(),
'AVATAR' => $this->get_avatar(),
-
'FORMATTED_TITLE' => $this->get_title(),
-
+ 'REFERENCE' => $this->get_reference(),
+ 'FORUM' => $this->get_forum(),
+ 'REASON' => $this->get_reason(),
'URL' => $this->get_url(),
'TIME' => $this->user->format_date($this->notification_time),
-
'UNREAD' => !$this->notification_read,
-
'U_MARK_READ' => (!$this->notification_read) ? $u_mark_read : '',
);
}
@@ -326,6 +337,16 @@ abstract class base implements \phpbb\notification\type\type_interface
}
/**
+ * Get the CSS style class of the notification (fall back)
+ *
+ * @return string
+ */
+ public function get_style_class()
+ {
+ return '';
+ }
+
+ /**
* Get the user's avatar (fall back)
*
* @return string
@@ -336,6 +357,36 @@ abstract class base implements \phpbb\notification\type\type_interface
}
/**
+ * Get the reference of the notifcation (fall back)
+ *
+ * @return string
+ */
+ public function get_reference()
+ {
+ return '';
+ }
+
+ /**
+ * Get the forum of the notification reference (fall back)
+ *
+ * @return string
+ */
+ public function get_forum()
+ {
+ return '';
+ }
+
+ /**
+ * Get the reason for the notifcation (fall back)
+ *
+ * @return string
+ */
+ public function get_reason()
+ {
+ return '';
+ }
+
+ /**
* Get the special items to load (fall back)
*
* @return array
@@ -482,4 +533,37 @@ abstract class base implements \phpbb\notification\type\type_interface
WHERE ' . $where;
$this->db->sql_query($sql);
}
+
+ /**
+ * Get a list of users that are authorised to receive notifications
+ *
+ * @param array $users Array of users that have subscribed to a notification
+ * @param int $forum_id Forum ID of the forum
+ * @param array $options Array of notification options
+ * @param bool $sort Whether the users array should be sorted. Default: false
+ * @return array Array of users that are authorised recipients
+ */
+ protected function get_authorised_recipients($users, $forum_id, $options, $sort = false)
+ {
+ if (empty($users))
+ {
+ return array();
+ }
+
+ $users = array_unique($users);
+
+ if ($sort)
+ {
+ sort($users);
+ }
+
+ $auth_read = $this->auth->acl_get_list($users, 'f_read', $forum_id);
+
+ if (empty($auth_read))
+ {
+ return array();
+ }
+
+ return $this->check_user_notification_options($auth_read[$forum_id]['f_read'], $options);
+ }
}
diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php
index 003998677d..4f2d34cb60 100644
--- a/phpBB/phpbb/notification/type/bookmark.php
+++ b/phpBB/phpbb/notification/type/bookmark.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Bookmark updating notifications class
* This class handles notifications for replies to a bookmarked topic
-*
-* @package notifications
*/
+
class bookmark extends \phpbb\notification\type\post
{
/**
@@ -24,7 +27,7 @@ class bookmark extends \phpbb\notification\type\post
*/
public function get_type()
{
- return 'bookmark';
+ return 'notification.type.bookmark';
}
/**
@@ -56,7 +59,8 @@ class bookmark extends \phpbb\notification\type\post
/**
* Find the users who want to receive notifications
*
- * @param array $post Data from
+ * @param array $post Data from submit_post
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -79,21 +83,13 @@ class bookmark extends \phpbb\notification\type\post
}
$this->db->sql_freeresult($result);
- if (empty($users))
- {
- return array();
- }
- sort($users);
+ $notify_users = $this->get_authorised_recipients($users, $post['forum_id'], $options, true);
- $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']);
-
- if (empty($auth_read))
+ if (empty($notify_users))
{
return array();
}
- $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options);
-
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$update_notifications = array();
$sql = 'SELECT n.*
@@ -110,10 +106,14 @@ class bookmark extends \phpbb\notification\type\post
unset($notify_users[$row['user_id']]);
$notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
- $sql = 'UPDATE ' . $this->notifications_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . '
- WHERE notification_id = ' . $row['notification_id'];
- $this->db->sql_query($sql);
+ $update_responders = $notification->add_responders($post);
+ if (!empty($update_responders))
+ {
+ $sql = 'UPDATE ' . $this->notifications_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . '
+ WHERE notification_id = ' . $row['notification_id'];
+ $this->db->sql_query($sql);
+ }
}
$this->db->sql_freeresult($result);
diff --git a/phpBB/phpbb/notification/type/disapprove_post.php b/phpBB/phpbb/notification/type/disapprove_post.php
index 70de2a3e10..6c7bcbcaee 100644
--- a/phpBB/phpbb/notification/type/disapprove_post.php
+++ b/phpBB/phpbb/notification/type/disapprove_post.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Post disapproved notifications class
* This class handles notifications for posts when they are disapproved (for authors)
-*
-* @package notifications
*/
+
class disapprove_post extends \phpbb\notification\type\approve_post
{
/**
@@ -24,7 +27,17 @@ class disapprove_post extends \phpbb\notification\type\approve_post
*/
public function get_type()
{
- return 'disapprove_post';
+ return 'notification.type.disapprove_post';
+ }
+
+ /**
+ * Get the CSS style class of the notification
+ *
+ * @return string
+ */
+ public function get_style_class()
+ {
+ return 'notification-disapproved';
}
/**
@@ -60,9 +73,31 @@ class disapprove_post extends \phpbb\notification\type\approve_post
*/
public function get_title()
{
+ return $this->user->lang($this->language_key);
+ }
+
+ /**
+ * Get the HTML formatted reference of the notification
+ *
+ * @return string
+ */
+ public function get_reference()
+ {
+ return $this->user->lang(
+ 'NOTIFICATION_REFERENCE',
+ censor_text($this->get_data('topic_title'))
+ );
+ }
+
+ /**
+ * Get the reason for the disapproval notification
+ *
+ * @return string
+ */
+ public function get_reason()
+ {
return $this->user->lang(
- $this->language_key,
- censor_text($this->get_data('topic_title')),
+ 'NOTIFICATION_REASON',
$this->get_data('disapprove_reason')
);
}
diff --git a/phpBB/phpbb/notification/type/disapprove_topic.php b/phpBB/phpbb/notification/type/disapprove_topic.php
index d39201d928..efa5eb7ecd 100644
--- a/phpBB/phpbb/notification/type/disapprove_topic.php
+++ b/phpBB/phpbb/notification/type/disapprove_topic.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Topic disapproved notifications class
* This class handles notifications for topics when they are disapproved (for authors)
-*
-* @package notifications
*/
+
class disapprove_topic extends \phpbb\notification\type\approve_topic
{
/**
@@ -24,7 +27,17 @@ class disapprove_topic extends \phpbb\notification\type\approve_topic
*/
public function get_type()
{
- return 'disapprove_topic';
+ return 'notification.type.disapprove_topic';
+ }
+
+ /**
+ * Get the CSS style class of the notification
+ *
+ * @return string
+ */
+ public function get_style_class()
+ {
+ return 'notification-disapproved';
}
/**
@@ -60,9 +73,31 @@ class disapprove_topic extends \phpbb\notification\type\approve_topic
*/
public function get_title()
{
+ return $this->user->lang($this->language_key);
+ }
+
+ /**
+ * Get the HTML formatted reference of the notification
+ *
+ * @return string
+ */
+ public function get_reference()
+ {
+ return $this->user->lang(
+ 'NOTIFICATION_REFERENCE',
+ censor_text($this->get_data('topic_title'))
+ );
+ }
+
+ /**
+ * Get the reason for the disapproval notification
+ *
+ * @return string
+ */
+ public function get_reason()
+ {
return $this->user->lang(
- $this->language_key,
- censor_text($this->get_data('topic_title')),
+ 'NOTIFICATION_REASON',
$this->get_data('disapprove_reason')
);
}
diff --git a/phpBB/phpbb/notification/type/group_request.php b/phpBB/phpbb/notification/type/group_request.php
index e0527fe220..4baf516fed 100644
--- a/phpBB/phpbb/notification/type/group_request.php
+++ b/phpBB/phpbb/notification/type/group_request.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -16,7 +20,7 @@ class group_request extends \phpbb\notification\type\base
*/
public function get_type()
{
- return 'group_request';
+ return 'notification.type.group_request';
}
/**
diff --git a/phpBB/phpbb/notification/type/group_request_approved.php b/phpBB/phpbb/notification/type/group_request_approved.php
index 448f049412..d284046ffa 100644
--- a/phpBB/phpbb/notification/type/group_request_approved.php
+++ b/phpBB/phpbb/notification/type/group_request_approved.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -16,7 +20,7 @@ class group_request_approved extends \phpbb\notification\type\base
*/
public function get_type()
{
- return 'group_request_approved';
+ return 'notification.type.group_request_approved';
}
/**
diff --git a/phpBB/phpbb/notification/type/pm.php b/phpBB/phpbb/notification/type/pm.php
index 584a30efa6..330a70c85a 100644
--- a/phpBB/phpbb/notification/type/pm.php
+++ b/phpBB/phpbb/notification/type/pm.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Private message notifications class
* This class handles notifications for private messages
-*
-* @package notifications
*/
+
class pm extends \phpbb\notification\type\base
{
/**
@@ -24,7 +27,7 @@ class pm extends \phpbb\notification\type\base
*/
public function get_type()
{
- return 'pm';
+ return 'notification.type.pm';
}
/**
@@ -69,7 +72,8 @@ class pm extends \phpbb\notification\type\base
/**
* Find the users who want to receive notifications
*
- * @param array $pm Data from
+ * @param array $pm Data from submit_pm
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -108,7 +112,20 @@ class pm extends \phpbb\notification\type\base
{
$username = $this->user_loader->get_username($this->get_data('from_user_id'), 'no_profile');
- return $this->user->lang('NOTIFICATION_PM', $username, $this->get_data('message_subject'));
+ return $this->user->lang('NOTIFICATION_PM', $username);
+ }
+
+ /**
+ * Get the HTML formatted reference of the notification
+ *
+ * @return string
+ */
+ public function get_reference()
+ {
+ return $this->user->lang(
+ 'NOTIFICATION_REFERENCE',
+ $this->get_data('message_subject')
+ );
}
/**
@@ -162,7 +179,7 @@ class pm extends \phpbb\notification\type\base
* Function for preparing the data for insertion in an SQL query
* (The service handles insertion)
*
- * @param array $post Data from submit_post
+ * @param array $pm Data from submit_post
* @param array $pre_create_data Data from pre_create_insert_array()
*
* @return array Array of data ready to be inserted into the database
diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php
index f973becc3b..d9e74f2e95 100644
--- a/phpBB/phpbb/notification/type/post.php
+++ b/phpBB/phpbb/notification/type/post.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Post notifications class
* This class handles notifications for replies to a topic
-*
-* @package notifications
*/
+
class post extends \phpbb\notification\type\base
{
/**
@@ -24,7 +27,7 @@ class post extends \phpbb\notification\type\base
*/
public function get_type()
{
- return 'post';
+ return 'notification.type.post';
}
/**
@@ -83,7 +86,8 @@ class post extends \phpbb\notification\type\base
/**
* Find the users who want to receive notifications
*
- * @param array $post Data from
+ * @param array $post Data from submit_post
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -119,23 +123,13 @@ class post extends \phpbb\notification\type\base
}
$this->db->sql_freeresult($result);
- if (empty($users))
- {
- return array();
- }
-
- $users = array_unique($users);
- sort($users);
-
- $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']);
+ $notify_users = $this->get_authorised_recipients($users, $post['forum_id'], $options, true);
- if (empty($auth_read))
+ if (empty($notify_users))
{
return array();
}
- $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options);
-
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$update_notifications = array();
$sql = 'SELECT n.*
@@ -152,10 +146,14 @@ class post extends \phpbb\notification\type\base
unset($notify_users[$row['user_id']]);
$notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
- $sql = 'UPDATE ' . $this->notifications_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . '
- WHERE notification_id = ' . $row['notification_id'];
- $this->db->sql_query($sql);
+ $update_responders = $notification->add_responders($post);
+ if (!empty($update_responders))
+ {
+ $sql = 'UPDATE ' . $this->notifications_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . '
+ WHERE notification_id = ' . $row['notification_id'];
+ $this->db->sql_query($sql);
+ }
}
$this->db->sql_freeresult($result);
@@ -206,7 +204,11 @@ class post extends \phpbb\notification\type\base
}
}
- if ($trimmed_responders_cnt)
+ if ($trimmed_responders_cnt > 20)
+ {
+ $usernames[] = $this->user->lang('NOTIFICATION_MANY_OTHERS');
+ }
+ else if ($trimmed_responders_cnt)
{
$usernames[] = $this->user->lang('NOTIFICATION_X_OTHERS', $trimmed_responders_cnt);
}
@@ -214,12 +216,24 @@ class post extends \phpbb\notification\type\base
return $this->user->lang(
$this->language_key,
phpbb_generate_string_list($usernames, $this->user),
- censor_text($this->get_data('topic_title')),
$responders_cnt
);
}
/**
+ * Get the HTML formatted reference of the notification
+ *
+ * @return string
+ */
+ public function get_reference()
+ {
+ return $this->user->lang(
+ 'NOTIFICATION_REFERENCE',
+ censor_text($this->get_data('topic_title'))
+ );
+ }
+
+ /**
* Get email template
*
* @return string|bool
@@ -270,6 +284,14 @@ class post extends \phpbb\notification\type\base
}
/**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "t={$this->item_parent_id}&amp;view=unread#unread");
+ }
+
+ /**
* Users needed to query before this notification can be displayed
*
* @return array Array of user_ids
@@ -384,19 +406,27 @@ class post extends \phpbb\notification\type\base
// Do not add them as a responder if they were the original poster that created the notification
if ($this->get_data('poster_id') == $post['poster_id'])
{
- return array('notification_data' => serialize($this->get_data(false)));
+ return array();
}
$responders = $this->get_data('responders');
$responders = ($responders === null) ? array() : $responders;
+ // Do not add more than 25 responders,
+ // we trim the username list to "a, b, c and x others" anyway
+ // so there is no use to add all of them anyway.
+ if (sizeof($responders) > 25)
+ {
+ return array();
+ }
+
foreach ($responders as $responder)
{
// Do not add them as a responder multiple times
if ($responder['poster_id'] == $post['poster_id'])
{
- return array('notification_data' => serialize($this->get_data(false)));
+ return array();
}
}
@@ -407,6 +437,15 @@ class post extends \phpbb\notification\type\base
$this->set_data('responders', $responders);
- return array('notification_data' => serialize($this->get_data(false)));
+ $serialized_data = serialize($this->get_data(false));
+
+ // If the data is longer then 4000 characters, it would cause a SQL error.
+ // We don't add the username to the list if this is the case.
+ if (utf8_strlen($serialized_data) >= 4000)
+ {
+ return array();
+ }
+
+ return array('notification_data' => $serialized_data);
}
}
diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php
index db16763583..315b8b0243 100644
--- a/phpBB/phpbb/notification/type/post_in_queue.php
+++ b/phpBB/phpbb/notification/type/post_in_queue.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Post in queue notifications class
* This class handles notifications for posts that are put in the moderation queue (for moderators)
-*
-* @package notifications
*/
+
class post_in_queue extends \phpbb\notification\type\post
{
/**
@@ -24,7 +27,7 @@ class post_in_queue extends \phpbb\notification\type\post
*/
public function get_type()
{
- return 'post_in_queue';
+ return 'notification.type.post_in_queue';
}
/**
@@ -41,7 +44,7 @@ class post_in_queue extends \phpbb\notification\type\post
* Array of data (including keys 'id', 'lang', and 'group')
*/
public static $notification_option = array(
- 'id' => 'needs_approval',
+ 'id' => 'notification.type.needs_approval',
'lang' => 'NOTIFICATION_TYPE_IN_MODERATION_QUEUE',
'group' => 'NOTIFICATION_GROUP_MODERATION',
);
@@ -67,6 +70,7 @@ class post_in_queue extends \phpbb\notification\type\post
* Find the users who want to receive notifications
*
* @param array $post Data from the post
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -119,6 +123,14 @@ class post_in_queue extends \phpbb\notification\type\post
}
/**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return parent::get_url();
+ }
+
+ /**
* Function for preparing the data for insertion in an SQL query
* (The service handles insertion)
*
diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php
index 745430e114..508ca92fa0 100644
--- a/phpBB/phpbb/notification/type/quote.php
+++ b/phpBB/phpbb/notification/type/quote.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Post quoting notifications class
* This class handles notifying users when they have been quoted in a post
-*
-* @package notifications
*/
+
class quote extends \phpbb\notification\type\post
{
/**
@@ -24,7 +27,7 @@ class quote extends \phpbb\notification\type\post
*/
public function get_type()
{
- return 'quote';
+ return 'notification.type.quote';
}
/**
@@ -63,7 +66,8 @@ class quote extends \phpbb\notification\type\post
/**
* Find the users who want to receive notifications
*
- * @param array $post Data from
+ * @param array $post Data from submit_post
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -98,51 +102,13 @@ class quote extends \phpbb\notification\type\post
}
$this->db->sql_freeresult($result);
- if (empty($users))
- {
- return array();
- }
- sort($users);
-
- $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']);
-
- if (empty($auth_read))
- {
- return array();
- }
-
- $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options);
-
- // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
- $update_notifications = array();
- $sql = 'SELECT n.*
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
- WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
- AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
- AND n.notification_read = 0
- AND nt.notification_type_id = n.notification_type_id
- AND nt.notification_type_enabled = 1';
- $result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
- {
- // Do not create a new notification
- unset($notify_users[$row['user_id']]);
-
- $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
- $sql = 'UPDATE ' . $this->notifications_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . '
- WHERE notification_id = ' . $row['notification_id'];
- $this->db->sql_query($sql);
- }
- $this->db->sql_freeresult($result);
-
- return $notify_users;
+ return $this->get_authorised_recipients($users, $post['forum_id'], $options, true);
}
/**
* Update a notification
*
- * @param array $data Data specific for this type that will be updated
+ * @param array $post Data specific for this type that will be updated
*/
public function update_notifications($post)
{
@@ -191,6 +157,14 @@ class quote extends \phpbb\notification\type\post
}
/**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return $this->get_url();
+ }
+
+ /**
* Get email template
*
* @return string|bool
diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php
index 55f6bf946d..d39143f4b7 100644
--- a/phpBB/phpbb/notification/type/report_pm.php
+++ b/phpBB/phpbb/notification/type/report_pm.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Private message reported notifications class
* This class handles notifications for private messages when they are reported
-*
-* @package notifications
*/
+
class report_pm extends \phpbb\notification\type\pm
{
/**
@@ -24,7 +27,17 @@ class report_pm extends \phpbb\notification\type\pm
*/
public function get_type()
{
- return 'report_pm';
+ return 'notification.type.report_pm';
+ }
+
+ /**
+ * Get the CSS style class of the notification
+ *
+ * @return string
+ */
+ public function get_style_class()
+ {
+ return 'notification-reported';
}
/**
@@ -48,7 +61,7 @@ class report_pm extends \phpbb\notification\type\pm
* Array of data (including keys 'id', 'lang', and 'group')
*/
public static $notification_option = array(
- 'id' => 'report',
+ 'id' => 'notification.type.report',
'lang' => 'NOTIFICATION_TYPE_REPORT',
'group' => 'NOTIFICATION_GROUP_MODERATION',
);
@@ -81,6 +94,7 @@ class report_pm extends \phpbb\notification\type\pm
* (copied from post_in_queue)
*
* @param array $post Data from the post
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -156,12 +170,36 @@ class report_pm extends \phpbb\notification\type\pm
$username = $this->user_loader->get_username($this->get_data('reporter_id'), 'no_profile');
+ return $this->user->lang(
+ $this->language_key,
+ $username
+ );
+ }
+
+ /**
+ * Get the HTML formatted reference of the notification
+ *
+ * @return string
+ */
+ public function get_reference()
+ {
+ return $this->user->lang(
+ 'NOTIFICATION_REFERENCE',
+ censor_text($this->get_data('message_subject'))
+ );
+ }
+
+ /**
+ * Get the reason for the notification
+ *
+ * @return string
+ */
+ public function get_reason()
+ {
if ($this->get_data('report_text'))
{
return $this->user->lang(
- $this->language_key,
- $username,
- censor_text($this->get_data('message_subject')),
+ 'NOTIFICATION_REASON',
$this->get_data('report_text')
);
}
@@ -169,17 +207,13 @@ class report_pm extends \phpbb\notification\type\pm
if (isset($this->user->lang[$this->get_data('reason_title')]))
{
return $this->user->lang(
- $this->language_key,
- $username,
- censor_text($this->get_data('message_subject')),
+ 'NOTIFICATION_REASON',
$this->user->lang[$this->get_data('reason_title')]
);
}
return $this->user->lang(
- $this->language_key,
- $username,
- censor_text($this->get_data('message_subject')),
+ 'NOTIFICATION_REASON',
$this->get_data('reason_description')
);
}
diff --git a/phpBB/phpbb/notification/type/report_pm_closed.php b/phpBB/phpbb/notification/type/report_pm_closed.php
index 56485f5d37..9f301ee2cc 100644
--- a/phpBB/phpbb/notification/type/report_pm_closed.php
+++ b/phpBB/phpbb/notification/type/report_pm_closed.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* PM report closed notifications class
* This class handles notifications for when reports are closed on PMs (for the one who reported the PM)
-*
-* @package notifications
*/
+
class report_pm_closed extends \phpbb\notification\type\pm
{
/**
@@ -24,7 +27,7 @@ class report_pm_closed extends \phpbb\notification\type\pm
*/
public function get_type()
{
- return 'report_pm_closed';
+ return 'notification.type.report_pm_closed';
}
/**
@@ -49,7 +52,8 @@ class report_pm_closed extends \phpbb\notification\type\pm
/**
* Find the users who want to receive notifications
*
- * @param array $pm Data from
+ * @param array $pm Data from submit_pm
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -104,7 +108,19 @@ class report_pm_closed extends \phpbb\notification\type\pm
return $this->user->lang(
$this->language_key,
- $username,
+ $username
+ );
+ }
+
+ /**
+ * Get the HTML formatted reference of the notification
+ *
+ * @return string
+ */
+ public function get_reference()
+ {
+ return $this->user->lang(
+ 'NOTIFICATION_REFERENCE',
censor_text($this->get_data('message_subject'))
);
}
diff --git a/phpBB/phpbb/notification/type/report_post.php b/phpBB/phpbb/notification/type/report_post.php
index 9bf035b91e..027cca716b 100644
--- a/phpBB/phpbb/notification/type/report_post.php
+++ b/phpBB/phpbb/notification/type/report_post.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,8 +16,6 @@ namespace phpbb\notification\type;
/**
* Reported post notifications class
* This class handles notifications for reported posts
-*
-* @package notifications
*/
class report_post extends \phpbb\notification\type\post_in_queue
{
@@ -24,7 +26,17 @@ class report_post extends \phpbb\notification\type\post_in_queue
*/
public function get_type()
{
- return 'report_post';
+ return 'notification.type.report_post';
+ }
+
+ /**
+ * Get the CSS style class of the notification
+ *
+ * @return string
+ */
+ public function get_style_class()
+ {
+ return 'notification-reported';
}
/**
@@ -55,7 +67,7 @@ class report_post extends \phpbb\notification\type\post_in_queue
* Array of data (including keys 'id' and 'lang')
*/
public static $notification_option = array(
- 'id' => 'report',
+ 'id' => 'notification.type.report',
'lang' => 'NOTIFICATION_TYPE_REPORT',
'group' => 'NOTIFICATION_GROUP_MODERATION',
);
@@ -64,6 +76,7 @@ class report_post extends \phpbb\notification\type\post_in_queue
* Find the users who want to receive notifications
*
* @param array $post Data from the post
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -130,12 +143,36 @@ class report_post extends \phpbb\notification\type\post_in_queue
$username = $this->user_loader->get_username($this->get_data('reporter_id'), 'no_profile');
+ return $this->user->lang(
+ $this->language_key,
+ $username
+ );
+ }
+
+ /**
+ * Get the HTML formatted reference of the notification
+ *
+ * @return string
+ */
+ public function get_reference()
+ {
+ return $this->user->lang(
+ 'NOTIFICATION_REFERENCE',
+ censor_text($this->get_data('post_subject'))
+ );
+ }
+
+ /**
+ * Get the reason for the notification
+ *
+ * @return string
+ */
+ public function get_reason()
+ {
if ($this->get_data('report_text'))
{
return $this->user->lang(
- $this->language_key,
- $username,
- censor_text($this->get_data('post_subject')),
+ 'NOTIFICATION_REASON',
$this->get_data('report_text')
);
}
@@ -143,17 +180,13 @@ class report_post extends \phpbb\notification\type\post_in_queue
if (isset($this->user->lang[$this->get_data('reason_title')]))
{
return $this->user->lang(
- $this->language_key,
- $username,
- censor_text($this->get_data('post_subject')),
+ 'NOTIFICATION_REASON',
$this->user->lang[$this->get_data('reason_title')]
);
}
return $this->user->lang(
- $this->language_key,
- $username,
- censor_text($this->get_data('post_subject')),
+ 'NOTIFICATION_REASON',
$this->get_data('reason_description')
);
}
diff --git a/phpBB/phpbb/notification/type/report_post_closed.php b/phpBB/phpbb/notification/type/report_post_closed.php
index fff45612b3..a0bb187a0d 100644
--- a/phpBB/phpbb/notification/type/report_post_closed.php
+++ b/phpBB/phpbb/notification/type/report_post_closed.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Post report closed notifications class
* This class handles notifications for when reports are closed on posts (for the one who reported the post)
-*
-* @package notifications
*/
+
class report_post_closed extends \phpbb\notification\type\post
{
/**
@@ -24,7 +27,7 @@ class report_post_closed extends \phpbb\notification\type\post
*/
public function get_type()
{
- return 'report_post_closed';
+ return 'notification.type.report_post_closed';
}
/**
@@ -56,7 +59,8 @@ class report_post_closed extends \phpbb\notification\type\post
/**
* Find the users who want to receive notifications
*
- * @param array $post Data from
+ * @param array $post Data from submit_post
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -111,7 +115,19 @@ class report_post_closed extends \phpbb\notification\type\post
return $this->user->lang(
$this->language_key,
- $username,
+ $username
+ );
+ }
+
+ /**
+ * Get the HTML formatted reference of the notification
+ *
+ * @return string
+ */
+ public function get_reference()
+ {
+ return $this->user->lang(
+ 'NOTIFICATION_REFERENCE',
censor_text($this->get_data('post_subject'))
);
}
diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php
index 635d05bccd..cf0ec77099 100644
--- a/phpBB/phpbb/notification/type/topic.php
+++ b/phpBB/phpbb/notification/type/topic.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Topic notifications class
* This class handles notifications for new topics
-*
-* @package notifications
*/
+
class topic extends \phpbb\notification\type\base
{
/**
@@ -24,7 +27,7 @@ class topic extends \phpbb\notification\type\base
*/
public function get_type()
{
- return 'topic';
+ return 'notification.type.topic';
}
/**
@@ -84,6 +87,7 @@ class topic extends \phpbb\notification\type\base
* Find the users who want to receive notifications
*
* @param array $topic Data from the topic
+ * @param array $options Options for finding users for notification
*
* @return array
*/
@@ -107,19 +111,7 @@ class topic extends \phpbb\notification\type\base
}
$this->db->sql_freeresult($result);
- if (empty($users))
- {
- return array();
- }
-
- $auth_read = $this->auth->acl_get_list($users, 'f_read', $topic['forum_id']);
-
- if (empty($auth_read))
- {
- return array();
- }
-
- return $this->check_user_notification_options($auth_read[$topic['forum_id']]['f_read'], $options);
+ return $this->get_authorised_recipients($users, $topic['forum_id'], $options);
}
/**
@@ -148,8 +140,32 @@ class topic extends \phpbb\notification\type\base
return $this->user->lang(
$this->language_key,
- $username,
- censor_text($this->get_data('topic_title')),
+ $username
+ );
+ }
+
+ /**
+ * Get the HTML formatted reference of the notification
+ *
+ * @return string
+ */
+ public function get_reference()
+ {
+ return $this->user->lang(
+ 'NOTIFICATION_REFERENCE',
+ censor_text($this->get_data('topic_title'))
+ );
+ }
+
+ /**
+ * Get the forum of the notification reference
+ *
+ * @return string
+ */
+ public function get_forum()
+ {
+ return $this->user->lang(
+ 'NOTIFICATION_FORUM',
$this->get_data('forum_name')
);
}
diff --git a/phpBB/phpbb/notification/type/topic_in_queue.php b/phpBB/phpbb/notification/type/topic_in_queue.php
index c8c1b5b7e2..4c60c6b858 100644
--- a/phpBB/phpbb/notification/type/topic_in_queue.php
+++ b/phpBB/phpbb/notification/type/topic_in_queue.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,9 +16,8 @@ namespace phpbb\notification\type;
/**
* Topic in queue notifications class
* This class handles notifications for topics when they are put in the moderation queue (for moderators)
-*
-* @package notifications
*/
+
class topic_in_queue extends \phpbb\notification\type\topic
{
/**
@@ -24,7 +27,7 @@ class topic_in_queue extends \phpbb\notification\type\topic
*/
public function get_type()
{
- return 'topic_in_queue';
+ return 'notification.type.topic_in_queue';
}
/**
@@ -41,7 +44,7 @@ class topic_in_queue extends \phpbb\notification\type\topic
* Array of data (including keys 'id', 'lang', and 'group')
*/
public static $notification_option = array(
- 'id' => 'needs_approval',
+ 'id' => 'notification.type.needs_approval',
'lang' => 'NOTIFICATION_TYPE_IN_MODERATION_QUEUE',
'group' => 'NOTIFICATION_GROUP_MODERATION',
);
@@ -67,6 +70,7 @@ class topic_in_queue extends \phpbb\notification\type\topic
* Find the users who want to receive notifications
*
* @param array $topic Data from the topic
+ * @param array $options Options for finding users for notification
*
* @return array
*/
diff --git a/phpBB/phpbb/notification/type/type_interface.php b/phpBB/phpbb/notification/type/type_interface.php
index e3e6898172..5c5a110836 100644
--- a/phpBB/phpbb/notification/type/type_interface.php
+++ b/phpBB/phpbb/notification/type/type_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package notifications
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\notification\type;
/**
* Base notifications interface
-* @package notifications
*/
interface type_interface
{
@@ -85,6 +88,13 @@ interface type_interface
public function load_special($data, $notifications);
/**
+ * Get the CSS style class of the notification
+ *
+ * @return string
+ */
+ public function get_style_class();
+
+ /**
* Get the HTML formatted title of this notification
*
* @return string
@@ -92,6 +102,20 @@ interface type_interface
public function get_title();
/**
+ * Get the HTML formatted reference of the notification
+ *
+ * @return string
+ */
+ public function get_reference();
+
+ /**
+ * Get the forum of the notification reference
+ *
+ * @return string
+ */
+ public function get_forum();
+
+ /**
* Get the url to this item
*
* @return string URL
@@ -99,6 +123,13 @@ interface type_interface
public function get_url();
/**
+ * Get the url to redirect after the item has been marked as read
+ *
+ * @return string URL
+ */
+ public function get_redirect_url();
+
+ /**
* URL to unsubscribe to this notification
*
* @param string|bool $method Method name to unsubscribe from (email|jabber|etc), False to unsubscribe from all notifications for this item
diff --git a/phpBB/phpbb/pagination.php b/phpBB/phpbb/pagination.php
index 6a7631c89d..7a81c25ad2 100644
--- a/phpBB/phpbb/pagination.php
+++ b/phpBB/phpbb/pagination.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpbb
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -17,18 +21,26 @@ class pagination
/** @var \phpbb\user */
protected $user;
+ /** @var \phpbb\controller\helper */
+ protected $helper;
+
+ /** @var \phpbb\event\dispatcher_interface */
+ protected $phpbb_dispatcher;
+
/**
* Constructor
*
- * @param \phpbb\template\template $template
- * @param \phpbb\user $user
- * @param \phpbb\controller\helper $helper
+ * @param \phpbb\template\template $template
+ * @param \phpbb\user $user
+ * @param \phpbb\controller\helper $helper
+ * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher
*/
- public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\controller\helper $helper)
+ public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\controller\helper $helper, \phpbb\event\dispatcher_interface $phpbb_dispatcher)
{
$this->template = $template;
$this->user = $user;
$this->helper = $helper;
+ $this->phpbb_dispatcher = $phpbb_dispatcher;
}
/**
@@ -42,10 +54,40 @@ class pagination
* If you use page numbers inside your controller route, start name should be the string
* that should be removed for the first page (example: /page/%d)
* @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce
- * @return URL for the requested page
+ * @return string URL for the requested page
*/
protected function generate_page_link($base_url, $on_page, $start_name, $per_page)
{
+ // A listener can set this variable to the new pagination URL
+ // to override the generate_page_link() function generated value
+ $generate_page_link_override = false;
+
+ /**
+ * Execute code and/or override generate_page_link()
+ *
+ * To override the generate_page_link() function generated value
+ * set $generate_page_link_override to the new URL value
+ *
+ * @event core.pagination_generate_page_link
+ * @var string base_url is url prepended to all links generated within the function
+ * If you use page numbers inside your controller route, base_url should contains a placeholder (%d)
+ * for the page. Also be sure to specify the pagination path information into the start_name argument
+ * @var string on_page is the page for which we want to generate the link
+ * @var string start_name is the name of the parameter containing the first item of the given page (example: start=20)
+ * If you use page numbers inside your controller route, start name should be the string
+ * that should be removed for the first page (example: /page/%d)
+ * @var int per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce
+ * @var bool|string generate_page_link_override Shall we return custom pagination link (string URL) or not (false)
+ * @since 3.1.0-RC5
+ */
+ $vars = array('base_url', 'on_page', 'start_name', 'per_page', 'generate_page_link_override');
+ extract($this->phpbb_dispatcher->trigger_event('core.pagination_generate_page_link', compact($vars)));
+
+ if ($generate_page_link_override)
+ {
+ return $generate_page_link_override;
+ }
+
if (!is_string($base_url))
{
if (is_array($base_url['routes']))
@@ -122,8 +164,8 @@ class pagination
// determine this number. Again at most five pages? Then just display them all. More than
// five and we first (min) determine whether we'd end up listing more pages than exist.
// We then (max) ensure we're displaying the minimum number of pages.
- $start_page = ($total_pages > 5) ? min(max(1, $on_page - 3), $total_pages - 4) : 1;
- $end_page = ($total_pages > 5) ? max(min($total_pages, $on_page + 3), 5) : $total_pages;
+ $start_page = ($total_pages > 5) ? min(max(1, $on_page - 2), $total_pages - 4) : 1;
+ $end_page = ($total_pages > 5) ? max(min($total_pages, $on_page + 2), 5) : $total_pages;
}
if ($on_page != 1)
diff --git a/phpBB/phpbb/passwords/driver/base.php b/phpBB/phpbb/passwords/driver/base.php
index 8256fd721c..fd07a61bf4 100644
--- a/phpBB/phpbb/passwords/driver/base.php
+++ b/phpBB/phpbb/passwords/driver/base.php
@@ -1,23 +1,24 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\passwords\driver;
-/**
-* @package passwords
-*/
abstract class base implements driver_interface
{
- /** @var phpbb\config\config */
+ /** @var \phpbb\config\config */
protected $config;
- /** @var phpbb\passwords\driver\helper */
+ /** @var \phpbb\passwords\driver\helper */
protected $helper;
/** @var driver name */
@@ -36,10 +37,26 @@ abstract class base implements driver_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function is_supported()
{
return true;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_legacy()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_settings_only($hash, $full = false)
+ {
+ return false;
+ }
}
diff --git a/phpBB/phpbb/passwords/driver/bcrypt.php b/phpBB/phpbb/passwords/driver/bcrypt.php
index 1d1b1e267d..eab1c3d569 100644
--- a/phpBB/phpbb/passwords/driver/bcrypt.php
+++ b/phpBB/phpbb/passwords/driver/bcrypt.php
@@ -1,23 +1,24 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\passwords\driver;
-/**
-* @package passwords
-*/
class bcrypt extends base
{
const PREFIX = '$2a$';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_prefix()
{
@@ -25,7 +26,7 @@ class bcrypt extends base
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function hash($password, $salt = '')
{
@@ -57,9 +58,9 @@ class bcrypt extends base
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function check($password, $hash)
+ public function check($password, $hash, $user_row = array())
{
$salt = substr($hash, 0, 29);
if (strlen($salt) != 29)
@@ -67,7 +68,7 @@ class bcrypt extends base
return false;
}
- if ($hash == $this->hash($password, $salt))
+ if ($this->helper->string_compare($hash, $this->hash($password, $salt)))
{
return true;
}
@@ -85,7 +86,7 @@ class bcrypt extends base
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_settings_only($hash, $full = false)
{
diff --git a/phpBB/phpbb/passwords/driver/bcrypt_2y.php b/phpBB/phpbb/passwords/driver/bcrypt_2y.php
index 11c3617e49..c710e0d04a 100644
--- a/phpBB/phpbb/passwords/driver/bcrypt_2y.php
+++ b/phpBB/phpbb/passwords/driver/bcrypt_2y.php
@@ -1,23 +1,24 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\passwords\driver;
-/**
-* @package passwords
-*/
class bcrypt_2y extends bcrypt
{
const PREFIX = '$2y$';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_prefix()
{
@@ -25,7 +26,7 @@ class bcrypt_2y extends bcrypt
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function is_supported()
{
diff --git a/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php b/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php
new file mode 100644
index 0000000000..0eee98d7b7
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/bcrypt_wcf2.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.
+*
+*/
+
+namespace phpbb\passwords\driver;
+
+class bcrypt_wcf2 extends base
+{
+ const PREFIX = '$wcf2$';
+
+ /** @var \phpbb\passwords\driver\bcrypt */
+ protected $bcrypt;
+
+ /** @var \phpbb\passwords\driver\helper */
+ protected $helper;
+
+ /**
+ * Constructor of passwords driver object
+ *
+ * @param \phpbb\passwords\driver\bcrypt $bcrypt Salted md5 driver
+ * @param \phpbb\passwords\driver\helper $helper Password driver helper
+ */
+ public function __construct(\phpbb\passwords\driver\bcrypt $bcrypt, helper $helper)
+ {
+ $this->bcrypt = $bcrypt;
+ $this->helper = $helper;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return self::PREFIX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_legacy()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hash($password, $user_row = '')
+ {
+ // Do not support hashing
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check($password, $hash, $user_row = array())
+ {
+ if (empty($hash) || strlen($hash) != 60)
+ {
+ return false;
+ }
+ else
+ {
+ $salt = substr($hash, 0, 29);
+
+ if (strlen($salt) != 29)
+ {
+ return false;
+ }
+ // Works for standard WCF 2.x, i.e. WBB4 and similar
+ return $this->helper->string_compare($hash, $this->bcrypt->hash($this->bcrypt->hash($password, $salt), $salt));
+ }
+ }
+}
diff --git a/phpBB/phpbb/passwords/driver/convert_password.php b/phpBB/phpbb/passwords/driver/convert_password.php
new file mode 100644
index 0000000000..eb70434df2
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/convert_password.php
@@ -0,0 +1,43 @@
+<?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\passwords\driver;
+
+class convert_password extends base
+{
+ const PREFIX = '$CP$';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return self::PREFIX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hash($password, $user_row = '')
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check($password, $hash, $user_row = array())
+ {
+ return false;
+ }
+}
diff --git a/phpBB/phpbb/passwords/driver/driver_interface.php b/phpBB/phpbb/passwords/driver/driver_interface.php
index ebaf0626af..3974484f13 100644
--- a/phpBB/phpbb/passwords/driver/driver_interface.php
+++ b/phpBB/phpbb/passwords/driver/driver_interface.php
@@ -1,17 +1,18 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\passwords\driver;
-/**
-* @package passwords
-*/
interface driver_interface
{
/**
@@ -22,6 +23,13 @@ interface driver_interface
public function is_supported();
/**
+ * Check if hash type is a legacy hash type
+ *
+ * @return bool True if it's a legacy hash type, false if not
+ */
+ public function is_legacy();
+
+ /**
* Returns the hash prefix
*
* @return string Hash prefix
@@ -43,10 +51,11 @@ interface driver_interface
*
* @param string $password The password to check
* @param string $hash The password hash to check against
+ * @param array $user_row User's row in users table
*
* @return bool True if password is correct, else false
*/
- public function check($password, $hash);
+ public function check($password, $hash, $user_row = array());
/**
* Get only the settings of the specified hash
diff --git a/phpBB/phpbb/passwords/driver/helper.php b/phpBB/phpbb/passwords/driver/helper.php
index 4b8dc9a123..caa65080ac 100644
--- a/phpBB/phpbb/passwords/driver/helper.php
+++ b/phpBB/phpbb/passwords/driver/helper.php
@@ -1,21 +1,22 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\passwords\driver;
-/**
-* @package passwords
-*/
class helper
{
/**
- * @var phpbb\config\config
+ * @var \phpbb\config\config
*/
protected $config;
@@ -28,7 +29,7 @@ class helper
/**
* Construct a driver helper object
*
- * @param phpbb\config\config $config phpBB configuration
+ * @param \phpbb\config\config $config phpBB configuration
*/
public function __construct(\phpbb\config\config $config)
{
@@ -141,4 +142,24 @@ class helper
}
return $random;
}
+
+ /**
+ * Compare two strings byte by byte
+ *
+ * @param string $string_a The first string
+ * @param string $string_b The second string
+ *
+ * @return bool True if strings are the same, false if not
+ */
+ public function string_compare($string_a, $string_b)
+ {
+ $difference = strlen($string_a) != strlen($string_b);
+
+ for ($i = 0; $i < strlen($string_a) && $i < strlen($string_b); $i++)
+ {
+ $difference |= $string_a[$i] != $string_b[$i];
+ }
+
+ return $difference === 0;
+ }
}
diff --git a/phpBB/phpbb/passwords/driver/md5_mybb.php b/phpBB/phpbb/passwords/driver/md5_mybb.php
new file mode 100644
index 0000000000..f631ceae78
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/md5_mybb.php
@@ -0,0 +1,60 @@
+<?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\passwords\driver;
+
+class md5_mybb extends base
+{
+ const PREFIX = '$md5_mybb$';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return self::PREFIX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_legacy()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hash($password, $user_row = '')
+ {
+ // Do not support hashing
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check($password, $hash, $user_row = array())
+ {
+ if (empty($hash) || strlen($hash) != 32 || !isset($user_row['user_passwd_salt']))
+ {
+ return false;
+ }
+ else
+ {
+ // Works for myBB 1.1.x, 1.2.x, 1.4.x, 1.6.x
+ return $this->helper->string_compare($hash, md5(md5($user_row['user_passwd_salt']) . md5($password)));
+ }
+ }
+}
diff --git a/phpBB/phpbb/passwords/driver/md5_phpbb2.php b/phpBB/phpbb/passwords/driver/md5_phpbb2.php
new file mode 100644
index 0000000000..bd8cc51e5a
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/md5_phpbb2.php
@@ -0,0 +1,123 @@
+<?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\passwords\driver;
+
+class md5_phpbb2 extends base
+{
+ const PREFIX = '$md5_phpbb2$';
+
+ /** @var \phpbb\request\request phpBB request object */
+ protected $request;
+
+ /** @var \phpbb\passwords\driver\salted_md5 */
+ protected $salted_md5;
+
+ /** @var \phpbb\passwords\driver\helper */
+ protected $helper;
+
+ /** @var string phpBB root path */
+ protected $phpbb_root_path;
+
+ /** @var string php file extension */
+ protected $php_ext;
+
+ /**
+ * Constructor of passwords driver object
+ *
+ * @param \phpbb\request\request $request phpBB request object
+ * @param \phpbb\passwords\driver\salted_md5 $salted_md5 Salted md5 driver
+ * @param \phpbb\passwords\driver\helper $helper Driver helper
+ * @param string $phpbb_root_path phpBB root path
+ * @param string $php_ext PHP file extension
+ */
+ public function __construct($request, salted_md5 $salted_md5, helper $helper, $phpbb_root_path, $php_ext)
+ {
+ $this->request = $request;
+ $this->salted_md5 = $salted_md5;
+ $this->helper = $helper;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return self::PREFIX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_legacy()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hash($password, $user_row = '')
+ {
+ // Do not support hashing
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check($password, $hash, $user_row = array())
+ {
+ if (strlen($hash) != 32 && strlen($hash) != 34)
+ {
+ return false;
+ }
+
+ // enable super globals to get literal value
+ // this is needed to prevent unicode normalization
+ $super_globals_disabled = $this->request->super_globals_disabled();
+ if ($super_globals_disabled)
+ {
+ $this->request->enable_super_globals();
+ }
+
+ // in phpBB2 passwords were used exactly as they were sent, with addslashes applied
+ $password_old_format = isset($_REQUEST['password']) ? (string) $_REQUEST['password'] : '';
+ $password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format;
+ $password_new_format = $this->request->variable('password', '', true);
+
+ if ($super_globals_disabled)
+ {
+ $this->request->disable_super_globals();
+ }
+
+ if ($password == $password_new_format)
+ {
+ if (!function_exists('utf8_to_cp1252'))
+ {
+ include($this->phpbb_root_path . 'includes/utf/data/recode_basic.' . $this->php_ext);
+ }
+
+ if ($this->helper->string_compare(md5($password_old_format), $hash) || $this->helper->string_compare(md5(\utf8_to_cp1252($password_old_format)), $hash)
+ || $this->salted_md5->check(md5($password_old_format), $hash) === true
+ || $this->salted_md5->check(md5(\utf8_to_cp1252($password_old_format)), $hash) === true)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/phpBB/phpbb/passwords/driver/md5_vb.php b/phpBB/phpbb/passwords/driver/md5_vb.php
new file mode 100644
index 0000000000..280b7114c7
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/md5_vb.php
@@ -0,0 +1,60 @@
+<?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\passwords\driver;
+
+class md5_vb extends base
+{
+ const PREFIX = '$md5_vb$';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return self::PREFIX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_legacy()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hash($password, $user_row = '')
+ {
+ // Do not support hashing
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check($password, $hash, $user_row = array())
+ {
+ if (empty($hash) || strlen($hash) != 32 || !isset($user_row['user_passwd_salt']))
+ {
+ return false;
+ }
+ else
+ {
+ // Works for vB 3.8.x, 4.x.x, 5.0.x
+ return $this->helper->string_compare($hash, md5(md5($password) . $user_row['user_passwd_salt']));
+ }
+ }
+}
diff --git a/phpBB/phpbb/passwords/driver/phpass.php b/phpBB/phpbb/passwords/driver/phpass.php
index 80c4d7a7f0..bef8355276 100644
--- a/phpBB/phpbb/passwords/driver/phpass.php
+++ b/phpBB/phpbb/passwords/driver/phpass.php
@@ -1,23 +1,24 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\passwords\driver;
-/**
-* @package passwords
-*/
class phpass extends salted_md5
{
const PREFIX = '$P$';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_prefix()
{
diff --git a/phpBB/phpbb/passwords/driver/salted_md5.php b/phpBB/phpbb/passwords/driver/salted_md5.php
index 5c72726422..81ac010785 100644
--- a/phpBB/phpbb/passwords/driver/salted_md5.php
+++ b/phpBB/phpbb/passwords/driver/salted_md5.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -37,15 +41,12 @@ namespace phpbb\passwords\driver;
*
*/
-/**
-* @package passwords
-*/
class salted_md5 extends base
{
const PREFIX = '$H$';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_prefix()
{
@@ -53,7 +54,15 @@ class salted_md5 extends base
}
/**
- * @inheritdoc
+ * {@inheritdoc}
+ */
+ public function is_legacy()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
*/
public function hash($password, $setting = '')
{
@@ -89,16 +98,16 @@ class salted_md5 extends base
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function check($password, $hash)
+ public function check($password, $hash, $user_row = array())
{
if (strlen($hash) !== 34)
{
return md5($password) === $hash;
}
- return $hash === $this->hash($password, $hash);
+ return $this->helper->string_compare($hash, $this->hash($password, $hash));
}
/**
@@ -151,7 +160,7 @@ class salted_md5 extends base
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_settings_only($hash, $full = false)
{
diff --git a/phpBB/phpbb/passwords/driver/sha1.php b/phpBB/phpbb/passwords/driver/sha1.php
new file mode 100644
index 0000000000..1abead42cd
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/sha1.php
@@ -0,0 +1,52 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\passwords\driver;
+
+class sha1 extends base
+{
+ const PREFIX = '$sha1$';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return self::PREFIX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_legacy()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hash($password, $user_row = '')
+ {
+ // Do not support hashing
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check($password, $hash, $user_row = array())
+ {
+ return (strlen($hash) == 40) ? $this->helper->string_compare($hash, sha1($password)) : false;
+ }
+}
diff --git a/phpBB/phpbb/passwords/driver/sha1_smf.php b/phpBB/phpbb/passwords/driver/sha1_smf.php
new file mode 100644
index 0000000000..b30d87265e
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/sha1_smf.php
@@ -0,0 +1,51 @@
+<?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\passwords\driver;
+
+class sha1_smf extends base
+{
+ const PREFIX = '$smf$';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return self::PREFIX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_legacy()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hash($password, $user_row = '')
+ {
+ return (isset($user_row['login_name'])) ? sha1(strtolower($user_row['login_name']) . $password) : false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check($password, $hash, $user_row = array())
+ {
+ return (strlen($hash) == 40) ? $this->helper->string_compare($hash, $this->hash($password, $user_row)) : false;
+ }
+}
diff --git a/phpBB/phpbb/passwords/driver/sha1_wcf1.php b/phpBB/phpbb/passwords/driver/sha1_wcf1.php
new file mode 100644
index 0000000000..68006486c4
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/sha1_wcf1.php
@@ -0,0 +1,60 @@
+<?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\passwords\driver;
+
+class sha1_wcf1 extends base
+{
+ const PREFIX = '$wcf1$';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return self::PREFIX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_legacy()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hash($password, $user_row = '')
+ {
+ // Do not support hashing
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check($password, $hash, $user_row = array())
+ {
+ if (empty($hash) || strlen($hash) != 40 || !isset($user_row['user_passwd_salt']))
+ {
+ return false;
+ }
+ else
+ {
+ // Works for standard WCF 1.x, i.e. WBB3 and similar
+ return $this->helper->string_compare($hash, sha1($user_row['user_passwd_salt'] . sha1($user_row['user_passwd_salt'] . sha1($password))));
+ }
+ }
+}
diff --git a/phpBB/phpbb/passwords/driver/sha_xf1.php b/phpBB/phpbb/passwords/driver/sha_xf1.php
new file mode 100644
index 0000000000..9d8f01796e
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/sha_xf1.php
@@ -0,0 +1,68 @@
+<?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\passwords\driver;
+
+class sha_xf1 extends base
+{
+ const PREFIX = '$xf1$';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return self::PREFIX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_legacy()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hash($password, $user_row = '')
+ {
+ // Do not support hashing
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check($password, $hash, $user_row = array())
+ {
+ if (empty($hash) || (strlen($hash) != 40 && strlen($hash) != 64) || !isset($user_row['user_passwd_salt']))
+ {
+ return false;
+ }
+ else
+ {
+ // Works for xenforo 1.0, 1.1
+ if ($this->helper->string_compare($hash, sha1(sha1($password) . $user_row['user_passwd_salt']))
+ || $this->helper->string_compare($hash, hash('sha256', hash('sha256', $password) . $user_row['user_passwd_salt'])))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+}
diff --git a/phpBB/phpbb/passwords/helper.php b/phpBB/phpbb/passwords/helper.php
index 95bad5805f..c2a49202cd 100644
--- a/phpBB/phpbb/passwords/helper.php
+++ b/phpBB/phpbb/passwords/helper.php
@@ -1,17 +1,18 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\passwords;
-/**
-* @package passwords
-*/
class helper
{
/**
@@ -59,7 +60,7 @@ class helper
$data[$type] .= ($data[$type] !== '$') ? '\\' : '';
$data[$type] .= str_replace('$', '', $value);
}
- elseif ($type == 'settings')
+ else if ($type == 'settings')
{
$data[$type] .= ($data[$type] !== '$') ? '$' : '';
$data[$type] .= $value;
diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php
index 0ac6b05ec4..fbb49d86a0 100644
--- a/phpBB/phpbb/passwords/manager.php
+++ b/phpBB/phpbb/passwords/manager.php
@@ -1,17 +1,18 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\passwords;
-/**
-* @package passwords
-*/
class manager
{
/**
@@ -38,23 +39,23 @@ class manager
/**
* Passwords helper
- * @var phpbb\passwords\helper
+ * @var \phpbb\passwords\helper
*/
protected $helper;
/**
* phpBB configuration
- * @var phpbb\config\config
+ * @var \phpbb\config\config
*/
protected $config;
/**
* Construct a passwords object
*
- * @param phpbb\config\config $config phpBB configuration
+ * @param \phpbb\config\config $config phpBB configuration
* @param array $hashing_algorithms Hashing driver
* service collection
- * @param phpbb\passwords\helper $helper Passwords helper object
+ * @param \phpbb\passwords\helper $helper Passwords helper object
* @param string $defaults List of default driver types
*/
public function __construct(\phpbb\config\config $config, $hashing_algorithms, helper $helper, $defaults)
@@ -88,7 +89,7 @@ class manager
/**
* Fill algorithm type map
*
- * @param phpbb\di\service_collection $hashing_algorithms
+ * @param \phpbb\di\service_collection $hashing_algorithms
*/
protected function fill_type_map($hashing_algorithms)
{
@@ -140,7 +141,7 @@ class manager
*/
if (!preg_match('#^\$([a-zA-Z0-9\\\]*?)\$#', $hash, $match))
{
- return $this->get_algorithm('$H$');
+ return false;
}
// Be on the lookout for multiple hashing algorithms
@@ -223,9 +224,10 @@ class manager
*
* @param string $password Password that should be checked
* @param string $hash Stored hash
+ * @param array $user_row User's row in users table
* @return string|bool True if password is correct, false if not
*/
- public function check($password, $hash)
+ public function check($password, $hash, $user_row = array())
{
if (strlen($password) > 4096)
{
@@ -234,11 +236,19 @@ class manager
return false;
}
+ // Empty hashes can't be checked
+ if (empty($hash))
+ {
+ return false;
+ }
+
// First find out what kind of hash we're dealing with
$stored_hash_type = $this->detect_algorithm($hash);
if ($stored_hash_type == false)
{
- return false;
+ // Still check MD5 hashes as that is what the installer
+ // will default to for the admin user
+ return $this->get_algorithm('$H$')->check($password, $hash);
}
// Multiple hash passes needed
@@ -258,6 +268,21 @@ class manager
$this->convert_flag = false;
}
+ // Check all legacy hash types if prefix is $CP$
+ if ($stored_hash_type->get_prefix() === '$CP$')
+ {
+ // Remove $CP$ prefix for proper checking
+ $hash = substr($hash, 4);
+
+ foreach ($this->type_map as $algorithm)
+ {
+ if ($algorithm->is_legacy() && $algorithm->check($password, $hash, $user_row) === true)
+ {
+ return true;
+ }
+ }
+ }
+
return $stored_hash_type->check($password, $hash);
}
diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php
index a8e12c4063..936564d8b6 100644
--- a/phpBB/phpbb/path_helper.php
+++ b/phpBB/phpbb/path_helper.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb;
/**
* A class with various functions that are related to paths, files and the filesystem
-* @package phpBB3
*/
class path_helper
{
@@ -21,6 +24,9 @@ class path_helper
/** @var \phpbb\filesystem */
protected $filesystem;
+ /** @var \phpbb\request\request_interface */
+ protected $request;
+
/** @var string */
protected $phpbb_root_path;
@@ -38,13 +44,16 @@ class path_helper
*
* @param \phpbb\symfony_request $symfony_request
* @param \phpbb\filesystem $filesystem
+ * @param \phpbb\request\request_interface $request
* @param string $phpbb_root_path Relative path to phpBB root
- * @param string $php_ext PHP extension (php)
+ * @param string $php_ext PHP file extension
+ * @param mixed $adm_relative_path Relative path admin path to adm/ root
*/
- public function __construct(\phpbb\symfony_request $symfony_request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext, $adm_relative_path = null)
+ public function __construct(\phpbb\symfony_request $symfony_request, \phpbb\filesystem $filesystem, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext, $adm_relative_path = null)
{
$this->symfony_request = $symfony_request;
$this->filesystem = $filesystem;
+ $this->request = $request;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
$this->adm_relative_path = $adm_relative_path;
@@ -95,7 +104,13 @@ class path_helper
{
$path = substr($path, strlen($this->phpbb_root_path));
- return $this->get_web_root_path() . $path;
+ $web_root_path = $this->get_web_root_path();
+ if (substr($web_root_path, -8) === 'app.php/' && substr($path, 0, 7) === 'app.php')
+ {
+ $path = substr($path, 8);
+ }
+
+ return $this->filesystem->clean_path($web_root_path . $path);
}
return $path;
@@ -149,6 +164,16 @@ class path_helper
$script_name = $this->symfony_request->getScriptName();
/*
+ * If the path info is empty but we're using app.php, then we
+ * might be using an empty route like app.php/ which is
+ * supported by symfony's routing
+ */
+ if ($path_info === '/' && preg_match('/app\.' . $this->php_ext . '\/$/', $request_uri))
+ {
+ return $this->web_root_path = $this->filesystem->clean_path('./../' . $this->phpbb_root_path);
+ }
+
+ /*
* If the path info is empty (single /), then we're not using
* a route like app.php/foo/bar
*/
@@ -157,31 +182,111 @@ class path_helper
return $this->web_root_path = $this->phpbb_root_path;
}
+ /*
+ * Check AJAX request:
+ * If the current request is a AJAX we need to fix the paths.
+ * We need to get the root path based on the Referer, so we can use
+ * the generated URLs in the template of the Referer. If we do not
+ * generate the relative path based on the Referer, but based on the
+ * currently requested URL, the generated URLs will not point to the
+ * intended locations:
+ * Referer desired URL desired relative root path
+ * memberlist.php faq.php ./
+ * memberlist.php app.php/foo/bar ./
+ * app.php/foo memberlist.php ../
+ * app.php/foo app.php/fox ../
+ * app.php/foo/bar memberlist.php ../../
+ * ../page.php memberlist.php ./phpBB/
+ * ../sub/page.php memberlist.php ./../phpBB/
+ *
+ * The referer must be specified as a parameter in the query.
+ */
+ if ($this->request->is_ajax() && $this->symfony_request->get('_referer'))
+ {
+ $referer_web_root_path = $this->get_web_root_path_from_ajax_referer(
+ $this->symfony_request->get('_referer'),
+ $this->symfony_request->getSchemeAndHttpHost() . $this->symfony_request->getBasePath()
+ );
+ return $this->web_root_path = $this->phpbb_root_path . $referer_web_root_path;
+ }
+
// How many corrections might we need?
$corrections = substr_count($path_info, '/');
/*
- * If the script name (e.g. phpBB/app.php) exists in the
- * requestUri (e.g. phpBB/app.php/foo/template), then we
- * are have a non-rewritten URL.
+ * If the script name (e.g. phpBB/app.php) does not exists in the
+ * requestUri (e.g. phpBB/app.php/foo/template), then we are rewriting
+ * the URL. So we must reduce the slash count by 1.
*/
- if (strpos($request_uri, $script_name) === 0)
+ if (strpos($request_uri, $script_name) !== 0)
{
- /*
- * Append ../ to the end of the phpbb_root_path as many times
- * as / exists in path_info
- */
- return $this->web_root_path = $this->phpbb_root_path . str_repeat('../', $corrections);
+ $corrections--;
}
- /*
- * If we're here it means we're at a re-written path, so we must
- * correct the relative path for web URLs. We must append ../
- * to the end of the root path as many times as / exists in path_info
- * less one time (because the script, e.g. /app.php, doesn't exist in
- * the URL)
- */
- return $this->web_root_path = $this->phpbb_root_path . str_repeat('../', $corrections - 1);
+ // Prepend ../ to the phpbb_root_path as many times as / exists in path_info
+ $this->web_root_path = $this->filesystem->clean_path(
+ './' . str_repeat('../', $corrections) . $this->phpbb_root_path
+ );
+ return $this->web_root_path;
+ }
+
+ /**
+ * Get the web root path of the referer form an ajax request
+ *
+ * @param string $absolute_referer_url
+ * @param string $absolute_board_url
+ * @return string
+ */
+ public function get_web_root_path_from_ajax_referer($absolute_referer_url, $absolute_board_url)
+ {
+ // If the board URL is in the beginning of the referer, this means
+ // we the referer is in the board URL or a subdirectory of it.
+ // So we just need to count the / (slashes) in the left over part of
+ // the referer and prepend ../ the the current root_path, to get the
+ // web root path of the referer.
+ if (strpos($absolute_referer_url, $absolute_board_url) === 0)
+ {
+ $relative_referer_path = substr($absolute_referer_url, strlen($absolute_board_url));
+ $has_params = strpos($relative_referer_path, '?');
+ if ($has_params !== false)
+ {
+ $relative_referer_path = substr($relative_referer_path, 0, $has_params);
+ }
+ $corrections = substr_count($relative_referer_path, '/');
+ return $this->phpbb_root_path . str_repeat('../', $corrections - 1);
+ }
+
+ // If not, it's a bit more complicated. We go to the parent directory
+ // of the referer until we find the remaining referer in the board URL.
+ // Foreach directory we need to add a ../ to the fixed root_path.
+ // When we finally found it, we need to remove the remaining referer
+ // from the board URL, to get the boards root path.
+ // If the then append these two strings, we get our fixed web root path.
+ $fixed_root_path = '';
+ $referer_dir = $absolute_referer_url;
+ $has_params = strpos($referer_dir, '?');
+ if ($has_params !== false)
+ {
+ $referer_dir = substr($referer_dir, 0, $has_params);
+ }
+
+ // If we do not find a slash at the end of the referer, we come
+ // from a file. So the first dirname() does not need a traversal
+ // path correction.
+ if (substr($referer_dir, -1) !== '/')
+ {
+ $referer_dir = dirname($referer_dir);
+ }
+
+ while (strpos($absolute_board_url, $referer_dir) !== 0)
+ {
+ $fixed_root_path .= '../';
+ $referer_dir = dirname($referer_dir);
+ }
+
+ $fixed_root_path .= substr($absolute_board_url, strlen($referer_dir) + 1);
+ // Add trailing slash
+ return $this->phpbb_root_path . $fixed_root_path . '/';
}
/**
@@ -206,4 +311,138 @@ class path_helper
return $scheme . $this->filesystem->clean_path($path);
}
+
+ /**
+ * Glue URL parameters together
+ *
+ * @param array $params URL parameters in the form of array(name => value)
+ * @return string Returns the glued string, e.g. name1=value1&amp;name2&amp;name3=value3
+ */
+ public function glue_url_params($params)
+ {
+ $_params = array();
+
+ foreach ($params as $key => $value)
+ {
+ // some parameters do not have value
+ if ($value !== null)
+ {
+ $_params[] = $key . '=' . $value;
+ }
+ else
+ {
+ $_params[] = $key;
+ }
+ }
+ return implode('&amp;', $_params);
+ }
+
+ /**
+ * Get the base and parameters of a URL
+ *
+ * @param string $url URL to break apart
+ * @param bool $is_amp Is the parameter separator &amp;. Defaults to true.
+ * @return array Returns the base and parameters in the form of array('base' => string, 'params' => array(name => value))
+ */
+ public function get_url_parts($url, $is_amp = true)
+ {
+ $separator = ($is_amp) ? '&amp;' : '&';
+ $params = array();
+
+ if (strpos($url, '?') !== false)
+ {
+ $base = substr($url, 0, strpos($url, '?'));
+ $args = substr($url, strlen($base) + 1);
+ $args = ($args) ? explode($separator, $args) : array();
+
+ foreach ($args as $argument)
+ {
+ if (empty($argument))
+ {
+ continue;
+ }
+
+ // some parameters don't have value
+ if (strpos($argument, '=') !== false)
+ {
+ list($key, $value) = explode('=', $argument, 2);
+ }
+ else
+ {
+ $key = $argument;
+ $value = null;
+ }
+
+ if ($key === '')
+ {
+ continue;
+ }
+
+ $params[$key] = $value;
+ }
+ }
+ else
+ {
+ $base = $url;
+ }
+
+ return array(
+ 'base' => $base,
+ 'params' => $params,
+ );
+ }
+
+ /**
+ * Strip parameters from an already built URL.
+ *
+ * @param string $url URL to strip parameters from
+ * @param array|string $strip Parameters to strip.
+ * @param bool $is_amp Is the parameter separator &amp;. Defaults to true.
+ * @return string Returns the new URL.
+ */
+ public function strip_url_params($url, $strip, $is_amp = true)
+ {
+ $url_parts = $this->get_url_parts($url, $is_amp);
+ $params = $url_parts['params'];
+
+ if (!is_array($strip))
+ {
+ $strip = array($strip);
+ }
+
+ if (!empty($params))
+ {
+ // Strip the parameters off
+ foreach ($strip as $param)
+ {
+ unset($params[$param]);
+ }
+ }
+
+ return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : '');
+ }
+
+ /**
+ * Append parameters to an already built URL.
+ *
+ * @param string $url URL to append parameters to
+ * @param array $new_params Parameters to add in the form of array(name => value)
+ * @param bool $is_amp Is the parameter separator &amp;. Defaults to true.
+ * @return string Returns the new URL.
+ */
+ public function append_url_params($url, $new_params, $is_amp = true)
+ {
+ $url_parts = $this->get_url_parts($url, $is_amp);
+ $params = array_merge($url_parts['params'], $new_params);
+
+ // Move the sid to the end if it's set
+ if (isset($params['sid']))
+ {
+ $sid = $params['sid'];
+ unset($params['sid']);
+ $params['sid'] = $sid;
+ }
+
+ return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : '');
+ }
}
diff --git a/phpBB/phpbb/permissions.php b/phpBB/phpbb/permissions.php
index a3fddb0b9e..9b3dcadf32 100644
--- a/phpBB/phpbb/permissions.php
+++ b/phpBB/phpbb/permissions.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,7 +17,7 @@ class permissions
{
/**
* Event dispatcher object
- * @var \phpbb\event\dispatcher
+ * @var \phpbb\event\dispatcher_interface
*/
protected $dispatcher;
@@ -26,11 +30,10 @@ class permissions
/**
* Constructor
*
- * @param \phpbb\event\dispatcher $phpbb_dispatcher Event dispatcher
+ * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher
* @param \phpbb\user $user User Object
- * @return null
*/
- public function __construct(\phpbb\event\dispatcher $phpbb_dispatcher, \phpbb\user $user)
+ public function __construct(\phpbb\event\dispatcher_interface $phpbb_dispatcher, \phpbb\user $user)
{
$this->dispatcher = $phpbb_dispatcher;
$this->user = $user;
@@ -57,7 +60,7 @@ class permissions
* 'lang' => 'ACL_U_VIEWPROFILE',
* 'cat' => 'profile',
* ),
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('types', 'categories', 'permissions');
extract($phpbb_dispatcher->trigger_event('core.permissions', compact($vars)));
diff --git a/phpBB/phpbb/php/ini.php b/phpBB/phpbb/php/ini.php
index f0f53807fe..73a30659a6 100644
--- a/phpBB/phpbb/php/ini.php
+++ b/phpBB/phpbb/php/ini.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,8 +17,6 @@ namespace phpbb\php;
* Wrapper class for ini_get function.
*
* Provides easier handling of the different interpretations of ini values.
-*
-* @package phpBB
*/
class ini
{
diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php
index 6bff2b8a7e..3c686a552f 100644
--- a/phpBB/phpbb/plupload/plupload.php
+++ b/phpBB/phpbb/plupload/plupload.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\plupload;
/**
* This class handles all server-side plupload functions
-*
-* @package \phpbb\plupload\plupload
*/
class plupload
{
@@ -67,8 +69,6 @@ class plupload
* @param \phpbb\user $user
* @param \phpbb\php\ini $php_ini
* @param \phpbb\mimetype\guesser $mimetype_guesser
- *
- * @return null
*/
public function __construct($phpbb_root_path, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\user $user, \phpbb\php\ini $php_ini, \phpbb\mimetype\guesser $mimetype_guesser)
{
@@ -79,8 +79,7 @@ class plupload
$this->php_ini = $php_ini;
$this->mimetype_guesser = $mimetype_guesser;
- $this->upload_directory = $this->phpbb_root_path . $this->config['upload_path'];
- $this->temporary_directory = $this->upload_directory . '/plupload';
+ $this->set_default_directories();
}
/**
@@ -120,6 +119,9 @@ class plupload
{
rename("{$file_path}.part", $file_path);
+ // Reset upload directories to defaults once completed
+ $this->set_default_directories();
+
// Need to modify some of the $_FILES values to reflect the new file
return array(
'tmp_name' => $file_path,
@@ -146,10 +148,11 @@ class plupload
* @param \phpbb\template\template $template
* @param string $s_action The URL to submit the POST data to
* @param int $forum_id The ID of the forum
+ * @param int $max_files Maximum number of files allowed. 0 for unlimited.
*
* @return null
*/
- public function configure(\phpbb\cache\service $cache, \phpbb\template\template $template, $s_action, $forum_id)
+ public function configure(\phpbb\cache\service $cache, \phpbb\template\template $template, $s_action, $forum_id, $max_files)
{
$filters = $this->generate_filter_string($cache, $forum_id);
$chunk_size = $this->get_chunk_size();
@@ -161,6 +164,9 @@ class plupload
'FILTERS' => $filters,
'CHUNK_SIZE' => $chunk_size,
'S_PLUPLOAD_URL' => htmlspecialchars_decode($s_action),
+ 'MAX_ATTACHMENTS' => $max_files,
+ 'ATTACH_ORDER' => ($this->config['display_order']) ? 'asc' : 'desc',
+ 'L_TOO_MANY_ATTACHMENTS' => $this->user->lang('TOO_MANY_ATTACHMENTS', $max_files),
));
$this->user->add_lang('plupload');
@@ -368,4 +374,29 @@ class plupload
);
}
}
+
+ /**
+ * Sets the default directories for uploads
+ *
+ * @return null
+ */
+ protected function set_default_directories()
+ {
+ $this->upload_directory = $this->phpbb_root_path . $this->config['upload_path'];
+ $this->temporary_directory = $this->upload_directory . '/plupload';
+ }
+
+ /**
+ * Sets the upload directories to the specified paths
+ *
+ * @param string $upload_directory Upload directory
+ * @param string $temporary_directory Temporary directory
+ *
+ * @return null
+ */
+ public function set_upload_directories($upload_directory, $temporary_directory)
+ {
+ $this->upload_directory = $upload_directory;
+ $this->temporary_directory = $temporary_directory;
+ }
}
diff --git a/phpBB/phpbb/profilefields/lang_helper.php b/phpBB/phpbb/profilefields/lang_helper.php
index 7bae1bdc18..2e353722b2 100644
--- a/phpBB/phpbb/profilefields/lang_helper.php
+++ b/phpBB/phpbb/profilefields/lang_helper.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\profilefields;
/**
* Custom Profile Fields
-* @package phpBB3
*/
class lang_helper
{
@@ -23,7 +26,7 @@ class lang_helper
/**
* Database object
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -36,7 +39,7 @@ class lang_helper
/**
* Construct
*
- * @param \phpbb\db\driver\driver $db Database object
+ * @param \phpbb\db\driver\driver_interface $db Database object
* @param string $language_table Table where the language strings are stored
*/
public function __construct($db, $language_table)
@@ -46,43 +49,50 @@ class lang_helper
}
/**
- * Get language entries for options and store them here for later use
+ * Loads preview options into language entries for options
+ *
+ * @param int $field_id
+ * @param int $lang_id
+ * @param mixed $preview_options
*/
- public function get_option_lang($field_id, $lang_id, $field_type, $preview_options)
+ public function load_preview_options($field_id, $lang_id, $preview_options)
{
- if ($preview_options !== false)
- {
- $lang_options = (!is_array($preview_options)) ? explode("\n", $preview_options) : $preview_options;
+ $lang_options = (!is_array($preview_options)) ? explode("\n", $preview_options) : $preview_options;
- foreach ($lang_options as $num => $var)
+ foreach ($lang_options as $num => $var)
+ {
+ if (!isset($this->options_lang[$field_id]))
{
- if (!isset($this->options_lang[$field_id]))
- {
- $this->options_lang[$field_id] = array();
- }
- if (!isset($this->options_lang[$field_id][$lang_id]))
- {
- $this->options_lang[$field_id][$lang_id] = array();
- }
- $this->options_lang[$field_id][$lang_id][($num + 1)] = $var;
+ $this->options_lang[$field_id] = array();
}
+ if (!isset($this->options_lang[$field_id][$lang_id]))
+ {
+ $this->options_lang[$field_id][$lang_id] = array();
+ }
+ $this->options_lang[$field_id][$lang_id][($num + 1)] = $var;
}
- else
- {
- $sql = 'SELECT option_id, lang_value
+ }
+
+ /**
+ * Fetches language entries for options from DB
+ *
+ * @param int $lang_id
+ */
+ public function load_option_lang($lang_id)
+ {
+ $sql = 'SELECT field_id, option_id, lang_value
FROM ' . $this->language_table . '
- WHERE field_id = ' . (int) $field_id . '
- AND lang_id = ' . (int) $lang_id . "
- AND field_type = '" . $this->db->sql_escape($field_type) . "'
+ WHERE lang_id = ' . (int) $lang_id . "
ORDER BY option_id";
- $result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
- {
- $this->options_lang[$field_id][$lang_id][($row['option_id'] + 1)] = $row['lang_value'];
- }
- $this->db->sql_freeresult($result);
+ $result = $this->db->sql_query($sql);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $this->options_lang[$row['field_id']][$lang_id][($row['option_id'] + 1)] = $row['lang_value'];
}
+
+ $this->db->sql_freeresult($result);
}
/**
diff --git a/phpBB/phpbb/profilefields/manager.php b/phpBB/phpbb/profilefields/manager.php
index a4626bc5de..4ad3214ae4 100644
--- a/phpBB/phpbb/profilefields/manager.php
+++ b/phpBB/phpbb/profilefields/manager.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\profilefields;
/**
* Custom Profile Fields
-* @package phpBB3
*/
class manager
{
@@ -23,11 +26,17 @@ class manager
/**
* Database object
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
/**
+ * Event dispatcher object
+ * @var \phpbb\event\dispatcher_interface
+ */
+ protected $dispatcher;
+
+ /**
* Request object
* @var \phpbb\request\request
*/
@@ -63,7 +72,8 @@ class manager
* Construct
*
* @param \phpbb\auth\auth $auth Auth object
- * @param \phpbb\db\driver\driver $db Database object
+ * @param \phpbb\db\driver\driver_interface $db Database object
+ * @param \phpbb\event\dispatcher_interface $dispatcher Event dispatcher object
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\di\service_collection $type_collection
@@ -72,10 +82,11 @@ class manager
* @param string $fields_language_table
* @param string $fields_data_table
*/
- public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver $db, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\di\service_collection $type_collection, \phpbb\user $user, $fields_table, $fields_language_table, $fields_data_table)
+ public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\di\service_collection $type_collection, \phpbb\user $user, $fields_table, $fields_language_table, $fields_data_table)
{
$this->auth = $auth;
$this->db = $db;
+ $this->dispatcher = $dispatcher;
$this->request = $request;
$this->template = $template;
$this->type_collection = $type_collection;
@@ -231,14 +242,11 @@ class manager
if (!$this->db->sql_affectedrows())
{
+ $cp_data = $this->build_insert_sql_array($cp_data);
$cp_data['user_id'] = (int) $user_id;
- $this->db->sql_return_on_error(true);
-
$sql = 'INSERT INTO ' . $this->fields_data_table . ' ' . $this->db->sql_build_array('INSERT', $cp_data);
$this->db->sql_query($sql);
-
- $this->db->sql_return_on_error(false);
}
}
@@ -312,6 +320,17 @@ class manager
}
$this->db->sql_freeresult($result);
+ /**
+ * Event to modify profile fields data retrieved from the database
+ *
+ * @event core.grab_profile_fields_data
+ * @var array user_ids Single user id or an array of ids
+ * @var array field_data Array with profile fields data
+ * @since 3.1.0-b3
+ */
+ $vars = array('user_ids', 'field_data');
+ extract($this->dispatcher->trigger_event('core.grab_profile_fields_data', compact($vars)));
+
$user_fields = array();
// Go through the fields in correct order
@@ -350,10 +369,23 @@ class manager
$tpl_fields = array();
$tpl_fields['row'] = $tpl_fields['blockrow'] = array();
+ /**
+ * Event to modify data of the generated profile fields, before the template assignment loop
+ *
+ * @event core.generate_profile_fields_template_data_before
+ * @var array profile_row Array with users profile field data
+ * @var array tpl_fields Array with template data fields
+ * @var bool use_contact_fields Should we display contact fields as such?
+ * @since 3.1.0-b3
+ */
+ $vars = array('profile_row', 'tpl_fields', 'use_contact_fields');
+ extract($this->dispatcher->trigger_event('core.generate_profile_fields_template_data_before', compact($vars)));
+
foreach ($profile_row as $ident => $ident_ary)
{
$profile_field = $this->type_collection[$ident_ary['data']['field_type']];
$value = $profile_field->get_profile_value($ident_ary['value'], $ident_ary['data']);
+ $value_raw = $profile_field->get_profile_value_raw($ident_ary['value'], $ident_ary['data']);
if ($value === null)
{
@@ -361,7 +393,7 @@ class manager
}
$field_desc = $contact_url = '';
- if ($use_contact_fields)
+ if ($use_contact_fields && $ident_ary['data']['field_is_contact'])
{
$value = $profile_field->get_profile_contact_value($ident_ary['value'], $ident_ary['data']);
$field_desc = $this->user->lang($ident_ary['data']['field_contact_desc']);
@@ -377,32 +409,46 @@ class manager
}
$tpl_fields['row'] += array(
- 'PROFILE_' . strtoupper($ident) . '_IDENT' => $ident,
- 'PROFILE_' . strtoupper($ident) . '_VALUE' => $value,
- 'PROFILE_' . strtoupper($ident) . '_CONTACT'=> $contact_url,
- 'PROFILE_' . strtoupper($ident) . '_DESC' => $field_desc,
- 'PROFILE_' . strtoupper($ident) . '_TYPE' => $ident_ary['data']['field_type'],
- 'PROFILE_' . strtoupper($ident) . '_NAME' => $this->user->lang($ident_ary['data']['lang_name']),
- 'PROFILE_' . strtoupper($ident) . '_EXPLAIN'=> $this->user->lang($ident_ary['data']['lang_explain']),
+ 'PROFILE_' . strtoupper($ident) . '_IDENT' => $ident,
+ 'PROFILE_' . strtoupper($ident) . '_VALUE' => $value,
+ 'PROFILE_' . strtoupper($ident) . '_VALUE_RAW' => $value_raw,
+ 'PROFILE_' . strtoupper($ident) . '_CONTACT' => $contact_url,
+ 'PROFILE_' . strtoupper($ident) . '_DESC' => $field_desc,
+ 'PROFILE_' . strtoupper($ident) . '_TYPE' => $ident_ary['data']['field_type'],
+ 'PROFILE_' . strtoupper($ident) . '_NAME' => $this->user->lang($ident_ary['data']['lang_name']),
+ 'PROFILE_' . strtoupper($ident) . '_EXPLAIN' => $this->user->lang($ident_ary['data']['lang_explain']),
'S_PROFILE_' . strtoupper($ident) . '_CONTACT' => $ident_ary['data']['field_is_contact'],
'S_PROFILE_' . strtoupper($ident) => true,
);
$tpl_fields['blockrow'][] = array(
- 'PROFILE_FIELD_IDENT' => $ident,
- 'PROFILE_FIELD_VALUE' => $value,
- 'PROFILE_FIELD_CONTACT' => $contact_url,
- 'PROFILE_FIELD_DESC' => $field_desc,
- 'PROFILE_FIELD_TYPE' => $ident_ary['data']['field_type'],
- 'PROFILE_FIELD_NAME' => $this->user->lang($ident_ary['data']['lang_name']),
- 'PROFILE_FIELD_EXPLAIN' => $this->user->lang($ident_ary['data']['lang_explain']),
+ 'PROFILE_FIELD_IDENT' => $ident,
+ 'PROFILE_FIELD_VALUE' => $value,
+ 'PROFILE_FIELD_VALUE_RAW' => $value_raw,
+ 'PROFILE_FIELD_CONTACT' => $contact_url,
+ 'PROFILE_FIELD_DESC' => $field_desc,
+ 'PROFILE_FIELD_TYPE' => $ident_ary['data']['field_type'],
+ 'PROFILE_FIELD_NAME' => $this->user->lang($ident_ary['data']['lang_name']),
+ 'PROFILE_FIELD_EXPLAIN' => $this->user->lang($ident_ary['data']['lang_explain']),
'S_PROFILE_CONTACT' => $ident_ary['data']['field_is_contact'],
'S_PROFILE_' . strtoupper($ident) => true,
);
}
+ /**
+ * Event to modify template data of the generated profile fields
+ *
+ * @event core.generate_profile_fields_template_data
+ * @var array profile_row Array with users profile field data
+ * @var array tpl_fields Array with template data fields
+ * @var bool use_contact_fields Should we display contact fields as such?
+ * @since 3.1.0-b3
+ */
+ $vars = array('profile_row', 'tpl_fields', 'use_contact_fields');
+ extract($this->dispatcher->trigger_event('core.generate_profile_fields_template_data', compact($vars)));
+
return $tpl_fields;
}
diff --git a/phpBB/phpbb/profilefields/type/type_base.php b/phpBB/phpbb/profilefields/type/type_base.php
index a96196674d..52f5d15511 100644
--- a/phpBB/phpbb/profilefields/type/type_base.php
+++ b/phpBB/phpbb/profilefields/type/type_base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -35,7 +39,6 @@ abstract class type_base implements type_interface
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
- * @param string $language_table Table where the language strings are stored
*/
public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user)
{
@@ -130,7 +133,7 @@ abstract class type_base implements type_interface
{
foreach ($field_data[$key] as $lang_id => $options)
{
- $field_data[$key][$lang_id] = explode("\n", $options);
+ $field_data[$key][$lang_id] = is_array($options) ? $options : explode("\n", $options);
}
return $current_value;
diff --git a/phpBB/phpbb/profilefields/type/type_bool.php b/phpBB/phpbb/profilefields/type/type_bool.php
index fa9c0a8714..0582722833 100644
--- a/phpBB/phpbb/profilefields/type/type_bool.php
+++ b/phpBB/phpbb/profilefields/type/type_bool.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -42,7 +46,6 @@ class type_bool extends type_base
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
- * @param string $language_table Table where the language strings are stored
*/
public function __construct(\phpbb\profilefields\lang_helper $lang_helper, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user)
{
@@ -152,7 +155,7 @@ class type_bool extends type_base
if (!$this->lang_helper->is_set($field_id, $lang_id))
{
- $this->lang_helper->get_option_lang($field_id, $lang_id, FIELD_BOOL, false);
+ $this->lang_helper->load_option_lang($lang_id);
}
if (!$field_value && $field_data['field_show_novalue'])
@@ -177,6 +180,24 @@ class type_bool extends type_base
/**
* {@inheritDoc}
*/
+ public function get_profile_value_raw($field_value, $field_data)
+ {
+ if ($field_value == $field_data['field_novalue'] && !$field_data['field_show_novalue'])
+ {
+ return null;
+ }
+
+ if (!$field_value && $field_data['field_show_novalue'])
+ {
+ $field_value = $field_data['field_novalue'];
+ }
+
+ return $field_value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public function generate_field($profile_row, $preview_options = false)
{
$profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident'];
@@ -200,7 +221,14 @@ class type_bool extends type_base
{
if (!$this->lang_helper->is_set($profile_row['field_id'], $profile_row['lang_id'], 1))
{
- $this->lang_helper->get_option_lang($profile_row['field_id'], $profile_row['lang_id'], $this->get_service_name(), $preview_options);
+ if ($preview_options)
+ {
+ $this->lang_helper->load_preview_options($profile_row['field_id'], $profile_row['lang_id'], $preview_options);
+ }
+ else
+ {
+ $this->lang_helper->load_option_lang($profile_row['lang_id']);
+ }
}
$options = $this->lang_helper->get($profile_row['field_id'], $profile_row['lang_id']);
diff --git a/phpBB/phpbb/profilefields/type/type_date.php b/phpBB/phpbb/profilefields/type/type_date.php
index af3d65c9b6..90ac9a6703 100644
--- a/phpBB/phpbb/profilefields/type/type_date.php
+++ b/phpBB/phpbb/profilefields/type/type_date.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -35,7 +39,6 @@ class type_date extends type_base
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
- * @param string $language_table Table where the language strings are stored
*/
public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user)
{
@@ -205,6 +208,19 @@ class type_date extends type_base
/**
* {@inheritDoc}
*/
+ public function get_profile_value_raw($field_value, $field_data)
+ {
+ if (($field_value === '' || $field_value === null) && !$field_data['field_show_novalue'])
+ {
+ return null;
+ }
+
+ return $field_value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public function generate_field($profile_row, $preview_options = false)
{
$profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident'];
diff --git a/phpBB/phpbb/profilefields/type/type_dropdown.php b/phpBB/phpbb/profilefields/type/type_dropdown.php
index bcf0ba05f9..17ae89e1b2 100644
--- a/phpBB/phpbb/profilefields/type/type_dropdown.php
+++ b/phpBB/phpbb/profilefields/type/type_dropdown.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -42,7 +46,6 @@ class type_dropdown extends type_base
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
- * @param string $language_table Table where the language strings are stored
*/
public function __construct(\phpbb\profilefields\lang_helper $lang_helper, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user)
{
@@ -132,7 +135,7 @@ class type_dropdown extends type_base
// retrieve option lang data if necessary
if (!$this->lang_helper->is_set($field_data['field_id'], $field_data['lang_id'], 1))
{
- $this->lang_helper->get_option_lang($field_data['field_id'], $field_data['lang_id'], $this->get_service_name(), false);
+ $this->lang_helper->load_option_lang($field_data['lang_id']);
}
if (!$this->lang_helper->is_set($field_data['field_id'], $field_data['lang_id'], $field_value))
@@ -157,7 +160,7 @@ class type_dropdown extends type_base
$lang_id = $field_data['lang_id'];
if (!$this->lang_helper->is_set($field_id, $lang_id))
{
- $this->lang_helper->get_option_lang($field_id, $lang_id, $this->get_service_name(), false);
+ $this->lang_helper->load_option_lang($lang_id);
}
if ($field_value == $field_data['field_novalue'] && !$field_data['field_show_novalue'])
@@ -186,6 +189,24 @@ class type_dropdown extends type_base
/**
* {@inheritDoc}
*/
+ public function get_profile_value_raw($field_value, $field_data)
+ {
+ if ($field_value == $field_data['field_novalue'] && !$field_data['field_show_novalue'])
+ {
+ return null;
+ }
+
+ if (!$field_value && $field_data['field_show_novalue'])
+ {
+ $field_value = $field_data['field_novalue'];
+ }
+
+ return $field_value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public function generate_field($profile_row, $preview_options = false)
{
$profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident'];
@@ -196,7 +217,14 @@ class type_dropdown extends type_base
if (!$this->lang_helper->is_set($profile_row['field_id'], $profile_row['lang_id'], 1))
{
- $this->lang_helper->get_option_lang($profile_row['field_id'], $profile_row['lang_id'], $this->get_service_name(), $preview_options);
+ if ($preview_options)
+ {
+ $this->lang_helper->load_preview_options($profile_row['field_id'], $profile_row['lang_id'], $preview_options);
+ }
+ else
+ {
+ $this->lang_helper->load_option_lang($profile_row['lang_id']);
+ }
}
$profile_row['field_value'] = (int) $value;
diff --git a/phpBB/phpbb/profilefields/type/type_googleplus.php b/phpBB/phpbb/profilefields/type/type_googleplus.php
new file mode 100644
index 0000000000..e6729b1935
--- /dev/null
+++ b/phpBB/phpbb/profilefields/type/type_googleplus.php
@@ -0,0 +1,66 @@
+<?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\profilefields\type;
+
+class type_googleplus extends type_string
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function get_name()
+ {
+ return $this->user->lang('FIELD_GOOGLEPLUS');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function get_service_name()
+ {
+ return 'profilefields.type.googleplus';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function get_default_option_values()
+ {
+ return array(
+ 'field_length' => 20,
+ 'field_minlen' => 3,
+ 'field_maxlen' => 255,
+ 'field_validation' => '(?:(?!\.{2,})([^<>=+]))+',
+ 'field_novalue' => '',
+ 'field_default_value' => '',
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function get_profile_contact_value($field_value, $field_data)
+ {
+ if (!$field_value && !$field_data['field_show_novalue'])
+ {
+ return null;
+ }
+
+ if (!is_numeric($field_value))
+ {
+ $field_value = '+' . $field_value;
+ }
+
+ return $field_value;
+ }
+}
diff --git a/phpBB/phpbb/profilefields/type/type_int.php b/phpBB/phpbb/profilefields/type/type_int.php
index c98c863e13..dd08df94c1 100644
--- a/phpBB/phpbb/profilefields/type/type_int.php
+++ b/phpBB/phpbb/profilefields/type/type_int.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -35,7 +39,6 @@ class type_int extends type_base
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
- * @param string $language_table Table where the language strings are stored
*/
public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user)
{
@@ -151,6 +154,18 @@ class type_int extends type_base
/**
* {@inheritDoc}
*/
+ public function get_profile_value_raw($field_value, $field_data)
+ {
+ if (($field_value === '' || $field_value === null) && !$field_data['field_show_novalue'])
+ {
+ return null;
+ }
+ return (int) $field_value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public function generate_field($profile_row, $preview_options = false)
{
$profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident'];
diff --git a/phpBB/phpbb/profilefields/type/type_interface.php b/phpBB/phpbb/profilefields/type/type_interface.php
index a1c3d879c8..ec770f9467 100644
--- a/phpBB/phpbb/profilefields/type/type_interface.php
+++ b/phpBB/phpbb/profilefields/type/type_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -90,6 +94,15 @@ interface type_interface
public function get_profile_value($field_value, $field_data);
/**
+ * Get Profile Value ID for display (the raw, unprocessed user data)
+ *
+ * @param mixed $field_value Field value as stored in the database
+ * @param array $field_data Array with requirements of the field
+ * @return mixed Field value ID to display
+ */
+ public function get_profile_value_raw($field_value, $field_data);
+
+ /**
* Get Profile Value for display
*
* When displaying a contact field, we don't want to have links already parsed and more
@@ -176,8 +189,8 @@ interface type_interface
/**
* Allows manipulating the intended variables if needed
*
- * @param string $key Name of the option
* @param int $step Step on which the option is hidden
+ * @param string $key Name of the option
* @param string $action Currently performed action (create|edit)
* @param array $field_data Array with data for this field
* @return mixed Final value of the option
diff --git a/phpBB/phpbb/profilefields/type/type_string.php b/phpBB/phpbb/profilefields/type/type_string.php
index 9dada592eb..67befc457d 100644
--- a/phpBB/phpbb/profilefields/type/type_string.php
+++ b/phpBB/phpbb/profilefields/type/type_string.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -35,7 +39,6 @@ class type_string extends type_string_common
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
- * @param string $language_table Table where the language strings are stored
*/
public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user)
{
diff --git a/phpBB/phpbb/profilefields/type/type_string_common.php b/phpBB/phpbb/profilefields/type/type_string_common.php
index 78e219a61f..ff33a7b49c 100644
--- a/phpBB/phpbb/profilefields/type/type_string_common.php
+++ b/phpBB/phpbb/profilefields/type/type_string_common.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -16,7 +20,14 @@ abstract class type_string_common extends type_base
'NUMBERS_ONLY' => '[0-9]+',
'ALPHA_ONLY' => '[\w]+',
'ALPHA_UNDERSCORE' => '[\w_]+',
- 'ALPHA_SPACERS' => '[\w_\+\. \-\[\]]+',
+ 'ALPHA_DOTS' => '[\w.]+',
+ 'ALPHA_SPACERS' => '[\w\x20_+\-\[\]]+',
+ 'ALPHA_PUNCTUATION' => '[a-zA-Z][\w\.,\-_]+',
+ 'LETTER_NUM_ONLY' => '[\p{Lu}\p{Ll}0-9]+',
+ 'LETTER_NUM_UNDERSCORE' => '[\p{Lu}\p{Ll}0-9_]+',
+ 'LETTER_NUM_DOTS' => '[\p{Lu}\p{Ll}0-9.]+',
+ 'LETTER_NUM_SPACERS' => '[\p{Lu}\p{Ll}0-9\x20_+\-\[\]]+',
+ 'LETTER_NUM_PUNCTUATION' => '[\p{Lu}\p{Ll}][\p{Lu}\p{Ll}0-9.,\-_]+',
);
/**
@@ -73,7 +84,7 @@ abstract class type_string_common extends type_base
if (!empty($field_data['field_validation']) && $field_data['field_validation'] != '.*')
{
$field_validate = ($field_type != 'text') ? $field_value : bbcode_nl2br($field_value);
- if (!preg_match('#^' . str_replace('\\\\', '\\', $field_data['field_validation']) . '$#i', $field_validate))
+ if (!preg_match('#^' . str_replace('\\\\', '\\', $field_data['field_validation']) . '$#iu', $field_validate))
{
$validation = array_search($field_data['field_validation'], $this->validation_options);
if ($validation)
@@ -92,7 +103,7 @@ abstract class type_string_common extends type_base
*/
public function get_profile_value($field_value, $field_data)
{
- if (!$field_value && !$field_data['field_show_novalue'])
+ if (($field_value === null || $field_value === '') && !$field_data['field_show_novalue'])
{
return null;
}
@@ -106,9 +117,9 @@ abstract class type_string_common extends type_base
/**
* {@inheritDoc}
*/
- public function get_profile_contact_value($field_value, $field_data)
+ public function get_profile_value_raw($field_value, $field_data)
{
- if (!$field_value && !$field_data['field_show_novalue'])
+ if (($field_value === null || $field_value === '') && !$field_data['field_show_novalue'])
{
return null;
}
@@ -119,6 +130,14 @@ abstract class type_string_common extends type_base
/**
* {@inheritDoc}
*/
+ public function get_profile_contact_value($field_value, $field_data)
+ {
+ return $this->get_profile_value_raw($field_value, $field_data);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public function prepare_options_form(&$exclude_options, &$visibility_options)
{
$exclude_options[1][] = 'lang_default_value';
diff --git a/phpBB/phpbb/profilefields/type/type_text.php b/phpBB/phpbb/profilefields/type/type_text.php
index 660bb20ef8..bacf60a213 100644
--- a/phpBB/phpbb/profilefields/type/type_text.php
+++ b/phpBB/phpbb/profilefields/type/type_text.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -35,7 +39,6 @@ class type_text extends type_string_common
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
- * @param string $language_table Table where the language strings are stored
*/
public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user)
{
diff --git a/phpBB/phpbb/profilefields/type/type_url.php b/phpBB/phpbb/profilefields/type/type_url.php
index b1523b9355..bc8ac869d0 100644
--- a/phpBB/phpbb/profilefields/type/type_url.php
+++ b/phpBB/phpbb/profilefields/type/type_url.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/recursive_dot_prefix_filter_iterator.php b/phpBB/phpbb/recursive_dot_prefix_filter_iterator.php
index 6ef63ec906..2500ba0cf8 100644
--- a/phpBB/phpbb/recursive_dot_prefix_filter_iterator.php
+++ b/phpBB/phpbb/recursive_dot_prefix_filter_iterator.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package extension
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -15,8 +19,6 @@ namespace phpbb;
* This filter ignores directories starting with a dot.
* When searching for php classes and template files of extensions
* we don't need to look inside these directories.
-*
-* @package phpbb
*/
class recursive_dot_prefix_filter_iterator extends \RecursiveFilterIterator
{
diff --git a/phpBB/phpbb/request/deactivated_super_global.php b/phpBB/phpbb/request/deactivated_super_global.php
index b6940cf51f..b6cad59be4 100644
--- a/phpBB/phpbb/request/deactivated_super_global.php
+++ b/phpBB/phpbb/request/deactivated_super_global.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package \phpbb\request\request
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,8 +16,6 @@ namespace phpbb\request;
/**
* Replacement for a superglobal (like $_GET or $_POST) which calls
* trigger_error on all operations but isset, overloads the [] operator with SPL.
-*
-* @package \phpbb\request\request
*/
class deactivated_super_global implements \ArrayAccess, \Countable, \IteratorAggregate
{
diff --git a/phpBB/phpbb/request/request.php b/phpBB/phpbb/request/request.php
index 3171a6edb7..ea9854894c 100644
--- a/phpBB/phpbb/request/request.php
+++ b/phpBB/phpbb/request/request.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package \phpbb\request\request
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,8 +18,6 @@ namespace phpbb\request;
*
* It provides a method to disable access to input data through super globals.
* This should force MOD authors to read about data validation.
-*
-* @package \phpbb\request\request
*/
class request implements \phpbb\request\request_interface
{
diff --git a/phpBB/phpbb/request/request_interface.php b/phpBB/phpbb/request/request_interface.php
index 1f9978b276..3236f73990 100644
--- a/phpBB/phpbb/request/request_interface.php
+++ b/phpBB/phpbb/request/request_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package \phpbb\request\request
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\request;
/**
* An interface through which all application input can be accessed.
-*
-* @package \phpbb\request\request
*/
interface request_interface
{
diff --git a/phpBB/phpbb/request/type_cast_helper.php b/phpBB/phpbb/request/type_cast_helper.php
index e9b55663af..bc654e6182 100644
--- a/phpBB/phpbb/request/type_cast_helper.php
+++ b/phpBB/phpbb/request/type_cast_helper.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package \phpbb\request\request
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\request;
/**
* A helper class that provides convenience methods for type casting.
-*
-* @package \phpbb\request\request
*/
class type_cast_helper implements \phpbb\request\type_cast_helper_interface
{
diff --git a/phpBB/phpbb/request/type_cast_helper_interface.php b/phpBB/phpbb/request/type_cast_helper_interface.php
index f12795eef9..2cb28d021f 100644
--- a/phpBB/phpbb/request/type_cast_helper_interface.php
+++ b/phpBB/phpbb/request/type_cast_helper_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package \phpbb\request\request
-* @copyright (c) 2010 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\request;
/**
* An interface for type cast operations.
-*
-* @package \phpbb\request\request
*/
interface type_cast_helper_interface
{
diff --git a/phpBB/phpbb/search/base.php b/phpBB/phpbb/search/base.php
index 9ecf3751d0..30781975d8 100644
--- a/phpBB/phpbb/search/base.php
+++ b/phpBB/phpbb/search/base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package search
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -17,10 +21,8 @@ define('SEARCH_RESULT_IN_CACHE', 1);
define('SEARCH_RESULT_INCOMPLETE', 2);
/**
-* \phpbb\search\base
* optional base class for search plugins providing simple caching based on ACM
* and functions to retrieve ignore_words and synonyms
-* @package search
*/
class base
{
@@ -83,8 +85,12 @@ class base
/**
* Retrieves cached search results
*
- * @param int &$result_count will contain the number of all results for the search (not only for the current page)
- * @param array &$id_ary is filled with the ids belonging to the requested page that are stored in the cache
+ * @param string $search_key an md5 string generated from all the passed search options to identify the results
+ * @param int &$result_count will contain the number of all results for the search (not only for the current page)
+ * @param array &$id_ary is filled with the ids belonging to the requested page that are stored in the cache
+ * @param int &$start indicates the first index of the page
+ * @param int $per_page number of ids each page is supposed to contain
+ * @param string $sort_dir is either a or d representing ASC and DESC
*
* @return int SEARCH_RESULT_NOT_IN_CACHE or SEARCH_RESULT_IN_CACHE or SEARCH_RESULT_INCOMPLETE
*/
@@ -158,8 +164,16 @@ class base
/**
* Caches post/topic ids
*
- * @param array &$id_ary contains a list of post or topic ids that shall be cached, the first element
+ * @param string $search_key an md5 string generated from all the passed search options to identify the results
+ * @param string $keywords contains the keywords as entered by the user
+ * @param array $author_ary an array of author ids, if the author should be ignored during the search the array is empty
+ * @param int $result_count contains the number of all results for the search (not only for the current page)
+ * @param array &$id_ary contains a list of post or topic ids that shall be cached, the first element
* must have the absolute index $start in the result set.
+ * @param int $start indicates the first index of the page
+ * @param string $sort_dir is either a or d representing ASC and DESC
+ *
+ * @return null
*/
function save_ids($search_key, $keywords, $author_ary, $result_count, &$id_ary, $start, $sort_dir)
{
@@ -280,7 +294,7 @@ class base
$sql_where = '';
foreach ($words as $word)
{
- $sql_where .= " OR search_keywords " . $db->sql_like_expression($db->any_char . $word . $db->any_char);
+ $sql_where .= " OR search_keywords " . $db->sql_like_expression($db->get_any_char() . $word . $db->get_any_char());
}
$sql = 'SELECT search_key
@@ -301,7 +315,7 @@ class base
$sql_where = '';
foreach ($authors as $author)
{
- $sql_where .= (($sql_where) ? ' OR ' : '') . 'search_authors ' . $db->sql_like_expression($db->any_char . ' ' . (int) $author . ' ' . $db->any_char);
+ $sql_where .= (($sql_where) ? ' OR ' : '') . 'search_authors ' . $db->sql_like_expression($db->get_any_char() . ' ' . (int) $author . ' ' . $db->get_any_char());
}
$sql = 'SELECT search_key
diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php
index 509b73e26e..1a0aba096f 100644
--- a/phpBB/phpbb/search/fulltext_mysql.php
+++ b/phpBB/phpbb/search/fulltext_mysql.php
@@ -1,18 +1,20 @@
<?php
/**
*
-* @package search
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\search;
/**
-* fulltext_mysql
* Fulltext search for MySQL
-* @package search
*/
class fulltext_mysql extends \phpbb\search\base
{
@@ -36,7 +38,7 @@ class fulltext_mysql extends \phpbb\search\base
/**
* Database connection
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -71,6 +73,12 @@ class fulltext_mysql extends \phpbb\search\base
* Creates a new \phpbb\search\fulltext_mysql, which is used as a search backend
*
* @param string|bool $error Any error that occurs is passed on through this reference variable otherwise false
+ * @param string $phpbb_root_path Relative path to phpBB root
+ * @param string $phpEx PHP file extension
+ * @param \phpbb\auth\auth $auth Auth object
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\db\driver\driver_interface Database object
+ * @param \phpbb\user $user User object
*/
public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user)
{
@@ -138,7 +146,7 @@ class fulltext_mysql extends \phpbb\search\base
*/
public function init()
{
- if ($this->db->sql_layer != 'mysql4' && $this->db->sql_layer != 'mysqli')
+ if ($this->db->get_sql_layer() != 'mysql4' && $this->db->get_sql_layer() != 'mysqli')
{
return $this->user->lang['FULLTEXT_MYSQL_INCOMPATIBLE_DATABASE'];
}
@@ -762,7 +770,7 @@ class fulltext_mysql extends \phpbb\search\base
if (!isset($this->stats['post_subject']))
{
- if ($this->db->sql_layer == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
+ if ($this->db->get_sql_layer() == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
{
$alter[] = 'MODIFY post_subject varchar(255) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL';
}
@@ -775,7 +783,7 @@ class fulltext_mysql extends \phpbb\search\base
if (!isset($this->stats['post_content']))
{
- if ($this->db->sql_layer == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
+ if ($this->db->get_sql_layer() == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
{
$alter[] = 'MODIFY post_text mediumtext COLLATE utf8_unicode_ci NOT NULL';
}
@@ -870,7 +878,7 @@ class fulltext_mysql extends \phpbb\search\base
*/
protected function get_stats()
{
- if (strpos($this->db->sql_layer, 'mysql') === false)
+ if (strpos($this->db->get_sql_layer(), 'mysql') === false)
{
$this->stats = array();
return;
diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php
index 60180f1728..48b0f077c7 100644
--- a/phpBB/phpbb/search/fulltext_native.php
+++ b/phpBB/phpbb/search/fulltext_native.php
@@ -1,18 +1,20 @@
<?php
/**
*
-* @package search
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\search;
/**
-* fulltext_native
* phpBB's own db driven fulltext search, version 2
-* @package search
*/
class fulltext_native extends \phpbb\search\base
{
@@ -80,7 +82,7 @@ class fulltext_native extends \phpbb\search\base
/**
* Database connection
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -756,7 +758,7 @@ class fulltext_native extends \phpbb\search\base
);
}
- switch ($this->db->sql_layer)
+ switch ($this->db->get_sql_layer())
{
case 'mysql4':
case 'mysqli':
@@ -768,6 +770,7 @@ class fulltext_native extends \phpbb\search\base
break;
case 'sqlite':
+ case 'sqlite3':
$sql_array_count['SELECT'] = ($type == 'posts') ? 'DISTINCT p.post_id' : 'DISTINCT p.topic_id';
$sql = 'SELECT COUNT(' . (($type == 'posts') ? 'post_id' : 'topic_id') . ') as total_results
FROM (' . $this->db->sql_build_query('SELECT', $sql_array_count) . ')';
@@ -975,7 +978,7 @@ class fulltext_native extends \phpbb\search\base
// If the cache was completely empty count the results
if (!$total_results)
{
- switch ($this->db->sql_layer)
+ switch ($this->db->get_sql_layer())
{
case 'mysql4':
case 'mysqli':
@@ -997,7 +1000,7 @@ class fulltext_native extends \phpbb\search\base
}
else
{
- if ($this->db->sql_layer == 'sqlite')
+ if ($this->db->get_sql_layer() == 'sqlite' || $this->db->get_sql_layer() == 'sqlite3')
{
$sql = 'SELECT COUNT(topic_id) as total_results
FROM (SELECT DISTINCT t.topic_id';
@@ -1014,7 +1017,7 @@ class fulltext_native extends \phpbb\search\base
$post_visibility
$sql_fora
AND t.topic_id = p.topic_id
- $sql_time" . (($this->db->sql_layer == 'sqlite') ? ')' : '');
+ $sql_time" . (($this->db->get_sql_layer() == 'sqlite' || $this->db->get_sql_layer() == 'sqlite3') ? ')' : '');
}
$result = $this->db->sql_query($sql);
@@ -1478,10 +1481,10 @@ class fulltext_native extends \phpbb\search\base
*/
public function delete_index($acp_module, $u_action)
{
- switch ($this->db->sql_layer)
+ switch ($this->db->get_sql_layer())
{
case 'sqlite':
- case 'firebird':
+ case 'sqlite3':
$this->db->sql_query('DELETE FROM ' . SEARCH_WORDLIST_TABLE);
$this->db->sql_query('DELETE FROM ' . SEARCH_WORDMATCH_TABLE);
$this->db->sql_query('DELETE FROM ' . SEARCH_RESULTS_TABLE);
diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php
index 63caeffcc5..b6af371d13 100644
--- a/phpBB/phpbb/search/fulltext_postgres.php
+++ b/phpBB/phpbb/search/fulltext_postgres.php
@@ -1,18 +1,20 @@
<?php
/**
*
-* @package search
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\search;
/**
-* fulltext_postgres
* Fulltext search for PostgreSQL
-* @package search
*/
class fulltext_postgres extends \phpbb\search\base
{
@@ -29,18 +31,6 @@ class fulltext_postgres extends \phpbb\search\base
protected $split_words = array();
/**
- * True if PostgreSQL version supports tsearch
- * @var boolean
- */
- protected $tsearch_usable = false;
-
- /**
- * Stores the PostgreSQL version
- * @var string
- */
- protected $version;
-
- /**
* Stores the tsearch query
* @var string
*/
@@ -61,7 +51,7 @@ class fulltext_postgres extends \phpbb\search\base
/**
* Database connection
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -96,6 +86,12 @@ class fulltext_postgres extends \phpbb\search\base
* Creates a new \phpbb\search\fulltext_postgres, which is used as a search backend
*
* @param string|bool $error Any error that occurs is passed on through this reference variable otherwise false
+ * @param string $phpbb_root_path Relative path to phpBB root
+ * @param string $phpEx PHP file extension
+ * @param \phpbb\auth\auth $auth Auth object
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\db\driver\driver_interface Database object
+ * @param \phpbb\user $user User object
*/
public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user)
{
@@ -105,16 +101,6 @@ class fulltext_postgres extends \phpbb\search\base
$this->word_length = array('min' => $this->config['fulltext_postgres_min_word_len'], 'max' => $this->config['fulltext_postgres_max_word_len']);
- if ($this->db->sql_layer == 'postgres')
- {
- $pgsql_version = explode(',', substr($this->db->sql_server_info(), 10));
- $this->version = trim($pgsql_version[0]);
- if (version_compare($this->version, '8.3', '>='))
- {
- $this->tsearch_usable = true;
- }
- }
-
/**
* Load the UTF tools
*/
@@ -183,16 +169,11 @@ class fulltext_postgres extends \phpbb\search\base
*/
public function init()
{
- if ($this->db->sql_layer != 'postgres')
+ if ($this->db->get_sql_layer() != 'postgres')
{
return $this->user->lang['FULLTEXT_POSTGRES_INCOMPATIBLE_DATABASE'];
}
- if (!$this->tsearch_usable)
- {
- return $this->user->lang['FULLTEXT_POSTGRES_TS_NOT_USABLE'];
- }
-
return false;
}
@@ -261,12 +242,12 @@ class fulltext_postgres extends \phpbb\search\base
$this->search_query .= $word . ' ';
$this->tsearch_query .= '&' . substr($word, 1) . ' ';
}
- elseif (strpos($word, '-') === 0)
+ else if (strpos($word, '-') === 0)
{
$this->search_query .= $word . ' ';
$this->tsearch_query .= '&!' . substr($word, 1) . ' ';
}
- elseif (strpos($word, '|') === 0)
+ else if (strpos($word, '|') === 0)
{
$this->search_query .= $word . ' ';
$this->tsearch_query .= '|' . substr($word, 1) . ' ';
@@ -867,7 +848,7 @@ class fulltext_postgres extends \phpbb\search\base
*/
protected function get_stats()
{
- if ($this->db->sql_layer != 'postgres')
+ if ($this->db->get_sql_layer() != 'postgres')
{
$this->stats = array();
return;
@@ -911,13 +892,13 @@ class fulltext_postgres extends \phpbb\search\base
$tpl = '
<dl>
<dt><label>' . $this->user->lang['FULLTEXT_POSTGRES_VERSION_CHECK'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_POSTGRES_VERSION_CHECK_EXPLAIN'] . '</span></dt>
- <dd>' . (($this->tsearch_usable) ? $this->user->lang['YES'] : $this->user->lang['NO']) . ' (PostgreSQL ' . $this->version . ')</dd>
+ <dd>' . (($this->db->get_sql_layer() == 'postgres') ? $this->user->lang['YES'] : $this->user->lang['NO']) . '</dd>
</dl>
<dl>
<dt><label>' . $this->user->lang['FULLTEXT_POSTGRES_TS_NAME'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_POSTGRES_TS_NAME_EXPLAIN'] . '</span></dt>
<dd><select name="config[fulltext_postgres_ts_name]">';
- if ($this->db->sql_layer == 'postgres' && $this->tsearch_usable)
+ if ($this->db->get_sql_layer() == 'postgres')
{
$sql = 'SELECT cfgname AS ts_name
FROM pg_ts_config';
diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php
index d86a394326..eb53ca6d40 100644
--- a/phpBB/phpbb/search/fulltext_sphinx.php
+++ b/phpBB/phpbb/search/fulltext_sphinx.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package search
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,9 +18,7 @@ define('SPHINX_CONNECT_RETRIES', 3);
define('SPHINX_CONNECT_WAIT_TIME', 300);
/**
-* fulltext_sphinx
* Fulltext search based on the sphinx search deamon
-* @package search
*/
class fulltext_sphinx
{
@@ -77,7 +79,7 @@ class fulltext_sphinx
/**
* Database connection
- * @var \phpbb\db\driver\driver
+ * @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -117,6 +119,12 @@ class fulltext_sphinx
* Creates a new \phpbb\search\fulltext_postgres, which is used as a search backend
*
* @param string|bool $error Any error that occurs is passed on through this reference variable otherwise false
+ * @param string $phpbb_root_path Relative path to phpBB root
+ * @param string $phpEx PHP file extension
+ * @param \phpbb\auth\auth $auth Auth object
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\db\driver\driver_interface Database object
+ * @param \phpbb\user $user User object
*/
public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user)
{
@@ -197,7 +205,7 @@ class fulltext_sphinx
*/
public function init()
{
- if ($this->db->sql_layer != 'mysql' && $this->db->sql_layer != 'mysql4' && $this->db->sql_layer != 'mysqli' && $this->db->sql_layer != 'postgres')
+ if ($this->db->get_sql_layer() != 'mysql' && $this->db->get_sql_layer() != 'mysql4' && $this->db->get_sql_layer() != 'mysqli' && $this->db->get_sql_layer() != 'postgres')
{
return $this->user->lang['FULLTEXT_SPHINX_WRONG_DATABASE'];
}
@@ -216,11 +224,11 @@ class fulltext_sphinx
protected function config_generate()
{
// Check if Database is supported by Sphinx
- if ($this->db->sql_layer =='mysql' || $this->db->sql_layer == 'mysql4' || $this->db->sql_layer == 'mysqli')
+ if ($this->db->get_sql_layer() =='mysql' || $this->db->get_sql_layer() == 'mysql4' || $this->db->get_sql_layer() == 'mysqli')
{
$this->dbtype = 'mysql';
}
- else if ($this->db->sql_layer == 'postgres')
+ else if ($this->db->get_sql_layer() == 'postgres')
{
$this->dbtype = 'pgsql';
}
@@ -248,8 +256,8 @@ class fulltext_sphinx
array('type', $this->dbtype . ' # mysql or pgsql'),
// This config value sql_host needs to be changed incase sphinx and sql are on different servers
array('sql_host', $dbhost . ' # SQL server host sphinx connects to'),
- array('sql_user', $dbuser),
- array('sql_pass', $dbpasswd),
+ array('sql_user', '[dbuser]'),
+ array('sql_pass', '[dbpassword]'),
array('sql_db', $dbname),
array('sql_port', $dbport . ' # optional, default is 3306 for mysql and 5432 for pgsql'),
array('sql_query_pre', 'SET NAMES \'utf8\''),
@@ -691,7 +699,7 @@ class fulltext_sphinx
{
if ($mode == 'edit')
{
- $this->sphinx->UpdateAttributes($this->indexes, array('forum_id', 'poster_id'), array((int)$post_id => array((int)$forum_id, (int)$poster_id)));
+ $this->sphinx->UpdateAttributes($this->indexes, array('forum_id', 'poster_id'), array((int) $post_id => array((int) $forum_id, (int) $poster_id)));
}
else if ($mode != 'post' && $post_id)
{
@@ -707,6 +715,7 @@ class fulltext_sphinx
),
'ON' => 'p1.topic_id = p2.topic_id',
)),
+ 'WHERE' => 'p2.post_id = ' . ((int) $post_id),
);
$sql = $this->db->sql_build_query('SELECT', $sql_array);
@@ -716,7 +725,7 @@ class fulltext_sphinx
$post_time = time();
while ($row = $this->db->sql_fetchrow($result))
{
- $post_updates[(int)$row['post_id']] = array($post_time);
+ $post_updates[(int) $row['post_id']] = array($post_time);
}
$this->db->sql_freeresult($result);
diff --git a/phpBB/phpbb/search/sphinx/config.php b/phpBB/phpbb/search/sphinx/config.php
index cb8e4524df..675649b460 100644
--- a/phpBB/phpbb/search/sphinx/config.php
+++ b/phpBB/phpbb/search/sphinx/config.php
@@ -1,19 +1,21 @@
<?php
/**
*
-* @package search
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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\search\sphinx;
/**
-* \phpbb\search\sphinx\config
* An object representing the sphinx configuration
* Can read it from file and write it back out after modification
-* @package search
*/
class config
{
diff --git a/phpBB/phpbb/search/sphinx/config_comment.php b/phpBB/phpbb/search/sphinx/config_comment.php
index 20b1c19af1..b5cd0a3db5 100644
--- a/phpBB/phpbb/search/sphinx/config_comment.php
+++ b/phpBB/phpbb/search/sphinx/config_comment.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package search
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/search/sphinx/config_section.php b/phpBB/phpbb/search/sphinx/config_section.php
index 8f9253ec56..14ab3a752c 100644
--- a/phpBB/phpbb/search/sphinx/config_section.php
+++ b/phpBB/phpbb/search/sphinx/config_section.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package search
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/search/sphinx/config_variable.php b/phpBB/phpbb/search/sphinx/config_variable.php
index c0f6d28dcc..85cee20b62 100644
--- a/phpBB/phpbb/search/sphinx/config_variable.php
+++ b/phpBB/phpbb/search/sphinx/config_variable.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package search
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php
index f530d30f1f..cf8ea1877e 100644
--- a/phpBB/phpbb/session.php
+++ b/phpBB/phpbb/session.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb;
/**
* Session class
-* @package phpBB3
*/
class session
{
@@ -405,9 +408,8 @@ class session
$session_expired = false;
// Check whether the session is still valid if we have one
- $method = basename(trim($config['auth_method']));
-
- $provider = $phpbb_container->get('auth.provider.' . $method);
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+ $provider = $provider_collection->get_provider();
if (!($provider instanceof \phpbb\auth\provider\provider_interface))
{
@@ -444,7 +446,8 @@ class session
{
$sql_ary = array('session_time' => $this->time_now);
- if ($this->update_session_page)
+ // Do not update the session page for ajax requests, so the view online still works as intended
+ if ($this->update_session_page && !$request->is_ajax())
{
$sql_ary['session_page'] = substr($this->page['page'], 0, 199);
$sql_ary['session_forum_id'] = $this->page['forum'];
@@ -574,33 +577,7 @@ class session
}
}
- $method = basename(trim($config['auth_method']));
-
- $provider = $phpbb_container->get('auth.provider.' . $method);
- $this->data = $provider->autologin();
-
- if (sizeof($this->data))
- {
- $this->cookie_data['k'] = '';
- $this->cookie_data['u'] = $this->data['user_id'];
- }
-
- // If we're presented with an autologin key we'll join against it.
- // Else if we've been passed a user_id we'll grab data based on that
- if (isset($this->cookie_data['k']) && $this->cookie_data['k'] && $this->cookie_data['u'] && !sizeof($this->data))
- {
- $sql = 'SELECT u.*
- FROM ' . USERS_TABLE . ' u, ' . SESSIONS_KEYS_TABLE . ' k
- WHERE u.user_id = ' . (int) $this->cookie_data['u'] . '
- AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ")
- AND k.user_id = u.user_id
- AND k.key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'";
- $result = $db->sql_query($sql);
- $this->data = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
- $bot = false;
- }
- else if ($user_id !== false && !sizeof($this->data))
+ if ($user_id !== false && !sizeof($this->data))
{
$this->cookie_data['k'] = '';
$this->cookie_data['u'] = $user_id;
@@ -614,6 +591,34 @@ class session
$db->sql_freeresult($result);
$bot = false;
}
+ else if (!$bot)
+ {
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+ $provider = $provider_collection->get_provider();
+ $this->data = $provider->autologin();
+
+ if (sizeof($this->data))
+ {
+ $this->cookie_data['k'] = '';
+ $this->cookie_data['u'] = $this->data['user_id'];
+ }
+
+ // If we're presented with an autologin key we'll join against it.
+ // Else if we've been passed a user_id we'll grab data based on that
+ if (isset($this->cookie_data['k']) && $this->cookie_data['k'] && $this->cookie_data['u'] && !sizeof($this->data))
+ {
+ $sql = 'SELECT u.*
+ FROM ' . USERS_TABLE . ' u, ' . SESSIONS_KEYS_TABLE . ' k
+ WHERE u.user_id = ' . (int) $this->cookie_data['u'] . '
+ AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ")
+ AND k.user_id = u.user_id
+ AND k.key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'";
+ $result = $db->sql_query($sql);
+ $this->data = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+ $bot = false;
+ }
+ }
// Bot user, if they have a SID in the Request URI we need to get rid of it
// otherwise they'll index this page with the SID, duplicate content oh my!
@@ -895,9 +900,8 @@ class session
$db->sql_query($sql);
// Allow connecting logout with external auth method logout
- $method = basename(trim($config['auth_method']));
-
- $provider = $phpbb_container->get('auth.provider.' . $method);
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+ $provider = $provider_collection->get_provider();
$provider->logout($this->data, $new_session);
if ($this->data['user_id'] != ANONYMOUS)
@@ -962,7 +966,7 @@ class session
*/
function session_gc()
{
- global $db, $config, $phpbb_root_path, $phpEx;
+ global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container;
$batch_size = 10;
@@ -1022,11 +1026,7 @@ class session
}
// only called from CRON; should be a safe workaround until the infrastructure gets going
- if (!class_exists('phpbb_captcha_factory', false))
- {
- include($phpbb_root_path . "includes/captcha/captcha_factory." . $phpEx);
- }
- $captcha_factory = new \phpbb_captcha_factory();
+ $captcha_factory = $phpbb_container->get('captcha.factory');
$captcha_factory->garbage_collect($config['captcha_plugin']);
$sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . '
@@ -1045,8 +1045,9 @@ class session
* @param string $name Name of the cookie, will be automatically prefixed with the phpBB cookie name. track becomes [cookie_name]_track then.
* @param string $cookiedata The data to hold within the cookie
* @param int $cookietime The expiration time as UNIX timestamp. If 0 is provided, a session cookie is set.
+ * @param bool $httponly Use HttpOnly. Defaults to true. Use false to make cookie accessible by client-side scripts.
*/
- function set_cookie($name, $cookiedata, $cookietime)
+ function set_cookie($name, $cookiedata, $cookietime, $httponly = true)
{
global $config;
@@ -1054,24 +1055,26 @@ class session
$expire = gmdate('D, d-M-Y H:i:s \\G\\M\\T', $cookietime);
$domain = (!$config['cookie_domain'] || $config['cookie_domain'] == 'localhost' || $config['cookie_domain'] == '127.0.0.1') ? '' : '; domain=' . $config['cookie_domain'];
- header('Set-Cookie: ' . $name_data . (($cookietime) ? '; expires=' . $expire : '') . '; path=' . $config['cookie_path'] . $domain . ((!$config['cookie_secure']) ? '' : '; secure') . '; HttpOnly', false);
+ header('Set-Cookie: ' . $name_data . (($cookietime) ? '; expires=' . $expire : '') . '; path=' . $config['cookie_path'] . $domain . ((!$config['cookie_secure']) ? '' : '; secure') . ';' . (($httponly) ? ' HttpOnly' : ''), false);
}
/**
* Check for banned user
*
* Checks whether the supplied user is banned by id, ip or email. If no parameters
- * are passed to the method pre-existing session data is used. If $return is false
- * this routine does not return on finding a banned user, it outputs a relevant
- * message and stops execution.
+ * are passed to the method pre-existing session data is used.
*
- * @param string|array $user_ips Can contain a string with one IP or an array of multiple IPs
+ * @param int|false $user_id The user id
+ * @param mixed $user_ips Can contain a string with one IP or an array of multiple IPs
+ * @param string|false $user_email The user email
+ * @param bool $return If $return is false this routine does not return on finding a banned user,
+ * it outputs a relevant message and stops execution.
*/
function check_ban($user_id = false, $user_ips = false, $user_email = false, $return = false)
{
global $config, $db;
- if (defined('IN_CHECK_BAN'))
+ if (defined('IN_CHECK_BAN') || defined('SKIP_CHECK_BAN'))
{
return;
}
@@ -1185,7 +1188,7 @@ class session
if ($banned && !$return)
{
- global $template;
+ global $template, $phpbb_root_path, $phpEx;
// If the session is empty we need to create a valid one...
if (empty($this->session_id))
@@ -1206,8 +1209,6 @@ class session
// We show a login box here to allow founders accessing the board if banned by IP
if (defined('IN_LOGIN') && $this->data['user_id'] == ANONYMOUS)
{
- global $phpEx;
-
$this->setup('ucp');
$this->data['is_registered'] = $this->data['is_bot'] = false;
@@ -1231,7 +1232,8 @@ class session
$till_date = ($ban_row['ban_end']) ? $this->format_date($ban_row['ban_end']) : '';
$message = ($ban_row['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM';
- $message = sprintf($this->lang[$message], $till_date, '<a href="mailto:' . $config['board_contact'] . '">', '</a>');
+ $contact_link = phpbb_get_board_contact_link($config, $phpbb_root_path, $phpEx);
+ $message = sprintf($this->lang[$message], $till_date, '<a href="' . $contact_link . '">', '</a>');
$message .= ($ban_row['ban_give_reason']) ? '<br /><br />' . sprintf($this->lang['BOARD_BAN_REASON'], $ban_row['ban_give_reason']) : '';
$message .= '<br /><br /><em>' . $this->lang['BAN_TRIGGERED_BY_' . strtoupper($ban_triggered_by)] . '</em>';
@@ -1254,12 +1256,14 @@ class session
/**
* Check if ip is blacklisted
- * This should be called only where absolutly necessary
+ * This should be called only where absolutely necessary
*
* Only IPv4 (rbldns does not support AAAA records/IPv6 lookups)
*
* @author satmd (from the php manual)
- * @param string $mode register/post - spamcop for example is ommitted for posting
+ * @param string $mode register/post - spamcop for example is ommitted for posting
+ * @param string|false $ip the IPv4 address to check
+ *
* @return false if ip is not blacklisted, else an array([checked server], [lookup])
*/
function check_dnsbl($mode, $ip = false)
diff --git a/phpBB/phpbb/symfony_request.php b/phpBB/phpbb/symfony_request.php
index ebe862a565..bf9ddec493 100644
--- a/phpBB/phpbb/symfony_request.php
+++ b/phpBB/phpbb/symfony_request.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -16,7 +20,7 @@ class symfony_request extends Request
/**
* Constructor
*
- * @param phpbb\request\request_interface $phpbb_request
+ * @param \phpbb\request\request_interface $phpbb_request
*/
public function __construct(\phpbb\request\request_interface $phpbb_request)
{
diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php
index 24e0d6698d..67dbd7b357 100644
--- a/phpBB/phpbb/template/asset.php
+++ b/phpBB/phpbb/template/asset.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -20,6 +24,7 @@ class asset
* Constructor
*
* @param string $url URL
+ * @param \phpbb\path_helper $path_helper Path helper object
*/
public function __construct($url, \phpbb\path_helper $path_helper)
{
diff --git a/phpBB/phpbb/template/base.php b/phpBB/phpbb/template/base.php
index 5bce79fd85..9a40702ba8 100644
--- a/phpBB/phpbb/template/base.php
+++ b/phpBB/phpbb/template/base.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -138,11 +142,11 @@ abstract class base implements template
{
global $phpbb_hook;
- if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this))
+ if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array('template', $method), $handle, $this))
{
- if ($phpbb_hook->hook_return(array(__CLASS__, $method)))
+ if ($phpbb_hook->hook_return(array('template', $method)))
{
- $result = $phpbb_hook->hook_return_result(array(__CLASS__, $method));
+ $result = $phpbb_hook->hook_return_result(array('template', $method));
return array($result);
}
}
diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php
index a222fbb69e..4ee48205c8 100644
--- a/phpBB/phpbb/template/context.php
+++ b/phpBB/phpbb/template/context.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,8 +15,6 @@ namespace phpbb\template;
/**
* Stores variables assigned to template.
-*
-* @package phpBB3
*/
class context
{
@@ -32,6 +34,11 @@ class context
*/
private $rootref;
+ /**
+ * @var bool
+ */
+ private $num_rows_is_set;
+
public function __construct()
{
$this->clear();
@@ -44,6 +51,7 @@ class context
{
$this->tpldata = array('.' => array(0 => array()));
$this->rootref = &$this->tpldata['.'][0];
+ $this->num_rows_is_set = false;
}
/**
@@ -53,6 +61,7 @@ class context
*
* @param string $varname Variable name
* @param string $varval Value to assign to variable
+ * @return true
*/
public function assign_var($varname, $varval)
{
@@ -68,6 +77,7 @@ class context
*
* @param string $varname Variable name
* @param string $varval Value to append to variable
+ * @return true
*/
public function append_var($varname, $varval)
{
@@ -91,10 +101,59 @@ class context
// returning a reference directly is not
// something php is capable of doing
$ref = &$this->tpldata;
+
+ if (!$this->num_rows_is_set)
+ {
+ /*
+ * We do not set S_NUM_ROWS while adding a row, to reduce the complexity
+ * If we would set it on adding, each subsequent adding would cause
+ * n modifications, resulting in a O(n!) complexity, rather then O(n)
+ */
+ foreach ($ref as $loop_name => &$loop_data)
+ {
+ if ($loop_name === '.')
+ {
+ continue;
+ }
+
+ $this->set_num_rows($loop_data);
+ }
+ $this->num_rows_is_set = true;
+ }
+
return $ref;
}
/**
+ * Set S_NUM_ROWS for each row in this template block
+ *
+ * @param array $loop_data
+ */
+ protected function set_num_rows(&$loop_data)
+ {
+ $s_num_rows = sizeof($loop_data);
+ foreach ($loop_data as &$mod_block)
+ {
+ foreach ($mod_block as $sub_block_name => &$sub_block)
+ {
+ // If the key name is lowercase and the data is an array,
+ // it could be a template loop. So we set the S_NUM_ROWS there
+ // aswell.
+ if ($sub_block_name === strtolower($sub_block_name) && is_array($sub_block))
+ {
+ $this->set_num_rows($sub_block);
+ }
+ }
+
+ // Check whether we are inside a block before setting the variable
+ if (isset($mod_block['S_BLOCK_NAME']))
+ {
+ $mod_block['S_NUM_ROWS'] = $s_num_rows;
+ }
+ }
+ }
+
+ /**
* Returns a reference to template root scope.
*
* This function is public so that template renderer may invoke it.
@@ -115,9 +174,11 @@ class context
*
* @param string $blockname Name of block to assign $vararray to
* @param array $vararray A hash of variable name => value pairs
+ * @return true
*/
public function assign_block_vars($blockname, array $vararray)
{
+ $this->num_rows_is_set = false;
if (strpos($blockname, '.') !== false)
{
// Nested block.
@@ -155,13 +216,6 @@ class context
// We're adding a new iteration to this block with the given
// variable assignments.
$str[$blocks[$blockcount]][] = $vararray;
- $s_num_rows = sizeof($str[$blocks[$blockcount]]);
-
- // Set S_NUM_ROWS
- foreach ($str[$blocks[$blockcount]] as &$mod_block)
- {
- $mod_block['S_NUM_ROWS'] = $s_num_rows;
- }
}
else
{
@@ -187,13 +241,6 @@ class context
// Add a new iteration to this block with the variable assignments we were given.
$this->tpldata[$blockname][] = $vararray;
- $s_num_rows = sizeof($this->tpldata[$blockname]);
-
- // Set S_NUM_ROWS
- foreach ($this->tpldata[$blockname] as &$mod_block)
- {
- $mod_block['S_NUM_ROWS'] = $s_num_rows;
- }
}
return true;
@@ -204,6 +251,7 @@ class context
*
* @param string $blockname Name of block to assign $block_vars_array to
* @param array $block_vars_array An array of hashes of variable name => value pairs
+ * @return true
*/
public function assign_block_vars_array($blockname, array $block_vars_array)
{
@@ -244,6 +292,7 @@ class context
*/
public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert')
{
+ $this->num_rows_is_set = false;
if (strpos($blockname, '.') !== false)
{
// Nested block.
@@ -343,12 +392,6 @@ class context
$block[$key] = $vararray;
$block[$key]['S_ROW_COUNT'] = $block[$key]['S_ROW_NUM'] = $key;
- // Set S_NUM_ROWS
- foreach ($this->tpldata[$blockname] as &$mod_block)
- {
- $mod_block['S_NUM_ROWS'] = sizeof($this->tpldata[$blockname]);
- }
-
return true;
}
@@ -372,9 +415,11 @@ class context
* Reset/empty complete block
*
* @param string $blockname Name of block to destroy
+ * @return true
*/
public function destroy_block_vars($blockname)
{
+ $this->num_rows_is_set = false;
if (strpos($blockname, '.') !== false)
{
// Nested block.
diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php
index 87ae7a9766..041ecb12e4 100644
--- a/phpBB/phpbb/template/template.php
+++ b/phpBB/phpbb/template/template.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -171,6 +175,7 @@ interface template
/**
* Get path to template for handle (required for BBCode parser)
*
+ * @param string $handle Handle to retrieve the source file
* @return string
*/
public function get_source_file_for_handle($handle);
diff --git a/phpBB/phpbb/template/twig/definition.php b/phpBB/phpbb/template/twig/definition.php
index 945c46675e..cb3c953692 100644
--- a/phpBB/phpbb/template/twig/definition.php
+++ b/phpBB/phpbb/template/twig/definition.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -21,6 +25,8 @@ class definition
* Get a DEFINE'd variable
*
* @param string $name
+ * @param array $arguments
+ *
* @return mixed Null if not found
*/
public function __call($name, $arguments)
diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php
index aa55f1e011..476ffd935e 100644
--- a/phpBB/phpbb/template/twig/environment.php
+++ b/phpBB/phpbb/template/twig/environment.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -32,11 +36,10 @@ class environment extends \Twig_Environment
/**
* Constructor
*
- * @param \phpbb\config\config $phpbb_config
- * @param \phpbb\path_helper
- * @param \phpbb\extension\manager
- * @param string $phpbb_root_path
- * @param Twig_LoaderInterface $loader
+ * @param \phpbb\config\config $phpbb_config The phpBB configuration
+ * @param \phpbb\path_helper $path_helper phpBB path helper
+ * @param \phpbb\extension\manager $extension_manager phpBB extension manager
+ * @param \Twig_LoaderInterface $loader Twig loader interface
* @param array $options Array of options to pass to Twig
*/
public function __construct($phpbb_config, \phpbb\path_helper $path_helper, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array())
@@ -118,7 +121,7 @@ class environment extends \Twig_Environment
* Set the namespace look up order to load templates from
*
* @param array $namespace
- * @return Twig_Environment
+ * @return \Twig_Environment
*/
public function setNamespaceLookUpOrder($namespace)
{
@@ -128,12 +131,13 @@ class environment extends \Twig_Environment
}
/**
- * Loads a template by name.
- *
- * @param string $name The template name
- * @param integer $index The index if it is an embedded template
- * @return Twig_TemplateInterface A template instance representing the given template name
- */
+ * Loads a template by name.
+ *
+ * @param string $name The template name
+ * @param integer $index The index if it is an embedded template
+ * @return \Twig_TemplateInterface A template instance representing the given template name
+ * @throws \Twig_Error_Loader
+ */
public function loadTemplate($name, $index = null)
{
if (strpos($name, '@') === false)
@@ -164,11 +168,12 @@ class environment extends \Twig_Environment
}
/**
- * Finds a template by name.
- *
- * @param string $name The template name
- * @return string
- */
+ * Finds a template by name.
+ *
+ * @param string $name The template name
+ * @return string
+ * @throws \Twig_Error_Loader
+ */
public function findTemplate($name)
{
if (strpos($name, '@') === false)
@@ -184,7 +189,7 @@ class environment extends \Twig_Environment
return parent::getLoader()->getCacheKey('@' . $namespace . '/' . $name);
}
- catch (Twig_Error_Loader $e)
+ catch (\Twig_Error_Loader $e)
{
}
}
diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php
index 6847dbd9f8..3a983491b9 100644
--- a/phpBB/phpbb/template/twig/extension.php
+++ b/phpBB/phpbb/template/twig/extension.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -123,7 +127,7 @@ class extension extends \Twig_Extension
/**
* Grabs a subset of a loop
*
- * @param Twig_Environment $env A Twig_Environment instance
+ * @param \Twig_Environment $env A Twig_Environment instance
* @param mixed $item A variable
* @param integer $start Start of the subset
* @param integer $end End of the subset
@@ -158,7 +162,6 @@ class extension extends \Twig_Extension
* (e.g. in the ACP, L_TITLE)
* If not, we return the result of $user->lang()
*
- * @param string $lang name
* @return string
*/
function lang()
diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php
index f4efc58540..c5dc7273ba 100644
--- a/phpBB/phpbb/template/twig/lexer.php
+++ b/phpBB/phpbb/template/twig/lexer.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -191,9 +195,16 @@ class lexer extends \Twig_Lexer
$parent_class = $this;
$callback = function ($matches) use ($parent_class, $parent_nodes)
{
- $name = $matches[1];
- $subset = trim(substr($matches[2], 1, -1)); // Remove parenthesis
- $body = $matches[3];
+ $hard_parents = explode('.', $matches[1]);
+ array_pop($hard_parents); // ends with .
+ if ($hard_parents)
+ {
+ $parent_nodes = array_merge($hard_parents, $parent_nodes);
+ }
+
+ $name = $matches[2];
+ $subset = trim(substr($matches[3], 1, -1)); // Remove parenthesis
+ $body = $matches[4];
// Replace <!-- BEGINELSE -->
$body = str_replace('<!-- BEGINELSE -->', '{% else %}', $body);
@@ -242,7 +253,7 @@ class lexer extends \Twig_Lexer
return "{% for {$name} in {$parent}{$name}{$subset} %}{$body}{% endfor %}";
};
- return preg_replace_callback('#<!-- BEGIN ([!a-zA-Z0-9_]+)(\([0-9,\-]+\))? -->(.+?)<!-- END \1 -->#s', $callback, $code);
+ return preg_replace_callback('#<!-- BEGIN ((?:[a-zA-Z0-9_]+\.)*)([!a-zA-Z0-9_]+)(\([0-9,\-]+\))? -->(.+?)<!-- END \1\2 -->#s', $callback, $code);
}
/**
@@ -274,7 +285,7 @@ class lexer extends \Twig_Lexer
return "<!-- {$matches[1]}IF{$inner}-->";
};
- return preg_replace_callback('#<!-- (ELSE)?IF((.*?) \(*!?[\$|\.]([^\s]+)(.*?))-->#', $callback, $code);
+ return preg_replace_callback('#<!-- (ELSE)?IF((.*?) (?:\(*!?[\$|\.]([^\s]+)(.*?))?)-->#', $callback, $code);
}
/**
diff --git a/phpBB/phpbb/template/twig/loader.php b/phpBB/phpbb/template/twig/loader.php
index e01e9de467..2f8ffaa776 100644
--- a/phpBB/phpbb/template/twig/loader.php
+++ b/phpBB/phpbb/template/twig/loader.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\template\twig;
/**
* Twig Template loader
-* @package phpBB3
*/
class loader extends \Twig_Loader_Filesystem
{
@@ -21,7 +24,7 @@ class loader extends \Twig_Loader_Filesystem
* Set safe directories
*
* @param array $directories Array of directories that are safe (empty to clear)
- * @return Twig_Loader_Filesystem
+ * @return \Twig_Loader_Filesystem
*/
public function setSafeDirectories($directories = array())
{
@@ -42,7 +45,7 @@ class loader extends \Twig_Loader_Filesystem
* Add safe directory
*
* @param string $directory Directory that should be added
- * @return Twig_Loader_Filesystem
+ * @return \Twig_Loader_Filesystem
*/
public function addSafeDirectory($directory)
{
@@ -107,7 +110,7 @@ class loader extends \Twig_Loader_Filesystem
// Try validating the name (which may throw an exception)
parent::validateName($name);
}
- catch (Twig_Error_Loader $e)
+ catch (\Twig_Error_Loader $e)
{
if (strpos($e->getRawMessage(), 'Looks like you try to load a template outside configured directories') === 0)
{
diff --git a/phpBB/phpbb/template/twig/node/definenode.php b/phpBB/phpbb/template/twig/node/definenode.php
index 6a9969f8c6..695ec4281f 100644
--- a/phpBB/phpbb/template/twig/node/definenode.php
+++ b/phpBB/phpbb/template/twig/node/definenode.php
@@ -1,9 +1,14 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group, sections (c) 2009 Fabien Potencier, Armin Ronacher
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @copyright Portions (c) 2009 Fabien Potencier, Armin Ronacher
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
*
*/
@@ -18,10 +23,10 @@ class definenode extends \Twig_Node
}
/**
- * Compiles the node to PHP.
- *
- * @param Twig_Compiler A Twig_Compiler instance
- */
+ * Compiles the node to PHP.
+ *
+ * @param \Twig_Compiler A Twig_Compiler instance
+ */
public function compile(\Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
diff --git a/phpBB/phpbb/template/twig/node/event.php b/phpBB/phpbb/template/twig/node/event.php
index 7a1181a866..8fc4ba4775 100644
--- a/phpBB/phpbb/template/twig/node/event.php
+++ b/phpBB/phpbb/template/twig/node/event.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,12 +17,12 @@ namespace phpbb\template\twig\node;
class event extends \Twig_Node
{
/**
- * The subdirectory in which all template listener files must be placed
- * @var string
- */
+ * The subdirectory in which all template listener files must be placed
+ * @var string
+ */
protected $listener_directory = 'event/';
- /** @var Twig_Environment */
+ /** @var \Twig_Environment */
protected $environment;
public function __construct(\Twig_Node_Expression $expr, \phpbb\template\twig\environment $environment, $lineno, $tag = null)
@@ -29,10 +33,10 @@ class event extends \Twig_Node
}
/**
- * Compiles the node to PHP.
- *
- * @param Twig_Compiler A Twig_Compiler instance
- */
+ * Compiles the node to PHP.
+ *
+ * @param \Twig_Compiler A Twig_Compiler instance
+ */
public function compile(\Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
diff --git a/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php b/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php
index f3bbfa6691..8c7f7b378d 100644
--- a/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php
+++ b/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php b/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php
index c9c2687e08..2e95c68090 100644
--- a/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php
+++ b/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php
index f6c9dc9c58..15195a226b 100644
--- a/phpBB/phpbb/template/twig/node/includeasset.php
+++ b/phpBB/phpbb/template/twig/node/includeasset.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,7 @@ namespace phpbb\template\twig\node;
abstract class includeasset extends \Twig_Node
{
- /** @var Twig_Environment */
+ /** @var \Twig_Environment */
protected $environment;
public function __construct(\Twig_Node_Expression $expr, \phpbb\template\twig\environment $environment, $lineno, $tag = null)
@@ -21,10 +25,10 @@ abstract class includeasset extends \Twig_Node
parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
}
/**
- * Compiles the node to PHP.
- *
- * @param Twig_Compiler A Twig_Compiler instance
- */
+ * Compiles the node to PHP.
+ *
+ * @param \Twig_Compiler A Twig_Compiler instance
+ */
public function compile(\Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
@@ -70,7 +74,7 @@ abstract class includeasset extends \Twig_Node
/**
* Append the output code for the asset
*
- * @param Twig_Compiler A Twig_Compiler instance
+ * @param \Twig_Compiler A Twig_Compiler instance
* @return null
*/
abstract protected function append_asset(\Twig_Compiler $compiler);
diff --git a/phpBB/phpbb/template/twig/node/includecss.php b/phpBB/phpbb/template/twig/node/includecss.php
index deb279fa4a..2ce63402aa 100644
--- a/phpBB/phpbb/template/twig/node/includecss.php
+++ b/phpBB/phpbb/template/twig/node/includecss.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/template/twig/node/includejs.php b/phpBB/phpbb/template/twig/node/includejs.php
index 696b640eac..0f67f9ff60 100644
--- a/phpBB/phpbb/template/twig/node/includejs.php
+++ b/phpBB/phpbb/template/twig/node/includejs.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
diff --git a/phpBB/phpbb/template/twig/node/includenode.php b/phpBB/phpbb/template/twig/node/includenode.php
index d9b45d6407..42428b6106 100644
--- a/phpBB/phpbb/template/twig/node/includenode.php
+++ b/phpBB/phpbb/template/twig/node/includenode.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,10 +17,10 @@ namespace phpbb\template\twig\node;
class includenode extends \Twig_Node_Include
{
/**
- * Compiles the node to PHP.
- *
- * @param Twig_Compiler A Twig_Compiler instance
- */
+ * Compiles the node to PHP.
+ *
+ * @param \Twig_Compiler A Twig_Compiler instance
+ */
public function compile(\Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
diff --git a/phpBB/phpbb/template/twig/node/includephp.php b/phpBB/phpbb/template/twig/node/includephp.php
index 3f4621c0a9..826617e8e8 100644
--- a/phpBB/phpbb/template/twig/node/includephp.php
+++ b/phpBB/phpbb/template/twig/node/includephp.php
@@ -1,9 +1,14 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group, sections (c) 2009 Fabien Potencier, Armin Ronacher
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* Sections (c) 2009 Fabien Potencier, Armin Ronacher
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
*
*/
@@ -12,7 +17,7 @@ namespace phpbb\template\twig\node;
class includephp extends \Twig_Node
{
- /** @var Twig_Environment */
+ /** @var \Twig_Environment */
protected $environment;
public function __construct(\Twig_Node_Expression $expr, \phpbb\template\twig\environment $environment, $lineno, $ignoreMissing = false, $tag = null)
@@ -23,10 +28,10 @@ class includephp extends \Twig_Node
}
/**
- * Compiles the node to PHP.
- *
- * @param Twig_Compiler A Twig_Compiler instance
- */
+ * Compiles the node to PHP.
+ *
+ * @param \Twig_Compiler A Twig_Compiler instance
+ */
public function compile(\Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
diff --git a/phpBB/phpbb/template/twig/node/php.php b/phpBB/phpbb/template/twig/node/php.php
index 2b18551266..3a24513dca 100644
--- a/phpBB/phpbb/template/twig/node/php.php
+++ b/phpBB/phpbb/template/twig/node/php.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,7 +16,7 @@ namespace phpbb\template\twig\node;
class php extends \Twig_Node
{
- /** @var Twig_Environment */
+ /** @var \Twig_Environment */
protected $environment;
public function __construct(\Twig_Node_Text $text, \phpbb\template\twig\environment $environment, $lineno, $tag = null)
@@ -23,10 +27,10 @@ class php extends \Twig_Node
}
/**
- * Compiles the node to PHP.
- *
- * @param Twig_Compiler A Twig_Compiler instance
- */
+ * Compiles the node to PHP.
+ *
+ * @param \Twig_Compiler A Twig_Compiler instance
+ */
public function compile(\Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
diff --git a/phpBB/phpbb/template/twig/tokenparser/defineparser.php b/phpBB/phpbb/template/twig/tokenparser/defineparser.php
index 8484f2e81a..cfee84a363 100644
--- a/phpBB/phpbb/template/twig/tokenparser/defineparser.php
+++ b/phpBB/phpbb/template/twig/tokenparser/defineparser.php
@@ -1,9 +1,14 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group, sections (c) 2009 Fabien Potencier
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @copyright Portions (c) 2009 Fabien Potencier, Armin Ronacher
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
*
*/
@@ -13,12 +18,14 @@ namespace phpbb\template\twig\tokenparser;
class defineparser extends \Twig_TokenParser
{
/**
- * Parses a token and returns a node.
- *
- * @param Twig_Token $token A Twig_Token instance
- *
- * @return Twig_NodeInterface A Twig_NodeInterface instance
- */
+ * Parses a token and returns a node.
+ *
+ * @param \Twig_Token $token A Twig_Token instance
+ *
+ * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ * @throws \Twig_Error_Syntax
+ * @throws \phpbb\template\twig\node\definenode
+ */
public function parse(\Twig_Token $token)
{
$lineno = $token->getLine();
@@ -56,10 +63,10 @@ class defineparser extends \Twig_TokenParser
}
/**
- * Gets the tag name associated with this token parser.
- *
- * @return string The tag name
- */
+ * Gets the tag name associated with this token parser.
+ *
+ * @return string The tag name
+ */
public function getTag()
{
return 'DEFINE';
diff --git a/phpBB/phpbb/template/twig/tokenparser/event.php b/phpBB/phpbb/template/twig/tokenparser/event.php
index 8864e879f8..4c7c8e07d9 100644
--- a/phpBB/phpbb/template/twig/tokenparser/event.php
+++ b/phpBB/phpbb/template/twig/tokenparser/event.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,12 +17,12 @@ namespace phpbb\template\twig\tokenparser;
class event extends \Twig_TokenParser
{
/**
- * Parses a token and returns a node.
- *
- * @param Twig_Token $token A Twig_Token instance
- *
- * @return Twig_NodeInterface A Twig_NodeInterface instance
- */
+ * Parses a token and returns a node.
+ *
+ * @param \Twig_Token $token A Twig_Token instance
+ *
+ * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ */
public function parse(\Twig_Token $token)
{
$expr = $this->parser->getExpressionParser()->parseExpression();
@@ -30,10 +34,10 @@ class event extends \Twig_TokenParser
}
/**
- * Gets the tag name associated with this token parser.
- *
- * @return string The tag name
- */
+ * Gets the tag name associated with this token parser.
+ *
+ * @return string The tag name
+ */
public function getTag()
{
return 'EVENT';
diff --git a/phpBB/phpbb/template/twig/tokenparser/includecss.php b/phpBB/phpbb/template/twig/tokenparser/includecss.php
index 7bf4c610b1..1f30811754 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includecss.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includecss.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -12,12 +16,12 @@ namespace phpbb\template\twig\tokenparser;
class includecss extends \Twig_TokenParser
{
/**
- * Parses a token and returns a node.
- *
- * @param Twig_Token $token A Twig_Token instance
- *
- * @return Twig_NodeInterface A Twig_NodeInterface instance
- */
+ * Parses a token and returns a node.
+ *
+ * @param \Twig_Token $token A Twig_Token instance
+ *
+ * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ */
public function parse(\Twig_Token $token)
{
$expr = $this->parser->getExpressionParser()->parseExpression();
@@ -29,10 +33,10 @@ class includecss extends \Twig_TokenParser
}
/**
- * Gets the tag name associated with this token parser.
- *
- * @return string The tag name
- */
+ * Gets the tag name associated with this token parser.
+ *
+ * @return string The tag name
+ */
public function getTag()
{
return 'INCLUDECSS';
diff --git a/phpBB/phpbb/template/twig/tokenparser/includejs.php b/phpBB/phpbb/template/twig/tokenparser/includejs.php
index 0e46915b86..4156048e42 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includejs.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includejs.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,12 +17,12 @@ namespace phpbb\template\twig\tokenparser;
class includejs extends \Twig_TokenParser
{
/**
- * Parses a token and returns a node.
- *
- * @param Twig_Token $token A Twig_Token instance
- *
- * @return Twig_NodeInterface A Twig_NodeInterface instance
- */
+ * Parses a token and returns a node.
+ *
+ * @param \Twig_Token $token A Twig_Token instance
+ *
+ * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ */
public function parse(\Twig_Token $token)
{
$expr = $this->parser->getExpressionParser()->parseExpression();
@@ -30,10 +34,10 @@ class includejs extends \Twig_TokenParser
}
/**
- * Gets the tag name associated with this token parser.
- *
- * @return string The tag name
- */
+ * Gets the tag name associated with this token parser.
+ *
+ * @return string The tag name
+ */
public function getTag()
{
return 'INCLUDEJS';
diff --git a/phpBB/phpbb/template/twig/tokenparser/includeparser.php b/phpBB/phpbb/template/twig/tokenparser/includeparser.php
index d351f1b4cd..6ee78e5562 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includeparser.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includeparser.php
@@ -1,9 +1,14 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group, sections (c) 2009 Fabien Potencier
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @copyright Portions (c) 2009 Fabien Potencier, Armin Ronacher
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
*
*/
@@ -13,12 +18,12 @@ namespace phpbb\template\twig\tokenparser;
class includeparser extends \Twig_TokenParser_Include
{
/**
- * Parses a token and returns a node.
- *
- * @param Twig_Token $token A Twig_Token instance
- *
- * @return Twig_NodeInterface A Twig_NodeInterface instance
- */
+ * Parses a token and returns a node.
+ *
+ * @param \Twig_Token $token A Twig_Token instance
+ *
+ * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ */
public function parse(\Twig_Token $token)
{
$expr = $this->parser->getExpressionParser()->parseExpression();
@@ -29,10 +34,10 @@ class includeparser extends \Twig_TokenParser_Include
}
/**
- * Gets the tag name associated with this token parser.
- *
- * @return string The tag name
- */
+ * Gets the tag name associated with this token parser.
+ *
+ * @return string The tag name
+ */
public function getTag()
{
return 'INCLUDE';
diff --git a/phpBB/phpbb/template/twig/tokenparser/includephp.php b/phpBB/phpbb/template/twig/tokenparser/includephp.php
index 1b3d1742e3..38196c5290 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includephp.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includephp.php
@@ -1,9 +1,14 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group, sections (c) 2009 Fabien Potencier, Armin Ronacher
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @copyright Portions (c) 2009 Fabien Potencier, Armin Ronacher
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
*
*/
@@ -13,12 +18,12 @@ namespace phpbb\template\twig\tokenparser;
class includephp extends \Twig_TokenParser
{
/**
- * Parses a token and returns a node.
- *
- * @param Twig_Token $token A Twig_Token instance
- *
- * @return Twig_NodeInterface A Twig_NodeInterface instance
- */
+ * Parses a token and returns a node.
+ *
+ * @param \Twig_Token $token A Twig_Token instance
+ *
+ * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ */
public function parse(\Twig_Token $token)
{
$expr = $this->parser->getExpressionParser()->parseExpression();
@@ -39,10 +44,10 @@ class includephp extends \Twig_TokenParser
}
/**
- * Gets the tag name associated with this token parser.
- *
- * @return string The tag name
- */
+ * Gets the tag name associated with this token parser.
+ *
+ * @return string The tag name
+ */
public function getTag()
{
return 'INCLUDEPHP';
diff --git a/phpBB/phpbb/template/twig/tokenparser/php.php b/phpBB/phpbb/template/twig/tokenparser/php.php
index b427969e2d..557a70cca1 100644
--- a/phpBB/phpbb/template/twig/tokenparser/php.php
+++ b/phpBB/phpbb/template/twig/tokenparser/php.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -13,12 +17,12 @@ namespace phpbb\template\twig\tokenparser;
class php extends \Twig_TokenParser
{
/**
- * Parses a token and returns a node.
- *
- * @param Twig_Token $token A Twig_Token instance
- *
- * @return Twig_NodeInterface A Twig_NodeInterface instance
- */
+ * Parses a token and returns a node.
+ *
+ * @param \Twig_Token $token A Twig_Token instance
+ *
+ * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ */
public function parse(\Twig_Token $token)
{
$stream = $this->parser->getStream();
@@ -38,10 +42,10 @@ class php extends \Twig_TokenParser
}
/**
- * Gets the tag name associated with this token parser.
- *
- * @return string The tag name
- */
+ * Gets the tag name associated with this token parser.
+ *
+ * @return string The tag name
+ */
public function getTag()
{
return 'PHP';
diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php
index 83630f5992..a3b002f350 100644
--- a/phpBB/phpbb/template/twig/twig.php
+++ b/phpBB/phpbb/template/twig/twig.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,6 @@ namespace phpbb\template\twig;
/**
* Twig Template class.
-* @package phpBB3
*/
class twig extends \phpbb\template\base
{
@@ -64,7 +67,7 @@ class twig extends \phpbb\template\base
/**
* Twig Environment
*
- * @var Twig_Environment
+ * @var \Twig_Environment
*/
protected $twig;
@@ -174,6 +177,10 @@ class twig extends \phpbb\template\base
}
$names = $this->get_user_style();
+ // Add 'all' folder to $names array
+ // It allows extensions to load a template file from 'all' folder,
+ // if a style doesn't include it.
+ $names[] = 'all';
$paths = array();
foreach ($style_directories as $directory)
@@ -211,9 +218,13 @@ class twig extends \phpbb\template\base
*
* Note: Templates are still compiled to phpBB's cache directory.
*
- * @param string|array $names Array of names or string of name of template(s) in inheritance tree order, used by extensions.
- * @param string|array or string $paths Array of style paths, relative to current root directory
- * @return phpbb_template $this
+ * @param string|array $names Array of names (or detailed names) or string of name of template(s) in inheritance tree order, used by extensions.
+ * E.g. array(
+ * 'name' => 'adm',
+ * 'ext_path' => 'adm/style/',
+ * )
+ * @param string|array of string $paths Array of style paths, relative to current root directory
+ * @return \phpbb\template\template $this
*/
public function set_custom_style($names, $paths)
{
@@ -234,10 +245,26 @@ class twig extends \phpbb\template\base
$namespace = str_replace('/', '_', $ext_namespace);
$paths = array();
- foreach ($names as $style_name)
+ foreach ($names as $template_dir)
{
- $ext_style_path = $ext_path . 'styles/' . $style_name . '/';
- $ext_style_template_path = $ext_style_path . 'template/';
+ if (is_array($template_dir))
+ {
+ if (isset($template_dir['ext_path']))
+ {
+ $ext_style_template_path = $ext_path . $template_dir['ext_path'];
+ $ext_style_path = dirname($ext_style_template_path);
+ }
+ else
+ {
+ $ext_style_path = $ext_path . 'styles/' . $template_dir['name'] . '/';
+ $ext_style_template_path = $ext_style_path . 'template/';
+ }
+ }
+ else
+ {
+ $ext_style_path = $ext_path . 'styles/' . $template_dir . '/';
+ $ext_style_template_path = $ext_style_path . 'template/';
+ }
if (is_dir($ext_style_template_path))
{
@@ -324,9 +351,7 @@ class twig extends \phpbb\template\base
}
/**
- * Get path to template for handle (required for BBCode parser)
- *
- * @return string
+ * {@inheritdoc}
*/
public function get_source_file_for_handle($handle)
{
diff --git a/phpBB/phpbb/tree/nestedset.php b/phpBB/phpbb/tree/nestedset.php
index 2bfb65732d..57d109652e 100644
--- a/phpBB/phpbb/tree/nestedset.php
+++ b/phpBB/phpbb/tree/nestedset.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package tree
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -11,7 +15,7 @@ namespace phpbb\tree;
abstract class nestedset implements \phpbb\tree\tree_interface
{
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\lock\db */
@@ -52,7 +56,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
/**
* Construct
*
- * @param \phpbb\db\driver\driver $db Database connection
+ * @param \phpbb\db\driver\driver_interface $db Database connection
* @param \phpbb\lock\db $lock Lock class used to lock the table when moving forums around
* @param string $table_name Table name
* @param string $message_prefix Prefix for the messages thrown by exceptions
@@ -60,7 +64,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
* @param array $item_basic_data Array with basic item data that is stored in item_parents
* @param array $columns Array with column names to overwrite
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\lock\db $lock, $table_name, $message_prefix = '', $sql_where = '', $item_basic_data = array(), $columns = array())
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\lock\db $lock, $table_name, $message_prefix = '', $sql_where = '', $item_basic_data = array(), $columns = array())
{
$this->db = $db;
$this->lock = $lock;
@@ -99,7 +103,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
*
* @return bool True if the lock was acquired, false if it has been acquired previously
*
- * @throws RuntimeException If the lock could not be acquired
+ * @throws \RuntimeException If the lock could not be acquired
*/
protected function acquire_lock()
{
@@ -117,7 +121,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function insert(array $additional_data)
{
@@ -172,6 +176,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
*
* @param int $item_id The item to be deleted
* @return array Item ids that have been removed
+ * @throws \OutOfBoundsException
*/
protected function remove_item_from_nestedset($item_id)
{
@@ -195,7 +200,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function delete($item_id)
{
@@ -210,7 +215,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function move($item_id, $delta)
{
@@ -328,7 +333,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function move_down($item_id)
{
@@ -336,7 +341,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function move_up($item_id)
{
@@ -344,7 +349,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function move_children($current_parent_id, $new_parent_id)
{
@@ -450,7 +455,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function change_parent($item_id, $new_parent_id)
{
@@ -549,7 +554,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_path_and_subtree_data($item_id, $order_asc = true, $include_item = true)
{
@@ -560,7 +565,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_path_data($item_id, $order_asc = true, $include_item = true)
{
@@ -570,7 +575,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
public function get_subtree_data($item_id, $order_asc = true, $include_item = true)
{
diff --git a/phpBB/phpbb/tree/nestedset_forum.php b/phpBB/phpbb/tree/nestedset_forum.php
index ef6023546b..890fc804c0 100644
--- a/phpBB/phpbb/tree/nestedset_forum.php
+++ b/phpBB/phpbb/tree/nestedset_forum.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package tree
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,11 +18,11 @@ class nestedset_forum extends \phpbb\tree\nestedset
/**
* Construct
*
- * @param \phpbb\db\driver\driver $db Database connection
+ * @param \phpbb\db\driver\driver_interface $db Database connection
* @param \phpbb\lock\db $lock Lock class used to lock the table when moving forums around
* @param string $table_name Table name
*/
- public function __construct(\phpbb\db\driver\driver $db, \phpbb\lock\db $lock, $table_name)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\lock\db $lock, $table_name)
{
parent::__construct(
$db,
diff --git a/phpBB/phpbb/tree/tree_interface.php b/phpBB/phpbb/tree/tree_interface.php
index 90ec27e024..5df01a89cf 100644
--- a/phpBB/phpbb/tree/tree_interface.php
+++ b/phpBB/phpbb/tree/tree_interface.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package tree
-* @copyright (c) 2013 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,7 +18,7 @@ interface tree_interface
/**
* Inserts an item into the database table and into the tree.
*
- * @param array $item The item to be added
+ * @param array $additional_data The item to be added
* @return array Array with item data as set in the database
*/
public function insert(array $additional_data);
diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php
index b9b3896606..882e9cef26 100644
--- a/phpBB/phpbb/user.php
+++ b/phpBB/phpbb/user.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -14,8 +18,6 @@ namespace phpbb;
*
* This is the overarching class which contains (through session extend)
* all methods utilised for user functionality during a session.
-*
-* @package phpBB3
*/
class user extends \phpbb\session
{
@@ -29,6 +31,11 @@ class user extends \phpbb\session
*/
public $timezone;
+ /**
+ * @var string Class name of datetime object
+ */
+ protected $datetime;
+
var $lang_name = false;
var $lang_id = false;
var $lang_path;
@@ -40,12 +47,14 @@ class user extends \phpbb\session
/**
* Constructor to set the lang path
+ * @param string $datetime_class Class name of datetime class
*/
- function __construct()
+ function __construct($datetime_class)
{
global $phpbb_root_path;
$this->lang_path = $phpbb_root_path . 'language/';
+ $this->datetime = $datetime_class;
}
/**
@@ -69,7 +78,7 @@ class user extends \phpbb\session
*/
function setup($lang_set = false, $style_id = false)
{
- global $db, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache;
+ global $db, $request, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache;
global $phpbb_dispatcher;
if ($this->data['user_id'] != ANONYMOUS)
@@ -80,7 +89,25 @@ class user extends \phpbb\session
}
else
{
- $user_lang_name = basename($config['default_lang']);
+ $lang_override = $request->variable('language', '');
+ if ($lang_override)
+ {
+ $this->set_cookie('lang', $lang_override, 0, false);
+ }
+ else
+ {
+ $lang_override = $request->variable($config['cookie_name'] . '_lang', '', true, \phpbb\request\request_interface::COOKIE);
+ }
+ if ($lang_override)
+ {
+ $use_lang = basename($lang_override);
+ $user_lang_name = (file_exists($this->lang_path . $use_lang . "/common.$phpEx")) ? $use_lang : basename($config['default_lang']);
+ $this->data['user_lang'] = $user_lang_name;
+ }
+ else
+ {
+ $user_lang_name = basename($config['default_lang']);
+ }
$user_date_format = $config['default_dateformat'];
$user_timezone = $config['board_timezone'];
@@ -143,9 +170,17 @@ class user extends \phpbb\session
* that are absolutely needed globally using this
* event. Use local events otherwise.
* @var mixed style_id Style we are going to display
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
- $vars = array('user_data', 'user_lang_name', 'user_date_format', 'user_timezone', 'lang_set', 'lang_set_ext', 'style_id');
+ $vars = array(
+ 'user_data',
+ 'user_lang_name',
+ 'user_date_format',
+ 'user_timezone',
+ 'lang_set',
+ 'lang_set_ext',
+ 'style_id',
+ );
extract($phpbb_dispatcher->trigger_event('core.user_setup', compact($vars)));
$this->data = $user_data;
@@ -182,7 +217,7 @@ class user extends \phpbb\session
}
unset($lang_set_ext);
- $style_request = request_var('style', 0);
+ $style_request = $request->variable('style', 0);
if ($style_request && (!$config['override_user_style'] || $auth->acl_get('a_styles')) && !defined('ADMIN_START'))
{
global $SID, $_EXTRA_URL;
@@ -289,7 +324,7 @@ class user extends \phpbb\session
}
// Is board disabled and user not an admin or moderator?
- if ($config['board_disable'] && !defined('IN_LOGIN') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
+ if ($config['board_disable'] && !defined('IN_LOGIN') && !defined('SKIP_CHECK_DISABLED') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
{
if ($this->data['is_bot'])
{
@@ -682,7 +717,7 @@ class user extends \phpbb\session
$utc = new \DateTimeZone('UTC');
}
- $time = new \phpbb\datetime($this, "@$gmepoch", $utc);
+ $time = new $this->datetime($this, "@$gmepoch", $utc);
$time->setTimezone($this->timezone);
return $time->format($format, $forcedate);
@@ -699,7 +734,7 @@ class user extends \phpbb\session
public function create_datetime($time = 'now', \DateTimeZone $timezone = null)
{
$timezone = $timezone ?: $this->timezone;
- return new \phpbb\datetime($this, $time, $timezone);
+ return new $this->datetime($this, $time, $timezone);
}
/**
@@ -769,8 +804,14 @@ class user extends \phpbb\session
*/
function img($img, $alt = '')
{
- $alt = (!empty($this->lang[$alt])) ? $this->lang[$alt] : $alt;
- return '<span class="imageset ' . $img . '">' . $alt . '</span>';
+ $title = '';
+
+ if ($alt)
+ {
+ $alt = $this->lang($alt);
+ $title = ' title="' . $alt . '"';
+ }
+ return '<span class="imageset ' . $img . '"' . $title . '>' . $alt . '</span>';
}
/**
diff --git a/phpBB/phpbb/user_loader.php b/phpBB/phpbb/user_loader.php
index c1d69802f8..24e663b150 100644
--- a/phpBB/phpbb/user_loader.php
+++ b/phpBB/phpbb/user_loader.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2012 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -19,7 +23,7 @@ namespace phpbb;
*/
class user_loader
{
- /** @var \phpbb\db\driver\driver */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db = null;
/** @var string */
@@ -41,12 +45,12 @@ class user_loader
/**
* User loader constructor
*
- * @param \phpbb\db\driver\driver $db A database connection
+ * @param \phpbb\db\driver\driver_interface $db A database connection
* @param string $phpbb_root_path Path to the phpbb includes directory.
* @param string $php_ext php file extension
* @param string $users_table The name of the database table (phpbb_users)
*/
- public function __construct(\phpbb\db\driver\driver $db, $phpbb_root_path, $php_ext, $users_table)
+ public function __construct(\phpbb\db\driver\driver_interface $db, $phpbb_root_path, $php_ext, $users_table)
{
$this->db = $db;
@@ -208,7 +212,7 @@ class user_loader
return '';
}
- if (!function_exists('get_user_rank'))
+ if (!function_exists('phpbb_get_user_rank'))
{
include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext);
}
@@ -219,7 +223,10 @@ class user_loader
'rank_img_src',
);
- get_user_rank($user['user_rank'], (($user['user_id'] == ANONYMOUS) ? false : $user['user_posts']), $rank['rank_title'], $rank['rank_img'], $rank['rank_img_src']);
+ $user_rank_data = phpbb_get_user_rank($user, (($user['user_id'] == ANONYMOUS) ? false : $user['user_posts']));
+ $rank['rank_title'] = $user_rank_data['title'];
+ $rank['rank_img'] = $user_rank_data['img'];
+ $rank['rank_img_src'] = $user_rank_data['img_src'];
return $rank;
}
diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php
index e2fdf6ce63..968a57428f 100644
--- a/phpBB/phpbb/version_helper.php
+++ b/phpBB/phpbb/version_helper.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2014 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* 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.
*
*/
@@ -154,15 +158,16 @@ class version_helper
}
/**
- * Gets the latest version for the current branch the user is on
- *
- * @param bool $force_update Ignores cached data. Defaults to false.
- * @return string
- * @throws \RuntimeException
- */
- public function get_latest_on_current_branch($force_update = false)
+ * Gets the latest version for the current branch the user is on
+ *
+ * @param bool $force_update Ignores cached data. Defaults to false.
+ * @param bool $force_cache Force the use of the cache. Override $force_update.
+ * @return string
+ * @throws \RuntimeException
+ */
+ public function get_latest_on_current_branch($force_update = false, $force_cache = false)
{
- $versions = $this->get_versions_matching_stability($force_update);
+ $versions = $this->get_versions_matching_stability($force_update, $force_cache);
$self = $this;
$current_version = $this->current_version;
@@ -184,15 +189,16 @@ class version_helper
}
/**
- * Obtains the latest version information
- *
- * @param bool $force_update Ignores cached data. Defaults to false.
- * @return string
- * @throws \RuntimeException
- */
- public function get_suggested_updates($force_update = false)
+ * Obtains the latest version information
+ *
+ * @param bool $force_update Ignores cached data. Defaults to false.
+ * @param bool $force_cache Force the use of the cache. Override $force_update.
+ * @return string
+ * @throws \RuntimeException
+ */
+ public function get_suggested_updates($force_update = false, $force_cache = false)
{
- $versions = $this->get_versions_matching_stability($force_update);
+ $versions = $this->get_versions_matching_stability($force_update, $force_cache);
$self = $this;
$current_version = $this->current_version;
@@ -204,15 +210,16 @@ class version_helper
}
/**
- * Obtains the latest version information matching the stability of the current install
- *
- * @param bool $force_update Ignores cached data. Defaults to false.
- * @return string Version info
- * @throws \RuntimeException
- */
- public function get_versions_matching_stability($force_update = false)
+ * Obtains the latest version information matching the stability of the current install
+ *
+ * @param bool $force_update Ignores cached data. Defaults to false.
+ * @param bool $force_cache Force the use of the cache. Override $force_update.
+ * @return string Version info
+ * @throws \RuntimeException
+ */
+ public function get_versions_matching_stability($force_update = false, $force_cache = false)
{
- $info = $this->get_versions($force_update);
+ $info = $this->get_versions($force_update, $force_cache);
if ($this->force_stability !== null)
{
@@ -223,19 +230,24 @@ class version_helper
}
/**
- * Obtains the latest version information
- *
- * @param bool $force_update Ignores cached data. Defaults to false.
- * @return string Version info, includes stable and unstable data
- * @throws \RuntimeException
- */
- public function get_versions($force_update = false)
+ * Obtains the latest version information
+ *
+ * @param bool $force_update Ignores cached data. Defaults to false.
+ * @param bool $force_cache Force the use of the cache. Override $force_update.
+ * @return string Version info, includes stable and unstable data
+ * @throws \RuntimeException
+ */
+ public function get_versions($force_update = false, $force_cache = false)
{
$cache_file = 'versioncheck_' . $this->host . $this->path . $this->file;
$info = $this->cache->get($cache_file);
- if ($info === false || $force_update)
+ if ($info === false && $force_cache)
+ {
+ throw new \RuntimeException($this->user->lang('VERSIONCHECK_FAIL'));
+ }
+ else if ($info === false || $force_update)
{
$errstr = $errno = '';
$info = get_remote_file($this->host, $this->path, $this->file, $errstr, $errno);
@@ -247,7 +259,7 @@ class version_helper
$info = json_decode($info, true);
- if (empty($info['stable']) || empty($info['unstable']))
+ if (empty($info['stable']) && empty($info['unstable']))
{
$this->user->add_lang('acp/common');
@@ -263,6 +275,9 @@ class version_helper
}
}
+ $info['stable'] = (empty($info['stable'])) ? array() : $info['stable'];
+ $info['unstable'] = (empty($info['unstable'])) ? $info['stable'] : $info['unstable'];
+
$this->cache->put($cache_file, $info, 86400); // 24 hours
}
diff --git a/phpBB/phpbb/viewonline_helper.php b/phpBB/phpbb/viewonline_helper.php
new file mode 100644
index 0000000000..b722f9d911
--- /dev/null
+++ b/phpBB/phpbb/viewonline_helper.php
@@ -0,0 +1,54 @@
+<?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;
+
+/**
+* Class to handle viewonline related tasks
+*/
+class viewonline_helper
+{
+ /** @var \phpbb\filesystem */
+ protected $filesystem;
+
+ /**
+ * @param \phpbb\filesystem $filesystem
+ */
+ public function __construct(\phpbb\filesystem $filesystem)
+ {
+ $this->filesystem = $filesystem;
+ }
+
+ /**
+ * Get user page
+ *
+ * @param string $session_page User's session page
+ * @return array Match array filled by preg_match()
+ */
+ public function get_user_page($session_page)
+ {
+ $session_page = $this->filesystem->clean_path($session_page);
+ if (strpos($session_page, './') === 0)
+ {
+ $session_page = substr($session_page, 2);
+ }
+
+ preg_match('#^((\.\./)*([a-z0-9/_-]+))#i', $session_page, $on_page);
+ if (empty($on_page))
+ {
+ $on_page[1] = '';
+ }
+
+ return $on_page;
+ }
+}