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"
- travis/install-php-extensions.sh
- cd phpBB
- php ../composer.phar install --dev
- php ../composer.phar install --dev --no-interaction --prefer-source
- cd ..
- 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', '');
// Set custom style for admin area
$phpbb_style->set_ext_dir_prefix('adm/');
$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_TEMPLATE_PATH', $phpbb_admin_path . 'style');

View file

@ -196,7 +196,7 @@
</dl>
<dl>
<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>
<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>{orphan.FILETIME}</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="delete[{orphan.ATTACH_ID}]" /></td>
</tr>

View file

@ -1,11 +1,11 @@
<dl>
<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>
<dt><label for="avatar_gravatar_width">{L_GRAVATAR_AVATAR_SIZE}{L_COLON}</label><br /><span>{L_GRAVATAR_AVATAR_SIZE_EXPLAIN}</span></dt>
<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="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_width" id="avatar_gravatar_width" size="3" value="{AVATAR_GRAVATAR_WIDTH}" class="inputbox autowidth" /> {L_PIXEL} &times;&nbsp;
<input type="number" name="avatar_gravatar_height" id="avatar_gravatar_height" size="3" value="{AVATAR_GRAVATAR_HEIGHT}" class="inputbox autowidth" /> {L_PIXEL}
</dd>
</dl>

View file

@ -1,11 +1,11 @@
<dl>
<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>
<dt><label for="avatar_remote_width">{L_LINK_REMOTE_SIZE}{L_COLON}</label><br /><span>{L_LINK_REMOTE_SIZE_EXPLAIN}</span></dt>
<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="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_width" id="avatar_remote_width" size="3" value="{AVATAR_REMOTE_WIDTH}" class="inputbox autowidth" /> {L_PIXEL} &times;&nbsp;
<input type="number" name="avatar_remote_height" id="avatar_remote_height" size="3" value="{AVATAR_REMOTE_HEIGHT}" class="inputbox autowidth" /> {L_PIXEL}
</dd>
</dl>

View file

@ -6,6 +6,6 @@
<!-- IF S_UPLOAD_AVATAR_URL -->
<dl>
<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>
<!-- ENDIF -->

View file

@ -19,11 +19,11 @@
</dl>
<dl>
<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>
<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>
<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>
<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>
<!-- EVENT acp_forums_normal_settings_append -->
</fieldset>
@ -253,15 +253,15 @@
</dl>
<dl>
<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>
<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>
<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>
<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>
<dl>
<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>
<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>
<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="emotion[{items.IMG}]" value="{items.EMOTION}" size="10" maxlength="50" /></td>
<!-- ENDIF -->
<td><input class="text post" type="text" 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="width[{items.IMG}]" value="{items.WIDTH}" /></td>
<td><input class="text post" type="number" size="3" name="height[{items.IMG}]" value="{items.HEIGHT}" /></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}');"/>
<!-- 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><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" 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_width" id="add_width" value="{WIDTH}" /></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><select id="order_add_order" name="add_order">
<optgroup id="order_disp_add_order" label="{L_DISPLAY_POSTING}">{S_ADD_ORDER_LIST_DISPLAY}</optgroup>

View file

@ -53,7 +53,7 @@
</table>
<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" />
</fieldset>

View file

@ -31,7 +31,7 @@
</dl>
<dl>
<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>
<dt><label for="jab_username">{L_JAB_USERNAME}{L_COLON}</label><br /><span>{L_JAB_USERNAME_EXPLAIN}</span></dt>
@ -50,7 +50,7 @@
<!-- ENDIF -->
<dl>
<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>
</fieldset>

View file

@ -73,11 +73,11 @@
<legend>{L_FORUM_PRUNE}</legend>
<dl>
<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>
<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>
<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>
<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>
<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>
<!-- IF S_GROUP_LIST -->
<dl>

View file

@ -41,7 +41,7 @@
<!-- IF S_SPECIAL_RANK --><div id="posts" style="display: none;"><!-- ELSE --><div id="posts"><!-- ENDIF -->
<dl>
<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>
</div>

View file

@ -18,11 +18,11 @@
</dl>
<dl>
<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>
<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>
<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>
<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>
<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>
<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>
</fieldset>

View file

@ -43,7 +43,7 @@
</dl>
<dl>
<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>
<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>
<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>
<dt><label for="yim">{L_UCP_YIM}{L_COLON}</label></dt>
@ -20,11 +20,11 @@
</dl>
<dl>
<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>
<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>
<dt><label for="location">{L_LOCATION}{L_COLON}</label></dt>
@ -38,7 +38,7 @@
<dt><label for="interests">{L_INTERESTS}{L_COLON}</label></dt>
<dd><textarea id="interests" name="interests" rows="3" cols="30">{INTERESTS}</textarea></dd>
</dl>
<dl>
<dl>
<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>
</dl>
@ -48,7 +48,7 @@
<fieldset>
<legend>{L_USER_CUSTOM_PROFILE_FIELDS}</legend>
<!-- 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>
<dd>{profile_fields.FIELD}</dd>
<!-- 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

View file

@ -20,11 +20,11 @@
</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>
<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>
<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>
<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}
<!-- 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 class="jalert" id="loadingalert"><h3>{L_LOADING}</h3><p>{L_PLEASE_WAIT}</p></div>
</div>

View file

