diff --git a/phpBB/adm/index.php b/phpBB/adm/index.php index 3f0aa4009b..68f8ee634a 100644 --- a/phpBB/adm/index.php +++ b/phpBB/adm/index.php @@ -53,12 +53,19 @@ $module_id = $request->variable('i', ''); $mode = $request->variable('mode', ''); // Set custom style for admin area -$template->set_custom_style(array( - array( - 'name' => 'adm', - 'ext_path' => 'adm/style/', - ), -), $phpbb_admin_path . 'style'); +/** @var \phpbb\template\base $template */ +$template->set_custom_style( + [ + [ + 'name' => 'adm', + 'ext_path' => 'adm/style/', + ] + ], + [ + $phpbb_admin_path . 'style', + $phpbb_root_path . 'styles/all/template/', + ], +); $template->assign_var('T_ASSETS_PATH', $phpbb_root_path . 'assets'); $template->assign_var('T_TEMPLATE_PATH', $phpbb_admin_path . 'style'); diff --git a/phpBB/adm/style/acp_attachments.html b/phpBB/adm/style/acp_attachments.html index a2cfe8f11e..c33d30b1c1 100644 --- a/phpBB/adm/style/acp_attachments.html +++ b/phpBB/adm/style/acp_attachments.html @@ -49,7 +49,13 @@

{options.TITLE_EXPLAIN}
-
{options.CONTENT}
+
+ {% if options.CONTENT is iterable %} + {{ FormsBuildTemplate(options.CONTENT)}} + {% else %} + {options.CONTENT} + {% endif %} +
{% if (options.KEY == 'allow_attachments' and S_EMPTY_POST_GROUPS) or (options.KEY == 'allow_pm_attach' and S_EMPTY_PM_GROUPS) %}
{{ lang(options.KEY == 'allow_attachments' ? 'NO_EXT_GROUP_ALLOWED_POST' : 'NO_EXT_GROUP_ALLOWED_PM', U_EXTENSION_GROUPS) }}
{% endif %} @@ -175,8 +181,14 @@
-

{L_SPECIAL_CATEGORY_EXPLAIN}
-
{S_CATEGORY_SELECT}
+

{L_SPECIAL_CATEGORY_EXPLAIN}
+
+ +
@@ -195,7 +207,10 @@
-
+
+ + {{ FormsSelect(EXT_GROUP_SIZE_OPTIONS) }} +
@@ -275,8 +290,14 @@
-
-
{GROUP_SELECT_OPTIONS}
+
+
+ +

@@ -309,7 +330,13 @@ {extensions.EXTENSION} - {extensions.GROUP_OPTIONS} + + + diff --git a/phpBB/adm/style/acp_board.html b/phpBB/adm/style/acp_board.html index fe3e250099..ae1525d586 100644 --- a/phpBB/adm/style/acp_board.html +++ b/phpBB/adm/style/acp_board.html @@ -27,7 +27,13 @@


{options.TITLE_EXPLAIN}
-
{options.CONTENT}
+
+ {% if options.CONTENT is iterable %} + {{ FormsBuildTemplate(options.CONTENT)}} + {% else %} + {{ options.CONTENT }} + {% endif %} +
diff --git a/phpBB/adm/style/acp_bots.html b/phpBB/adm/style/acp_bots.html index b0e61015b6..b4f8ea5072 100644 --- a/phpBB/adm/style/acp_bots.html +++ b/phpBB/adm/style/acp_bots.html @@ -30,8 +30,10 @@
-

{L_BOT_LANG_EXPLAIN}
-
+

{L_BOT_LANG_EXPLAIN}
+
+ {{ FormsSelect(LANG_OPTIONS) }} +
diff --git a/phpBB/adm/style/acp_inactive.html b/phpBB/adm/style/acp_inactive.html index 1b0b6d46de..153a93fdb4 100644 --- a/phpBB/adm/style/acp_inactive.html +++ b/phpBB/adm/style/acp_inactive.html @@ -65,7 +65,7 @@
- + {{ FormsSelect(INACTIVE_OPTIONS) }}

{L_MARK_ALL}{L_UNMARK_ALL}

{S_FORM_TOKEN} diff --git a/phpBB/adm/style/acp_users_prefs.html b/phpBB/adm/style/acp_users_prefs.html index cd95ea0013..68420389b4 100644 --- a/phpBB/adm/style/acp_users_prefs.html +++ b/phpBB/adm/style/acp_users_prefs.html @@ -9,47 +9,49 @@
{L_UCP_PREFS_PERSONAL} -
+
-
+
-
+

{L_ALLOW_PM_EXPLAIN}
-
+
-
+

{L_NOTIFY_METHOD_EXPLAIN}
-
+
-
-
-
+
+
+
+ {{ FormsSelect(LANG_OPTIONS) }} +
-
+
-
+

