Merge branch 'develop' of https://github.com/phpbb/phpbb3 into ticket/11531

This commit is contained in:
Marc Alexander 2013-06-03 22:42:49 +02:00
commit af8c4b2900
182 changed files with 3247 additions and 1226 deletions

View file

@ -15,7 +15,7 @@ before_script:
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi"
- travis/install-php-extensions.sh - travis/install-php-extensions.sh
- cd phpBB - cd phpBB
- php ../composer.phar install --dev - php ../composer.phar install --dev --no-interaction --prefer-source
- cd .. - cd ..
- sh -c "if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.3.19', '>=');"` = "1" ]; then travis/setup-webserver.sh; fi" - sh -c "if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.3.19', '>=');"` = "1" ]; then travis/setup-webserver.sh; fi"

View file

@ -50,7 +50,6 @@ $module_id = request_var('i', '');
$mode = request_var('mode', ''); $mode = request_var('mode', '');
// Set custom style for admin area // Set custom style for admin area
$phpbb_style->set_ext_dir_prefix('adm/');
$phpbb_style->set_custom_style('admin', $phpbb_admin_path . 'style', array(), ''); $phpbb_style->set_custom_style('admin', $phpbb_admin_path . 'style', array(), '');
$template->assign_var('T_ASSETS_PATH', $phpbb_root_path . 'assets'); $template->assign_var('T_ASSETS_PATH', $phpbb_root_path . 'assets');
$template->assign_var('T_TEMPLATE_PATH', $phpbb_admin_path . 'style'); $template->assign_var('T_TEMPLATE_PATH', $phpbb_admin_path . 'style');

View file

@ -196,7 +196,7 @@
</dl> </dl>
<dl> <dl>
<dt><label for="extgroup_filesize">{L_MAX_EXTGROUP_FILESIZE}{L_COLON}</label></dt> <dt><label for="extgroup_filesize">{L_MAX_EXTGROUP_FILESIZE}{L_COLON}</label></dt>
<dd><input type="text" id="extgroup_filesize" size="3" maxlength="15" name="max_filesize" value="{EXTGROUP_FILESIZE}" /> <select name="size_select">{S_EXT_GROUP_SIZE_OPTIONS}</select></dd> <dd><input type="number" id="extgroup_filesize" size="3" maxlength="15" name="max_filesize" value="{EXTGROUP_FILESIZE}" /> <select name="size_select">{S_EXT_GROUP_SIZE_OPTIONS}</select></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="assigned_extensions">{L_ASSIGNED_EXTENSIONS}{L_COLON}</label></dt> <dt><label for="assigned_extensions">{L_ASSIGNED_EXTENSIONS}{L_COLON}</label></dt>
@ -348,7 +348,7 @@
<td><a href="{orphan.U_FILE}">{orphan.REAL_FILENAME}</a></td> <td><a href="{orphan.U_FILE}">{orphan.REAL_FILENAME}</a></td>
<td>{orphan.FILETIME}</td> <td>{orphan.FILETIME}</td>
<td>{orphan.FILESIZE}</td> <td>{orphan.FILESIZE}</td>
<td><strong>{L_ATTACH_ID}{L_COLON} </strong><input type="text" name="post_id[{orphan.ATTACH_ID}]" size="7" maxlength="10" value="{orphan.POST_ID}" /></td> <td><strong>{L_ATTACH_ID}{L_COLON} </strong><input type="number" name="post_id[{orphan.ATTACH_ID}]" size="7" maxlength="10" value="{orphan.POST_ID}" /></td>
<td><input type="checkbox" class="radio" name="add[{orphan.ATTACH_ID}]" /></td> <td><input type="checkbox" class="radio" name="add[{orphan.ATTACH_ID}]" /></td>
<td><input type="checkbox" class="radio" name="delete[{orphan.ATTACH_ID}]" /></td> <td><input type="checkbox" class="radio" name="delete[{orphan.ATTACH_ID}]" /></td>
</tr> </tr>

View file

@ -1,11 +1,11 @@
<dl> <dl>
<dt><label for="avatar_gravatar_email">{L_GRAVATAR_AVATAR_EMAIL}{L_COLON}</label><br /><span>{L_GRAVATAR_AVATAR_EMAIL_EXPLAIN}</span></dt> <dt><label for="avatar_gravatar_email">{L_GRAVATAR_AVATAR_EMAIL}{L_COLON}</label><br /><span>{L_GRAVATAR_AVATAR_EMAIL_EXPLAIN}</span></dt>
<dd><input type="text" name="avatar_gravatar_email" id="avatar_gravatar_email" value="{AVATAR_GRAVATAR_EMAIL}" class="inputbox" /></dd> <dd><input type="email" name="avatar_gravatar_email" id="avatar_gravatar_email" value="{AVATAR_GRAVATAR_EMAIL}" class="inputbox" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="avatar_gravatar_width">{L_GRAVATAR_AVATAR_SIZE}{L_COLON}</label><br /><span>{L_GRAVATAR_AVATAR_SIZE_EXPLAIN}</span></dt> <dt><label for="avatar_gravatar_width">{L_GRAVATAR_AVATAR_SIZE}{L_COLON}</label><br /><span>{L_GRAVATAR_AVATAR_SIZE_EXPLAIN}</span></dt>
<dd> <dd>
<input type="text" name="avatar_gravatar_width" id="avatar_gravatar_width" size="3" value="{AVATAR_GRAVATAR_WIDTH}" class="inputbox autowidth" /> {L_PIXEL} &times;&nbsp; <input type="number" name="avatar_gravatar_width" id="avatar_gravatar_width" size="3" value="{AVATAR_GRAVATAR_WIDTH}" class="inputbox autowidth" /> {L_PIXEL} &times;&nbsp;
<input type="text" name="avatar_gravatar_height" id="avatar_gravatar_height" size="3" value="{AVATAR_GRAVATAR_HEIGHT}" class="inputbox autowidth" /> {L_PIXEL} <input type="number" name="avatar_gravatar_height" id="avatar_gravatar_height" size="3" value="{AVATAR_GRAVATAR_HEIGHT}" class="inputbox autowidth" /> {L_PIXEL}
</dd> </dd>
</dl> </dl>

View file

@ -1,11 +1,11 @@
<dl> <dl>
<dt><label for="avatar_remote_url">{L_LINK_REMOTE_AVATAR}{L_COLON}</label><br /><span>{L_LINK_REMOTE_AVATAR_EXPLAIN}</span></dt> <dt><label for="avatar_remote_url">{L_LINK_REMOTE_AVATAR}{L_COLON}</label><br /><span>{L_LINK_REMOTE_AVATAR_EXPLAIN}</span></dt>
<dd><input type="text" name="avatar_remote_url" id="avatar_remote_url" value="{AVATAR_REMOTE_URL}" class="inputbox" /></dd> <dd><input type="url" name="avatar_remote_url" id="avatar_remote_url" value="{AVATAR_REMOTE_URL}" class="inputbox" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="avatar_remote_width">{L_LINK_REMOTE_SIZE}{L_COLON}</label><br /><span>{L_LINK_REMOTE_SIZE_EXPLAIN}</span></dt> <dt><label for="avatar_remote_width">{L_LINK_REMOTE_SIZE}{L_COLON}</label><br /><span>{L_LINK_REMOTE_SIZE_EXPLAIN}</span></dt>
<dd> <dd>
<input type="text" name="avatar_remote_width" id="avatar_remote_width" size="3" value="{AVATAR_REMOTE_WIDTH}" class="inputbox autowidth" /> {L_PIXEL} &times;&nbsp; <input type="number" name="avatar_remote_width" id="avatar_remote_width" size="3" value="{AVATAR_REMOTE_WIDTH}" class="inputbox autowidth" /> {L_PIXEL} &times;&nbsp;
<input type="text" name="avatar_remote_height" id="avatar_remote_height" size="3" value="{AVATAR_REMOTE_HEIGHT}" class="inputbox autowidth" /> {L_PIXEL} <input type="number" name="avatar_remote_height" id="avatar_remote_height" size="3" value="{AVATAR_REMOTE_HEIGHT}" class="inputbox autowidth" /> {L_PIXEL}
</dd> </dd>
</dl> </dl>

View file

@ -6,6 +6,6 @@
<!-- IF S_UPLOAD_AVATAR_URL --> <!-- IF S_UPLOAD_AVATAR_URL -->
<dl> <dl>
<dt><label for="avatar_upload_url">{L_UPLOAD_AVATAR_URL}{L_COLON}</label><br /><span>{L_UPLOAD_AVATAR_URL_EXPLAIN}</span></dt> <dt><label for="avatar_upload_url">{L_UPLOAD_AVATAR_URL}{L_COLON}</label><br /><span>{L_UPLOAD_AVATAR_URL_EXPLAIN}</span></dt>
<dd><input type="text" name="avatar_upload_url" id="avatar_upload_url" value="" class="inputbox" /></dd> <dd><input type="url" name="avatar_upload_url" id="avatar_upload_url" value="" class="inputbox" /></dd>
</dl> </dl>
<!-- ENDIF --> <!-- ENDIF -->

View file

@ -19,11 +19,11 @@
</dl> </dl>
<dl> <dl>
<dt><label for="max_reg_attempts">{L_REG_LIMIT}{L_COLON}</label><br /><span>{L_REG_LIMIT_EXPLAIN}</span></dt> <dt><label for="max_reg_attempts">{L_REG_LIMIT}{L_COLON}</label><br /><span>{L_REG_LIMIT_EXPLAIN}</span></dt>
<dd><input id="max_reg_attempts" type="text" size="4" maxlength="4" name="max_reg_attempts" value="{REG_LIMIT}" /></dd> <dd><input id="max_reg_attempts" type="number" size="4" maxlength="4" min="0" max="9999" name="max_reg_attempts" value="{REG_LIMIT}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="max_login_attempts">{L_MAX_LOGIN_ATTEMPTS}{L_COLON}</label><br /><span>{L_MAX_LOGIN_ATTEMPTS_EXPLAIN}</span></dt> <dt><label for="max_login_attempts">{L_MAX_LOGIN_ATTEMPTS}{L_COLON}</label><br /><span>{L_MAX_LOGIN_ATTEMPTS_EXPLAIN}</span></dt>
<dd><input id="max_login_attempts" type="text" size="4" maxlength="4" name="max_login_attempts" value="{MAX_LOGIN_ATTEMPTS}" /></dd> <dd><input id="max_login_attempts" type="number" size="4" maxlength="4" min="0" max="9999" name="max_login_attempts" value="{MAX_LOGIN_ATTEMPTS}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="enable_post_confirm">{L_VISUAL_CONFIRM_POST}{L_COLON}</label><br /><span>{L_VISUAL_CONFIRM_POST_EXPLAIN}</span></dt> <dt><label for="enable_post_confirm">{L_VISUAL_CONFIRM_POST}{L_COLON}</label><br /><span>{L_VISUAL_CONFIRM_POST_EXPLAIN}</span></dt>

View file

@ -239,7 +239,7 @@
</dl> </dl>
<dl> <dl>
<dt><label for="topics_per_page">{L_FORUM_TOPICS_PAGE}{L_COLON}</label><br /><span>{L_FORUM_TOPICS_PAGE_EXPLAIN}</span></dt> <dt><label for="topics_per_page">{L_FORUM_TOPICS_PAGE}{L_COLON}</label><br /><span>{L_FORUM_TOPICS_PAGE_EXPLAIN}</span></dt>
<dd><input type="text" id="topics_per_page" name="topics_per_page" value="{TOPICS_PER_PAGE}" size="4" maxlength="4" /></dd> <dd><input type="number" id="topics_per_page" name="topics_per_page" value="{TOPICS_PER_PAGE}" size="4" maxlength="4" min="0" max="9999" /></dd>
</dl> </dl>
<!-- EVENT acp_forums_normal_settings_append --> <!-- EVENT acp_forums_normal_settings_append -->
</fieldset> </fieldset>
@ -253,15 +253,15 @@
</dl> </dl>
<dl> <dl>
<dt><label for="prune_freq">{L_AUTO_PRUNE_FREQ}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_FREQ_EXPLAIN}</span></dt> <dt><label for="prune_freq">{L_AUTO_PRUNE_FREQ}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_FREQ_EXPLAIN}</span></dt>
<dd><input type="text" id="prune_freq" name="prune_freq" value="{PRUNE_FREQ}" maxlength="4" size="4" /> {L_DAYS}</dd> <dd><input type="number" id="prune_freq" name="prune_freq" value="{PRUNE_FREQ}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="prune_days">{L_AUTO_PRUNE_DAYS}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_DAYS_EXPLAIN}</span></dt> <dt><label for="prune_days">{L_AUTO_PRUNE_DAYS}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_DAYS_EXPLAIN}</span></dt>
<dd><input type="text" id="prune_days" name="prune_days" value="{PRUNE_DAYS}" maxlength="4" size="4" /> {L_DAYS}</dd> <dd><input type="number" id="prune_days" name="prune_days" value="{PRUNE_DAYS}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="prune_viewed">{L_AUTO_PRUNE_VIEWED}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_VIEWED_EXPLAIN}</span></dt> <dt><label for="prune_viewed">{L_AUTO_PRUNE_VIEWED}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_VIEWED_EXPLAIN}</span></dt>
<dd><input type="text" id="prune_viewed" name="prune_viewed" value="{PRUNE_VIEWED}" maxlength="4" size="4" /> {L_DAYS}</dd> <dd><input type="number" id="prune_viewed" name="prune_viewed" value="{PRUNE_VIEWED}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="prune_old_polls">{L_PRUNE_OLD_POLLS}{L_COLON}</label><br /><span>{L_PRUNE_OLD_POLLS_EXPLAIN}</span></dt> <dt><label for="prune_old_polls">{L_PRUNE_OLD_POLLS}{L_COLON}</label><br /><span>{L_PRUNE_OLD_POLLS_EXPLAIN}</span></dt>

View file

@ -84,11 +84,11 @@
<legend>{L_GROUP_SETTINGS_SAVE}</legend> <legend>{L_GROUP_SETTINGS_SAVE}</legend>
<dl> <dl>
<dt><label for="group_message_limit">{L_GROUP_MESSAGE_LIMIT}{L_COLON}</label><br /><span>{L_GROUP_MESSAGE_LIMIT_EXPLAIN}</span></dt> <dt><label for="group_message_limit">{L_GROUP_MESSAGE_LIMIT}{L_COLON}</label><br /><span>{L_GROUP_MESSAGE_LIMIT_EXPLAIN}</span></dt>
<dd><input name="group_message_limit" type="text" id="group_message_limit" maxlength="4" size="4" value="{GROUP_MESSAGE_LIMIT}" /></dd> <dd><input name="group_message_limit" type="number" id="group_message_limit" maxlength="4" size="4" min="0" max="9999" value="{GROUP_MESSAGE_LIMIT}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="group_max_recipients">{L_GROUP_MAX_RECIPIENTS}{L_COLON}</label><br /><span>{L_GROUP_MAX_RECIPIENTS_EXPLAIN}</span></dt> <dt><label for="group_max_recipients">{L_GROUP_MAX_RECIPIENTS}{L_COLON}</label><br /><span>{L_GROUP_MAX_RECIPIENTS_EXPLAIN}</span></dt>
<dd><input name="group_max_recipients" type="text" id="group_max_recipients" maxlength="10" size="4" value="{GROUP_MAX_RECIPIENTS}" /></dd> <dd><input name="group_max_recipients" type="number" id="group_max_recipients" maxlength="10" size="4" value="{GROUP_MAX_RECIPIENTS}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="group_colour">{L_GROUP_COLOR}{L_COLON}</label><br /><span>{L_GROUP_COLOR_EXPLAIN}</span></dt> <dt><label for="group_colour">{L_GROUP_COLOR}{L_COLON}</label><br /><span>{L_GROUP_COLOR_EXPLAIN}</span></dt>

View file

@ -108,8 +108,8 @@
<td><input class="text post" type="text" name="code[{items.IMG}]" value="{items.CODE}" size="10" maxlength="50" /></td> <td><input class="text post" type="text" name="code[{items.IMG}]" value="{items.CODE}" size="10" maxlength="50" /></td>
<td><input class="text post" type="text" name="emotion[{items.IMG}]" value="{items.EMOTION}" size="10" maxlength="50" /></td> <td><input class="text post" type="text" name="emotion[{items.IMG}]" value="{items.EMOTION}" size="10" maxlength="50" /></td>
<!-- ENDIF --> <!-- ENDIF -->
<td><input class="text post" type="text" size="3" name="width[{items.IMG}]" value="{items.WIDTH}" /></td> <td><input class="text post" type="number" size="3" name="width[{items.IMG}]" value="{items.WIDTH}" /></td>
<td><input class="text post" type="text" size="3" name="height[{items.IMG}]" value="{items.HEIGHT}" /></td> <td><input class="text post" type="number" size="3" name="height[{items.IMG}]" value="{items.HEIGHT}" /></td>
<td> <td>
<input type="checkbox" class="radio" name="display_on_posting[{items.IMG}]"{items.POSTING_CHECKED} onclick="toggle_select('{items.A_IMG}', this.checked, '{items.S_ROW_COUNT}');"/> <input type="checkbox" class="radio" name="display_on_posting[{items.IMG}]"{items.POSTING_CHECKED} onclick="toggle_select('{items.A_IMG}', this.checked, '{items.S_ROW_COUNT}');"/>
<!-- IF items.S_ID --> <!-- IF items.S_ID -->
@ -136,8 +136,8 @@
<td style="vertical-align: top;"><img src="{IMG_SRC}" id="add_image_src" alt="" title="" /></td> <td style="vertical-align: top;"><img src="{IMG_SRC}" id="add_image_src" alt="" title="" /></td>
<td><input class="text post" type="text" name="add_code" id="add_code" value="{CODE}" size="10" maxlength="50" /></td> <td><input class="text post" type="text" name="add_code" id="add_code" value="{CODE}" size="10" maxlength="50" /></td>
<td><input class="text post" type="text" name="add_emotion" id="add_emotion" value="{EMOTION}" size="10" maxlength="50" /></td> <td><input class="text post" type="text" name="add_emotion" id="add_emotion" value="{EMOTION}" size="10" maxlength="50" /></td>
<td><input class="text post" type="text" size="3" name="add_width" id="add_width" value="{WIDTH}" /></td> <td><input class="text post" type="number" size="3" name="add_width" id="add_width" value="{WIDTH}" /></td>
<td><input class="text post" type="text" size="3" name="add_height" id="add_height" value="{HEIGHT}" /></td> <td><input class="text post" type="number" size="3" name="add_height" id="add_height" value="{HEIGHT}" /></td>
<td><input type="checkbox" class="radio" name="add_display_on_posting" checked="checked" onclick="toggle_select('add', this.checked, 'add_order');"/></td> <td><input type="checkbox" class="radio" name="add_display_on_posting" checked="checked" onclick="toggle_select('add', this.checked, 'add_order');"/></td>
<td><select id="order_add_order" name="add_order"> <td><select id="order_add_order" name="add_order">
<optgroup id="order_disp_add_order" label="{L_DISPLAY_POSTING}">{S_ADD_ORDER_LIST_DISPLAY}</optgroup> <optgroup id="order_disp_add_order" label="{L_DISPLAY_POSTING}">{S_ADD_ORDER_LIST_DISPLAY}</optgroup>

View file

@ -53,7 +53,7 @@
</table> </table>
<fieldset class="display-options"> <fieldset class="display-options">
{L_DISPLAY_LOG}{L_COLON} &nbsp;{S_LIMIT_DAYS}&nbsp;{L_SORT_BY}{L_COLON} {S_SORT_KEY} {S_SORT_DIR}<!-- IF .pagination -->&nbsp;Users per page{L_COLON} <input class="inputbox autowidth" type="text" name="users_per_page" id="users_per_page" size="3" value="{USERS_PER_PAGE}" /><!-- ENDIF --> {L_DISPLAY_LOG}{L_COLON} &nbsp;{S_LIMIT_DAYS}&nbsp;{L_SORT_BY}{L_COLON} {S_SORT_KEY} {S_SORT_DIR}<!-- IF .pagination -->&nbsp;Users per page{L_COLON} <input class="inputbox autowidth" type="number" name="users_per_page" id="users_per_page" size="3" value="{USERS_PER_PAGE}" /><!-- ENDIF -->
<input class="button2" type="submit" value="{L_GO}" name="sort" /> <input class="button2" type="submit" value="{L_GO}" name="sort" />
</fieldset> </fieldset>

View file

@ -31,7 +31,7 @@
</dl> </dl>
<dl> <dl>
<dt><label for="jab_port">{L_JAB_PORT}{L_COLON}</label><br /><span>{L_JAB_PORT_EXPLAIN}</span></dt> <dt><label for="jab_port">{L_JAB_PORT}{L_COLON}</label><br /><span>{L_JAB_PORT_EXPLAIN}</span></dt>
<dd><input type="text" id="jab_port" name="jab_port" value="{JAB_PORT}" maxlength="5" size="5" /></dd> <dd><input type="number" id="jab_port" name="jab_port" value="{JAB_PORT}" maxlength="5" size="5" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="jab_username">{L_JAB_USERNAME}{L_COLON}</label><br /><span>{L_JAB_USERNAME_EXPLAIN}</span></dt> <dt><label for="jab_username">{L_JAB_USERNAME}{L_COLON}</label><br /><span>{L_JAB_USERNAME_EXPLAIN}</span></dt>
@ -50,7 +50,7 @@
<!-- ENDIF --> <!-- ENDIF -->
<dl> <dl>
<dt><label for="jab_package_size">{L_JAB_PACKAGE_SIZE}{L_COLON}</label><br /><span>{L_JAB_PACKAGE_SIZE_EXPLAIN}</span></dt> <dt><label for="jab_package_size">{L_JAB_PACKAGE_SIZE}{L_COLON}</label><br /><span>{L_JAB_PACKAGE_SIZE_EXPLAIN}</span></dt>
<dd><input type="text" id="jab_package_size" name="jab_package_size" value="{JAB_PACKAGE_SIZE}" maxlength="5" size="5" /></dd> <dd><input type="number" id="jab_package_size" name="jab_package_size" value="{JAB_PACKAGE_SIZE}" maxlength="5" size="5" min="0" max="99999" /></dd>
</dl> </dl>
</fieldset> </fieldset>

View file

@ -73,11 +73,11 @@
<legend>{L_FORUM_PRUNE}</legend> <legend>{L_FORUM_PRUNE}</legend>
<dl> <dl>
<dt><label for="prune_days">{L_PRUNE_NOT_POSTED}{L_COLON}</label></dt> <dt><label for="prune_days">{L_PRUNE_NOT_POSTED}{L_COLON}</label></dt>
<dd><input type="text" id="prune_days" name="prune_days" /></dd> <dd><input type="number" id="prune_days" name="prune_days" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="prune_vieweddays">{L_PRUNE_NOT_VIEWED}{L_COLON}</label></dt> <dt><label for="prune_vieweddays">{L_PRUNE_NOT_VIEWED}{L_COLON}</label></dt>
<dd><input type="text" id="prune_vieweddays" name="prune_vieweddays" /></dd> <dd><input type="number" id="prune_vieweddays" name="prune_vieweddays" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="polls">{L_PRUNE_OLD_POLLS}{L_COLON}</label><br /><span>{L_PRUNE_OLD_POLLS_EXPLAIN}</span></dt> <dt><label for="polls">{L_PRUNE_OLD_POLLS}{L_COLON}</label><br /><span>{L_PRUNE_OLD_POLLS_EXPLAIN}</span></dt>

View file

@ -35,11 +35,11 @@
</dl> </dl>
<dl> <dl>
<dt><label for="count">{L_POSTS}{L_COLON}</label></dt> <dt><label for="count">{L_POSTS}{L_COLON}</label></dt>
<dd><select name="count_select">{S_COUNT_OPTIONS}</select> <input type="text" id="count" name="count" /></dd> <dd><select name="count_select">{S_COUNT_OPTIONS}</select> <input type="number" id="count" name="count" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="posts_on_queue">{L_POSTS_ON_QUEUE}{L_COLON}</label></dt> <dt><label for="posts_on_queue">{L_POSTS_ON_QUEUE}{L_COLON}</label></dt>
<dd><select name="queue_select">{S_COUNT_OPTIONS}</select> <input type="text" id="posts_on_queue" name="posts_on_queue" /></select> <dd><select name="queue_select">{S_COUNT_OPTIONS}</select> <input type="number" id="posts_on_queue" name="posts_on_queue" /></select>
</dl> </dl>
<!-- IF S_GROUP_LIST --> <!-- IF S_GROUP_LIST -->
<dl> <dl>

View file

@ -41,7 +41,7 @@
<!-- IF S_SPECIAL_RANK --><div id="posts" style="display: none;"><!-- ELSE --><div id="posts"><!-- ENDIF --> <!-- IF S_SPECIAL_RANK --><div id="posts" style="display: none;"><!-- ELSE --><div id="posts"><!-- ENDIF -->
<dl> <dl>
<dt><label for="min_posts">{L_RANK_MINIMUM}{L_COLON}</label></dt> <dt><label for="min_posts">{L_RANK_MINIMUM}{L_COLON}</label></dt>
<dd><input name="min_posts" type="text" id="min_posts" maxlength="10" value="{MIN_POSTS}" /></dd> <dd><input name="min_posts" type="number" id="min_posts" maxlength="10" value="{MIN_POSTS}" /></dd>
</dl> </dl>
</div> </div>

View file

@ -18,11 +18,11 @@
</dl> </dl>
<dl> <dl>
<dt><label for="search_interval">{L_SEARCH_INTERVAL}{L_COLON}</label><br /><span>{L_SEARCH_INTERVAL_EXPLAIN}</span></dt> <dt><label for="search_interval">{L_SEARCH_INTERVAL}{L_COLON}</label><br /><span>{L_SEARCH_INTERVAL_EXPLAIN}</span></dt>
<dd><input id="search_interval" type="text" size="4" maxlength="4" name="config[search_interval]" value="{SEARCH_INTERVAL}" /> {L_SECONDS}</dd> <dd><input id="search_interval" type="number" size="4" maxlength="4" min="0" max="9999" name="config[search_interval]" value="{SEARCH_INTERVAL}" /> {L_SECONDS}</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="search_anonymous_interval">{L_SEARCH_GUEST_INTERVAL}{L_COLON}</label><br /><span>{L_SEARCH_GUEST_INTERVAL_EXPLAIN}</span></dt> <dt><label for="search_anonymous_interval">{L_SEARCH_GUEST_INTERVAL}{L_COLON}</label><br /><span>{L_SEARCH_GUEST_INTERVAL_EXPLAIN}</span></dt>
<dd><input id="search_anonymous_interval" type="text" size="4" maxlength="4" name="config[search_anonymous_interval]" value="{SEARCH_GUEST_INTERVAL}" /> {L_SECONDS}</dd> <dd><input id="search_anonymous_interval" type="number" size="4" maxlength="4" min="0" max="9999" name="config[search_anonymous_interval]" value="{SEARCH_GUEST_INTERVAL}" /> {L_SECONDS}</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="limit_search_load">{L_LIMIT_SEARCH_LOAD}{L_COLON}</label><br /><span>{L_LIMIT_SEARCH_LOAD_EXPLAIN}</span></dt> <dt><label for="limit_search_load">{L_LIMIT_SEARCH_LOAD}{L_COLON}</label><br /><span>{L_LIMIT_SEARCH_LOAD_EXPLAIN}</span></dt>
@ -30,15 +30,15 @@
</dl> </dl>
<dl> <dl>
<dt><label for="min_search_author_chars">{L_MIN_SEARCH_AUTHOR_CHARS}{L_COLON}</label><br /><span>{L_MIN_SEARCH_AUTHOR_CHARS_EXPLAIN}</span></dt> <dt><label for="min_search_author_chars">{L_MIN_SEARCH_AUTHOR_CHARS}{L_COLON}</label><br /><span>{L_MIN_SEARCH_AUTHOR_CHARS_EXPLAIN}</span></dt>
<dd><input id="min_search_author_chars" type="text" size="4" maxlength="4" name="config[min_search_author_chars]" value="{MIN_SEARCH_AUTHOR_CHARS}" /></dd> <dd><input id="min_search_author_chars" type="number" size="4" maxlength="4" min="0" max="9999" name="config[min_search_author_chars]" value="{MIN_SEARCH_AUTHOR_CHARS}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="max_num_search_keywords">{L_MAX_NUM_SEARCH_KEYWORDS}{L_COLON}</label><br /><span>{L_MAX_NUM_SEARCH_KEYWORDS_EXPLAIN}</span></dt> <dt><label for="max_num_search_keywords">{L_MAX_NUM_SEARCH_KEYWORDS}{L_COLON}</label><br /><span>{L_MAX_NUM_SEARCH_KEYWORDS_EXPLAIN}</span></dt>
<dd><input id="max_num_search_keywords" type="text" size="4" maxlength="4" name="config[max_num_search_keywords]" value="{MAX_NUM_SEARCH_KEYWORDS}" /></dd> <dd><input id="max_num_search_keywords" type="number" size="4" maxlength="4" min="0" max="9999" name="config[max_num_search_keywords]" value="{MAX_NUM_SEARCH_KEYWORDS}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="search_store_results">{L_SEARCH_STORE_RESULTS}{L_COLON}</label><br /><span>{L_SEARCH_STORE_RESULTS_EXPLAIN}</span></dt> <dt><label for="search_store_results">{L_SEARCH_STORE_RESULTS}{L_COLON}</label><br /><span>{L_SEARCH_STORE_RESULTS_EXPLAIN}</span></dt>
<dd><input id="search_store_results" type="text" size="4" maxlength="6" name="config[search_store_results]" value="{SEARCH_STORE_RESULTS}" /> {L_SECONDS}</dd> <dd><input id="search_store_results" type="number" size="4" maxlength="6" min="0" max="999999" name="config[search_store_results]" value="{SEARCH_STORE_RESULTS}" /> {L_SECONDS}</dd>
</dl> </dl>
</fieldset> </fieldset>

View file

@ -43,7 +43,7 @@
</dl> </dl>
<dl> <dl>
<dt><label for="user_email">{L_EMAIL}{L_COLON}</label></dt> <dt><label for="user_email">{L_EMAIL}{L_COLON}</label></dt>
<dd><input class="text medium" type="text" id="user_email" name="user_email" value="{USER_EMAIL}" autocomplete="off" /></dd> <dd><input class="text medium" type="email" id="user_email" name="user_email" value="{USER_EMAIL}" autocomplete="off" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="new_password">{L_NEW_PASSWORD}{L_COLON}</label><br /><span>{L_CHANGE_PASSWORD_EXPLAIN}</span></dt> <dt><label for="new_password">{L_NEW_PASSWORD}{L_COLON}</label><br /><span>{L_CHANGE_PASSWORD_EXPLAIN}</span></dt>

View file