@ -252,9 +252,24 @@ phpbb.ajaxify = function(options) {
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.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);
});
/**
* 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

View file

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

View file

@ -1317,16 +1317,20 @@ function get_schema_struct()
$schema_data['phpbb_notification_types'] = 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),
),
'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(
'COLUMNS' => array(
'notification_id' => array('UINT', NULL, 'auto_increment'),
'item_type' => array('VCHAR:255', ''),
'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),
@ -1336,7 +1340,7 @@ function get_schema_struct()
),
'PRIMARY_KEY' => 'notification_id',
'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')),
),
);
@ -1814,7 +1818,7 @@ function get_schema_struct()
);
$schema_data['phpbb_user_notifications'] = array(
'COLUMNS' => array(
'COLUMNS' => array(
'item_type' => array('VCHAR:255', ''),
'item_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)
EXreaction (Nathan Guse)
igorw (Igor Wiedler)
dhruv.goel92 (Dhruv Goel)
imkingdavid (David King)
nickvergessen (Joas Schilling)
Oleg (Oleg Pudeyev)
Contributions by: leviatan21 (Gabriel Vazquez)
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]
GrahamJE (Graham Eames) [09/2005 - 11/2006]
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]
TerraFrost (Jim Wigginton) [04/2009 - 01/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),
'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_attachments' => array('lang' => 'MAX_ATTACHMENTS', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => false),
'max_attachments_pm' => array('lang' => 'MAX_ATTACHMENTS_PM', '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:0:999', 'type' => 'number:0:999', 'explain' => false),
'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_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,
'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_max_thumb_width' => array('lang' => 'MAX_THUMB_WIDTH', 'validate' => 'int', 'type' => 'text:7:15', '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_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: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_max' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', '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_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:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
)
);
@ -1203,8 +1203,8 @@ class acp_attachments
// Just get the files
$sql = 'SELECT a.*, u.username, u.user_colour, t.topic_title
FROM ' . ATTACHMENTS_TABLE . ' a
LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = a.poster_id)
FROM ' . ATTACHMENTS_TABLE . ' a
LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = a.poster_id)
LEFT JOIN ' . TOPICS_TABLE . " t ON (a.topic_id = t.topic_id)
WHERE a.is_orphan = 0
$limit_filetime
@ -1670,7 +1670,8 @@ class acp_attachments
$size_var = $filesize['si_identifier'];
$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',
'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_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),
'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),
@ -65,7 +65,7 @@ class acp_board
'override_user_style' => array('lang' => 'OVERRIDE_STYLE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'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',
)
@ -136,8 +136,8 @@ class acp_board
'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),
'avatar_min' => array('lang' => 'MIN_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: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:0', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
)
);
@ -154,11 +154,11 @@ class acp_board
'vars' => array(
'legend1' => 'GENERAL_SETTINGS',
'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_msgs' => array('lang' => 'BOXES_LIMIT', '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: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),
'pm_edit_time' => array('lang' => 'PM_EDIT_TIME', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'pm_max_recipients' => array('lang' => 'PM_MAX_RECIPIENTS', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true),
'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:99999', 'type' => 'number:0:99999', 'explain' => true),
'legend2' => 'GENERAL_OPTIONS',
'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',
'bump_type' => false,
'edit_time' => array('lang' => 'EDIT_TIME', 'validate' => 'int:0', 'type' => 'text:5:5', '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']),
'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: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),
'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),
'topics_per_page' => array('lang' => 'TOPICS_PER_PAGE', 'validate' => 'int:1', 'type' => 'text:3:4', 'explain' => false),
'posts_per_page' => array('lang' => 'POSTS_PER_PAGE', 'validate' => 'int:1', 'type' => 'text:3:4', 'explain' => false),
'smilies_per_page' => array('lang' => 'SMILIES_PER_PAGE', 'validate' => 'int:1', 'type' => 'text:3:4', 'explain' => false),
'hot_threshold' => array('lang' => 'HOT_THRESHOLD', 'validate' => 'int:0', 'type' => 'text:3:4', 'explain' => true),
'max_poll_options' => array('lang' => 'MAX_POLL_OPTIONS', 'validate' => 'int:2:127', 'type' => 'text:4:4', 'explain' => false),
'max_post_chars' => array('lang' => 'CHAR_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:6', 'explain' => true),
'min_post_chars' => array('lang' => 'MIN_CHAR_LIMIT', 'validate' => 'int:1', 'type' => 'text:4:6', 'explain' => true),
'max_post_smilies' => array('lang' => 'SMILIES_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true),
'max_post_urls' => array('lang' => 'MAX_POST_URLS', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true),
'max_post_font_size' => array('lang' => 'MAX_POST_FONT_SIZE', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' %'),
'max_quote_depth' => array('lang' => 'QUOTE_DEPTH_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', '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_height' => array('lang' => 'MAX_POST_IMG_HEIGHT', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'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:9999', 'type' => 'number:1:9999', '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:9999', 'type' => 'number:0:9999', 'explain' => true),
'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:999999', 'type' => 'number:0:999999', '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:9999', 'type' => 'number:0:9999', '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:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' %'),
'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:9999', 'type' => 'number:0:9999', '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',
)
@ -232,12 +232,12 @@ class acp_board
'allow_sig_links' => array('lang' => 'ALLOW_SIG_LINKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend2' => 'GENERAL_SETTINGS',
'max_sig_chars' => array('lang' => 'MAX_SIG_LENGTH', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true),
'max_sig_urls' => array('lang' => 'MAX_SIG_URLS', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true),
'max_sig_font_size' => array('lang' => 'MAX_SIG_FONT_SIZE', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' %'),
'max_sig_smilies' => array('lang' => 'MAX_SIG_SMILIES', 'validate' => 'int:0', 'type' => 'text:5:4', '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_height' => array('lang' => 'MAX_SIG_IMG_HEIGHT', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'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:9999', 'type' => 'number:0:9999', 'explain' => true),
'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:9999', 'type' => 'number:0:9999', 'explain' => true),
'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:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'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,),
'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),
'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),
'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),
'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',
'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),
'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_reg_attempts' => array('lang' => 'REG_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', '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:9999', 'type' => 'number:0:9999', 'explain' => true),
'legend3' => 'COPPA',
'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),
'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_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 ),
'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_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),
@ -324,10 +324,10 @@ class acp_board
'title' => 'ACP_LOAD_SETTINGS',
'vars' => array(
'legend1' => 'GENERAL_SETTINGS',
'limit_load' => array('lang' => 'LIMIT_LOAD', 'validate' => 'string', 'type' => 'text:4:4', 'explain' => true),
'session_length' => array('lang' => 'SESSION_LENGTH', 'validate' => 'int:60', 'type' => 'text:5:10', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
'active_sessions' => array('lang' => 'LIMIT_SESSIONS', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true),
'load_online_time' => array('lang' => 'ONLINE_LENGTH', 'validate' => 'int:0', 'type' => 'text:4:3', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'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:9999999999', 'type' => 'number:60:9999999999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
'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:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'legend2' => 'GENERAL_OPTIONS',
'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),
'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_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),
'legend4' => 'ACP_SUBMIT_CHANGES',
@ -399,7 +399,7 @@ class acp_board
'legend1' => 'ACP_SECURITY_SETTINGS',
'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),
'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),
'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),
@ -409,13 +409,13 @@ class acp_board
'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),
'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']),
'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true),
'ip_login_limit_max' => array('lang' => 'IP_LOGIN_LIMIT_MAX', 'validate' => 'int:0', 'type' => 'text:3:3', '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']),
'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:999', 'type' => 'number:0:999', '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: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),
'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),
)
@ -430,16 +430,16 @@ class acp_board
'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),
'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),
'board_contact' => array('lang' => 'CONTACT_EMAIL', 'validate' => 'email', 'type' => 'text:25:100', 'explain' => true),
'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'email', 'type' => 'text:25:100', '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' => 'email: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_hide_emails' => array('lang' => 'BOARD_HIDE_EMAILS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend2' => 'SMTP_SETTINGS',
'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_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_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),
@ -805,7 +805,7 @@ class acp_board
{
$act_ary['ACC_USER'] = USER_ACTIVATION_SELF;
$act_ary['ACC_ADMIN'] = USER_ACTIVATION_ADMIN;
}
}
$act_options = '';
foreach ($act_ary as $key => $value)
@ -824,7 +824,7 @@ class acp_board
{
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;
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');
$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
if ($request->is_set_post('cancel'))
{
@ -105,11 +109,15 @@ class acp_extensions
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)
@ -139,11 +147,15 @@ class acp_extensions
break;
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';
@ -165,11 +177,15 @@ class acp_extensions
case 'purge':
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)

View file

@ -87,6 +87,11 @@ class acp_groups
case 'approve':
case 'demote':
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)
{
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING);
@ -259,6 +264,11 @@ class acp_groups
break;
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)
{
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_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
// which is the lowest amongst DBMSes supported by phpBB3
if ($max_recipients_error = validate_data($submit_ary, array('max_recipients' => array('num', false, 0, 16777215))))
/*
* 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 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
$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))
@ -570,8 +591,11 @@ class acp_groups
$avatar = phpbb_get_group_avatar($group_row, 'GROUP_AVATAR', true);
// Merge any avatar errors into the primary error array
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));
if (!$update)
{
// 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', '');
@ -906,10 +930,12 @@ class acp_groups
case 'set_config_teampage':
$config->set('teampage_forums', $request->variable('teampage_forums', 0));
$config->set('teampage_memberships', $request->variable('teampage_memberships', 0));
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
break;
case 'set_config_legend':
$config->set('legend_sort_groupname', $request->variable('legend_sort_groupname', 0));
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
break;
}
}

View file

@ -544,81 +544,60 @@ class acp_modules
*/
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;
$directory = $phpbb_root_path . 'includes/' . $module_class . '/info/';
$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;
$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 $module)
// Skip entries we do not need if we know the module we are
// looking for
if ($module && strpos($cur_module, $module) === false)
{
$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))
{
$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;
}
continue;
}
ksort($fileinfo);
}
else
{
$info_class = preg_replace('/_module$/', '_info', $module);
$info_class = preg_replace('/_module$/', '_info', $cur_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))
{
$info_class = $module . '_info';
if (!class_exists($info_class) && file_exists($directory . $module . '.' . $phpEx))
$info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module);
$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))
{
$info = new $info_class();
$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;
}
}
ksort($fileinfo);
return $fileinfo;
}