{L_BOARD_DATE_FORMAT_EXPLAIN}
style="display:none;">
@@ -60,22 +62,22 @@
{L_UCP_PREFS_POST} -
+
-
+
-
+
-
+
@@ -86,52 +88,52 @@
{L_UCP_PREFS_VIEW} -
+
-
+
-
+
-
+
-
+
-
+
{S_TOPIC_SORT_DAYS}
-
+
{S_TOPIC_SORT_KEY}
-
+
{S_TOPIC_SORT_DIR}
-
+
{S_POST_SORT_DAYS}
-
+
{S_POST_SORT_KEY}
-
+
{S_POST_SORT_DIR}
diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index d1007d0173..5949c73920 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -340,6 +340,19 @@ $(function() { }); } + // Handle date option changes + const dateoptionSelect = document.getElementById('dateoptions'); + if (dateoptionSelect) { + dateoptionSelect.addEventListener('change', function() { + const dateoptionInput = document.getElementById(this.getAttribute('data-dateoption')); + if (this.value === 'custom') { + dateoptionInput.value = this.getAttribute('data-dateoption-default'); + } else { + dateoptionInput.value = this.value; + } + }) + } + if ($('#acp_help_phpbb')) { phpbb.prepareSendStats(); } diff --git a/phpBB/adm/style/timezone_option.html b/phpBB/adm/style/timezone_option.html index acfff30184..9b0817902a 100644 --- a/phpBB/adm/style/timezone_option.html +++ b/phpBB/adm/style/timezone_option.html @@ -1,27 +1,15 @@
-
- -
+ {% if TIMEZONE_OPTIONS %} +
+ {% set tz_date_data = TIMEZONE_OPTIONS | merge({options: [{ value: "", label: lang('SELECT_CURRENT_TIME')}] | merge(TIMEZONE_OPTIONS.options) }) %} + {{ FormsSelect(tz_date_data | merge({class: 'autowidth tz_select', id: 'tz_date', name: 'tz_date', group_only: true})) }}
- + {% endif %}
- + {% set tz_select_data = TIMEZONE_OPTIONS | merge({ options: [{ value: "", label: lang('SELECT_TIMEZONE') }] | merge(TIMEZONE_OPTIONS.options) }) %} + {{ FormsSelect(tz_select_data | merge({class: 'autowidth tz_select', id: 'timezone'})) }} - + {% INCLUDEJS('timezone.js') %}
diff --git a/phpBB/config/default/container/services_twig.yml b/phpBB/config/default/container/services_twig.yml index 747d2ee155..8700630a73 100644 --- a/phpBB/config/default/container/services_twig.yml +++ b/phpBB/config/default/container/services_twig.yml @@ -69,6 +69,13 @@ services: template.twig.extensions.debug: class: Twig\Extension\DebugExtension + template.twig.extensions.forms: + class: phpbb\template\twig\extension\forms + arguments: + - '@user' + tags: + - { name: twig.extension } + template: class: phpbb\template\twig\twig arguments: diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 0f1fc3f6a8..329900130e 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -452,11 +452,11 @@ class acp_attachments $cache->destroy('_extensions'); } - $template->assign_vars(array( + $template->assign_vars([ 'S_EXTENSIONS' => true, 'ADD_EXTENSION' => (isset($add_extension)) ? $add_extension : '', - 'GROUP_SELECT_OPTIONS' => (isset($_POST['add_extension_check'])) ? $this->group_select('add_group_select', $add_extension_group, 'extension_group') : $this->group_select('add_group_select', false, 'extension_group')) - ); + 'GROUP_SELECT_OPTIONS' => $this->group_select('add_group_select', $request->is_set_post('add_extension_check') ? $add_extension_group : false, 'extension_group'), + ]); $sql = 'SELECT * FROM ' . EXTENSIONS_TABLE . ' @@ -794,7 +794,10 @@ class acp_attachments 'ASSIGNED_EXTENSIONS' => $assigned_extensions, 'S_CATEGORY_SELECT' => $this->category_select('special_category', $group_id, 'category'), - 'S_EXT_GROUP_SIZE_OPTIONS' => size_select_options($size_format), + 'EXT_GROUP_SIZE_OPTIONS' => [ + 'name' => 'size_select', + 'options' => size_select_options($size_format), + ], 'S_EXTENSION_OPTIONS' => $s_extension_options, 'S_FILENAME_LIST' => $filename_list, 'S_EDIT_GROUP' => true, @@ -1445,16 +1448,21 @@ class acp_attachments $cat_type = attachment_category::NONE; } - $group_select = ''; - return $group_select; } @@ -1465,8 +1473,6 @@ class acp_attachments { global $db, $user; - $group_select = ''; - return $group_select; } @@ -1712,8 +1726,23 @@ class acp_attachments $size_var = $filesize['si_identifier']; $value = $filesize['value']; - // size and maxlength must not be specified for input of type number - return ' '; + return [ + [ + 'tag' => 'input', + 'id' => $key, + 'type' => 'number', + 'name' => 'config[' . $key . ']', + 'min' => 0, + 'max' => 999999999999999, + 'step' => 'any', + 'value' => $value, + ], + [ + 'tag' => 'select', + 'name' => $key, + 'options' => size_select_options($size_var), + ] + ]; } /** diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 8c3950d65c..beccef809d 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -18,6 +18,11 @@ /** * @ignore */ + +use phpbb\config\config; +use phpbb\language\language; +use phpbb\user; + if (!defined('IN_PHPBB')) { exit; @@ -28,16 +33,26 @@ class acp_board var $u_action; var $new_config; + /** @var config */ + protected $config; + + /** @var language */ + protected $language; + + /** @var user */ + protected $user; + function main($id, $mode) { global $user, $template, $request, $language; global $config, $phpbb_root_path, $phpEx; global $cache, $phpbb_container, $phpbb_dispatcher, $phpbb_log; - /** @var \phpbb\language\language $language Language object */ - $language = $phpbb_container->get('language'); + $this->config = $config; + $this->language = $language; + $this->user = $user; - $user->add_lang('acp/board'); + $this->language->add_lang('acp/board'); $submit = (isset($_POST['submit']) || isset($_POST['allow_quick_reply_enable'])) ? true : false; @@ -64,7 +79,7 @@ class acp_board 'board_index_text' => array('lang' => 'BOARD_INDEX_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'board_disable' => array('lang' => 'DISABLE_BOARD', 'validate' => 'bool', 'type' => 'custom', 'method' => 'board_disable', 'explain' => true), 'board_disable_msg' => false, - 'default_lang' => array('lang' => 'DEFAULT_LANGUAGE', 'validate' => 'lang', 'type' => 'select', 'function' => 'language_select', 'params' => array('{CONFIG_VALUE}'), 'explain' => false), + 'default_lang' => array('lang' => 'DEFAULT_LANGUAGE', 'validate' => 'lang', 'type' => 'select', 'method' => 'language_select', 'params' => array('{CONFIG_VALUE}'), 'explain' => false), 'default_dateformat' => array('lang' => 'DEFAULT_DATE_FORMAT', 'validate' => 'string', 'type' => 'custom', 'method' => 'dateformat_select', 'explain' => true), 'board_timezone' => array('lang' => 'SYSTEM_TIMEZONE', 'validate' => 'timezone', 'type' => 'custom', 'method' => 'timezone_select', 'explain' => true), @@ -503,7 +518,7 @@ class acp_board { if (!preg_match('#^[a-z][a-z0-9+\\-.]*$#Di', $scheme)) { - $error[] = $language->lang('URL_SCHEME_INVALID', $language->lang('ALLOWED_SCHEMES_LINKS'), $scheme); + $error[] = $this->language->lang('URL_SCHEME_INVALID', $this->language->lang('ALLOWED_SCHEMES_LINKS'), $scheme); } } } @@ -976,19 +991,50 @@ class acp_board /** * Select bump interval */ - function bump_interval($value, $key) + public function bump_interval($value, $key): array { - global $user; - - $s_bump_type = ''; + $bump_type_options = []; $types = array('m' => 'MINUTES', 'h' => 'HOURS', 'd' => 'DAYS'); foreach ($types as $type => $lang) { - $selected = ($this->new_config['bump_type'] == $type) ? ' selected="selected"' : ''; - $s_bump_type .= ''; + $bump_type_options[] = [ + 'value' => $type, + 'selected' => $this->new_config['bump_type'] == $type, + 'label' => $this->language->lang($lang), + ]; } - return ' '; + return [ + [ + 'tag' => 'input', + 'id' => $key, + 'type' => 'text', + 'size' => 3, + 'maxlength' => 4, + 'name' => 'config[bump_interval]', + 'value' => $value, + ], + [ + 'tag' => 'select', + 'name' => 'config[bump_type]', + 'options' => $bump_type_options, + ], + ]; + } + + /** + * Wrapper function for phpbb_language_select() + * + * @param string $default + * @param array $langdata + * + * @return array + */ + public function language_select(string $default = '', array $langdata = []): array + { + global $db; + + return phpbb_language_select($db, $default, $langdata); } /** @@ -1019,11 +1065,13 @@ class acp_board */ function timezone_select($value, $key) { - global $template, $user; + $timezone_select = phpbb_timezone_select($this->user, $value, true); - $timezone_select = phpbb_timezone_select($template, $user, $value, true); - - return ''; + return [ + 'tag' => 'select', + 'name' => 'config[' . $key . ']', + 'options' => $timezone_select, + ]; } /** @@ -1060,81 +1108,132 @@ class acp_board } /** - * Select default dateformat - */ - function dateformat_select($value, $key) + * Create select for default date format + * + * @param string $value Current date format value + * @param string $key Date format key + * + * @return array Date format select data + */ + public function dateformat_select(string $value, string $key): array { - global $user, $config; - // Let the format_date function operate with the acp values - $old_tz = $user->timezone; + $old_tz = $this->user->timezone; try { - $user->timezone = new DateTimeZone($config['board_timezone']); + $this->user->timezone = new DateTimeZone($this->config['board_timezone']); } catch (\Exception $e) { // If the board timezone is invalid, we just use the users timezone. } - $dateformat_options = ''; + $dateformat_options = []; - foreach ($user->lang['dateformats'] as $format => $null) + $dateformats = $this->language->lang_raw('dateformats'); + if (!is_array($dateformats)) { - $dateformat_options .= ''; + $dateformats = []; } - $dateformat_options .= ''; + + // Add custom entry + $dateformat_options[] = [ + 'value' => 'custom', + 'selected' => !isset($dateformats[$value]), + 'label' => $this->language->lang('CUSTOM_DATEFORMAT'), + ]; // Reset users date options - $user->timezone = $old_tz; + $this->user->timezone = $old_tz; - return " - "; + return [ + [ + 'tag' => 'select', + 'name' => 'dateoptions', + 'id' => 'dateoptions', + 'options' => $dateformat_options, + 'data' => [ + 'dateoption' => $key, + 'dateoption-default' => $value, + ] + ], + [ + 'tag' => 'input', + 'type' => 'text', + 'name' => "config[$key]", + 'id' => $key, + 'value' => $value, + 'maxlength' => 64, + ] + ]; } /** - * Select multiple forums - */ - function select_news_forums($value, $key) + * Select for multiple forums + * + * @param mixed $value Config value, unused + * @param string $key Config key + * + * @return array Forum select data + */ + public function select_news_forums($value, string $key) { - $forum_list = make_forum_select(false, false, true, true, true, false, true); - - // Build forum options - $s_forum_options = ''; - - return $s_forum_options; + return $this->get_forum_select($key); } - function select_exclude_forums($value, $key) + /** + * Select for multiple forums to exclude + * + * @param mixed $value Config value, unused + * @param string $key Config key + * + * @return array Forum select data + */ + public function select_exclude_forums($value, string $key): array + { + return $this->get_forum_select($key, FORUM_OPTION_FEED_EXCLUDE); + } + + /** + * Get forum select data for specified key and option + * + * @param string $key Config key + * @param int $forum_option Forum option bit + * + * @return array Forum select data + */ + protected function get_forum_select(string $key, int $forum_option = FORUM_OPTION_FEED_NEWS): array { $forum_list = make_forum_select(false, false, true, true, true, false, true); // Build forum options - $s_forum_options = ''; - return $s_forum_options; + return [ + 'tag' => 'select', + 'id' => $key, + 'name' => $key . '[]', + 'multiple' => true, + 'options' => $forum_options, + ]; } function store_feed_forums($option, $key) diff --git a/phpBB/includes/acp/acp_bots.php b/phpBB/includes/acp/acp_bots.php index 8bd357bc91..323dd1baee 100644 --- a/phpBB/includes/acp/acp_bots.php +++ b/phpBB/includes/acp/acp_bots.php @@ -330,7 +330,7 @@ class acp_bots } $style_select = style_select($bot_row['bot_style'], true); - $lang_select = language_select($bot_row['bot_lang']); + $lang_options = phpbb_language_select($db, $bot_row['bot_lang']); $l_title = ($action == 'edit') ? 'EDIT' : 'ADD'; @@ -347,10 +347,13 @@ class acp_bots 'S_EDIT_BOT' => true, 'S_ACTIVE_OPTIONS' => $s_active_options, 'S_STYLE_OPTIONS' => $style_select, - 'S_LANG_OPTIONS' => $lang_select, + 'LANG_OPTIONS' => [ + 'id' => 'bot_lang', + 'name' => 'bot_lang', + 'options' => $lang_options, + ], 'S_ERROR' => (count($error)) ? true : false, - ) - ); + )); return; diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index 7b4536f755..02412aa526 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -306,7 +306,10 @@ class acp_inactive $template->assign_vars(array( 'S_INACTIVE_USERS' => true, - 'S_INACTIVE_OPTIONS' => build_select($option_ary), + 'INACTIVE_OPTIONS' => [ + 'name' => 'action', + 'options' => build_select($option_ary), + ], 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index 71e9ed7a2e..d99d1995db 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -626,16 +626,7 @@ class acp_main )); } - $option_ary = array('activate' => 'ACTIVATE', 'delete' => 'DELETE'); - if ($config['email_enable']) - { - $option_ary += array('remind' => 'REMIND'); - } - - $template->assign_vars(array( - 'S_INACTIVE_USERS' => true, - 'S_INACTIVE_OPTIONS' => build_select($option_ary)) - ); + $template->assign_var('S_INACTIVE_USERS', true); } // Warn if install is still present diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index e98cbcaf2e..8be78c24f2 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1795,7 +1795,9 @@ class acp_users ${'s_sort_' . $sort_option . '_dir'} .= ''; } - phpbb_timezone_select($template, $user, $data['tz'], true); + $timezone_select = phpbb_timezone_select($user, $data['tz'], true); + $lang_options = phpbb_language_select($db, $data['lang']); + $user_prefs_data = array( 'S_PREFS' => true, 'S_JABBER_DISABLED' => ($config['jab_enable'] && $user_row['user_jabber'] && @extension_loaded('xml')) ? false : true, @@ -1831,8 +1833,17 @@ class acp_users 'DEFAULT_DATEFORMAT' => $config['default_dateformat'], 'A_DEFAULT_DATEFORMAT' => addslashes($config['default_dateformat']), - 'S_LANG_OPTIONS' => language_select($data['lang']), + 'LANG_OPTIONS' => [ + 'id' => 'lang', + 'name' => 'lang', + 'options' => $lang_options, + ], 'S_STYLE_OPTIONS' => style_select($data['style']), + 'TIMEZONE_OPTIONS' => [ + 'tag' => 'select', + 'name' => 'tz', + 'options' => $timezone_select, + ], ); /** diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 27ead08d9c..57aa0eccb2 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -265,15 +265,12 @@ function phpbb_version_compare(string $version1, string $version2, string $opera /** * Pick a language, any language ... * + * @param \phpbb\db\driver\driver_interface $db DBAL driver * @param string $default Language ISO code to be selected by default in the dropdown list * @param array $langdata Language data in format of array(array('lang_iso' => string, lang_local_name => string), ...) - * - * @return string HTML options for language selection dropdown list. */ -function language_select($default = '', array $langdata = []) +function phpbb_language_select(\phpbb\db\driver\driver_interface $db, string $default = '', array $langdata = []): array { - global $db; - if (empty($langdata)) { $sql = 'SELECT lang_iso, lang_local_name @@ -284,11 +281,14 @@ function language_select($default = '', array $langdata = []) $db->sql_freeresult($result); } - $lang_options = ''; + $lang_options = []; foreach ($langdata as $row) { - $selected = ($row['lang_iso'] == $default) ? ' selected="selected"' : ''; - $lang_options .= ''; + $lang_options[] = [ + 'value' => $row['lang_iso'], + 'label' => $row['lang_local_name'], + 'selected' => $row['lang_iso'] === $default, + ]; } return $lang_options; @@ -442,14 +442,13 @@ 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 string Returns an array containing the options for the time selector. */ -function phpbb_timezone_select($template, $user, $default = '', $truncate = false) +function phpbb_timezone_select($user, $default = '', $truncate = false) { static $timezones; @@ -481,27 +480,22 @@ function phpbb_timezone_select($template, $user, $default = '', $truncate = fals uksort($timezones, 'phpbb_tz_select_compare'); } - $tz_select = $opt_group = ''; + $opt_group = ''; + $tz_data = []; foreach ($timezones as $key => $timezone) { if ($opt_group != $timezone['offset']) { - // Generate tz_select for backwards compatibility - $tz_select .= ($opt_group) ? '' : ''; - $tz_select .= ''; - $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'], - )); + $tz_data[$timezone['offset']] = [ + 'label' => $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $timezone['current']), + 'value' => $key . ' - ' . $timezone['current'], + 'options' => [], + 'selected' => !empty($default_offset) && strpos($key, $default_offset) !== false, + 'data' => ['tz-value' => $key . ' - ' . $timezone['current']], + ]; - $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']), - )); + $opt_group = $timezone['offset']; } $label = $timezone['tz']; @@ -516,19 +510,15 @@ function phpbb_timezone_select($template, $user, $default = '', $truncate = fals $label = truncate_string($label, 50, 255, false, '...'); } - // Also generate timezone_select for backwards compatibility - $selected = ($timezone['tz'] === $default) ? ' selected="selected"' : ''; - $tz_select .= ''; - $template->assign_block_vars('timezone_select.timezone_options', array( + $tz_data[$timezone['offset']]['options'][] = [ 'TITLE' => $title, - 'VALUE' => $timezone['tz'], - 'SELECTED' => !empty($selected), - 'LABEL' => $label, - )); + 'value' => $timezone['tz'], + 'selected' => $timezone['tz'] === $default, + 'label' => $label, + ]; } - $tz_select .= ''; - return $tz_select; + return $tz_data; } // Functions handling topic/post tracking/marking diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php index 9a1d4b6a70..26d16aaae8 100644 --- a/phpBB/includes/functions_acp.php +++ b/phpBB/includes/functions_acp.php @@ -209,18 +209,21 @@ function adm_back_link($u_action) /** * Build select field options in acp pages */ -function build_select($option_ary, $option_default = false) +function build_select($option_ary, $option_default = false): array { - global $user; + global $language; - $html = ''; + $options = []; foreach ($option_ary as $value => $title) { - $selected = ($option_default !== false && $value == $option_default) ? ' selected="selected"' : ''; - $html .= ''; + $options[] = [ + 'value' => $value, + 'selected' => $option_default !== false && $value == $option_default, + 'label' => $language->lang($title), + ]; } - return $html; + return $options; } /** @@ -243,13 +246,20 @@ function h_radio($name, $input_ary, $input_default = false, $id = false, $key = } /** -* Build configuration template for acp configuration pages -*/ -function build_cfg_template($tpl_type, $key, &$new_ary, $config_key, $vars) + * HTML-less version of build_cfg_template + * + * @param array $tpl_type Template type + * @param string $key Config key + * @param $new_ary + * @param $config_key + * @param $vars + * @return array + */ +function phpbb_build_cfg_template(array $tpl_type, string $key, &$new_ary, $config_key, $vars): array { - global $user, $module, $phpbb_dispatcher; + global $language; - $tpl = ''; + $tpl = []; $name = 'config[' . $config_key . ']'; // Make sure there is no notice printed out for non-existent config options (we simply set them) @@ -266,6 +276,8 @@ function build_cfg_template($tpl_type, $key, &$new_ary, $config_key, $vars) // replace passwords with asterixes $new_ary[$config_key] = '********'; } + // no break + case 'text': case 'url': case 'email': @@ -276,7 +288,15 @@ function build_cfg_template($tpl_type, $key, &$new_ary, $config_key, $vars) $size = (int) $tpl_type[1]; $maxlength = (int) $tpl_type[2]; - $tpl = ''; + $tpl = [ + 'tag' => 'input', + 'id' => $key, + 'type' => $tpl_type[0], + 'name' => $name, + 'size' => $size ?: '', + 'maxlength' => $maxlength ?: 255, + 'value' => $new_ary[$config_key], + ]; break; case 'color': @@ -284,7 +304,13 @@ function build_cfg_template($tpl_type, $key, &$new_ary, $config_key, $vars) case 'datetime-local': case 'month': case 'week': - $tpl = ''; + $tpl = [ + 'tag' => 'input', + 'id' => $key, + 'type' => $tpl_type[0], + 'name' => $name, + 'value' => $new_ary[$config_key], + ]; break; case 'date': @@ -294,34 +320,125 @@ function build_cfg_template($tpl_type, $key, &$new_ary, $config_key, $vars) $min = isset($tpl_type[1]) ? (int) $tpl_type[1] : false; $max = isset($tpl_type[2]) ? (int) $tpl_type[2] : false; - $tpl = ''; + $tpl = [ + 'tag' => 'input', + 'id' => $key, + 'type' => $tpl_type[0], + 'name' => $name, + 'min' => $min !== false ? $min : '', + 'max' => $max !== false ? $max : '', + 'value' => $new_ary[$config_key], + ]; break; case 'dimension': $min = isset($tpl_type[1]) ? (int) $tpl_type[1] : false; $max = isset($tpl_type[2]) ? (int) $tpl_type[2] : false; - $tpl = ' x '; + $tpl = [ + 'tag' => 'dimension', + 'width' => [ + 'id' => $key, + 'type' => 'number', + 'name' => 'config[' . $config_key . '_width]', + 'min' => $min !== false ? $min : '', + 'max' => $max !== false ? $max : '', + 'value' => $new_ary[$config_key . '_width'], + ], + 'height' => [ + 'type' => 'number', + 'name' => 'config[' . $config_key . '_height]', + 'min' => $min !== false ? $min : '', + 'max' => $max !== false ? $max : '', + 'value' => $new_ary[$config_key . '_height'], + ], + ]; break; case 'textarea': - $rows = (int) $tpl_type[1]; - $cols = (int) $tpl_type[2]; - - $tpl = ''; + $tpl = [ + 'tag' => 'textarea', + 'id' => $key, + 'name' => $name, + 'rows' => (int) $tpl_type[1], + 'cols' => (int) $tpl_type[2], + 'content' => $new_ary[$config_key], + ]; break; case 'radio': - $key_yes = ($new_ary[$config_key]) ? ' checked="checked"' : ''; - $key_no = (!$new_ary[$config_key]) ? ' checked="checked"' : ''; - $tpl_type_cond = explode('_', $tpl_type[1]); - $type_no = ($tpl_type_cond[0] == 'disabled' || $tpl_type_cond[0] == 'enabled') ? false : true; + $type_no = $tpl_type_cond[0] != 'disabled' && $tpl_type_cond[0] != 'enabled'; - $tpl_no = ''; - $tpl_yes = ''; + $no_button = [ + 'type' => 'radio', + 'name' => $name, + 'value' => 0, + 'checked' => !$new_ary[$config_key], + 'label' => $type_no ? $language->lang('NO') : $language->lang('DISABLED'), + ]; - $tpl = ($tpl_type_cond[0] == 'yes' || $tpl_type_cond[0] == 'enabled') ? $tpl_yes . $tpl_no : $tpl_no . $tpl_yes; + $yes_button = [ + 'id' => $key, + 'type' => 'radio', + 'name' => $name, + 'value' => 1, + 'checked' => (bool) $new_ary[$config_key], + 'label' => $type_no ? $language->lang('YES') : $language->lang('ENABLED'), + ]; + + $tpl = ['tag' => 'radio']; + if ($tpl_type_cond[0] == 'yes' || $tpl_type_cond[0] == 'enabled') + { + $tpl['buttons'] = [$yes_button, $no_button]; + } + else + { + $tpl['buttons'] = [$no_button, $yes_button]; + } + break; + } + + return $tpl; +} + +/** +* Build configuration template for acp configuration pages +*/ +function build_cfg_template($tpl_type, $key, &$new_ary, $config_key, $vars) +{ + global $module, $phpbb_dispatcher; + + $tpl = ''; + $name = 'config[' . $config_key . ']'; + + // Make sure there is no notice printed out for non-existent config options (we simply set them) + if (!isset($new_ary[$config_key])) + { + $new_ary[$config_key] = ''; + } + + switch ($tpl_type[0]) + { + case 'password': + case 'text': + case 'url': + case 'email': + case 'tel': + case 'search': + case 'color': + case 'datetime': + case 'datetime-local': + case 'month': + case 'week': + case 'date': + case 'time': + case 'number': + case 'range': + case 'dimension': + case 'textarea': + case 'radio': + $tpl = phpbb_build_cfg_template($tpl_type, $key, $new_ary, $config_key, $vars); break; case 'select': @@ -369,9 +486,29 @@ function build_cfg_template($tpl_type, $key, &$new_ary, $config_key, $vars) if ($tpl_type[0] == 'select') { $size = (isset($tpl_type[1])) ? (int) $tpl_type[1] : 1; - $data_toggle = (!empty($tpl_type[2])) ? ' data-togglable-settings="true"' : ''; - $tpl = ''; + if (is_string($return)) + { + $data_toggle = (!empty($tpl_type[2])) ? ' data-togglable-settings="true"' : ''; + + $tpl = ''; + } + else + { + $tpl = [ + 'tag' => 'select', + 'id' => $key, + 'name' => $name, + 'toggleable' => !empty($tpl_type[2]), + 'options' => $return, + ]; + + // Add size if it differs from default value of 1 + if ($size != 1) + { + $tpl['size'] = $size; + } + } } else { @@ -386,7 +523,14 @@ function build_cfg_template($tpl_type, $key, &$new_ary, $config_key, $vars) if (isset($vars['append'])) { - $tpl .= $vars['append']; + if (is_array($tpl)) + { + $tpl['append'] = $vars['append']; + } + else + { + $tpl .= $vars['append']; + } } $new = $new_ary; diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 621d1a284e..4eaedc4041 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -160,20 +160,23 @@ function make_forum_select($select_id = false, $ignore_id = false, $ignore_acl = */ function size_select_options($size_compare) { - global $user; + global $language; - $size_types_text = array($user->lang['BYTES'], $user->lang['KIB'], $user->lang['MIB']); + $size_types_text = array($language->lang('BYTES'), $language->lang('KIB'), $language->lang('MIB')); $size_types = array('b', 'kb', 'mb'); - $s_size_options = ''; + $size_options = []; for ($i = 0, $size = count($size_types_text); $i < $size; $i++) { - $selected = ($size_compare == $size_types[$i]) ? ' selected="selected"' : ''; - $s_size_options .= ''; + $size_options[] = [ + 'value' => $size_types[$i], + 'selected' => $size_compare == $size_types[$i], + 'label' => $size_types_text[$i], + ]; } - return $s_size_options; + return $size_options; } /** diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php index 77b2ef4220..95def7b7e9 100644 --- a/phpBB/includes/functions_compatibility.php +++ b/phpBB/includes/functions_compatibility.php @@ -111,9 +111,9 @@ function phpbb_clean_path($path) */ function tz_select($default = '', $truncate = false) { - global $template, $user; + global $user; - return phpbb_timezone_select($template, $user, $default, $truncate); + return phpbb_timezone_select($user, $default, $truncate); } /** diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index a1fa086b52..dcbd2624f2 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -156,7 +156,7 @@ class ucp_prefs } $dateformat_options .= '>' . $user->lang['CUSTOM_DATEFORMAT'] . ''; - phpbb_timezone_select($template, $user, $data['tz'], true); + $timezone_select = phpbb_timezone_select($user, $data['tz'], true); // check if there are any user-selectable languages $sql = 'SELECT lang_iso, lang_local_name @@ -177,6 +177,8 @@ class ucp_prefs $db->sql_freeresult($result); $s_more_styles = count($styles_row) > 1; + $lang_options = phpbb_language_select($db, $data['lang'], $lang_row); + $template->assign_vars(array( 'ERROR' => (count($error)) ? implode('
', $error) : '', @@ -198,8 +200,17 @@ class ucp_prefs 'S_MORE_LANGUAGES' => $s_more_languages, 'S_MORE_STYLES' => $s_more_styles, - 'S_LANG_OPTIONS' => language_select($data['lang'], $lang_row), + 'LANG_OPTIONS' => [ + 'id' => 'lang', + 'name' => 'lang', + 'options' => $lang_options, + ], 'S_STYLE_OPTIONS' => ($config['override_user_style']) ? '' : style_select($data['user_style'], false, $styles_row), + 'TIMEZONE_OPTIONS' => [ + 'tag' => 'select', + 'name' => 'tz', + 'options' => $timezone_select, + ], '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) ); diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index d5c9e0209f..b739cb6ce8 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -157,6 +157,8 @@ class ucp_register $lang_row = (array) $db->sql_fetchrowset($result); $db->sql_freeresult($result); + $lang_options = phpbb_language_select($db, $user_lang, $lang_row); + if ($coppa === false && $config['coppa_enable']) { $now = getdate(); @@ -167,7 +169,11 @@ class ucp_register unset($now); $template_vars = array( - 'S_LANG_OPTIONS' => (count($lang_row) > 1) ? language_select($user_lang, $lang_row) : '', + 'LANG_OPTIONS' => [ + 'id' => 'lang', + 'name' => 'lang', + 'options' => $lang_options, + ], 'L_COPPA_NO' => $user->lang('UCP_COPPA_BEFORE', $coppa_birthday), 'L_COPPA_YES' => $user->lang('UCP_COPPA_ON_AFTER', $coppa_birthday), @@ -182,7 +188,11 @@ class ucp_register else { $template_vars = array( - 'S_LANG_OPTIONS' => (count($lang_row) > 1) ? language_select($user_lang, $lang_row) : '', + 'LANG_OPTIONS' => [ + 'id' => 'lang', + 'name' => 'lang', + 'options' => $lang_options, + ], 'L_TERMS_OF_USE' => sprintf($user->lang['TERMS_OF_USE_CONTENT'], $config['sitename'], generate_board_url()), 'S_SHOW_COPPA' => false, @@ -616,7 +626,7 @@ class ucp_register } // Assign template vars for timezone select - phpbb_timezone_select($template, $user, $data['tz'], true); + $timezone_select = phpbb_timezone_select($user, $data['tz'], true); // Checking amount of available languages $sql = 'SELECT lang_iso, lang_local_name @@ -626,6 +636,8 @@ class ucp_register $lang_row = (array) $db->sql_fetchrowset($result); $db->sql_freeresult($result); + $lang_options = phpbb_language_select($db, $data['lang'], $lang_row); + $template_vars = array( 'USERNAME' => $data['username'], 'PASSWORD' => $data['new_password'], @@ -636,7 +648,16 @@ class ucp_register 'L_USERNAME_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])), 'L_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars'])), - 'S_LANG_OPTIONS' => (count($lang_row) > 1) ? language_select($data['lang'], $lang_row) : '', + 'LANG_OPTIONS' => [ + 'id' => 'lang', + 'name' => 'lang', + 'options' => $lang_options, + ], + 'TIMEZONE_OPTIONS' => [ + 'tag' => 'select', + 'name' => 'tz', + 'options' => $timezone_select, + ], 'S_TZ_PRESELECT' => !$submit, 'S_CONFIRM_REFRESH' => ($config['enable_confirm'] && $config['confirm_refresh']) ? true : false, 'S_REGISTRATION' => true, diff --git a/phpBB/index.php b/phpBB/index.php index d797ae1230..ac6ab8a134 100644 --- a/phpBB/index.php +++ b/phpBB/index.php @@ -86,52 +86,10 @@ if (($mark_notification = $request->variable('mark_notification', 0))) display_forums('', $config['load_moderators']); -$order_legend = ($config['legend_sort_groupname']) ? 'group_name' : 'group_legend'; -// Grab group details for legend display -if ($auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) -{ - $sql = 'SELECT group_id, group_name, group_colour, group_type, group_legend - FROM ' . GROUPS_TABLE . ' - WHERE group_legend > 0 - ORDER BY ' . $order_legend . ' ASC'; -} -else -{ - $sql = 'SELECT g.group_id, g.group_name, g.group_colour, g.group_type, g.group_legend - FROM ' . GROUPS_TABLE . ' g - LEFT JOIN ' . USER_GROUP_TABLE . ' ug - ON ( - g.group_id = ug.group_id - AND ug.user_id = ' . $user->data['user_id'] . ' - AND ug.user_pending = 0 - ) - WHERE g.group_legend > 0 - AND (g.group_type <> ' . GROUP_HIDDEN . ' OR ug.user_id = ' . $user->data['user_id'] . ') - ORDER BY g.' . $order_legend . ' ASC'; -} -$result = $db->sql_query($sql); - /** @var \phpbb\group\helper $group_helper */ $group_helper = $phpbb_container->get('group_helper'); -$legend = array(); -while ($row = $db->sql_fetchrow($result)) -{ - $colour_text = ($row['group_colour']) ? ' style="color:#' . $row['group_colour'] . '"' : ''; - $group_name = $group_helper->get_name($row['group_name']); - - if ($row['group_name'] == 'BOTS' || ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile'))) - { - $legend[] = '' . $group_name . ''; - } - else - { - $legend[] = '' . $group_name . ''; - } -} -$db->sql_freeresult($result); - -$legend = implode($user->lang['COMMA_SEPARATOR'], $legend); +$group_helper->display_legend($db, $template); // Generate birthday list if required ... $show_birthdays = ($config['load_birthdays'] && $config['allow_birthdays'] && $auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel')); @@ -219,7 +177,6 @@ $template->assign_vars(array( 'TOTAL_USERS' => $user->lang('TOTAL_USERS', (int) $config['num_users']), 'NEWEST_USER' => $user->lang('NEWEST_USER', get_username_string('full', $config['newest_user_id'], $config['newest_username'], $config['newest_user_colour'])), - 'LEGEND' => $legend, 'BIRTHDAY_LIST' => (empty($birthday_list)) ? '' : implode($user->lang['COMMA_SEPARATOR'], $birthday_list), 'S_LOGIN_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'), diff --git a/phpBB/phpbb/group/helper.php b/phpBB/phpbb/group/helper.php index c56c08c0a4..4098846709 100644 --- a/phpBB/phpbb/group/helper.php +++ b/phpBB/phpbb/group/helper.php @@ -17,9 +17,11 @@ use phpbb\auth\auth; use phpbb\avatar\helper as avatar_helper; use phpbb\cache\service as cache; use phpbb\config\config; +use phpbb\db\driver\driver_interface; use phpbb\language\language; use phpbb\event\dispatcher_interface; use phpbb\path_helper; +use phpbb\template\template; use phpbb\user; class helper @@ -294,8 +296,56 @@ class helper * * @return array Avatar data */ - function get_avatar($group_row, $alt = 'GROUP_AVATAR', $ignore_config = false, $lazy = false) + public function get_avatar($group_row, $alt = 'GROUP_AVATAR', $ignore_config = false, $lazy = false) { return $this->avatar_helper->get_group_avatar($group_row, $alt, $ignore_config, $lazy); } + + /** + * Display groups legend + * + * @param driver_interface $db + * @param template $template + * @return void + */ + public function display_legend(driver_interface $db, template $template): void + { + $order_legend = $this->config['legend_sort_groupname'] ? 'group_name' : 'group_legend'; + + // Grab group details for legend display + if ($this->auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) + { + $sql = 'SELECT group_id, group_name, group_colour, group_type, group_legend + FROM ' . GROUPS_TABLE . ' + WHERE group_legend > 0 + ORDER BY ' . $order_legend . ' ASC'; + } + else + { + $sql = 'SELECT g.group_id, g.group_name, g.group_colour, g.group_type, g.group_legend + FROM ' . GROUPS_TABLE . ' g + LEFT JOIN ' . USER_GROUP_TABLE . ' ug + ON ( + g.group_id = ug.group_id + AND ug.user_id = ' . $this->user->data['user_id'] . ' + AND ug.user_pending = 0 + ) + WHERE g.group_legend > 0 + AND (g.group_type <> ' . GROUP_HIDDEN . ' OR ug.user_id = ' . $this->user->data['user_id'] . ') + ORDER BY g.' . $order_legend . ' ASC'; + } + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $show_group_url = $row['group_name'] != 'BOTS' && $this->auth->acl_get('u_viewprofile'); + + $template->assign_block_vars('LEGEND', [ + 'GROUP_COLOR' => $row['group_colour'] ?: '', + 'GROUP_NAME' => $this->get_name($row['group_name']), + 'GROUP_URL' => $show_group_url ? append_sid("{$this->path_helper->get_phpbb_root_path()}memberlist.{$this->path_helper->get_php_ext()}", 'mode=group&g=' . $row['group_id']) : '', + ]); + } + $db->sql_freeresult($result); + } } diff --git a/phpBB/phpbb/message/topic_form.php b/phpBB/phpbb/message/topic_form.php index 8dc6e6a2e5..e8344417ef 100644 --- a/phpBB/phpbb/message/topic_form.php +++ b/phpBB/phpbb/message/topic_form.php @@ -153,10 +153,17 @@ class topic_form extends form parent::render($template); $this->user->add_lang('viewtopic'); + + $lang_options = phpbb_language_select($this->db, $this->recipient_lang); + $template->assign_vars(array( 'EMAIL' => $this->recipient_address, 'NAME' => $this->recipient_name, - 'S_LANG_OPTIONS' => language_select($this->recipient_lang), + 'LANG_OPTIONS' => [ + 'id' => 'lang', + 'name' => 'lang', + 'options' => $lang_options, + ], 'MESSAGE' => $this->body, 'L_EMAIL_BODY_EXPLAIN' => $this->user->lang['EMAIL_TOPIC_EXPLAIN'], diff --git a/phpBB/phpbb/template/twig/extension/forms.php b/phpBB/phpbb/template/twig/extension/forms.php new file mode 100644 index 0000000000..dc6e28acaa --- /dev/null +++ b/phpBB/phpbb/template/twig/extension/forms.php @@ -0,0 +1,221 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\template\twig\extension; + +use phpbb\template\twig\environment; +use phpbb\user; +use Twig\Extension\AbstractExtension; +use Twig\TwigFunction; + +class forms extends AbstractExtension +{ + /** @var user */ + protected $user; + + /** + * Constructor. + * + * @param user $user User object + */ + public function __construct(user $user) + { + $this->user = $user; + } + + /** + * Returns the name of this extension. + * + * @return string The extension name + */ + public function getName() + { + return 'forms'; + } + + /** + * Returns a list of functions to add to the existing list. + * + * @return TwigFunction[] Array of twig functions + */ + public function getFunctions(): array + { + return [ + new TwigFunction('FormsBuildTemplate', [$this, 'build_template'], ['needs_environment' => true]), + new TwigFunction('FormsDimension', [$this, 'dimension'], ['needs_environment' => true]), + new TwigFunction('FormsInput', [$this, 'input'], ['needs_environment' => true]), + new TwigFunction('FormsRadioButtons', [$this, 'radio_buttons'], ['needs_environment' => true]), + new TwigFunction('FormsSelect', [$this, 'select'], ['needs_environment' => true]), + new TwigFunction('FormsTextarea', [$this, 'textarea'], ['needs_environment' => true]), + ]; + } + + /** + * Renders a form template + * + * @param environment $environment + * @param array $form_data + * + * @return string Rendered form template + */ + public function build_template(environment $environment, array $form_data): string + { + try + { + return $environment->render('macros/forms/build_template.twig', [ + 'form_data' => $form_data ?? [], + ]); + } + catch (\Twig\Error\Error $e) + { + return ''; + } + } + + /** + * Renders form dimension fields + * + * @param environment $environment The twig environment + * @param array $form_data The form data + * + * @return string Form dimension fields + */ + public function dimension(environment $environment, array $form_data): string + { + try + { + return $environment->render('macros/forms/dimension.twig', [ + 'WIDTH' => $form_data['width'], + 'HEIGHT' => $form_data['height'], + ]); + } + catch (\Twig\Error\Error $e) + { + return ''; + } + } + + /** + * Renders a form input field + * + * @param environment $environment The twig environment + * @param array $form_data The form data + * + * @return string Form input field + */ + public function input(environment $environment, array $form_data): string + { + try + { + return $environment->render('macros/forms/input.twig', [ + 'ID' => (string) ($form_data['id'] ?? ''), + 'TYPE' => (string) $form_data['type'], + 'NAME' => (string) $form_data['name'], + 'SIZE' => (int) ($form_data['size'] ?? 0), + 'MAXLENGTH' => (int) ($form_data['maxlength'] ?? 0), + 'MIN' => (int) ($form_data['min'] ?? 0), + 'MAX' => (int) ($form_data['max'] ?? 0), + 'STEP' => (int) ($form_data['step'] ?? 0), + 'CHECKED' => (bool) ($form_data['checked'] ?? false), + 'CLASS' => (string) ($form_data['class'] ?? ''), + 'VALUE' => (string) ($form_data['value']), + 'DATA' => $form_data['data'] ?? [], + ]); + } + catch (\Twig\Error\Error $e) + { + return ''; + } + } + + /** + * Renders form radio buttons + * + * @param environment $environment The twig environment + * @param array $form_data The form data + * + * @return string Form radio buttons + */ + public function radio_buttons(environment $environment, array $form_data): string + { + try + { + return $environment->render('macros/forms/radio_buttons.twig', [ + 'FIRST_BUTTON' => $form_data['buttons'][0], + 'FIRST_BUTTON_LABEL' => $form_data['buttons'][0]['label'], + 'SECOND_BUTTON' => $form_data['buttons'][1], + 'SECOND_BUTTON_LABEL' => $form_data['buttons'][1]['label'], + ]); + } + catch (\Twig\Error\Error $e) + { + return ''; + } + } + + /** + * Renders a form select field + * + * @param environment $environment The twig environment + * @param array $form_data The form data + * + * @return string Form select field + */ + public function select(environment $environment, array $form_data): string + { + try + { + return $environment->render('macros/forms/select.twig', [ + 'ID' => (string) ($form_data['id'] ?? ''), + 'CLASS' => (string) ($form_data['class'] ?? ''), + 'NAME' => (string) $form_data['name'], + 'TOGGLEABLE' => (bool) ($form_data['toggleable'] ?? false), + 'OPTIONS' => $form_data['options'] ?? [], + 'GROUP_ONLY' => (bool) ($form_data['group_only'] ?? false), + 'DATA' => $form_data['data'] ?? [], + 'SIZE' => (int) ($form_data['size'] ?? 0), + 'MULTIPLE' => (bool) ($form_data['multiple'] ?? false), + ]); + } + catch (\Twig\Error\Error $e) + { + return ''; + } + } + + /** + * Renders a form textarea field + * + * @param environment $environment + * @param array $form_data + * + * @return string Form textarea field + */ + public function textarea(environment $environment, array $form_data): string + { + try + { + return $environment->render('macros/forms/textarea.twig', [ + 'ID' => (string) $form_data['id'], + 'NAME' => (string) $form_data['name'], + 'ROWS' => (int) $form_data['rows'], + 'COLS' => (int) $form_data['cols'], + 'CONTENT' => (string) $form_data['content'], + ]); + } + catch (\Twig\Error\Error $e) + { + return ''; + } + } +} diff --git a/phpBB/styles/all/template/macros/forms/build_template.twig b/phpBB/styles/all/template/macros/forms/build_template.twig new file mode 100644 index 0000000000..fb63e3e1ed --- /dev/null +++ b/phpBB/styles/all/template/macros/forms/build_template.twig @@ -0,0 +1,16 @@ +{% if form_data.tag == 'input' %} + {{ FormsInput(form_data) }} +{% elseif form_data.tag == 'dimension' %} + {{ FormsDimension(form_data) }} +{% elseif form_data.tag == 'radio' %} + {{ FormsRadioButtons(form_data) }} +{% elseif form_data.tag == 'select' %} + {{ FormsSelect(form_data) }} +{% elseif form_data.tag == 'textarea' %} + {{ FormsTextarea(form_data) }} +{% elseif form_data[0] %} + {% for element in form_data %} + {{ FormsBuildTemplate(element) }} + {% endfor %} +{% endif %} +{% if form_data.append %}{{ form_data.append }}{% endif %} diff --git a/phpBB/styles/all/template/macros/forms/dimension.twig b/phpBB/styles/all/template/macros/forms/dimension.twig new file mode 100644 index 0000000000..05bf563168 --- /dev/null +++ b/phpBB/styles/all/template/macros/forms/dimension.twig @@ -0,0 +1 @@ +{{ FormsInput(WIDTH) }} x {{ FormsInput(HEIGHT) }} diff --git a/phpBB/styles/all/template/macros/forms/input.twig b/phpBB/styles/all/template/macros/forms/input.twig new file mode 100644 index 0000000000..c902552ce7 --- /dev/null +++ b/phpBB/styles/all/template/macros/forms/input.twig @@ -0,0 +1,18 @@ +{% apply replace({"\n": ' ', "\t": ''}) %} + +{% endapply %} diff --git a/phpBB/styles/all/template/macros/forms/radio_buttons.twig b/phpBB/styles/all/template/macros/forms/radio_buttons.twig new file mode 100644 index 0000000000..1ef7804c29 --- /dev/null +++ b/phpBB/styles/all/template/macros/forms/radio_buttons.twig @@ -0,0 +1,2 @@ + + diff --git a/phpBB/styles/all/template/macros/forms/select.twig b/phpBB/styles/all/template/macros/forms/select.twig new file mode 100644 index 0000000000..70a13b97aa --- /dev/null +++ b/phpBB/styles/all/template/macros/forms/select.twig @@ -0,0 +1,30 @@ +{% apply replace({"\n": ' ', "\t": ''}) %} + diff --git a/phpBB/styles/all/template/macros/forms/textarea.twig b/phpBB/styles/all/template/macros/forms/textarea.twig new file mode 100644 index 0000000000..51a4c98ee6 --- /dev/null +++ b/phpBB/styles/all/template/macros/forms/textarea.twig @@ -0,0 +1,9 @@ +{% apply replace({"\n": ' ', '\t': ''}) %} + +{% endapply %} diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html index 4b41e2b83c..7b69b92a5f 100644 --- a/phpBB/styles/prosilver/template/index_body.html +++ b/phpBB/styles/prosilver/template/index_body.html @@ -41,10 +41,24 @@

{L_WHO_IS_ONLINE}

{L_WHO_IS_ONLINE}

- {TOTAL_USERS_ONLINE} ({L_ONLINE_EXPLAIN})
{RECORD_USERS}
+ {TOTAL_USERS_ONLINE} ({L_ONLINE_EXPLAIN})
{RECORD_USERS}

{LOGGED_IN_USER_LIST} -
{L_LEGEND}{L_COLON} {LEGEND} + {% if LEGEND|length > 0 %} + {% apply spaceless %} +
+ + {{ lang('LEGEND') ~ lang('COLON') }} + {% for group in LEGEND %} + {% if group.GROUP_URL %} + {{ group.GROUP_NAME }}{% if not loop.last %}, {% endif %} + {% else %} + {{ group.GROUP_NAME }}{% if not loop.last %}, {% endif %} + {% endif %} + {% endfor %} + + {% endapply %} + {% endif %}

diff --git a/phpBB/styles/prosilver/template/memberlist_email.html b/phpBB/styles/prosilver/template/memberlist_email.html index 5bbfb08506..abd4c88488 100644 --- a/phpBB/styles/prosilver/template/memberlist_email.html +++ b/phpBB/styles/prosilver/template/memberlist_email.html @@ -71,7 +71,13 @@

{L_DEST_LANG_EXPLAIN}
-
+
+ +
diff --git a/phpBB/styles/prosilver/template/timezone_option.html b/phpBB/styles/prosilver/template/timezone_option.html index 01786d5ef4..0c7be8de74 100644 --- a/phpBB/styles/prosilver/template/timezone_option.html +++ b/phpBB/styles/prosilver/template/timezone_option.html @@ -1,28 +1,16 @@
-
- -
+ {% if TIMEZONE_OPTIONS %} +
+ {% set tz_date_data = TIMEZONE_OPTIONS | merge({ options: [{ value: "", label: lang('SELECT_CURRENT_TIME') }] | merge(TIMEZONE_OPTIONS.options) }) %} + {{ FormsSelect(tz_date_data | merge({class: 'autowidth tz_select', id: 'tz_date', name: 'tz_date', group_only: true})) }}
- + {% endif %}
- + {% set tz_select_data = TIMEZONE_OPTIONS | merge({ options: [{ value: "", label: lang('SELECT_TIMEZONE') }] | merge(TIMEZONE_OPTIONS.options) }) %} + {{ FormsSelect(tz_select_data | merge({class: 'autowidth tz_select', id: 'timezone'})) }} - + {% INCLUDEJS('timezone.js') %}
diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html index 810fe2bec1..94d280a31a 100644 --- a/phpBB/styles/prosilver/template/ucp_agreement.html +++ b/phpBB/styles/prosilver/template/ucp_agreement.html @@ -2,29 +2,29 @@ - - - +{% if LANG_OPTIONS %}

- + + {{ FormsSelect(LANG_OPTIONS) }} {S_HIDDEN_FIELDS}

- + +{% endif %}
diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html index badfa5861d..4e81b78fb3 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html @@ -52,8 +52,10 @@
-
-
+
+
+ {{ FormsSelect(LANG_OPTIONS) }} +
diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html index 7c61ae24d3..0956317497 100644 --- a/phpBB/styles/prosilver/template/ucp_register.html +++ b/phpBB/styles/prosilver/template/ucp_register.html @@ -57,11 +57,22 @@
- {% if S_LANG_OPTIONS %} + {% if LANG_OPTIONS %}
-
-
+
+
+ {{ FormsSelect(LANG_OPTIONS) }} +
+ {% endif %} diff --git a/phpBB/styles/prosilver/template/viewonline_body.html b/phpBB/styles/prosilver/template/viewonline_body.html index c019977179..acbfb71ba5 100644 --- a/phpBB/styles/prosilver/template/viewonline_body.html +++ b/phpBB/styles/prosilver/template/viewonline_body.html @@ -47,7 +47,22 @@ -

{L_LEGEND}{L_COLON} {LEGEND}

+{% if LEGEND|length > 0 %} + {% apply spaceless %} +

+ + {{ lang('LEGEND') ~ lang('COLON') }} + {% for group in LEGEND %} + {% if group.GROUP_URL %} + {{ group.GROUP_NAME }}{% if not loop.last %}, {% endif %} + {% else %} + {{ group.GROUP_NAME }}{% if not loop.last %}, {% endif %} + {% endif %} + {% endfor %} + +

+ {% endapply %} +{% endif %}