@ -12,7 +12,7 @@
</dl> </dl>
<dl> <dl>
<dt><label for="msn">{L_UCP_MSNM}{L_COLON}</label></dt> <dt><label for="msn">{L_UCP_MSNM}{L_COLON}</label></dt>
<dd><input type="text" id="msn" name="msn" value="{MSN}" /></dd> <dd><input type="email" id="msn" name="msn" value="{MSN}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="yim">{L_UCP_YIM}{L_COLON}</label></dt> <dt><label for="yim">{L_UCP_YIM}{L_COLON}</label></dt>
@ -20,11 +20,11 @@
</dl> </dl>
<dl> <dl>
<dt><label for="jabber">{L_UCP_JABBER}{L_COLON}</label></dt> <dt><label for="jabber">{L_UCP_JABBER}{L_COLON}</label></dt>
<dd><input type="text" id="jabber" name="jabber" value="{JABBER}" /></dd> <dd><input type="email" id="jabber" name="jabber" value="{JABBER}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="website">{L_WEBSITE}{L_COLON}</label></dt> <dt><label for="website">{L_WEBSITE}{L_COLON}</label></dt>
<dd><input type="text" id="website" name="website" value="{WEBSITE}" /></dd> <dd><input type="url" id="website" name="website" value="{WEBSITE}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="location">{L_LOCATION}{L_COLON}</label></dt> <dt><label for="location">{L_LOCATION}{L_COLON}</label></dt>
@ -38,7 +38,7 @@
<dt><label for="interests">{L_INTERESTS}{L_COLON}</label></dt> <dt><label for="interests">{L_INTERESTS}{L_COLON}</label></dt>
<dd><textarea id="interests" name="interests" rows="3" cols="30">{INTERESTS}</textarea></dd> <dd><textarea id="interests" name="interests" rows="3" cols="30">{INTERESTS}</textarea></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="birthday">{L_BIRTHDAY}{L_COLON}</label><br /><span>{L_BIRTHDAY_EXPLAIN}</span></dt> <dt><label for="birthday">{L_BIRTHDAY}{L_COLON}</label><br /><span>{L_BIRTHDAY_EXPLAIN}</span></dt>
<dd>{L_DAY}{L_COLON} <select id="birthday" name="bday_day">{S_BIRTHDAY_DAY_OPTIONS}</select> {L_MONTH}{L_COLON} <select name="bday_month">{S_BIRTHDAY_MONTH_OPTIONS}</select> {L_YEAR}{L_COLON} <select name="bday_year">{S_BIRTHDAY_YEAR_OPTIONS}</select></dd> <dd>{L_DAY}{L_COLON} <select id="birthday" name="bday_day">{S_BIRTHDAY_DAY_OPTIONS}</select> {L_MONTH}{L_COLON} <select name="bday_month">{S_BIRTHDAY_MONTH_OPTIONS}</select> {L_YEAR}{L_COLON} <select name="bday_year">{S_BIRTHDAY_YEAR_OPTIONS}</select></dd>
</dl> </dl>
@ -48,7 +48,7 @@
<fieldset> <fieldset>
<legend>{L_USER_CUSTOM_PROFILE_FIELDS}</legend> <legend>{L_USER_CUSTOM_PROFILE_FIELDS}</legend>
<!-- BEGIN profile_fields --> <!-- BEGIN profile_fields -->
<dl> <dl>
<dt><label<!-- IF profile_fields.FIELD_ID --> for="{profile_fields.FIELD_ID}"<!-- ENDIF -->>{profile_fields.LANG_NAME}{L_COLON}</label><!-- IF profile_fields.LANG_EXPLAIN --><br /><span>{profile_fields.LANG_EXPLAIN}</span><!-- ENDIF --></dt> <dt><label<!-- IF profile_fields.FIELD_ID --> for="{profile_fields.FIELD_ID}"<!-- ENDIF -->>{profile_fields.LANG_NAME}{L_COLON}</label><!-- IF profile_fields.LANG_EXPLAIN --><br /><span>{profile_fields.LANG_EXPLAIN}</span><!-- ENDIF --></dt>
<dd>{profile_fields.FIELD}</dd> <dd>{profile_fields.FIELD}</dd>
<!-- IF profile_fields.ERROR --> <!-- IF profile_fields.ERROR -->

View file

@ -148,6 +148,12 @@ $('[data-ajax]').each(function() {
} }
}); });
/**
* Automatically resize textarea
*/
$(document).ready(function() {
phpbb.resizeTextArea($('textarea:not(.no-auto-resize)'), {minHeight: 75});
});
})(jQuery); // Avoid conflicts with other libraries })(jQuery); // Avoid conflicts with other libraries

View file

@ -20,11 +20,11 @@
</dl> </dl>
<dl> <dl>
<dt><label for="captcha_gd_x_grid">{L_CAPTCHA_GD_X_GRID}{L_COLON}</label><br /><span>{L_CAPTCHA_GD_X_GRID_EXPLAIN}</span></dt> <dt><label for="captcha_gd_x_grid">{L_CAPTCHA_GD_X_GRID}{L_COLON}</label><br /><span>{L_CAPTCHA_GD_X_GRID_EXPLAIN}</span></dt>
<dd><input id="captcha_gd_x_grid" name="captcha_gd_x_grid" value="{CAPTCHA_GD_X_GRID}" type="text" /></dd> <dd><input id="captcha_gd_x_grid" name="captcha_gd_x_grid" value="{CAPTCHA_GD_X_GRID}" type="number" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="captcha_gd_y_grid">{L_CAPTCHA_GD_Y_GRID}{L_COLON}</label><br /><span>{L_CAPTCHA_GD_Y_GRID_EXPLAIN}</span></dt> <dt><label for="captcha_gd_y_grid">{L_CAPTCHA_GD_Y_GRID}{L_COLON}</label><br /><span>{L_CAPTCHA_GD_Y_GRID_EXPLAIN}</span></dt>
<dd><input id="captcha_gd_y_grid" name="captcha_gd_y_grid" value="{CAPTCHA_GD_Y_GRID}" type="text" /></dd> <dd><input id="captcha_gd_y_grid" name="captcha_gd_y_grid" value="{CAPTCHA_GD_Y_GRID}" type="number" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="captcha_gd_wave">{L_CAPTCHA_GD_WAVE}{L_COLON}</label><br /><span>{L_CAPTCHA_GD_WAVE_EXPLAIN}</span></dt> <dt><label for="captcha_gd_wave">{L_CAPTCHA_GD_WAVE}{L_COLON}</label><br /><span>{L_CAPTCHA_GD_WAVE_EXPLAIN}</span></dt>

View file

@ -18,7 +18,7 @@
{DEBUG_OUTPUT} {DEBUG_OUTPUT}
<!-- ENDIF --> <!-- ENDIF -->
<div id="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}"> <div id="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}" data-ajax-error-text-abort="{L_AJAX_ERROR_TEXT_ABORT}" data-ajax-error-text-timeout="{L_AJAX_ERROR_TEXT_TIMEOUT}" data-ajax-error-text-parsererror="{L_AJAX_ERROR_TEXT_PARSERERROR}">
<div id="darken">&nbsp;</div> <div id="darken">&nbsp;</div>
<div class="jalert" id="loadingalert"><h3>{L_LOADING}</h3><p>{L_PLEASE_WAIT}</p></div> <div class="jalert" id="loadingalert"><h3>{L_LOADING}</h3><p>{L_PLEASE_WAIT}</p></div>
</div> </div>

View file

@ -252,9 +252,24 @@ phpbb.ajaxify = function(options) {
return; return;
} }
function errorHandler() { /**
* Handler for AJAX errors
*/
function errorHandler(jqXHR, textStatus, errorThrown) {
if (console && console.log) {
console.log('AJAX error. status: ' + textStatus + ', message: ' + errorThrown);
}
phpbb.clearLoadingTimeout(); phpbb.clearLoadingTimeout();
phpbb.alert(dark.attr('data-ajax-error-title'), dark.attr('data-ajax-error-text')); var errorText = false;
if (typeof errorThrown === 'string' && errorThrown.length > 0) {
errorText = errorThrown;
}
else {
errorText = dark.attr('data-ajax-error-text-' + textStatus);
if (typeof errorText !== 'string' || !errorText.length)
errorText = dark.attr('data-ajax-error-text');
}
phpbb.alert(dark.attr('data-ajax-error-title'), errorText);
} }
/** /**
@ -568,4 +583,100 @@ phpbb.addAjaxCallback('toggle_link', function() {
el.parent().attr('class', toggleClass); el.parent().attr('class', toggleClass);
}); });
/**
* Automatically resize textarea
*
* This function automatically resizes textarea elements when user
* types text.
*
* @param {jQuery} items jQuery object(s) to resize
* @param {object} options Optional parameter that adjusts default
* configuration. See configuration variable
*
* Optional parameters:
* minWindowHeight {number} Minimum browser window height when textareas are resized. Default = 500
* minHeight {number} Minimum height of textarea. Default = 200
* maxHeight {number} Maximum height of textarea. Default = 500
* heightDiff {number} Minimum difference between window and textarea height. Default = 200
* resizeCallback {function} Function to call after resizing textarea
* resetCallback {function} Function to call when resize has been canceled
* Callback function format: function(item) {}
* this points to DOM object
* item is a jQuery object, same as this
*/
phpbb.resizeTextArea = function(items, options) {
// Configuration
var configuration = {
minWindowHeight: 500,
minHeight: 200,
maxHeight: 500,
heightDiff: 200,
resizeCallback: function(item) { },
resetCallback: function(item) { }
};
if (arguments.length > 1)
{
configuration = $.extend(configuration, options);
}
function resetAutoResize(item)
{
var $item = $(item);
if ($item.hasClass('auto-resized'))
{
$(item).css({height: '', resize: ''}).removeClass('auto-resized');
configuration.resetCallback.call(item, $item);
}
}
function autoResize(item)
{
function setHeight(height)
{
$item.css({height: height + 'px', resize: 'none'}).addClass('auto-resized');
configuration.resizeCallback.call(item, $item);
}
var windowHeight = $(window).height();
if (windowHeight < configuration.minWindowHeight)
{
resetAutoResize(item);
return;
}
var maxHeight = Math.min(Math.max(windowHeight - configuration.heightDiff, configuration.minHeight), configuration.maxHeight),
$item = $(item),
height = parseInt($item.height()),
scrollHeight = (item.scrollHeight) ? item.scrollHeight : 0;
if (height > maxHeight)
{
setHeight(maxHeight);
}
else if (scrollHeight > (height + 5))
{
setHeight(Math.min(maxHeight, scrollHeight));
}
}
items.bind('focus change keyup', function() {
$(this).each(function() {
autoResize(this);
});
}).change();
$(window).resize(function() {
items.each(function() {
if ($(this).hasClass('auto-resized'))
{
autoResize(this);
}
});
});
};
})(jQuery); // Avoid conflicts with other libraries })(jQuery); // Avoid conflicts with other libraries

View file

@ -130,7 +130,6 @@ services:
- @service_container - @service_container
- @dbal.conn - @dbal.conn
- @config - @config
- @migrator
- @filesystem - @filesystem
- %tables.ext% - %tables.ext%
- %core.root_path% - %core.root_path%
@ -218,6 +217,7 @@ services:
- @service_container - @service_container
- @user_loader - @user_loader
- @dbal.conn - @dbal.conn
- @cache
- @user - @user
- %core.root_path% - %core.root_path%
- %core.php_ext% - %core.php_ext%

View file

@ -1317,16 +1317,20 @@ function get_schema_struct()
$schema_data['phpbb_notification_types'] = array( $schema_data['phpbb_notification_types'] = array(
'COLUMNS' => array( 'COLUMNS' => array(
'notification_type' => array('VCHAR:255', ''), 'notification_type_id' => array('USINT', NULL, 'auto_increment'),
'notification_type_name' => array('VCHAR:255', ''),
'notification_type_enabled' => array('BOOL', 1), 'notification_type_enabled' => array('BOOL', 1),
), ),
'PRIMARY_KEY' => array('notification_type', 'notification_type_enabled'), 'PRIMARY_KEY' => array('notification_type_id'),
'KEYS' => array(
'type' => array('UNIQUE', array('notification_type_name')),
),
); );
$schema_data['phpbb_notifications'] = array( $schema_data['phpbb_notifications'] = array(
'COLUMNS' => array( 'COLUMNS' => array(
'notification_id' => array('UINT', NULL, 'auto_increment'), 'notification_id' => array('UINT:10', NULL, 'auto_increment'),
'item_type' => array('VCHAR:255', ''), 'notification_type_id' => array('USINT', 0),
'item_id' => array('UINT', 0), 'item_id' => array('UINT', 0),
'item_parent_id' => array('UINT', 0), 'item_parent_id' => array('UINT', 0),
'user_id' => array('UINT', 0), 'user_id' => array('UINT', 0),
@ -1336,7 +1340,7 @@ function get_schema_struct()
), ),
'PRIMARY_KEY' => 'notification_id', 'PRIMARY_KEY' => 'notification_id',
'KEYS' => array( 'KEYS' => array(
'item_ident' => array('INDEX', array('item_type', 'item_id')), 'item_ident' => array('INDEX', array('notification_type_id', 'item_id')),
'user' => array('INDEX', array('user_id', 'notification_read')), 'user' => array('INDEX', array('user_id', 'notification_read')),
), ),
); );
@ -1814,7 +1818,7 @@ function get_schema_struct()
); );
$schema_data['phpbb_user_notifications'] = array( $schema_data['phpbb_user_notifications'] = array(
'COLUMNS' => array( 'COLUMNS' => array(
'item_type' => array('VCHAR:255', ''), 'item_type' => array('VCHAR:255', ''),
'item_id' => array('UINT', 0), 'item_id' => array('UINT', 0),
'user_id' => array('UINT', 0), 'user_id' => array('UINT', 0),

View file

@ -24,10 +24,9 @@ phpBB Lead Developer: naderman (Nils Adermann)
phpBB Developers: bantu (Andreas Fischer) phpBB Developers: bantu (Andreas Fischer)
EXreaction (Nathan Guse) EXreaction (Nathan Guse)
igorw (Igor Wiedler) dhruv.goel92 (Dhruv Goel)
imkingdavid (David King) imkingdavid (David King)
nickvergessen (Joas Schilling) nickvergessen (Joas Schilling)
Oleg (Oleg Pudeyev)
Contributions by: leviatan21 (Gabriel Vazquez) Contributions by: leviatan21 (Gabriel Vazquez)
Raimon (Raimon Meuldijk) Raimon (Raimon Meuldijk)
@ -53,6 +52,8 @@ phpBB Developers: A_Jelly_Doughnut (Josh Woody) [01/2010 - 11/2010]
dhn (Dominik Dröscher) [05/2007 - 01/2011] dhn (Dominik Dröscher) [05/2007 - 01/2011]
GrahamJE (Graham Eames) [09/2005 - 11/2006] GrahamJE (Graham Eames) [09/2005 - 11/2006]
kellanved (Henry Sudhof) [04/2007 - 03/2011] kellanved (Henry Sudhof) [04/2007 - 03/2011]
igorw (Igor Wiedler) [08/2010 - 02/2013]
Oleg (Oleg Pudeyev) [01/2011 - 05/2013]
rxu (Ruslan Uzdenov) [04/2010 - 12/2012] rxu (Ruslan Uzdenov) [04/2010 - 12/2012]
TerraFrost (Jim Wigginton) [04/2009 - 01/2011] TerraFrost (Jim Wigginton) [04/2009 - 01/2011]
ToonArmy (Chris Smith) [06/2008 - 11/2011] ToonArmy (Chris Smith) [06/2008 - 11/2011]

View file

@ -117,8 +117,8 @@ class acp_attachments
'attachment_quota' => array('lang' => 'ATTACH_QUOTA', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true), 'attachment_quota' => array('lang' => 'ATTACH_QUOTA', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true),
'max_filesize' => array('lang' => 'ATTACH_MAX_FILESIZE', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true), 'max_filesize' => array('lang' => 'ATTACH_MAX_FILESIZE', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true),
'max_filesize_pm' => array('lang' => 'ATTACH_MAX_PM_FILESIZE','validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true), 'max_filesize_pm' => array('lang' => 'ATTACH_MAX_PM_FILESIZE','validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true),
'max_attachments' => array('lang' => 'MAX_ATTACHMENTS', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => false), 'max_attachments' => array('lang' => 'MAX_ATTACHMENTS', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => false),
'max_attachments_pm' => array('lang' => 'MAX_ATTACHMENTS_PM', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => false), 'max_attachments_pm' => array('lang' => 'MAX_ATTACHMENTS_PM', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => false),
'secure_downloads' => array('lang' => 'SECURE_DOWNLOADS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'secure_downloads' => array('lang' => 'SECURE_DOWNLOADS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'secure_allow_deny' => array('lang' => 'SECURE_ALLOW_DENY', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_allow_deny', 'explain' => true), 'secure_allow_deny' => array('lang' => 'SECURE_ALLOW_DENY', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_allow_deny', 'explain' => true),
'secure_allow_empty_referer' => array('lang' => 'SECURE_EMPTY_REFERRER', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'secure_allow_empty_referer' => array('lang' => 'SECURE_EMPTY_REFERRER', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
@ -128,11 +128,11 @@ class acp_attachments
'legend2' => $l_legend_cat_images, 'legend2' => $l_legend_cat_images,
'img_display_inlined' => array('lang' => 'DISPLAY_INLINED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'img_display_inlined' => array('lang' => 'DISPLAY_INLINED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'img_create_thumbnail' => array('lang' => 'CREATE_THUMBNAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'img_create_thumbnail' => array('lang' => 'CREATE_THUMBNAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'img_max_thumb_width' => array('lang' => 'MAX_THUMB_WIDTH', 'validate' => 'int', 'type' => 'text:7:15', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'img_max_thumb_width' => array('lang' => 'MAX_THUMB_WIDTH', 'validate' => 'int:0:999999999999999', 'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'img_min_thumb_filesize' => array('lang' => 'MIN_THUMB_FILESIZE', 'validate' => 'int', 'type' => 'text:7:15', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), 'img_min_thumb_filesize' => array('lang' => 'MIN_THUMB_FILESIZE', 'validate' => 'int:0:999999999999999', 'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'string', 'type' => 'text:20:200', 'explain' => true, 'append' => '&nbsp;&nbsp;<span>[ <a href="' . $this->u_action . '&amp;action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'), 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'string', 'type' => 'text:20:200', 'explain' => true, 'append' => '&nbsp;&nbsp;<span>[ <a href="' . $this->u_action . '&amp;action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'),
'img_max' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'img_max' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'img_link' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'img_link' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
) )
); );
@ -1203,8 +1203,8 @@ class acp_attachments
// Just get the files // Just get the files
$sql = 'SELECT a.*, u.username, u.user_colour, t.topic_title $sql = 'SELECT a.*, u.username, u.user_colour, t.topic_title
FROM ' . ATTACHMENTS_TABLE . ' a FROM ' . ATTACHMENTS_TABLE . ' a
LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = a.poster_id) LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = a.poster_id)
LEFT JOIN ' . TOPICS_TABLE . " t ON (a.topic_id = t.topic_id) LEFT JOIN ' . TOPICS_TABLE . " t ON (a.topic_id = t.topic_id)
WHERE a.is_orphan = 0 WHERE a.is_orphan = 0
$limit_filetime $limit_filetime
@ -1670,7 +1670,8 @@ class acp_attachments
$size_var = $filesize['si_identifier']; $size_var = $filesize['si_identifier'];
$value = $filesize['value']; $value = $filesize['value'];
return '<input type="text" id="' . $key . '" size="8" maxlength="15" name="config[' . $key . ']" value="' . $value . '" /> <select name="' . $key . '">' . size_select_options($size_var) . '</select>'; // size="8" and maxlength="15" attributes as a fallback for browsers that do not support type="number" yet.
return '<input type="number" id="' . $key . '" size="8" maxlength="15" min="0" name="config[' . $key . ']" value="' . $value . '" /> <select name="' . $key . '">' . size_select_options($size_var) . '</select>';
} }
/** /**

View file

@ -53,7 +53,7 @@ class acp_board
'legend1' => 'ACP_BOARD_SETTINGS', 'legend1' => 'ACP_BOARD_SETTINGS',
'sitename' => array('lang' => 'SITE_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false), 'sitename' => array('lang' => 'SITE_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false),
'site_desc' => array('lang' => 'SITE_DESC', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false), 'site_desc' => array('lang' => 'SITE_DESC', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false),
'site_home_url' => array('lang' => 'SITE_HOME_URL', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'site_home_url' => array('lang' => 'SITE_HOME_URL', 'validate' => 'string', 'type' => 'url:40:255', 'explain' => true),
'site_home_text' => array('lang' => 'SITE_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'site_home_text' => array('lang' => 'SITE_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true),
'board_index_text' => array('lang' => 'BOARD_INDEX_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), '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' => array('lang' => 'DISABLE_BOARD', 'validate' => 'bool', 'type' => 'custom', 'method' => 'board_disable', 'explain' => true),
@ -65,7 +65,7 @@ class acp_board
'override_user_style' => array('lang' => 'OVERRIDE_STYLE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'override_user_style' => array('lang' => 'OVERRIDE_STYLE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend2' => 'WARNINGS', 'legend2' => 'WARNINGS',
'warnings_expire_days' => array('lang' => 'WARNINGS_EXPIRE', 'validate' => 'int', 'type' => 'text:3:4', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'warnings_expire_days' => array('lang' => 'WARNINGS_EXPIRE', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
'legend3' => 'ACP_SUBMIT_CHANGES', 'legend3' => 'ACP_SUBMIT_CHANGES',
) )
@ -136,8 +136,8 @@ class acp_board
'avatar_max_height' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false), 'avatar_max_height' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false),
'allow_avatar' => array('lang' => 'ALLOW_AVATARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_avatar' => array('lang' => 'ALLOW_AVATARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'avatar_min' => array('lang' => 'MIN_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'avatar_min' => array('lang' => 'MIN_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:0', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'avatar_max' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'avatar_max' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:0', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
) )
); );
@ -154,11 +154,11 @@ class acp_board
'vars' => array( 'vars' => array(
'legend1' => 'GENERAL_SETTINGS', 'legend1' => 'GENERAL_SETTINGS',
'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'pm_max_boxes' => array('lang' => 'BOXES_MAX', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'pm_max_boxes' => array('lang' => 'BOXES_MAX', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'pm_max_msgs' => array('lang' => 'BOXES_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'pm_max_msgs' => array('lang' => 'BOXES_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'full_folder_action' => array('lang' => 'FULL_FOLDER_ACTION', 'validate' => 'int', 'type' => 'select', 'method' => 'full_folder_select', 'explain' => true), 'full_folder_action' => array('lang' => 'FULL_FOLDER_ACTION', 'validate' => 'int', 'type' => 'select', 'method' => 'full_folder_select', 'explain' => true),
'pm_edit_time' => array('lang' => 'PM_EDIT_TIME', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'pm_edit_time' => array('lang' => 'PM_EDIT_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'pm_max_recipients' => array('lang' => 'PM_MAX_RECIPIENTS', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true), 'pm_max_recipients' => array('lang' => 'PM_MAX_RECIPIENTS', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true),
'legend2' => 'GENERAL_OPTIONS', 'legend2' => 'GENERAL_OPTIONS',
'allow_mass_pm' => array('lang' => 'ALLOW_MASS_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_mass_pm' => array('lang' => 'ALLOW_MASS_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
@ -195,24 +195,24 @@ class acp_board
'legend2' => 'POSTING', 'legend2' => 'POSTING',
'bump_type' => false, 'bump_type' => false,
'edit_time' => array('lang' => 'EDIT_TIME', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'edit_time' => array('lang' => 'EDIT_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'delete_time' => array('lang' => 'DELETE_TIME', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'delete_time' => array('lang' => 'DELETE_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'display_last_edited' => array('lang' => 'DISPLAY_LAST_EDITED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'display_last_edited' => array('lang' => 'DISPLAY_LAST_EDITED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'flood_interval' => array('lang' => 'FLOOD_INTERVAL', 'validate' => 'int:0', 'type' => 'text:3:10', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'flood_interval' => array('lang' => 'FLOOD_INTERVAL', 'validate' => 'int:0:9999999999', 'type' => 'number:0:9999999999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
'bump_interval' => array('lang' => 'BUMP_INTERVAL', 'validate' => 'int:0', 'type' => 'custom', 'method' => 'bump_interval', 'explain' => true), 'bump_interval' => array('lang' => 'BUMP_INTERVAL', 'validate' => 'int:0', 'type' => 'custom', 'method' => 'bump_interval', 'explain' => true),
'topics_per_page' => array('lang' => 'TOPICS_PER_PAGE', 'validate' => 'int:1', 'type' => 'text:3:4', 'explain' => false), 'topics_per_page' => array('lang' => 'TOPICS_PER_PAGE', 'validate' => 'int:1:9999', 'type' => 'number:1:9999', 'explain' => false),
'posts_per_page' => array('lang' => 'POSTS_PER_PAGE', 'validate' => 'int:1', 'type' => 'text:3:4', 'explain' => false), 'posts_per_page' => array('lang' => 'POSTS_PER_PAGE', 'validate' => 'int:1:9999', 'type' => 'number:1:9999', 'explain' => false),
'smilies_per_page' => array('lang' => 'SMILIES_PER_PAGE', 'validate' => 'int:1', 'type' => 'text:3:4', 'explain' => false), 'smilies_per_page' => array('lang' => 'SMILIES_PER_PAGE', 'validate' => 'int:1:9999', 'type' => 'number:1:9999', 'explain' => false),
'hot_threshold' => array('lang' => 'HOT_THRESHOLD', 'validate' => 'int:0', 'type' => 'text:3:4', 'explain' => true), 'hot_threshold' => array('lang' => 'HOT_THRESHOLD', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_poll_options' => array('lang' => 'MAX_POLL_OPTIONS', 'validate' => 'int:2:127', 'type' => 'text:4:4', 'explain' => false), 'max_poll_options' => array('lang' => 'MAX_POLL_OPTIONS', 'validate' => 'int:2:127', 'type' => 'number:2:127', 'explain' => false),
'max_post_chars' => array('lang' => 'CHAR_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:6', 'explain' => true), 'max_post_chars' => array('lang' => 'CHAR_LIMIT', 'validate' => 'int:0:999999', 'type' => 'number:0:999999', 'explain' => true),
'min_post_chars' => array('lang' => 'MIN_CHAR_LIMIT', 'validate' => 'int:1', 'type' => 'text:4:6', 'explain' => true), 'min_post_chars' => array('lang' => 'MIN_CHAR_LIMIT', 'validate' => 'int:1:999999', 'type' => 'number:1:999999', 'explain' => true),
'max_post_smilies' => array('lang' => 'SMILIES_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'max_post_smilies' => array('lang' => 'SMILIES_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_post_urls' => array('lang' => 'MAX_POST_URLS', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true), 'max_post_urls' => array('lang' => 'MAX_POST_URLS', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_post_font_size' => array('lang' => 'MAX_POST_FONT_SIZE', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' %'), 'max_post_font_size' => array('lang' => 'MAX_POST_FONT_SIZE', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' %'),
'max_quote_depth' => array('lang' => 'QUOTE_DEPTH_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'max_quote_depth' => array('lang' => 'QUOTE_DEPTH_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_post_img_width' => array('lang' => 'MAX_POST_IMG_WIDTH', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'max_post_img_width' => array('lang' => 'MAX_POST_IMG_WIDTH', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'max_post_img_height' => array('lang' => 'MAX_POST_IMG_HEIGHT', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'max_post_img_height' => array('lang' => 'MAX_POST_IMG_HEIGHT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'legend3' => 'ACP_SUBMIT_CHANGES', 'legend3' => 'ACP_SUBMIT_CHANGES',
) )
@ -232,12 +232,12 @@ class acp_board
'allow_sig_links' => array('lang' => 'ALLOW_SIG_LINKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_sig_links' => array('lang' => 'ALLOW_SIG_LINKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend2' => 'GENERAL_SETTINGS', 'legend2' => 'GENERAL_SETTINGS',
'max_sig_chars' => array('lang' => 'MAX_SIG_LENGTH', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true), 'max_sig_chars' => array('lang' => 'MAX_SIG_LENGTH', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_sig_urls' => array('lang' => 'MAX_SIG_URLS', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true), 'max_sig_urls' => array('lang' => 'MAX_SIG_URLS', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_sig_font_size' => array('lang' => 'MAX_SIG_FONT_SIZE', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' %'), 'max_sig_font_size' => array('lang' => 'MAX_SIG_FONT_SIZE', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' %'),
'max_sig_smilies' => array('lang' => 'MAX_SIG_SMILIES', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true), 'max_sig_smilies' => array('lang' => 'MAX_SIG_SMILIES', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_sig_img_width' => array('lang' => 'MAX_SIG_IMG_WIDTH', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'max_sig_img_width' => array('lang' => 'MAX_SIG_IMG_WIDTH', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'max_sig_img_height' => array('lang' => 'MAX_SIG_IMG_HEIGHT', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'max_sig_img_height' => array('lang' => 'MAX_SIG_IMG_HEIGHT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'legend3' => 'ACP_SUBMIT_CHANGES', 'legend3' => 'ACP_SUBMIT_CHANGES',
) )
@ -253,20 +253,20 @@ class acp_board
'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,), 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,),
'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'select', 'method' => 'select_acc_activation', 'explain' => true), 'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'select', 'method' => 'select_acc_activation', 'explain' => true),
'new_member_post_limit' => array('lang' => 'NEW_MEMBER_POST_LIMIT', 'validate' => 'int:0:255', 'type' => 'text:4:4', 'explain' => true, 'append' => ' ' . $user->lang['POSTS']), 'new_member_post_limit' => array('lang' => 'NEW_MEMBER_POST_LIMIT', 'validate' => 'int:0:255', 'type' => 'number:0:255', 'explain' => true, 'append' => ' ' . $user->lang['POSTS']),
'new_member_group_default'=> array('lang' => 'NEW_MEMBER_GROUP_DEFAULT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'new_member_group_default'=> array('lang' => 'NEW_MEMBER_GROUP_DEFAULT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'min_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:1', 'type' => 'custom:5:180', 'method' => 'username_length', 'explain' => true), 'min_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:1', 'type' => 'custom:5:180', 'method' => 'username_length', 'explain' => true),
'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true), 'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true),
'allow_name_chars' => array('lang' => 'USERNAME_CHARS', 'validate' => 'string', 'type' => 'select', 'method' => 'select_username_chars', 'explain' => true), 'allow_name_chars' => array('lang' => 'USERNAME_CHARS', 'validate' => 'string', 'type' => 'select', 'method' => 'select_username_chars', 'explain' => true),
'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true), 'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true),
'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
'legend2' => 'GENERAL_OPTIONS', 'legend2' => 'GENERAL_OPTIONS',
'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'allow_emailreuse' => array('lang' => 'ALLOW_EMAIL_REUSE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_emailreuse' => array('lang' => 'ALLOW_EMAIL_REUSE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'enable_confirm' => array('lang' => 'VISUAL_CONFIRM_REG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'enable_confirm' => array('lang' => 'VISUAL_CONFIRM_REG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true), 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true),
'max_reg_attempts' => array('lang' => 'REG_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'max_reg_attempts' => array('lang' => 'REG_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'legend3' => 'COPPA', 'legend3' => 'COPPA',
'coppa_enable' => array('lang' => 'ENABLE_COPPA', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'coppa_enable' => array('lang' => 'ENABLE_COPPA', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
@ -288,13 +288,13 @@ class acp_board
'feed_http_auth' => array('lang' => 'ACP_FEED_HTTP_AUTH', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'feed_http_auth' => array('lang' => 'ACP_FEED_HTTP_AUTH', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true),
'legend2' => 'ACP_FEED_POST_BASED', 'legend2' => 'ACP_FEED_POST_BASED',
'feed_limit_post' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5', 'type' => 'text:3:4', 'explain' => true), 'feed_limit_post' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5:9999', 'type' => 'number:5:9999', 'explain' => true),
'feed_overall' => array('lang' => 'ACP_FEED_OVERALL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_overall' => array('lang' => 'ACP_FEED_OVERALL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ),
'feed_forum' => array('lang' => 'ACP_FEED_FORUM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_forum' => array('lang' => 'ACP_FEED_FORUM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ),
'feed_topic' => array('lang' => 'ACP_FEED_TOPIC', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_topic' => array('lang' => 'ACP_FEED_TOPIC', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ),
'legend3' => 'ACP_FEED_TOPIC_BASED', 'legend3' => 'ACP_FEED_TOPIC_BASED',
'feed_limit_topic' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5', 'type' => 'text:3:4', 'explain' => true), 'feed_limit_topic' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5:9999', 'type' => 'number:5:9999', 'explain' => true),
'feed_topics_new' => array('lang' => 'ACP_FEED_TOPICS_NEW', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_topics_new' => array('lang' => 'ACP_FEED_TOPICS_NEW', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ),
'feed_topics_active' => array('lang' => 'ACP_FEED_TOPICS_ACTIVE', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_topics_active' => array('lang' => 'ACP_FEED_TOPICS_ACTIVE', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ),
'feed_news_id' => array('lang' => 'ACP_FEED_NEWS', 'validate' => 'string', 'type' => 'custom', 'method' => 'select_news_forums', 'explain' => true), 'feed_news_id' => array('lang' => 'ACP_FEED_NEWS', 'validate' => 'string', 'type' => 'custom', 'method' => 'select_news_forums', 'explain' => true),
@ -324,10 +324,10 @@ class acp_board
'title' => 'ACP_LOAD_SETTINGS', 'title' => 'ACP_LOAD_SETTINGS',
'vars' => array( 'vars' => array(
'legend1' => 'GENERAL_SETTINGS', 'legend1' => 'GENERAL_SETTINGS',
'limit_load' => array('lang' => 'LIMIT_LOAD', 'validate' => 'string', 'type' => 'text:4:4', 'explain' => true), 'limit_load' => array('lang' => 'LIMIT_LOAD', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'session_length' => array('lang' => 'SESSION_LENGTH', 'validate' => 'int:60', 'type' => 'text:5:10', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'session_length' => array('lang' => 'SESSION_LENGTH', 'validate' => 'int:60:9999999999', 'type' => 'number:60:9999999999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
'active_sessions' => array('lang' => 'LIMIT_SESSIONS', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'active_sessions' => array('lang' => 'LIMIT_SESSIONS', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'load_online_time' => array('lang' => 'ONLINE_LENGTH', 'validate' => 'int:0', 'type' => 'text:4:3', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'load_online_time' => array('lang' => 'ONLINE_LENGTH', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'legend2' => 'GENERAL_OPTIONS', 'legend2' => 'GENERAL_OPTIONS',
'load_notifications' => array('lang' => 'LOAD_NOTIFICATIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_notifications' => array('lang' => 'LOAD_NOTIFICATIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
@ -384,7 +384,7 @@ class acp_board
'force_server_vars' => array('lang' => 'FORCE_SERVER_VARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'force_server_vars' => array('lang' => 'FORCE_SERVER_VARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'server_protocol' => array('lang' => 'SERVER_PROTOCOL', 'validate' => 'string', 'type' => 'text:10:10', 'explain' => true), 'server_protocol' => array('lang' => 'SERVER_PROTOCOL', 'validate' => 'string', 'type' => 'text:10:10', 'explain' => true),
'server_name' => array('lang' => 'SERVER_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'server_name' => array('lang' => 'SERVER_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true),
'server_port' => array('lang' => 'SERVER_PORT', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true), 'server_port' => array('lang' => 'SERVER_PORT', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true),
'script_path' => array('lang' => 'SCRIPT_PATH', 'validate' => 'script_path', 'type' => 'text::255', 'explain' => true), 'script_path' => array('lang' => 'SCRIPT_PATH', 'validate' => 'script_path', 'type' => 'text::255', 'explain' => true),
'legend4' => 'ACP_SUBMIT_CHANGES', 'legend4' => 'ACP_SUBMIT_CHANGES',
@ -399,7 +399,7 @@ class acp_board
'legend1' => 'ACP_SECURITY_SETTINGS', 'legend1' => 'ACP_SECURITY_SETTINGS',
'allow_autologin' => array('lang' => 'ALLOW_AUTOLOGIN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_autologin' => array('lang' => 'ALLOW_AUTOLOGIN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'allow_password_reset' => array('lang' => 'ALLOW_PASSWORD_RESET', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_password_reset' => array('lang' => 'ALLOW_PASSWORD_RESET', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'max_autologin_time' => array('lang' => 'AUTOLOGIN_LENGTH', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'max_autologin_time' => array('lang' => 'AUTOLOGIN_LENGTH', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
'ip_check' => array('lang' => 'IP_VALID', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_ip_check', 'explain' => true), 'ip_check' => array('lang' => 'IP_VALID', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_ip_check', 'explain' => true),
'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'forwarded_for_check' => array('lang' => 'FORWARDED_FOR_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'forwarded_for_check' => array('lang' => 'FORWARDED_FOR_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
@ -409,13 +409,13 @@ class acp_board
'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,), 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,),
'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true), 'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true),
'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true), 'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true),
'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true), 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true),
'ip_login_limit_max' => array('lang' => 'IP_LOGIN_LIMIT_MAX', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true), 'ip_login_limit_max' => array('lang' => 'IP_LOGIN_LIMIT_MAX', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true),
'ip_login_limit_time' => array('lang' => 'IP_LOGIN_LIMIT_TIME', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'ip_login_limit_time' => array('lang' => 'IP_LOGIN_LIMIT_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
'ip_login_limit_use_forwarded' => array('lang' => 'IP_LOGIN_LIMIT_USE_FORWARDED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'ip_login_limit_use_forwarded' => array('lang' => 'IP_LOGIN_LIMIT_USE_FORWARDED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'tpl_allow_php' => array('lang' => 'TPL_ALLOW_PHP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'tpl_allow_php' => array('lang' => 'TPL_ALLOW_PHP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'form_token_lifetime' => array('lang' => 'FORM_TIME_MAX', 'validate' => 'int:-1', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'form_token_lifetime' => array('lang' => 'FORM_TIME_MAX', 'validate' => 'int:-1:99999', 'type' => 'number:-1:99999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
'form_token_sid_guests' => array('lang' => 'FORM_SID_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'form_token_sid_guests' => array('lang' => 'FORM_SID_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
) )
@ -430,16 +430,16 @@ class acp_board
'email_enable' => array('lang' => 'ENABLE_EMAIL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'email_enable' => array('lang' => 'ENABLE_EMAIL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true),
'board_email_form' => array('lang' => 'BOARD_EMAIL_FORM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'board_email_form' => array('lang' => 'BOARD_EMAIL_FORM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true),
'email_function_name' => array('lang' => 'EMAIL_FUNCTION_NAME', 'validate' => 'string', 'type' => 'text:20:50', 'explain' => true), 'email_function_name' => array('lang' => 'EMAIL_FUNCTION_NAME', 'validate' => 'string', 'type' => 'text:20:50', 'explain' => true),
'email_package_size' => array('lang' => 'EMAIL_PACKAGE_SIZE', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true), 'email_package_size' => array('lang' => 'EMAIL_PACKAGE_SIZE', 'validate' => 'int:0', 'type' => 'number:0:99999', 'explain' => true),
'board_contact' => array('lang' => 'CONTACT_EMAIL', 'validate' => 'email', 'type' => 'text:25:100', 'explain' => true), 'board_contact' => array('lang' => 'CONTACT_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true),
'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'email', 'type' => 'text:25:100', 'explain' => true), 'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true),
'board_email_sig' => array('lang' => 'EMAIL_SIG', 'validate' => 'string', 'type' => 'textarea:5:30', 'explain' => true), 'board_email_sig' => array('lang' => 'EMAIL_SIG', 'validate' => 'string', 'type' => 'textarea:5:30', 'explain' => true),
'board_hide_emails' => array('lang' => 'BOARD_HIDE_EMAILS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'board_hide_emails' => array('lang' => 'BOARD_HIDE_EMAILS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend2' => 'SMTP_SETTINGS', 'legend2' => 'SMTP_SETTINGS',
'smtp_delivery' => array('lang' => 'USE_SMTP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'smtp_delivery' => array('lang' => 'USE_SMTP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'smtp_host' => array('lang' => 'SMTP_SERVER', 'validate' => 'string', 'type' => 'text:25:50', 'explain' => false), 'smtp_host' => array('lang' => 'SMTP_SERVER', 'validate' => 'string', 'type' => 'text:25:50', 'explain' => false),
'smtp_port' => array('lang' => 'SMTP_PORT', 'validate' => 'int:0', 'type' => 'text:4:5', 'explain' => true), 'smtp_port' => array('lang' => 'SMTP_PORT', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true),
'smtp_auth_method' => array('lang' => 'SMTP_AUTH_METHOD', 'validate' => 'string', 'type' => 'select', 'method' => 'mail_auth_select', 'explain' => true), 'smtp_auth_method' => array('lang' => 'SMTP_AUTH_METHOD', 'validate' => 'string', 'type' => 'select', 'method' => 'mail_auth_select', 'explain' => true),
'smtp_username' => array('lang' => 'SMTP_USERNAME', 'validate' => 'string', 'type' => 'text:25:255', 'explain' => true), 'smtp_username' => array('lang' => 'SMTP_USERNAME', 'validate' => 'string', 'type' => 'text:25:255', 'explain' => true),
'smtp_password' => array('lang' => 'SMTP_PASSWORD', 'validate' => 'string', 'type' => 'password:25:255', 'explain' => true), 'smtp_password' => array('lang' => 'SMTP_PASSWORD', 'validate' => 'string', 'type' => 'password:25:255', 'explain' => true),
@ -805,7 +805,7 @@ class acp_board
{ {
$act_ary['ACC_USER'] = USER_ACTIVATION_SELF; $act_ary['ACC_USER'] = USER_ACTIVATION_SELF;
$act_ary['ACC_ADMIN'] = USER_ACTIVATION_ADMIN; $act_ary['ACC_ADMIN'] = USER_ACTIVATION_ADMIN;
} }
$act_options = ''; $act_options = '';
foreach ($act_ary as $key => $value) foreach ($act_ary as $key => $value)
@ -824,7 +824,7 @@ class acp_board
{ {
global $user; global $user;
return '<input id="' . $key . '" type="text" size="3" maxlength="3" name="config[min_name_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . '&nbsp;&nbsp;<input type="text" size="3" maxlength="3" name="config[max_name_chars]" value="' . $this->new_config['max_name_chars'] . '" /> ' . $user->lang['MAX_CHARS']; return '<input id="' . $key . '" type="number" size="3" maxlength="3" min="1" max="999" name="config[min_name_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . '&nbsp;&nbsp;<input type="number" size="3" maxlength="3" min="8" max="180" name="config[max_name_chars]" value="' . $this->new_config['max_name_chars'] . '" /> ' . $user->lang['MAX_CHARS'];
} }
/** /**
@ -852,7 +852,7 @@ class acp_board
{ {
global $user; global $user;
return '<input id="' . $key . '" type="text" size="3" maxlength="3" name="config[min_pass_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . '&nbsp;&nbsp;<input type="text" size="3" maxlength="3" name="config[max_pass_chars]" value="' . $this->new_config['max_pass_chars'] . '" /> ' . $user->lang['MAX_CHARS']; return '<input id="' . $key . '" type="number" size="3" maxlength="3" min="1" max="999" name="config[min_pass_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . '&nbsp;&nbsp;<input type="number" size="3" maxlength="3" min="8" max="255" name="config[max_pass_chars]" value="' . $this->new_config['max_pass_chars'] . '" /> ' . $user->lang['MAX_CHARS'];
} }
/** /**

View file

@ -44,6 +44,10 @@ class acp_extensions
$action = $request->variable('action', 'list'); $action = $request->variable('action', 'list');
$ext_name = $request->variable('ext_name', ''); $ext_name = $request->variable('ext_name', '');
// What is a safe limit of execution time? Half the max execution time should be safe.
$safe_time_limit = (ini_get('max_execution_time') / 2);
$start_time = time();
// Cancel action // Cancel action
if ($request->is_set_post('cancel')) if ($request->is_set_post('cancel'))
{ {
@ -105,11 +109,15 @@ class acp_extensions
try try
{ {
if ($phpbb_extension_manager->enable_step($ext_name)) while ($phpbb_extension_manager->enable_step($ext_name))
{ {
$template->assign_var('S_NEXT_STEP', true); // Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{
$template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=enable&amp;ext_name=' . urlencode($ext_name)); meta_refresh(0, $this->u_action . '&amp;action=enable&amp;ext_name=' . urlencode($ext_name));
}
} }
} }
catch (phpbb_db_migration_exception $e) catch (phpbb_db_migration_exception $e)
@ -139,11 +147,15 @@ class acp_extensions
break; break;
case 'disable': case 'disable':
if ($phpbb_extension_manager->disable_step($ext_name)) while ($phpbb_extension_manager->disable_step($ext_name))
{ {
$template->assign_var('S_NEXT_STEP', true); // Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{
$template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=disable&amp;ext_name=' . urlencode($ext_name)); meta_refresh(0, $this->u_action . '&amp;action=disable&amp;ext_name=' . urlencode($ext_name));
}
} }
$this->tpl_name = 'acp_ext_disable'; $this->tpl_name = 'acp_ext_disable';
@ -165,11 +177,15 @@ class acp_extensions
case 'purge': case 'purge':
try try
{ {
if ($phpbb_extension_manager->purge_step($ext_name)) while ($phpbb_extension_manager->purge_step($ext_name))
{ {
$template->assign_var('S_NEXT_STEP', true); // Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{
$template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=purge&amp;ext_name=' . urlencode($ext_name)); meta_refresh(0, $this->u_action . '&amp;action=purge&amp;ext_name=' . urlencode($ext_name));
}
} }
} }
catch (phpbb_db_migration_exception $e) catch (phpbb_db_migration_exception $e)

View file

@ -87,6 +87,11 @@ class acp_groups
case 'approve': case 'approve':
case 'demote': case 'demote':
case 'promote': case 'promote':
if (!check_form_key($form_key))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (!$group_id) if (!$group_id)
{ {
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING); trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING);
@ -259,6 +264,11 @@ class acp_groups
break; break;
case 'addusers': case 'addusers':
if (!check_form_key($form_key))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (!$group_id) if (!$group_id)
{ {
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING); trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING);
@ -381,15 +391,26 @@ class acp_groups
$submit_ary['avatar_width'] = 0; $submit_ary['avatar_width'] = 0;
$submit_ary['avatar_height'] = 0; $submit_ary['avatar_height'] = 0;
} }
// Merge any avatar errors into the primary error array
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));
} }
// Validate the length of "Maximum number of allowed recipients per private message" setting. /*
// We use 16777215 as a maximum because it matches MySQL unsigned mediumint maximum value * Validate the length of "Maximum number of allowed recipients per
// which is the lowest amongst DBMSes supported by phpBB3 * private message" setting. We use 16777215 as a maximum because it matches
if ($max_recipients_error = validate_data($submit_ary, array('max_recipients' => array('num', false, 0, 16777215)))) * MySQL unsigned mediumint maximum value which is the lowest amongst DBMSes
* supported by phpBB3. Also validate the submitted colour value.
*/
$validation_checks = array(
'max_recipients' => array('num', false, 0, 16777215),
'colour' => array('hex_colour', true),
);
if ($validation_error = validate_data($submit_ary, $validation_checks))
{ {
// Replace "error" string with its real, localised form // Replace "error" string with its real, localised form
$error = array_merge($error, array_map(array(&$user, 'lang'), $max_recipients_error)); $error = array_merge($error, array_map(array(&$user, 'lang'), $validation_error));
} }
if (!sizeof($error)) if (!sizeof($error))
@ -570,8 +591,11 @@ class acp_groups
$avatar = phpbb_get_group_avatar($group_row, 'GROUP_AVATAR', true); $avatar = phpbb_get_group_avatar($group_row, 'GROUP_AVATAR', true);
// Merge any avatar errors into the primary error array if (!$update)
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error)); {
// Merge any avatar errors into the primary error array
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));
}
$back_link = request_var('back_link', ''); $back_link = request_var('back_link', '');
@ -906,10 +930,12 @@ class acp_groups
case 'set_config_teampage': case 'set_config_teampage':
$config->set('teampage_forums', $request->variable('teampage_forums', 0)); $config->set('teampage_forums', $request->variable('teampage_forums', 0));
$config->set('teampage_memberships', $request->variable('teampage_memberships', 0)); $config->set('teampage_memberships', $request->variable('teampage_memberships', 0));
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
break; break;
case 'set_config_legend': case 'set_config_legend':
$config->set('legend_sort_groupname', $request->variable('legend_sort_groupname', 0)); $config->set('legend_sort_groupname', $request->variable('legend_sort_groupname', 0));
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
break; break;
} }
} }