View file

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

View file

@ -330,7 +330,7 @@ function acp_ldap(&$new)
</dl>
<dl>
<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>
<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(
'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),
);
}

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
$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))
{
$sql = 'SELECT module_id
@ -267,6 +264,8 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac
else
{
// 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
if (isset($data['before']) && $data['before'])

View file

@ -27,25 +27,51 @@ class phpbb_extension_base implements phpbb_extension_interface
/** @var ContainerInterface */
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
*
* @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->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
* @return false Indicates no further steps are required
*/
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
* @return false Indicates no further steps are required
*/
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;
}
/**
* 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;
}
/**
* 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

View file

@ -29,7 +29,6 @@ class phpbb_extension_manager
protected $db;
protected $config;
protected $migrator;
protected $cache;
protected $php_ext;
protected $extensions;
@ -43,7 +42,6 @@ class phpbb_extension_manager
* @param ContainerInterface $container A container
* @param phpbb_db_driver $db A database connection
* @param phpbb_config $config phpbb_config
* @param phpbb_db_migrator $migrator
* @param phpbb_filesystem $filesystem
* @param string $extension_table The name of the table holding extensions
* @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 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->phpbb_root_path = $phpbb_root_path;
$this->db = $db;
$this->config = $config;
$this->migrator = $migrator;
$this->cache = $cache;
$this->filesystem = $filesystem;
$this->php_ext = $php_ext;
@ -136,13 +133,15 @@ class phpbb_extension_manager
{
$extension_class_name = 'phpbb_ext_' . str_replace('/', '_', $name) . '_ext';
$migrator = $this->container->get('migrator');
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
{
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;
// Returns false if not completed
if (!$this->handle_migrations($name, 'enable'))
{
return true;
}
$extension = $this->get_extension($name);
$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']);
ksort($this->extensions);
$sql = 'UPDATE ' . $this->extension_table . '
SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
$sql = 'SELECT COUNT(ext_name) as row_count
FROM ' . $this->extension_table . "
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 . '
' . $this->db->sql_build_array('INSERT', $extension_data);
@ -335,12 +337,6 @@ class phpbb_extension_manager
$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);
$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');
}
/**
* 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)
{
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;
$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 '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];
$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"' : '') . ' />';
break;
case 'dimension':
$size = (int) $tpl_type[1];
$maxlength = (int) $tpl_type[2];
case 'number':
$min = $max = $maxlength = '';
$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;
case 'textarea':

View file

@ -3040,38 +3040,29 @@ function tidy_database()
*/
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.
$user->add_lang('acp/permissions_phpbb');
// add permission language files from extensions
$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 (array('acp/', 'mods/') as $path)
foreach ($lang_files as $lang_file => $ext_name)
{
$dh = @opendir($user->lang_path . $user->lang_name . '/' . $path);
if ($dh)
if ($ext_name === '/')
{
while (($file = readdir($dh)) !== false)
{
if ($file !== 'permissions_phpbb.' . $phpEx && strpos($file, 'permissions_') === 0 && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx)
{
$files_to_add[] = $path . substr($file, 0, -(strlen($phpEx) + 1));
}
}
closedir($dh);
$user->add_lang($lang_file);
}
else
{
$user->add_lang_ext($ext_name, $lang_file);
}
}
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',
((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno);
if ($info === false)
if (empty($info))
{
$cache->destroy('versioncheck');
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']));
}
if (!$local)
{
$filedata['post_attach'] = ($upload->is_valid($form_name)) ? true : false;
}
else
{
$filedata['post_attach'] = true;
}
$filedata['post_attach'] = $local || $upload->is_valid($form_name);
if (!$filedata['post_attach'])
{
@ -429,30 +422,18 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
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))
{
// Check Image Size, if it is an image
if ($is_image)
{
$file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
}
// Admins and mods are allowed to exceed the allowed filesize
if (!empty($extensions[$file->get('extension')]['max_filesize']))
{
$allowed_filesize = $extensions[$file->get('extension')]['max_filesize'];
@ -467,10 +448,12 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
$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.
$no_image = ($cat_id == ATTACHMENT_CATEGORY_IMAGE) ? false : true;
// Are we uploading an image *and* this image being within the image category?
// Only then perform additional image checks.
$file->move_file($config['upload_path'], false, !$is_image);
$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))
{
@ -481,6 +464,16 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
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['mimetype'] = $file->get('mimetype');
$filedata['extension'] = $file->get('extension');

View file

@ -1040,9 +1040,9 @@ class custom_profile_admin extends custom_profile
global $user;
$options = array(
0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="text" 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'] . '" />'),
2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_maxlen" size="5" value="' . $this->vars['field_maxlen'] . '" />'),
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="number" min="0" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'),
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>')
);
@ -1057,9 +1057,9 @@ class custom_profile_admin extends custom_profile
global $user;
$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'] . '" />'),
1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="text" 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'] . '" />'),
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="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="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>')
);
@ -1074,9 +1074,9 @@ class custom_profile_admin extends custom_profile
global $user;
$options = array(
0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="text" 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'] . '" />'),
2 => array('TITLE' => $user->lang['MAX_FIELD_NUMBER'], 'FIELD' => '<input type="text" name="field_maxlen" size="5" value="' . $this->vars['field_maxlen'] . '" />'),
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="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="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'] . '" />')
);

View file

@ -1330,22 +1330,12 @@ function validate_data($data, $val_ary)
{
$function = array_shift($validate);
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);
}
}
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);
}
// 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;
}
/**
* 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.
*

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 */
protected $db;
/** @var phpbb_cache_service */
protected $cache;
/** @var phpbb_user */
protected $user;
@ -70,7 +73,7 @@ class phpbb_notification_manager
* @param string $user_notifications_table
* @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_methods = $notification_methods;
@ -78,6 +81,7 @@ class phpbb_notification_manager
$this->user_loader = $user_loader;
$this->db = $db;
$this->cache = $cache;
$this->user = $user;
$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
WHERE n.user_id = ' . (int) $options['user_id'] . '
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';
$result = $this->db->sql_query($sql);
$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
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
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';
$result = $this->db->sql_query($sql);
$total_count = (int) $this->db->sql_fetchfield('total_count', $result);
@ -170,11 +174,11 @@ class phpbb_notification_manager
$rowset = array();
// Get the main notifications
$sql = 'SELECT n.*
$sql = 'SELECT n.*, nt.notification_type_name
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
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']) : '') . '
AND nt.notification_type = n.item_type
AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1
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']);
@ -188,12 +192,12 @@ class phpbb_notification_manager
// Get all unread notifications
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
WHERE n.user_id = ' . (int) $options['user_id'] . '
AND n.notification_read = 0
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
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']);
@ -207,17 +211,17 @@ class phpbb_notification_manager
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
$user_ids = array_merge($user_ids, $notification->users_to_query());
// 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;
}
@ -243,19 +247,21 @@ class phpbb_notification_manager
/**
* 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 $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)
*/
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();
$sql = 'UPDATE ' . $this->notifications_table . "
SET notification_read = 1
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) : '') .
(($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);
@ -264,29 +270,21 @@ class phpbb_notification_manager
/**
* 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 $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)
*/
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();
$sql = 'UPDATE ' . $this->notifications_table . "
SET notification_read = 1
WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
AND notification_time <= " . (int) $time .
WHERE 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) : '') .
(($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);
@ -312,7 +310,7 @@ class phpbb_notification_manager
/**
* 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
* 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
@ -320,18 +318,18 @@ class phpbb_notification_manager
* 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
*/
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(
'ignore_users' => array(),
), $options);
if (is_array($item_type))
if (is_array($notification_type_name))
{
$notified_users = array();
$temp_options = $options;
foreach ($item_type as $type)
foreach ($notification_type_name as $type)
{
$temp_options['ignore_users'] = $options['ignore_users'] + $notified_users;
$notified_users += $this->add_notifications($type, $data, $temp_options);
@ -340,12 +338,12 @@ class phpbb_notification_manager
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
$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;
}
@ -353,15 +351,15 @@ class phpbb_notification_manager
/**
* 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 $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);
}
@ -369,24 +367,9 @@ class phpbb_notification_manager
return;
}
$sql = 'SELECT notification_type
FROM ' . $this->notification_types_table . "
WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'";
$result = $this->db->sql_query($sql);
$notification_type_id = $this->get_notification_type_id($notification_type_name);
if ($this->db->sql_fetchrow($result) === false)
{
// 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);
$item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data);
$user_ids = 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
// This may happen when an item was added, but now new users are able to see the item
$sql = 'SELECT n.user_id
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt
WHERE n.item_type = '" . $this->db->sql_escape($item_type) . "'
AND n.item_id = " . (int) $item_id . '
AND nt.notification_type = n.item_type
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.notification_type_id = ' . (int) $notification_type_id . '
AND n.item_id = ' . (int) $item_id . '
AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
@ -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)
$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);
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
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;
@ -464,14 +447,14 @@ class phpbb_notification_manager
/**
* 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
*/
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);
}
@ -479,7 +462,7 @@ class phpbb_notification_manager
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
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);
$update_array = $notification->create_update_array($data);
$sql = 'UPDATE ' . $this->notifications_table . '
SET ' . $this->db->sql_build_array('UPDATE', $update_array) . "
WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
AND item_id = " . (int) $item_id;
SET ' . $this->db->sql_build_array('UPDATE', $update_array) . '
WHERE notification_type_id = ' . (int) $notification_type_id . '
AND item_id = ' . (int) $item_id;
$this->db->sql_query($sql);
}
/**
* 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 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);
}
@ -520,9 +504,11 @@ class phpbb_notification_manager
return;
}
$sql = 'DELETE FROM ' . $this->notifications_table . "
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);
$notification_type_id = $this->get_notification_type_id($notification_type_name);
$sql = 'DELETE FROM ' . $this->notifications_table . '
WHERE notification_type_id = ' . (int) $notification_type_id . '
AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id);
$this->db->sql_query($sql);
}
@ -655,7 +641,8 @@ class phpbb_notification_manager
{
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;
@ -755,13 +742,13 @@ class phpbb_notification_manager
* is disabled so that all those notifications are hidden and do not
* 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 . "
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);
}
@ -771,17 +758,21 @@ class phpbb_notification_manager
* This should be called when an extension which has notification types
* 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 . "
WHERE item_type = '" . $this->db->sql_escape($item_type) . "'";
$notification_type_id = $this->get_notification_type_id($notification_type_name);
$sql = 'DELETE FROM ' . $this->notifications_table . '
WHERE notification_type_id = ' . (int) $notification_type_id;
$this->db->sql_query($sql);
$sql = 'DELETE FROM ' . $this->notification_types_table . "
WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'";
$sql = 'DELETE FROM ' . $this->notification_types_table . '
WHERE notification_type_id = ' . (int) $notification_type_id;
$this->db->sql_query($sql);
$this->cache->destroy('notification_type_ids');
}
/**
@ -791,13 +782,13 @@ class phpbb_notification_manager
* that was disabled is re-enabled so that all those notifications that
* 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 . "
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);
}
@ -816,11 +807,11 @@ class phpbb_notification_manager
/**
* 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);
@ -851,4 +842,69 @@ class phpbb_notification_manager
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 */
protected $db;
/** @var phpbb_cache_service */
/** @var phpbb_cache_driver_interface */
protected $cache;
/** @var phpbb_template */

