aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/acp/acp_ban.php81
-rw-r--r--phpBB/includes/acp/acp_board.php7
-rw-r--r--phpBB/includes/acp/acp_captcha.php17
-rw-r--r--phpBB/includes/acp/acp_database.php4
-rw-r--r--phpBB/includes/acp/acp_groups.php22
-rw-r--r--phpBB/includes/acp/acp_icons.php2
-rw-r--r--phpBB/includes/acp/acp_profile.php145
-rw-r--r--phpBB/includes/acp/acp_styles.php22
-rw-r--r--phpBB/includes/acp/acp_users.php64
-rw-r--r--phpBB/includes/acp/auth.php5
-rw-r--r--phpBB/includes/acp/info/acp_styles.php1
-rw-r--r--phpBB/includes/captcha/captcha_factory.php100
-rw-r--r--phpBB/includes/captcha/captcha_gd.php2629
-rw-r--r--phpBB/includes/captcha/captcha_gd_wave.php843
-rw-r--r--phpBB/includes/captcha/captcha_non_gd.php392
-rw-r--r--phpBB/includes/captcha/plugins/captcha_abstract.php374
-rw-r--r--phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php158
-rw-r--r--phpBB/includes/captcha/plugins/phpbb_captcha_gd_wave_plugin.php69
-rw-r--r--phpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php70
-rw-r--r--phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php998
-rw-r--r--phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php345
-rw-r--r--phpBB/includes/compatibility_globals.php1
-rw-r--r--phpBB/includes/constants.php2
-rw-r--r--phpBB/includes/functions.php271
-rw-r--r--phpBB/includes/functions_acp.php57
-rw-r--r--phpBB/includes/functions_admin.php18
-rw-r--r--phpBB/includes/functions_compatibility.php32
-rw-r--r--phpBB/includes/functions_compress.php4
-rw-r--r--phpBB/includes/functions_content.php31
-rw-r--r--phpBB/includes/functions_display.php145
-rw-r--r--phpBB/includes/functions_download.php39
-rw-r--r--phpBB/includes/functions_mcp.php17
-rw-r--r--phpBB/includes/functions_messenger.php12
-rw-r--r--phpBB/includes/functions_posting.php61
-rw-r--r--phpBB/includes/functions_privmsgs.php16
-rw-r--r--phpBB/includes/functions_transfer.php2
-rw-r--r--phpBB/includes/functions_upload.php9
-rw-r--r--phpBB/includes/functions_user.php49
-rw-r--r--phpBB/includes/mcp/mcp_ban.php128
-rw-r--r--phpBB/includes/mcp/mcp_front.php20
-rw-r--r--phpBB/includes/mcp/mcp_main.php36
-rw-r--r--phpBB/includes/mcp/mcp_pm_reports.php2
-rw-r--r--phpBB/includes/mcp/mcp_queue.php93
-rw-r--r--phpBB/includes/mcp/mcp_reports.php33
-rw-r--r--phpBB/includes/mcp/mcp_warn.php20
-rw-r--r--phpBB/includes/ucp/ucp_activate.php2
-rw-r--r--phpBB/includes/ucp/ucp_attachments.php1
-rw-r--r--phpBB/includes/ucp/ucp_confirm.php5
-rw-r--r--phpBB/includes/ucp/ucp_groups.php36
-rw-r--r--phpBB/includes/ucp/ucp_login_link.php4
-rw-r--r--phpBB/includes/ucp/ucp_main.php6
-rw-r--r--phpBB/includes/ucp/ucp_notifications.php8
-rw-r--r--phpBB/includes/ucp/ucp_pm_options.php6
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewfolder.php2
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewmessage.php14
-rw-r--r--phpBB/includes/ucp/ucp_prefs.php30
-rw-r--r--phpBB/includes/ucp/ucp_profile.php45
-rw-r--r--phpBB/includes/ucp/ucp_register.php9
58 files changed, 965 insertions, 6649 deletions
diff --git a/phpBB/includes/acp/acp_ban.php b/phpBB/includes/acp/acp_ban.php
index 361ef2666c..b555f46a94 100644
--- a/phpBB/includes/acp/acp_ban.php
+++ b/phpBB/includes/acp/acp_ban.php
@@ -25,14 +25,13 @@ class acp_ban
function main($id, $mode)
{
- global $config, $db, $user, $auth, $template, $cache;
- global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix;
+ global $user, $template, $request, $phpbb_dispatcher;
+ global $phpbb_root_path, $phpEx;
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
- $bansubmit = (isset($_POST['bansubmit'])) ? true : false;
- $unbansubmit = (isset($_POST['unbansubmit'])) ? true : false;
- $current_time = time();
+ $bansubmit = $request->is_set_post('bansubmit');
+ $unbansubmit = $request->is_set_post('unbansubmit');
$user->add_lang(array('acp/ban', 'acp/users'));
$this->tpl_name = 'acp_ban';
@@ -48,23 +47,79 @@ class acp_ban
if ($bansubmit)
{
// Grab the list of entries
- $ban = utf8_normalize_nfc(request_var('ban', '', true));
- $ban_len = request_var('banlength', 0);
- $ban_len_other = request_var('banlengthother', '');
- $ban_exclude = request_var('banexclude', 0);
- $ban_reason = utf8_normalize_nfc(request_var('banreason', '', true));
- $ban_give_reason = utf8_normalize_nfc(request_var('bangivereason', '', true));
+ $ban = $request->variable('ban', '', true);
+ $ban_length = $request->variable('banlength', 0);
+ $ban_length_other = $request->variable('banlengthother', '');
+ $ban_exclude = $request->variable('banexclude', 0);
+ $ban_reason = $request->variable('banreason', '', true);
+ $ban_give_reason = $request->variable('bangivereason', '', true);
if ($ban)
{
- user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reason, $ban_give_reason);
+ $abort_ban = false;
+ /**
+ * Use this event to modify the ban details before the ban is performed
+ *
+ * @event core.acp_ban_before
+ * @var string mode One of the following: user, ip, email
+ * @var string ban Either string or array with usernames, ips or email addresses
+ * @var int ban_length Ban length in minutes
+ * @var string ban_length_other Ban length as a date (YYYY-MM-DD)
+ * @var bool ban_exclude Are we banning or excluding from another ban
+ * @var string ban_reason Ban reason displayed to moderators
+ * @var string ban_give_reason Ban reason displayed to the banned user
+ * @var mixed abort_ban Either false, or an error message that is displayed to the user.
+ * If a string is given the bans are not issued.
+ * @since 3.1.0-RC5
+ */
+ $vars = array(
+ 'mode',
+ 'ban',
+ 'ban_length',
+ 'ban_length_other',
+ 'ban_exclude',
+ 'ban_reason',
+ 'ban_give_reason',
+ 'abort_ban',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.acp_ban_before', compact($vars)));
+
+ if ($abort_ban)
+ {
+ trigger_error($abort_ban . adm_back_link($this->u_action));
+ }
+ user_ban($mode, $ban, $ban_length, $ban_length_other, $ban_exclude, $ban_reason, $ban_give_reason);
+
+ /**
+ * Use this event to perform actions after the ban has been performed
+ *
+ * @event core.acp_ban_after
+ * @var string mode One of the following: user, ip, email
+ * @var string ban Either string or array with usernames, ips or email addresses
+ * @var int ban_length Ban length in minutes
+ * @var string ban_length_other Ban length as a date (YYYY-MM-DD)
+ * @var bool ban_exclude Are we banning or excluding from another ban
+ * @var string ban_reason Ban reason displayed to moderators
+ * @var string ban_give_reason Ban reason displayed to the banned user
+ * @since 3.1.0-RC5
+ */
+ $vars = array(
+ 'mode',
+ 'ban',
+ 'ban_length',
+ 'ban_length_other',
+ 'ban_exclude',
+ 'ban_reason',
+ 'ban_give_reason',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.acp_ban_after', compact($vars)));
trigger_error($user->lang['BAN_UPDATE_SUCCESSFUL'] . adm_back_link($this->u_action));
}
}
else if ($unbansubmit)
{
- $ban = request_var('unban', array(''));
+ $ban = $request->variable('unban', array(''));
if ($ban)
{
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index f2707f15ca..9c9e32b57c 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -904,12 +904,11 @@ class acp_board
*/
function timezone_select($value, $key)
{
- global $user;
+ global $template, $user;
- $timezone_select = phpbb_timezone_select($user, $value, true);
- $timezone_select['tz_select'];
+ $timezone_select = phpbb_timezone_select($template, $user, $value, true);
- return '<select name="config[' . $key . ']" id="' . $key . '">' . $timezone_select['tz_select'] . '</select>';
+ return '<select name="config[' . $key . ']" id="' . $key . '">' . $timezone_select . '</select>';
}
/**
diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php
index a625005bf8..fa8d8fb6a9 100644
--- a/phpBB/includes/acp/acp_captcha.php
+++ b/phpBB/includes/acp/acp_captcha.php
@@ -26,12 +26,11 @@ class acp_captcha
function main($id, $mode)
{
global $db, $user, $auth, $template;
- global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
+ global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_container;
$user->add_lang('acp/board');
- include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
- $factory = new phpbb_captcha_factory();
+ $factory = $phpbb_container->get('captcha.factory');
$captchas = $factory->get_captcha_types();
$selected = request_var('select_captcha', $config['captcha_plugin']);
@@ -47,7 +46,7 @@ class acp_captcha
// Delegate
if ($configure)
{
- $config_captcha = phpbb_captcha_factory::get_instance($selected);
+ $config_captcha = $factory->get_instance($selected);
$config_captcha->acp_page($id, $this);
}
else
@@ -79,11 +78,11 @@ class acp_captcha
// sanity check
if (isset($captchas['available'][$selected]))
{
- $old_captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $old_captcha = $factory->get_instance($config['captcha_plugin']);
$old_captcha->uninstall();
set_config('captcha_plugin', $selected);
- $new_captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $new_captcha = $factory->get_instance($config['captcha_plugin']);
$new_captcha->install();
add_log('admin', 'LOG_CONFIG_VISUAL');
@@ -114,7 +113,7 @@ class acp_captcha
$captcha_select .= '<option value="' . $value . '"' . $current . ' class="disabled-option">' . $user->lang($title) . '</option>';
}
- $demo_captcha = phpbb_captcha_factory::get_instance($selected);
+ $demo_captcha = $factory->get_instance($selected);
foreach ($config_vars as $config_var => $options)
{
@@ -137,9 +136,9 @@ class acp_captcha
*/
function deliver_demo($selected)
{
- global $db, $user, $config;
+ global $db, $user, $config, $phpbb_container;
- $captcha = phpbb_captcha_factory::get_instance($selected);
+ $captcha = $phpbb_container->get('captcha.factory')->get_instance($selected);
$captcha->init(CONFIRM_REG);
$captcha->execute_demo();
diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php
index 8f9c155ffc..0c52f82459 100644
--- a/phpBB/includes/acp/acp_database.php
+++ b/phpBB/includes/acp/acp_database.php
@@ -269,7 +269,7 @@ class acp_database
break;
}
- header('Pragma: no-cache');
+ header('Cache-Control: private, no-cache');
header("Content-Type: $mimetype; name=\"$name\"");
header("Content-disposition: attachment; filename=$name");
@@ -510,7 +510,7 @@ class base_extractor
if ($download == true)
{
$name = $filename . $ext;
- header('Pragma: no-cache');
+ header('Cache-Control: private, no-cache');
header("Content-Type: $mimetype; name=\"$name\"");
header("Content-disposition: attachment; filename=$name");
diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php
index f10f0b1015..edfada1bf1 100644
--- a/phpBB/includes/acp/acp_groups.php
+++ b/phpBB/includes/acp/acp_groups.php
@@ -331,6 +331,28 @@ class acp_groups
}
}
+ if ($request->is_set_post('avatar_delete'))
+ {
+ if (confirm_box(true))
+ {
+ $avatar_data['id'] = substr($avatar_data['id'], 1);
+ $phpbb_avatar_manager->handle_avatar_delete($db, $user, $avatar_data, GROUPS_TABLE, 'group_');
+
+ $message = ($action == 'edit') ? 'GROUP_UPDATED' : 'GROUP_CREATED';
+ trigger_error($user->lang[$message] . adm_back_link($this->u_action));
+ }
+ else
+ {
+ confirm_box(false, $user->lang('CONFIRM_AVATAR_DELETE'), build_hidden_fields(array(
+ 'avatar_delete' => true,
+ 'i' => $id,
+ 'mode' => $mode,
+ 'g' => $group_id,
+ 'action' => $action))
+ );
+ }
+ }
+
// Did we submit?
if ($update)
{
diff --git a/phpBB/includes/acp/acp_icons.php b/phpBB/includes/acp/acp_icons.php
index 028025b547..9265415dd1 100644
--- a/phpBB/includes/acp/acp_icons.php
+++ b/phpBB/includes/acp/acp_icons.php
@@ -737,7 +737,7 @@ class acp_icons
{
garbage_collection();
- header('Pragma: public');
+ header('Cache-Control: public');
// Send out the Headers
header('Content-Type: text/x-delimtext; name="' . $mode . '.pak"');
diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php
index fda6ef25ec..046281596c 100644
--- a/phpBB/includes/acp/acp_profile.php
+++ b/phpBB/includes/acp/acp_profile.php
@@ -112,58 +112,8 @@ class acp_profile
$db->sql_query('DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " WHERE field_id = $field_id");
$db->sql_query('DELETE FROM ' . PROFILE_LANG_TABLE . " WHERE field_id = $field_id");
- switch ($db->get_sql_layer())
- {
- case 'sqlite':
- case 'sqlite3':
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '" . PROFILE_FIELDS_DATA_TABLE . "'
- ORDER BY type DESC, name;";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- // Create a temp table and populate it, destroy the existing one
- $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . PROFILE_FIELDS_DATA_TABLE . '"?#i', 'CREATE TEMPORARY TABLE ' . PROFILE_FIELDS_DATA_TABLE . '_temp', $row['sql']));
- $db->sql_query('INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . '_temp SELECT * FROM ' . PROFILE_FIELDS_DATA_TABLE);
- $db->sql_query('DROP TABLE ' . PROFILE_FIELDS_DATA_TABLE);
-
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
-
- $new_table_cols = trim($matches[1]);
- $old_table_cols = preg_split('/,(?=[\\sa-z])/im', $new_table_cols);
- $column_list = array();
-
- foreach ($old_table_cols as $declaration)
- {
- $entities = preg_split('#\s+#', trim($declaration));
-
- if ($entities[0] == 'PRIMARY')
- {
- continue;
- }
-
- if ($entities[0] !== 'pf_' . $field_ident)
- {
- $column_list[] = $entities[0];
- }
- }
-
- $columns = implode(',', $column_list);
-
- $new_table_cols = preg_replace('/' . 'pf_' . $field_ident . '[^,]+,/', '', $new_table_cols);
-
- // create a new table and fill it up. destroy the temp one
- $db->sql_query('CREATE TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' (' . $new_table_cols . ');');
- $db->sql_query('INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . PROFILE_FIELDS_DATA_TABLE . '_temp;');
- $db->sql_query('DROP TABLE ' . PROFILE_FIELDS_DATA_TABLE . '_temp');
- break;
-
- default:
- $db->sql_query('ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " DROP COLUMN pf_$field_ident");
- }
+ $db_tools = $phpbb_container->get('dbal.tools');
+ $db_tools->sql_column_remove(PROFILE_FIELDS_DATA_TABLE, 'pf_' . $field_ident);
$order = 0;
@@ -932,9 +882,7 @@ class acp_profile
$field_ident = 'pf_' . $field_ident;
$db_tools = $phpbb_container->get('dbal.tools');
-
- list($sql_type, $null) = $db_tools->get_column_type($profile_field->get_database_column_type());
- $profile_sql[] = $this->add_field_ident($field_ident, $sql_type);
+ $db_tools->sql_column_add(PROFILE_FIELDS_DATA_TABLE, $field_ident, array($profile_field->get_database_column_type(), null));
}
$sql_ary = array(
@@ -1188,91 +1136,4 @@ class acp_profile
}
}
}
-
- /**
- * Return sql statement for adding a new field ident (profile field) to the profile fields data table
- */
- function add_field_ident($field_ident, $sql_type)
- {
- global $db;
-
- switch ($db->get_sql_layer())
- {
- case 'mysql':
- case 'mysql4':
- case 'mysqli':
- $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD `$field_ident` " . $sql_type;
-
- break;
-
- case 'sqlite':
- case 'sqlite3':
- if (version_compare($db->sql_server_info(true), '3.0') == -1)
- {
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '" . PROFILE_FIELDS_DATA_TABLE . "'
- ORDER BY type DESC, name;";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- // Create a temp table and populate it, destroy the existing one
- $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . PROFILE_FIELDS_DATA_TABLE . '"?#i', 'CREATE TEMPORARY TABLE ' . PROFILE_FIELDS_DATA_TABLE . '_temp', $row['sql']));
- $db->sql_query('INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . '_temp SELECT * FROM ' . PROFILE_FIELDS_DATA_TABLE);
- $db->sql_query('DROP TABLE ' . PROFILE_FIELDS_DATA_TABLE);
-
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
-
- $new_table_cols = trim($matches[1]);
- $old_table_cols = explode(',', $new_table_cols);
- $column_list = array();
-
- foreach ($old_table_cols as $declaration)
- {
- $entities = preg_split('#\s+#', trim($declaration));
- if ($entities[0] == 'PRIMARY')
- {
- continue;
- }
- $column_list[] = $entities[0];
- }
-
- $columns = implode(',', $column_list);
-
- $new_table_cols = $field_ident . ' ' . $sql_type . ',' . $new_table_cols;
-
- // create a new table and fill it up. destroy the temp one
- $db->sql_query('CREATE TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' (' . $new_table_cols . ');');
- $db->sql_query('INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . PROFILE_FIELDS_DATA_TABLE . '_temp;');
- $db->sql_query('DROP TABLE ' . PROFILE_FIELDS_DATA_TABLE . '_temp');
- }
- else
- {
- $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident [$sql_type]";
- }
-
- break;
-
- case 'mssql':
- case 'mssql_odbc':
- case 'mssqlnative':
- $sql = 'ALTER TABLE [' . PROFILE_FIELDS_DATA_TABLE . "] ADD [$field_ident] " . $sql_type;
-
- break;
-
- case 'postgres':
- $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD COLUMN \"$field_ident\" " . $sql_type;
-
- break;
-
- case 'oracle':
- $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident " . $sql_type;
-
- break;
- }
-
- return $sql;
- }
}
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php
index 2a02e3e845..42c67a88b5 100644
--- a/phpBB/includes/acp/acp_styles.php
+++ b/phpBB/includes/acp/acp_styles.php
@@ -133,33 +133,11 @@ class acp_styles
$this->welcome_message('INSTALL_STYLES', 'INSTALL_STYLES_EXPLAIN');
$this->show_available();
return;
- case 'cache':
- $this->action_cache();
- return;
}
trigger_error($this->user->lang['NO_MODE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
/**
- * Purge cache
- */
- protected function action_cache()
- {
- global $db, $cache, $auth;
-
- $this->config->increment('assets_version', 1);
- $this->cache->purge();
-
- // Clear permissions
- $this->auth->acl_clear_prefetch();
- phpbb_cache_moderators($db, $cache, $auth);
-
- add_log('admin', 'LOG_PURGE_CACHE');
-
- trigger_error($this->user->lang['PURGED_CACHE'] . adm_back_link($this->u_base_action), E_USER_NOTICE);
- }
-
- /**
* Install style(s)
*/
protected function action_install()
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 71880c2267..31b033604d 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -404,7 +404,7 @@ class acp_users
if ($config['require_activation'] == USER_ACTIVATION_ADMIN)
{
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->delete_notifications('admin_activate_user', $user_row['user_id']);
+ $phpbb_notifications->delete_notifications('notification.type.admin_activate_user', $user_row['user_id']);
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
@@ -465,25 +465,9 @@ class acp_users
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&amp;u=' . $user_id), E_USER_WARNING);
}
- $sql_ary = array(
- 'user_avatar' => '',
- 'user_avatar_type' => '',
- 'user_avatar_width' => 0,
- 'user_avatar_height' => 0,
- );
-
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
- WHERE user_id = $user_id";
- $db->sql_query($sql);
-
// Delete old avatar if present
$phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
- $driver = $phpbb_avatar_manager->get_driver($user_row['user_avatar_type']);
- if ($driver)
- {
- $driver->delete($user_row);
- }
+ $phpbb_avatar_manager->handle_avatar_delete($db, $user, $phpbb_avatar_manager->clean_row($user_row, 'user'), USERS_TABLE, 'user_');
add_log('admin', 'LOG_USER_DEL_AVATAR', $user_row['username']);
add_log('user', $user_id, 'LOG_USER_DEL_AVATAR_USER');
@@ -1677,7 +1661,7 @@ class acp_users
${'s_sort_' . $sort_option . '_dir'} .= '</select>';
}
- $timezone_selects = phpbb_timezone_select($user, $data['tz'], true);
+ phpbb_timezone_select($template, $user, $data['tz'], true);
$user_prefs_data = array(
'S_PREFS' => true,
'S_JABBER_DISABLED' => ($config['jab_enable'] && $user_row['user_jabber'] && @extension_loaded('xml')) ? false : true,
@@ -1716,8 +1700,6 @@ class acp_users
'S_LANG_OPTIONS' => language_select($data['lang']),
'S_STYLE_OPTIONS' => style_select($data['style']),
- 'S_TZ_OPTIONS' => $timezone_selects['tz_select'],
- 'S_TZ_DATE_OPTIONS' => $timezone_selects['tz_dates'],
);
/**
@@ -1779,29 +1761,6 @@ class acp_users
trigger_error($user->lang['USER_AVATAR_UPDATED'] . adm_back_link($this->u_action . '&amp;u=' . $user_id));
}
}
- else
- {
- $driver = $phpbb_avatar_manager->get_driver($avatar_data['avatar_type']);
- if ($driver)
- {
- $driver->delete($avatar_data);
- }
-
- // Removing the avatar
- $result = array(
- 'user_avatar' => '',
- 'user_avatar_type' => '',
- 'user_avatar_width' => 0,
- 'user_avatar_height' => 0,
- );
-
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET ' . $db->sql_build_array('UPDATE', $result) . '
- WHERE user_id = ' . (int) $user_id;
-
- $db->sql_query($sql);
- trigger_error($user->lang['USER_AVATAR_UPDATED'] . adm_back_link($this->u_action . '&amp;u=' . $user_id));
- }
}
else
{
@@ -1809,6 +1768,23 @@ class acp_users
}
}
+ // Handle deletion of avatars
+ if ($request->is_set_post('avatar_delete'))
+ {
+ if (!confirm_box(true))
+ {
+ confirm_box(false, $user->lang('CONFIRM_AVATAR_DELETE'), build_hidden_fields(array(
+ 'avatar_delete' => true))
+ );
+ }
+ else
+ {
+ $phpbb_avatar_manager->handle_avatar_delete($db, $user, $avatar_data, USERS_TABLE, 'user_');
+
+ trigger_error($user->lang['USER_AVATAR_UPDATED'] . adm_back_link($this->u_action . '&amp;u=' . $user_id));
+ }
+ }
+
$selected_driver = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', $user_row['user_avatar_type']));
foreach ($avatar_drivers as $current_driver)
diff --git a/phpBB/includes/acp/auth.php b/phpBB/includes/acp/auth.php
index 7ff3212b72..905e981cdc 100644
--- a/phpBB/includes/acp/auth.php
+++ b/phpBB/includes/acp/auth.php
@@ -183,7 +183,10 @@ class auth_admin extends \phpbb\auth\auth
}
// Defining the user-function here to save some memory
- $return_acl_fill = create_function('$value', 'return ' . $acl_fill . ';');
+ $return_acl_fill = function () use ($acl_fill)
+ {
+ return $acl_fill;
+ };
// Actually fill the gaps
if (sizeof($hold_ary))
diff --git a/phpBB/includes/acp/info/acp_styles.php b/phpBB/includes/acp/info/acp_styles.php
index 1a9865aa1d..c0ab005502 100644
--- a/phpBB/includes/acp/info/acp_styles.php
+++ b/phpBB/includes/acp/info/acp_styles.php
@@ -22,7 +22,6 @@ class acp_styles_info
'modes' => array(
'style' => array('title' => 'ACP_STYLES', 'auth' => 'acl_a_styles', 'cat' => array('ACP_STYLE_MANAGEMENT')),
'install' => array('title' => 'ACP_STYLES_INSTALL', 'auth' => 'acl_a_styles', 'cat' => array('ACP_STYLE_MANAGEMENT')),
- 'cache' => array('title' => 'ACP_STYLES_CACHE', 'auth' => 'acl_a_styles', 'cat' => array('ACP_STYLE_MANAGEMENT')),
),
);
}
diff --git a/phpBB/includes/captcha/captcha_factory.php b/phpBB/includes/captcha/captcha_factory.php
deleted file mode 100644
index ebeb695282..0000000000
--- a/phpBB/includes/captcha/captcha_factory.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* A small class for 3.0.x (no autoloader in 3.0.x)
-*/
-class phpbb_captcha_factory
-{
- /**
- * return an instance of class $name in file $name_plugin.php
- */
- static public function get_instance($name)
- {
- global $phpbb_root_path, $phpEx;
-
- $name = basename($name);
- if (!class_exists($name))
- {
- include($phpbb_root_path . "includes/captcha/plugins/{$name}_plugin." . $phpEx);
- }
- $instance = call_user_func(array($name, 'get_instance'));
- return $instance;
- }
-
- /**
- * Call the garbage collector
- */
- function garbage_collect($name)
- {
- global $phpbb_root_path, $phpEx;
-
- $name = basename($name);
- if (!class_exists($name))
- {
- include($phpbb_root_path . "includes/captcha/plugins/{$name}_plugin." . $phpEx);
- }
- $captcha = self::get_instance($name);
- $captcha->garbage_collect(0);
- }
-
- /**
- * return a list of all discovered CAPTCHA plugins
- */
- function get_captcha_types()
- {
- global $phpbb_root_path, $phpEx, $phpbb_extension_manager;
-
- $captchas = array(
- 'available' => array(),
- 'unavailable' => array(),
- );
-
- $finder = $phpbb_extension_manager->get_finder();
- $captcha_plugin_classes = $finder
- ->extension_directory('/captcha')
- ->suffix('_plugin')
- ->core_path('includes/captcha/plugins/')
- ->get_classes();
-
- foreach ($captcha_plugin_classes as $class)
- {
- // check if this class needs to be loaded in legacy mode
- $old_class = preg_replace('/^phpbb_captcha_plugins_/', '', $class);
- if (file_exists($phpbb_root_path . "includes/captcha/plugins/$old_class.$phpEx") && !class_exists($old_class))
- {
- include($phpbb_root_path . "includes/captcha/plugins/$old_class.$phpEx");
- $class = preg_replace('/_plugin$/', '', $old_class);
- }
-
- if (call_user_func(array($class, 'is_available')))
- {
- $captchas['available'][$class] = call_user_func(array($class, 'get_name'));
- }
- else
- {
- $captchas['unavailable'][$class] = call_user_func(array($class, 'get_name'));
- }
- }
-
- return $captchas;
- }
-}
diff --git a/phpBB/includes/captcha/captcha_gd.php b/phpBB/includes/captcha/captcha_gd.php
deleted file mode 100644
index 7e37cc33f9..0000000000
--- a/phpBB/includes/captcha/captcha_gd.php
+++ /dev/null
@@ -1,2629 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-class captcha
-{
- 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),
- ),
- )
- );
- }
-}
-
-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 char_cube3d(&$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);
- }
-}
-
-class colour_manager
-{
- var $img;
- var $mode;
- var $colours;
- var $named_colours;
-
- /**
- * Create the colour manager, link it to the image resource
- */
- function colour_manager($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/includes/captcha/captcha_gd_wave.php b/phpBB/includes/captcha/captcha_gd_wave.php
deleted file mode 100644
index c2a4d3a31e..0000000000
--- a/phpBB/includes/captcha/captcha_gd_wave.php
+++ /dev/null
@@ -1,843 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* Wave3D CAPTCHA
-*/
-class captcha
-{
- 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/includes/captcha/captcha_non_gd.php b/phpBB/includes/captcha/captcha_non_gd.php
deleted file mode 100644
index 91970ea7a4..0000000000
--- a/phpBB/includes/captcha/captcha_non_gd.php
+++ /dev/null
@@ -1,392 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Main non-gd captcha class
-* @ignore
-*/
-class captcha
-{
- var $filtered_pngs;
- var $width = 320;
- var $height = 50;
-
- /**
- * Define filtered pngs on init
- */
- function captcha()
- {
- // 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/includes/captcha/plugins/captcha_abstract.php b/phpBB/includes/captcha/plugins/captcha_abstract.php
deleted file mode 100644
index 8e1e61bdb7..0000000000
--- a/phpBB/includes/captcha/plugins/captcha_abstract.php
+++ /dev/null
@@ -1,374 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* This class holds the code shared by the two default 3.0.x CAPTCHAs.
-*/
-class phpbb_captcha_plugins_captcha_abstract
-{
- var $confirm_id;
- var $confirm_code;
- var $code;
- var $seed;
- var $attempts = 0;
- var $type;
- var $solved = 0;
- var $captcha_vars = false;
-
- 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);
-
- $captcha = new captcha();
- 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;
- }
- }
- $captcha = new captcha();
- 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_class_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;
- }
-
-}
-
-/**
-* Old class name for legacy use. The new class name is auto loadable.
-*/
-class phpbb_default_captcha extends phpbb_captcha_plugins_captcha_abstract
-{
-}
diff --git a/phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php
deleted file mode 100644
index 8dbd458ede..0000000000
--- a/phpBB/includes/captcha/plugins/phpbb_captcha_gd_plugin.php
+++ /dev/null
@@ -1,158 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Placeholder for autoload
-*/
-if (!class_exists('phpbb_default_captcha', false))
-{
- include($phpbb_root_path . 'includes/captcha/plugins/captcha_abstract.' . $phpEx);
-}
-
-class phpbb_captcha_gd extends phpbb_default_captcha
-{
-
- 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',
- );
-
- function phpbb_captcha_gd()
- {
- global $phpbb_root_path, $phpEx;
-
- if (!class_exists('captcha'))
- {
- include($phpbb_root_path . 'includes/captcha/captcha_gd.' . $phpEx);
- }
- }
-
- static public function get_instance()
- {
- $instance = new phpbb_captcha_gd();
- return $instance;
- }
-
- static public function is_available()
- {
- return @extension_loaded('gd');
- }
-
- /**
- * API function
- */
- function has_config()
- {
- return true;
- }
-
- static public function get_name()
- {
- return 'CAPTCHA_GD';
- }
-
- function get_class_name()
- {
- return 'phpbb_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_class_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/includes/captcha/plugins/phpbb_captcha_gd_wave_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_gd_wave_plugin.php
deleted file mode 100644
index b6ccabaa2e..0000000000
--- a/phpBB/includes/captcha/plugins/phpbb_captcha_gd_wave_plugin.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Placeholder for autoload
-*/
-if (!class_exists('phpbb_default_captcha', false))
-{
- include($phpbb_root_path . 'includes/captcha/plugins/captcha_abstract.' . $phpEx);
-}
-
-class phpbb_captcha_gd_wave extends phpbb_default_captcha
-{
-
- function phpbb_captcha_gd_wave()
- {
- global $phpbb_root_path, $phpEx;
-
- if (!class_exists('captcha'))
- {
- include_once($phpbb_root_path . 'includes/captcha/captcha_gd_wave.' . $phpEx);
- }
- }
-
- static public function get_instance()
- {
- return new phpbb_captcha_gd_wave();
- }
-
- static public function is_available()
- {
- return @extension_loaded('gd');
- }
-
- static public function get_name()
- {
- return 'CAPTCHA_GD_3D';
- }
-
- function get_class_name()
- {
- 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/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php
deleted file mode 100644
index 64f788a659..0000000000
--- a/phpBB/includes/captcha/plugins/phpbb_captcha_nogd_plugin.php
+++ /dev/null
@@ -1,70 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Placeholder for autoload
-*/
-if (!class_exists('phpbb_default_captcha', false))
-{
- include($phpbb_root_path . 'includes/captcha/plugins/captcha_abstract.' . $phpEx);
-}
-
-class phpbb_captcha_nogd extends phpbb_default_captcha
-{
-
- function phpbb_captcha_nogd()
- {
- global $phpbb_root_path, $phpEx;
-
- if (!class_exists('captcha'))
- {
- include_once($phpbb_root_path . 'includes/captcha/captcha_non_gd.' . $phpEx);
- }
- }
-
- static public function get_instance()
- {
- $instance = new phpbb_captcha_nogd();
- return $instance;
- }
-
- static public function is_available()
- {
- return true;
- }
-
- static public function get_name()
- {
- return 'CAPTCHA_NO_GD';
- }
-
- function get_class_name()
- {
- return 'phpbb_captcha_nogd';
- }
-
- function acp_page($id, &$module)
- {
- global $user;
-
- trigger_error($user->lang['CAPTCHA_NO_OPTIONS'] . adm_back_link($module->u_action));
- }
-}
diff --git a/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php
deleted file mode 100644
index 5a44755365..0000000000
--- a/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php
+++ /dev/null
@@ -1,998 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-global $table_prefix;
-
-define('CAPTCHA_QUESTIONS_TABLE', $table_prefix . 'captcha_questions');
-define('CAPTCHA_ANSWERS_TABLE', $table_prefix . 'captcha_answers');
-define('CAPTCHA_QA_CONFIRM_TABLE', $table_prefix . 'qa_confirm');
-
-/**
-* And now to something completely different. Let's make a captcha without extending the abstract class.
-* QA CAPTCHA sample implementation
-*/
-class phpbb_captcha_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;
-
- /**
- * @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 ' . CAPTCHA_QUESTIONS_TABLE . "
- 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 ' . CAPTCHA_QUESTIONS_TABLE . "
- 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();
- }
- }
-
- /**
- * API function
- */
- static public function get_instance()
- {
- $instance = new phpbb_captcha_qa();
-
- return $instance;
- }
-
- /**
- * See if the captcha has created its tables.
- */
- static public function is_installed()
- {
- global $db;
-
- $db_tool = new \phpbb\db\tools($db);
-
- return $db_tool->sql_table_exists(CAPTCHA_QUESTIONS_TABLE);
- }
-
- /**
- * 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
- */
- static 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 (!self::is_installed())
- {
- return false;
- }
-
- $sql = 'SELECT COUNT(question_id) AS question_count
- FROM ' . CAPTCHA_QUESTIONS_TABLE . "
- 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';
- }
-
- /**
- * API function
- */
- function get_class_name()
- {
- return 'phpbb_captcha_qa';
- }
-
- /**
- * 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 ' . CAPTCHA_QUESTIONS_TABLE . "
- 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 ' . CAPTCHA_QA_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['confirm_id'];
- }
- while ($row = $db->sql_fetchrow($result));
-
- if (sizeof($sql_in))
- {
- $sql = 'DELETE FROM ' . CAPTCHA_QA_CONFIRM_TABLE . '
- 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(CAPTCHA_QUESTIONS_TABLE, CAPTCHA_ANSWERS_TABLE, CAPTCHA_QA_CONFIRM_TABLE);
-
- $schemas = array(
- CAPTCHA_QUESTIONS_TABLE => 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'),
- ),
- ),
- CAPTCHA_ANSWERS_TABLE => array (
- 'COLUMNS' => array(
- 'question_id' => array('UINT', 0),
- 'answer_text' => array('STEXT_UNI', ''),
- ),
- 'KEYS' => array(
- 'qid' => array('INDEX', 'question_id'),
- ),
- ),
- CAPTCHA_QA_CONFIRM_TABLE => 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 ' . CAPTCHA_QA_CONFIRM_TABLE . ' ' . $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 ' . CAPTCHA_QA_CONFIRM_TABLE . '
- 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 ' . CAPTCHA_QA_CONFIRM_TABLE . '
- 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 ' . CAPTCHA_QA_CONFIRM_TABLE . "
- 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 ' . CAPTCHA_QA_CONFIRM_TABLE . ' con, ' . CAPTCHA_QUESTIONS_TABLE . " 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 ' . CAPTCHA_ANSWERS_TABLE . '
- 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 ' . CAPTCHA_QA_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->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_class_name();
-
- $template->assign_vars(array(
- 'U_ACTION' => $module->u_action,
- 'QUESTION_ID' => $question_id ,
- 'CLASS' => $this->get_class_name(),
- ));
-
- // show the list?
- if (!$question_id && $action != 'add')
- {
- $this->acp_question_list($module);
- }
- else if ($question_id && $action == 'delete')
- {
- if ($this->get_class_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_class_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 ' . CAPTCHA_QUESTIONS_TABLE;
- $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_class_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 ' . CAPTCHA_QUESTIONS_TABLE . '
- 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 ' . CAPTCHA_ANSWERS_TABLE . '
- 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 ' . CAPTCHA_ANSWERS_TABLE . " 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 ' . CAPTCHA_QUESTIONS_TABLE . '
- 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', CAPTCHA_QUESTIONS_TABLE);
- }
-
- /**
- * 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 ' . CAPTCHA_QUESTIONS_TABLE . ' ' . $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', CAPTCHA_QUESTIONS_TABLE);
- }
-
- /**
- * 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 ' . CAPTCHA_ANSWERS_TABLE . ' ' . $db->sql_build_array('INSERT', $answer_ary);
- $db->sql_query($sql);
- }
-
- $cache->destroy('sql', CAPTCHA_ANSWERS_TABLE);
- }
-
- /**
- * Delete a question.
- */
- function acp_delete_question($question_id)
- {
- global $db, $cache;
-
- $tables = array(CAPTCHA_QUESTIONS_TABLE, CAPTCHA_ANSWERS_TABLE);
-
- 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 ' . CAPTCHA_QUESTIONS_TABLE . "
- 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/includes/captcha/plugins/phpbb_recaptcha_plugin.php b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php
deleted file mode 100644
index 12cc49ef9b..0000000000
--- a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php
+++ /dev/null
@@ -1,345 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-if (!class_exists('phpbb_default_captcha', false))
-{
- // we need the classic captcha code for tracking solutions and attempts
- include($phpbb_root_path . 'includes/captcha/plugins/captcha_abstract.' . $phpEx);
-}
-
-class phpbb_recaptcha extends phpbb_default_captcha
-{
- 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', '');
- }
-
- static public function get_instance()
- {
- $instance = new phpbb_recaptcha();
- return $instance;
- }
-
- static 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';
- }
-
- function get_class_name()
- {
- return 'phpbb_recaptcha';
- }
-
- 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_class_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/includes/compatibility_globals.php b/phpBB/includes/compatibility_globals.php
index 2a60f7fb8e..54c9287c96 100644
--- a/phpBB/includes/compatibility_globals.php
+++ b/phpBB/includes/compatibility_globals.php
@@ -43,6 +43,5 @@ $phpbb_path_helper = $phpbb_container->get('path_helper');
// load extensions
$phpbb_extension_manager = $phpbb_container->get('ext.manager');
-$phpbb_subscriber_loader = $phpbb_container->get('event.subscriber_loader');
$template = $phpbb_container->get('template');
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index cd4e19bf1d..b72e4ab6d4 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))
*/
// phpBB Version
-define('PHPBB_VERSION', '3.1.0-RC3-dev');
+define('PHPBB_VERSION', '3.1.0-RC5-dev');
// QA-related
// define('PHPBB_QA', 1);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 4318b20b97..7700dcfd27 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -31,7 +31,7 @@ function phpbb_load_extensions_autoloaders($phpbb_root_path)
new \phpbb\recursive_dot_prefix_filter_iterator(
new \RecursiveDirectoryIterator(
$phpbb_root_path . 'ext/',
- \FilesystemIterator::SKIP_DOTS
+ \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS
)
),
\RecursiveIteratorIterator::SELF_FIRST
@@ -289,7 +289,6 @@ function phpbb_gmgetdate($time = false)
* @param array $allowed_units only allow these units (data array indexes)
*
* @return mixed data array if $string_only is false
-* @author bantu
*/
function get_formatted_filesize($value, $string_only = true, $allowed_units = false)
{
@@ -463,7 +462,6 @@ function phpbb_version_compare($version1, $version2, $operator = null)
* @param int $perms Permissions to set
*
* @return bool true on success, otherwise false
-* @author faw, phpBB Limited
*/
function phpbb_chmod($filename, $perms = CHMOD_READ)
{
@@ -939,14 +937,20 @@ function style_select($default = '', $all = false)
* Format the timezone offset with hours and minutes
*
* @param int $tz_offset Timezone offset in seconds
+* @param bool $show_null Whether null offsets should be shown
* @return string Normalized offset string: -7200 => -02:00
* 16200 => +04:30
*/
-function phpbb_format_timezone_offset($tz_offset)
+function phpbb_format_timezone_offset($tz_offset, $show_null = false)
{
$sign = ($tz_offset < 0) ? '-' : '+';
$time_offset = abs($tz_offset);
+ if ($time_offset == 0 && $show_null == false)
+ {
+ return '';
+ }
+
$offset_seconds = $time_offset % 3600;
$offset_minutes = $offset_seconds / 60;
$offset_hours = ($time_offset - $offset_seconds) / 3600;
@@ -1042,13 +1046,14 @@ function phpbb_get_timezone_identifiers($selected_timezone)
/**
* Options to pick a timezone and date/time
*
+* @param \phpbb\template\template $template phpBB template object
* @param \phpbb\user $user Object of the current user
* @param string $default A timezone to select
* @param boolean $truncate Shall we truncate the options text
*
-* @return array Returns an array, also containing the options for the time selector.
+* @return array Returns an array containing the options for the time selector.
*/
-function phpbb_timezone_select($user, $default = '', $truncate = false)
+function phpbb_timezone_select($template, $user, $default = '', $truncate = false)
{
static $timezones;
@@ -1061,18 +1066,18 @@ function phpbb_timezone_select($user, $default = '', $truncate = false)
foreach ($unsorted_timezones as $timezone)
{
$tz = new DateTimeZone($timezone);
- $dt = new \phpbb\datetime($user, 'now', $tz);
+ $dt = $user->create_datetime('now', $tz);
$offset = $dt->getOffset();
$current_time = $dt->format($user->lang['DATETIME_FORMAT'], true);
- $offset_string = phpbb_format_timezone_offset($offset);
- $timezones['GMT' . $offset_string . ' - ' . $timezone] = array(
+ $offset_string = phpbb_format_timezone_offset($offset, true);
+ $timezones['UTC' . $offset_string . ' - ' . $timezone] = array(
'tz' => $timezone,
- 'offset' => 'GMT' . $offset_string,
+ 'offset' => $offset_string,
'current' => $current_time,
);
if ($timezone === $default)
{
- $default_offset = 'GMT' . $offset_string;
+ $default_offset = 'UTC' . $offset_string;
}
}
unset($unsorted_timezones);
@@ -1080,18 +1085,27 @@ function phpbb_timezone_select($user, $default = '', $truncate = false)
uksort($timezones, 'phpbb_tz_select_compare');
}
- $tz_select = $tz_dates = $opt_group = '';
+ $tz_select = $opt_group = '';
- foreach ($timezones as $timezone)
+ foreach ($timezones as $key => $timezone)
{
if ($opt_group != $timezone['offset'])
{
+ // Generate tz_select for backwards compatibility
$tz_select .= ($opt_group) ? '</optgroup>' : '';
- $tz_select .= '<optgroup label="' . $timezone['offset'] . ' - ' . $timezone['current'] . '">';
+ $tz_select .= '<optgroup label="' . $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $timezone['current']) . '">';
$opt_group = $timezone['offset'];
+ $template->assign_block_vars('timezone_select', array(
+ 'LABEL' => $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $timezone['current']),
+ 'VALUE' => $key . ' - ' . $timezone['current'],
+ ));
- $selected = ($default_offset == $timezone['offset']) ? ' selected="selected"' : '';
- $tz_dates .= '<option value="' . $timezone['offset'] . ' - ' . $timezone['current'] . '"' . $selected . '>' . $timezone['offset'] . ' - ' . $timezone['current'] . '</option>';
+ $selected = (!empty($default_offset) && strpos($key, $default_offset) !== false) ? ' selected="selected"' : '';
+ $template->assign_block_vars('timezone_date', array(
+ 'VALUE' => $key . ' - ' . $timezone['current'],
+ 'SELECTED' => !empty($selected),
+ 'TITLE' => $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $timezone['current']),
+ ));
}
$label = $timezone['tz'];
@@ -1099,22 +1113,26 @@ function phpbb_timezone_select($user, $default = '', $truncate = false)
{
$label = $user->lang['timezones'][$label];
}
- $title = $timezone['offset'] . ' - ' . $label;
+ $title = $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $label);
if ($truncate)
{
$label = truncate_string($label, 50, 255, false, '...');
}
+ // Also generate timezone_select for backwards compatibility
$selected = ($timezone['tz'] === $default) ? ' selected="selected"' : '';
$tz_select .= '<option title="' . $title . '" value="' . $timezone['tz'] . '"' . $selected . '>' . $label . '</option>';
+ $template->assign_block_vars('timezone_select.timezone_options', array(
+ 'TITLE' => $title,
+ 'VALUE' => $timezone['tz'],
+ 'SELECTED' => !empty($selected),
+ 'LABEL' => $label,
+ ));
}
$tz_select .= '</optgroup>';
- return array(
- 'tz_select' => $tz_select,
- 'tz_dates' => $tz_dates,
- );
+ return $tz_select;
}
// Functions handling topic/post tracking/marking
@@ -1146,12 +1164,12 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
// Mark all topic notifications read for this user
$phpbb_notifications->mark_notifications_read(array(
- 'topic',
- 'quote',
- 'bookmark',
- 'post',
- 'approve_topic',
- 'approve_post',
+ 'notification.type.topic',
+ 'notification.type.quote',
+ 'notification.type.bookmark',
+ 'notification.type.post',
+ 'notification.type.approve_topic',
+ 'notification.type.approve_post',
), false, $user->data['user_id'], $post_time);
if ($config['load_db_lastread'] && $user->data['is_registered'])
@@ -1211,8 +1229,8 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
$phpbb_notifications = $phpbb_container->get('notification_manager');
$phpbb_notifications->mark_notifications_read_by_parent(array(
- 'topic',
- 'approve_topic',
+ 'notification.type.topic',
+ 'notification.type.approve_topic',
), $forum_id, $user->data['user_id'], $post_time);
// Mark all post/quote notifications read for this user in this forum
@@ -1228,10 +1246,10 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
$db->sql_freeresult($result);
$phpbb_notifications->mark_notifications_read_by_parent(array(
- 'quote',
- 'bookmark',
- 'post',
- 'approve_post',
+ 'notification.type.quote',
+ 'notification.type.bookmark',
+ 'notification.type.post',
+ 'notification.type.approve_post',
), $topic_ids, $user->data['user_id'], $post_time);
// Add 0 to forums array to mark global announcements correctly
@@ -1334,15 +1352,15 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
// Mark post notifications read for this user in this topic
$phpbb_notifications->mark_notifications_read(array(
- 'topic',
- 'approve_topic',
+ 'notification.type.topic',
+ 'notification.type.approve_topic',
), $topic_id, $user->data['user_id'], $post_time);
$phpbb_notifications->mark_notifications_read_by_parent(array(
- 'quote',
- 'bookmark',
- 'post',
- 'approve_post',
+ 'notification.type.quote',
+ 'notification.type.bookmark',
+ 'notification.type.post',
+ 'notification.type.approve_post',
), $topic_id, $user->data['user_id'], $post_time);
if ($config['load_db_lastread'] && $user->data['is_registered'])
@@ -1638,7 +1656,7 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s
if (empty($sql_sort))
{
- $sql_sort = 'ORDER BY t.topic_last_post_time DESC';
+ $sql_sort = 'ORDER BY t.topic_last_post_time DESC, t.topic_last_post_id DESC';
}
if ($config['load_db_lastread'] && $user->data['is_registered'])
@@ -1991,6 +2009,9 @@ function tracking_unserialize($string, $max_depth = 3)
* @param mixed $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 bool $is_route Is url generated by a route.
+*
+* @return string The corrected url.
*
* Examples:
* <code>
@@ -2001,7 +2022,7 @@ function tracking_unserialize($string, $max_depth = 3)
* </code>
*
*/
-function append_sid($url, $params = false, $is_amp = true, $session_id = false)
+function append_sid($url, $params = false, $is_amp = true, $session_id = false, $is_route = false)
{
global $_SID, $_EXTRA_URL, $phpbb_hook, $phpbb_path_helper;
global $phpbb_dispatcher;
@@ -2013,7 +2034,7 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false)
}
// Update the root path with the correct relative web path
- if ($phpbb_path_helper instanceof \phpbb\path_helper)
+ if (!$is_route && $phpbb_path_helper instanceof \phpbb\path_helper)
{
$url = $phpbb_path_helper->update_web_root_path($url);
}
@@ -2039,9 +2060,10 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false)
* the global one (false)
* @var bool|string append_sid_overwrite Overwrite function (string
* URL) or not (false)
+ * @var bool is_route Is url generated by a route.
* @since 3.1.0-a1
*/
- $vars = array('url', 'params', 'is_amp', 'session_id', 'append_sid_overwrite');
+ $vars = array('url', 'params', 'is_amp', 'session_id', 'append_sid_overwrite', 'is_route');
extract($phpbb_dispatcher->trigger_event('core.append_sid', compact($vars)));
if ($append_sid_overwrite)
@@ -2540,7 +2562,7 @@ function check_link_hash($token, $link_name)
*/
function add_form_key($form_name)
{
- global $config, $template, $user;
+ global $config, $template, $user, $phpbb_dispatcher;
$now = time();
$token_sid = ($user->data['user_id'] == ANONYMOUS && !empty($config['form_token_sid_guests'])) ? $user->session_id : '';
@@ -2551,21 +2573,44 @@ function add_form_key($form_name)
'form_token' => $token,
));
+ /**
+ * Perform additional actions on creation of the form token
+ *
+ * @event core.add_form_key
+ * @var string form_name The form name
+ * @var int now Current time timestamp
+ * @var string s_fields Generated hidden fields
+ * @var string token Form token
+ * @var string token_sid User session ID
+ *
+ * @since 3.1.0-RC3
+ */
+ $vars = array(
+ 'form_name',
+ 'now',
+ 's_fields',
+ 'token',
+ 'token_sid',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.add_form_key', compact($vars)));
+
$template->assign_vars(array(
'S_FORM_TOKEN' => $s_fields,
));
}
/**
-* Check the form key. Required for all altering actions not secured by confirm_box
-* @param string $form_name The name of the form; has to match the name used in add_form_key, otherwise no restrictions apply
-* @param int $timespan The maximum acceptable age for a submitted form in seconds. Defaults to the config setting.
-* @param string $return_page The address for the return link
-* @param bool $trigger If true, the function will triger an error when encountering an invalid form
-*/
-function check_form_key($form_name, $timespan = false, $return_page = '', $trigger = false)
+ * Check the form key. Required for all altering actions not secured by confirm_box
+ *
+ * @param string $form_name The name of the form; has to match the name used
+ * in add_form_key, otherwise no restrictions apply
+ * @param int $timespan The maximum acceptable age for a submitted form
+ * in seconds. Defaults to the config setting.
+ * @return bool True, if the form key was valid, false otherwise
+ */
+function check_form_key($form_name, $timespan = false)
{
- global $config, $user;
+ global $config, $request, $user;
if ($timespan === false)
{
@@ -2573,10 +2618,10 @@ function check_form_key($form_name, $timespan = false, $return_page = '', $trigg
$timespan = ($config['form_token_lifetime'] == -1) ? -1 : max(30, $config['form_token_lifetime']);
}
- if (isset($_POST['creation_time']) && isset($_POST['form_token']))
+ if ($request->is_set_post('creation_time') && $request->is_set_post('form_token'))
{
- $creation_time = abs(request_var('creation_time', 0));
- $token = request_var('form_token', '');
+ $creation_time = abs($request->variable('creation_time', 0));
+ $token = $request->variable('form_token', '');
$diff = time() - $creation_time;
@@ -2593,11 +2638,6 @@ function check_form_key($form_name, $timespan = false, $return_page = '', $trigg
}
}
- if ($trigger)
- {
- trigger_error($user->lang['FORM_INVALID'] . $return_page);
- }
-
return false;
}
@@ -2728,12 +2768,7 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = false, $s_display = true)
{
global $db, $user, $template, $auth, $phpEx, $phpbb_root_path, $config;
- global $request, $phpbb_container;
-
- if (!class_exists('phpbb_captcha_factory', false))
- {
- include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
- }
+ global $request, $phpbb_container, $phpbb_dispatcher;
$err = '';
@@ -2818,8 +2853,18 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
if ($result['status'] == LOGIN_SUCCESS)
{
$redirect = request_var('redirect', "{$phpbb_root_path}index.$phpEx");
- $message = ($l_success) ? $l_success : $user->lang['LOGIN_REDIRECT'];
- $l_redirect = ($admin) ? $user->lang['PROCEED_TO_ACP'] : (($redirect === "{$phpbb_root_path}index.$phpEx" || $redirect === "index.$phpEx") ? $user->lang['RETURN_INDEX'] : $user->lang['RETURN_PAGE']);
+
+ /**
+ * This event allows an extension to modify the redirection when a user successfully logs in
+ *
+ * @event core.login_box_redirect
+ * @var string redirect Redirect string
+ * @var boolean admin Is admin?
+ * @var bool return If true, do not redirect but return the sanitized URL.
+ * @since 3.1.0-RC5
+ */
+ $vars = array('redirect', 'admin', 'return');
+ extract($phpbb_dispatcher->trigger_event('core.login_box_redirect', compact($vars)));
// append/replace SID (may change during the session for AOL users)
$redirect = reapply_sid($redirect);
@@ -2844,7 +2889,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
{
case LOGIN_ERROR_ATTEMPTS:
- $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
// $captcha->reset();
@@ -2956,7 +3001,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
*/
function login_forum_box($forum_data)
{
- global $db, $phpbb_container, $request, $template, $user;
+ global $db, $phpbb_container, $request, $template, $user, $phpbb_dispatcher;
$password = $request->variable('password', '', true);
@@ -3017,6 +3062,17 @@ function login_forum_box($forum_data)
$template->assign_var('LOGIN_ERROR', $user->lang['WRONG_PASSWORD']);
}
+ /**
+ * Performing additional actions, load additional data on forum login
+ *
+ * @event core.login_forum_box
+ * @var array forum_data Array with forum data
+ * @var string password Password entered
+ * @since 3.1.0-RC3
+ */
+ $vars = array('forum_data', 'password');
+ extract($phpbb_dispatcher->trigger_event('core.login_forum_box', compact($vars)));
+
page_header($user->lang['LOGIN']);
$template->assign_vars(array(
@@ -3293,6 +3349,11 @@ function get_preg_expression($mode)
case 'table_prefix':
return '#^[a-zA-Z][a-zA-Z0-9_]*$#';
break;
+
+ // Matches the predecing dot
+ case 'path_remove_dot_trailing_slash':
+ return '#^(?:(\.)?)+(?:(.+)?)+(?:([\\/\\\])$)#';
+ break;
}
return '';
@@ -3377,8 +3438,6 @@ function short_ipv6($ip, $length)
*
* @return mixed false if specified address is not valid,
* string otherwise
-*
-* @author bantu
*/
function phpbb_ip_normalise($address)
{
@@ -3407,8 +3466,6 @@ function phpbb_ip_normalise($address)
*
* @return mixed false on failure,
* string otherwise
-*
-* @author APTX
*/
function phpbb_inet_ntop($in_addr)
{
@@ -3478,8 +3535,6 @@ function phpbb_inet_ntop($in_addr)
*
* @return mixed false if address is invalid,
* in_addr representation of the given address otherwise (string)
-*
-* @author APTX
*/
function phpbb_inet_pton($address)
{
@@ -3559,8 +3614,6 @@ function phpbb_inet_pton($address)
*
* Since null can also be returned, you probably want to compare the result
* with === true or === false,
-*
-* @author bantu
*/
function phpbb_checkdnsrr($host, $type = 'MX')
{
@@ -4647,7 +4700,7 @@ function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config
/**
* Get avatar
*
-* @param array $row Row cleaned by \phpbb\avatar\driver\driver::clean_row
+* @param array $row Row cleaned by \phpbb\avatar\manager::clean_row
* @param string $alt Optional language string for alt tag within image, can be a language key or text
* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
*
@@ -4881,8 +4934,8 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
}
}
- $dt = new \phpbb\datetime($user, 'now', $user->timezone);
- $timezone_offset = 'GMT' . phpbb_format_timezone_offset($dt->getOffset());
+ $dt = $user->create_datetime();
+ $timezone_offset = $user->lang(array('timezones', 'UTC_OFFSET'), phpbb_format_timezone_offset($dt->getOffset()));
$timezone_name = $user->timezone->getName();
if (isset($user->lang['timezones'][$timezone_name]))
{
@@ -5041,6 +5094,19 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'SITE_LOGO_IMG' => $user->img('site_logo'),
));
+ // An array of http headers that phpbb will set. The following event may override these.
+ $http_headers = array(
+ // application/xhtml+xml not used because of IE
+ 'Content-type' => 'text/html; charset=UTF-8',
+ 'Cache-Control' => 'private, no-cache="set-cookie"',
+ 'Expires' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ );
+ if (!empty($user->data['is_bot']))
+ {
+ // Let reverse proxies know we detected a bot.
+ $http_headers['X-PHPBB-IS-BOT'] = 'yes';
+ }
+
/**
* Execute code and/or overwrite _common_ template variables after they have been assigned.
*
@@ -5051,23 +5117,16 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
* session item, e.g. forum for
* session_forum_id
* @var int item_id Restrict online users to item id
+ * @var array http_headers HTTP headers that should be set by phpbb
*
* @since 3.1.0-b3
*/
- $vars = array('page_title', 'display_online_list', 'item_id', 'item');
+ $vars = array('page_title', 'display_online_list', 'item_id', 'item', 'http_headers');
extract($phpbb_dispatcher->trigger_event('core.page_header_after', compact($vars)));
- // application/xhtml+xml not used because of IE
- header('Content-type: text/html; charset=UTF-8');
-
- header('Cache-Control: private, no-cache="set-cookie"');
- header('Expires: 0');
- header('Pragma: no-cache');
-
- if (!empty($user->data['is_bot']))
+ foreach ($http_headers as $hname => $hval)
{
- // Let reverse proxies know we detected a bot.
- header('X-PHPBB-IS-BOT: yes');
+ header((string) $hname . ': ' . (string) $hval);
}
return;
@@ -5095,9 +5154,10 @@ function phpbb_check_and_display_sql_report(\phpbb\request\request_interface $re
* @param \phpbb\config\config $config Config object
* @param \phpbb\auth\auth $auth Auth object
* @param \phpbb\user $user User object
+* @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher
* @return string
*/
-function phpbb_generate_debug_output(phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\auth\auth $auth, \phpbb\user $user)
+function phpbb_generate_debug_output(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\auth\auth $auth, \phpbb\user $user, \phpbb\event\dispatcher_interface $phpbb_dispatcher)
{
$debug_info = array();
@@ -5136,6 +5196,17 @@ function phpbb_generate_debug_output(phpbb\db\driver\driver_interface $db, \phpb
}
}
+ /**
+ * Modify debug output information
+ *
+ * @event core.phpbb_generate_debug_output
+ * @var array debug_info Array of strings with debug information
+ *
+ * @since 3.1.0-RC3
+ */
+ $vars = array('debug_info');
+ extract($phpbb_dispatcher->trigger_event('core.phpbb_generate_debug_output', compact($vars)));
+
return implode(' | ', $debug_info);
}
@@ -5174,7 +5245,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler =
phpbb_check_and_display_sql_report($request, $auth, $db);
$template->assign_vars(array(
- 'DEBUG_OUTPUT' => phpbb_generate_debug_output($db, $config, $auth, $user),
+ 'DEBUG_OUTPUT' => phpbb_generate_debug_output($db, $config, $auth, $user, $phpbb_dispatcher),
'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '',
'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>&reg; Forum Software &copy; phpBB Limited'),
@@ -5219,6 +5290,18 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler =
}
}
+ /**
+ * Execute code and/or modify output before displaying the template.
+ *
+ * @event core.page_footer_after
+ * @var bool display_template Whether or not to display the template
+ * @var bool exit_handler Whether or not to run the exit_handler()
+ *
+ * @since 3.1.0-RC5
+ */
+ $vars = array('display_template', 'exit_handler');
+ extract($phpbb_dispatcher->trigger_event('core.page_footer_after', compact($vars)));
+
if ($display_template)
{
$template->display('body');
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index ad5a359710..e30c6da505 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -107,12 +107,30 @@ function adm_page_header($page_title)
'S_CONTENT_FLOW_END' => ($user->lang['DIRECTION'] == 'ltr') ? 'right' : 'left',
));
- // application/xhtml+xml not used because of IE
- header('Content-type: text/html; charset=UTF-8');
+ // An array of http headers that phpbb will set. The following event may override these.
+ $http_headers = array(
+ // application/xhtml+xml not used because of IE
+ 'Content-type' => 'text/html; charset=UTF-8',
+ 'Cache-Control' => 'private, no-cache="set-cookie"',
+ 'Expires' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ );
- header('Cache-Control: private, no-cache="set-cookie"');
- header('Expires: 0');
- header('Pragma: no-cache');
+ /**
+ * Execute code and/or overwrite _common_ template variables after they have been assigned.
+ *
+ * @event core.adm_page_header_after
+ * @var string page_title Page title
+ * @var array http_headers HTTP headers that should be set by phpbb
+ *
+ * @since 3.1.0-RC3
+ */
+ $vars = array('page_title', 'http_headers');
+ extract($phpbb_dispatcher->trigger_event('core.adm_page_header_after', compact($vars)));
+
+ foreach ($http_headers as $hname => $hval)
+ {
+ header((string) $hname . ': ' . (string) $hval);
+ }
return;
}
@@ -149,7 +167,7 @@ function adm_page_footer($copyright_html = true)
phpbb_check_and_display_sql_report($request, $auth, $db);
$template->assign_vars(array(
- 'DEBUG_OUTPUT' => phpbb_generate_debug_output($db, $config, $auth, $user),
+ 'DEBUG_OUTPUT' => phpbb_generate_debug_output($db, $config, $auth, $user, $phpbb_dispatcher),
'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '',
'S_COPYRIGHT_HTML' => $copyright_html,
'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>&reg; Forum Software &copy; phpBB Limited'),
@@ -655,3 +673,30 @@ function validate_range($value_ary, &$error)
}
}
}
+
+/**
+* Inserts new config display_vars into an exisiting display_vars array
+* at the given position.
+*
+* @param array $display_vars An array of existing config display vars
+* @param array $add_config_vars An array of new config display vars
+* @param array $where Where to place the new config vars,
+* before or after an exisiting config, as an array
+* of the form: array('after' => 'config_name') or
+* array('before' => 'config_name').
+* @return array The array of config display vars
+*/
+function phpbb_insert_config_array($display_vars, $add_config_vars, $where)
+{
+ if (is_array($where) && array_key_exists(current($where), $display_vars))
+ {
+ $position = array_search(current($where), array_keys($display_vars)) + ((key($where) == 'before') ? 0 : 1);
+ $display_vars = array_merge(
+ array_slice($display_vars, 0, $position),
+ $add_config_vars,
+ array_slice($display_vars, $position)
+ );
+ }
+
+ return $display_vars;
+}
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index accc8a6a83..e3e8657afb 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -27,8 +27,6 @@ if (!defined('IN_PHPBB'))
* @param string $table constant or fullname of the table
* @param int $parent_id parent_id of the current set (default = 0)
* @param array $where contains strings to compare closer on the where statement (additional)
-*
-* @author EXreaction
*/
function recalc_nested_sets(&$new_id, $pkey, $table, $parent_id = 0, $where = array())
{
@@ -315,8 +313,6 @@ function get_forum_branch($forum_id, $type = 'all', $order = 'descending', $incl
* @param bool $add_log True if log entry should be added
*
* @return bool False on error
-*
-* @author bantu
*/
function copy_forum_permissions($src_forum_id, $dest_forum_ids, $clear_dest_perms = true, $add_log = true)
{
@@ -722,9 +718,9 @@ function delete_topics($where_type, $where_ids, $auto_sync = true, $post_count_s
$phpbb_notifications = $phpbb_container->get('notification_manager');
$phpbb_notifications->delete_notifications(array(
- 'topic',
- 'approve_topic',
- 'topic_in_queue',
+ 'notification.type.topic',
+ 'notification.type.approve_topic',
+ 'notification.type.topic_in_queue',
), $topic_ids);
return $return;
@@ -739,9 +735,9 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
// Notifications types to delete
$delete_notifications_types = array(
- 'quote',
- 'approve_post',
- 'post_in_queue',
+ 'notification.type.quote',
+ 'notification.type.approve_post',
+ 'notification.type.post_in_queue',
);
/**
@@ -1224,8 +1220,6 @@ function delete_attachments($mode, $ids, $resync = true)
* @param bool $auto_sync Will call sync() if this is true
*
* @return array Array with affected forums
-*
-* @author bantu
*/
function delete_topic_shadows($forum_id, $sql_more = '', $auto_sync = true)
{
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
index 093cb19538..fbb1f0e03d 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -133,10 +133,9 @@ function phpbb_clean_path($path)
*/
function tz_select($default = '', $truncate = false)
{
- global $user;
+ global $template, $user;
- $timezone_select = phpbb_timezone_select($user, $default, $truncate);
- return $timezone_select['tz_select'];
+ return phpbb_timezone_select($template, $user, $default, $truncate);
}
/**
@@ -166,3 +165,30 @@ function update_foes($group_id = false, $user_id = false)
global $db, $auth;
return phpbb_update_foes($db, $auth, $group_id, $user_id);
}
+
+/**
+* Get user rank title and image
+*
+* @param int $user_rank the current stored users rank id
+* @param int $user_posts the users number of posts
+* @param string &$rank_title the rank title will be stored here after execution
+* @param string &$rank_img the rank image as full img tag is stored here after execution
+* @param string &$rank_img_src the rank image source is stored here after execution
+*
+* @deprecated 3.1.0-RC5 (To be removed: 3.3.0)
+*
+* Note: since we do not want to break backwards-compatibility, this function will only properly assign ranks to guests if you call it for them with user_posts == false
+*/
+function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank_img_src)
+{
+ global $phpbb_root_path, $phpEx;
+ if (!function_exists('phpbb_get_user_rank'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
+
+ $rank_data = phpbb_get_user_rank(array('user_rank' => $user_rank), $user_posts);
+ $rank_title = $rank_data['title'];
+ $rank_img = $rank_data['img'];
+ $rank_img_src = $rank_data['img_src'];
+}
diff --git a/phpBB/includes/functions_compress.php b/phpBB/includes/functions_compress.php
index 6ed69d6928..a7ee29dd91 100644
--- a/phpBB/includes/functions_compress.php
+++ b/phpBB/includes/functions_compress.php
@@ -509,7 +509,7 @@ class compress_zip extends compress
$mimetype = 'application/zip';
- header('Pragma: no-cache');
+ header('Cache-Control: private, no-cache');
header("Content-Type: $mimetype; name=\"$download_name.zip\"");
header("Content-disposition: attachment; filename=$download_name.zip");
@@ -757,7 +757,7 @@ class compress_tar extends compress
break;
}
- header('Pragma: no-cache');
+ header('Cache-Control: private, no-cache');
header("Content-Type: $mimetype; name=\"$download_name$this->type\"");
header("Content-disposition: attachment; filename=$download_name$this->type");
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index ee78364083..25ca50e8f1 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -912,7 +912,7 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
return;
}
- global $template, $cache, $user;
+ global $template, $cache, $user, $phpbb_dispatcher;
global $extensions, $config, $phpbb_root_path, $phpEx;
//
@@ -1187,6 +1187,34 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count,
);
}
+ /**
+ * Use this event to modify the attachment template data.
+ *
+ * This event is triggered once per attachment.
+ *
+ * @event core.parse_attachments_modify_template_data
+ * @var array attachment Array with attachment data
+ * @var array block_array Template data of the attachment
+ * @var int display_cat Attachment category data
+ * @var string download_link Attachment download link
+ * @var array extensions Array with attachment extensions data
+ * @var mixed forum_id The forum id the attachments are displayed in (false if in private message)
+ * @var bool preview Flag indicating if we are in post preview mode
+ * @var array update_count Array with attachment ids to update download count
+ * @since 3.1.0-RC5
+ */
+ $vars = array(
+ 'attachment',
+ 'block_array',
+ 'display_cat',
+ 'download_link',
+ 'extensions',
+ 'forum_id',
+ 'preview',
+ 'update_count',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.parse_attachments_modify_template_data', compact($vars)));
+
$template->assign_block_vars('_file', $block_array);
$compiled_attachments[] = $template->assign_display('attachment_tpl');
@@ -1323,7 +1351,6 @@ function truncate_string($string, $max_length = 60, $max_store_length = 255, $al
* @param string $custom_profile_url optional parameter to specify a profile url. The user id get appended to this url as &amp;u={user_id}
*
* @return string A string consisting of what is wanted based on $mode.
-* @author BartVB, Acyd Burn
*/
function get_username_string($mode, $user_id, $username, $username_colour = '', $guest_username = false, $custom_profile_url = false)
{
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index 62f218cf60..745eb20c77 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -379,10 +379,10 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$last_catless = true;
foreach ($forum_rows as $row)
{
- // Empty category
+ // Category
if ($row['parent_id'] == $root_data['forum_id'] && $row['forum_type'] == FORUM_CAT)
{
- $template->assign_block_vars('forumrow', array(
+ $cat_row = array(
'S_IS_CAT' => true,
'FORUM_ID' => $row['forum_id'],
'FORUM_NAME' => $row['forum_name'],
@@ -391,9 +391,33 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'FORUM_FOLDER_IMG_SRC' => '',
'FORUM_IMAGE' => ($row['forum_image']) ? '<img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="' . $user->lang['FORUM_CAT'] . '" />' : '',
'FORUM_IMAGE_SRC' => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '',
- 'U_VIEWFORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']))
+ 'U_VIEWFORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']),
);
+ /**
+ * Modify the template data block of the 'category'
+ *
+ * This event is triggered once per 'category'
+ *
+ * @event core.display_forums_modify_category_template_vars
+ * @var array cat_row Template data of the 'category'
+ * @var bool catless The flag indicating whether the 'category' has a parent category
+ * @var bool last_catless The flag indicating whether the last forum had a parent category
+ * @var array root_data Array with the root forum data
+ * @var array row The data of the 'category'
+ * @since 3.1.0-RC4
+ */
+ $vars = array(
+ 'cat_row',
+ 'catless',
+ 'last_catless',
+ 'root_data',
+ 'row',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_category_template_vars', compact($vars)));
+
+ $template->assign_block_vars('forumrow', $cat_row);
+
continue;
}
@@ -625,6 +649,28 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'UNAPPROVED_POST_IMG' => $user->img('icon_topic_unapproved', 'POSTS_UNAPPROVED_FORUM'),
));
+ /**
+ * Event to perform additional actions after the forum list has been generated
+ *
+ * @event core.display_forums_after
+ * @var array active_forum_ary Array with forum data to display active topics
+ * @var bool display_moderators Flag indicating if we display forum moderators
+ * @var array forum_moderators Array with forum moderators list
+ * @var array forum_rows Data array of all forums we display
+ * @var bool return_moderators Flag indicating if moderators list should be returned
+ * @var array root_data Array with the root forum data
+ * @since 3.1.0-RC5
+ */
+ $vars = array(
+ 'active_forum_ary',
+ 'display_moderators',
+ 'forum_moderators',
+ 'forum_rows',
+ 'return_moderators',
+ 'root_data',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.display_forums_after', compact($vars)));
+
if ($return_moderators)
{
return array($active_forum_ary, $forum_moderators);
@@ -1378,17 +1424,34 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id,
/**
* Get user rank title and image
*
-* @param int $user_rank the current stored users rank id
+* @param array $user_data the current stored users data
* @param int $user_posts the users number of posts
-* @param string &$rank_title the rank title will be stored here after execution
-* @param string &$rank_img the rank image as full img tag is stored here after execution
-* @param string &$rank_img_src the rank image source is stored here after execution
+*
+* @return array An associative array containing the rank title (title), the rank image source (img) and the rank image as full img tag (img)
*
* Note: since we do not want to break backwards-compatibility, this function will only properly assign ranks to guests if you call it for them with user_posts == false
*/
-function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank_img_src)
+function phpbb_get_user_rank($user_data, $user_posts)
{
- global $ranks, $config, $phpbb_root_path, $phpbb_path_helper;
+ global $ranks, $config, $phpbb_root_path, $phpbb_path_helper, $phpbb_dispatcher;
+
+ $user_rank_data = array(
+ 'title' => null,
+ 'img' => null,
+ 'img_src' => null,
+ );
+
+ /**
+ * Preparing a user's rank before displaying
+ *
+ * @event core.modify_user_rank
+ * @var array user_data Array with user's data
+ * @var int user_posts User_posts to change
+ * @since 3.1.0-RC4
+ */
+
+ $vars = array('user_data', 'user_posts');
+ extract($phpbb_dispatcher->trigger_event('core.modify_user_rank', compact($vars)));
if (empty($ranks))
{
@@ -1396,11 +1459,14 @@ function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank
$ranks = $cache->obtain_ranks();
}
- if (!empty($user_rank))
+ if (!empty($user_data['user_rank']))
{
- $rank_title = (isset($ranks['special'][$user_rank]['rank_title'])) ? $ranks['special'][$user_rank]['rank_title'] : '';
- $rank_img_src = (!empty($ranks['special'][$user_rank]['rank_image'])) ? $phpbb_path_helper->update_web_root_path($phpbb_root_path . $config['ranks_path'] . '/' . $ranks['special'][$user_rank]['rank_image']) : '';
- $rank_img = (!empty($ranks['special'][$user_rank]['rank_image'])) ? '<img src="' . $rank_img_src . '" alt="' . $ranks['special'][$user_rank]['rank_title'] . '" title="' . $ranks['special'][$user_rank]['rank_title'] . '" />' : '';
+
+ $user_rank_data['title'] = (isset($ranks['special'][$user_data['user_rank']]['rank_title'])) ? $ranks['special'][$user_data['user_rank']]['rank_title'] : '';
+
+ $user_rank_data['img_src'] = (!empty($ranks['special'][$user_data['user_rank']]['rank_image'])) ? $phpbb_path_helper->update_web_root_path($phpbb_root_path . $config['ranks_path'] . '/' . $ranks['special'][$user_data['user_rank']]['rank_image']) : '';
+
+ $user_rank_data['img'] = (!empty($ranks['special'][$user_data['user_rank']]['rank_image'])) ? '<img src="' . $user_rank_data['img_src'] . '" alt="' . $ranks['special'][$user_data['user_rank']]['rank_title'] . '" title="' . $ranks['special'][$user_data['user_rank']]['rank_title'] . '" />' : '';
}
else if ($user_posts !== false)
{
@@ -1410,52 +1476,16 @@ function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank
{
if ($user_posts >= $rank['rank_min'])
{
- $rank_title = $rank['rank_title'];
- $rank_img_src = (!empty($rank['rank_image'])) ? $phpbb_path_helper->update_web_root_path($phpbb_root_path . $config['ranks_path'] . '/' . $rank['rank_image']) : '';
- $rank_img = (!empty($rank['rank_image'])) ? '<img src="' . $rank_img_src . '" alt="' . $rank['rank_title'] . '" title="' . $rank['rank_title'] . '" />' : '';
+ $user_rank_data['title'] = $rank['rank_title'];
+ $user_rank_data['img_src'] = (!empty($rank['rank_image'])) ? $phpbb_path_helper->update_web_root_path($phpbb_root_path . $config['ranks_path'] . '/' . $rank['rank_image']) : '';
+ $user_rank_data['img'] = (!empty($rank['rank_image'])) ? '<img src="' . $user_rank_data['img_src'] . '" alt="' . $rank['rank_title'] . '" title="' . $rank['rank_title'] . '" />' : '';
break;
}
}
}
}
-}
-
-/**
-* Generate a list of archive types available for compressing attachments
-*
-* @param string $param_key Either topic_id or post_id
-* @param string $param_val The value of the topic or post id
-* @param string $phpbb_root_path The root path of the phpBB installation
-* @param string $phpEx The PHP file extension
-*
-* @return array Array containing the link and the type of compression
-*/
-function phpbb_gen_download_links($param_key, $param_val, $phpbb_root_path, $phpEx)
-{
- if (!class_exists('compress'))
- {
- require $phpbb_root_path . 'includes/functions_compress.' . $phpEx;
- }
-
- $methods = compress::methods();
- // Sort by preferred type.
- $methods = array_intersect(array('.zip', '.tar.bz2', '.tar.gz', '.tar'), $methods);
- $links = array();
-
- foreach ($methods as $method)
- {
- $exploded = explode('.', $method);
- $type = array_pop($exploded);
- $params = array('archive' => $method);
- $params[$param_key] = $param_val;
-
- $links[] = array(
- 'LINK' => append_sid("{$phpbb_root_path}download/file.$phpEx", $params),
- 'TYPE' => $type,
- );
- }
- return $links;
+ return $user_rank_data;
}
/**
@@ -1468,8 +1498,7 @@ function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabl
$username = $data['username'];
$user_id = $data['user_id'];
- $rank_title = $rank_img = $rank_img_src = '';
- get_user_rank($data['user_rank'], (($user_id == ANONYMOUS) ? false : $data['user_posts']), $rank_title, $rank_img, $rank_img_src);
+ $user_rank_data = phpbb_get_user_rank($data, (($user_id == ANONYMOUS) ? false : $data['user_posts']));
if ((!empty($data['user_allow_viewemail']) && $auth->acl_get('u_sendemail')) || $auth->acl_get('a_user'))
{
@@ -1550,7 +1579,7 @@ function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabl
// Dump it out to the template
$template_data = array(
'AGE' => $age,
- 'RANK_TITLE' => $rank_title,
+ 'RANK_TITLE' => $user_rank_data['title'],
'JOINED' => $user->format_date($data['user_regdate']),
'LAST_ACTIVE' => (empty($last_active)) ? ' - ' : $user->format_date($last_active),
'POSTS' => ($data['user_posts']) ? $data['user_posts'] : 0,
@@ -1566,8 +1595,8 @@ function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabl
'AVATAR_IMG' => phpbb_get_user_avatar($data),
'ONLINE_IMG' => (!$config['load_onlinetrack']) ? '' : (($online) ? $user->img('icon_user_online', 'ONLINE') : $user->img('icon_user_offline', 'OFFLINE')),
'S_ONLINE' => ($config['load_onlinetrack'] && $online) ? true : false,
- 'RANK_IMG' => $rank_img,
- 'RANK_IMG_SRC' => $rank_img_src,
+ 'RANK_IMG' => $user_rank_data['img'],
+ 'RANK_IMG_SRC' => $user_rank_data['img_src'],
'S_JABBER_ENABLED' => ($config['jab_enable']) ? true : false,
'S_WARNINGS' => ($auth->acl_getf_global('m_') || $auth->acl_get('m_warn')) ? true : false,
diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php
index 7a7efd5b34..fbeae50f55 100644
--- a/phpBB/includes/functions_download.php
+++ b/phpBB/includes/functions_download.php
@@ -45,28 +45,28 @@ function send_avatar_to_browser($file, $browser)
if ((@file_exists($file_path) && @is_readable($file_path)) && !headers_sent())
{
- header('Pragma: public');
+ header('Cache-Control: public');
$image_data = @getimagesize($file_path);
header('Content-Type: ' . image_type_to_mime_type($image_data[2]));
- if ((strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($browser, 7))
+ if ((strpos(strtolower($browser), 'msie') !== false) && !phpbb_is_greater_ie_version($browser, 7))
{
header('Content-Disposition: attachment; ' . header_filename($file));
if (strpos(strtolower($browser), 'msie 6.0') !== false)
{
- header('Expires: -1');
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
}
else
{
- header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000));
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');
}
}
else
{
header('Content-Disposition: inline; ' . header_filename($file));
- header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000));
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');
}
$size = @filesize($file_path);
@@ -175,7 +175,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)
}
// Now the tricky part... let's dance
- header('Pragma: public');
+ header('Cache-Control: public');
// Send out the Headers. Do not set Content-Disposition to inline please, it is a security measure for users using the Internet Explorer.
header('Content-Type: ' . $attachment['mimetype']);
@@ -197,7 +197,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)
header('Content-Disposition: attachment; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
if (empty($user->browser) || (strpos(strtolower($user->browser), 'msie 6.0') !== false))
{
- header('expires: -1');
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
}
}
else
@@ -420,8 +420,8 @@ function set_modified_headers($stamp, $browser)
{
send_status_line(304, 'Not Modified');
// seems that we need those too ... browsers
- header('Pragma: public');
- header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000));
+ header('Cache-Control: public');
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');
return true;
}
else
@@ -718,27 +718,6 @@ function phpbb_download_check_pm_auth($db, $user_id, $msg_id)
}
/**
-* Cleans a filename of any characters that could potentially cause a problem on
-* a user's filesystem.
-*
-* @param string $filename The filename to clean
-*
-* @return string The cleaned filename
-*/
-function phpbb_download_clean_filename($filename)
-{
- $bad_chars = array("'", "\\", ' ', '/', ':', '*', '?', '"', '<', '>', '|');
-
- // rawurlencode to convert any potentially 'bad' characters that we missed
- $filename = rawurlencode(str_replace($bad_chars, '_', $filename));
-
- // Turn the %xx entities created by rawurlencode to _
- $filename = preg_replace("/%(\w{2})/", '_', $filename);
-
- return $filename;
-}
-
-/**
* Check if the browser is internet explorer version 7+
*
* @param string $user_agent User agent HTTP header
diff --git a/phpBB/includes/functions_mcp.php b/phpBB/includes/functions_mcp.php
index 7593f08f4d..811d49f1de 100644
--- a/phpBB/includes/functions_mcp.php
+++ b/phpBB/includes/functions_mcp.php
@@ -521,21 +521,21 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
$limit_days = array(0 => $user->lang['ALL_TOPICS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
$sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'tt' => $user->lang['TOPIC_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']);
- $sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_post_time', 'tt' => 't.topic_time', 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'), 's' => 't.topic_title', 'v' => 't.topic_views');
+ $sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => array('t.topic_last_post_time', 't.topic_last_post_id'), 'tt' => 't.topic_time', 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'), 's' => 't.topic_title', 'v' => 't.topic_views');
$limit_time_sql = ($min_time) ? "AND t.topic_last_post_time >= $min_time" : '';
break;
case 'posts':
$limit_days = array(0 => $user->lang['ALL_POSTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
$sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 's' => $user->lang['SUBJECT']);
- $sort_by_sql = array('a' => 'u.username_clean', 't' => 'p.post_time', 's' => 'p.post_subject');
+ $sort_by_sql = array('a' => 'u.username_clean', 't' => array('p.post_time', 'p.post_id'), 's' => 'p.post_subject');
$limit_time_sql = ($min_time) ? "AND p.post_time >= $min_time" : '';
break;
case 'reports':
$limit_days = array(0 => $user->lang['ALL_REPORTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
$sort_by_text = array('a' => $user->lang['AUTHOR'], 'r' => $user->lang['REPORTER'], 'p' => $user->lang['POST_TIME'], 't' => $user->lang['REPORT_TIME'], 's' => $user->lang['SUBJECT']);
- $sort_by_sql = array('a' => 'u.username_clean', 'r' => 'ru.username', 'p' => 'p.post_time', 't' => 'r.report_time', 's' => 'p.post_subject');
+ $sort_by_sql = array('a' => 'u.username_clean', 'r' => 'ru.username', 'p' => array('p.post_time', 'p.post_id'), 't' => 'r.report_time', 's' => 'p.post_subject');
break;
case 'pm_reports':
@@ -558,7 +558,16 @@ function phpbb_mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by
$sort_key = $default_key;
}
- $sort_order_sql = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
+ $direction = ($sort_dir == 'd') ? 'DESC' : 'ASC';
+
+ if (is_array($sort_by_sql[$sort_key]))
+ {
+ $sort_order_sql = implode(' ' . $direction . ', ', $sort_by_sql[$sort_key]) . ' ' . $direction;
+ }
+ else
+ {
+ $sort_order_sql = $sort_by_sql[$sort_key] . ' ' . $direction;
+ }
$s_limit_days = $s_sort_key = $s_sort_dir = $sort_url = '';
gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $sort_url);
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index 3657a89aa0..045e555d05 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -402,17 +402,9 @@ class messenger
*/
function generate_message_id()
{
- global $config;
+ global $config, $request;
- $domain = 'phpbb.generated';
- if ($config['server_name'])
- {
- $domain = $config['server_name'];
- }
- else if (!empty($_SERVER['SERVER_NAME']))
- {
- $domain = $_SERVER['SERVER_NAME'];
- }
+ $domain = ($config['server_name']) ?: $request->server('SERVER_NAME', 'phpbb.generated');
return md5(unique_id(time())) . '@' . $domain;
}
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index fb09bc7057..1fdc7ee9ea 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -1040,6 +1040,7 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
global $config, $phpbb_root_path, $phpEx, $phpbb_container;
$phpbb_content_visibility = $phpbb_container->get('content.visibility');
+ $sql_sort = ($mode == 'post_review') ? 'ASC' : 'DESC';
// Go ahead and pull all data for this topic
$sql = 'SELECT p.post_id
@@ -1048,8 +1049,7 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id, 'p.') . '
' . (($mode == 'post_review') ? " AND p.post_id > $cur_post_id" : '') . '
' . (($mode == 'post_review_edit') ? " AND p.post_id = $cur_post_id" : '') . '
- ORDER BY p.post_time ';
- $sql .= ($mode == 'post_review') ? 'ASC' : 'DESC';
+ ORDER BY p.post_time ' . $sql_sort . ', p.post_id ' . $sql_sort;
$result = $db->sql_query_limit($sql, $config['posts_per_page']);
$post_list = array();
@@ -1324,18 +1324,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
{
delete_topics('topic_id', array($topic_id), false);
- if ($data['topic_visibility'] == ITEM_APPROVED)
- {
- $sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1';
- }
- else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE)
- {
- $sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1';
- }
- else if ($data['topic_visibility'] == ITEM_DELETED)
- {
- $sql_data[FORUMS_TABLE] .= 'forum_posts_softdeleted = forum_posts_softdeleted - 1, forum_topics_softdeleted = forum_topics_softdeleted - 1';
- }
+ $phpbb_content_visibility->remove_topic_from_statistic($data, $sql_data);
$update_sql = update_post_information('forum', $forum_id, true);
if (sizeof($update_sql))
@@ -1353,7 +1342,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
WHERE p.topic_id = $topic_id
AND p.poster_id = u.user_id
AND p.post_visibility = " . ITEM_APPROVED . '
- ORDER BY p.post_time ASC';
+ ORDER BY p.post_time ASC, p.post_id ASC';
$result = $db->sql_query_limit($sql, 1);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
@@ -1365,7 +1354,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u
WHERE p.topic_id = $topic_id
AND p.poster_id = u.user_id
- ORDER BY p.post_time ASC";
+ ORDER BY p.post_time ASC, p.post_id ASC";
$result = $db->sql_query_limit($sql, 1);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
@@ -1420,7 +1409,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
WHERE topic_id = $topic_id
AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id) . '
AND post_time > ' . $data['post_time'] . '
- ORDER BY post_time ASC';
+ ORDER BY post_time ASC, post_id ASC';
$result = $db->sql_query_limit($sql, 1);
$next_post_id = (int) $db->sql_fetchfield('post_id');
$db->sql_freeresult($result);
@@ -2267,17 +2256,17 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
{
case 'post':
$phpbb_notifications->add_notifications(array(
- 'quote',
- 'topic',
+ 'notification.type.quote',
+ 'notification.type.topic',
), $notification_data);
break;
case 'reply':
case 'quote':
$phpbb_notifications->add_notifications(array(
- 'quote',
- 'bookmark',
- 'post',
+ 'notification.type.quote',
+ 'notification.type.bookmark',
+ 'notification.type.post',
), $notification_data);
break;
@@ -2286,10 +2275,10 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
case 'edit':
case 'edit_last_post':
$phpbb_notifications->update_notifications(array(
- 'quote',
- 'bookmark',
- 'topic',
- 'post',
+ 'notification.type.quote',
+ 'notification.type.bookmark',
+ 'notification.type.topic',
+ 'notification.type.post',
), $notification_data);
break;
}
@@ -2299,12 +2288,12 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
switch ($mode)
{
case 'post':
- $phpbb_notifications->add_notifications('topic_in_queue', $notification_data);
+ $phpbb_notifications->add_notifications('notification.type.topic_in_queue', $notification_data);
break;
case 'reply':
case 'quote':
- $phpbb_notifications->add_notifications('post_in_queue', $notification_data);
+ $phpbb_notifications->add_notifications('notification.type.post_in_queue', $notification_data);
break;
case 'edit_topic':
@@ -2321,20 +2310,20 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
{
case 'edit_topic':
case 'edit_first_post':
- $phpbb_notifications->add_notifications('topic_in_queue', $notification_data);
+ $phpbb_notifications->add_notifications('notification.type.topic_in_queue', $notification_data);
// Delete the approve_post notification so we can notify the user again,
// when his post got reapproved
- $phpbb_notifications->delete_notifications('approve_post', $notification_data['post_id']);
+ $phpbb_notifications->delete_notifications('notification.type.approve_post', $notification_data['post_id']);
break;
case 'edit':
case 'edit_last_post':
- $phpbb_notifications->add_notifications('post_in_queue', $notification_data);
+ $phpbb_notifications->add_notifications('notification.type.post_in_queue', $notification_data);
// Delete the approve_post notification so we can notify the user again,
// when his post got reapproved
- $phpbb_notifications->delete_notifications('approve_post', $notification_data['post_id']);
+ $phpbb_notifications->delete_notifications('notification.type.approve_post', $notification_data['post_id']);
break;
case 'post':
@@ -2549,7 +2538,7 @@ function phpbb_upload_popup($forum_style = 0)
/**
* Do the various checks required for removing posts as well as removing it
*/
-function phpbb_handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $is_soft = false, $soft_delete_reason = '')
+function phpbb_handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $is_soft = false, $delete_reason = '')
{
global $user, $auth, $config, $request;
global $phpbb_root_path, $phpEx;
@@ -2582,19 +2571,19 @@ function phpbb_handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $
'post_postcount' => $post_data['post_postcount'],
);
- $next_post_id = delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $soft_delete_reason);
+ $next_post_id = delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $delete_reason);
$post_username = ($post_data['poster_id'] == ANONYMOUS && !empty($post_data['post_username'])) ? $post_data['post_username'] : $post_data['username'];
if ($next_post_id === false)
{
- add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_TOPIC' : 'LOG_DELETE_TOPIC'), $post_data['topic_title'], $post_username, $soft_delete_reason);
+ add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_TOPIC' : 'LOG_DELETE_TOPIC'), $post_data['topic_title'], $post_username, $delete_reason);
$meta_info = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id");
$message = $user->lang['POST_DELETED'];
}
else
{
- add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_POST' : 'LOG_DELETE_POST'), $post_data['post_subject'], $post_username, $soft_delete_reason);
+ add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_POST' : 'LOG_DELETE_POST'), $post_data['post_subject'], $post_username, $delete_reason);
$meta_info = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;p=$next_post_id") . "#p$next_post_id";
$message = $user->lang['POST_DELETED'];
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index 488f46a398..ad142b1cca 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -883,7 +883,7 @@ function update_unread_status($unread, $msg_id, $user_id, $folder_id)
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->mark_notifications_read('pm', $msg_id, $user_id);
+ $phpbb_notifications->mark_notifications_read('notification.type.pm', $msg_id, $user_id);
$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "
SET pm_unread = 0
@@ -1114,7 +1114,7 @@ function delete_pm($user_id, $msg_ids, $folder_id)
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->delete_notifications('pm', array_keys($delete_rows));
+ $phpbb_notifications->delete_notifications('notification.type.pm', array_keys($delete_rows));
// Now we have to check which messages we can delete completely
$sql = 'SELECT msg_id
@@ -1296,7 +1296,7 @@ function phpbb_delete_users_pms($user_ids)
AND ' . $db->sql_in_set('msg_id', $delivered_msg);
$db->sql_query($sql);
- $phpbb_notifications->delete_notifications('pm', $delivered_msg);
+ $phpbb_notifications->delete_notifications('notification.type.pm', $delivered_msg);
}
if (!empty($undelivered_msg))
@@ -1309,7 +1309,7 @@ function phpbb_delete_users_pms($user_ids)
WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg);
$db->sql_query($sql);
- $phpbb_notifications->delete_notifications('pm', $undelivered_msg);
+ $phpbb_notifications->delete_notifications('notification.type.pm', $undelivered_msg);
}
}
@@ -1353,7 +1353,7 @@ function phpbb_delete_users_pms($user_ids)
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
$db->sql_query($sql);
- $phpbb_notifications->delete_notifications('pm', $delete_ids);
+ $phpbb_notifications->delete_notifications('notification.type.pm', $delete_ids);
}
}
@@ -1573,7 +1573,7 @@ function get_folder_status($folder_id, $folder)
'cur' => $folder['num_messages'],
'remaining' => ($user->data['message_limit']) ? $user->data['message_limit'] - $folder['num_messages'] : 0,
'max' => $user->data['message_limit'],
- 'percent' => ($user->data['message_limit']) ? (($user->data['message_limit'] > 0) ? round(($folder['num_messages'] / $user->data['message_limit']) * 100) : 100) : 0,
+ 'percent' => ($user->data['message_limit']) ? (($user->data['message_limit'] > 0) ? floor(($folder['num_messages'] / $user->data['message_limit']) * 100) : 100) : 0,
);
$return['message'] = $user->lang('FOLDER_STATUS_MSG', $user->lang('MESSAGES_COUNT', (int) $return['max']), $return['cur'], $return['percent']);
@@ -1911,11 +1911,11 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
if ($mode == 'edit')
{
- $phpbb_notifications->update_notifications('pm', $pm_data);
+ $phpbb_notifications->update_notifications('notification.type.pm', $pm_data);
}
else
{
- $phpbb_notifications->add_notifications('pm', $pm_data);
+ $phpbb_notifications->add_notifications('notification.type.pm', $pm_data);
}
/**
diff --git a/phpBB/includes/functions_transfer.php b/phpBB/includes/functions_transfer.php
index fca183a225..42fdee364c 100644
--- a/phpBB/includes/functions_transfer.php
+++ b/phpBB/includes/functions_transfer.php
@@ -507,8 +507,6 @@ class ftp extends transfer
/**
* FTP fsock transfer class
-*
-* @author wGEric
*/
class ftp_fsock extends transfer
{
diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php
index e973e6ec28..f179b2fd70 100644
--- a/phpBB/includes/functions_upload.php
+++ b/phpBB/includes/functions_upload.php
@@ -232,7 +232,12 @@ class filespec
{
if ($this->mimetype_guesser !== null)
{
- $this->mimetype = $this->mimetype_guesser->guess($filename);
+ $mimetype = $this->mimetype_guesser->guess($filename, $this->uploadname);
+
+ if ($mimetype !== 'application/octet-stream')
+ {
+ $this->mimetype = $mimetype;
+ }
}
return $this->mimetype;
@@ -586,6 +591,7 @@ class fileupload
* Upload file from users harddisk
*
* @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified)
+ * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser
* @param \phpbb\plupload\plupload $plupload The plupload object
*
* @return object $file Object "filespec" is returned, all further operations can be done with this object
@@ -743,6 +749,7 @@ class fileupload
* Uploads file from given url
*
* @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif
+ * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser
* @return object $file Object "filespec" is returned, all further operations can be done with this object
* @access public
*/
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index d39be50251..e4479f07b0 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -363,12 +363,16 @@ function user_add($user_row, $cp_data = false)
}
/**
-* Remove User
-* @param $mode Either 'retain' or 'remove'
-*/
+ * Remove User
+ *
+ * @param string $mode Either 'retain' or 'remove'
+ * @param mixed $user_ids Either an array of integers or an integer
+ * @param bool $retain_username
+ * @return bool
+ */
function user_delete($mode, $user_ids, $retain_username = true)
{
- global $cache, $config, $db, $user, $auth, $phpbb_dispatcher;
+ global $cache, $config, $db, $user, $phpbb_dispatcher;
global $phpbb_root_path, $phpEx;
$db->sql_transaction('begin');
@@ -555,11 +559,6 @@ function user_delete($mode, $user_ids, $retain_username = true)
WHERE ' . $db->sql_in_set('poster_id', $user_ids);
$db->sql_query($sql);
- $sql = 'UPDATE ' . POSTS_TABLE . '
- SET post_edit_user = ' . ANONYMOUS . '
- WHERE ' . $db->sql_in_set('post_edit_user', $user_ids);
- $db->sql_query($sql);
-
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_posts = user_posts + ' . $added_guest_posts . '
WHERE user_id = ' . ANONYMOUS;
@@ -589,6 +588,30 @@ function user_delete($mode, $user_ids, $retain_username = true)
$cache->destroy('sql', MODERATOR_CACHE_TABLE);
+ // Change user_id to anonymous for posts edited by this user
+ $sql = 'UPDATE ' . POSTS_TABLE . '
+ SET post_edit_user = ' . ANONYMOUS . '
+ WHERE ' . $db->sql_in_set('post_edit_user', $user_ids);
+ $db->sql_query($sql);
+
+ // Change user_id to anonymous for pms edited by this user
+ $sql = 'UPDATE ' . PRIVMSGS_TABLE . '
+ SET message_edit_user = ' . ANONYMOUS . '
+ WHERE ' . $db->sql_in_set('message_edit_user', $user_ids);
+ $db->sql_query($sql);
+
+ // Change user_id to anonymous for posts deleted by this user
+ $sql = 'UPDATE ' . POSTS_TABLE . '
+ SET post_delete_user = ' . ANONYMOUS . '
+ WHERE ' . $db->sql_in_set('post_delete_user', $user_ids);
+ $db->sql_query($sql);
+
+ // Change user_id to anonymous for topics deleted by this user
+ $sql = 'UPDATE ' . TOPICS_TABLE . '
+ SET topic_delete_user = ' . ANONYMOUS . '
+ WHERE ' . $db->sql_in_set('topic_delete_user', $user_ids);
+ $db->sql_query($sql);
+
// Delete user log entries about this user
$sql = 'DELETE FROM ' . LOG_TABLE . '
WHERE ' . $db->sql_in_set('reportee_id', $user_ids);
@@ -2675,7 +2698,7 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false,
foreach ($add_id_ary as $user_id)
{
- $phpbb_notifications->add_notifications('group_request', array(
+ $phpbb_notifications->add_notifications('notification.type.group_request', array(
'group_id' => $group_id,
'user_id' => $user_id,
'group_name' => $group_name,
@@ -2832,7 +2855,7 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false,
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->delete_notifications('group_request', $user_id_ary, $group_id);
+ $phpbb_notifications->delete_notifications('notification.type.group_request', $user_id_ary, $group_id);
// Return false - no error
return false;
@@ -2996,12 +3019,12 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->add_notifications('group_request_approved', array(
+ $phpbb_notifications->add_notifications('notification.type.group_request_approved', array(
'user_ids' => $user_id_ary,
'group_id' => $group_id,
'group_name' => $group_name,
));
- $phpbb_notifications->delete_notifications('group_request', $user_id_ary, $group_id);
+ $phpbb_notifications->delete_notifications('notification.type.group_request', $user_id_ary, $group_id);
$log = 'LOG_USERS_APPROVED';
break;
diff --git a/phpBB/includes/mcp/mcp_ban.php b/phpBB/includes/mcp/mcp_ban.php
index e6fac3b80c..4d2151fded 100644
--- a/phpBB/includes/mcp/mcp_ban.php
+++ b/phpBB/includes/mcp/mcp_ban.php
@@ -25,7 +25,7 @@ class mcp_ban
function main($id, $mode)
{
- global $config, $db, $user, $auth, $template, $cache;
+ global $db, $user, $auth, $template, $request, $phpbb_dispatcher;
global $phpbb_root_path, $phpEx;
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
@@ -33,55 +33,133 @@ class mcp_ban
// Include the admin banning interface...
include($phpbb_root_path . 'includes/acp/acp_ban.' . $phpEx);
- $bansubmit = (isset($_POST['bansubmit'])) ? true : false;
- $unbansubmit = (isset($_POST['unbansubmit'])) ? true : false;
- $current_time = time();
+ $bansubmit = $request->is_set_post('bansubmit');
+ $unbansubmit = $request->is_set_post('unbansubmit');
$user->add_lang(array('acp/ban', 'acp/users'));
$this->tpl_name = 'mcp_ban';
+ /**
+ * Use this event to pass perform actions when a ban is issued or revoked
+ *
+ * @event core.mcp_ban_main
+ * @var bool bansubmit True if a ban is issued
+ * @var bool unbansubmit True if a ban is removed
+ * @var string mode Mode of the ban that is being worked on
+ * @since 3.1.0-RC5
+ */
+ $vars = array(
+ 'bansubmit',
+ 'unbansubmit',
+ 'mode',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_ban_main', compact($vars)));
+
// Ban submitted?
if ($bansubmit)
{
// Grab the list of entries
- $ban = request_var('ban', '', ($mode === 'user') ? true : false);
-
- if ($mode === 'user')
- {
- $ban = utf8_normalize_nfc($ban);
- }
-
- $ban_len = request_var('banlength', 0);
- $ban_len_other = request_var('banlengthother', '');
- $ban_exclude = request_var('banexclude', 0);
- $ban_reason = utf8_normalize_nfc(request_var('banreason', '', true));
- $ban_give_reason = utf8_normalize_nfc(request_var('bangivereason', '', true));
+ $ban = $request->variable('ban', '', $mode === 'user');
+ $ban_length = $request->variable('banlength', 0);
+ $ban_length_other = $request->variable('banlengthother', '');
+ $ban_exclude = $request->variable('banexclude', 0);
+ $ban_reason = $request->variable('banreason', '', true);
+ $ban_give_reason = $request->variable('bangivereason', '', true);
if ($ban)
{
if (confirm_box(true))
{
- user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reason, $ban_give_reason);
+ $abort_ban = false;
+ /**
+ * Use this event to modify the ban details before the ban is performed
+ *
+ * @event core.mcp_ban_before
+ * @var string mode One of the following: user, ip, email
+ * @var string ban Either string or array with usernames, ips or email addresses
+ * @var int ban_length Ban length in minutes
+ * @var string ban_length_other Ban length as a date (YYYY-MM-DD)
+ * @var bool ban_exclude Are we banning or excluding from another ban
+ * @var string ban_reason Ban reason displayed to moderators
+ * @var string ban_give_reason Ban reason displayed to the banned user
+ * @var mixed abort_ban Either false, or an error message that is displayed to the user.
+ * If a string is given the bans are not issued.
+ * @since 3.1.0-RC5
+ */
+ $vars = array(
+ 'mode',
+ 'ban',
+ 'ban_length',
+ 'ban_length_other',
+ 'ban_exclude',
+ 'ban_reason',
+ 'ban_give_reason',
+ 'abort_ban',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_ban_before', compact($vars)));
+
+ if ($abort_ban)
+ {
+ trigger_error($abort_ban);
+ }
+ user_ban($mode, $ban, $ban_length, $ban_length_other, $ban_exclude, $ban_reason, $ban_give_reason);
+
+ /**
+ * Use this event to perform actions after the ban has been performed
+ *
+ * @event core.mcp_ban_after
+ * @var string mode One of the following: user, ip, email
+ * @var string ban Either string or array with usernames, ips or email addresses
+ * @var int ban_length Ban length in minutes
+ * @var string ban_length_other Ban length as a date (YYYY-MM-DD)
+ * @var bool ban_exclude Are we banning or excluding from another ban
+ * @var string ban_reason Ban reason displayed to moderators
+ * @var string ban_give_reason Ban reason displayed to the banned user
+ * @since 3.1.0-RC5
+ */
+ $vars = array(
+ 'mode',
+ 'ban',
+ 'ban_length',
+ 'ban_length_other',
+ 'ban_exclude',
+ 'ban_reason',
+ 'ban_give_reason',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_ban_after', compact($vars)));
trigger_error($user->lang['BAN_UPDATE_SUCCESSFUL'] . '<br /><br /><a href="' . $this->u_action . '">&laquo; ' . $user->lang['BACK_TO_PREV'] . '</a>');
}
else
{
- confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
+ $hidden_fields = array(
'mode' => $mode,
'ban' => $ban,
'bansubmit' => true,
- 'banlength' => $ban_len,
- 'banlengthother' => $ban_len_other,
+ 'banlength' => $ban_length,
+ 'banlengthother' => $ban_length_other,
'banexclude' => $ban_exclude,
'banreason' => $ban_reason,
- 'bangivereason' => $ban_give_reason)));
+ 'bangivereason' => $ban_give_reason,
+ );
+
+ /**
+ * Use this event to pass data from the ban form to the confirmation screen
+ *
+ * @event core.mcp_ban_confirm
+ * @var array hidden_fields Hidden fields that are passed through the confirm screen
+ * @since 3.1.0-RC5
+ */
+ $vars = array('hidden_fields');
+ extract($phpbb_dispatcher->trigger_event('core.mcp_ban_confirm', compact($vars)));
+
+ confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($hidden_fields));
}
}
}
else if ($unbansubmit)
{
- $ban = request_var('unban', array(''));
+ $ban = $request->variable('unban', array(''));
if ($ban)
{
@@ -157,9 +235,9 @@ class mcp_ban
}
// As a "service" we will check if any post id is specified and populate the username of the poster id if given
- $post_id = request_var('p', 0);
- $user_id = request_var('u', 0);
- $username = $pre_fill = false;
+ $post_id = $request->variable('p', 0);
+ $user_id = $request->variable('u', 0);
+ $pre_fill = false;
if ($user_id && $user_id <> ANONYMOUS)
{
diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php
index 98773d5b0e..ebcf7ce643 100644
--- a/phpBB/includes/mcp/mcp_front.php
+++ b/phpBB/includes/mcp/mcp_front.php
@@ -26,6 +26,7 @@ function mcp_front_view($id, $mode, $action)
{
global $phpEx, $phpbb_root_path, $config;
global $template, $db, $user, $auth, $module;
+ global $phpbb_dispatcher;
// Latest 5 unapproved
if ($module->loaded('queue'))
@@ -65,7 +66,7 @@ function mcp_front_view($id, $mode, $action)
FROM ' . POSTS_TABLE . '
WHERE ' . $db->sql_in_set('forum_id', $forum_list) . '
AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . '
- ORDER BY post_time DESC';
+ ORDER BY post_time DESC, post_id DESC';
$result = $db->sql_query_limit($sql, 5);
while ($row = $db->sql_fetchrow($result))
@@ -80,6 +81,19 @@ function mcp_front_view($id, $mode, $action)
}
}
+ /**
+ * Alter list of posts and total as required
+ *
+ * @event core.mcp_front_view_queue_postid_list_after
+ * @var int total Number of unapproved posts
+ * @var array post_list List of unapproved posts
+ * @var array forum_list List of forums that contain the posts
+ * @var array forum_names Associative array with forum_id as key and it's corresponding forum_name as value
+ * @since 3.1.0-RC3
+ */
+ $vars = array('total', 'post_list', 'forum_list', 'forum_names');
+ extract($phpbb_dispatcher->trigger_event('core.mcp_front_view_queue_postid_list_after', compact($vars)));
+
if ($total)
{
$sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.post_attachment, p.poster_id, p.post_username, u.username, u.username_clean, u.user_colour, t.topic_id, t.topic_title, t.topic_first_post_id, p.forum_id
@@ -87,7 +101,7 @@ function mcp_front_view($id, $mode, $action)
WHERE ' . $db->sql_in_set('p.post_id', $post_list) . '
AND t.topic_id = p.topic_id
AND p.poster_id = u.user_id
- ORDER BY p.post_time DESC';
+ ORDER BY p.post_time DESC, p.post_id DESC';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
@@ -176,7 +190,7 @@ function mcp_front_view($id, $mode, $action)
AND p.poster_id = u2.user_id
AND ' . $db->sql_in_set('p.forum_id', $forum_list),
- 'ORDER_BY' => 'p.post_time DESC',
+ 'ORDER_BY' => 'p.post_time DESC, p.post_id DESC',
);
/**
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index 9f6125f256..74bf687fc8 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -161,9 +161,13 @@ class mcp_main
* This event allows you to handle custom quickmod options
*
* @event core.modify_quickmod_actions
+ * @var string action Topic quick moderation action name
+ * @var bool quickmod Flag indicating whether MCP is in quick moderation mode
* @since 3.1.0-a4
+ * @change 3.1.0-RC4 Added variables: action, quickmod
*/
- $phpbb_dispatcher->dispatch('core.modify_quickmod_actions');
+ $vars = array('action', 'quickmod');
+ extract($phpbb_dispatcher->trigger_event('core.modify_quickmod_actions', compact($vars)));
break;
}
@@ -1114,6 +1118,7 @@ function mcp_fork_topic($topic_ids)
$forum_id = request_var('f', 0);
$redirect = request_var('redirect', build_url(array('action', 'quickmod')));
$additional_msg = $success_msg = '';
+ $counter = array();
$s_hidden_fields = build_hidden_fields(array(
'topic_id_list' => $topic_ids,
@@ -1264,7 +1269,7 @@ function mcp_fork_topic($topic_ids)
$sql = 'SELECT *
FROM ' . POSTS_TABLE . "
WHERE topic_id = $topic_id
- ORDER BY post_time ASC";
+ ORDER BY post_time ASC, post_id ASC";
$result = $db->sql_query($sql);
$post_rows = array();
@@ -1306,9 +1311,20 @@ function mcp_fork_topic($topic_ids)
'post_edit_time' => (int) $row['post_edit_time'],
'post_edit_count' => (int) $row['post_edit_count'],
'post_edit_locked' => (int) $row['post_edit_locked'],
- 'post_postcount' => 0,
+ 'post_postcount' => $row['post_postcount'],
);
-
+ // Adjust post count only if the post can be incremented to the user counter
+ if ($row['post_postcount'])
+ {
+ if (isset($counter[$row['poster_id']]))
+ {
+ ++$counter[$row['poster_id']];
+ }
+ else
+ {
+ $counter[$row['poster_id']] = 1;
+ }
+ }
$db->sql_query('INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
$new_post_id = $db->sql_nextid();
@@ -1428,6 +1444,18 @@ function mcp_fork_topic($topic_ids)
WHERE forum_id = ' . $to_forum_id;
$db->sql_query($sql);
+ if (!empty($counter))
+ {
+ // Do only one query per user and not a query per post.
+ foreach ($counter as $user_id => $count)
+ {
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET user_posts = user_posts + ' . (int) $count . '
+ WHERE user_id = ' . (int) $user_id;
+ $db->sql_query($sql);
+ }
+ }
+
sync('topic', 'topic_id', $new_topic_id_list);
sync('forum', 'forum_id', $to_forum_id);
diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php
index 03e4ed4722..d76bedba98 100644
--- a/phpBB/includes/mcp/mcp_pm_reports.php
+++ b/phpBB/includes/mcp/mcp_pm_reports.php
@@ -95,7 +95,7 @@ class mcp_pm_reports
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->mark_notifications_read_by_parent('report_pm', $report_id, $user->data['user_id']);
+ $phpbb_notifications->mark_notifications_read_by_parent('notification.type.report_pm', $report_id, $user->data['user_id']);
$pm_id = $report['pm_id'];
$report_id = $report['report_id'];
diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php
index 37ce3c6fc3..f9c00da3ec 100644
--- a/phpBB/includes/mcp/mcp_queue.php
+++ b/phpBB/includes/mcp/mcp_queue.php
@@ -37,6 +37,7 @@ class mcp_queue
{
global $auth, $db, $user, $template, $cache, $request;
global $config, $phpbb_root_path, $phpEx, $action, $phpbb_container;
+ global $phpbb_dispatcher;
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
@@ -164,7 +165,7 @@ class mcp_queue
{
$post_id = (int) $topic_info[$topic_id]['topic_first_post_id'];
- $phpbb_notifications->mark_notifications_read('topic_in_queue', $topic_id, $user->data['user_id']);
+ $phpbb_notifications->mark_notifications_read('notification.type.topic_in_queue', $topic_id, $user->data['user_id']);
}
else
{
@@ -172,7 +173,7 @@ class mcp_queue
}
}
- $phpbb_notifications->mark_notifications_read('post_in_queue', $post_id, $user->data['user_id']);
+ $phpbb_notifications->mark_notifications_read('notification.type.post_in_queue', $post_id, $user->data['user_id']);
$post_info = phpbb_get_post_data(array($post_id), 'm_approve', true);
@@ -429,6 +430,29 @@ class mcp_queue
OR t.topic_delete_user = 0)
$limit_time_sql
ORDER BY $sort_order_sql";
+
+ /**
+ * Alter sql query to get posts in queue to be accepted
+ *
+ * @event core.mcp_queue_get_posts_query_before
+ * @var string sql Associative array with the query to be executed
+ * @var array forum_list List of forums that contain the posts
+ * @var int visibility_const Integer with one of the possible ITEM_* constant values
+ * @var int topic_id If topic_id not equal to 0, the topic id to filter the posts to display
+ * @var string limit_time_sql String with the SQL code to limit the time interval of the post (Note: May be empty string)
+ * @var string sort_order_sql String with the ORDER BY SQL code used in this query
+ * @since 3.1.0-RC3
+ */
+ $vars = array(
+ 'sql',
+ 'forum_list',
+ 'visibility_const',
+ 'topic_id',
+ 'limit_time_sql',
+ 'sort_order_sql',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_queue_get_posts_query_before', compact($vars)));
+
$result = $db->sql_query_limit($sql, $config['topics_per_page'], $start);
$i = 0;
@@ -478,6 +502,29 @@ class mcp_queue
AND topic_delete_user <> 0
$limit_time_sql
ORDER BY $sort_order_sql";
+
+ /**
+ * Alter sql query to get information on all topics in the list of forums provided.
+ *
+ * @event core.mcp_queue_get_posts_for_topics_query_before
+ * @var string sql String with the query to be executed
+ * @var array forum_list List of forums that contain the posts
+ * @var int visibility_const Integer with one of the possible ITEM_* constant values
+ * @var int topic_id topic_id in the page request
+ * @var string limit_time_sql String with the SQL code to limit the time interval of the post (Note: May be empty string)
+ * @var string sort_order_sql String with the ORDER BY SQL code used in this query
+ * @since 3.1.0-RC3
+ */
+ $vars = array(
+ 'sql',
+ 'forum_list',
+ 'visibility_const',
+ 'topic_id',
+ 'limit_time_sql',
+ 'sort_order_sql',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_queue_get_posts_for_topics_query_before', compact($vars)));
+
$result = $db->sql_query_limit($sql, $config['topics_per_page'], $start);
$rowset = array();
@@ -654,11 +701,11 @@ class mcp_queue
// A single topic approval may also happen here, so handle deleting the respective notification.
if (!$post_data['topic_posts_approved'])
{
- $phpbb_notifications->delete_notifications('topic_in_queue', $post_data['topic_id']);
+ $phpbb_notifications->delete_notifications('notification.type.topic_in_queue', $post_data['topic_id']);
if ($post_data['post_visibility'] == ITEM_UNAPPROVED)
{
- $phpbb_notifications->add_notifications(array('topic'), $post_data);
+ $phpbb_notifications->add_notifications(array('notification.type.topic'), $post_data);
}
if ($post_data['post_visibility'] != ITEM_APPROVED)
{
@@ -674,18 +721,18 @@ class mcp_queue
if ($post_data['post_visibility'] == ITEM_UNAPPROVED)
{
$phpbb_notifications->add_notifications(array(
- 'bookmark',
- 'post',
+ 'notification.type.bookmark',
+ 'notification.type.post',
), $post_data);
}
}
- $phpbb_notifications->add_notifications(array('quote'), $post_data);
- $phpbb_notifications->delete_notifications('post_in_queue', $post_id);
+ $phpbb_notifications->add_notifications(array('notification.type.quote'), $post_data);
+ $phpbb_notifications->delete_notifications('notification.type.post_in_queue', $post_id);
$phpbb_notifications->mark_notifications_read(array(
- 'quote',
- 'bookmark',
- 'post',
+ 'notification.type.quote',
+ 'notification.type.bookmark',
+ 'notification.type.post',
), $post_data['post_id'], $user->data['user_id']);
// Notify Poster?
@@ -698,11 +745,11 @@ class mcp_queue
if (!$post_data['topic_posts_approved'])
{
- $phpbb_notifications->add_notifications('approve_post', $post_data);
+ $phpbb_notifications->add_notifications('notification.type.approve_topic', $post_data);
}
else
{
- $phpbb_notifications->add_notifications('approve_topic', $post_data);
+ $phpbb_notifications->add_notifications('notification.type.approve_post', $post_data);
}
}
}
@@ -874,7 +921,7 @@ class mcp_queue
'post_username' => $topic_data['topic_first_poster_name'],
));
- $phpbb_notifications->delete_notifications('topic_in_queue', $topic_id);
+ $phpbb_notifications->delete_notifications('notification.type.topic_in_queue', $topic_id);
// Only add notifications, if we are not reapproving post
// When the topic was already approved, but was edited and
@@ -883,17 +930,17 @@ class mcp_queue
if ($topic_data['topic_visibility'] == ITEM_UNAPPROVED)
{
$phpbb_notifications->add_notifications(array(
- 'quote',
- 'topic',
+ 'notification.type.quote',
+ 'notification.type.topic',
), $topic_data);
}
- $phpbb_notifications->mark_notifications_read('quote', $topic_data['post_id'], $user->data['user_id']);
- $phpbb_notifications->mark_notifications_read('topic', $topic_id, $user->data['user_id']);
+ $phpbb_notifications->mark_notifications_read('notification.type.quote', $topic_data['post_id'], $user->data['user_id']);
+ $phpbb_notifications->mark_notifications_read('notification.type.topic', $topic_id, $user->data['user_id']);
if ($notify_poster)
{
- $phpbb_notifications->add_notifications('approve_topic', $topic_data);
+ $phpbb_notifications->add_notifications('notification.type.approve_topic', $topic_data);
}
}
}
@@ -1131,12 +1178,12 @@ class mcp_queue
$topic_information[$topic_id]['topic_posts_softdeleted'] == 0 &&
$topic_information[$topic_id]['topic_posts_unapproved'] == $topic_posts_unapproved[$topic_id];
- $phpbb_notifications->delete_notifications('post_in_queue', $post_id);
+ $phpbb_notifications->delete_notifications('notification.type.post_in_queue', $post_id);
// Do we disapprove the whole topic? Remove potential notifications
if ($disapprove_all_posts_in_topic)
{
- $phpbb_notifications->delete_notifications('topic_in_queue', $post_data['topic_id']);
+ $phpbb_notifications->delete_notifications('notification.type.topic_in_queue', $post_data['topic_id']);
}
// Notify Poster?
@@ -1181,13 +1228,13 @@ class mcp_queue
{
// If there is only 1 post when disapproving the topic,
// we send the user a "disapprove topic" notification...
- $phpbb_notifications->add_notifications('disapprove_topic', $post_data);
+ $phpbb_notifications->add_notifications('notification.type.disapprove_topic', $post_data);
}
else
{
// ... otherwise there are multiple unapproved posts and
// all of them are disapproved as posts.
- $phpbb_notifications->add_notifications('disapprove_post', $post_data);
+ $phpbb_notifications->add_notifications('notification.type.disapprove_post', $post_data);
}
}
}
diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php
index a7d8bf18d6..804d48ea97 100644
--- a/phpBB/includes/mcp/mcp_reports.php
+++ b/phpBB/includes/mcp/mcp_reports.php
@@ -36,7 +36,7 @@ class mcp_reports
function main($id, $mode)
{
global $auth, $db, $user, $template, $cache;
- global $config, $phpbb_root_path, $phpEx, $action, $phpbb_container;
+ global $config, $phpbb_root_path, $phpEx, $action, $phpbb_container, $phpbb_dispatcher;
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
@@ -92,7 +92,7 @@ class mcp_reports
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->mark_notifications_read('report_post', $post_id, $user->data['user_id']);
+ $phpbb_notifications->mark_notifications_read('notification.type.report_post', $post_id, $user->data['user_id']);
if (!$report_id && $report['report_closed'])
{
@@ -364,6 +364,27 @@ class mcp_reports
AND r.pm_id = 0
$limit_time_sql
ORDER BY $sort_order_sql";
+
+ /**
+ * Alter sql query to get report id of all reports for requested forum and topic or just forum
+ *
+ * @event core.mcp_reports_get_reports_query_before
+ * @var string sql String with the query to be executed
+ * @var array forum_list List of forums that contain the posts
+ * @var int topic_id topic_id in the page request
+ * @var string limit_time_sql String with the SQL code to limit the time interval of the post (Note: May be empty string)
+ * @var string sort_order_sql String with the ORDER BY SQL code used in this query
+ * @since 3.1.0-RC4
+ */
+ $vars = array(
+ 'sql',
+ 'forum_list',
+ 'topic_id',
+ 'limit_time_sql',
+ 'sort_order_sql',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_reports_get_reports_query_before', compact($vars)));
+
$result = $db->sql_query_limit($sql, $config['topics_per_page'], $start);
$i = 0;
@@ -631,12 +652,12 @@ function close_report($report_id_list, $mode, $action, $pm = false)
if ($pm)
{
add_log('mod', 0, 0, 'LOG_PM_REPORT_' . strtoupper($action) . 'D', $post_info[$report['pm_id']]['message_subject']);
- $phpbb_notifications->delete_notifications('report_pm', $report['pm_id']);
+ $phpbb_notifications->delete_notifications('notification.type.report_pm', $report['pm_id']);
}
else
{
add_log('mod', $post_info[$report['post_id']]['forum_id'], $post_info[$report['post_id']]['topic_id'], 'LOG_REPORT_' . strtoupper($action) . 'D', $post_info[$report['post_id']]['post_subject']);
- $phpbb_notifications->delete_notifications('report_post', $report['post_id']);
+ $phpbb_notifications->delete_notifications('notification.type.report_post', $report['post_id']);
}
}
@@ -654,7 +675,7 @@ function close_report($report_id_list, $mode, $action, $pm = false)
if ($pm)
{
- $phpbb_notifications->add_notifications('report_pm_closed', array_merge($post_info[$post_id], array(
+ $phpbb_notifications->add_notifications('notification.type.report_pm_closed', array_merge($post_info[$post_id], array(
'reporter' => $reporter['user_id'],
'closer_id' => $user->data['user_id'],
'from_user_id' => $post_info[$post_id]['author_id'],
@@ -662,7 +683,7 @@ function close_report($report_id_list, $mode, $action, $pm = false)
}
else
{
- $phpbb_notifications->add_notifications('report_post_closed', array_merge($post_info[$post_id], array(
+ $phpbb_notifications->add_notifications('notification.type.report_post_closed', array_merge($post_info[$post_id], array(
'reporter' => $reporter['user_id'],
'closer_id' => $user->data['user_id'],
)));
diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php
index fb47522644..425c3ac235 100644
--- a/phpBB/includes/mcp/mcp_warn.php
+++ b/phpBB/includes/mcp/mcp_warn.php
@@ -336,12 +336,12 @@ class mcp_warn
$message = generate_text_for_display($user_row['post_text'], $user_row['bbcode_uid'], $user_row['bbcode_bitfield'], $parse_flags, true);
// Generate the appropriate user information for the user we are looking at
- if (!function_exists('get_user_rank'))
+ if (!function_exists('phpbb_get_user_rank'))
{
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
}
- get_user_rank($user_row['user_rank'], $user_row['user_posts'], $rank_title, $rank_img, $rank_img_src);
+ $user_rank_data = phpbb_get_user_rank($user_row, $user_row['user_posts']);
$avatar_img = phpbb_get_user_avatar($user_row);
$template->assign_vars(array(
@@ -350,13 +350,13 @@ class mcp_warn
'POST' => $message,
'USERNAME' => $user_row['username'],
'USER_COLOR' => (!empty($user_row['user_colour'])) ? $user_row['user_colour'] : '',
- 'RANK_TITLE' => $rank_title,
+ 'RANK_TITLE' => $user_rank_data['title'],
'JOINED' => $user->format_date($user_row['user_regdate']),
'POSTS' => ($user_row['user_posts']) ? $user_row['user_posts'] : 0,
'WARNINGS' => ($user_row['user_warnings']) ? $user_row['user_warnings'] : 0,
'AVATAR_IMG' => $avatar_img,
- 'RANK_IMG' => $rank_img,
+ 'RANK_IMG' => $user_rank_data['img'],
'L_WARNING_POST_DEFAULT' => sprintf($user->lang['WARNING_POST_DEFAULT'], generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&amp;p=$post_id#p$post_id"),
@@ -486,18 +486,18 @@ class mcp_warn
}
// Generate the appropriate user information for the user we are looking at
- if (!function_exists('get_user_rank'))
+ if (!function_exists('phpbb_get_user_rank'))
{
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
}
- get_user_rank($user_row['user_rank'], $user_row['user_posts'], $rank_title, $rank_img, $rank_img_src);
+ $user_rank_data = phpbb_get_user_rank($user_row, $user_row['user_posts']);
$avatar_img = phpbb_get_user_avatar($user_row);
// OK, they didn't submit a warning so lets build the page for them to do so
$template->assign_vars(array(
'U_POST_ACTION' => $this->u_action,
- 'RANK_TITLE' => $rank_title,
+ 'RANK_TITLE' => $user_rank_data['title'],
'JOINED' => $user->format_date($user_row['user_regdate']),
'POSTS' => ($user_row['user_posts']) ? $user_row['user_posts'] : 0,
'WARNINGS' => ($user_row['user_warnings']) ? $user_row['user_warnings'] : 0,
@@ -508,7 +508,7 @@ class mcp_warn
'U_PROFILE' => get_username_string('profile', $user_row['user_id'], $user_row['username'], $user_row['user_colour']),
'AVATAR_IMG' => $avatar_img,
- 'RANK_IMG' => $rank_img,
+ 'RANK_IMG' => $user_rank_data['img'],
'S_CAN_NOTIFY' => $s_can_notify,
));
@@ -535,7 +535,7 @@ function add_warning($user_row, $warning, $send_pm = true, $post_id = 0)
$message_parser = new parse_message();
- $message_parser->message = sprintf($lang['WARNING_PM_BODY'], $warning);
+ $message_parser->message = $user->lang('WARNING_PM_BODY', $warning);
$message_parser->parse(true, true, true, false, false, true, true);
$pm_data = array(
@@ -553,7 +553,7 @@ function add_warning($user_row, $warning, $send_pm = true, $post_id = 0)
'address_list' => array('u' => array($user_row['user_id'] => 'to')),
);
- submit_pm('post', $lang['WARNING_PM_SUBJECT'], $pm_data, false);
+ submit_pm('post', $user->lang('WARNING_PM_SUBJECT'), $pm_data, false);
}
add_log('admin', 'LOG_USER_WARNING', $user_row['username']);
diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php
index 53dec89aad..6e357b260a 100644
--- a/phpBB/includes/ucp/ucp_activate.php
+++ b/phpBB/includes/ucp/ucp_activate.php
@@ -111,7 +111,7 @@ class ucp_activate
if ($config['require_activation'] == USER_ACTIVATION_ADMIN && !$update_password)
{
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->delete_notifications('admin_activate_user', $user_row['user_id']);
+ $phpbb_notifications->delete_notifications('notification.type.admin_activate_user', $user_row['user_id']);
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php
index aab45339c5..42724209aa 100644
--- a/phpBB/includes/ucp/ucp_attachments.php
+++ b/phpBB/includes/ucp/ucp_attachments.php
@@ -182,6 +182,7 @@ class ucp_attachments
$template->assign_vars(array(
'TOTAL_ATTACHMENTS' => $num_attachments,
+ 'NUM_ATTACHMENTS' => $user->lang('NUM_ATTACHMENTS', $num_attachments),
'L_TITLE' => $user->lang['UCP_ATTACHMENTS'],
diff --git a/phpBB/includes/ucp/ucp_confirm.php b/phpBB/includes/ucp/ucp_confirm.php
index bcba32cdf6..7392f8dea8 100644
--- a/phpBB/includes/ucp/ucp_confirm.php
+++ b/phpBB/includes/ucp/ucp_confirm.php
@@ -36,10 +36,9 @@ class ucp_confirm
function main($id, $mode)
{
- global $db, $user, $phpbb_root_path, $config, $phpEx;
+ global $db, $user, $phpbb_root_path, $config, $phpEx, $phpbb_container;
- include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
- $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
$captcha->init(request_var('type', 0));
$captcha->execute();
diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php
index e4931fbe23..b9606945b4 100644
--- a/phpBB/includes/ucp/ucp_groups.php
+++ b/phpBB/includes/ucp/ucp_groups.php
@@ -471,6 +471,29 @@ class ucp_groups
$avatar_data = \phpbb\avatar\manager::clean_row($group_row, 'group');
}
+ // Handle deletion of avatars
+ if ($request->is_set_post('avatar_delete'))
+ {
+ if (confirm_box(true))
+ {
+ $phpbb_avatar_manager->handle_avatar_delete($db, $user, $avatar_data, GROUPS_TABLE, 'group_');
+ $cache->destroy('sql', GROUPS_TABLE);
+
+ $message = ($action == 'edit') ? 'GROUP_UPDATED' : 'GROUP_CREATED';
+ trigger_error($user->lang[$message] . $return_page);
+ }
+ else
+ {
+ confirm_box(false, $user->lang('CONFIRM_AVATAR_DELETE'), build_hidden_fields(array(
+ 'avatar_delete' => true,
+ 'i' => $id,
+ 'mode' => $mode,
+ 'g' => $group_id,
+ 'action' => $action))
+ );
+ }
+ }
+
// Did we submit?
if ($update)
{
@@ -510,19 +533,6 @@ class ucp_groups
$submit_ary = array_merge($submit_ary, $result);
}
}
- else
- {
- if ($driver = $phpbb_avatar_manager->get_driver($avatar_data['avatar_type']))
- {
- $driver->delete($avatar_data);
- }
-
- // Removing the avatar
- $submit_ary['avatar_type'] = '';
- $submit_ary['avatar'] = '';
- $submit_ary['avatar_width'] = 0;
- $submit_ary['avatar_height'] = 0;
- }
// Merge any avatars errors into the primary error array
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));
diff --git a/phpBB/includes/ucp/ucp_login_link.php b/phpBB/includes/ucp/ucp_login_link.php
index a8762313fd..5ca5df00f7 100644
--- a/phpBB/includes/ucp/ucp_login_link.php
+++ b/phpBB/includes/ucp/ucp_login_link.php
@@ -181,7 +181,7 @@ class ucp_login_link
*/
protected function process_login_result($result)
{
- global $config, $request, $template, $user;
+ global $config, $request, $template, $user, $phpbb_container;
$login_error = null;
@@ -197,7 +197,7 @@ class ucp_login_link
{
case LOGIN_ERROR_ATTEMPTS:
- $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
$template->assign_vars(array(
diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php
index 304c04eb3d..a1624e78ec 100644
--- a/phpBB/includes/ucp/ucp_main.php
+++ b/phpBB/includes/ucp/ucp_main.php
@@ -81,7 +81,7 @@ class ucp_main
FROM $sql_from
WHERE t.topic_type = " . POST_GLOBAL . '
AND ' . $db->sql_in_set('t.forum_id', $forum_ary) . '
- ORDER BY t.topic_last_post_time DESC';
+ ORDER BY t.topic_last_post_time DESC, t.topic_last_post_id DESC';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
@@ -693,7 +693,7 @@ class ucp_main
AND t.topic_id = tw.topic_id
AND ' . $db->sql_in_set('t.forum_id', $forbidden_forum_ary, true, true),
- 'ORDER_BY' => 't.topic_last_post_time DESC'
+ 'ORDER_BY' => 't.topic_last_post_time DESC, t.topic_last_post_id DESC'
);
$sql_array['LEFT_JOIN'] = array();
@@ -710,7 +710,7 @@ class ucp_main
'WHERE' => 'b.user_id = ' . $user->data['user_id'] . '
AND ' . $db->sql_in_set('f.forum_id', $forbidden_forum_ary, true, true),
- 'ORDER_BY' => 't.topic_last_post_time DESC'
+ 'ORDER_BY' => 't.topic_last_post_time DESC, t.topic_last_post_id DESC'
);
$sql_array['LEFT_JOIN'] = array();
diff --git a/phpBB/includes/ucp/ucp_notifications.php b/phpBB/includes/ucp/ucp_notifications.php
index 0ed3084e9f..5691302b83 100644
--- a/phpBB/includes/ucp/ucp_notifications.php
+++ b/phpBB/includes/ucp/ucp_notifications.php
@@ -58,21 +58,21 @@ class ucp_notifications
{
foreach($notification_methods as $method => $method_data)
{
- if ($request->is_set_post($type . '_' . $method_data['id']) && (!isset($subscriptions[$type]) || !in_array($method_data['id'], $subscriptions[$type])))
+ if ($request->is_set_post(str_replace('.', '_', $type . '_' . $method_data['id'])) && (!isset($subscriptions[$type]) || !in_array($method_data['id'], $subscriptions[$type])))
{
$phpbb_notifications->add_subscription($type, 0, $method_data['id']);
}
- else if (!$request->is_set_post($type . '_' . $method_data['id']) && isset($subscriptions[$type]) && in_array($method_data['id'], $subscriptions[$type]))
+ else if (!$request->is_set_post(str_replace('.', '_', $type . '_' . $method_data['id'])) && isset($subscriptions[$type]) && in_array($method_data['id'], $subscriptions[$type]))
{
$phpbb_notifications->delete_subscription($type, 0, $method_data['id']);
}
}
- if ($request->is_set_post($type . '_notification') && !isset($subscriptions[$type]))
+ if ($request->is_set_post(str_replace('.', '_', $type) . '_notification') && !isset($subscriptions[$type]))
{
$phpbb_notifications->add_subscription($type);
}
- else if (!$request->is_set_post($type . '_notification') && isset($subscriptions[$type]))
+ else if (!$request->is_set_post(str_replace('.', '_', $type) . '_notification') && isset($subscriptions[$type]))
{
$phpbb_notifications->delete_subscription($type);
}
diff --git a/phpBB/includes/ucp/ucp_pm_options.php b/phpBB/includes/ucp/ucp_pm_options.php
index 353bfdc7ec..d1fc9d2c62 100644
--- a/phpBB/includes/ucp/ucp_pm_options.php
+++ b/phpBB/includes/ucp/ucp_pm_options.php
@@ -32,7 +32,11 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit
// Change "full folder" setting - what to do if folder is full
if (isset($_POST['fullfolder']))
{
- check_form_key('ucp_pm_options', $config['form_token_lifetime'], $redirect_url);
+ if (!check_form_key('ucp_pm_options'))
+ {
+ trigger_error('FORM_INVALID');
+ }
+
$full_action = request_var('full_action', 0);
$set_folder_id = 0;
diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php
index 72921270f4..19acd9ecb9 100644
--- a/phpBB/includes/ucp/ucp_pm_viewfolder.php
+++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php
@@ -383,7 +383,7 @@ function view_folder($id, $mode, $folder_id, $folder)
break;
}
- header('Pragma: no-cache');
+ header('Cache-Control: private, no-cache');
header("Content-Type: $mimetype; name=\"data.$filetype\"");
header("Content-disposition: attachment; filename=data.$filetype");
echo $string;
diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php
index 94383b935f..2f34fd64a5 100644
--- a/phpBB/includes/ucp/ucp_pm_viewmessage.php
+++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php
@@ -250,7 +250,6 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
'U_PM_ACTION' => $url . '&amp;mode=compose&amp;f=' . $folder_id . '&amp;p=' . $message_row['msg_id'],
'S_HAS_ATTACHMENTS' => (sizeof($attachments)) ? true : false,
- 'S_HAS_MULTIPLE_ATTACHMENTS' => (sizeof($attachments) > 1),
'S_DISPLAY_NOTICE' => $display_notice && $message_row['message_attachment'],
'S_AUTHOR_DELETED' => ($author_id == ANONYMOUS) ? true : false,
'S_SPECIAL_FOLDER' => in_array($folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)),
@@ -339,12 +338,6 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
// Display not already displayed Attachments for this post, we already parsed them. ;)
if (isset($attachments) && sizeof($attachments))
{
- $methods = phpbb_gen_download_links('msg_id', $msg_id, $phpbb_root_path, $phpEx);
- foreach ($methods as $method)
- {
- $template->assign_block_vars('dl_method', $method);
- }
-
foreach ($attachments as $attachment)
{
$template->assign_block_vars('attachment', array(
@@ -410,12 +403,15 @@ function get_user_information($user_id, $user_row)
$user_row['avatar'] = ($user->optionget('viewavatars')) ? phpbb_get_user_avatar($user_row) : '';
- if (!function_exists('get_user_rank'))
+ if (!function_exists('phpbb_get_user_rank'))
{
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
}
- get_user_rank($user_row['user_rank'], $user_row['user_posts'], $user_row['rank_title'], $user_row['rank_image'], $user_row['rank_image_src']);
+ $user_rank_data = phpbb_get_user_rank($user_row, $user_row['user_posts']);
+ $user_row['rank_title'] = $user_rank_data['title'];
+ $user_row['rank_image'] = $user_rank_data['img'];
+ $user_row['rank_image_src'] = $user_rank_data['img_src'];
if ((!empty($user_row['user_allow_viewemail']) && $auth->acl_get('u_sendemail')) || $auth->acl_get('a_email'))
{
diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php
index a8c8920a7d..2195500b57 100644
--- a/phpBB/includes/ucp/ucp_prefs.php
+++ b/phpBB/includes/ucp/ucp_prefs.php
@@ -154,7 +154,7 @@ class ucp_prefs
}
$dateformat_options .= '>' . $user->lang['CUSTOM_DATEFORMAT'] . '</option>';
- $timezone_selects = phpbb_timezone_select($user, $data['tz'], true);
+ phpbb_timezone_select($template, $user, $data['tz'], true);
// check if there are any user-selectable languages
$sql = 'SELECT COUNT(lang_id) as languages_count
@@ -208,8 +208,6 @@ class ucp_prefs
'S_LANG_OPTIONS' => language_select($data['lang']),
'S_STYLE_OPTIONS' => ($config['override_user_style']) ? '' : style_select($data['user_style']),
- 'S_TZ_OPTIONS' => $timezone_selects['tz_select'],
- 'S_TZ_DATE_OPTIONS' => $timezone_selects['tz_dates'],
'S_CAN_HIDE_ONLINE' => ($auth->acl_get('u_hideonline')) ? true : false,
'S_SELECT_NOTIFY' => ($config['jab_enable'] && $user->data['user_jabber'] && @extension_loaded('xml')) ? true : false)
);
@@ -223,11 +221,11 @@ class ucp_prefs
$data = array(
'topic_sk' => request_var('topic_sk', (!empty($user->data['user_topic_sortby_type'])) ? $user->data['user_topic_sortby_type'] : 't'),
'topic_sd' => request_var('topic_sd', (!empty($user->data['user_topic_sortby_dir'])) ? $user->data['user_topic_sortby_dir'] : 'd'),
- 'topic_st' => request_var('topic_st', (!empty($user->data['user_topic_show_days'])) ? $user->data['user_topic_show_days'] : 0),
+ 'topic_st' => request_var('topic_st', (!empty($user->data['user_topic_show_days'])) ? (int) $user->data['user_topic_show_days'] : 0),
'post_sk' => request_var('post_sk', (!empty($user->data['user_post_sortby_type'])) ? $user->data['user_post_sortby_type'] : 't'),
'post_sd' => request_var('post_sd', (!empty($user->data['user_post_sortby_dir'])) ? $user->data['user_post_sortby_dir'] : 'a'),
- 'post_st' => request_var('post_st', (!empty($user->data['user_post_show_days'])) ? $user->data['user_post_show_days'] : 0),
+ 'post_st' => request_var('post_st', (!empty($user->data['user_post_show_days'])) ? (int) $user->data['user_post_show_days'] : 0),
'images' => request_var('images', (bool) $user->optionget('viewimg')),
'flash' => request_var('flash', (bool) $user->optionget('viewflash')),
@@ -254,10 +252,22 @@ class ucp_prefs
if ($submit)
{
$error = validate_data($data, array(
- 'topic_sk' => array('string', false, 1, 1),
- 'topic_sd' => array('string', false, 1, 1),
- 'post_sk' => array('string', false, 1, 1),
- 'post_sd' => array('string', false, 1, 1),
+ 'topic_sk' => array(
+ array('string', false, 1, 1),
+ array('match', false, '#(a|r|s|t|v)#'),
+ ),
+ 'topic_sd' => array(
+ array('string', false, 1, 1),
+ array('match', false, '#(a|d)#'),
+ ),
+ 'post_sk' => array(
+ array('string', false, 1, 1),
+ array('match', false, '#(a|s|t)#'),
+ ),
+ 'post_sd' => array(
+ array('string', false, 1, 1),
+ array('match', false, '#(a|d)#'),
+ ),
));
if (!check_form_key('ucp_prefs_view'))
@@ -320,7 +330,7 @@ class ucp_prefs
$limit_topic_days = array(0 => $user->lang['ALL_TOPICS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
$sort_by_topic_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']);
- $sort_by_topic_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_post_time', 'r' => 't.topic_posts_approved', 's' => 't.topic_title', 'v' => 't.topic_views');
+ $sort_by_topic_sql = array('a' => 't.topic_first_poster_name', 't' => array('t.topic_last_post_time', 't.topic_last_post_id'), 'r' => 't.topic_posts_approved', 's' => 't.topic_title', 'v' => 't.topic_views');
// Post ordering options
$limit_post_days = array(0 => $user->lang['ALL_POSTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index a315b167d7..361dc831aa 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -564,30 +564,6 @@ class ucp_profile
trigger_error($message);
}
}
- else
- {
- if ($driver = $phpbb_avatar_manager->get_driver($avatar_data['avatar_type']))
- {
- $driver->delete($avatar_data);
- }
-
- $result = array(
- 'user_avatar' => '',
- 'user_avatar_type' => '',
- 'user_avatar_width' => 0,
- 'user_avatar_height' => 0,
- );
-
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET ' . $db->sql_build_array('UPDATE', $result) . '
- WHERE user_id = ' . (int) $user->data['user_id'];
-
- $db->sql_query($sql);
-
- meta_refresh(3, $this->u_action);
- $message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
- trigger_error($message);
- }
}
else
{
@@ -595,6 +571,27 @@ class ucp_profile
}
}
+ // Handle deletion of avatars
+ if ($request->is_set_post('avatar_delete'))
+ {
+ if (!confirm_box(true))
+ {
+ confirm_box(false, $user->lang('CONFIRM_AVATAR_DELETE'), build_hidden_fields(array(
+ 'avatar_delete' => true,
+ 'i' => $id,
+ 'mode' => $mode))
+ );
+ }
+ else
+ {
+ $phpbb_avatar_manager->handle_avatar_delete($db, $user, $avatar_data, USERS_TABLE, 'user_');
+
+ meta_refresh(3, $this->u_action);
+ $message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
+ trigger_error($message);
+ }
+ }
+
$selected_driver = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', $user->data['user_avatar_type']));
foreach ($avatar_drivers as $current_driver)
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 97934fc32d..9a15967bae 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -182,8 +182,7 @@ class ucp_register
// The CAPTCHA kicks in here. We can't help that the information gets lost on language change.
if ($config['enable_confirm'])
{
- include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
- $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_REG);
}
@@ -390,7 +389,7 @@ class ucp_register
if ($config['require_activation'] == USER_ACTIVATION_ADMIN)
{
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->add_notifications('admin_activate_user', array(
+ $phpbb_notifications->add_notifications('notification.type.admin_activate_user', array(
'user_id' => $user_id,
'user_actkey' => $user_row['user_actkey'],
'user_regdate' => $user_row['user_regdate'],
@@ -453,7 +452,7 @@ class ucp_register
break;
}
- $timezone_selects = phpbb_timezone_select($user, $data['tz'], true);
+ $timezone_selects = phpbb_timezone_select($template, $user, $data['tz'], true);
$template->assign_vars(array(
'ERROR' => (sizeof($error)) ? implode('<br />', $error) : '',
'USERNAME' => $data['username'],
@@ -466,8 +465,6 @@ class ucp_register
'L_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars']), $user->lang('CHARACTERS', (int) $config['max_pass_chars'])),
'S_LANG_OPTIONS' => language_select($data['lang']),
- 'S_TZ_OPTIONS' => $timezone_selects['tz_select'],
- 'S_TZ_DATE_OPTIONS' => $timezone_selects['tz_dates'],
'S_TZ_PRESELECT' => !$submit,
'S_CONFIRM_REFRESH' => ($config['enable_confirm'] && $config['confirm_refresh']) ? true : false,
'S_REGISTRATION' => true,