View file

@ -544,81 +544,60 @@ class acp_modules
*/ */
function get_module_infos($module = '', $module_class = false, $use_all_available = false) function get_module_infos($module = '', $module_class = false, $use_all_available = false)
{ {
global $phpbb_root_path, $phpEx; global $phpbb_extension_manager, $phpbb_root_path, $phpEx;
$module_class = ($module_class === false) ? $this->module_class : $module_class; $module_class = ($module_class === false) ? $this->module_class : $module_class;
$directory = $phpbb_root_path . 'includes/' . $module_class . '/info/'; $directory = $phpbb_root_path . 'includes/' . $module_class . '/info/';
$fileinfo = array(); $fileinfo = array();
if (!$module) $finder = $phpbb_extension_manager->get_finder();
$modules = $finder
->extension_suffix('_module')
->extension_directory("/$module_class")
->core_path("includes/$module_class/info/")
->core_prefix($module_class . '_')
->get_classes(true, $use_all_available);
foreach ($modules as $cur_module)
{ {
global $phpbb_extension_manager; // Skip entries we do not need if we know the module we are
// looking for
$finder = $phpbb_extension_manager->get_finder(); if ($module && strpos($cur_module, $module) === false)
$modules = $finder
->extension_suffix('_module')
->extension_directory("/$module_class")
->core_path("includes/$module_class/info/")
->core_prefix($module_class . '_')
->get_classes(true, $use_all_available);
foreach ($modules as $module)
{ {
$info_class = preg_replace('/_module$/', '_info', $module); continue;
// If the class does not exist it might be following the old
// format. phpbb_acp_info_acp_foo needs to be turned into
// acp_foo_info and the respective file has to be included
// manually because it does not support auto loading
if (!class_exists($info_class))
{
$info_class = str_replace("phpbb_{$module_class}_info_", '', $module) . '_info';
if (file_exists($directory . $info_class . '.' . $phpEx))
{
include($directory . $info_class . '.' . $phpEx);
}
}
if (class_exists($info_class))
{
$info = new $info_class();
$module_info = $info->module();
$main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $module;
$fileinfo[$main_class] = $module_info;
}
} }
ksort($fileinfo); $info_class = preg_replace('/_module$/', '_info', $cur_module);
}
else
{
$info_class = preg_replace('/_module$/', '_info', $module);
// If the class does not exist it might be following the old
// format. phpbb_acp_info_acp_foo needs to be turned into
// acp_foo_info and the respective file has to be included
// manually because it does not support auto loading
if (!class_exists($info_class)) if (!class_exists($info_class))
{ {
$info_class = $module . '_info'; $info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module);
if (!class_exists($info_class) && file_exists($directory . $module . '.' . $phpEx)) $info_class = $info_class_file . '_info';
if (!class_exists($info_class) && file_exists($directory . $info_class_file . '.' . $phpEx))
{ {
include($directory . $module . '.' . $phpEx); include($directory . $info_class_file . '.' . $phpEx);
} }
} }
// Get module title tag
if (class_exists($info_class)) if (class_exists($info_class))
{ {
$info = new $info_class(); $info = new $info_class();
$module_info = $info->module(); $module_info = $info->module();
$main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $module; $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $cur_module;
$fileinfo[$main_class] = $module_info; $fileinfo[$main_class] = $module_info;
} }
} }
ksort($fileinfo);
return $fileinfo; return $fileinfo;
} }

View file

@ -38,7 +38,7 @@ class acp_update
$info = obtain_latest_version_info(request_var('versioncheck_force', false)); $info = obtain_latest_version_info(request_var('versioncheck_force', false));
if ($info === false) if (empty($info))
{ {
trigger_error('VERSIONCHECK_FAIL', E_USER_WARNING); trigger_error('VERSIONCHECK_FAIL', E_USER_WARNING);
} }

View file

@ -330,7 +330,7 @@ function acp_ldap(&$new)
</dl> </dl>
<dl> <dl>
<dt><label for="ldap_email">' . $user->lang['LDAP_EMAIL'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_EMAIL_EXPLAIN'] . '</span></dt> <dt><label for="ldap_email">' . $user->lang['LDAP_EMAIL'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_EMAIL_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_email" size="40" name="config[ldap_email]" value="' . $new['ldap_email'] . '" /></dd> <dd><input type="email" id="ldap_email" size="40" name="config[ldap_email]" value="' . $new['ldap_email'] . '" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="ldap_user">' . $user->lang['LDAP_USER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_USER_EXPLAIN'] . '</span></dt> <dt><label for="ldap_user">' . $user->lang['LDAP_USER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_USER_EXPLAIN'] . '</span></dt>

View file

@ -126,7 +126,7 @@ class phpbb_avatar_driver_upload extends phpbb_avatar_driver
{ {
return array( return array(
'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'text:4:10', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), 'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true), 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true),
); );
} }

View file

@ -0,0 +1,92 @@
<?php
/**
*
* @package migration
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
*
*/
class phpbb_db_migration_data_310_notifications_schema_fix extends phpbb_db_migration
{
static public function depends_on()
{
return array('phpbb_db_migration_data_310_notifications');
}
public function update_schema()
{
return array(
'drop_tables' => array(
$this->table_prefix . 'notification_types',
$this->table_prefix . 'notifications',
),
'add_tables' => array(
$this->table_prefix . 'notification_types' => array(
'COLUMNS' => array(
'notification_type_id' => array('USINT', NULL, 'auto_increment'),
'notification_type_name' => array('VCHAR:255', ''),
'notification_type_enabled' => array('BOOL', 1),
),
'PRIMARY_KEY' => array('notification_type_id'),
'KEYS' => array(
'type' => array('UNIQUE', array('notification_type_name')),
),
),
$this->table_prefix . 'notifications' => array(
'COLUMNS' => array(
'notification_id' => array('UINT:10', NULL, 'auto_increment'),
'notification_type_id' => array('USINT', 0),
'item_id' => array('UINT', 0),
'item_parent_id' => array('UINT', 0),
'user_id' => array('UINT', 0),
'notification_read' => array('BOOL', 0),
'notification_time' => array('TIMESTAMP', 1),
'notification_data' => array('TEXT_UNI', ''),
),
'PRIMARY_KEY' => 'notification_id',
'KEYS' => array(
'item_ident' => array('INDEX', array('notification_type_id', 'item_id')),
'user' => array('INDEX', array('user_id', 'notification_read')),
),
),
),
);
}
public function revert_schema()
{
return array(
'drop_tables' => array(
$this->table_prefix . 'notification_types',
$this->table_prefix . 'notifications',
),
'add_tables' => array(
$this->table_prefix . 'notification_types' => array(
'COLUMNS' => array(
'notification_type' => array('VCHAR:255', ''),
'notification_type_enabled' => array('BOOL', 1),
),
'PRIMARY_KEY' => array('notification_type', 'notification_type_enabled'),
),
$this->table_prefix . 'notifications' => array(
'COLUMNS' => array(
'notification_id' => array('UINT', NULL, 'auto_increment'),
'item_type' => array('VCHAR:255', ''),
'item_id' => array('UINT', 0),
'item_parent_id' => array('UINT', 0),
'user_id' => array('UINT', 0),
'notification_read' => array('BOOL', 0),
'notification_time' => array('TIMESTAMP', 1),
'notification_data' => array('TEXT_UNI', ''),
),
'PRIMARY_KEY' => 'notification_id',
'KEYS' => array(
'item_ident' => array('INDEX', array('item_type', 'item_id')),
'user' => array('INDEX', array('user_id', 'notification_read')),
),
),
),
);
}
}

View file