View file

@ -39,7 +39,7 @@ class phpbb_notification_method_email extends phpbb_notification_method_messenge
*/
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 */
protected $db;
/** @var phpbb_cache_service */
/** @var phpbb_cache_driver_interface */
protected $cache;
/** @var phpbb_template */
@ -68,11 +68,19 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
*/
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
* item_type - Type of the item (translates to the notification type)
* 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)
* 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_parent_id - Parent item id (ex: for topic => forum_id, for post => topic_id, etc)
* user_id
* notification_read
* 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)
{
$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
$this->data = array_merge(array(
'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),
'notification_time' => time(),
@ -460,7 +470,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
$this->notification_read = (bool) !$unread;
$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,
'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
$update_notifications = array();
$sql = 'SELECT n.*
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt
WHERE n.item_type = '" . $this->get_type() . "'
AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . '
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
AND n.notification_read = 0
AND nt.notification_type = n.item_type
AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))

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
$update_notifications = array();
$sql = 'SELECT n.*
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt
WHERE n.item_type = '" . $this->get_type() . "'
AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . '
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
AND n.notification_read = 0
AND nt.notification_type = n.item_type
AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))

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
$update_notifications = array();
$sql = 'SELECT n.*
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt
WHERE n.item_type = '" . $this->get_type() . "'
AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . '
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
AND n.notification_read = 0
AND nt.notification_type = n.item_type
AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
@ -154,10 +154,10 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post
{
$old_notifications = array();
$sql = 'SELECT n.user_id
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt
WHERE n.item_type = '" . $this->get_type() . "'
AND n.item_id = " . self::get_item_id($post) . '
AND nt.notification_type = n.item_type
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
AND n.item_id = ' . self::get_item_id($post) . '
AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
@ -185,9 +185,9 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post
// Remove the necessary notifications
if (!empty($remove_notifications))
{
$sql = 'DELETE FROM ' . $this->notifications_table . "
WHERE item_type = '" . $this->get_type() . "'
AND item_id = " . self::get_item_id($post) . '
$sql = 'DELETE FROM ' . $this->notifications_table . '
WHERE notification_type_id = ' . (int) $this->notification_type_id . '
AND item_id = ' . self::get_item_id($post) . '
AND ' . $this->db->sql_in_set('user_id', $remove_notifications);
$this->db->sql_query($sql);
}

View file

@ -1819,11 +1819,11 @@ class phpbb_search_fulltext_native extends phpbb_search_base
</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>
<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>
<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>
<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>
<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>
<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>
';

View file

@ -888,11 +888,11 @@ class phpbb_search_fulltext_sphinx
</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>
<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>
<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>
<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;
/**
* Array of default parameters
*
* @var array
*/
private $default_filter_params;
/**
* 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)
{
$this->filter_params = array(
'allow_php' => $allow_php,
'style_names' => $style_names,
'locator' => $locator,
$this->filter_params = $this->default_filter_params = array(
'allow_php' => $allow_php,
'style_names' => $style_names,
'locator' => $locator,
'phpbb_root_path' => $phpbb_root_path,
'extension_manager' => $extension_manager,
'user' => $user,
'user' => $user,
'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
* cache directory

View file

@ -75,6 +75,14 @@ class phpbb_template_filter extends php_user_filter
*/
private $allow_php;
/**
* Whether cleanup will be performed on resulting code, see compile()
* (Preserve whitespace)
*
* @var bool
*/
private $cleanup = true;
/**
* Resource locator.
*
@ -183,6 +191,7 @@ class phpbb_template_filter extends php_user_filter
$this->phpbb_root_path = $this->params['phpbb_root_path'];
$this->style_names = $this->params['style_names'];
$this->extension_manager = $this->params['extension_manager'];
$this->cleanup = $this->params['cleanup'];
if (isset($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);
}
/*
if ($this->cleanup)
{
/*
Preserve whitespace.
PHP removes a newline after the closing tag (if it's there).
This is by design:
Preserve whitespace.
PHP removes a newline after the closing tag (if it's there).
This is by design:
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.phpmode.php
http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php
Consider the following template:
Consider the following template:
<!-- IF condition -->
some content
<!-- ENDIF -->
<!-- IF condition -->
some content
<!-- ENDIF -->
If we were to simply preserve all whitespace, we could simply
replace all "?>" tags with "?>\n".
Doing that, would add additional newlines to the compiled
template in place of the IF and ENDIF statements. These
newlines are unwanted (and one is conditional). The IF and
ENDIF are usually on their own line for ease of reading.
If we were to simply preserve all whitespace, we could simply
replace all "?>" tags with "?>\n".
Doing that, would add additional newlines to the compiled
template in place of the IF and ENDIF statements. These
newlines are unwanted (and one is conditional). The IF and
ENDIF are usually on their own line for ease of reading.
This replacement preserves newlines only for statements that
are not the only statement on a line. It will NOT preserve
newlines at the end of statements in the above example.
It will preserve newlines in situations like:
This replacement preserves newlines only for statements that
are not the only statement on a line. It will NOT preserve
newlines at the end of statements in the above example.
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;
}
@ -335,6 +348,10 @@ class phpbb_template_filter extends php_user_filter
return '<?php ' . $this->compile_tag_define($matches[2], false) . ' ?>';
break;
case 'ENDDEFINE':
return '<?php ' . $this->compile_tag_enddefine() . ' ?>';
break;
case 'INCLUDE':
return '<?php ' . $this->compile_tag_include($matches[2]) . ' ?>';
break;
@ -839,6 +856,16 @@ class phpbb_template_filter extends php_user_filter
$match = array();
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))
{
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 . ';';
}
/**
* 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
*
@ -967,8 +1008,14 @@ class phpbb_template_filter extends php_user_filter
$all_compiled = '';
foreach ($files as $file)
{
$this->template_compile->set_filter_params(array(
'cleanup' => false,
));
$compiled = $this->template_compile->compile_file($file);
$this->template_compile->reset_filter_params();
if ($compiled === false)
{
if ($this->user)

View file

@ -547,6 +547,9 @@ class ucp_groups
$submit_ary['avatar_width'] = 0;
$submit_ary['avatar_height'] = 0;
}
// Merge any avatars errors into the primary error array
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));
}
if (!check_form_key('ucp_groups'))
@ -554,6 +557,13 @@ class ucp_groups
$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))
{
// 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
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));
if (!$update)
{
// 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(
'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');
$extension_manager = $phpbb_container->get('ext.manager');
$finder = $extension_manager->get_finder();
$phpbb_extension_manager = $phpbb_container->get('ext.manager');
$finder = $phpbb_extension_manager->get_finder();
$migrations = $finder
->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
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 '<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);
}
@ -276,6 +275,17 @@ if ($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);

View file

@ -373,6 +373,7 @@ class module
'L_SKIP' => $lang['SKIP'],
'PAGE_TITLE' => $this->get_page_title(),
'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_FLOW_BEGIN' => ($lang['DIRECTION'] == 'ltr') ? 'left' : 'right',
@ -666,6 +667,21 @@ class module
{
case 'text':
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];
$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.
$template->assign_vars(array(
'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)
$name = str_replace(array('\\', '//', '/install'), '/', $name);
$data['script_path'] = trim(dirname($name));
$name = str_replace(array('\\', '//'), '/', $name);
$data['script_path'] = trim(dirname(dirname($name)));
}
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_pass1' => array('lang' => 'ADMIN_PASSWORD', 'type' => 'password:25:100', 'explain' => true),
'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(
'legend1' => 'ACP_EMAIL_SETTINGS',

View file

@ -642,17 +642,30 @@ END;;
# 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
);;
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'
CREATE TABLE phpbb_notifications (
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_parent_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);;
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 GENERATOR phpbb_notifications_gen;;

View file

@ -793,7 +793,8 @@ GO
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
) ON [PRIMARY]
GO
@ -801,18 +802,20 @@ GO
ALTER TABLE [phpbb_notification_types] WITH NOCHECK ADD
CONSTRAINT [PK_phpbb_notification_types] PRIMARY KEY CLUSTERED
(
[notification_type],
[notification_type_enabled]
[notification_type_id]
) ON [PRIMARY]
GO
CREATE UNIQUE INDEX [type] ON [phpbb_notification_types]([notification_type_name]) ON [PRIMARY]
GO
/*
Table: 'phpbb_notifications'
*/
CREATE TABLE [phpbb_notifications] (
[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_parent_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]
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
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'
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,
PRIMARY KEY (notification_type, notification_type_enabled)
PRIMARY KEY (notification_type_id),
UNIQUE type (notification_type_name)
);
# Table: 'phpbb_notifications'
CREATE TABLE phpbb_notifications (
notification_id mediumint(8) UNSIGNED NOT NULL auto_increment,
item_type varbinary(255) DEFAULT '' NOT NULL,
notification_id int(10) UNSIGNED NOT NULL auto_increment,
notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL,
item_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,
@ -469,7 +471,7 @@ CREATE TABLE phpbb_notifications (
notification_time int(11) UNSIGNED DEFAULT '1' NOT NULL,
notification_data blob NOT NULL,
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)
);

View file

@ -452,16 +452,18 @@ CREATE TABLE phpbb_modules (
# 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,
PRIMARY KEY (notification_type, notification_type_enabled)
PRIMARY KEY (notification_type_id),
UNIQUE type (notification_type_name)
) CHARACTER SET `utf8` COLLATE `utf8_bin`;
# Table: 'phpbb_notifications'
CREATE TABLE phpbb_notifications (
notification_id mediumint(8) UNSIGNED NOT NULL auto_increment,
item_type varchar(255) DEFAULT '' NOT NULL,
notification_id int(10) UNSIGNED NOT NULL auto_increment,
notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL,
item_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,
@ -469,7 +471,7 @@ CREATE TABLE phpbb_notifications (
notification_time int(11) UNSIGNED DEFAULT '1' NOT NULL,
notification_data text NOT NULL,
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)
) CHARACTER SET `utf8` COLLATE `utf8_bin`;

View file

@ -870,19 +870,37 @@ END;
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,
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'
*/
CREATE TABLE phpbb_notifications (
notification_id number(8) NOT NULL,
item_type varchar2(255) DEFAULT '' ,
notification_id number(10) NOT NULL,
notification_type_id number(4) DEFAULT '0' NOT NULL,
item_id number(8) DEFAULT '0' NOT NULL,
item_parent_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)
/

View file

@ -623,12 +623,16 @@ CREATE INDEX phpbb_modules_class_left_id ON phpbb_modules (module_class, left_id
/*
Table: 'phpbb_notification_types'
*/
CREATE SEQUENCE phpbb_notification_types_seq;
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),
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'
@ -637,7 +641,7 @@ CREATE SEQUENCE phpbb_notifications_seq;
CREATE TABLE phpbb_notifications (
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_parent_id INT4 DEFAULT '0' NOT NULL CHECK (item_parent_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)
);
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);
/*

View file

@ -439,16 +439,17 @@ CREATE INDEX phpbb_modules_class_left_id ON phpbb_modules (module_class, left_id
# Table: 'phpbb_notification_types'
CREATE TABLE phpbb_notification_types (
notification_type varchar(255) NOT NULL DEFAULT '',
notification_type_enabled INTEGER UNSIGNED NOT NULL DEFAULT '1',
PRIMARY KEY (notification_type, notification_type_enabled)
notification_type_id INTEGER PRIMARY KEY NOT NULL ,
notification_type_name varchar(255) NOT NULL DEFAULT '',
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'
CREATE TABLE phpbb_notifications (
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_parent_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 ''
);
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);
# Table: 'phpbb_poll_options'

View file

@ -70,6 +70,9 @@ $lang = array_merge($lang, array(
'AIM' => 'AIM',
'AJAX_ERROR_TITLE' => 'AJAX error',
'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',
'ALL_FILES' => 'All files',
'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_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_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.',
'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>',
'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',
'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_JABBER' => 'The name you entered is not a valid Jabber account name.',
'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',
'POLL_DELETE' => 'Delete poll',
'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_EXPLAIN' => 'This is the number of options each user may select when voting.',
'POLL_OPTIONS' => 'Poll options',
@ -211,7 +211,7 @@ $lang = array_merge($lang, array(
'SMILIES_ARE_ON' => 'Smilies are <em>ON</em>',
'STICKY_ANNOUNCE_TIME_LIMIT'=> 'Sticky/Announcement time limit',
'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.',
'TOO_FEW_CHARS' => 'Your message contains too few characters.',

View file

@ -225,4 +225,13 @@ $('#member_search').click(function () {
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

View file

@ -21,11 +21,11 @@
<!-- END bool -->
<!-- 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 -->
<!-- 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}_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}_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}_year">{L_YEAR}{L_COLON} <select name="{date.FIELD_IDENT}_year" id="{date.FIELD_IDENT}_year">{date.S_YEAR_OPTIONS}</select></label>
<!-- END date -->

View file

@ -394,3 +394,102 @@ function getCaretPosition(txtarea) {
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
*/
/**
* Find a member
*/
function find_username(url) {
popup(url, 760, 570, '_usersearch');
return false;
}
/**
* Window popup
*/
@ -20,7 +28,7 @@ function popup(url, width, height, name) {
function jumpto() {
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) {
document.location.href = base_url + '?start=' + ((page - 1) * per_page);
} else {
@ -356,41 +364,24 @@ function submit_default_button(event, selector, class_name) {
* The non-jQuery code is a mimick of the jQuery code ;)
*/
function apply_onkeypress_event() {
// jQuery code in case jQuery is used
if (jquery_present) {
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;
}
jQuery('form input[type=text], form input[type=password]').on('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;
});
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;
});
}
/**
* 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';
jQuery(document).ready(apply_onkeypress_event);

View file

@ -13,7 +13,7 @@
<ul class="topiclist">
<li class="header">
<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="posts">{L_POSTS}</dd>
<dd class="lastpost"><span>{L_LAST_POST}</span></dd>
@ -27,20 +27,22 @@
<li class="row">
<dl class="icon {forumrow.FORUM_IMG_STYLE}">
<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 -->
<a href="{forumrow.U_VIEWFORUM}" class="forumtitle">{forumrow.FORUM_NAME}</a><br />
{forumrow.FORUM_DESC}
<!-- IF forumrow.MODERATORS -->
<br /><strong>{forumrow.L_MODERATOR_STR}{L_COLON}</strong> {forumrow.MODERATORS}
<!-- ENDIF -->
<!-- IF .forumrow.subforum and forumrow.S_LIST_SUBFORUMS -->
<br /><strong>{forumrow.L_SUBFORUM_STR}</strong>
<!-- 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 -->
<!-- END subforum -->
<!-- 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 />
{forumrow.FORUM_DESC}
<!-- IF forumrow.MODERATORS -->
<br /><strong>{forumrow.L_MODERATOR_STR}{L_COLON}</strong> {forumrow.MODERATORS}
<!-- ENDIF -->
<!-- IF .forumrow.subforum and forumrow.S_LIST_SUBFORUMS -->
<br /><strong>{forumrow.L_SUBFORUM_STR}</strong>
<!-- 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 -->
<!-- END subforum -->
<!-- ENDIF -->
</div>
</dt>
<!-- IF forumrow.CLICKS -->
<dd class="redirect"><span>{L_REDIRECTS}{L_COLON} {forumrow.CLICKS}</span></dd>

View file

@ -24,22 +24,24 @@
<!-- ENDIF -->
<!-- IF .topicrow -->
<ul class="topiclist">
<ul class="topiclist<!-- IF S_MERGE_SELECT --> missing-column<!-- ENDIF -->">
<li class="header">
<dl class="icon">
<dt>{L_TOPICS}</dt>
<dt><div class="list-inner">{L_TOPICS}</div></dt>
<dd class="posts">{L_REPLIES}</dd>
<dd class="lastpost"><span>{L_LAST_POST}</span></dd>
<!-- IF not S_MERGE_SELECT --><dd class="mark">{L_MARK}</dd><!-- ENDIF -->
</dl>
</li>
</ul>
<ul class="topiclist cplist">
<ul class="topiclist cplist<!-- IF S_MERGE_SELECT --> missing-column<!-- ENDIF -->">
<!-- BEGIN topicrow -->
<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}">
<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 -->
<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 -->
@ -60,7 +62,10 @@
</ul>
</div>
<!-- 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="lastpost"><span><dfn>{L_LAST_POST} </dfn>{L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL}<br />{topicrow.LAST_POST_TIME}</span>
</dd>

View file

@ -13,22 +13,24 @@
<p>{L_UNAPPROVED_TOTAL}</p>
<!-- IF .unapproved -->
<ul class="topiclist">
<ul class="topiclist two-long-columns">
<li class="header">
<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>
</dl>
</li>
</ul>
<ul class="topiclist cplist">
<ul class="topiclist cplist two-long-columns">
<!-- BEGIN unapproved -->
<li class="row<!-- IF unapproved.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl>
<dt>
<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 class="list-inner">
<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>
<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 />
@ -65,22 +67,24 @@
<p>{L_REPORTS_TOTAL}</p>
<!-- IF .report -->
<ul class="topiclist">
<ul class="topiclist two-long-columns">
<li class="header">
<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>
</dl>
</li>
</ul>
<ul class="topiclist cplist">
<ul class="topiclist cplist two-long-columns">
<!-- BEGIN report -->
<li class="row<!-- IF report.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl>
<dt>
<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 class="list-inner">
<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>
<dd class="moderation">
<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>
<!-- IF .pm_report -->
<ul class="topiclist">
<ul class="topiclist two-long-columns">
<li class="header">
<dl>
<dt>{L_VIEW_DETAILS}</dt>
<dt><div class="list-inner">{L_VIEW_DETAILS}</div></dt>
<dd class="moderation"><span>{L_REPORTER}</span></dd>
</dl>
</li>
</ul>
<ul class="topiclist cplist">
<ul class="topiclist cplist two-long-columns">
<!-- BEGIN pm_report -->
<li class="row<!-- IF pm_report.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl>
<dt>
<a href="{pm_report.U_PM_DETAILS}" class="topictitle">{pm_report.PM_SUBJECT}</a> {pm_report.ATTACH_ICON_IMG}<br />
<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 class="list-inner">
<a href="{pm_report.U_PM_DETAILS}" class="topictitle">{pm_report.PM_SUBJECT}</a> {pm_report.ATTACH_ICON_IMG}<br />
<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>
<dd class="moderation">
<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">
<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 class="rightside pagination">
<!-- IF TOTAL -->{TOTAL} &bull; <!-- ENDIF -->

View file

@ -52,7 +52,7 @@
<ul class="linklist">
<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 class="rightside pagination">
<!-- IF TOTAL_REPORTS -->{TOTAL_REPORTS} &bull; <!-- ENDIF -->

View file

@ -26,16 +26,16 @@
<!-- ENDIF -->
</li>
</ul>
<ul class="topiclist">
<ul class="topiclist missing-column">
<li class="header">
<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="mark">{L_MARK}</dd>
</dl>
</li>
</ul>
<ul class="topiclist cplist">
<ul class="topiclist cplist missing-column">
<!-- BEGIN postrow -->
@ -46,8 +46,10 @@
<li class="row<!-- IF postrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl>
<dt>
<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 class="list-inner">
<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>
<dd class="moderation">
<span>

View file

@ -28,33 +28,37 @@
<!-- ENDIF -->
</li>
</ul>
<ul class="topiclist">
<ul class="topiclist missing-column">
<li class="header">
<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="mark">{L_MARK}</dd>
</dl>
</li>
</ul>
<ul class="topiclist cplist">
<ul class="topiclist cplist missing-column">
<!-- BEGIN postrow -->
<li class="row<!-- IF postrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl>
<!-- IF S_PM -->
<dt>
<a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.PM_SUBJECT}</a> {postrow.ATTACH_ICON_IMG}<br />
<span>{L_MESSAGE_BY_AUTHOR} {postrow.PM_AUTHOR_FULL} &raquo; {postrow.PM_TIME}</span><br />
<span>{L_MESSAGE_TO} {postrow.RECIPIENTS}</span>
<div class="list-inner">
<a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.PM_SUBJECT}</a> {postrow.ATTACH_ICON_IMG}<br />
<span>{L_MESSAGE_BY_AUTHOR} {postrow.PM_AUTHOR_FULL} &raquo; {postrow.PM_TIME}</span><br />
<span>{L_MESSAGE_TO} {postrow.RECIPIENTS}</span>
</div>
</dt>
<dd class="moderation">
<span>{postrow.REPORTER_FULL} &laquo; {postrow.REPORT_TIME}</span>
</dd>
<!-- ELSE -->
<dt>
<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 class="list-inner">
<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>
<dd class="moderation">
<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">
<dl>
<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>
<dt><label>{L_DISPLAY_POSTS}{L_COLON}</label></dt>
@ -80,7 +80,7 @@ onload_functions.push('subPanels()');
<dl>
<dt><label for="to_topic_id">{L_MERGE_TOPIC_ID}{L_COLON}</label></dt>
<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>
</dd>
<!-- IF TO_TOPIC_INFO --><dd>{TO_TOPIC_INFO}</dd><!-- ENDIF -->
@ -141,9 +141,9 @@ onload_functions.push('subPanels()');
<ul class="linklist">
<li class="rightside pagination">
<!-- IF TOTAL_POSTS --> {TOTAL_POSTS} &bull; <!-- ENDIF -->
<!-- IF .pagination -->
<!-- IF .pagination -->
<!-- INCLUDE pagination.html -->
<!-- ELSE -->
<!-- ELSE -->
{PAGE_NUMBER}
<!-- ENDIF -->
</li>

View file

@ -22,7 +22,7 @@
<!-- ELSE -->
<dl>
<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>
<dt><label for="name">{L_REAL_NAME}{L_COLON}</label></dt>

View file

@ -89,7 +89,7 @@ function insert_single(user)
<!-- ENDIF -->
<dl>
<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>
<!-- IF S_IP_SEARCH_ALLOWED -->
<dl>

View file

@ -29,7 +29,7 @@
<!-- IF U_ACP --><br /><strong><a href="{U_ACP}">{L_ACP}</a></strong><!-- ENDIF -->
</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 class="phpbb_alert" id="loadingalert"><h3>{L_LOADING}</h3><p>{L_PLEASE_WAIT}</p></div>
</div>
@ -53,6 +53,7 @@
<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 -->
<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>
<!-- INCLUDEJS template/ajax.js -->
{SCRIPTS}

View file

@ -40,15 +40,6 @@
window.open(url.replace(/&amp;/g, '&'), '_phpbbprivmsg', 'height=225,resizable=yes,scrollbars=yes, width=400');
<!-- 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
*/
@ -70,7 +61,6 @@
// ]]>
</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_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" />
@ -106,7 +96,7 @@
<div id="search-box">
<form action="{U_SEARCH}" method="get" id="search">
<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 />
<a href="{U_SEARCH}" title="{L_SEARCH_ADV_EXPLAIN}">{L_SEARCH_ADV}</a> {S_SEARCH_HIDDEN_FIELDS}
</fieldset>
@ -137,8 +127,8 @@
<!-- IF not S_IS_BOT and S_USER_LOGGED_IN -->
<ul class="linklist leftside">
<!-- IF S_NOTIFICATIONS_DISPLAY -->
<li>
[ <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button">{NOTIFICATIONS_COUNT}</a> ] &bull;
<li class="icon-notification">
<a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button">{NOTIFICATIONS_COUNT}</a>
<div id="notification_list" class="notification_list">
<div class="pointer"><div class="pointer_inner"></div></div>
<div class="header">

View file

@ -1,9 +1,3 @@
<script type="text/javascript">
// <![CDATA[
onload_functions.push(apply_onkeypress_event);
// ]]>
</script>
<fieldset class="fields1">
<!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF -->
@ -250,7 +244,7 @@
<!-- IF S_TOPIC_TYPE_ANNOUNCE or S_TOPIC_TYPE_STICKY -->
<dl>
<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>
</dl>
<!-- ENDIF -->

View file

@ -26,18 +26,18 @@
<dl>
<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>
</dl>
<dl>
<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>
</dl>
<!-- IF S_POLL_VOTE_CHANGE -->
<hr class="dashed" />
<dl>
<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>

View file

@ -19,13 +19,13 @@
<fieldset>
<dl>
<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="terms2"><input type="radio" name="terms" id="terms2" value="any" /> {L_SEARCH_ANY_TERMS}</label></dd>
</dl>
<dl>
<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>
</fieldset>

View file

@ -19,7 +19,7 @@
<!-- IF SEARCH_MATCHES -->
<div class="search-box">
<!-- 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}" />
<!-- ENDIF -->
</div>
@ -48,7 +48,7 @@
<ul class="topiclist">
<li class="header">
<dl class="icon">
<dt>{L_TOPICS}</dt>
<dt><div class="list-inner">{L_TOPICS}</div></dt>
<dd class="posts">{L_REPLIES}</dd>
<dd class="views">{L_VIEWS}</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 -->">
<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}">
<!-- IF searchresults.S_UNREAD_TOPIC --><a href="{searchresults.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF -->
<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_TOPIC_REPORTED --><a href="{searchresults.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --><br />
<!-- IF .searchresults.pagination -->
<div class="pagination">
<ul>
<!-- BEGIN pagination -->
<!-- IF searchresults.pagination.S_IS_PREV -->
<!-- ELSEIF searchresults.pagination.S_IS_CURRENT --><li class="active"><span>{searchresults.pagination.PAGE_NUMBER}</span></li>
<!-- ELSEIF searchresults.pagination.S_IS_ELLIPSIS --><li class="ellipsis"><span>{L_ELLIPSIS}</span></li>
<!-- ELSEIF searchresults.pagination.S_IS_NEXT -->
<!-- ELSE --><li><a href="{searchresults.pagination.PAGE_URL}">{searchresults.pagination.PAGE_NUMBER}</a></li>
<!-- ENDIF -->
<!-- END pagination -->
</ul>
<div class="list-inner">
<!-- IF searchresults.S_UNREAD_TOPIC --><a href="{searchresults.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF -->
<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_TOPIC_REPORTED --><a href="{searchresults.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --><br />
<!-- IF .searchresults.pagination -->
<div class="pagination">
<ul>
<!-- BEGIN pagination -->
<!-- IF searchresults.pagination.S_IS_PREV -->
<!-- ELSEIF searchresults.pagination.S_IS_CURRENT --><li class="active"><span>{searchresults.pagination.PAGE_NUMBER}</span></li>
<!-- ELSEIF searchresults.pagination.S_IS_ELLIPSIS --><li class="ellipsis"><span>{L_ELLIPSIS}</span></li>
<!-- ELSEIF searchresults.pagination.S_IS_NEXT -->
<!-- ELSE --><li><a href="{searchresults.pagination.PAGE_URL}">{searchresults.pagination.PAGE_NUMBER}</a></li>
<!-- 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>
<!-- 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>
<dd class="posts">{searchresults.TOPIC_REPLIES}</dd>
<dd class="views">{searchresults.TOPIC_VIEWS}</dd>