@ -209,9 +209,6 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac
} }
// The "manual" way // The "manual" way
$module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']);
add_log('admin', 'LOG_MODULE_ADD', $module_log_name);
if (!is_numeric($parent)) if (!is_numeric($parent))
{ {
$sql = 'SELECT module_id $sql = 'SELECT module_id
@ -267,6 +264,8 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac
else else
{ {
// Success // Success
$module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']);
add_log('admin', 'LOG_MODULE_ADD', $module_log_name);
// Move the module if requested above/below an existing one // Move the module if requested above/below an existing one
if (isset($data['before']) && $data['before']) if (isset($data['before']) && $data['before'])

View file

@ -27,25 +27,51 @@ class phpbb_extension_base implements phpbb_extension_interface
/** @var ContainerInterface */ /** @var ContainerInterface */
protected $container; protected $container;
/** @var phpbb_extension_finder */
protected $finder;
/** @var phpbb_db_migrator */
protected $migrator;
/** @var string */
protected $extension_name;
/** @var string */
protected $extension_path;
/** /**
* Constructor * Constructor
* *
* @param ContainerInterface $container Container object * @param ContainerInterface $container Container object
* @param phpbb_extension_finder $extension_finder
* @param string $extension_name Name of this extension (from ext.manager)
* @param string $extension_path Relative path to this extension
*/ */
public function __construct(ContainerInterface $container) public function __construct(ContainerInterface $container, phpbb_extension_finder $extension_finder, phpbb_db_migrator $migrator, $extension_name, $extension_path)
{ {
$this->container = $container; $this->container = $container;
$this->extension_finder = $extension_finder;
$this->migrator = $migrator;
$this->extension_name = $extension_name;
$this->extension_path = $extension_path;
} }
/** /**
* Single enable step that does nothing * Single enable step that installs any included migrations
* *
* @param mixed $old_state State returned by previous call of this method * @param mixed $old_state State returned by previous call of this method
* @return false Indicates no further steps are required * @return false Indicates no further steps are required
*/ */
public function enable_step($old_state) public function enable_step($old_state)
{ {
return false; $migrations = $this->get_migration_file_list();
$this->migrator->set_migrations($migrations);
$this->migrator->update();
return !$this->migrator->finished();
} }
/** /**
@ -60,13 +86,50 @@ class phpbb_extension_base implements phpbb_extension_interface
} }
/** /**
* Single purge step that does nothing * Single purge step that reverts any included and installed migrations
* *
* @param mixed $old_state State returned by previous call of this method * @param mixed $old_state State returned by previous call of this method
* @return false Indicates no further steps are required * @return false Indicates no further steps are required
*/ */
public function purge_step($old_state) public function purge_step($old_state)
{ {
$migrations = $this->get_migration_file_list();
$this->migrator->set_migrations($migrations);
foreach ($migrations as $migration)
{
while ($this->migrator->migration_state($migration) !== false)
{
$this->migrator->revert($migration);
return true;
}
}
return false; return false;
} }
/**
* Get the list of migration files from this extension
*
* @return array
*/
protected function get_migration_file_list()
{
static $migrations = false;
if ($migrations !== false)
{
return $migrations;
}
// Only have the finder search in this extension path directory
$migrations = $this->extension_finder
->extension_directory('/migrations')
->find_from_extension($this->extension_name, $this->extension_path);
$migrations = $this->extension_finder->get_classes_from_files($migrations);
return $migrations;
}
} }

View file

@ -377,6 +377,34 @@ class phpbb_extension_finder
return $files; return $files;
} }
/**
* Finds all file system entries matching the configured options for one
* specific extension
*
* @param string $extension_name Name of the extension
* @param string $extension_path Relative path to the extension root directory
* @param bool $cache Whether the result should be cached
* @param bool $is_dir Directories will be returned when true, only files
* otherwise
* @return array An array of paths to found items
*/
public function find_from_extension($extension_name, $extension_path, $cache = true, $is_dir = false)
{
$extensions = array(
$extension_name => $extension_path,
);
$files = array();
$file_list = $this->find_from_paths($extensions, $cache, $is_dir);
foreach ($file_list as $file)
{
$files[$file['named_path']] = $file['ext_name'];
}
return $files;
}
/** /**
* Finds all file system entries matching the configured options from * Finds all file system entries matching the configured options from

View file

@ -29,7 +29,6 @@ class phpbb_extension_manager
protected $db; protected $db;
protected $config; protected $config;
protected $migrator;
protected $cache; protected $cache;
protected $php_ext; protected $php_ext;
protected $extensions; protected $extensions;
@ -43,7 +42,6 @@ class phpbb_extension_manager
* @param ContainerInterface $container A container * @param ContainerInterface $container A container
* @param phpbb_db_driver $db A database connection * @param phpbb_db_driver $db A database connection
* @param phpbb_config $config phpbb_config * @param phpbb_config $config phpbb_config
* @param phpbb_db_migrator $migrator
* @param phpbb_filesystem $filesystem * @param phpbb_filesystem $filesystem
* @param string $extension_table The name of the table holding extensions * @param string $extension_table The name of the table holding extensions
* @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $phpbb_root_path Path to the phpbb includes directory.
@ -51,13 +49,12 @@ class phpbb_extension_manager
* @param phpbb_cache_driver_interface $cache A cache instance or null * @param phpbb_cache_driver_interface $cache A cache instance or null
* @param string $cache_name The name of the cache variable, defaults to _ext * @param string $cache_name The name of the cache variable, defaults to _ext
*/ */
public function __construct(ContainerInterface $container, phpbb_db_driver $db, phpbb_config $config, phpbb_db_migrator $migrator, phpbb_filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') public function __construct(ContainerInterface $container, phpbb_db_driver $db, phpbb_config $config, phpbb_filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext')
{ {
$this->container = $container; $this->container = $container;
$this->phpbb_root_path = $phpbb_root_path; $this->phpbb_root_path = $phpbb_root_path;
$this->db = $db; $this->db = $db;
$this->config = $config; $this->config = $config;
$this->migrator = $migrator;
$this->cache = $cache; $this->cache = $cache;
$this->filesystem = $filesystem; $this->filesystem = $filesystem;
$this->php_ext = $php_ext; $this->php_ext = $php_ext;
@ -136,13 +133,15 @@ class phpbb_extension_manager
{ {
$extension_class_name = 'phpbb_ext_' . str_replace('/', '_', $name) . '_ext'; $extension_class_name = 'phpbb_ext_' . str_replace('/', '_', $name) . '_ext';
$migrator = $this->container->get('migrator');
if (class_exists($extension_class_name)) if (class_exists($extension_class_name))
{ {
return new $extension_class_name($this->container); return new $extension_class_name($this->container, $this->get_finder(), $migrator, $name, $this->get_extension_path($name, true));
} }
else else
{ {
return new phpbb_extension_base($this->container); return new phpbb_extension_base($this->container, $this->get_finder(), $migrator, $name, $this->get_extension_path($name, true));
} }
} }
@ -178,12 +177,6 @@ class phpbb_extension_manager
$old_state = (isset($this->extensions[$name]['ext_state'])) ? unserialize($this->extensions[$name]['ext_state']) : false; $old_state = (isset($this->extensions[$name]['ext_state'])) ? unserialize($this->extensions[$name]['ext_state']) : false;
// Returns false if not completed
if (!$this->handle_migrations($name, 'enable'))
{
return true;
}
$extension = $this->get_extension($name); $extension = $this->get_extension($name);
$state = $extension->enable_step($old_state); $state = $extension->enable_step($old_state);
@ -199,12 +192,21 @@ class phpbb_extension_manager
$this->extensions[$name]['ext_path'] = $this->get_extension_path($extension_data['ext_name']); $this->extensions[$name]['ext_path'] = $this->get_extension_path($extension_data['ext_name']);
ksort($this->extensions); ksort($this->extensions);
$sql = 'UPDATE ' . $this->extension_table . ' $sql = 'SELECT COUNT(ext_name) as row_count
SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . " FROM ' . $this->extension_table . "
WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
$this->db->sql_query($sql); $result = $this->db->sql_query($sql);
$count = $this->db->sql_fetchfield('row_count');
$this->db->sql_freeresult($result);
if (!$this->db->sql_affectedrows()) if ($count)
{
$sql = 'UPDATE ' . $this->extension_table . '
SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
$this->db->sql_query($sql);
}
else
{ {
$sql = 'INSERT INTO ' . $this->extension_table . ' $sql = 'INSERT INTO ' . $this->extension_table . '
' . $this->db->sql_build_array('INSERT', $extension_data); ' . $this->db->sql_build_array('INSERT', $extension_data);
@ -335,12 +337,6 @@ class phpbb_extension_manager
$old_state = unserialize($this->extensions[$name]['ext_state']); $old_state = unserialize($this->extensions[$name]['ext_state']);
// Returns false if not completed
if (!$this->handle_migrations($name, 'purge'))
{
return true;
}
$extension = $this->get_extension($name); $extension = $this->get_extension($name);
$state = $extension->purge_step($old_state); $state = $extension->purge_step($old_state);
@ -514,72 +510,4 @@ class phpbb_extension_manager
{ {
return new phpbb_extension_finder($this, $this->filesystem, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder'); return new phpbb_extension_finder($this, $this->filesystem, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder');
} }
/**
* Handle installing/reverting migrations
*
* @param string $extension_name Name of the extension
* @param string $mode enable or purge
* @return bool True if completed, False if not completed
*/
protected function handle_migrations($extension_name, $mode)
{
$extensions = array(
$extension_name => $this->phpbb_root_path . $this->get_extension_path($extension_name),
);
$finder = $this->get_finder();
$migrations = array();
$file_list = $finder
->extension_directory('/migrations')
->find_from_paths($extensions);
if (empty($file_list))
{
return true;
}
foreach ($file_list as $file)
{
$migrations[$file['named_path']] = $file['ext_name'];
}
$migrations = $finder->get_classes_from_files($migrations);
$this->migrator->set_migrations($migrations);
// What is a safe limit of execution time? Half the max execution time should be safe.
$safe_time_limit = (ini_get('max_execution_time') / 2);
$start_time = time();
if ($mode == 'enable')
{
while (!$this->migrator->finished())
{
$this->migrator->update();
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{
return false;
}
}
}
else if ($mode == 'purge')
{
foreach ($migrations as $migration)
{
while ($this->migrator->migration_state($migration) !== false)
{
$this->migrator->revert($migration);
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{
return false;
}
}
}
}
return true;
}
} }

View file

@ -846,7 +846,7 @@ function phpbb_is_writable($file)
*/ */
function phpbb_is_absolute($path) function phpbb_is_absolute($path)
{ {
return ($path[0] == '/' || (DIRECTORY_SEPARATOR == '\\' && preg_match('#^[a-z]:[/\\\]#i', $path))) ? true : false; return (isset($path[0]) && $path[0] == '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false;
} }
/** /**
@ -2907,7 +2907,7 @@ function meta_refresh($time, $url, $disable_cd_check = false)
// For XHTML compatibility we change back & to &amp; // For XHTML compatibility we change back & to &amp;
$template->assign_vars(array( $template->assign_vars(array(
'META' => '<meta http-equiv="refresh" content="' . $time . ';url=' . $url . '" />') 'META' => '<meta http-equiv="refresh" content="' . $time . '; url=' . $url . '" />')
); );
} }

View file

@ -249,17 +249,49 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars)
{ {
case 'text': case 'text':
case 'password': case 'password':
case 'url':
case 'email':
case 'color':
case 'date':
case 'time':
case 'datetime':
case 'datetime-local':
case 'month':
case 'range':
case 'search':
case 'tel':
case 'url':
case 'week':
$size = (int) $tpl_type[1]; $size = (int) $tpl_type[1];
$maxlength = (int) $tpl_type[2]; $maxlength = (int) $tpl_type[2];
$tpl = '<input id="' . $key . '" type="' . $tpl_type[0] . '"' . (($size) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength) ? $maxlength : 255) . '" name="' . $name . '" value="' . $new[$config_key] . '"' . (($tpl_type[0] === 'password') ? ' autocomplete="off"' : '') . ' />'; $tpl = '<input id="' . $key . '" type="' . $tpl_type[0] . '"' . (($size) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength) ? $maxlength : 255) . '" name="' . $name . '" value="' . $new[$config_key] . '"' . (($tpl_type[0] === 'password') ? ' autocomplete="off"' : '') . ' />';
break; break;
case 'dimension': case 'number':
$size = (int) $tpl_type[1]; $min = $max = $maxlength = '';
$maxlength = (int) $tpl_type[2]; $min = ( isset($tpl_type[1]) ) ? (int) $tpl_type[1] : false;
if ( isset($tpl_type[2]) )
{
$max = (int) $tpl_type[2];
$maxlength = strlen( (string) $max );
}
$tpl = '<input id="' . $key . '" type="text"' . (($size) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength) ? $maxlength : 255) . '" name="config[' . $config_key . '_width]" value="' . $new[$config_key . '_width'] . '" /> x <input type="text"' . (($size) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength) ? $maxlength : 255) . '" name="config[' . $config_key . '_height]" value="' . $new[$config_key . '_height'] . '" />'; $tpl = '<input id="' . $key . '" type="number" maxlength="' . (( $maxlength != '' ) ? $maxlength : 255) . '"' . (( $min != '' ) ? ' min="' . $min . '"' : '') . (( $max != '' ) ? ' max="' . $max . '"' : '') . ' name="' . $name . '" value="' . $new[$config_key] . '" />';
break;
case 'dimension':
$min = $max = $maxlength = $size = '';
$min = (int) $tpl_type[1];
if ( isset($tpl_type[2]) )
{
$max = (int) $tpl_type[2];
$size = $maxlength = strlen( (string) $max );
}
$tpl = '<input id="' . $key . '" type="number"' . (( $size != '' ) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength != '') ? $maxlength : 255) . '"' . (( $min !== '' ) ? ' min="' . $min . '"' : '') . (( $max != '' ) ? ' max="' . $max . '"' : '') . ' name="config[' . $config_key . '_width]" value="' . $new[$config_key . '_width'] . '" /> x <input type="number"' . (( $size != '' ) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength != '') ? $maxlength : 255) . '"' . (( $min !== '' ) ? ' min="' . $min . '"' : '') . (( $max != '' ) ? ' max="' . $max . '"' : '') . ' name="config[' . $config_key . '_height]" value="' . $new[$config_key . '_height'] . '" />';
break; break;
case 'textarea': case 'textarea':

View file

@ -3040,38 +3040,29 @@ function tidy_database()
*/ */
function add_permission_language() function add_permission_language()
{ {
global $user, $phpEx; global $user, $phpEx, $phpbb_extension_manager;
// First of all, our own file. We need to include it as the first file because it presets all relevant variables. // add permission language files from extensions
$user->add_lang('acp/permissions_phpbb'); $finder = $phpbb_extension_manager->get_finder();
$files_to_add = array(); $lang_files = $finder
->prefix('permissions_')
->suffix(".$phpEx")
->core_path('language/' . $user->lang_name . '/')
->extension_directory('/language/' . $user->lang_name)
->find();
// Now search in acp and mods folder for permissions_ files. foreach ($lang_files as $lang_file => $ext_name)
foreach (array('acp/', 'mods/') as $path)
{ {
$dh = @opendir($user->lang_path . $user->lang_name . '/' . $path); if ($ext_name === '/')
if ($dh)
{ {
while (($file = readdir($dh)) !== false) $user->add_lang($lang_file);
{ }
if ($file !== 'permissions_phpbb.' . $phpEx && strpos($file, 'permissions_') === 0 && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx) else
{ {
$files_to_add[] = $path . substr($file, 0, -(strlen($phpEx) + 1)); $user->add_lang_ext($ext_name, $lang_file);
}
}
closedir($dh);
} }
} }
if (!sizeof($files_to_add))
{
return false;
}
$user->add_lang($files_to_add);
return true;
} }
/** /**
@ -3097,7 +3088,7 @@ function obtain_latest_version_info($force_update = false, $warn_fail = false, $
$info = get_remote_file('version.phpbb.com', '/phpbb', $info = get_remote_file('version.phpbb.com', '/phpbb',
((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno); ((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno);
if ($info === false) if (empty($info))
{ {
$cache->destroy('versioncheck'); $cache->destroy('versioncheck');
if ($warn_fail) if ($warn_fail)

View file

@ -403,14 +403,7 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
$upload->set_disallowed_content(explode('|', $config['mime_triggers'])); $upload->set_disallowed_content(explode('|', $config['mime_triggers']));
} }
if (!$local) $filedata['post_attach'] = $local || $upload->is_valid($form_name);
{
$filedata['post_attach'] = ($upload->is_valid($form_name)) ? true : false;
}
else
{
$filedata['post_attach'] = true;
}
if (!$filedata['post_attach']) if (!$filedata['post_attach'])
{ {
@ -429,30 +422,18 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
return $filedata; return $filedata;
} }
$cat_id = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] : ATTACHMENT_CATEGORY_NONE; // Whether the uploaded file is in the image category
$is_image = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false;
// Make sure the image category only holds valid images...
if ($cat_id == ATTACHMENT_CATEGORY_IMAGE && !$file->is_image())
{
$file->remove();
// If this error occurs a user tried to exploit an IE Bug by renaming extensions
// Since the image category is displaying content inline we need to catch this.
trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
}
// Do we have to create a thumbnail?
$filedata['thumbnail'] = ($cat_id == ATTACHMENT_CATEGORY_IMAGE && $config['img_create_thumbnail']) ? 1 : 0;
// Check Image Size, if it is an image
if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id) && $cat_id == ATTACHMENT_CATEGORY_IMAGE)
{
$file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
}
// Admins and mods are allowed to exceed the allowed filesize
if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id)) if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id))
{ {
// Check Image Size, if it is an image
if ($is_image)
{
$file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
}
// Admins and mods are allowed to exceed the allowed filesize
if (!empty($extensions[$file->get('extension')]['max_filesize'])) if (!empty($extensions[$file->get('extension')]['max_filesize']))
{ {
$allowed_filesize = $extensions[$file->get('extension')]['max_filesize']; $allowed_filesize = $extensions[$file->get('extension')]['max_filesize'];
@ -467,10 +448,12 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
$file->clean_filename('unique', $user->data['user_id'] . '_'); $file->clean_filename('unique', $user->data['user_id'] . '_');
// Are we uploading an image *and* this image being within the image category? Only then perform additional image checks. // Are we uploading an image *and* this image being within the image category?
$no_image = ($cat_id == ATTACHMENT_CATEGORY_IMAGE) ? false : true; // Only then perform additional image checks.
$file->move_file($config['upload_path'], false, !$is_image);
$file->move_file($config['upload_path'], false, $no_image); // Do we have to create a thumbnail?
$filedata['thumbnail'] = ($is_image && $config['img_create_thumbnail']) ? 1 : 0;
if (sizeof($file->error)) if (sizeof($file->error))
{ {
@ -481,6 +464,16 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
return $filedata; return $filedata;
} }
// Make sure the image category only holds valid images...
if ($is_image && !$file->is_image())
{
$file->remove();
// If this error occurs a user tried to exploit an IE Bug by renaming extensions
// Since the image category is displaying content inline we need to catch this.
trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
}
$filedata['filesize'] = $file->get('filesize'); $filedata['filesize'] = $file->get('filesize');
$filedata['mimetype'] = $file->get('mimetype'); $filedata['mimetype'] = $file->get('mimetype');
$filedata['extension'] = $file->get('extension'); $filedata['extension'] = $file->get('extension');

View file

@ -1040,9 +1040,9 @@ class custom_profile_admin extends custom_profile
global $user; global $user;
$options = array( $options = array(
0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="text" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'), 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'),
1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'), 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'),
2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_maxlen" size="5" value="' . $this->vars['field_maxlen'] . '" />'), 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" size="5" value="' . $this->vars['field_maxlen'] . '" />'),
3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options() . '</select>') 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options() . '</select>')
); );
@ -1057,9 +1057,9 @@ class custom_profile_admin extends custom_profile
global $user; global $user;
$options = array( $options = array(
0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input name="rows" size="5" value="' . $this->vars['rows'] . '" /> ' . $user->lang['ROWS'] . '</dd><dd><input name="columns" size="5" value="' . $this->vars['columns'] . '" /> ' . $user->lang['COLUMNS'] . ' <input type="hidden" name="field_length" value="' . $this->vars['field_length'] . '" />'), 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" max="99999" name="rows" size="5" value="' . $this->vars['rows'] . '" /> ' . $user->lang['ROWS'] . '</dd><dd><input type="number" min="0" max="99999" name="columns" size="5" value="' . $this->vars['columns'] . '" /> ' . $user->lang['COLUMNS'] . ' <input type="hidden" name="field_length" value="' . $this->vars['field_length'] . '" />'),
1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_minlen" size="10" value="' . $this->vars['field_minlen'] . '" />'), 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" max="9999999999" name="field_minlen" size="10" value="' . $this->vars['field_minlen'] . '" />'),
2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_maxlen" size="10" value="' . $this->vars['field_maxlen'] . '" />'), 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" max="9999999999" name="field_maxlen" size="10" value="' . $this->vars['field_maxlen'] . '" />'),
3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options() . '</select>') 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options() . '</select>')
); );
@ -1074,9 +1074,9 @@ class custom_profile_admin extends custom_profile
global $user; global $user;
$options = array( $options = array(
0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="text" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'), 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'),
1 => array('TITLE' => $user->lang['MIN_FIELD_NUMBER'], 'FIELD' => '<input type="text" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'), 1 => array('TITLE' => $user->lang['MIN_FIELD_NUMBER'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'),
2 => array('TITLE' => $user->lang['MAX_FIELD_NUMBER'], 'FIELD' => '<input type="text" name="field_maxlen" size="5" value="' . $this->vars['field_maxlen'] . '" />'), 2 => array('TITLE' => $user->lang['MAX_FIELD_NUMBER'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_maxlen" size="5" value="' . $this->vars['field_maxlen'] . '" />'),
3 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => '<input type="post" name="field_default_value" value="' . $this->vars['field_default_value'] . '" />') 3 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => '<input type="post" name="field_default_value" value="' . $this->vars['field_default_value'] . '" />')
); );

View file

@ -1330,22 +1330,12 @@ function validate_data($data, $val_ary)
{ {
$function = array_shift($validate); $function = array_shift($validate);
array_unshift($validate, $data[$var]); array_unshift($validate, $data[$var]);
$function_prefix = (function_exists('phpbb_validate_' . $function)) ? 'phpbb_validate_' : 'validate_';
if (function_exists('phpbb_validate_' . $function)) if ($result = call_user_func_array($function_prefix . $function, $validate))
{ {
if ($result = call_user_func_array('phpbb_validate_' . $function, $validate)) // Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted.
{ $error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var);
// Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted.
$error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var);
}
}
else
{
if ($result = call_user_func_array('validate_' . $function, $validate))
{
// Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted.
$error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var);
}
} }
} }
} }
@ -2008,6 +1998,30 @@ function validate_jabber($jid)
return false; return false;
} }
/**
* Validate hex colour value
*
* @param string $colour The hex colour value
* @param bool $optional Whether the colour value is optional. True if an empty
* string will be accepted as correct input, false if not.
* @return bool|string Error message if colour value is incorrect, false if it
* fits the hex colour code
*/
function phpbb_validate_hex_colour($colour, $optional = false)
{
if ($colour === '')
{
return (($optional) ? false : 'WRONG_DATA');
}
if (!preg_match('/^([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/', $colour))
{
return 'WRONG_DATA';
}
return false;
}
/** /**
* Verifies whether a style ID corresponds to an active style. * Verifies whether a style ID corresponds to an active style.
* *

View file

@ -0,0 +1,29 @@
<?php
/**
*
* @package notifications
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Notifications exception
*
* @package notifications
*/
class phpbb_notification_exception extends \Exception
{
public function __toString()
{
return $this->getMessage();
}
}

View file

@ -36,6 +36,9 @@ class phpbb_notification_manager
/** @var phpbb_db_driver */ /** @var phpbb_db_driver */
protected $db; protected $db;
/** @var phpbb_cache_service */
protected $cache;
/** @var phpbb_user */ /** @var phpbb_user */
protected $user; protected $user;
@ -70,7 +73,7 @@ class phpbb_notification_manager
* @param string $user_notifications_table * @param string $user_notifications_table
* @return phpbb_notification_manager * @return phpbb_notification_manager
*/ */
public function __construct($notification_types, $notification_methods, $phpbb_container, phpbb_user_loader $user_loader, phpbb_db_driver $db, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) public function __construct($notification_types, $notification_methods, $phpbb_container, phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table)
{ {
$this->notification_types = $notification_types; $this->notification_types = $notification_types;
$this->notification_methods = $notification_methods; $this->notification_methods = $notification_methods;
@ -78,6 +81,7 @@ class phpbb_notification_manager
$this->user_loader = $user_loader; $this->user_loader = $user_loader;
$this->db = $db; $this->db = $db;
$this->cache = $cache;
$this->user = $user; $this->user = $user;
$this->phpbb_root_path = $phpbb_root_path; $this->phpbb_root_path = $phpbb_root_path;
@ -145,7 +149,7 @@ class phpbb_notification_manager
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.user_id = ' . (int) $options['user_id'] . ' WHERE n.user_id = ' . (int) $options['user_id'] . '
AND n.notification_read = 0 AND n.notification_read = 0
AND nt.notification_type = n.item_type AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1'; AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql); $result = $this->db->sql_query($sql);
$unread_count = (int) $this->db->sql_fetchfield('unread_count', $result); $unread_count = (int) $this->db->sql_fetchfield('unread_count', $result);
@ -158,7 +162,7 @@ class phpbb_notification_manager
$sql = 'SELECT COUNT(n.notification_id) AS total_count $sql = 'SELECT COUNT(n.notification_id) AS total_count
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.user_id = ' . (int) $options['user_id'] . ' WHERE n.user_id = ' . (int) $options['user_id'] . '
AND nt.notification_type = n.item_type AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1'; AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql); $result = $this->db->sql_query($sql);
$total_count = (int) $this->db->sql_fetchfield('total_count', $result); $total_count = (int) $this->db->sql_fetchfield('total_count', $result);
@ -170,11 +174,11 @@ class phpbb_notification_manager
$rowset = array(); $rowset = array();
// Get the main notifications // Get the main notifications
$sql = 'SELECT n.* $sql = 'SELECT n.*, nt.notification_type_name
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.user_id = ' . (int) $options['user_id'] . WHERE n.user_id = ' . (int) $options['user_id'] .
(($options['notification_id']) ? ((is_array($options['notification_id'])) ? ' AND ' . $this->db->sql_in_set('n.notification_id', $options['notification_id']) : ' AND n.notification_id = ' . (int) $options['notification_id']) : '') . ' (($options['notification_id']) ? ((is_array($options['notification_id'])) ? ' AND ' . $this->db->sql_in_set('n.notification_id', $options['notification_id']) : ' AND n.notification_id = ' . (int) $options['notification_id']) : '') . '
AND nt.notification_type = n.item_type AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1 AND nt.notification_type_enabled = 1
ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']); ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']);
$result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']); $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
@ -188,12 +192,12 @@ class phpbb_notification_manager
// Get all unread notifications // Get all unread notifications
if ($unread_count && $options['all_unread'] && !empty($rowset)) if ($unread_count && $options['all_unread'] && !empty($rowset))
{ {
$sql = 'SELECT n.* $sql = 'SELECT n.*, nt.notification_type_name
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.user_id = ' . (int) $options['user_id'] . ' WHERE n.user_id = ' . (int) $options['user_id'] . '
AND n.notification_read = 0 AND n.notification_read = 0
AND ' . $this->db->sql_in_set('n.notification_id', array_keys($rowset), true) . ' AND ' . $this->db->sql_in_set('n.notification_id', array_keys($rowset), true) . '
AND nt.notification_type = n.item_type AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1 AND nt.notification_type_enabled = 1
ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']); ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']);
$result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']); $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
@ -207,17 +211,17 @@ class phpbb_notification_manager
foreach ($rowset as $row) foreach ($rowset as $row)
{ {
$notification = $this->get_item_type_class($row['item_type'], $row); $notification = $this->get_item_type_class($row['notification_type_name'], $row);
// Array of user_ids to query all at once // Array of user_ids to query all at once
$user_ids = array_merge($user_ids, $notification->users_to_query()); $user_ids = array_merge($user_ids, $notification->users_to_query());
// Some notification types also require querying additional tables themselves // Some notification types also require querying additional tables themselves
if (!isset($load_special[$row['item_type']])) if (!isset($load_special[$row['notification_type_name']]))
{ {
$load_special[$row['item_type']] = array(); $load_special[$row['notification_type_name']] = array();
} }
$load_special[$row['item_type']] = array_merge($load_special[$row['item_type']], $notification->get_load_special()); $load_special[$row['notification_type_name']] = array_merge($load_special[$row['notification_type_name']], $notification->get_load_special());
$notifications[$row['notification_id']] = $notification; $notifications[$row['notification_id']] = $notification;
} }
@ -243,19 +247,21 @@ class phpbb_notification_manager
/** /**
* Mark notifications read * Mark notifications read
* *
* @param bool|string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types * @param bool|string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types
* @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids
* @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
* @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False) * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
*/ */
public function mark_notifications_read($item_type, $item_id, $user_id, $time = false) public function mark_notifications_read($notification_type_name, $item_id, $user_id, $time = false)
{ {
$time = ($time !== false) ? $time : time(); $time = ($time !== false) ? $time : time();
$sql = 'UPDATE ' . $this->notifications_table . " $sql = 'UPDATE ' . $this->notifications_table . "
SET notification_read = 1 SET notification_read = 1
WHERE notification_time <= " . (int) $time . WHERE notification_time <= " . (int) $time .
(($item_type !== false) ? ' AND ' . (is_array($item_type) ? $this->db->sql_in_set('item_type', $item_type) : " item_type = '" . $this->db->sql_escape($item_type) . "'") : '') . (($notification_type_name !== false) ? ' AND ' .
(is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name))
: '') .
(($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '') . (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '') .
(($item_id !== false) ? ' AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) : ''); (($item_id !== false) ? ' AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) : '');
$this->db->sql_query($sql); $this->db->sql_query($sql);
@ -264,29 +270,21 @@ class phpbb_notification_manager
/** /**
* Mark notifications read from a parent identifier * Mark notifications read from a parent identifier
* *
* @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types) * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
* @param bool|int|array $item_parent_id Item parent id or array of item parent ids. False to mark read for all item parent ids * @param bool|int|array $item_parent_id Item parent id or array of item parent ids. False to mark read for all item parent ids
* @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
* @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False) * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
*/ */
public function mark_notifications_read_by_parent($item_type, $item_parent_id, $user_id, $time = false) public function mark_notifications_read_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false)
{ {
if (is_array($item_type))
{
foreach ($item_type as $type)
{
$this->mark_notifications_read_by_parent($type, $item_parent_id, $user_id, $time);
}
return;
}
$time = ($time !== false) ? $time : time(); $time = ($time !== false) ? $time : time();
$sql = 'UPDATE ' . $this->notifications_table . " $sql = 'UPDATE ' . $this->notifications_table . "
SET notification_read = 1 SET notification_read = 1
WHERE item_type = '" . $this->db->sql_escape($item_type) . "' WHERE notification_time <= " . (int) $time .
AND notification_time <= " . (int) $time . (($notification_type_name !== false) ? ' AND ' .
(is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name))
: '') .
(($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id) : 'item_parent_id = ' . (int) $item_parent_id) : '') . (($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id) : 'item_parent_id = ' . (int) $item_parent_id) : '') .
(($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : ''); (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '');
$this->db->sql_query($sql); $this->db->sql_query($sql);
@ -312,7 +310,7 @@ class phpbb_notification_manager
/** /**
* Add a notification * Add a notification
* *
* @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types) * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
* Note: If you send an array of types, any user who could receive multiple notifications from this single item will only receive * Note: If you send an array of types, any user who could receive multiple notifications from this single item will only receive
* a single notification. If they MUST receive multiple notifications, call this function multiple times instead of sending an array * a single notification. If they MUST receive multiple notifications, call this function multiple times instead of sending an array
* @param array $data Data specific for this type that will be inserted * @param array $data Data specific for this type that will be inserted
@ -320,18 +318,18 @@ class phpbb_notification_manager
* ignore_users array of data to specify which users should not receive certain types of notifications * ignore_users array of data to specify which users should not receive certain types of notifications
* @return array Information about what users were notified and how they were notified * @return array Information about what users were notified and how they were notified
*/ */
public function add_notifications($item_type, $data, array $options = array()) public function add_notifications($notification_type_name, $data, array $options = array())
{ {
$options = array_merge(array( $options = array_merge(array(
'ignore_users' => array(), 'ignore_users' => array(),
), $options); ), $options);
if (is_array($item_type)) if (is_array($notification_type_name))
{ {
$notified_users = array(); $notified_users = array();
$temp_options = $options; $temp_options = $options;
foreach ($item_type as $type) foreach ($notification_type_name as $type)
{ {
$temp_options['ignore_users'] = $options['ignore_users'] + $notified_users; $temp_options['ignore_users'] = $options['ignore_users'] + $notified_users;
$notified_users += $this->add_notifications($type, $data, $temp_options); $notified_users += $this->add_notifications($type, $data, $temp_options);
@ -340,12 +338,12 @@ class phpbb_notification_manager
return $notified_users; return $notified_users;
} }
$item_id = $this->get_item_type_class($item_type)->get_item_id($data); $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data);
// find out which users want to receive this type of notification // find out which users want to receive this type of notification
$notify_users = $this->get_item_type_class($item_type)->find_users_for_notification($data, $options); $notify_users = $this->get_item_type_class($notification_type_name)->find_users_for_notification($data, $options);
$this->add_notifications_for_users($item_type, $data, $notify_users); $this->add_notifications_for_users($notification_type_name, $data, $notify_users);
return $notify_users; return $notify_users;
} }
@ -353,15 +351,15 @@ class phpbb_notification_manager
/** /**
* Add a notification for specific users * Add a notification for specific users
* *
* @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types) * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
* @param array $data Data specific for this type that will be inserted * @param array $data Data specific for this type that will be inserted
* @param array $notify_users User list to notify * @param array $notify_users User list to notify
*/ */
public function add_notifications_for_users($item_type, $data, $notify_users) public function add_notifications_for_users($notification_type_name, $data, $notify_users)
{ {
if (is_array($item_type)) if (is_array($notification_type_name))
{ {
foreach ($item_type as $type) foreach ($notification_type_name as $type)
{ {
$this->add_notifications_for_users($type, $data, $notify_users); $this->add_notifications_for_users($type, $data, $notify_users);
} }
@ -369,24 +367,9 @@ class phpbb_notification_manager
return; return;
} }
$sql = 'SELECT notification_type $notification_type_id = $this->get_notification_type_id($notification_type_name);
FROM ' . $this->notification_types_table . "
WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'";
$result = $this->db->sql_query($sql);
if ($this->db->sql_fetchrow($result) === false) $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data);
{
// Does not exist in the database, must add the item type
$sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array(
'notification_type' => $item_type,
'notification_type_enabled' => 1,
));
$this->db->sql_query($sql);
}
$this->db->sql_freeresult($result);
$item_id = $this->get_item_type_class($item_type)->get_item_id($data);
$user_ids = array(); $user_ids = array();
$notification_objects = $notification_methods = array(); $notification_objects = $notification_methods = array();
@ -397,10 +380,10 @@ class phpbb_notification_manager
// Make sure not to send new notifications to users who've already been notified about this item // Make sure not to send new notifications to users who've already been notified about this item
// This may happen when an item was added, but now new users are able to see the item // This may happen when an item was added, but now new users are able to see the item
$sql = 'SELECT n.user_id $sql = 'SELECT n.user_id
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.item_type = '" . $this->db->sql_escape($item_type) . "' WHERE n.notification_type_id = ' . (int) $notification_type_id . '
AND n.item_id = " . (int) $item_id . ' AND n.item_id = ' . (int) $item_id . '
AND nt.notification_type = n.item_type AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1'; AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql); $result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result)) while ($row = $this->db->sql_fetchrow($result))
@ -415,7 +398,7 @@ class phpbb_notification_manager
} }
// Allow notifications to perform actions before creating the insert array (such as run a query to cache some data needed for all notifications) // Allow notifications to perform actions before creating the insert array (such as run a query to cache some data needed for all notifications)
$notification = $this->get_item_type_class($item_type); $notification = $this->get_item_type_class($notification_type_name);
$pre_create_data = $notification->pre_create_insert_array($data, $notify_users); $pre_create_data = $notification->pre_create_insert_array($data, $notify_users);
unset($notification); unset($notification);
@ -424,7 +407,7 @@ class phpbb_notification_manager
// Go through each user so we can insert a row in the DB and then notify them by their desired means // Go through each user so we can insert a row in the DB and then notify them by their desired means
foreach ($notify_users as $user => $methods) foreach ($notify_users as $user => $methods)
{ {
$notification = $this->get_item_type_class($item_type); $notification = $this->get_item_type_class($notification_type_name);
$notification->user_id = (int) $user; $notification->user_id = (int) $user;
@ -464,14 +447,14 @@ class phpbb_notification_manager
/** /**
* Update a notification * Update a notification
* *
* @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types) * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
* @param array $data Data specific for this type that will be updated * @param array $data Data specific for this type that will be updated
*/ */
public function update_notifications($item_type, $data) public function update_notifications($notification_type_name, $data)
{ {
if (is_array($item_type)) if (is_array($notification_type_name))
{ {
foreach ($item_type as $type) foreach ($notification_type_name as $type)
{ {
$this->update_notifications($type, $data); $this->update_notifications($type, $data);
} }
@ -479,7 +462,7 @@ class phpbb_notification_manager
return; return;
} }
$notification = $this->get_item_type_class($item_type); $notification = $this->get_item_type_class($notification_type_name);
// Allow the notifications class to over-ride the update_notifications functionality // Allow the notifications class to over-ride the update_notifications functionality
if (method_exists($notification, 'update_notifications')) if (method_exists($notification, 'update_notifications'))
@ -491,28 +474,29 @@ class phpbb_notification_manager
} }
} }
$notification_type_id = $this->get_notification_type_id($notification_type_name);
$item_id = $notification->get_item_id($data); $item_id = $notification->get_item_id($data);
$update_array = $notification->create_update_array($data); $update_array = $notification->create_update_array($data);
$sql = 'UPDATE ' . $this->notifications_table . ' $sql = 'UPDATE ' . $this->notifications_table . '
SET ' . $this->db->sql_build_array('UPDATE', $update_array) . " SET ' . $this->db->sql_build_array('UPDATE', $update_array) . '
WHERE item_type = '" . $this->db->sql_escape($item_type) . "' WHERE notification_type_id = ' . (int) $notification_type_id . '
AND item_id = " . (int) $item_id; AND item_id = ' . (int) $item_id;
$this->db->sql_query($sql); $this->db->sql_query($sql);
} }
/** /**
* Delete a notification * Delete a notification
* *
* @param string|array $item_type Type identifier or array of item types (only acceptable if the $item_id is identical for the specified types) * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $item_id is identical for the specified types)
* @param int|array $item_id Identifier within the type (or array of ids) * @param int|array $item_id Identifier within the type (or array of ids)
* @param array $data Data specific for this type that will be updated * @param array $data Data specific for this type that will be updated
*/ */
public function delete_notifications($item_type, $item_id) public function delete_notifications($notification_type_name, $item_id)
{ {
if (is_array($item_type)) if (is_array($notification_type_name))
{ {
foreach ($item_type as $type) foreach ($notification_type_name as $type)
{ {
$this->delete_notifications($type, $item_id); $this->delete_notifications($type, $item_id);
} }
@ -520,9 +504,11 @@ class phpbb_notification_manager
return; return;
} }
$sql = 'DELETE FROM ' . $this->notifications_table . " $notification_type_id = $this->get_notification_type_id($notification_type_name);
WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
AND " . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id); $sql = 'DELETE FROM ' . $this->notifications_table . '
WHERE notification_type_id = ' . (int) $notification_type_id . '
AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id);
$this->db->sql_query($sql); $this->db->sql_query($sql);
} }
@ -655,7 +641,8 @@ class phpbb_notification_manager
{ {
if ($method !== '') if ($method !== '')
{ {
$this->add_subscription($item_type, $item_type, '', $user_id); // Make sure to subscribe them to the base subscription
$this->add_subscription($item_type, $item_id, '', $user_id);
} }
$user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id; $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id;
@ -755,13 +742,13 @@ class phpbb_notification_manager
* is disabled so that all those notifications are hidden and do not * is disabled so that all those notifications are hidden and do not
* cause errors * cause errors
* *
* @param string $item_type Type identifier of the subscription * @param string $notification_type_name Type identifier of the subscription
*/ */
public function disable_notifications($item_type) public function disable_notifications($notification_type_name)
{ {
$sql = 'UPDATE ' . $this->notification_types_table . " $sql = 'UPDATE ' . $this->notification_types_table . "
SET notification_type_enabled = 0 SET notification_type_enabled = 0
WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'"; WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'";
$this->db->sql_query($sql); $this->db->sql_query($sql);
} }
@ -771,17 +758,21 @@ class phpbb_notification_manager
* This should be called when an extension which has notification types * This should be called when an extension which has notification types
* is purged so that all those notifications are removed * is purged so that all those notifications are removed
* *
* @param string $item_type Type identifier of the subscription * @param string $notification_type_name Type identifier of the subscription
*/ */
public function purge_notifications($item_type) public function purge_notifications($notification_type_name)
{ {
$sql = 'DELETE FROM ' . $this->notifications_table . " $notification_type_id = $this->get_notification_type_id($notification_type_name);
WHERE item_type = '" . $this->db->sql_escape($item_type) . "'";
$sql = 'DELETE FROM ' . $this->notifications_table . '
WHERE notification_type_id = ' . (int) $notification_type_id;
$this->db->sql_query($sql); $this->db->sql_query($sql);
$sql = 'DELETE FROM ' . $this->notification_types_table . " $sql = 'DELETE FROM ' . $this->notification_types_table . '
WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'"; WHERE notification_type_id = ' . (int) $notification_type_id;
$this->db->sql_query($sql); $this->db->sql_query($sql);
$this->cache->destroy('notification_type_ids');
} }
/** /**
@ -791,13 +782,13 @@ class phpbb_notification_manager
* that was disabled is re-enabled so that all those notifications that * that was disabled is re-enabled so that all those notifications that
* were hidden are shown again * were hidden are shown again
* *
* @param string $item_type Type identifier of the subscription * @param string $notification_type_name Type identifier of the subscription
*/ */
public function enable_notifications($item_type) public function enable_notifications($notification_type_name)
{ {
$sql = 'UPDATE ' . $this->notification_types_table . " $sql = 'UPDATE ' . $this->notification_types_table . "
SET notification_type_enabled = 1 SET notification_type_enabled = 1
WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'"; WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'";
$this->db->sql_query($sql); $this->db->sql_query($sql);
} }
@ -816,11 +807,11 @@ class phpbb_notification_manager
/** /**
* Helper to get the notifications item type class and set it up * Helper to get the notifications item type class and set it up
*/ */
public function get_item_type_class($item_type, $data = array()) public function get_item_type_class($notification_type_name, $data = array())
{ {
$item_type = (strpos($item_type, 'notification.type.') === 0) ? $item_type : 'notification.type.' . $item_type; $notification_type_name = (strpos($notification_type_name, 'notification.type.') === 0) ? $notification_type_name : 'notification.type.' . $notification_type_name;
$item = $this->load_object($item_type); $item = $this->load_object($notification_type_name);
$item->set_initial_data($data); $item->set_initial_data($data);
@ -851,4 +842,69 @@ class phpbb_notification_manager
return $object; return $object;
} }
/**
* Get the notification type id from the name
*
* @param string $notification_type_name The name
* @return int the notification_type_id
*/
public function get_notification_type_id($notification_type_name)
{
$notification_type_ids = $this->cache->get('notification_type_ids');
if ($notification_type_ids === false)
{
$notification_type_ids = array();
$sql = 'SELECT notification_type_id, notification_type_name
FROM ' . $this->notification_types_table;
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$notification_type_ids[$row['notification_type_name']] = (int) $row['notification_type_id'];
}
$this->db->sql_freeresult($result);
$this->cache->put('notification_type_ids', $notification_type_ids);
}
if (!isset($notification_type_ids[$notification_type_name]))
{
if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name]))
{
throw new phpbb_notification_exception($this->user->lang('NOTIFICATION_TYPE_NOT_EXIST', $notification_type_name));
}
$sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array(
'notification_type_name' => $notification_type_name,
'notification_type_enabled' => 1,
));
$this->db->sql_query($sql);
$notification_type_ids[$notification_type_name] = (int) $this->db->sql_nextid();
$this->cache->put('notification_type_ids', $notification_type_ids);
}
return $notification_type_ids[$notification_type_name];
}
/**
* Get notification type ids (as an array)
*
* @param array $notification_type_names Array of strings
* @return array Array of integers
*/
public function get_notification_type_ids(array $notification_type_names)
{
$notification_type_ids = array();
foreach ($notification_type_names as $name)
{
$notification_type_ids[$name] = $this->get_notification_type_id($name);
}
return $notification_type_ids;
}
} }

View file

@ -30,7 +30,7 @@ abstract class phpbb_notification_method_base implements phpbb_notification_meth
/** @var phpbb_db_driver */ /** @var phpbb_db_driver */
protected $db; protected $db;
/** @var phpbb_cache_service */ /** @var phpbb_cache_driver_interface */
protected $cache; protected $cache;
/** @var phpbb_template */ /** @var phpbb_template */

View file

@ -39,7 +39,7 @@ class phpbb_notification_method_email extends phpbb_notification_method_messenge
*/ */
public function is_available() public function is_available()
{ {
return (bool) $this->config['email_enable']; return $this->config['email_enable'] && $this->user->data['user_email'];
} }
/** /**

View file

@ -30,7 +30,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
/** @var phpbb_db_driver */ /** @var phpbb_db_driver */
protected $db; protected $db;
/** @var phpbb_cache_service */ /** @var phpbb_cache_driver_interface */
protected $cache; protected $cache;
/** @var phpbb_template */ /** @var phpbb_template */
@ -68,11 +68,19 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
*/ */
public static $notification_option = false; public static $notification_option = false;
/**
* The notification_type_id, set upon creation of the class
* This is the notification_type_id from the notification_types table
*
* @var int
*/
protected $notification_type_id;
/** /**
* Indentification data * Indentification data
* item_type - Type of the item (translates to the notification type) * notification_type_id - ID of the item type (auto generated, from notification types table)
* item_id - ID of the item (e.g. post_id, msg_id) * item_id - ID of the item (e.g. post_id, msg_id)
* item_parent_id - Parent item id (ex: for topic => forum_id, for post => topic_id, etc) * item_parent_id - Parent item id (ex: for topic => forum_id, for post => topic_id, etc)
* user_id * user_id
* notification_read * notification_read
* notification_time * notification_time
@ -124,6 +132,8 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
public function set_notification_manager(phpbb_notification_manager $notification_manager) public function set_notification_manager(phpbb_notification_manager $notification_manager)
{ {
$this->notification_manager = $notification_manager; $this->notification_manager = $notification_manager;
$this->notification_type_id = $this->notification_manager->get_notification_type_id($this->get_type());
} }
/** /**
@ -211,7 +221,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
// Defaults // Defaults
$this->data = array_merge(array( $this->data = array_merge(array(
'item_id' => static::get_item_id($type_data), 'item_id' => static::get_item_id($type_data),
'item_type' => $this->get_type(), 'notification_type_id' => $this->notification_type_id,
'item_parent_id' => static::get_item_parent_id($type_data), 'item_parent_id' => static::get_item_parent_id($type_data),
'notification_time' => time(), 'notification_time' => time(),
@ -460,7 +470,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
$this->notification_read = (bool) !$unread; $this->notification_read = (bool) !$unread;
$where = array( $where = array(
"item_type = '" . $this->db->sql_escape($this->item_type) . "'", 'notification_type_id = ' . (int) $this->notification_type_id,
'item_id = ' . (int) $this->item_id, 'item_id = ' . (int) $this->item_id,
'user_id = ' . (int) $this->user_id, 'user_id = ' . (int) $this->user_id,
); );

View file

@ -103,11 +103,11 @@ class phpbb_notification_type_bookmark extends phpbb_notification_type_post
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$update_notifications = array(); $update_notifications = array();
$sql = 'SELECT n.* $sql = 'SELECT n.*
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.item_type = '" . $this->get_type() . "' WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . ' AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
AND n.notification_read = 0 AND n.notification_read = 0
AND nt.notification_type = n.item_type AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1'; AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql); $result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result)) while ($row = $this->db->sql_fetchrow($result))

View file

@ -138,11 +138,11 @@ class phpbb_notification_type_post extends phpbb_notification_type_base
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$update_notifications = array(); $update_notifications = array();
$sql = 'SELECT n.* $sql = 'SELECT n.*
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.item_type = '" . $this->get_type() . "' WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . ' AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
AND n.notification_read = 0 AND n.notification_read = 0
AND nt.notification_type = n.item_type AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1'; AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql); $result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result)) while ($row = $this->db->sql_fetchrow($result))

View file

@ -122,11 +122,11 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$update_notifications = array(); $update_notifications = array();
$sql = 'SELECT n.* $sql = 'SELECT n.*
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.item_type = '" . $this->get_type() . "' WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . ' AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
AND n.notification_read = 0 AND n.notification_read = 0
AND nt.notification_type = n.item_type AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1'; AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql); $result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result)) while ($row = $this->db->sql_fetchrow($result))
@ -154,10 +154,10 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post
{ {
$old_notifications = array(); $old_notifications = array();
$sql = 'SELECT n.user_id $sql = 'SELECT n.user_id
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.item_type = '" . $this->get_type() . "' WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
AND n.item_id = " . self::get_item_id($post) . ' AND n.item_id = ' . self::get_item_id($post) . '
AND nt.notification_type = n.item_type AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1'; AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql); $result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result)) while ($row = $this->db->sql_fetchrow($result))
@ -185,9 +185,9 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post
// Remove the necessary notifications // Remove the necessary notifications
if (!empty($remove_notifications)) if (!empty($remove_notifications))
{ {
$sql = 'DELETE FROM ' . $this->notifications_table . " $sql = 'DELETE FROM ' . $this->notifications_table . '
WHERE item_type = '" . $this->get_type() . "' WHERE notification_type_id = ' . (int) $this->notification_type_id . '
AND item_id = " . self::get_item_id($post) . ' AND item_id = ' . self::get_item_id($post) . '
AND ' . $this->db->sql_in_set('user_id', $remove_notifications); AND ' . $this->db->sql_in_set('user_id', $remove_notifications);
$this->db->sql_query($sql); $this->db->sql_query($sql);
} }

View file

@ -1819,11 +1819,11 @@ class phpbb_search_fulltext_native extends phpbb_search_base
</dl> </dl>
<dl> <dl>
<dt><label for="fulltext_native_min_chars">' . $this->user->lang['MIN_SEARCH_CHARS'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['MIN_SEARCH_CHARS_EXPLAIN'] . '</span></dt> <dt><label for="fulltext_native_min_chars">' . $this->user->lang['MIN_SEARCH_CHARS'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['MIN_SEARCH_CHARS_EXPLAIN'] . '</span></dt>
<dd><input id="fulltext_native_min_chars" type="text" size="3" maxlength="3" name="config[fulltext_native_min_chars]" value="' . (int) $this->config['fulltext_native_min_chars'] . '" /></dd> <dd><input id="fulltext_native_min_chars" type="number" size="3" maxlength="3" min="0" max="255" name="config[fulltext_native_min_chars]" value="' . (int) $this->config['fulltext_native_min_chars'] . '" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="fulltext_native_max_chars">' . $this->user->lang['MAX_SEARCH_CHARS'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['MAX_SEARCH_CHARS_EXPLAIN'] . '</span></dt> <dt><label for="fulltext_native_max_chars">' . $this->user->lang['MAX_SEARCH_CHARS'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['MAX_SEARCH_CHARS_EXPLAIN'] . '</span></dt>
<dd><input id="fulltext_native_max_chars" type="text" size="3" maxlength="3" name="config[fulltext_native_max_chars]" value="' . (int) $this->config['fulltext_native_max_chars'] . '" /></dd> <dd><input id="fulltext_native_max_chars" type="number" size="3" maxlength="3" min="0" max="255" name="config[fulltext_native_max_chars]" value="' . (int) $this->config['fulltext_native_max_chars'] . '" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="fulltext_native_common_thres">' . $this->user->lang['COMMON_WORD_THRESHOLD'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['COMMON_WORD_THRESHOLD_EXPLAIN'] . '</span></dt> <dt><label for="fulltext_native_common_thres">' . $this->user->lang['COMMON_WORD_THRESHOLD'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['COMMON_WORD_THRESHOLD_EXPLAIN'] . '</span></dt>

View file

@ -970,11 +970,11 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base
</dl> </dl>
<dl> <dl>
<dt><label for="fulltext_postgres_min_word_len">' . $this->user->lang['FULLTEXT_POSTGRES_MIN_WORD_LEN'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_POSTGRES_MIN_WORD_LEN_EXPLAIN'] . '</span></dt> <dt><label for="fulltext_postgres_min_word_len">' . $this->user->lang['FULLTEXT_POSTGRES_MIN_WORD_LEN'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_POSTGRES_MIN_WORD_LEN_EXPLAIN'] . '</span></dt>
<dd><input id="fulltext_postgres_min_word_len" type="text" size="3" maxlength="3" name="config[fulltext_postgres_min_word_len]" value="' . (int) $this->config['fulltext_postgres_min_word_len'] . '" /></dd> <dd><input id="fulltext_postgres_min_word_len" type="number" size="3" maxlength="3" min="0" max="255" name="config[fulltext_postgres_min_word_len]" value="' . (int) $this->config['fulltext_postgres_min_word_len'] . '" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="fulltext_postgres_max_word_len">' . $this->user->lang['FULLTEXT_POSTGRES_MAX_WORD_LEN'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_POSTGRES_MAX_WORD_LEN_EXPLAIN'] . '</span></dt> <dt><label for="fulltext_postgres_max_word_len">' . $this->user->lang['FULLTEXT_POSTGRES_MAX_WORD_LEN'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_POSTGRES_MAX_WORD_LEN_EXPLAIN'] . '</span></dt>
<dd><input id="fulltext_postgres_max_word_len" type="text" size="3" maxlength="3" name="config[fulltext_postgres_max_word_len]" value="' . (int) $this->config['fulltext_postgres_max_word_len'] . '" /></dd> <dd><input id="fulltext_postgres_max_word_len" type="number" size="3" maxlength="3" min="0" max="255" name="config[fulltext_postgres_max_word_len]" value="' . (int) $this->config['fulltext_postgres_max_word_len'] . '" /></dd>
</dl> </dl>
'; ';

View file

@ -888,11 +888,11 @@ class phpbb_search_fulltext_sphinx
</dl> </dl>
<dl> <dl>
<dt><label for="fulltext_sphinx_port">' . $this->user->lang['FULLTEXT_SPHINX_PORT'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_PORT_EXPLAIN'] . '</span></dt> <dt><label for="fulltext_sphinx_port">' . $this->user->lang['FULLTEXT_SPHINX_PORT'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_PORT_EXPLAIN'] . '</span></dt>
<dd><input id="fulltext_sphinx_port" type="text" size="4" maxlength="10" name="config[fulltext_sphinx_port]" value="' . $this->config['fulltext_sphinx_port'] . '" /></dd> <dd><input id="fulltext_sphinx_port" type="number" size="4" maxlength="10" name="config[fulltext_sphinx_port]" value="' . $this->config['fulltext_sphinx_port'] . '" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="fulltext_sphinx_indexer_mem_limit">' . $this->user->lang['FULLTEXT_SPHINX_INDEXER_MEM_LIMIT'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_INDEXER_MEM_LIMIT_EXPLAIN'] . '</span></dt> <dt><label for="fulltext_sphinx_indexer_mem_limit">' . $this->user->lang['FULLTEXT_SPHINX_INDEXER_MEM_LIMIT'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_INDEXER_MEM_LIMIT_EXPLAIN'] . '</span></dt>
<dd><input id="fulltext_sphinx_indexer_mem_limit" type="text" size="4" maxlength="10" name="config[fulltext_sphinx_indexer_mem_limit]" value="' . $this->config['fulltext_sphinx_indexer_mem_limit'] . '" /> ' . $this->user->lang['MIB'] . '</dd> <dd><input id="fulltext_sphinx_indexer_mem_limit" type="number" size="4" maxlength="10" name="config[fulltext_sphinx_indexer_mem_limit]" value="' . $this->config['fulltext_sphinx_indexer_mem_limit'] . '" /> ' . $this->user->lang['MIB'] . '</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="fulltext_sphinx_config_file">' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE_EXPLAIN'] . '</span></dt> <dt><label for="fulltext_sphinx_config_file">' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['FULLTEXT_SPHINX_CONFIG_FILE_EXPLAIN'] . '</span></dt>

View file

@ -32,6 +32,13 @@ class phpbb_template_compile
*/ */
private $filter_params; private $filter_params;
/**
* Array of default parameters
*
* @var array
*/
private $default_filter_params;
/** /**
* Constructor. * Constructor.
* *
@ -44,17 +51,39 @@ class phpbb_template_compile
*/ */
public function __construct($allow_php, $style_names, $locator, $phpbb_root_path, $extension_manager = null, $user = null) public function __construct($allow_php, $style_names, $locator, $phpbb_root_path, $extension_manager = null, $user = null)
{ {
$this->filter_params = array( $this->filter_params = $this->default_filter_params = array(
'allow_php' => $allow_php, 'allow_php' => $allow_php,
'style_names' => $style_names, 'style_names' => $style_names,
'locator' => $locator, 'locator' => $locator,
'phpbb_root_path' => $phpbb_root_path, 'phpbb_root_path' => $phpbb_root_path,
'extension_manager' => $extension_manager, 'extension_manager' => $extension_manager,
'user' => $user, 'user' => $user,
'template_compile' => $this, 'template_compile' => $this,
'cleanup' => true,
); );
} }
/**
* Set filter parameters
*
* @param array $params Array of parameters (will be merged onto $this->filter_params)
*/
public function set_filter_params($params)
{
$this->filter_params = array_merge(
$this->filter_params,
$params
);
}
/**
* Reset filter parameters to their default settings
*/
public function reset_filter_params()
{
$this->filter_params = $this->default_filter_params;
}
/** /**
* Compiles template in $source_file and writes compiled template to * Compiles template in $source_file and writes compiled template to
* cache directory * cache directory

View file

@ -75,6 +75,14 @@ class phpbb_template_filter extends php_user_filter
*/ */
private $allow_php; private $allow_php;
/**
* Whether cleanup will be performed on resulting code, see compile()
* (Preserve whitespace)
*
* @var bool
*/
private $cleanup = true;
/** /**
* Resource locator. * Resource locator.
* *
@ -183,6 +191,7 @@ class phpbb_template_filter extends php_user_filter
$this->phpbb_root_path = $this->params['phpbb_root_path']; $this->phpbb_root_path = $this->params['phpbb_root_path'];
$this->style_names = $this->params['style_names']; $this->style_names = $this->params['style_names'];
$this->extension_manager = $this->params['extension_manager']; $this->extension_manager = $this->params['extension_manager'];
$this->cleanup = $this->params['cleanup'];
if (isset($this->params['user'])) if (isset($this->params['user']))
{ {
$this->user = $this->params['user']; $this->user = $this->params['user'];
@ -223,41 +232,45 @@ class phpbb_template_filter extends php_user_filter
$data = preg_replace('~<!-- ENDPHP -->.*?$~', '', $data); $data = preg_replace('~<!-- ENDPHP -->.*?$~', '', $data);
} }
/* if ($this->cleanup)
{
/*
Preserve whitespace. Preserve whitespace.
PHP removes a newline after the closing tag (if it's there). PHP removes a newline after the closing tag (if it's there).
This is by design: This is by design:
http://www.php.net/manual/en/language.basic-syntax.phpmode.php http://www.php.net/manual/en/language.basic-syntax.phpmode.php
http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php
Consider the following template: Consider the following template:
<!-- IF condition --> <!-- IF condition -->
some content some content
<!-- ENDIF --> <!-- ENDIF -->
If we were to simply preserve all whitespace, we could simply If we were to simply preserve all whitespace, we could simply
replace all "?>" tags with "?>\n". replace all "?>" tags with "?>\n".
Doing that, would add additional newlines to the compiled Doing that, would add additional newlines to the compiled
template in place of the IF and ENDIF statements. These template in place of the IF and ENDIF statements. These
newlines are unwanted (and one is conditional). The IF and newlines are unwanted (and one is conditional). The IF and
ENDIF are usually on their own line for ease of reading. ENDIF are usually on their own line for ease of reading.
This replacement preserves newlines only for statements that This replacement preserves newlines only for statements that
are not the only statement on a line. It will NOT preserve are not the only statement on a line. It will NOT preserve
newlines at the end of statements in the above example. newlines at the end of statements in the above example.
It will preserve newlines in situations like: It will preserve newlines in situations like:
<!-- IF condition -->inline content<!-- ENDIF --> <!-- IF condition -->inline content<!-- ENDIF -->
*/ */
$data = preg_replace('~(?<!^)(<\?php.+(?<!/\*\*/)\?>)$~m', "$1\n", $data);
$data = str_replace('/**/?>', "?>\n", $data);
$data = str_replace('?><?php', '', $data);
}
$data = preg_replace('~(?<!^)(<\?php.+(?<!/\*\*/)\?>)$~m', "$1\n", $data);
$data = str_replace('/**/?>', "?>\n", $data);
$data = str_replace('?><?php', '', $data);
return $data; return $data;
} }
@ -335,6 +348,10 @@ class phpbb_template_filter extends php_user_filter
return '<?php ' . $this->compile_tag_define($matches[2], false) . ' ?>'; return '<?php ' . $this->compile_tag_define($matches[2], false) . ' ?>';
break; break;
case 'ENDDEFINE':
return '<?php ' . $this->compile_tag_enddefine() . ' ?>';
break;
case 'INCLUDE': case 'INCLUDE':
return '<?php ' . $this->compile_tag_include($matches[2]) . ' ?>'; return '<?php ' . $this->compile_tag_include($matches[2]) . ' ?>';
break; break;
@ -839,6 +856,16 @@ class phpbb_template_filter extends php_user_filter
$match = array(); $match = array();
preg_match('#^((?:' . self::REGEX_NS . '\.)+)?\$(?=[A-Z])([A-Z0-9_\-]*)(?: = (.*?))?$#', $tag_args, $match); preg_match('#^((?:' . self::REGEX_NS . '\.)+)?\$(?=[A-Z])([A-Z0-9_\-]*)(?: = (.*?))?$#', $tag_args, $match);
if (!empty($match[2]) && !isset($match[3]) && $op)
{
// DEFINE tag with ENDDEFINE
$array = "\$_tpldata['DEFINE']['.vars']";
$code = 'ob_start(); ';
$code .= "if (!isset($array)) { $array = array(); } ";
$code .= "{$array}[] = '{$match[2]}'";
return $code;
}
if (empty($match[2]) || (!isset($match[3]) && $op)) if (empty($match[2]) || (!isset($match[3]) && $op))
{ {
return ''; return '';
@ -865,6 +892,20 @@ class phpbb_template_filter extends php_user_filter
return (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ' = ' . $parsed_statement . ';'; return (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ' = ' . $parsed_statement . ';';
} }
/**
* Compile ENDDEFINE tag
*
* @return string compiled template code
*/
private function compile_tag_enddefine()
{
$array = "\$_tpldata['DEFINE']['.vars']";
$code = "if (!isset($array) || !sizeof($array)) { trigger_error('ENDDEFINE tag without DEFINE in ' . basename(__FILE__), E_USER_ERROR); }";
$code .= "\$define_var = array_pop($array); ";
$code .= "\$_tpldata['DEFINE']['.'][\$define_var] = ob_get_clean();";
return $code;
}
/** /**
* Compile INCLUDE tag * Compile INCLUDE tag
* *
@ -967,8 +1008,14 @@ class phpbb_template_filter extends php_user_filter
$all_compiled = ''; $all_compiled = '';
foreach ($files as $file) foreach ($files as $file)
{ {
$this->template_compile->set_filter_params(array(
'cleanup' => false,
));
$compiled = $this->template_compile->compile_file($file); $compiled = $this->template_compile->compile_file($file);
$this->template_compile->reset_filter_params();
if ($compiled === false) if ($compiled === false)
{ {
if ($this->user) if ($this->user)

View file

@ -547,6 +547,9 @@ class ucp_groups
$submit_ary['avatar_width'] = 0; $submit_ary['avatar_width'] = 0;
$submit_ary['avatar_height'] = 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));
} }
if (!check_form_key('ucp_groups')) if (!check_form_key('ucp_groups'))
@ -554,6 +557,13 @@ class ucp_groups
$error[] = $user->lang['FORM_INVALID']; $error[] = $user->lang['FORM_INVALID'];
} }
// Validate submitted colour value
if ($colour_error = validate_data($submit_ary, array('colour' => array('hex_colour', true))))
{
// Replace "error" string with its real, localised form
$error = array_merge($error, array_map(array(&$user, 'lang'), $colour_error));
}
if (!sizeof($error)) if (!sizeof($error))
{ {
// Only set the rank, colour, etc. if it's changed or if we're adding a new // Only set the rank, colour, etc. if it's changed or if we're adding a new
@ -672,8 +682,11 @@ class ucp_groups
} }
} }
// Merge any avatars errors into the primary error array if (!$update)
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error)); {
// Merge any avatars errors into the primary error array
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));
}
$template->assign_vars(array( $template->assign_vars(array(
'S_EDIT' => true, 'S_EDIT' => true,

View file

@ -200,6 +200,10 @@ class ucp_notifications
} }
} }
} }
$template->assign_vars(array(
strtoupper($block) . '_COLS' => sizeof($notification_methods) + 2,
));
} }
/** /**

View file

@ -213,8 +213,8 @@ if (!$db_tools->sql_table_exists($table_prefix . 'migrations'))
} }
$migrator = $phpbb_container->get('migrator'); $migrator = $phpbb_container->get('migrator');
$extension_manager = $phpbb_container->get('ext.manager'); $phpbb_extension_manager = $phpbb_container->get('ext.manager');
$finder = $extension_manager->get_finder(); $finder = $phpbb_extension_manager->get_finder();
$migrations = $finder $migrations = $finder
->core_path('includes/db/migration/data/') ->core_path('includes/db/migration/data/')
@ -263,9 +263,8 @@ while (!$migrator->finished())
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing // Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $update_start_time) >= $safe_time_limit) if ((time() - $update_start_time) >= $safe_time_limit)
{ {
//echo '<meta http-equiv="refresh" content="0;url=' . str_replace('&', '&amp;', append_sid($phpbb_root_path . 'test.' . $phpEx)) . '" />';
echo $user->lang['DATABASE_UPDATE_NOT_COMPLETED'] . '<br />'; echo $user->lang['DATABASE_UPDATE_NOT_COMPLETED'] . '<br />';
echo '<a href="' . append_sid($phpbb_root_path . 'test.' . $phpEx) . '">' . $user->lang['DATABASE_UPDATE_CONTINUE'] . '</a>'; echo '<a href="' . append_sid($phpbb_root_path . 'install/database_update.' . $phpEx, 'type=' . $request->variable('type', 0) . '&amp;language=' . $user->lang['USER_LANG']) . '">' . $user->lang['DATABASE_UPDATE_CONTINUE'] . '</a>';
phpbb_end_update($cache, $config); phpbb_end_update($cache, $config);
} }
@ -276,6 +275,17 @@ if ($orig_version != $config['version'])
add_log('admin', 'LOG_UPDATE_DATABASE', $orig_version, $config['version']); add_log('admin', 'LOG_UPDATE_DATABASE', $orig_version, $config['version']);
} }
echo $user->lang['DATABASE_UPDATE_COMPLETE']; echo $user->lang['DATABASE_UPDATE_COMPLETE'] . '<br />';
if ($request->variable('type', 0))
{
echo $user->lang['INLINE_UPDATE_SUCCESSFUL'] . '<br /><br />';
echo '<a href="' . append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=update&amp;sub=file_check&amp;language=' . $user->lang['USER_LANG']) . '" class="button1">' . $user->lang['CONTINUE_UPDATE_NOW'] . '</a>';
}
else
{
echo '<div class="errorbox">' . $user->lang['UPDATE_FILES_NOTICE'] . '</div>';
echo $user->lang['COMPLETE_LOGIN_TO_BOARD'];
}
phpbb_end_update($cache, $config); phpbb_end_update($cache, $config);

View file

@ -373,6 +373,7 @@ class module
'L_SKIP' => $lang['SKIP'], 'L_SKIP' => $lang['SKIP'],
'PAGE_TITLE' => $this->get_page_title(), 'PAGE_TITLE' => $this->get_page_title(),
'T_IMAGE_PATH' => htmlspecialchars($phpbb_admin_path) . 'images/', 'T_IMAGE_PATH' => htmlspecialchars($phpbb_admin_path) . 'images/',
'T_JQUERY_LINK' => $phpbb_root_path . 'assets/javascript/jquery.js',
'S_CONTENT_DIRECTION' => $lang['DIRECTION'], 'S_CONTENT_DIRECTION' => $lang['DIRECTION'],
'S_CONTENT_FLOW_BEGIN' => ($lang['DIRECTION'] == 'ltr') ? 'left' : 'right', 'S_CONTENT_FLOW_BEGIN' => ($lang['DIRECTION'] == 'ltr') ? 'left' : 'right',
@ -666,6 +667,21 @@ class module
{ {
case 'text': case 'text':
case 'password': case 'password':
// HTML5 text-like input types
case 'color':
case 'date':
case 'time':
case 'datetime':
case 'datetime-local':
case 'email':
case 'month':
case 'number':
case 'range':
case 'search':
case 'tel':
case 'url':
case 'week':
$size = (int) $tpl_type[1]; $size = (int) $tpl_type[1];
$maxlength = (int) $tpl_type[2]; $maxlength = (int) $tpl_type[2];

View file

@ -2065,7 +2065,7 @@ class install_convert extends module
// Because we should not rely on correct settings, we simply use the relative path here directly. // Because we should not rely on correct settings, we simply use the relative path here directly.
$template->assign_vars(array( $template->assign_vars(array(
'S_REFRESH' => true, 'S_REFRESH' => true,
'META' => '<meta http-equiv="refresh" content="5;url=' . $url . '" />') 'META' => '<meta http-equiv="refresh" content="5; url=' . $url . '" />')
); );
} }
} }

View file

@ -1022,8 +1022,8 @@ class install_install extends module
} }
// Replace backslashes and doubled slashes (could happen on some proxy setups) // Replace backslashes and doubled slashes (could happen on some proxy setups)
$name = str_replace(array('\\', '//', '/install'), '/', $name); $name = str_replace(array('\\', '//'), '/', $name);
$data['script_path'] = trim(dirname($name)); $data['script_path'] = trim(dirname(dirname($name)));
} }
foreach ($this->advanced_config_options as $config_key => $vars) foreach ($this->advanced_config_options as $config_key => $vars)
@ -1977,7 +1977,7 @@ class install_install extends module
'admin_name' => array('lang' => 'ADMIN_USERNAME', 'type' => 'text:25:100', 'explain' => true), 'admin_name' => array('lang' => 'ADMIN_USERNAME', 'type' => 'text:25:100', 'explain' => true),
'admin_pass1' => array('lang' => 'ADMIN_PASSWORD', 'type' => 'password:25:100', 'explain' => true), 'admin_pass1' => array('lang' => 'ADMIN_PASSWORD', 'type' => 'password:25:100', 'explain' => true),
'admin_pass2' => array('lang' => 'ADMIN_PASSWORD_CONFIRM', 'type' => 'password:25:100', 'explain' => false), 'admin_pass2' => array('lang' => 'ADMIN_PASSWORD_CONFIRM', 'type' => 'password:25:100', 'explain' => false),
'board_email' => array('lang' => 'CONTACT_EMAIL', 'type' => 'text:25:100', 'explain' => false), 'board_email' => array('lang' => 'CONTACT_EMAIL', 'type' => 'email:25:100', 'explain' => false),
); );
var $advanced_config_options = array( var $advanced_config_options = array(
'legend1' => 'ACP_EMAIL_SETTINGS', 'legend1' => 'ACP_EMAIL_SETTINGS',

View file

@ -642,17 +642,30 @@ END;;
# Table: 'phpbb_notification_types' # Table: 'phpbb_notification_types'
CREATE TABLE phpbb_notification_types ( CREATE TABLE phpbb_notification_types (
notification_type VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, notification_type_id INTEGER NOT NULL,
notification_type_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL,
notification_type_enabled INTEGER DEFAULT 1 NOT NULL notification_type_enabled INTEGER DEFAULT 1 NOT NULL
);; );;
ALTER TABLE phpbb_notification_types ADD PRIMARY KEY (notification_type, notification_type_enabled);; ALTER TABLE phpbb_notification_types ADD PRIMARY KEY (notification_type_id);;
CREATE UNIQUE INDEX phpbb_notification_types_type ON phpbb_notification_types(notification_type_name);;
CREATE GENERATOR phpbb_notification_types_gen;;
SET GENERATOR phpbb_notification_types_gen TO 0;;
CREATE TRIGGER t_phpbb_notification_types FOR phpbb_notification_types
BEFORE INSERT
AS
BEGIN
NEW.notification_type_id = GEN_ID(phpbb_notification_types_gen, 1);
END;;
# Table: 'phpbb_notifications' # Table: 'phpbb_notifications'
CREATE TABLE phpbb_notifications ( CREATE TABLE phpbb_notifications (
notification_id INTEGER NOT NULL, notification_id INTEGER NOT NULL,
item_type VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, notification_type_id INTEGER DEFAULT 0 NOT NULL,
item_id INTEGER DEFAULT 0 NOT NULL, item_id INTEGER DEFAULT 0 NOT NULL,
item_parent_id INTEGER DEFAULT 0 NOT NULL, item_parent_id INTEGER DEFAULT 0 NOT NULL,
user_id INTEGER DEFAULT 0 NOT NULL, user_id INTEGER DEFAULT 0 NOT NULL,
@ -663,7 +676,7 @@ CREATE TABLE phpbb_notifications (
ALTER TABLE phpbb_notifications ADD PRIMARY KEY (notification_id);; ALTER TABLE phpbb_notifications ADD PRIMARY KEY (notification_id);;
CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications(item_type, item_id);; CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications(notification_type_id, item_id);;
CREATE INDEX phpbb_notifications_user ON phpbb_notifications(user_id, notification_read);; CREATE INDEX phpbb_notifications_user ON phpbb_notifications(user_id, notification_read);;
CREATE GENERATOR phpbb_notifications_gen;; CREATE GENERATOR phpbb_notifications_gen;;

View file

@ -793,7 +793,8 @@ GO
Table: 'phpbb_notification_types' Table: 'phpbb_notification_types'
*/ */
CREATE TABLE [phpbb_notification_types] ( CREATE TABLE [phpbb_notification_types] (
[notification_type] [varchar] (255) DEFAULT ('') NOT NULL , [notification_type_id] [int] IDENTITY (1, 1) NOT NULL ,
[notification_type_name] [varchar] (255) DEFAULT ('') NOT NULL ,
[notification_type_enabled] [int] DEFAULT (1) NOT NULL [notification_type_enabled] [int] DEFAULT (1) NOT NULL
) ON [PRIMARY] ) ON [PRIMARY]
GO GO
@ -801,18 +802,20 @@ GO
ALTER TABLE [phpbb_notification_types] WITH NOCHECK ADD ALTER TABLE [phpbb_notification_types] WITH NOCHECK ADD
CONSTRAINT [PK_phpbb_notification_types] PRIMARY KEY CLUSTERED CONSTRAINT [PK_phpbb_notification_types] PRIMARY KEY CLUSTERED
( (
[notification_type], [notification_type_id]
[notification_type_enabled]
) ON [PRIMARY] ) ON [PRIMARY]
GO GO
CREATE UNIQUE INDEX [type] ON [phpbb_notification_types]([notification_type_name]) ON [PRIMARY]
GO
/* /*
Table: 'phpbb_notifications' Table: 'phpbb_notifications'
*/ */
CREATE TABLE [phpbb_notifications] ( CREATE TABLE [phpbb_notifications] (
[notification_id] [int] IDENTITY (1, 1) NOT NULL , [notification_id] [int] IDENTITY (1, 1) NOT NULL ,
[item_type] [varchar] (255) DEFAULT ('') NOT NULL , [notification_type_id] [int] DEFAULT (0) NOT NULL ,
[item_id] [int] DEFAULT (0) NOT NULL , [item_id] [int] DEFAULT (0) NOT NULL ,
[item_parent_id] [int] DEFAULT (0) NOT NULL , [item_parent_id] [int] DEFAULT (0) NOT NULL ,
[user_id] [int] DEFAULT (0) NOT NULL , [user_id] [int] DEFAULT (0) NOT NULL ,
@ -829,7 +832,7 @@ ALTER TABLE [phpbb_notifications] WITH NOCHECK ADD
) ON [PRIMARY] ) ON [PRIMARY]
GO GO
CREATE INDEX [item_ident] ON [phpbb_notifications]([item_type], [item_id]) ON [PRIMARY] CREATE INDEX [item_ident] ON [phpbb_notifications]([notification_type_id], [item_id]) ON [PRIMARY]
GO GO
CREATE INDEX [user] ON [phpbb_notifications]([user_id], [notification_read]) ON [PRIMARY] CREATE INDEX [user] ON [phpbb_notifications]([user_id], [notification_read]) ON [PRIMARY]

View file

@ -452,16 +452,18 @@ CREATE TABLE phpbb_modules (
# Table: 'phpbb_notification_types' # Table: 'phpbb_notification_types'
CREATE TABLE phpbb_notification_types ( CREATE TABLE phpbb_notification_types (
notification_type varbinary(255) DEFAULT '' NOT NULL, notification_type_id smallint(4) UNSIGNED NOT NULL auto_increment,
notification_type_name varbinary(255) DEFAULT '' NOT NULL,
notification_type_enabled tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, notification_type_enabled tinyint(1) UNSIGNED DEFAULT '1' NOT NULL,
PRIMARY KEY (notification_type, notification_type_enabled) PRIMARY KEY (notification_type_id),
UNIQUE type (notification_type_name)
); );
# Table: 'phpbb_notifications' # Table: 'phpbb_notifications'
CREATE TABLE phpbb_notifications ( CREATE TABLE phpbb_notifications (
notification_id mediumint(8) UNSIGNED NOT NULL auto_increment, notification_id int(10) UNSIGNED NOT NULL auto_increment,
item_type varbinary(255) DEFAULT '' NOT NULL, notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL,
item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL,
item_parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, item_parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL,
user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL,
@ -469,7 +471,7 @@ CREATE TABLE phpbb_notifications (
notification_time int(11) UNSIGNED DEFAULT '1' NOT NULL, notification_time int(11) UNSIGNED DEFAULT '1' NOT NULL,
notification_data blob NOT NULL, notification_data blob NOT NULL,
PRIMARY KEY (notification_id), PRIMARY KEY (notification_id),
KEY item_ident (item_type, item_id), KEY item_ident (notification_type_id, item_id),
KEY user (user_id, notification_read) KEY user (user_id, notification_read)
); );

View file

@ -452,16 +452,18 @@ CREATE TABLE phpbb_modules (
# Table: 'phpbb_notification_types' # Table: 'phpbb_notification_types'
CREATE TABLE phpbb_notification_types ( CREATE TABLE phpbb_notification_types (
notification_type varchar(255) DEFAULT '' NOT NULL, notification_type_id smallint(4) UNSIGNED NOT NULL auto_increment,
notification_type_name varchar(255) DEFAULT '' NOT NULL,
notification_type_enabled tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, notification_type_enabled tinyint(1) UNSIGNED DEFAULT '1' NOT NULL,
PRIMARY KEY (notification_type, notification_type_enabled) PRIMARY KEY (notification_type_id),
UNIQUE type (notification_type_name)
) CHARACTER SET `utf8` COLLATE `utf8_bin`; ) CHARACTER SET `utf8` COLLATE `utf8_bin`;
# Table: 'phpbb_notifications' # Table: 'phpbb_notifications'
CREATE TABLE phpbb_notifications ( CREATE TABLE phpbb_notifications (
notification_id mediumint(8) UNSIGNED NOT NULL auto_increment, notification_id int(10) UNSIGNED NOT NULL auto_increment,
item_type varchar(255) DEFAULT '' NOT NULL, notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL,
item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL,
item_parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, item_parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL,
user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL,
@ -469,7 +471,7 @@ CREATE TABLE phpbb_notifications (
notification_time int(11) UNSIGNED DEFAULT '1' NOT NULL, notification_time int(11) UNSIGNED DEFAULT '1' NOT NULL,
notification_data text NOT NULL, notification_data text NOT NULL,
PRIMARY KEY (notification_id), PRIMARY KEY (notification_id),
KEY item_ident (item_type, item_id), KEY item_ident (notification_type_id, item_id),
KEY user (user_id, notification_read) KEY user (user_id, notification_read)
) CHARACTER SET `utf8` COLLATE `utf8_bin`; ) CHARACTER SET `utf8` COLLATE `utf8_bin`;

View file

@ -870,19 +870,37 @@ END;
Table: 'phpbb_notification_types' Table: 'phpbb_notification_types'
*/ */
CREATE TABLE phpbb_notification_types ( CREATE TABLE phpbb_notification_types (
notification_type varchar2(255) DEFAULT '' , notification_type_id number(4) NOT NULL,
notification_type_name varchar2(255) DEFAULT '' ,
notification_type_enabled number(1) DEFAULT '1' NOT NULL, notification_type_enabled number(1) DEFAULT '1' NOT NULL,
CONSTRAINT pk_phpbb_notification_types PRIMARY KEY (notification_type, notification_type_enabled) CONSTRAINT pk_phpbb_notification_types PRIMARY KEY (notification_type_id),
CONSTRAINT u_phpbb_type UNIQUE (notification_type_name)
) )
/ /
CREATE SEQUENCE phpbb_notification_types_seq
/
CREATE OR REPLACE TRIGGER t_phpbb_notification_types
BEFORE INSERT ON phpbb_notification_types
FOR EACH ROW WHEN (
new.notification_type_id IS NULL OR new.notification_type_id = 0
)
BEGIN
SELECT phpbb_notification_types_seq.nextval
INTO :new.notification_type_id
FROM dual;
END;
/
/* /*
Table: 'phpbb_notifications' Table: 'phpbb_notifications'
*/ */
CREATE TABLE phpbb_notifications ( CREATE TABLE phpbb_notifications (
notification_id number(8) NOT NULL, notification_id number(10) NOT NULL,
item_type varchar2(255) DEFAULT '' , notification_type_id number(4) DEFAULT '0' NOT NULL,
item_id number(8) DEFAULT '0' NOT NULL, item_id number(8) DEFAULT '0' NOT NULL,
item_parent_id number(8) DEFAULT '0' NOT NULL, item_parent_id number(8) DEFAULT '0' NOT NULL,
user_id number(8) DEFAULT '0' NOT NULL, user_id number(8) DEFAULT '0' NOT NULL,
@ -893,7 +911,7 @@ CREATE TABLE phpbb_notifications (
) )
/ /
CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (item_type, item_id) CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (notification_type_id, item_id)
/ /
CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read) CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read)
/ /

View file

@ -623,12 +623,16 @@ CREATE INDEX phpbb_modules_class_left_id ON phpbb_modules (module_class, left_id
/* /*
Table: 'phpbb_notification_types' Table: 'phpbb_notification_types'
*/ */
CREATE SEQUENCE phpbb_notification_types_seq;
CREATE TABLE phpbb_notification_types ( CREATE TABLE phpbb_notification_types (
notification_type varchar(255) DEFAULT '' NOT NULL, notification_type_id INT2 DEFAULT nextval('phpbb_notification_types_seq'),
notification_type_name varchar(255) DEFAULT '' NOT NULL,
notification_type_enabled INT2 DEFAULT '1' NOT NULL CHECK (notification_type_enabled >= 0), notification_type_enabled INT2 DEFAULT '1' NOT NULL CHECK (notification_type_enabled >= 0),
PRIMARY KEY (notification_type, notification_type_enabled) PRIMARY KEY (notification_type_id)
); );
CREATE UNIQUE INDEX phpbb_notification_types_type ON phpbb_notification_types (notification_type_name);
/* /*
Table: 'phpbb_notifications' Table: 'phpbb_notifications'
@ -637,7 +641,7 @@ CREATE SEQUENCE phpbb_notifications_seq;
CREATE TABLE phpbb_notifications ( CREATE TABLE phpbb_notifications (
notification_id INT4 DEFAULT nextval('phpbb_notifications_seq'), notification_id INT4 DEFAULT nextval('phpbb_notifications_seq'),
item_type varchar(255) DEFAULT '' NOT NULL, notification_type_id INT2 DEFAULT '0' NOT NULL CHECK (notification_type_id >= 0),
item_id INT4 DEFAULT '0' NOT NULL CHECK (item_id >= 0), item_id INT4 DEFAULT '0' NOT NULL CHECK (item_id >= 0),
item_parent_id INT4 DEFAULT '0' NOT NULL CHECK (item_parent_id >= 0), item_parent_id INT4 DEFAULT '0' NOT NULL CHECK (item_parent_id >= 0),
user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0),
@ -647,7 +651,7 @@ CREATE TABLE phpbb_notifications (
PRIMARY KEY (notification_id) PRIMARY KEY (notification_id)
); );
CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (item_type, item_id); CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (notification_type_id, item_id);
CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read); CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read);
/* /*

View file

@ -439,16 +439,17 @@ CREATE INDEX phpbb_modules_class_left_id ON phpbb_modules (module_class, left_id
# Table: 'phpbb_notification_types' # Table: 'phpbb_notification_types'
CREATE TABLE phpbb_notification_types ( CREATE TABLE phpbb_notification_types (
notification_type varchar(255) NOT NULL DEFAULT '', notification_type_id INTEGER PRIMARY KEY NOT NULL ,
notification_type_enabled INTEGER UNSIGNED NOT NULL DEFAULT '1', notification_type_name varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (notification_type, notification_type_enabled) notification_type_enabled INTEGER UNSIGNED NOT NULL DEFAULT '1'
); );
CREATE UNIQUE INDEX phpbb_notification_types_type ON phpbb_notification_types (notification_type_name);
# Table: 'phpbb_notifications' # Table: 'phpbb_notifications'
CREATE TABLE phpbb_notifications ( CREATE TABLE phpbb_notifications (
notification_id INTEGER PRIMARY KEY NOT NULL , notification_id INTEGER PRIMARY KEY NOT NULL ,
item_type varchar(255) NOT NULL DEFAULT '', notification_type_id INTEGER UNSIGNED NOT NULL DEFAULT '0',
item_id INTEGER UNSIGNED NOT NULL DEFAULT '0', item_id INTEGER UNSIGNED NOT NULL DEFAULT '0',
item_parent_id INTEGER UNSIGNED NOT NULL DEFAULT '0', item_parent_id INTEGER UNSIGNED NOT NULL DEFAULT '0',
user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', user_id INTEGER UNSIGNED NOT NULL DEFAULT '0',
@ -457,7 +458,7 @@ CREATE TABLE phpbb_notifications (
notification_data text(65535) NOT NULL DEFAULT '' notification_data text(65535) NOT NULL DEFAULT ''
); );
CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (item_type, item_id); CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (notification_type_id, item_id);
CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read); CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read);
# Table: 'phpbb_poll_options' # Table: 'phpbb_poll_options'

View file

@ -70,6 +70,9 @@ $lang = array_merge($lang, array(
'AIM' => 'AIM', 'AIM' => 'AIM',
'AJAX_ERROR_TITLE' => 'AJAX error', 'AJAX_ERROR_TITLE' => 'AJAX error',
'AJAX_ERROR_TEXT' => 'Something went wrong when processing your request.', 'AJAX_ERROR_TEXT' => 'Something went wrong when processing your request.',
'AJAX_ERROR_TEXT_ABORT' => 'User aborted request.',
'AJAX_ERROR_TEXT_TIMEOUT' => 'Your request timed out; please try again.',
'AJAX_ERROR_TEXT_PARSERERROR' => 'Something went wrong with the request and the server returned an invalid reply.',
'ALLOWED' => 'Allowed', 'ALLOWED' => 'Allowed',
'ALL_FILES' => 'All files', 'ALL_FILES' => 'All files',
'ALL_FORUMS' => 'All forums', 'ALL_FORUMS' => 'All forums',
@ -424,6 +427,7 @@ $lang = array_merge($lang, array(
'NOTIFICATION_TOPIC_APPROVED' => 'Your topic "%2$s" in the forum "%3$s" was approved.', 'NOTIFICATION_TOPIC_APPROVED' => 'Your topic "%2$s" in the forum "%3$s" was approved.',
'NOTIFICATION_TOPIC_DISAPPROVED' => 'Your topic "%1$s" was disapproved for reason: "%2$s".', 'NOTIFICATION_TOPIC_DISAPPROVED' => 'Your topic "%1$s" was disapproved for reason: "%2$s".',
'NOTIFICATION_TOPIC_IN_QUEUE' => 'A new topic titled "%2$s" was posted by %1$s and needs approval.', 'NOTIFICATION_TOPIC_IN_QUEUE' => 'A new topic titled "%2$s" was posted by %1$s and needs approval.',
'NOTIFICATION_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.',
'NOTIFY_ADMIN' => 'Please notify the board administrator or webmaster.', 'NOTIFY_ADMIN' => 'Please notify the board administrator or webmaster.',
'NOTIFY_ADMIN_EMAIL' => 'Please notify the board administrator or webmaster: <a href="mailto:%1$s">%1$s</a>', 'NOTIFY_ADMIN_EMAIL' => 'Please notify the board administrator or webmaster: <a href="mailto:%1$s">%1$s</a>',
'NO_ACCESS_ATTACHMENT' => 'You are not allowed to access this file.', 'NO_ACCESS_ATTACHMENT' => 'You are not allowed to access this file.',
@ -815,6 +819,7 @@ $lang = array_merge($lang, array(
'WHO_IS_ONLINE' => 'Who is online', 'WHO_IS_ONLINE' => 'Who is online',
'WRONG_PASSWORD' => 'You entered an incorrect password.', 'WRONG_PASSWORD' => 'You entered an incorrect password.',
'WRONG_DATA_COLOUR' => 'The colour value you entered is invalid.',
'WRONG_DATA_ICQ' => 'The number you entered is not a valid ICQ number.', 'WRONG_DATA_ICQ' => 'The number you entered is not a valid ICQ number.',
'WRONG_DATA_JABBER' => 'The name you entered is not a valid Jabber account name.', 'WRONG_DATA_JABBER' => 'The name you entered is not a valid Jabber account name.',
'WRONG_DATA_LANG' => 'The language you specified is not valid.', 'WRONG_DATA_LANG' => 'The language you specified is not valid.',

View file

@ -161,7 +161,7 @@ $lang = array_merge($lang, array(
'PLACE_INLINE' => 'Place inline', 'PLACE_INLINE' => 'Place inline',
'POLL_DELETE' => 'Delete poll', 'POLL_DELETE' => 'Delete poll',
'POLL_FOR' => 'Run poll for', 'POLL_FOR' => 'Run poll for',
'POLL_FOR_EXPLAIN' => 'Enter 0 or leave blank for a never ending poll.', 'POLL_FOR_EXPLAIN' => 'Enter 0 for a never ending poll.',
'POLL_MAX_OPTIONS' => 'Options per user', 'POLL_MAX_OPTIONS' => 'Options per user',
'POLL_MAX_OPTIONS_EXPLAIN' => 'This is the number of options each user may select when voting.', 'POLL_MAX_OPTIONS_EXPLAIN' => 'This is the number of options each user may select when voting.',
'POLL_OPTIONS' => 'Poll options', 'POLL_OPTIONS' => 'Poll options',
@ -211,7 +211,7 @@ $lang = array_merge($lang, array(
'SMILIES_ARE_ON' => 'Smilies are <em>ON</em>', 'SMILIES_ARE_ON' => 'Smilies are <em>ON</em>',
'STICKY_ANNOUNCE_TIME_LIMIT'=> 'Sticky/Announcement time limit', 'STICKY_ANNOUNCE_TIME_LIMIT'=> 'Sticky/Announcement time limit',
'STICK_TOPIC_FOR' => 'Stick topic for', 'STICK_TOPIC_FOR' => 'Stick topic for',
'STICK_TOPIC_FOR_EXPLAIN' => 'Enter 0 or leave blank for a never ending Sticky/Announcement. Please note that this number is relative to the date of the post.', 'STICK_TOPIC_FOR_EXPLAIN' => 'Enter 0 for a never ending Sticky/Announcement. Please note that this number is relative to the date of the post.',
'STYLES_TIP' => 'Tip: Styles can be applied quickly to selected text.', 'STYLES_TIP' => 'Tip: Styles can be applied quickly to selected text.',
'TOO_FEW_CHARS' => 'Your message contains too few characters.', 'TOO_FEW_CHARS' => 'Your message contains too few characters.',

View file

@ -225,4 +225,13 @@ $('#member_search').click(function () {
return false; return false;
}); });
/**
* Automatically resize textarea
*/
$(document).ready(function() {
phpbb.resizeTextArea($('textarea:not(#message-box textarea, .no-auto-resize)'), {minHeight: 75, maxHeight: 250});
phpbb.resizeTextArea($('#message-box textarea'));
});
})(jQuery); // Avoid conflicts with other libraries })(jQuery); // Avoid conflicts with other libraries

View file

@ -21,11 +21,11 @@
<!-- END bool --> <!-- END bool -->
<!-- BEGIN int --> <!-- BEGIN int -->
<input type="text" class="inputbox autowidth" name="{int.FIELD_IDENT}" id="{int.FIELD_IDENT}" size="{int.FIELD_LENGTH}" value="{int.FIELD_VALUE}" /> <input type="number" min="{int.FIELD_MINLEN}" max="{int.FIELD_MAXLEN}" class="inputbox autowidth" name="{int.FIELD_IDENT}" id="{int.FIELD_IDENT}" size="{int.FIELD_LENGTH}" value="{int.FIELD_VALUE}" />
<!-- END int --> <!-- END int -->
<!-- BEGIN date --> <!-- BEGIN date -->
<label for="{date.FIELD_IDENT}_day">{L_DAY}{L_COLON} <select name="{date.FIELD_IDENT}_day" id="{date.FIELD_IDENT}_day">{date.S_DAY_OPTIONS}</select></label> <label for="{date.FIELD_IDENT}_day">{L_DAY}{L_COLON} <select name="{date.FIELD_IDENT}_day" id="{date.FIELD_IDENT}_day">{date.S_DAY_OPTIONS}</select></label>
<label for="{date.FIELD_IDENT}_month">{L_MONTH}{L_COLON} <select name="{date.FIELD_IDENT}_month" id="{date.FIELD_IDENT}_month">{date.S_MONTH_OPTIONS}</select></label> <label for="{date.FIELD_IDENT}_month">{L_MONTH}{L_COLON} <select name="{date.FIELD_IDENT}_month" id="{date.FIELD_IDENT}_month">{date.S_MONTH_OPTIONS}</select></label>
<label for="{date.FIELD_IDENT}_year">{L_YEAR}{L_COLON} <select name="{date.FIELD_IDENT}_year" id="{date.FIELD_IDENT}_year">{date.S_YEAR_OPTIONS}</select></label> <label for="{date.FIELD_IDENT}_year">{L_YEAR}{L_COLON} <select name="{date.FIELD_IDENT}_year" id="{date.FIELD_IDENT}_year">{date.S_YEAR_OPTIONS}</select></label>
<!-- END date --> <!-- END date -->

View file

@ -394,3 +394,102 @@ function getCaretPosition(txtarea) {
return caretPos; return caretPos;
} }
/**
* Allow to use tab character when typing code
* Keep indentation of last line of code when typing code
*/
(function($) {
$(document).ready(function() {
var doc, textarea, startTags, endTags;
// find textarea, make sure browser supports necessary functions
if (document.forms[form_name]) {
doc = document;
} else {
doc = opener.document;
}
if (!doc.forms[form_name]) {
return;
}
textarea = doc.forms[form_name].elements[text_name];
if (!textarea || typeof textarea.selectionStart !== 'number') {
return;
}
// list of allowed start and end bbcode code tags, in lower case
startTags = ['[code]', '[code='];
endTags = ['[/code]'];
function inTag() {
var start = textarea.selectionStart,
lastEnd = -1,
lastStart = -1,
i, index, value;
value = textarea.value.toLowerCase();
for (i = 0; i < startTags.length; i++) {
var tagLength = startTags[i].length;
if (start >= tagLength) {
index = value.lastIndexOf(startTags[i], start - tagLength);
lastStart = Math.max(lastStart, index);
}
}
if (lastStart == -1) return false;
if (start > 0) {
for (i = 0; i < endTags.length; i++) {
index = value.lastIndexOf(endTags[i], start - 1);
lastEnd = Math.max(lastEnd, index);
}
}
return (lastEnd < lastStart);
}
function getLastLine() {
var start = textarea.selectionStart,
value = textarea.value,
index = value.lastIndexOf("\n", start - 1);
return value.substring(index + 1, start);
}
function appendCode(code) {
var start = textarea.selectionStart,
end = textarea.selectionEnd,
value = textarea.value;
textarea.value = value.substr(0, start) + code + value.substr(end);
textarea.selectionStart = textarea.selectionEnd = start + code.length;
}
$(textarea).on('keydown', function(event) {
var key = event.keyCode || event.which;
// intercept tabs
if (key == 9) {
if (inTag()) {
appendCode("\t");
event.preventDefault();
return;
}
}
// intercept new line characters
if (key == 13) {
if (inTag()) {
var lastLine = getLastLine(),
code = '' + /^\s*/g.exec(lastLine);
if (code.length > 0) {
appendCode("\n" + code);
event.preventDefault();
return;
}
}
}
});
});
})(jQuery);

View file

@ -2,6 +2,14 @@
* phpBB3 forum functions * phpBB3 forum functions
*/ */
/**
* Find a member
*/
function find_username(url) {
popup(url, 760, 570, '_usersearch');
return false;
}
/** /**
* Window popup * Window popup
*/ */
@ -20,7 +28,7 @@ function popup(url, width, height, name) {
function jumpto() { function jumpto() {
var page = prompt(jump_page, on_page); var page = prompt(jump_page, on_page);
if (page !== null && !isNaN(page) && page === Math.floor(page) && page > 0) { if (page !== null && !isNaN(page) && page == Math.floor(page) && page > 0) {
if (base_url.indexOf('?') === -1) { if (base_url.indexOf('?') === -1) {
document.location.href = base_url + '?start=' + ((page - 1) * per_page); document.location.href = base_url + '?start=' + ((page - 1) * per_page);
} else { } else {
@ -356,41 +364,24 @@ function submit_default_button(event, selector, class_name) {
* The non-jQuery code is a mimick of the jQuery code ;) * The non-jQuery code is a mimick of the jQuery code ;)
*/ */
function apply_onkeypress_event() { function apply_onkeypress_event() {
// jQuery code in case jQuery is used jQuery('form input[type=text], form input[type=password]').on('keypress', function (e) {
if (jquery_present) { var default_button = jQuery(this).parents('form').find('input[type=submit].default-submit-action');
jQuery('form input[type=text], form input[type=password]').live('keypress', function (e) {
var default_button = jQuery(this).parents('form').find('input[type=submit].default-submit-action');
if (!default_button || default_button.length <= 0) {
return true;
}
if (phpbb_check_key(e)) {
return true;
}
if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) {
default_button.click();
return false;
}
if (!default_button || default_button.length <= 0) {
return true; return true;
});
return;
}
var input_tags = document.getElementsByTagName('input');
for (var i = 0, element = input_tags[0]; i < input_tags.length ; element = input_tags[++i]) {
if (element.type === 'text' || element.type === 'password') {
// onkeydown is possible too
element.onkeypress = function (evt) { submit_default_button((evt || window.event), this, 'default-submit-action'); };
} }
}
if (phpbb_check_key(e)) {
return true;
}
if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) {
default_button.click();
return false;
}
return true;
});
} }
/** jQuery(document).ready(apply_onkeypress_event);
* Detect JQuery existance. We currently do not deliver it, but some styles do, so why not benefit from it. ;)
*/
var jquery_present = typeof jQuery === 'function';

View file

@ -13,7 +13,7 @@
<ul class="topiclist"> <ul class="topiclist">
<li class="header"> <li class="header">
<dl class="icon"> <dl class="icon">
<dt><!-- IF forumrow.S_IS_CAT --><a href="{forumrow.U_VIEWFORUM}">{forumrow.FORUM_NAME}</a><!-- ELSE -->{L_FORUM}<!-- ENDIF --></dt> <dt><div class="list-inner"><!-- IF forumrow.S_IS_CAT --><a href="{forumrow.U_VIEWFORUM}">{forumrow.FORUM_NAME}</a><!-- ELSE -->{L_FORUM}<!-- ENDIF --></div></dt>
<dd class="topics">{L_TOPICS}</dd> <dd class="topics">{L_TOPICS}</dd>
<dd class="posts">{L_POSTS}</dd> <dd class="posts">{L_POSTS}</dd>
<dd class="lastpost"><span>{L_LAST_POST}</span></dd> <dd class="lastpost"><span>{L_LAST_POST}</span></dd>
@ -27,20 +27,22 @@
<li class="row"> <li class="row">
<dl class="icon {forumrow.FORUM_IMG_STYLE}"> <dl class="icon {forumrow.FORUM_IMG_STYLE}">
<dt title="{forumrow.FORUM_FOLDER_IMG_ALT}"> <dt title="{forumrow.FORUM_FOLDER_IMG_ALT}">
<!-- IF S_ENABLE_FEEDS and forumrow.S_FEED_ENABLED --><!-- <a class="feed-icon-forum" title="{L_FEED} - {forumrow.FORUM_NAME}" href="{U_FEED}?f={forumrow.FORUM_ID}"><img src="{T_THEME_PATH}/images/feed.gif" alt="{L_FEED} - {forumrow.FORUM_NAME}" /></a> --><!-- ENDIF --> <div class="list-inner">
<!-- IF S_ENABLE_FEEDS and forumrow.S_FEED_ENABLED --><!-- <a class="feed-icon-forum" title="{L_FEED} - {forumrow.FORUM_NAME}" href="{U_FEED}?f={forumrow.FORUM_ID}"><img src="{T_THEME_PATH}/images/feed.gif" alt="{L_FEED} - {forumrow.FORUM_NAME}" /></a> --><!-- ENDIF -->
<!-- IF forumrow.FORUM_IMAGE --><span class="forum-image">{forumrow.FORUM_IMAGE}</span><!-- ENDIF --> <!-- IF forumrow.FORUM_IMAGE --><span class="forum-image">{forumrow.FORUM_IMAGE}</span><!-- ENDIF -->
<a href="{forumrow.U_VIEWFORUM}" class="forumtitle">{forumrow.FORUM_NAME}</a><br /> <a href="{forumrow.U_VIEWFORUM}" class="forumtitle">{forumrow.FORUM_NAME}</a><br />
{forumrow.FORUM_DESC} {forumrow.FORUM_DESC}
<!-- IF forumrow.MODERATORS --> <!-- IF forumrow.MODERATORS -->
<br /><strong>{forumrow.L_MODERATOR_STR}{L_COLON}</strong> {forumrow.MODERATORS} <br /><strong>{forumrow.L_MODERATOR_STR}{L_COLON}</strong> {forumrow.MODERATORS}
<!-- ENDIF --> <!-- ENDIF -->
<!-- IF .forumrow.subforum and forumrow.S_LIST_SUBFORUMS --> <!-- IF .forumrow.subforum and forumrow.S_LIST_SUBFORUMS -->
<br /><strong>{forumrow.L_SUBFORUM_STR}</strong> <br /><strong>{forumrow.L_SUBFORUM_STR}</strong>
<!-- BEGIN subforum --> <!-- BEGIN subforum -->
<a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->,<!-- ENDIF --> <a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->,<!-- ENDIF -->
<!-- END subforum --> <!-- END subforum -->
<!-- ENDIF --> <!-- ENDIF -->
</div>
</dt> </dt>
<!-- IF forumrow.CLICKS --> <!-- IF forumrow.CLICKS -->
<dd class="redirect"><span>{L_REDIRECTS}{L_COLON} {forumrow.CLICKS}</span></dd> <dd class="redirect"><span>{L_REDIRECTS}{L_COLON} {forumrow.CLICKS}</span></dd>

View file

@ -24,22 +24,24 @@
<!-- ENDIF --> <!-- ENDIF -->
<!-- IF .topicrow --> <!-- IF .topicrow -->
<ul class="topiclist"> <ul class="topiclist<!-- IF S_MERGE_SELECT --> missing-column<!-- ENDIF -->">
<li class="header"> <li class="header">
<dl class="icon"> <dl class="icon">
<dt>{L_TOPICS}</dt> <dt><div class="list-inner">{L_TOPICS}</div></dt>
<dd class="posts">{L_REPLIES}</dd> <dd class="posts">{L_REPLIES}</dd>
<dd class="lastpost"><span>{L_LAST_POST}</span></dd> <dd class="lastpost"><span>{L_LAST_POST}</span></dd>
<!-- IF not S_MERGE_SELECT --><dd class="mark">{L_MARK}</dd><!-- ENDIF --> <!-- IF not S_MERGE_SELECT --><dd class="mark">{L_MARK}</dd><!-- ENDIF -->
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist<!-- IF S_MERGE_SELECT --> missing-column<!-- ENDIF -->">
<!-- BEGIN topicrow --> <!-- BEGIN topicrow -->
<li class="row<!-- IF topicrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF --><!-- IF topicrow.S_TOPIC_REPORTED --> reported<!-- ENDIF -->"> <li class="row<!-- IF topicrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF --><!-- IF topicrow.S_TOPIC_REPORTED --> reported<!-- ENDIF -->">
<dl class="icon {topicrow.TOPIC_IMG_STYLE}"> <dl class="icon {topicrow.TOPIC_IMG_STYLE}">
<dt <!-- IF topicrow.TOPIC_ICON_IMG -->style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF -->> <dt <!-- IF topicrow.TOPIC_ICON_IMG -->style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF -->>
<div class="list-inner">
<!-- IF topicrow.S_SELECT_TOPIC --><a href="{topicrow.U_SELECT_TOPIC}" class="topictitle">[ {L_SELECT_MERGE} ]</a>&nbsp;&nbsp; <!-- ENDIF --> <!-- IF topicrow.S_SELECT_TOPIC --><a href="{topicrow.U_SELECT_TOPIC}" class="topictitle">[ {L_SELECT_MERGE} ]</a>&nbsp;&nbsp; <!-- ENDIF -->
<a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a> <a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a>
<!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF --> <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF -->
@ -60,7 +62,10 @@
</ul> </ul>
</div> </div>
<!-- ENDIF --> <!-- ENDIF -->
<!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF -->{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} &raquo; {topicrow.FIRST_POST_TIME} </dt> <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF -->{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} &raquo; {topicrow.FIRST_POST_TIME}
</div>
</dt>
<dd class="posts">{topicrow.REPLIES} <dfn>{L_REPLIES}</dfn></dd> <dd class="posts">{topicrow.REPLIES} <dfn>{L_REPLIES}</dfn></dd>
<dd class="lastpost"><span><dfn>{L_LAST_POST} </dfn>{L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL}<br />{topicrow.LAST_POST_TIME}</span> <dd class="lastpost"><span><dfn>{L_LAST_POST} </dfn>{L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL}<br />{topicrow.LAST_POST_TIME}</span>
</dd> </dd>

View file

@ -13,22 +13,24 @@
<p>{L_UNAPPROVED_TOTAL}</p> <p>{L_UNAPPROVED_TOTAL}</p>
<!-- IF .unapproved --> <!-- IF .unapproved -->
<ul class="topiclist"> <ul class="topiclist two-long-columns">
<li class="header"> <li class="header">
<dl> <dl>
<dt>{L_VIEW_DETAILS}</dt> <dt><div class="list-inner">{L_VIEW_DETAILS}</div></dt>
<dd class="moderation"><span>{L_TOPIC} &amp; {L_FORUM}</span></dd> <dd class="moderation"><span>{L_TOPIC} &amp; {L_FORUM}</span></dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist two-long-columns">
<!-- BEGIN unapproved --> <!-- BEGIN unapproved -->
<li class="row<!-- IF unapproved.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF unapproved.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<dt> <dt>
<a href="{unapproved.U_POST_DETAILS}" class="topictitle">{unapproved.SUBJECT}</a> {unapproved.ATTACH_ICON_IMG}<br /> <div class="list-inner">
{L_POSTED} {L_POST_BY_AUTHOR} {unapproved.AUTHOR_FULL} &raquo; {unapproved.POST_TIME} <a href="{unapproved.U_POST_DETAILS}" class="topictitle">{unapproved.SUBJECT}</a> {unapproved.ATTACH_ICON_IMG}<br />
{L_POSTED} {L_POST_BY_AUTHOR} {unapproved.AUTHOR_FULL} &raquo; {unapproved.POST_TIME}
</div>
</dt> </dt>
<dd class="moderation"><span> <dd class="moderation"><span>
{L_TOPIC}{L_COLON} <a href="{unapproved.U_TOPIC}">{unapproved.TOPIC_TITLE}</a> [<a href="{unapproved.U_MCP_TOPIC}">{L_MODERATE}</a>]<br /> {L_TOPIC}{L_COLON} <a href="{unapproved.U_TOPIC}">{unapproved.TOPIC_TITLE}</a> [<a href="{unapproved.U_MCP_TOPIC}">{L_MODERATE}</a>]<br />
@ -65,22 +67,24 @@
<p>{L_REPORTS_TOTAL}</p> <p>{L_REPORTS_TOTAL}</p>
<!-- IF .report --> <!-- IF .report -->
<ul class="topiclist"> <ul class="topiclist two-long-columns">
<li class="header"> <li class="header">
<dl> <dl>
<dt>{L_VIEW_DETAILS}</dt> <dt><div class="list-inner">{L_VIEW_DETAILS}</div></dt>
<dd class="moderation"><span>{L_REPORTER} &amp; {L_FORUM}</span></dd> <dd class="moderation"><span>{L_REPORTER} &amp; {L_FORUM}</span></dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist two-long-columns">
<!-- BEGIN report --> <!-- BEGIN report -->
<li class="row<!-- IF report.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF report.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<dt> <dt>
<a href="{report.U_POST_DETAILS}#reports" class="topictitle">{report.SUBJECT}</a> {report.ATTACH_ICON_IMG}<br /> <div class="list-inner">
<span>{L_POSTED} {L_POST_BY_AUTHOR} {report.AUTHOR_FULL} &raquo; {report.POST_TIME}</span> <a href="{report.U_POST_DETAILS}#reports" class="topictitle">{report.SUBJECT}</a> {report.ATTACH_ICON_IMG}<br />
<span>{L_POSTED} {L_POST_BY_AUTHOR} {report.AUTHOR_FULL} &raquo; {report.POST_TIME}</span>
</div>
</dt> </dt>
<dd class="moderation"> <dd class="moderation">
<span>{L_REPORTED} {L_POST_BY_AUTHOR} {report.REPORTER_FULL} {L_REPORTED_ON_DATE} {report.REPORT_TIME}<br /> <span>{L_REPORTED} {L_POST_BY_AUTHOR} {report.REPORTER_FULL} {L_REPORTED_ON_DATE} {report.REPORT_TIME}<br />
@ -104,23 +108,25 @@
<p>{L_PM_REPORTS_TOTAL}</p> <p>{L_PM_REPORTS_TOTAL}</p>
<!-- IF .pm_report --> <!-- IF .pm_report -->
<ul class="topiclist"> <ul class="topiclist two-long-columns">
<li class="header"> <li class="header">
<dl> <dl>
<dt>{L_VIEW_DETAILS}</dt> <dt><div class="list-inner">{L_VIEW_DETAILS}</div></dt>
<dd class="moderation"><span>{L_REPORTER}</span></dd> <dd class="moderation"><span>{L_REPORTER}</span></dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist two-long-columns">
<!-- BEGIN pm_report --> <!-- BEGIN pm_report -->
<li class="row<!-- IF pm_report.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF pm_report.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<dt> <dt>
<a href="{pm_report.U_PM_DETAILS}" class="topictitle">{pm_report.PM_SUBJECT}</a> {pm_report.ATTACH_ICON_IMG}<br /> <div class="list-inner">
<span>{L_MESSAGE_BY_AUTHOR} {pm_report.PM_AUTHOR_FULL} &raquo; {pm_report.PM_TIME}</span><br /> <a href="{pm_report.U_PM_DETAILS}" class="topictitle">{pm_report.PM_SUBJECT}</a> {pm_report.ATTACH_ICON_IMG}<br />
<span>{L_MESSAGE_TO} {pm_report.RECIPIENTS}</span> <span>{L_MESSAGE_BY_AUTHOR} {pm_report.PM_AUTHOR_FULL} &raquo; {pm_report.PM_TIME}</span><br />
<span>{L_MESSAGE_TO} {pm_report.RECIPIENTS}</span>
</div>
</dt> </dt>
<dd class="moderation"> <dd class="moderation">
<span>{L_REPORTED} {L_POST_BY_AUTHOR} {pm_report.REPORTER_FULL} {L_REPORTED_ON_DATE} {pm_report.REPORT_TIME}</span> <span>{L_REPORTED} {L_POST_BY_AUTHOR} {pm_report.REPORTER_FULL} {L_REPORTED_ON_DATE} {pm_report.REPORT_TIME}</span>

View file

@ -9,7 +9,7 @@
<ul class="linklist"> <ul class="linklist">
<li class="leftside"> <li class="leftside">
{L_SEARCH_KEYWORDS}{L_COLON} <input type="text" class="inputbox autowidth" name="keywords" value="{S_KEYWORDS}" />&nbsp;<input type="submit" class="button2" name="filter" value="{L_SEARCH}" /> {L_SEARCH_KEYWORDS}{L_COLON} <input type="search" class="inputbox autowidth" name="keywords" value="{S_KEYWORDS}" />&nbsp;<input type="submit" class="button2" name="filter" value="{L_SEARCH}" />
</li> </li>
<li class="rightside pagination"> <li class="rightside pagination">
<!-- IF TOTAL -->{TOTAL} &bull; <!-- ENDIF --> <!-- IF TOTAL -->{TOTAL} &bull; <!-- ENDIF -->

View file

@ -52,7 +52,7 @@
<ul class="linklist"> <ul class="linklist">
<li class="leftside"> <li class="leftside">
{L_SEARCH_KEYWORDS}{L_COLON} <input type="text" class="inputbox autowidth" name="keywords" value="{S_KEYWORDS}" />&nbsp;<input type="submit" class="button2" name="filter" value="{L_SEARCH}" /> {L_SEARCH_KEYWORDS}{L_COLON} <input type="search" class="inputbox autowidth" name="keywords" value="{S_KEYWORDS}" />&nbsp;<input type="submit" class="button2" name="filter" value="{L_SEARCH}" />
</li> </li>
<li class="rightside pagination"> <li class="rightside pagination">
<!-- IF TOTAL_REPORTS -->{TOTAL_REPORTS} &bull; <!-- ENDIF --> <!-- IF TOTAL_REPORTS -->{TOTAL_REPORTS} &bull; <!-- ENDIF -->

View file

@ -26,16 +26,16 @@
<!-- ENDIF --> <!-- ENDIF -->
</li> </li>
</ul> </ul>
<ul class="topiclist"> <ul class="topiclist missing-column">
<li class="header"> <li class="header">
<dl> <dl>
<dt><!-- IF S_TOPICS -->{L_TOPIC}<!-- ELSE -->{L_POST}<!-- ENDIF --></dt> <dt><div class="list-inner"><!-- IF S_TOPICS -->{L_TOPIC}<!-- ELSE -->{L_POST}<!-- ENDIF --></div></dt>
<dd class="moderation"><span><!-- IF not S_TOPICS -->{L_TOPIC} &amp; <!-- ENDIF -->{L_FORUM}</span></dd> <dd class="moderation"><span><!-- IF not S_TOPICS -->{L_TOPIC} &amp; <!-- ENDIF -->{L_FORUM}</span></dd>
<dd class="mark">{L_MARK}</dd> <dd class="mark">{L_MARK}</dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist missing-column">
<!-- BEGIN postrow --> <!-- BEGIN postrow -->
@ -46,8 +46,10 @@
<li class="row<!-- IF postrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF postrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<dt> <dt>
<a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.POST_SUBJECT}</a> {postrow.ATTACH_ICON_IMG}<br /> <div class="list-inner">
<span>{L_POSTED} {L_POST_BY_AUTHOR} {postrow.POST_AUTHOR_FULL} &raquo; {postrow.POST_TIME}</span> <a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.POST_SUBJECT}</a> {postrow.ATTACH_ICON_IMG}<br />
<span>{L_POSTED} {L_POST_BY_AUTHOR} {postrow.POST_AUTHOR_FULL} &raquo; {postrow.POST_TIME}</span>
</div>
</dt> </dt>
<dd class="moderation"> <dd class="moderation">
<span> <span>

View file

@ -28,33 +28,37 @@
<!-- ENDIF --> <!-- ENDIF -->
</li> </li>
</ul> </ul>
<ul class="topiclist"> <ul class="topiclist missing-column">
<li class="header"> <li class="header">
<dl> <dl>
<dt>{L_VIEW_DETAILS}</dt> <dt><div class="list-inner">{L_VIEW_DETAILS}</div></dt>
<dd class="moderation"><span>{L_REPORTER}<!-- IF not S_PM --> &amp; {L_FORUM}<!-- ENDIF --></span></dd> <dd class="moderation"><span>{L_REPORTER}<!-- IF not S_PM --> &amp; {L_FORUM}<!-- ENDIF --></span></dd>
<dd class="mark">{L_MARK}</dd> <dd class="mark">{L_MARK}</dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist missing-column">
<!-- BEGIN postrow --> <!-- BEGIN postrow -->
<li class="row<!-- IF postrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF postrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<!-- IF S_PM --> <!-- IF S_PM -->
<dt> <dt>
<a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.PM_SUBJECT}</a> {postrow.ATTACH_ICON_IMG}<br /> <div class="list-inner">
<span>{L_MESSAGE_BY_AUTHOR} {postrow.PM_AUTHOR_FULL} &raquo; {postrow.PM_TIME}</span><br /> <a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.PM_SUBJECT}</a> {postrow.ATTACH_ICON_IMG}<br />
<span>{L_MESSAGE_TO} {postrow.RECIPIENTS}</span> <span>{L_MESSAGE_BY_AUTHOR} {postrow.PM_AUTHOR_FULL} &raquo; {postrow.PM_TIME}</span><br />
<span>{L_MESSAGE_TO} {postrow.RECIPIENTS}</span>
</div>
</dt> </dt>
<dd class="moderation"> <dd class="moderation">
<span>{postrow.REPORTER_FULL} &laquo; {postrow.REPORT_TIME}</span> <span>{postrow.REPORTER_FULL} &laquo; {postrow.REPORT_TIME}</span>
</dd> </dd>
<!-- ELSE --> <!-- ELSE -->
<dt> <dt>
<a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.POST_SUBJECT}</a> {postrow.ATTACH_ICON_IMG}<br /> <div class="list-inner">
<span>{L_POSTED} {L_POST_BY_AUTHOR} {postrow.POST_AUTHOR_FULL} &raquo; {postrow.POST_TIME}</span> <a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.POST_SUBJECT}</a> {postrow.ATTACH_ICON_IMG}<br />
<span>{L_POSTED} {L_POST_BY_AUTHOR} {postrow.POST_AUTHOR_FULL} &raquo; {postrow.POST_TIME}</span>
</div>
</dt> </dt>
<dd class="moderation"> <dd class="moderation">
<span>{postrow.REPORTER_FULL} &laquo; {postrow.REPORT_TIME}<br /> <span>{postrow.REPORTER_FULL} &laquo; {postrow.REPORT_TIME}<br />