View file

@ -8,6 +8,7 @@
<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 -->
<script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/forum_fn.js?assets_version={T_ASSETS_VERSION}"></script>
{SCRIPTS}
<!-- EVENT simple_footer_after -->

View file

@ -40,7 +40,6 @@
// ]]>
</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_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" />

View file

@ -24,7 +24,7 @@
<ul class="topiclist">
<li class="header">
<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="time"><span><a href="{U_SORT_POST_TIME}">{L_POST_TIME}</a></span></dd>
<dd class="mark">{L_MARK}</dd>
@ -36,8 +36,12 @@
<!-- BEGIN attachrow -->
<li class="row<!-- IF attachrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl>
<dt style="width: 40%"><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></dt>
<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="time"><span>{attachrow.POST_TIME}</span></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>
<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>
<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>
<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>
<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 -->
<dl>
<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>
<!-- ENDIF -->

View file

@ -6,19 +6,18 @@
<div class="panel">
<div class="inner">
<!-- IF S_ERROR -->
<fieldset>
<p class="error">{ERROR_MSG}</p>
</fieldset>
<!-- ENDIF -->
<p>{L_GROUPS_EXPLAIN}</p>
<!-- IF S_EDIT -->
<h3>{L_GROUP_DETAILS}</h3>
<!-- IF S_ERROR -->
<div class="errorbox">
<h3>{L_WARNING}</h3>
<p>{ERROR_MSG}</p>
</div>
<!-- ENDIF -->
<fieldset>
<dl>
<dt><label for="group_name">{L_GROUP_NAME}{L_COLON}</label></dt>
@ -55,7 +54,7 @@
<fieldset>
<dl>
<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>
<dt><label for="group_rank">{L_GROUP_RANK}{L_COLON}</label></dt>
@ -207,21 +206,25 @@
<!-- ELSE -->
<!-- IF .leader -->
<ul class="topiclist">
<ul class="topiclist two-long-columns">
<li class="header">
<dl>
<dt>{L_GROUP_LEADER}</dt>
<dt><div class="list-inner">{L_GROUP_LEADER}</div></dt>
<dd class="info"><span>{L_OPTIONS}</span></dd>
</dl>
</li>
</ul>
<ul class="topiclist cplist">
<ul class="topiclist cplist two-long-columns">
<!-- BEGIN leader -->
<li class="row<!-- IF attachrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">
<dl>
<dt><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 --></dt>
<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_LIST}">{L_GROUP_LIST}</a></span></dd>
</dl>

View file

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

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