View file

@ -43,7 +43,7 @@ onload_functions.push('subPanels()');
<fieldset id="display-panel" class="fields2"> <fieldset id="display-panel" class="fields2">
<dl> <dl>
<dt><label for="posts_per_page">{L_POSTS_PER_PAGE}{L_COLON}</label><br /><span>{L_POSTS_PER_PAGE_EXPLAIN}</span></dt> <dt><label for="posts_per_page">{L_POSTS_PER_PAGE}{L_COLON}</label><br /><span>{L_POSTS_PER_PAGE_EXPLAIN}</span></dt>
<dd><input class="inputbox autowidth" type="text" name="posts_per_page" id="posts_per_page" size="6" value="{POSTS_PER_PAGE}" /></dd> <dd><input class="inputbox autowidth" type="number" min="1" name="posts_per_page" id="posts_per_page" size="6" value="{POSTS_PER_PAGE}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label>{L_DISPLAY_POSTS}{L_COLON}</label></dt> <dt><label>{L_DISPLAY_POSTS}{L_COLON}</label></dt>
@ -80,7 +80,7 @@ onload_functions.push('subPanels()');
<dl> <dl>
<dt><label for="to_topic_id">{L_MERGE_TOPIC_ID}{L_COLON}</label></dt> <dt><label for="to_topic_id">{L_MERGE_TOPIC_ID}{L_COLON}</label></dt>
<dd> <dd>
<input class="inputbox autowidth" type="text" size="6" name="to_topic_id" id="to_topic_id" value="{TO_TOPIC_ID}" /> <input class="inputbox autowidth" type="number" min="0" size="6" name="to_topic_id" id="to_topic_id" value="{TO_TOPIC_ID}" />
<a href="{U_SELECT_TOPIC}" >{L_SELECT_TOPIC}</a> <a href="{U_SELECT_TOPIC}" >{L_SELECT_TOPIC}</a>
</dd> </dd>
<!-- IF TO_TOPIC_INFO --><dd>{TO_TOPIC_INFO}</dd><!-- ENDIF --> <!-- IF TO_TOPIC_INFO --><dd>{TO_TOPIC_INFO}</dd><!-- ENDIF -->
@ -141,9 +141,9 @@ onload_functions.push('subPanels()');
<ul class="linklist"> <ul class="linklist">
<li class="rightside pagination"> <li class="rightside pagination">
<!-- IF TOTAL_POSTS --> {TOTAL_POSTS} &bull; <!-- ENDIF --> <!-- IF TOTAL_POSTS --> {TOTAL_POSTS} &bull; <!-- ENDIF -->
<!-- IF .pagination --> <!-- IF .pagination -->
<!-- INCLUDE pagination.html --> <!-- INCLUDE pagination.html -->
<!-- ELSE --> <!-- ELSE -->
{PAGE_NUMBER} {PAGE_NUMBER}
<!-- ENDIF --> <!-- ENDIF -->
</li> </li>

View file

@ -22,7 +22,7 @@
<!-- ELSE --> <!-- ELSE -->
<dl> <dl>
<dt><label for="email">{L_EMAIL_ADDRESS}{L_COLON}</label></dt> <dt><label for="email">{L_EMAIL_ADDRESS}{L_COLON}</label></dt>
<dd><input class="inputbox autowidth" type="text" name="email" id="email" size="50" maxlength="100" tabindex="2" value="{EMAIL}" /></dd> <dd><input class="inputbox autowidth" type="email" name="email" id="email" size="50" maxlength="100" tabindex="2" value="{EMAIL}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="name">{L_REAL_NAME}{L_COLON}</label></dt> <dt><label for="name">{L_REAL_NAME}{L_COLON}</label></dt>

View file

@ -89,7 +89,7 @@ function insert_single(user)
<!-- ENDIF --> <!-- ENDIF -->
<dl> <dl>
<dt><label for="count">{L_POSTS}{L_COLON}</label></dt> <dt><label for="count">{L_POSTS}{L_COLON}</label></dt>
<dd><select name="count_select">{S_COUNT_OPTIONS}</select> <input class="inputbox medium" type="text" name="count" id="count" value="{COUNT}" /></dd> <dd><select name="count_select">{S_COUNT_OPTIONS}</select> <input class="inputbox medium" type="number" min="0" name="count" id="count" value="{COUNT}" /></dd>
</dl> </dl>
<!-- IF S_IP_SEARCH_ALLOWED --> <!-- IF S_IP_SEARCH_ALLOWED -->
<dl> <dl>

View file

@ -29,7 +29,7 @@
<!-- IF U_ACP --><br /><strong><a href="{U_ACP}">{L_ACP}</a></strong><!-- ENDIF --> <!-- IF U_ACP --><br /><strong><a href="{U_ACP}">{L_ACP}</a></strong><!-- ENDIF -->
</div> </div>
<div id="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}"> <div id="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}" data-ajax-error-text-abort="{L_AJAX_ERROR_TEXT_ABORT}" data-ajax-error-text-timeout="{L_AJAX_ERROR_TEXT_TIMEOUT}" data-ajax-error-text-parsererror="{L_AJAX_ERROR_TEXT_PARSERERROR}">
<div id="darken">&nbsp;</div> <div id="darken">&nbsp;</div>
<div class="phpbb_alert" id="loadingalert"><h3>{L_LOADING}</h3><p>{L_PLEASE_WAIT}</p></div> <div class="phpbb_alert" id="loadingalert"><h3>{L_LOADING}</h3><p>{L_PLEASE_WAIT}</p></div>
</div> </div>
@ -53,6 +53,7 @@
<script type="text/javascript" src="{T_JQUERY_LINK}"></script> <script type="text/javascript" src="{T_JQUERY_LINK}"></script>
<!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> <!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF -->
<script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/forum_fn.js?assets_version={T_ASSETS_VERSION}"></script>
<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script> <script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- INCLUDEJS template/ajax.js --> <!-- INCLUDEJS template/ajax.js -->
{SCRIPTS} {SCRIPTS}

View file

@ -40,15 +40,6 @@
window.open(url.replace(/&amp;/g, '&'), '_phpbbprivmsg', 'height=225,resizable=yes,scrollbars=yes, width=400'); window.open(url.replace(/&amp;/g, '&'), '_phpbbprivmsg', 'height=225,resizable=yes,scrollbars=yes, width=400');
<!-- ENDIF --> <!-- ENDIF -->
/**
* Find a member
*/
function find_username(url)
{
popup(url, 760, 570, '_usersearch');
return false;
}
/** /**
* New function for handling multiple calls to window.onload and window.unload by pentapenguin * New function for handling multiple calls to window.onload and window.unload by pentapenguin
*/ */
@ -70,7 +61,6 @@
// ]]> // ]]>
</script> </script>
<script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/forum_fn.js?assets_version={T_ASSETS_VERSION}"></script>
<link href="{T_THEME_PATH}/print.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="print" title="printonly" /> <link href="{T_THEME_PATH}/print.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="print" title="printonly" />
<link href="{T_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" /> <link href="{T_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" />
@ -106,7 +96,7 @@
<div id="search-box"> <div id="search-box">
<form action="{U_SEARCH}" method="get" id="search"> <form action="{U_SEARCH}" method="get" id="search">
<fieldset> <fieldset>
<input name="keywords" id="keywords" type="text" maxlength="128" title="{L_SEARCH_KEYWORDS}" class="inputbox search" value="<!-- IF SEARCH_WORDS-->{SEARCH_WORDS}<!-- ELSE -->{L_SEARCH_MINI}<!-- ENDIF -->" onclick="if(this.value=='{LA_SEARCH_MINI}')this.value='';" onblur="if(this.value=='')this.value='{LA_SEARCH_MINI}';" /> <input name="keywords" id="keywords" type="search" maxlength="128" title="{L_SEARCH_KEYWORDS}" class="inputbox search" value="{SEARCH_WORDS}" placeholder="{L_SEARCH_MINI}" />
<input class="button2" value="{L_SEARCH}" type="submit" /><br /> <input class="button2" value="{L_SEARCH}" type="submit" /><br />
<a href="{U_SEARCH}" title="{L_SEARCH_ADV_EXPLAIN}">{L_SEARCH_ADV}</a> {S_SEARCH_HIDDEN_FIELDS} <a href="{U_SEARCH}" title="{L_SEARCH_ADV_EXPLAIN}">{L_SEARCH_ADV}</a> {S_SEARCH_HIDDEN_FIELDS}
</fieldset> </fieldset>
@ -137,8 +127,8 @@
<!-- IF not S_IS_BOT and S_USER_LOGGED_IN --> <!-- IF not S_IS_BOT and S_USER_LOGGED_IN -->
<ul class="linklist leftside"> <ul class="linklist leftside">
<!-- IF S_NOTIFICATIONS_DISPLAY --> <!-- IF S_NOTIFICATIONS_DISPLAY -->
<li> <li class="icon-notification">
[ <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button">{NOTIFICATIONS_COUNT}</a> ] &bull; <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button">{NOTIFICATIONS_COUNT}</a>
<div id="notification_list" class="notification_list"> <div id="notification_list" class="notification_list">
<div class="pointer"><div class="pointer_inner"></div></div> <div class="pointer"><div class="pointer_inner"></div></div>
<div class="header"> <div class="header">

View file

@ -1,9 +1,3 @@
<script type="text/javascript">
// <![CDATA[
onload_functions.push(apply_onkeypress_event);
// ]]>
</script>
<fieldset class="fields1"> <fieldset class="fields1">
<!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF --> <!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF -->
@ -250,7 +244,7 @@
<!-- IF S_TOPIC_TYPE_ANNOUNCE or S_TOPIC_TYPE_STICKY --> <!-- IF S_TOPIC_TYPE_ANNOUNCE or S_TOPIC_TYPE_STICKY -->
<dl> <dl>
<dt><label for="topic_time_limit">{L_STICK_TOPIC_FOR}{L_COLON}</label></dt> <dt><label for="topic_time_limit">{L_STICK_TOPIC_FOR}{L_COLON}</label></dt>
<dd><label for="topic_time_limit"><input type="text" name="topic_time_limit" id="topic_time_limit" size="3" maxlength="3" value="{TOPIC_TIME_LIMIT}" class="inputbox autowidth" /> {L_DAYS}</label></dd> <dd><label for="topic_time_limit"><input type="number" min="0" max="999" name="topic_time_limit" id="topic_time_limit" size="3" maxlength="3" value="{TOPIC_TIME_LIMIT}" class="inputbox autowidth" /> {L_DAYS}</label></dd>
<dd>{L_STICK_TOPIC_FOR_EXPLAIN}</dd> <dd>{L_STICK_TOPIC_FOR_EXPLAIN}</dd>
</dl> </dl>
<!-- ENDIF --> <!-- ENDIF -->

View file

@ -26,18 +26,18 @@
<dl> <dl>
<dt><label for="poll_max_options">{L_POLL_MAX_OPTIONS}{L_COLON}</label></dt> <dt><label for="poll_max_options">{L_POLL_MAX_OPTIONS}{L_COLON}</label></dt>
<dd><input type="text" name="poll_max_options" id="poll_max_options" size="3" maxlength="3" value="{POLL_MAX_OPTIONS}" class="inputbox autowidth" /></dd> <dd><input type="number" min="1" max="999" name="poll_max_options" id="poll_max_options" size="3" maxlength="3" value="{POLL_MAX_OPTIONS}" class="inputbox autowidth" /></dd>
<dd>{L_POLL_MAX_OPTIONS_EXPLAIN}</dd> <dd>{L_POLL_MAX_OPTIONS_EXPLAIN}</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="poll_length">{L_POLL_FOR}{L_COLON}</label></dt> <dt><label for="poll_length">{L_POLL_FOR}{L_COLON}</label></dt>
<dd><label for="poll_length"><input type="text" name="poll_length" id="poll_length" size="3" maxlength="3" value="{POLL_LENGTH}" class="inputbox autowidth" /> {L_DAYS}</label></dd> <dd><label for="poll_length"><input type="number" min="0" max="999" name="poll_length" id="poll_length" size="3" maxlength="3" value="{POLL_LENGTH}" class="inputbox autowidth" /> {L_DAYS}</label></dd>
<dd>{L_POLL_FOR_EXPLAIN}</dd> <dd>{L_POLL_FOR_EXPLAIN}</dd>
</dl> </dl>
<!-- IF S_POLL_VOTE_CHANGE --> <!-- IF S_POLL_VOTE_CHANGE -->
<hr class="dashed" /> <hr class="dashed" />
<dl> <dl>
<dt><label for="poll_vote_change">{L_POLL_VOTE_CHANGE}{L_COLON}</label></dt> <dt><label for="poll_vote_change">{L_POLL_VOTE_CHANGE}{L_COLON}</label></dt>
<dd><label for="poll_vote_change"><input type="checkbox" id="poll_vote_change" name="poll_vote_change"{VOTE_CHANGE_CHECKED} /> {L_POLL_VOTE_CHANGE_EXPLAIN}</label></dd> <dd><label for="poll_vote_change"><input type="checkbox" id="poll_vote_change" name="poll_vote_change"{VOTE_CHANGE_CHECKED} /> {L_POLL_VOTE_CHANGE_EXPLAIN}</label></dd>

View file

@ -19,13 +19,13 @@
<fieldset> <fieldset>
<dl> <dl>
<dt><label for="keywords">{L_SEARCH_KEYWORDS}{L_COLON}</label><br /><span>{L_SEARCH_KEYWORDS_EXPLAIN}</span></dt> <dt><label for="keywords">{L_SEARCH_KEYWORDS}{L_COLON}</label><br /><span>{L_SEARCH_KEYWORDS_EXPLAIN}</span></dt>
<dd><input type="text" class="inputbox" name="keywords" id="keywords" size="40" title="{L_SEARCH_KEYWORDS}" /></dd> <dd><input type="search" class="inputbox" name="keywords" id="keywords" size="40" title="{L_SEARCH_KEYWORDS}" /></dd>
<dd><label for="terms1"><input type="radio" name="terms" id="terms1" value="all" checked="checked" /> {L_SEARCH_ALL_TERMS}</label></dd> <dd><label for="terms1"><input type="radio" name="terms" id="terms1" value="all" checked="checked" /> {L_SEARCH_ALL_TERMS}</label></dd>
<dd><label for="terms2"><input type="radio" name="terms" id="terms2" value="any" /> {L_SEARCH_ANY_TERMS}</label></dd> <dd><label for="terms2"><input type="radio" name="terms" id="terms2" value="any" /> {L_SEARCH_ANY_TERMS}</label></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="author">{L_SEARCH_AUTHOR}{L_COLON}</label><br /><span>{L_SEARCH_AUTHOR_EXPLAIN}</span></dt> <dt><label for="author">{L_SEARCH_AUTHOR}{L_COLON}</label><br /><span>{L_SEARCH_AUTHOR_EXPLAIN}</span></dt>
<dd><input type="text" class="inputbox" name="author" id="author" size="40" title="{L_SEARCH_AUTHOR}" /></dd> <dd><input type="search" class="inputbox" name="author" id="author" size="40" title="{L_SEARCH_AUTHOR}" /></dd>
</dl> </dl>
</fieldset> </fieldset>

View file

@ -19,7 +19,7 @@
<!-- IF SEARCH_MATCHES --> <!-- IF SEARCH_MATCHES -->
<div class="search-box"> <div class="search-box">
<!-- IF SEARCH_IN_RESULTS --> <!-- IF SEARCH_IN_RESULTS -->
<label for="add_keywords">{L_SEARCH_IN_RESULTS}{L_COLON} <input type="text" name="add_keywords" id="add_keywords" value="" class="inputbox narrow" /></label> <label for="add_keywords">{L_SEARCH_IN_RESULTS}{L_COLON} <input type="search" name="add_keywords" id="add_keywords" value="" class="inputbox narrow" /></label>
<input class="button2" type="submit" name="submit" value="{L_SEARCH}" /> <input class="button2" type="submit" name="submit" value="{L_SEARCH}" />
<!-- ENDIF --> <!-- ENDIF -->
</div> </div>
@ -48,7 +48,7 @@
<ul class="topiclist"> <ul class="topiclist">
<li class="header"> <li class="header">
<dl class="icon"> <dl class="icon">
<dt>{L_TOPICS}</dt> <dt><div class="list-inner">{L_TOPICS}</div></dt>
<dd class="posts">{L_REPLIES}</dd> <dd class="posts">{L_REPLIES}</dd>
<dd class="views">{L_VIEWS}</dd> <dd class="views">{L_VIEWS}</dd>
<dd class="lastpost"><span>{L_LAST_POST}</span></dd> <dd class="lastpost"><span>{L_LAST_POST}</span></dd>
@ -61,25 +61,29 @@
<li class="row<!-- IF searchresults.S_ROW_COUNT is even --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF searchresults.S_ROW_COUNT is even --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl class="icon {searchresults.TOPIC_IMG_STYLE}"> <dl class="icon {searchresults.TOPIC_IMG_STYLE}">
<dt <!-- IF searchresults.TOPIC_ICON_IMG -->style="background-image: url({T_ICONS_PATH}{searchresults.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{searchresults.TOPIC_FOLDER_IMG_ALT}"> <dt <!-- IF searchresults.TOPIC_ICON_IMG -->style="background-image: url({T_ICONS_PATH}{searchresults.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{searchresults.TOPIC_FOLDER_IMG_ALT}">
<!-- IF searchresults.S_UNREAD_TOPIC --><a href="{searchresults.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --> <div class="list-inner">
<a href="{searchresults.U_VIEW_TOPIC}" class="topictitle">{searchresults.TOPIC_TITLE}</a> {searchresults.ATTACH_ICON_IMG}
<!-- IF searchresults.S_TOPIC_UNAPPROVED or searchresults.S_POSTS_UNAPPROVED --><a href="{searchresults.U_MCP_QUEUE}">{searchresults.UNAPPROVED_IMG}</a> <!-- ENDIF --> <!-- IF searchresults.S_UNREAD_TOPIC --><a href="{searchresults.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF -->
<!-- IF searchresults.S_TOPIC_REPORTED --><a href="{searchresults.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --><br /> <a href="{searchresults.U_VIEW_TOPIC}" class="topictitle">{searchresults.TOPIC_TITLE}</a> {searchresults.ATTACH_ICON_IMG}
<!-- IF .searchresults.pagination --> <!-- IF searchresults.S_TOPIC_UNAPPROVED or searchresults.S_POSTS_UNAPPROVED --><a href="{searchresults.U_MCP_QUEUE}">{searchresults.UNAPPROVED_IMG}</a> <!-- ENDIF -->
<div class="pagination"> <!-- IF searchresults.S_TOPIC_REPORTED --><a href="{searchresults.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --><br />
<ul> <!-- IF .searchresults.pagination -->
<!-- BEGIN pagination --> <div class="pagination">
<!-- IF searchresults.pagination.S_IS_PREV --> <ul>
<!-- ELSEIF searchresults.pagination.S_IS_CURRENT --><li class="active"><span>{searchresults.pagination.PAGE_NUMBER}</span></li> <!-- BEGIN pagination -->
<!-- ELSEIF searchresults.pagination.S_IS_ELLIPSIS --><li class="ellipsis"><span>{L_ELLIPSIS}</span></li> <!-- IF searchresults.pagination.S_IS_PREV -->
<!-- ELSEIF searchresults.pagination.S_IS_NEXT --> <!-- ELSEIF searchresults.pagination.S_IS_CURRENT --><li class="active"><span>{searchresults.pagination.PAGE_NUMBER}</span></li>
<!-- ELSE --><li><a href="{searchresults.pagination.PAGE_URL}">{searchresults.pagination.PAGE_NUMBER}</a></li> <!-- ELSEIF searchresults.pagination.S_IS_ELLIPSIS --><li class="ellipsis"><span>{L_ELLIPSIS}</span></li>
<!-- ENDIF --> <!-- ELSEIF searchresults.pagination.S_IS_NEXT -->
<!-- END pagination --> <!-- ELSE --><li><a href="{searchresults.pagination.PAGE_URL}">{searchresults.pagination.PAGE_NUMBER}</a></li>
</ul> <!-- ENDIF -->
<!-- END pagination -->
</ul>
</div>
<!-- ENDIF -->
{L_POST_BY_AUTHOR} {searchresults.TOPIC_AUTHOR_FULL} &raquo; {searchresults.FIRST_POST_TIME} &raquo; {L_IN} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a>
</div> </div>
<!-- ENDIF -->
{L_POST_BY_AUTHOR} {searchresults.TOPIC_AUTHOR_FULL} &raquo; {searchresults.FIRST_POST_TIME} &raquo; {L_IN} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a>
</dt> </dt>
<dd class="posts">{searchresults.TOPIC_REPLIES}</dd> <dd class="posts">{searchresults.TOPIC_REPLIES}</dd>
<dd class="views">{searchresults.TOPIC_VIEWS}</dd> <dd class="views">{searchresults.TOPIC_VIEWS}</dd>

View file

@ -8,6 +8,7 @@
<script type="text/javascript" src="{T_JQUERY_LINK}"></script> <script type="text/javascript" src="{T_JQUERY_LINK}"></script>
<!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> <!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF -->
<script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/forum_fn.js?assets_version={T_ASSETS_VERSION}"></script>
{SCRIPTS} {SCRIPTS}
<!-- EVENT simple_footer_after --> <!-- EVENT simple_footer_after -->

View file

@ -40,7 +40,6 @@
// ]]> // ]]>
</script> </script>
<script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/forum_fn.js?assets_version={T_ASSETS_VERSION}"></script>
<link href="{T_THEME_PATH}/print.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="print" title="printonly" /> <link href="{T_THEME_PATH}/print.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="print" title="printonly" />
<link href="{T_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" /> <link href="{T_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" />

View file

@ -24,7 +24,7 @@
<ul class="topiclist"> <ul class="topiclist">
<li class="header"> <li class="header">
<dl> <dl>
<dt style="width: 40%"><a href="{U_SORT_FILENAME}">{L_FILENAME}</a></dt> <dt><div class="list-inner"><a href="{U_SORT_FILENAME}">{L_FILENAME}</a></div></dt>
<dd class="extra"><a href="{U_SORT_DOWNLOADS}">{L_DOWNLOADS}</a></dd> <dd class="extra"><a href="{U_SORT_DOWNLOADS}">{L_DOWNLOADS}</a></dd>
<dd class="time"><span><a href="{U_SORT_POST_TIME}">{L_POST_TIME}</a></span></dd> <dd class="time"><span><a href="{U_SORT_POST_TIME}">{L_POST_TIME}</a></span></dd>
<dd class="mark">{L_MARK}</dd> <dd class="mark">{L_MARK}</dd>
@ -36,8 +36,12 @@
<!-- BEGIN attachrow --> <!-- BEGIN attachrow -->
<li class="row<!-- IF attachrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF attachrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<dt style="width: 40%"><a href="{attachrow.U_VIEW_ATTACHMENT}" class="topictitle">{attachrow.FILENAME}</a> ({attachrow.SIZE})<br /> <dt>
<!-- IF attachrow.S_IN_MESSAGE -->{L_PM}{L_COLON} <!-- ELSE -->{L_TOPIC}{L_COLON} <!-- ENDIF --><a href="{attachrow.U_VIEW_TOPIC}">{attachrow.TOPIC_TITLE}</a></dt> <div class="list-inner">
<a href="{attachrow.U_VIEW_ATTACHMENT}" class="topictitle">{attachrow.FILENAME}</a> ({attachrow.SIZE})<br />
<!-- IF attachrow.S_IN_MESSAGE -->{L_PM}{L_COLON} <!-- ELSE -->{L_TOPIC}{L_COLON} <!-- ENDIF --><a href="{attachrow.U_VIEW_TOPIC}">{attachrow.TOPIC_TITLE}</a>
</div>
</dt>
<dd class="extra">{attachrow.DOWNLOAD_COUNT}</dd> <dd class="extra">{attachrow.DOWNLOAD_COUNT}</dd>
<dd class="time"><span>{attachrow.POST_TIME}</span></dd> <dd class="time"><span>{attachrow.POST_TIME}</span></dd>
<dd class="mark"><input type="checkbox" name="attachment[{attachrow.ATTACH_ID}]" value="1" /></dd> <dd class="mark"><input type="checkbox" name="attachment[{attachrow.ATTACH_ID}]" value="1" /></dd>

View file

@ -14,7 +14,7 @@ onload_functions.push(function() {
<dl> <dl>
<dt><label for="avatar_gravatar_email">{L_GRAVATAR_AVATAR_EMAIL}{L_COLON}</label><br /><span>{L_GRAVATAR_AVATAR_EMAIL_EXPLAIN}</span></dt> <dt><label for="avatar_gravatar_email">{L_GRAVATAR_AVATAR_EMAIL}{L_COLON}</label><br /><span>{L_GRAVATAR_AVATAR_EMAIL_EXPLAIN}</span></dt>
<dd><input type="text" name="avatar_gravatar_email" id="avatar_gravatar_email" value="{AVATAR_GRAVATAR_EMAIL}" class="inputbox" /></dd> <dd><input type="email" name="avatar_gravatar_email" id="avatar_gravatar_email" value="{AVATAR_GRAVATAR_EMAIL}" class="inputbox" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="avatar_gravatar_width">{L_GRAVATAR_AVATAR_SIZE}{L_COLON}</label><br /><span>{L_GRAVATAR_AVATAR_SIZE_EXPLAIN}</span></dt> <dt><label for="avatar_gravatar_width">{L_GRAVATAR_AVATAR_SIZE}{L_COLON}</label><br /><span>{L_GRAVATAR_AVATAR_SIZE_EXPLAIN}</span></dt>

View file

@ -14,7 +14,7 @@ onload_functions.push(function() {
<dl> <dl>
<dt><label for="avatar_remote_url">{L_LINK_REMOTE_AVATAR}{L_COLON}</label><br /><span>{L_LINK_REMOTE_AVATAR_EXPLAIN}</span></dt> <dt><label for="avatar_remote_url">{L_LINK_REMOTE_AVATAR}{L_COLON}</label><br /><span>{L_LINK_REMOTE_AVATAR_EXPLAIN}</span></dt>
<dd><input type="text" name="avatar_remote_url" id="avatar_remote_url" value="{AVATAR_REMOTE_URL}" class="inputbox" /></dd> <dd><input type="url" name="avatar_remote_url" id="avatar_remote_url" value="{AVATAR_REMOTE_URL}" class="inputbox" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="avatar_remote_width">{L_LINK_REMOTE_SIZE}{L_COLON}</label><br /><span>{L_LINK_REMOTE_SIZE_EXPLAIN}</span></dt> <dt><label for="avatar_remote_width">{L_LINK_REMOTE_SIZE}{L_COLON}</label><br /><span>{L_LINK_REMOTE_SIZE_EXPLAIN}</span></dt>

View file

@ -6,6 +6,6 @@
<!-- IF S_UPLOAD_AVATAR_URL --> <!-- IF S_UPLOAD_AVATAR_URL -->
<dl> <dl>
<dt><label for="avatar_upload_url">{L_UPLOAD_AVATAR_URL}{L_COLON}</label><br /><span>{L_UPLOAD_AVATAR_URL_EXPLAIN}</span></dt> <dt><label for="avatar_upload_url">{L_UPLOAD_AVATAR_URL}{L_COLON}</label><br /><span>{L_UPLOAD_AVATAR_URL_EXPLAIN}</span></dt>
<dd><input type="text" name="avatar_upload_url" id="avatar_upload_url" value="" class="inputbox" /></dd> <dd><input type="url" name="avatar_upload_url" id="avatar_upload_url" value="" class="inputbox" /></dd>
</dl> </dl>
<!-- ENDIF --> <!-- ENDIF -->

View file

@ -6,19 +6,18 @@
<div class="panel"> <div class="panel">
<div class="inner"> <div class="inner">
<!-- IF S_ERROR -->
<fieldset>
<p class="error">{ERROR_MSG}</p>
</fieldset>
<!-- ENDIF -->
<p>{L_GROUPS_EXPLAIN}</p> <p>{L_GROUPS_EXPLAIN}</p>
<!-- IF S_EDIT --> <!-- IF S_EDIT -->
<h3>{L_GROUP_DETAILS}</h3> <h3>{L_GROUP_DETAILS}</h3>
<!-- IF S_ERROR -->
<div class="errorbox">
<h3>{L_WARNING}</h3>
<p>{ERROR_MSG}</p>
</div>
<!-- ENDIF -->
<fieldset> <fieldset>
<dl> <dl>
<dt><label for="group_name">{L_GROUP_NAME}{L_COLON}</label></dt> <dt><label for="group_name">{L_GROUP_NAME}{L_COLON}</label></dt>
@ -55,7 +54,7 @@
<fieldset> <fieldset>
<dl> <dl>
<dt><label for="group_colour">{L_GROUP_COLOR}{L_COLON}</label><br /><span>{L_GROUP_COLOR_EXPLAIN}</span></dt> <dt><label for="group_colour">{L_GROUP_COLOR}{L_COLON}</label><br /><span>{L_GROUP_COLOR_EXPLAIN}</span></dt>
<dd><input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="7" maxlength="7" class="inputbox narrow" /> <span style="background-color: {GROUP_COLOUR};">&nbsp;&nbsp;&nbsp;</span> [ <a href="{U_SWATCH}" onclick="popup(this.href, 636, 150, '_swatch'); return false;">{L_COLOUR_SWATCH}</a> ]</dd> <dd><input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="6" maxlength="6" class="inputbox narrow" /> <span style="background-color: {GROUP_COLOUR};">&nbsp;&nbsp;&nbsp;</span> [ <a href="{U_SWATCH}" onclick="popup(this.href, 636, 150, '_swatch'); return false;">{L_COLOUR_SWATCH}</a> ]</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="group_rank">{L_GROUP_RANK}{L_COLON}</label></dt> <dt><label for="group_rank">{L_GROUP_RANK}{L_COLON}</label></dt>
@ -207,21 +206,25 @@
<!-- ELSE --> <!-- ELSE -->
<!-- IF .leader --> <!-- IF .leader -->
<ul class="topiclist"> <ul class="topiclist two-long-columns">
<li class="header"> <li class="header">
<dl> <dl>
<dt>{L_GROUP_LEADER}</dt> <dt><div class="list-inner">{L_GROUP_LEADER}</div></dt>
<dd class="info"><span>{L_OPTIONS}</span></dd> <dd class="info"><span>{L_OPTIONS}</span></dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist two-long-columns">
<!-- BEGIN leader --> <!-- BEGIN leader -->
<li class="row<!-- IF attachrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF attachrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<dt><a href="{leader.U_EDIT}" class="topictitle"<!-- IF leader.GROUP_COLOUR --> style="color: #{leader.GROUP_COLOUR};"<!-- ENDIF -->>{leader.GROUP_NAME}</a> <dt>
<!-- IF leader.GROUP_DESC --><br />{leader.GROUP_DESC}<!-- ENDIF --></dt> <div class="list-inner">
<a href="{leader.U_EDIT}" class="topictitle"<!-- IF leader.GROUP_COLOUR --> style="color: #{leader.GROUP_COLOUR};"<!-- ENDIF -->>{leader.GROUP_NAME}</a>
<!-- IF leader.GROUP_DESC --><br />{leader.GROUP_DESC}<!-- ENDIF -->
</div>
</dt>
<dd class="option"><span><a href="{leader.U_EDIT}" >{L_EDIT}</a></span></dd> <dd class="option"><span><a href="{leader.U_EDIT}" >{L_EDIT}</a></span></dd>
<dd class="option"><span><a href="{leader.U_LIST}">{L_GROUP_LIST}</a></span></dd> <dd class="option"><span><a href="{leader.U_LIST}">{L_GROUP_LIST}</a></span></dd>
</dl> </dl>

View file

@ -10,15 +10,15 @@
<p>{L_GROUPS_EXPLAIN}</p> <p>{L_GROUPS_EXPLAIN}</p>
<!-- DEFINE $SHOW_BUTTONS = 0 --> <!-- DEFINE $SHOW_BUTTONS = 0 -->
<!-- IF .leader --> <!-- IF .leader -->
<ul class="topiclist"> <ul class="topiclist two-columns">
<li class="header"> <li class="header">
<dl> <dl>
<dt>{L_GROUP_LEADER}</dt> <dt><div class="list-inner">{L_GROUP_LEADER}</div></dt>
<dd class="mark">{L_SELECT}</dd> <dd class="mark">{L_SELECT}</dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist two-columns">
<!-- BEGIN leader --> <!-- BEGIN leader -->
<!-- IF not leader.GROUP_SPECIAL --> <!-- IF not leader.GROUP_SPECIAL -->
@ -26,10 +26,13 @@
<!-- ENDIF --> <!-- ENDIF -->
<li class="row<!-- IF leader.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF leader.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<dt><!-- IF S_CHANGE_DEFAULT --><input title="{L_CHANGE_DEFAULT_GROUP}" type="radio" name="default"<!-- IF leader.S_GROUP_DEFAULT --> checked="checked"<!-- ENDIF --> value="{leader.GROUP_ID}" /> <!-- ENDIF --> <dt>
<a href="{leader.U_VIEW_GROUP}" class="forumtitle"<!-- IF leader.GROUP_COLOUR --> style="color:#{leader.GROUP_COLOUR}"<!-- ENDIF -->>{leader.GROUP_NAME}</a> <div class="list-inner">
<!-- IF leader.GROUP_DESC --><br />{leader.GROUP_DESC}<!-- ENDIF --> <!-- IF S_CHANGE_DEFAULT --><input title="{L_CHANGE_DEFAULT_GROUP}" type="radio" name="default"<!-- IF leader.S_GROUP_DEFAULT --> checked="checked"<!-- ENDIF --> value="{leader.GROUP_ID}" /> <!-- ENDIF -->
<!-- IF not leader.GROUP_SPECIAL --><br /><i>{leader.GROUP_STATUS}</i><!-- ENDIF --> <a href="{leader.U_VIEW_GROUP}" class="forumtitle"<!-- IF leader.GROUP_COLOUR --> style="color:#{leader.GROUP_COLOUR}"<!-- ENDIF -->>{leader.GROUP_NAME}</a>
<!-- IF leader.GROUP_DESC --><br />{leader.GROUP_DESC}<!-- ENDIF -->
<!-- IF not leader.GROUP_SPECIAL --><br /><i>{leader.GROUP_STATUS}</i><!-- ENDIF -->
</div>
</dt> </dt>
<dd class="mark"><input type="radio" name="selected" value="{leader.GROUP_ID}" <!-- IF leader.GROUP_SPECIAL -->disabled="disabled"<!-- ENDIF --> /></dd> <dd class="mark"><input type="radio" name="selected" value="{leader.GROUP_ID}" <!-- IF leader.GROUP_SPECIAL -->disabled="disabled"<!-- ENDIF --> /></dd>
</dl> </dl>
@ -39,15 +42,15 @@
<!-- ENDIF --> <!-- ENDIF -->
<!-- IF .member --> <!-- IF .member -->
<ul class="topiclist"> <ul class="topiclist two-columns">
<li class="header"> <li class="header">
<dl> <dl>
<dt>{L_GROUP_MEMBER}</dt> <dt><div class="list-inner">{L_GROUP_MEMBER}</div></dt>
<dd class="mark">{L_SELECT}</dd> <dd class="mark">{L_SELECT}</dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist two-columns">
<!-- BEGIN member --> <!-- BEGIN member -->
<!-- IF not member.GROUP_SPECIAL --> <!-- IF not member.GROUP_SPECIAL -->
@ -55,10 +58,13 @@
<!-- ENDIF --> <!-- ENDIF -->
<li class="row<!-- IF member.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF member.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<dt><!-- IF S_CHANGE_DEFAULT --><input title="{L_CHANGE_DEFAULT_GROUP}" type="radio" name="default"<!-- IF member.S_GROUP_DEFAULT --> checked="checked"<!-- ENDIF --> value="{member.GROUP_ID}" /> <!-- ENDIF --> <dt>
<a href="{member.U_VIEW_GROUP}" class="forumtitle"<!-- IF member.GROUP_COLOUR --> style="color:#{member.GROUP_COLOUR}"<!-- ENDIF -->>{member.GROUP_NAME}</a> <div class="list-inner">
<!-- IF member.GROUP_DESC --><br />{member.GROUP_DESC}<!-- ENDIF --> <!-- IF S_CHANGE_DEFAULT --><input title="{L_CHANGE_DEFAULT_GROUP}" type="radio" name="default"<!-- IF member.S_GROUP_DEFAULT --> checked="checked"<!-- ENDIF --> value="{member.GROUP_ID}" /> <!-- ENDIF -->
<!-- IF not member.GROUP_SPECIAL --><br /><i>{member.GROUP_STATUS}</i><!-- ENDIF --> <a href="{member.U_VIEW_GROUP}" class="forumtitle"<!-- IF member.GROUP_COLOUR --> style="color:#{member.GROUP_COLOUR}"<!-- ENDIF -->>{member.GROUP_NAME}</a>
<!-- IF member.GROUP_DESC --><br />{member.GROUP_DESC}<!-- ENDIF -->
<!-- IF not member.GROUP_SPECIAL --><br /><i>{member.GROUP_STATUS}</i><!-- ENDIF -->
</div>
</dt> </dt>
<dd class="mark"><input type="radio" name="selected" value="{member.GROUP_ID}" <!-- IF member.GROUP_SPECIAL -->disabled="disabled"<!-- ENDIF --> /></dd> <dd class="mark"><input type="radio" name="selected" value="{member.GROUP_ID}" <!-- IF member.GROUP_SPECIAL -->disabled="disabled"<!-- ENDIF --> /></dd>
</dl> </dl>
@ -72,15 +78,15 @@
<!-- IF .pending --> <!-- IF .pending -->
<div class="panel"> <div class="panel">
<div class="inner"> <div class="inner">
<ul class="topiclist"> <ul class="topiclist two-columns">
<li class="header"> <li class="header">
<dl> <dl>
<dt>{L_GROUP_PENDING}</dt> <dt><div class="list-inner">{L_GROUP_PENDING}</div></dt>
<dd class="mark">{L_SELECT}</dd> <dd class="mark">{L_SELECT}</dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist two-columns">
<!-- BEGIN pending --> <!-- BEGIN pending -->
<!-- IF not pending.GROUP_SPECIAL --> <!-- IF not pending.GROUP_SPECIAL -->
@ -89,9 +95,11 @@
<li class="row<!-- IF pending.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF pending.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<dt> <dt>
<a href="{pending.U_VIEW_GROUP}" class="forumtitle"<!-- IF pending.GROUP_COLOUR --> style="color:#{pending.GROUP_COLOUR}"<!-- ENDIF -->>{pending.GROUP_NAME}</a> <div class="list-inner">
<!-- IF pending.GROUP_DESC --><br />{pending.GROUP_DESC}<!-- ENDIF --> <a href="{pending.U_VIEW_GROUP}" class="forumtitle"<!-- IF pending.GROUP_COLOUR --> style="color:#{pending.GROUP_COLOUR}"<!-- ENDIF -->>{pending.GROUP_NAME}</a>
<!-- IF not pending.GROUP_SPECIAL --><br /><i>{pending.GROUP_STATUS}</i><!-- ENDIF --> <!-- IF pending.GROUP_DESC --><br />{pending.GROUP_DESC}<!-- ENDIF -->
<!-- IF not pending.GROUP_SPECIAL --><br /><i>{pending.GROUP_STATUS}</i><!-- ENDIF -->
</div>
</dt> </dt>
<dd class="mark"><input type="radio" name="selected" value="{pending.GROUP_ID}" <!-- IF pending.GROUP_SPECIAL -->disabled="disabled"<!-- ENDIF --> /></dd> <dd class="mark"><input type="radio" name="selected" value="{pending.GROUP_ID}" <!-- IF pending.GROUP_SPECIAL -->disabled="disabled"<!-- ENDIF --> /></dd>
</dl> </dl>
@ -104,15 +112,15 @@
<!-- IF .nonmember --> <!-- IF .nonmember -->
<div class="panel"> <div class="panel">
<div class="inner"> <div class="inner">
<ul class="topiclist"> <ul class="topiclist two-columns">
<li class="header"> <li class="header">
<dl> <dl>
<dt>{L_GROUP_NONMEMBER}</dt> <dt><div class="list-inner">{L_GROUP_NONMEMBER}</div></dt>
<dd class="mark">{L_SELECT}</dd> <dd class="mark">{L_SELECT}</dd>
</dl> </dl>
</li> </li>
</ul> </ul>
<ul class="topiclist cplist"> <ul class="topiclist cplist two-columns">
<!-- BEGIN nonmember --> <!-- BEGIN nonmember -->
<!-- IF nonmember.S_CAN_JOIN --> <!-- IF nonmember.S_CAN_JOIN -->
@ -121,9 +129,11 @@
<li class="row<!-- IF nonmember.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <li class="row<!-- IF nonmember.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl> <dl>
<dt> <dt>
<a href="{nonmember.U_VIEW_GROUP}" class="forumtitle"<!-- IF nonmember.GROUP_COLOUR --> style="color:#{nonmember.GROUP_COLOUR}"<!-- ENDIF -->>{nonmember.GROUP_NAME}</a> <div class="list-inner">
<!-- IF nonmember.GROUP_DESC --><br />{nonmember.GROUP_DESC}<!-- ENDIF --> <a href="{nonmember.U_VIEW_GROUP}" class="forumtitle"<!-- IF nonmember.GROUP_COLOUR --> style="color:#{nonmember.GROUP_COLOUR}"<!-- ENDIF -->>{nonmember.GROUP_NAME}</a>
<!-- IF not nonmember.GROUP_SPECIAL --><br /><i>{nonmember.GROUP_STATUS}</i><!-- ENDIF --> <!-- IF nonmember.GROUP_DESC --><br />{nonmember.GROUP_DESC}<!-- ENDIF -->
<!-- IF not nonmember.GROUP_SPECIAL --><br /><i>{nonmember.GROUP_STATUS}</i><!-- ENDIF -->
</div>
</dt> </dt>
<dd class="mark"><input type="radio" name="selected" value="{nonmember.GROUP_ID}" <!-- IF not nonmember.S_CAN_JOIN -->disabled="disabled"<!-- ENDIF --> /></dd> <dd class="mark"><input type="radio" name="selected" value="{nonmember.GROUP_ID}" <!-- IF not nonmember.S_CAN_JOIN -->disabled="disabled"<!-- ENDIF --> /></dd>
</dl> </dl>

Some files were not shown because too many files have changed in this diff Show more