diff options
169 files changed, 3366 insertions, 3106 deletions
diff --git a/.gitignore b/.gitignore index 589fec4639..885e37f194 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,14 @@ *~ -phpunit.xml -phpBB/cache/*.html -phpBB/cache/*.php -phpBB/cache/queue.php.lock -phpBB/config.php -phpBB/files/* -phpBB/images/avatars/gallery/* -phpBB/images/avatars/upload/* -phpBB/store/* -tests/phpbb_unit_tests.sqlite2 -tests/test_config.php -tests/tmp -tests/utf/data/*.txt +/phpunit.xml +/phpBB/cache/*.html +/phpBB/cache/*.php +/phpBB/cache/queue.php.lock +/phpBB/config.php +/phpBB/files/* +/phpBB/images/avatars/gallery/* +/phpBB/images/avatars/upload/* +/phpBB/store/* +/tests/phpbb_unit_tests.sqlite2 +/tests/test_config.php +/tests/tmp +/tests/utf/data/*.txt diff --git a/build/build.xml b/build/build.xml index 268f09d674..7cfb5d0bf8 100644 --- a/build/build.xml +++ b/build/build.xml @@ -2,9 +2,9 @@ <project name="phpBB" description="The phpBB forum software" default="all" basedir="../"> <!-- a few settings for the build --> - <property name="newversion" value="3.0.8" /> - <property name="prevversion" value="3.0.8-RC1" /> - <property name="olderversions" value="3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.0.6, 3.0.7-PL1" /> + <property name="newversion" value="3.0.9" /> + <property name="prevversion" value="3.0.8" /> + <property name="olderversions" value="3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.0.6, 3.0.7, 3.0.7-PL1, 3.0.9-RC1, 3.0.9-RC2, 3.0.9-RC3, 3.0.9-RC4" /> <!-- no configuration should be needed beyond this point --> <property name="oldversions" value="${olderversions}, ${prevversion}" /> @@ -49,19 +49,16 @@ --coverage-clover build/logs/clover.xml --coverage-html build/coverage" passthru="true" /> + </target> - - <!-- Does not allow changing the working directory to tests/ - so this approach does not work for us unfortunately - <phpunit codecoverage="true" haltonfailure="true"> - <formatter todir="build/logs" type="xml"/> - <batchtest> - <fileset dir="tests"> - <include name="all_tests.php"/> - </fileset> - </batchtest> - </phpunit> - --> + <target name="test-slow" depends="clean,prepare"> + <exec dir="." + command="phpunit --log-junit build/logs/phpunit.xml + --configuration phpunit.xml.all + --group slow + --coverage-clover build/logs/clover-slow.xml + --coverage-html build/coverage-slow" + passthru="true" /> </target> <target name="docs"> @@ -133,7 +130,7 @@ --> <target name="export"> <exec dir="phpBB" - command="git archive ${revision} | tar -x -C ../${dir}" + command="git archive ${revision} | tar -xf - -C ../${dir}" checkreturn="true" /> <delete file="${dir}/config.php" /> <delete dir="${dir}/develop" /> @@ -141,8 +138,8 @@ <echo msg="Setting permissions for checkout of ${revision} in ${dir}" /> <!-- set permissions of all files to 644, directories to 755 --> - <exec dir="${dir}" command="find -type f|xargs chmod 644" escape="false" /> - <exec dir="${dir}" command="find -type d|xargs chmod 755" escape="false" /> + <exec dir="${dir}" command="find . -type f|xargs chmod 644" escape="false" /> + <exec dir="${dir}" command="find . -type d|xargs chmod 755" escape="false" /> <!-- set permissions of some directories to 777 --> <chmod mode="0777" file="${dir}/cache" /> <chmod mode="0777" file="${dir}/store" /> diff --git a/build/build_helper.php b/build/build_helper.php index 94fc0ff3b5..2d9b86b3c3 100644 --- a/build/build_helper.php +++ b/build/build_helper.php @@ -177,7 +177,7 @@ class build_package } // Is binary? - if (preg_match('/^Binary files ' . $package_name . '\/(.*) and [a-z0-9_-]+\/\1 differ/i', $line, $match)) + if (preg_match('/^Binary files ' . $package_name . '\/(.*) and [a-z0-9._-]+\/\1 differ/i', $line, $match)) { $binary[] = trim($match[1]); } diff --git a/phpBB/adm/style/acp_attachments.html b/phpBB/adm/style/acp_attachments.html index 22f271ea82..d938135440 100644 --- a/phpBB/adm/style/acp_attachments.html +++ b/phpBB/adm/style/acp_attachments.html @@ -371,6 +371,79 @@ </fieldset> </form> +<!-- ELSEIF S_MANAGE --> + + <form id="attachments" method="post" action="{U_ACTION}"> + + <fieldset class="tabulated"> + <legend>{L_TITLE}</legend> + + <!-- IF PAGINATION or TOTAL_FILES --> + <div class="pagination"> + {L_NUMBER_FILES}: {TOTAL_FILES} • {L_TOTAL_SIZE}: {TOTAL_SIZE}<!-- IF S_ON_PAGE --><!-- IF PAGINATION --> • <a href="#" onclick="jumpto(); return false;" title="{L_JUMP_TO_PAGE}">{S_ON_PAGE}</a> • <span>{PAGINATION}</span><!-- ELSE --> • {S_ON_PAGE}<!-- ENDIF --><!-- ENDIF --> + </div> + <!-- ENDIF --> + + <table cellspacing="1"> + <thead> + <tr> + <th>{L_FILENAME}</th> + <th>{L_POSTED}</th> + <th>{L_FILESIZE}</th> + <th>{L_DELETE}</th> + </tr> + </thead> + <tbody> + <!-- BEGIN attachments --> + <!-- IF attachments.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <td> + <!-- IF attachments.S_IN_MESSAGE -->{L_EXTENSION_GROUP}: <strong><!-- IF attachments.EXT_GROUP_NAME -->{attachments.EXT_GROUP_NAME}<!-- ELSE -->{L_NO_EXT_GROUP}<!-- ENDIF --></strong><br />{attachments.L_DOWNLOAD_COUNT}<br />{L_IN} {L_PRIVATE_MESSAGE} + <!-- ELSE --><a href="{attachments.U_FILE}" style="font-weight: bold;">{attachments.REAL_FILENAME}</a><br /><!-- IF attachments.COMMENT -->{attachments.COMMENT}<br /><!-- ENDIF -->{attachments.L_DOWNLOAD_COUNT}<br />{L_TOPIC}: <a href="{attachments.U_VIEW_TOPIC}">{attachments.TOPIC_TITLE}</a><!-- ENDIF --> + </td> + <td>{attachments.FILETIME}<br />{L_POST_BY_AUTHOR} {attachments.ATTACHMENT_POSTER}</td> + <td>{attachments.FILESIZE}</td> + <td><input type="checkbox" class="radio" name="delete[{attachments.ATTACH_ID}]" /></td> + </tr> + <!-- END attachments --> + <tr class="row4"> + <td colspan="3"> </td> + <td class="small"><a href="#" onclick="marklist('attachments', 'delete', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('attachments', 'delete', false); return false;">{L_UNMARK_ALL}</a></td> + </tr> + </tbody> + </table> + + <!-- IF TOTAL_FILES --> + <fieldset class="display-options"> + {L_DISPLAY_LOG}: {S_LIMIT_DAYS} {L_SORT_BY}: {S_SORT_KEY} {S_SORT_DIR} + <input class="button2" type="submit" value="{L_GO}" name="sort" /> + </fieldset> + + <hr /> + + <div class="pagination"> + {L_NUMBER_FILES}: {TOTAL_FILES} • {L_TOTAL_SIZE}: {TOTAL_SIZE}<!-- IF S_ON_PAGE --><!-- IF PAGINATION --> • <a href="#" onclick="jumpto(); return false;" title="{L_JUMP_TO_PAGE}">{S_ON_PAGE}</a> • <span>{PAGINATION}</span><!-- ELSE --> • {S_ON_PAGE}<!-- ENDIF --><!-- ENDIF --> + </div> + <!-- ENDIF --> + + <p class="submit-buttons"> + <input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" /> + <input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" /> + </p> + {S_FORM_TOKEN} + </fieldset> + </form> + + <!-- IF S_ACTION_OPTIONS --> + <fieldset> + <legend>{L_RESYNC_STATS}</legend> + <form id="action_stats_form" method="post" action="{U_ACTION}"> + <dl> + <dt><label for="action_stats">{L_RESYNC_FILES_STATS}</label><br /><span>{L_RESYNC_FILES_STATS_EXPLAIN}</span></dt> + <dd><input type="hidden" name="action" value="stats" /><input class="button2" type="submit" id="action_stats" name="action_stats" value="{L_RUN}" /></dd> + </dl> + </form> + </fieldset> + <!-- ENDIF --> <!-- ENDIF --> <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html index d27cea28f7..8577c08860 100644 --- a/phpBB/adm/style/acp_forums.html +++ b/phpBB/adm/style/acp_forums.html @@ -140,6 +140,12 @@ <dt><label for="parent">{L_FORUM_PARENT}:</label></dt> <dd><select id="parent" name="forum_parent_id"><option value="0"<!-- IF not S_FORUM_PARENT_ID --> selected="selected"<!-- ENDIF -->>{L_NO_PARENT}</option>{S_PARENT_OPTIONS}</select></dd> </dl> + <!-- IF S_CAN_COPY_PERMISSIONS --> + <dl> + <dt><label for="forum_perm_from">{L_COPY_PERMISSIONS}:</label><br /><span>{L_COPY_PERMISSIONS_EXPLAIN}</span></dt> + <dd><select id="forum_perm_from" name="forum_perm_from"><option value="0">{L_NO_PERMISSIONS}</option>{S_FORUM_OPTIONS}</select></dd> + </dl> + <!-- ENDIF --> <dl> <dt><label for="forum_name">{L_FORUM_NAME}:</label></dt> <dd><input class="text medium" type="text" id="forum_name" name="forum_name" value="{FORUM_NAME}" maxlength="255" /></dd> @@ -160,11 +166,11 @@ </dl> <dl> <dt><label for="forum_password">{L_FORUM_PASSWORD}:</label><br /><span>{L_FORUM_PASSWORD_EXPLAIN}</span></dt> - <dd><input type="password" id="forum_password" name="forum_password" value="<!-- IF S_FORUM_PASSWORD_SET -->      <!-- ENDIF -->" /></dd> + <dd><input type="password" id="forum_password" name="forum_password" value="<!-- IF S_FORUM_PASSWORD_SET -->      <!-- ENDIF -->" autocomplete="off" /></dd> </dl> <dl> <dt><label for="forum_password_confirm">{L_FORUM_PASSWORD_CONFIRM}:</label><br /><span>{L_FORUM_PASSWORD_CONFIRM_EXPLAIN}</span></dt> - <dd><input type="password" id="forum_password_confirm" name="forum_password_confirm" value="<!-- IF S_FORUM_PASSWORD_SET -->      <!-- ENDIF -->" /></dd> + <dd><input type="password" id="forum_password_confirm" name="forum_password_confirm" value="<!-- IF S_FORUM_PASSWORD_SET -->      <!-- ENDIF -->" autocomplete="off" /></dd> </dl> <!-- IF S_FORUM_PASSWORD_SET --> <dl> @@ -176,12 +182,6 @@ <dt><label for="forum_style">{L_FORUM_STYLE}:</label></dt> <dd><select id="forum_style" name="forum_style"><option value="0">{L_DEFAULT_STYLE}</option>{S_STYLES_OPTIONS}</select></dd> </dl> - <!-- IF S_CAN_COPY_PERMISSIONS --> - <dl> - <dt><label for="forum_perm_from">{L_COPY_PERMISSIONS}:</label><br /><span>{L_COPY_PERMISSIONS_EXPLAIN}</span></dt> - <dd><select id="forum_perm_from" name="forum_perm_from"><option value="0">{L_NO_PERMISSIONS}</option>{S_FORUM_OPTIONS}</select></dd> - </dl> - <!-- ENDIF --> </fieldset> <div id="forum_cat_options"> diff --git a/phpBB/adm/style/acp_profile.html b/phpBB/adm/style/acp_profile.html index 85d37568c2..c1143e9ba4 100644 --- a/phpBB/adm/style/acp_profile.html +++ b/phpBB/adm/style/acp_profile.html @@ -56,6 +56,10 @@ <dd><input type="checkbox" class="radio" id="field_show_on_reg" name="field_show_on_reg" value="1"<!-- IF S_SHOW_ON_REG --> checked="checked"<!-- ENDIF --> /></dd> </dl> <dl> + <dt><label for="field_show_on_pm">{L_DISPLAY_ON_PM}:</label><br /><span>{L_DISPLAY_ON_PM_EXPLAIN}</span></dt> + <dd><input type="checkbox" class="radio" id="field_show_on_pm" name="field_show_on_pm" value="1"<!-- IF S_SHOW_ON_PM --> checked="checked"<!-- ENDIF --> /></dd> + </dl> + <dl> <dt><label for="field_show_on_vt">{L_DISPLAY_ON_VT}:</label><br /><span>{L_DISPLAY_ON_VT_EXPLAIN}</span></dt> <dd><input type="checkbox" class="radio" id="field_show_on_vt" name="field_show_on_vt" value="1"<!-- IF S_SHOW_ON_VT --> checked="checked"<!-- ENDIF --> /></dd> </dl> diff --git a/phpBB/adm/style/acp_ranks.html b/phpBB/adm/style/acp_ranks.html index 2ad8b3e8aa..1f45109517 100644 --- a/phpBB/adm/style/acp_ranks.html +++ b/phpBB/adm/style/acp_ranks.html @@ -35,7 +35,7 @@ </dl> <dl> <dt><label for="special_rank">{L_RANK_SPECIAL}:</label></dt> - <dd><label><input onclick="dE('posts', -1)" type="radio" class="radio" name="special_rank" value="1" id="special_rank"<!-- IF S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> />{L_YES}</label> + <dd><label><input onclick="dE('posts', -1)" type="radio" class="radio" name="special_rank" value="1" id="special_rank"<!-- IF S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> /> {L_YES}</label> <label><input onclick="dE('posts', 1)" type="radio" class="radio" name="special_rank" value="0"<!-- IF not S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> </dl> <!-- IF S_SPECIAL_RANK --><div id="posts" style="display: none;"><!-- ELSE --><div id="posts"><!-- ENDIF --> diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index 911dcad293..9237e45daf 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -43,19 +43,19 @@ </dl> <dl> <dt><label for="user_email">{L_EMAIL}:</label></dt> - <dd><input class="text medium" type="text" id="user_email" name="user_email" value="{USER_EMAIL}" /></dd> + <dd><input class="text medium" type="text" id="user_email" name="user_email" value="{USER_EMAIL}" autocomplete="off" /></dd> </dl> <dl> <dt><label for="email_confirm">{L_CONFIRM_EMAIL}:</label><br /><span>{L_CONFIRM_EMAIL_EXPLAIN}</span></dt> - <dd><input class="text medium" type="text" id="email_confirm" name="email_confirm" value="" /></dd> + <dd><input class="text medium" type="text" id="email_confirm" name="email_confirm" value="" autocomplete="off" /></dd> </dl> <dl> <dt><label for="new_password">{L_NEW_PASSWORD}:</label><br /><span>{L_CHANGE_PASSWORD_EXPLAIN}</span></dt> - <dd><input type="password" id="new_password" name="new_password" value="" /></dd> + <dd><input type="password" id="new_password" name="new_password" value="" autocomplete="off" /></dd> </dl> <dl> <dt><label for="password_confirm">{L_CONFIRM_PASSWORD}:</label><br /><span>{L_CONFIRM_PASSWORD_EXPLAIN}</span></dt> - <dd><input type="password" id="password_confirm" name="password_confirm" value="" /></dd> + <dd><input type="password" id="password_confirm" name="password_confirm" value="" autocomplete="off" /></dd> </dl> <p class="quick"> diff --git a/phpBB/adm/style/acp_users_signature.html b/phpBB/adm/style/acp_users_signature.html index 27fd957e61..d55deac808 100644 --- a/phpBB/adm/style/acp_users_signature.html +++ b/phpBB/adm/style/acp_users_signature.html @@ -22,9 +22,8 @@ w: '{LA_BBCODE_W_HELP}', s: '{LA_BBCODE_S_HELP}', f: '{LA_BBCODE_F_HELP}', - e: '{LA_BBCODE_E_HELP}', + y: '{LA_BBCODE_Y_HELP}', d: '{LA_BBCODE_D_HELP}', - t: '{LA_BBCODE_T_HELP}', tip: '{L_STYLES_TIP}' <!-- BEGIN custom_tags --> ,cb_{custom_tags.BBCODE_ID}: '{custom_tags.A_BBCODE_HELPLINE}' @@ -56,7 +55,7 @@ <input type="button" class="button2" accesskey="c" name="addbbcode8" value="Code" style="width: 40px" onclick="bbstyle(8)" onmouseover="helpline('c')" onmouseout="helpline('tip')" /> <input type="button" class="button2" accesskey="l" name="addbbcode10" value="List" style="width: 40px" onclick="bbstyle(10)" onmouseover="helpline('l')" onmouseout="helpline('tip')" /> <input type="button" class="button2" accesskey="o" name="addbbcode12" value="List=" style="width: 40px" onclick="bbstyle(12)" onmouseover="helpline('o')" onmouseout="helpline('tip')" /> - <input type="button" class="button2" accesskey="y" name="addlitsitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" onmouseover="helpline('e')" onmouseout="helpline('tip')" /> + <input type="button" class="button2" accesskey="y" name="addlistitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" onmouseover="helpline('y')" onmouseout="helpline('tip')" /> <!-- IF S_BBCODE_IMG --> <input type="button" class="button2" accesskey="p" name="addbbcode14" value="Img" style="width: 40px" onclick="bbstyle(14)" onmouseover="helpline('p')" onmouseout="helpline('tip')" /> <!-- ENDIF --> diff --git a/phpBB/adm/style/colour_swatch.html b/phpBB/adm/style/colour_swatch.html index 795e277949..e731620bd3 100644 --- a/phpBB/adm/style/colour_swatch.html +++ b/phpBB/adm/style/colour_swatch.html @@ -1,10 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta http-equiv="Content-Type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="Content-Style-Type" content="text/css" /> -<meta http-equiv="Content-Language" content="{S_USER_LANG}" /> -<meta http-equiv="imagetoolbar" content="no" /> +<meta charset="utf-8"> <title>{L_COLOUR_SWATCH}</title> <style type="text/css"> diff --git a/phpBB/adm/style/install_footer.html b/phpBB/adm/style/install_footer.html index 7fac8a4b9e..fabbee1911 100644 --- a/phpBB/adm/style/install_footer.html +++ b/phpBB/adm/style/install_footer.html @@ -8,7 +8,7 @@ </div> <div id="page-footer"> - Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group + Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group </div> </div> diff --git a/phpBB/adm/style/install_header.html b/phpBB/adm/style/install_header.html index fbb6a7b409..e306d8f6bf 100644 --- a/phpBB/adm/style/install_header.html +++ b/phpBB/adm/style/install_header.html @@ -1,11 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> - -<meta http-equiv="Content-Type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="Content-Style-Type" content="text/css" /> -<meta http-equiv="Content-Language" content="{S_USER_LANG}" /> -<meta http-equiv="imagetoolbar" content="no" /> +<meta charset="utf-8"> <!-- IF META -->{META}<!-- ENDIF --> <title>{PAGE_TITLE}</title> diff --git a/phpBB/adm/style/install_update_diff.html b/phpBB/adm/style/install_update_diff.html index 8b0708cfdb..39c73d5652 100644 --- a/phpBB/adm/style/install_update_diff.html +++ b/phpBB/adm/style/install_update_diff.html @@ -1,11 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> - -<meta http-equiv="Content-Type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="Content-Style-Type" content="text/css" /> -<meta http-equiv="Content-Language" content="{S_USER_LANG}" /> -<meta http-equiv="imagetoolbar" content="no" /> +<meta charset="utf-8"> <!-- IF META -->{META}<!-- ENDIF --> <title>{PAGE_TITLE}</title> diff --git a/phpBB/adm/style/overall_footer.html b/phpBB/adm/style/overall_footer.html index 51949d4c66..689452c268 100644 --- a/phpBB/adm/style/overall_footer.html +++ b/phpBB/adm/style/overall_footer.html @@ -9,7 +9,7 @@ <div id="page-footer"> <!-- IF S_COPYRIGHT_HTML --> - Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group + Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group <!-- IF TRANSLATION_INFO --><br />{TRANSLATION_INFO}<!-- ENDIF --> <!-- ENDIF --> diff --git a/phpBB/adm/style/overall_header.html b/phpBB/adm/style/overall_header.html index a376884507..be5ac29131 100644 --- a/phpBB/adm/style/overall_header.html +++ b/phpBB/adm/style/overall_header.html @@ -1,11 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> - -<meta http-equiv="Content-Type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="Content-Style-Type" content="text/css" /> -<meta http-equiv="Content-Language" content="{S_USER_LANG}" /> -<meta http-equiv="imagetoolbar" content="no" /> +<meta charset="utf-8"> <!-- IF META -->{META}<!-- ENDIF --> <title>{PAGE_TITLE}</title> diff --git a/phpBB/adm/style/simple_footer.html b/phpBB/adm/style/simple_footer.html index 7276fb4b63..ac9c26a690 100644 --- a/phpBB/adm/style/simple_footer.html +++ b/phpBB/adm/style/simple_footer.html @@ -5,7 +5,7 @@ <div id="page-footer"> <!-- IF S_COPYRIGHT_HTML --> - <br />Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group + <br />Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group <!-- IF TRANSLATION_INFO --><br />{TRANSLATION_INFO}<!-- ENDIF --> <!-- ENDIF --> diff --git a/phpBB/adm/style/simple_header.html b/phpBB/adm/style/simple_header.html index 2339b70a93..84ff665acc 100644 --- a/phpBB/adm/style/simple_header.html +++ b/phpBB/adm/style/simple_header.html @@ -1,11 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> - -<meta http-equiv="Content-Type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="Content-Style-Type" content="text/css" /> -<meta http-equiv="Content-Language" content="{S_USER_LANG}" /> -<meta http-equiv="imagetoolbar" content="no" /> +<meta charset="utf-8"> <!-- IF META -->{META}<!-- ENDIF --> <title>{PAGE_TITLE}</title> diff --git a/phpBB/common.php b/phpBB/common.php index f206dc70fd..524c05ae70 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -6,7 +6,7 @@ * @copyright (c) 2005 phpBB Group * @license http://opensource.org/licenses/gpl-license.php GNU Public License * -* Minimum Requirement: PHP 4.3.3 +* Minimum Requirement: PHP 5.2.0 */ /** @@ -16,107 +16,7 @@ if (!defined('IN_PHPBB')) exit; } -$starttime = explode(' ', microtime()); -$starttime = $starttime[1] + $starttime[0]; - -// Report all errors, except notices and deprecation messages -if (!defined('E_DEPRECATED')) -{ - define('E_DEPRECATED', 8192); -} -error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED); - -/* -* Remove variables created by register_globals from the global scope -* Thanks to Matt Kavanagh -*/ -function deregister_globals() -{ - $not_unset = array( - 'GLOBALS' => true, - '_GET' => true, - '_POST' => true, - '_COOKIE' => true, - '_REQUEST' => true, - '_SERVER' => true, - '_SESSION' => true, - '_ENV' => true, - '_FILES' => true, - 'phpEx' => true, - 'phpbb_root_path' => true - ); - - // Not only will array_merge and array_keys give a warning if - // a parameter is not an array, array_merge will actually fail. - // So we check if _SESSION has been initialised. - if (!isset($_SESSION) || !is_array($_SESSION)) - { - $_SESSION = array(); - } - - // Merge all into one extremely huge array; unset this later - $input = array_merge( - array_keys($_GET), - array_keys($_POST), - array_keys($_COOKIE), - array_keys($_SERVER), - array_keys($_SESSION), - array_keys($_ENV), - array_keys($_FILES) - ); - - foreach ($input as $varname) - { - if (isset($not_unset[$varname])) - { - // Hacking attempt. No point in continuing unless it's a COOKIE - if ($varname !== 'GLOBALS' || isset($_GET['GLOBALS']) || isset($_POST['GLOBALS']) || isset($_SERVER['GLOBALS']) || isset($_SESSION['GLOBALS']) || isset($_ENV['GLOBALS']) || isset($_FILES['GLOBALS'])) - { - exit; - } - else - { - $cookie = &$_COOKIE; - while (isset($cookie['GLOBALS'])) - { - foreach ($cookie['GLOBALS'] as $registered_var => $value) - { - if (!isset($not_unset[$registered_var])) - { - unset($GLOBALS[$registered_var]); - } - } - $cookie = &$cookie['GLOBALS']; - } - } - } - - unset($GLOBALS[$varname]); - } - - unset($input); -} - -// If we are on PHP >= 6.0.0 we do not need some code -if (version_compare(PHP_VERSION, '6.0.0-dev', '>=')) -{ - /** - * @ignore - */ - define('STRIP', false); -} -else -{ - @set_magic_quotes_runtime(0); - - // Be paranoid with passed vars - if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on' || !function_exists('ini_get')) - { - deregister_globals(); - } - - define('STRIP', (get_magic_quotes_gpc()) ? true : false); -} +require($phpbb_root_path . 'includes/startup.' . $phpEx); if (file_exists($phpbb_root_path . 'config.' . $phpEx)) { diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 8a4c4a329a..213354fcb9 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -329,6 +329,15 @@ foreach ($supported_dbms as $dbms) // Write columns one by one... foreach ($table_data['COLUMNS'] as $column_name => $column_data) { + if (strlen($column_name) > 30) + { + trigger_error("Column name '$column_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); + } + if (isset($column_data[2]) && $column_data[2] == 'auto_increment' && strlen($column_name) > 26) // "${column_name}_gen" + { + trigger_error("Index name '${column_name}_gen' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); + } + // Get type if (strpos($column_data[0], ':') !== false) { @@ -632,6 +641,11 @@ foreach ($supported_dbms as $dbms) $key_data[1] = array($key_data[1]); } + if (strlen($table_name . $key_name) > 30) + { + trigger_error("Index name '${table_name}_$key_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); + } + switch ($dbms) { case 'mysql_40': @@ -1209,6 +1223,24 @@ function get_schema_struct() ), ); + $schema_data['phpbb_login_attempts'] = array( + 'COLUMNS' => array( + 'attempt_ip' => array('VCHAR:40', ''), + 'attempt_browser' => array('VCHAR:150', ''), + 'attempt_forwarded_for' => array('VCHAR:255', ''), + 'attempt_time' => array('TIMESTAMP', 0), + 'user_id' => array('UINT', 0), + 'username' => array('VCHAR_UNI:255', 0), + 'username_clean' => array('VCHAR_CI', 0), + ), + 'KEYS' => array( + 'att_ip' => array('INDEX', array('attempt_ip', 'attempt_time')), + 'att_for' => array('INDEX', array('attempt_forwarded_for', 'attempt_time')), + 'att_time' => array('INDEX', array('attempt_time')), + 'user_id' => array('INDEX', 'user_id'), + ), + ); + $schema_data['phpbb_moderator_cache'] = array( 'COLUMNS' => array( 'forum_id' => array('UINT', 0), @@ -1413,6 +1445,7 @@ function get_schema_struct() 'field_validation' => array('VCHAR_UNI:20', ''), 'field_required' => array('BOOL', 0), 'field_show_on_reg' => array('BOOL', 0), + 'field_show_on_pm' => array('BOOL', 0), 'field_show_on_vt' => array('BOOL', 0), 'field_show_profile' => array('BOOL', 0), 'field_hide' => array('BOOL', 0), diff --git a/phpBB/develop/create_variable_overview.php b/phpBB/develop/create_variable_overview.php index 46314ca8d1..b42d1aebe2 100644 --- a/phpBB/develop/create_variable_overview.php +++ b/phpBB/develop/create_variable_overview.php @@ -44,7 +44,7 @@ fwrite($fp, $contents); fclose($fp); $html_skeleton = ' -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="subSilver.css" type="text/css"> @@ -83,7 +83,7 @@ $html_skeleton .= '<br><br><a name="ref"></a><b>References: </b>{SEE_FILES}'; $html_skeleton .= ' <br><br> -<div class="copyright" align="center">Powered by phpBB 2.2 © <a href="http://www.phpbb.com/" target="_phpbb" class="copyright">phpBB Group</a>, 2003</div> +<div class="copyright" align="center">Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group</div> <br clear="all" /></td> </tr> @@ -362,7 +362,7 @@ echo '<br>Store Files'; $fp = fopen($store_dir . 'index.html', 'w'); $html_data = ' -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="subSilver.css" type="text/css"> @@ -405,7 +405,7 @@ $html_data .= '<br><li><a href="./lang_index.html" class="gen">Appendix A: Langu $html_data .= ' </ol><br><br> -<div class="copyright" align="center">Powered by phpBB 2.2 © <a href="http://www.phpbb.com/" target="_phpbb" class="copyright">phpBB Group</a>, 2003</div> +<div class="copyright" align="center">Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group</div> <br clear="all" /></td> </tr> @@ -427,7 +427,7 @@ fwrite($common_fp, "<?php\n\n \$lang = array(\n"); $fp = fopen($store_dir . 'lang_index.html', 'w'); $html_data = ' -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="subSilver.css" type="text/css"> @@ -528,7 +528,7 @@ foreach ($lang_fp as $filepointer) $html_data .= ' <br><br> -<div class="copyright" align="center">Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group</div> +<div class="copyright" align="center">Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group</div> <br clear="all" /></td> </tr> diff --git a/phpBB/develop/mysql_upgrader.php b/phpBB/develop/mysql_upgrader.php index 6c052b03eb..ca3e87dcc6 100644 --- a/phpBB/develop/mysql_upgrader.php +++ b/phpBB/develop/mysql_upgrader.php @@ -253,7 +253,7 @@ foreach ($schema_data as $table_name => $table_data) // Do we now need to re-add the fulltext index? ;) if ($table_name == ($prefix . 'posts') && $drop_index) { - echo "ALTER TABLE $table_name ADD FULLTEXT (post_subject), ADD FULLTEXT (post_text), ADD FULLTEXT post_content (post_subject, post_text){$newline}"; + echo "ALTER TABLE $table_name ADD FULLTEXT (post_subject), ADD FULLTEXT (post_text), ADD FULLTEXT post_content (post_subject, post_text);{$newline}"; } } diff --git a/phpBB/docs/AUTHORS b/phpBB/docs/AUTHORS index 83feca009b..81bc9f52e6 100644 --- a/phpBB/docs/AUTHORS +++ b/phpBB/docs/AUTHORS @@ -23,13 +23,12 @@ involved in phpBB. phpBB Lead Developer: naderman (Nils Adermann) phpBB Developers: Acyd Burn (Meik Sievertsen) [Lead 09/2005 - 01/2010] - APTX (Marek A. R.) bantu (Andreas Fischer) ckwalsh (Cullen Walsh) igorw (Igor Wiedler) kellanved (Henry Sudhof) nickvergessen (Joas Schilling) - nn- (Oleg Pudeyev) + Oleg (Oleg Pudeyev) rxu (Ruslan Uzdenov) ToonArmy (Chris Smith) @@ -46,6 +45,7 @@ phpBB Project Manager: theFinn (James Atkinson) [Founder - 04/2007] phpBB Lead Developer: psoTFX (Paul S. Owen) [2001 - 09/2005] phpBB Developers: A_Jelly_Doughnut (Josh Woody) [01/2010 - 11/2010] + APTX (Marek A. Ruszczyński) [12/2007 - 04/2011] Ashe (Ludovic Arnaud) [10/2002 - 11/2003, 06/2006 - 10/2006] BartVB (Bart van Bragt) [11/2000 - 03/2006] DavidMJ (David M.) [12/2005 - 08/2009] diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index 253df4ac56..d0511c0336 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -1,14 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en" xml:lang="en"> +<!DOCTYPE html> +<html dir="ltr" lang="en"> <head> - -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="en" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> -<meta name="copyright" content="phpBB Group" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="phpBB 3.0.x Changelog" /> <title>phpBB3 • Changelog</title> @@ -53,6 +46,7 @@ <ol> <li><a href="#changelog">Changelog</a> <ol style="list-style-type: lower-roman;"> + <li><a href="#v308">Changes since 3.0.8</a></li> <li><a href="#v307-PL1">Changes since 3.0.7-PL1</a></li> <li><a href="#v307">Changes since 3.0.7</a></li> <li><a href="#v306">Changes since 3.0.6</a></li> @@ -89,7 +83,375 @@ <div class="content"> - <a name="v307-PL1"></a><h3>1.i. Changes since 3.0.7-PL1</h3> + <a name="v308"></a><h3>1.i. Changes since 3.0.8</h3> + +<h4> Bug +</h4> +<ul> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-217'>PHPBB3-217</a>] - Multiline [url] not Converted +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-6712'>PHPBB3-6712</a>] - Topic bumping does not create new topic icon on index +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-7057'>PHPBB3-7057</a>] - Quicksearch uses POST, thus the page expires! +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-7778'>PHPBB3-7778</a>] - Increase limit of custom BBcodes +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-7834'>PHPBB3-7834</a>] - Correctly update topic_time when deleting first post in topic +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-7888'>PHPBB3-7888</a>] - URL of search results page does not always contain all keywords of the search query +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-7941'>PHPBB3-7941</a>] - mistake in description of function generate_board_url +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-8138'>PHPBB3-8138</a>] - Browser autocompleton fills wrong fields in ACP +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-8736'>PHPBB3-8736</a>] - Honour ACP settings for min/max username length when posting as a guest. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-8802'>PHPBB3-8802</a>] - Wrong confirmation text when clicking "mark forums read" in a category +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-8904'>PHPBB3-8904</a>] - Show numeric CPF default value when editing +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9166'>PHPBB3-9166</a>] - Subsilver and prosilver CSS elements out of order. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9348'>PHPBB3-9348</a>] - Correctly encode default_dateformat when converting from phpBB2 +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9575'>PHPBB3-9575</a>] - The word "administrate" is not correct. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9630'>PHPBB3-9630</a>] - Naming inconsistency of Merging Posts / Topics in MCP +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9675'>PHPBB3-9675</a>] - Add option to delete template/theme/imageset when deleting style. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9685'>PHPBB3-9685</a>] - Unable to create "Fulltext native" search index using the mssqlnative DBAL +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9751'>PHPBB3-9751</a>] - Password requirement "Must contain letters and numbers" is not working properly +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9764'>PHPBB3-9764</a>] - Empty value for CONFIG_TABLE config_name= 'mime_triggers' causes functions_fileupload.php->fileupload->check_content() to be too restrictive +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9851'>PHPBB3-9851</a>] - "Search new posts" should require login +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9872'>PHPBB3-9872</a>] - Total topics isn't correct after I deleted a user +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9874'>PHPBB3-9874</a>] - view_log() performs unneeded count query over all log entries. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9892'>PHPBB3-9892</a>] - Firebird index name length limit is not taken into account +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9905'>PHPBB3-9905</a>] - DSN field should include SQLite +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9908'>PHPBB3-9908</a>] - Send "Moved Permanently" before stripping off session ids for Bots. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9910'>PHPBB3-9910</a>] - Javascript bug in Subsilver2 PMs +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9911'>PHPBB3-9911</a>] - Incorrect open/close field in Manage ranks ACP +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9913'>PHPBB3-9913</a>] - currunt should be current +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9915'>PHPBB3-9915</a>] - "Length of ban:" is not displayed in ACP +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9924'>PHPBB3-9924</a>] - $template->display hook does not pass $template instance +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9925'>PHPBB3-9925</a>] - prosilver logo margin bug in IE 6-7-8 +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9928'>PHPBB3-9928</a>] - Do not link "login to your board" to the "send statistics" page after completed update. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9930'>PHPBB3-9930</a>] - Redirect fails with open_basedir enabled +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9932'>PHPBB3-9932</a>] - The Bing bot is not added when converting. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9933'>PHPBB3-9933</a>] - Wrong handling of consecutive multiple asterisks in word censor +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9934'>PHPBB3-9934</a>] - Mass Mail missing under the system tab on a fresh install +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9939'>PHPBB3-9939</a>] - JavaScript error in recaptcha ACP template +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9944'>PHPBB3-9944</a>] - Extension groups naming don't use users' language in ACP +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9946'>PHPBB3-9946</a>] - $inserts empty in sql_query() for oracle +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9948'>PHPBB3-9948</a>] - Inline quicktime files won't display +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9949'>PHPBB3-9949</a>] - $user->lang() is not handling arguments as per documentation +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9950'>PHPBB3-9950</a>] - Problem with localized button images after uprading from 3.0.7-PL1 to 3.0.8 +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9953'>PHPBB3-9953</a>] - Set focus to password on re-authentication +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9954'>PHPBB3-9954</a>] - u_masspm* permissions are forced to never for certain groups +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9961'>PHPBB3-9961</a>] - Inconsistent activation logs +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9966'>PHPBB3-9966</a>] - Language download in ACP creates index.html and misses captcha_* +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9970'>PHPBB3-9970</a>] - user_lang input not checked during registration +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9981'>PHPBB3-9981</a>] - Fix unit test dependencies on phpBB files +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9985'>PHPBB3-9985</a>] - 3D Wave CAPTCHA mt_rand() does not check order of min/max values +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9997'>PHPBB3-9997</a>] - Inconsistent approve/disapprove button order in modcp +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9999'>PHPBB3-9999</a>] - {forumrow.L_FORUM_FOLDER_ALT} and {SEARCH_IMG} only return a language key. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10005'>PHPBB3-10005</a>] - users can register without custom profile field correctly entered +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10011'>PHPBB3-10011</a>] - __DIR__ in test suite renders it unusable on php < 5.3 +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10016'>PHPBB3-10016</a>] - set_config_count() fails on PostreSQL 7 +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10020'>PHPBB3-10020</a>] - ACP function validate_range() fails partially on non-32-bit systems +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10021'>PHPBB3-10021</a>] - "Find a member" generates SQL error when large dates are entered +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10029'>PHPBB3-10029</a>] - No such thing as $_SERVER['HTTP_VERSION'] +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10033'>PHPBB3-10033</a>] - "Disallow usernames" does not check already disallowed names +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10035'>PHPBB3-10035</a>] - ACP template edit feature allows to read any files on webserver and to upload/execute any script on it +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10036'>PHPBB3-10036</a>] - Use image from configuration file for displaying online-status. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10038'>PHPBB3-10038</a>] - download/file.php uses $_GET value instead of function request_var() +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10039'>PHPBB3-10039</a>] - 2.x to 3.x conversion fails when using mssqlnative to connect to destination database +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10042'>PHPBB3-10042</a>] - GD captcha has invalid mt_rand calls +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10047'>PHPBB3-10047</a>] - Session ID always included in URL on posting.php +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10049'>PHPBB3-10049</a>] - Session test files are misnamed, session tests are not run +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10052'>PHPBB3-10052</a>] - Session tests are broken +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10056'>PHPBB3-10056</a>] - Firebird misspelled in database updater +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10058'>PHPBB3-10058</a>] - Root path is undefined in MySQL upgrader +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10059'>PHPBB3-10059</a>] - Consistent is misspelled twice +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10060'>PHPBB3-10060</a>] - Typo in tests database connection manager +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10068'>PHPBB3-10068</a>] - Firefox4 restrictions to :visited +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10078'>PHPBB3-10078</a>] - commit-msg hook prints \n on freebsd +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10081'>PHPBB3-10081</a>] - Cleanup Template Tests +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10084'>PHPBB3-10084</a>] - Add smilie errors out when image is missing +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10088'>PHPBB3-10088</a>] - Cache mock does not unset database versions other than mysqli +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10090'>PHPBB3-10090</a>] - cache/queue.php.lock isn't covered by .gitignore +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10092'>PHPBB3-10092</a>] - commit-msg hook aborts on overlength comment lines +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10096'>PHPBB3-10096</a>] - Wrong whitespace in functions.php +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10100'>PHPBB3-10100</a>] - Race condition in unique_id() on heavily busy database. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10102'>PHPBB3-10102</a>] - member.S_PENDING_SET in styles/prosilver/template/ucp_groups_manage.html +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10104'>PHPBB3-10104</a>] - missing one intval() along with others already being there +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10109'>PHPBB3-10109</a>] - Errors while copying a topic +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10112'>PHPBB3-10112</a>] - Use of count() in captcha_gd.php and mssqlnative.php +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10115'>PHPBB3-10115</a>] - BBcodes not working if post contains about or more 55000 non-english symbols +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10117'>PHPBB3-10117</a>] - Big posts becomes empty if they have smilies on specified places. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10121'>PHPBB3-10121</a>] - ICQ profile link leads to a webservice that is no longer active +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10123'>PHPBB3-10123</a>] - Inconsistent use of smilie/smiley +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10128'>PHPBB3-10128</a>] - Error message is on green background when trying to ban a nonexistent user +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10137'>PHPBB3-10137</a>] - Deleting an unintended space at the end of PHP_URL_FOPEN_SUPPORT_EXPLAIN +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10146'>PHPBB3-10146</a>] - Firebird cannot handle DECIMAL(255, 0) +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10147'>PHPBB3-10147</a>] - Typo in code comment in functions_template.php +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10149'>PHPBB3-10149</a>] - deregister_globals causes error when cookie called GLOBALS is set to scalar value +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10170'>PHPBB3-10170</a>] - reCAPTCHA address has changed +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10171'>PHPBB3-10171</a>] - Firefox4 displays grey pixels at PM message rows when message is neither marked nor replied +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10177'>PHPBB3-10177</a>] - phpBB package cannot be built with bsdtar +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10178'>PHPBB3-10178</a>] - build.xml does not specify path to find - breaks on FreeBSD +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10188'>PHPBB3-10188</a>] - Broken compressed output when errors/warnings are handled by phpbb and output_buffering is set to 4096 and phpbb gzip is enabled +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10191'>PHPBB3-10191</a>] - Duplicate output when output_handler is set in php.ini +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10192'>PHPBB3-10192</a>] - Missing semicolon in MySQL Upgrader +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10195'>PHPBB3-10195</a>] - Do not check DNS Blacklists if IPv6 address is passed to session::check_dnsbl(). +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10198'>PHPBB3-10198</a>] - Function validate_config_vars() improperly validates multibyte strings +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10203'>PHPBB3-10203</a>] - Fix quotations and hyphen in language strings for PHPBB3-10067 +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10204'>PHPBB3-10204</a>] - Package build tool does not detect binary file changes +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10206'>PHPBB3-10206</a>] - Normalization tests fail when unicode.org is not reachable +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10211'>PHPBB3-10211</a>] - Missing space on the recent PHPBB3-9992 changes +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10213'>PHPBB3-10213</a>] - IP limit index name too long on Oracle +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10214'>PHPBB3-10214</a>] - Cannot configure Q&A on Oracle +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10218'>PHPBB3-10218</a>] - STRIP is not defined in style.php causing a notice to be thrown +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10219'>PHPBB3-10219</a>] - Inappropriate character in web.config file +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10220'>PHPBB3-10220</a>] - Logging in with Mobile Device triggers SQL error on *_login_attempts. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10221'>PHPBB3-10221</a>] - Inconsistent usage of "Seconds" in ACP Settings +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-7729'>PHPBB3-7729</a>] - Prevent date/time functions from throwing E_WARNING on PHP 5.3 by setting a default timezone +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10188'>PHPBB3-10188</a>] - Broken compressed output when errors/warnings are handled by phpbb and output_buffering is set to 4096 and phpbb gzip is enabled +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10223'>PHPBB3-10223</a>] - Updater references startup.php from board path +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10228'>PHPBB3-10228</a>] - Typo in 3.0.9-RC1 user registration settings +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10229'>PHPBB3-10229</a>] - On languge/acp/styles.php "%s" should be "%s" +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10232'>PHPBB3-10232</a>] - Search within topic/forum searches all posts +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10233'>PHPBB3-10233</a>] - IE Emulation fix breaks posting layout when PMing +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10234'>PHPBB3-10234</a>] - msg_handler() reports E_WARNING as "PHP Notice: " +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10247'>PHPBB3-10247</a>] - mediumint(8) too small for phpbb_login_attempts.attempt_id +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10250'>PHPBB3-10250</a>] - phpBB Logo needs the Registered Trademark Symbol +</li> +</ul> + +<h4> Improvement +</h4> +<ul> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9581'>PHPBB3-9581</a>] - Banned users get mass emails. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9802'>PHPBB3-9802</a>] - Optimize session_begin REMOTE_ADDR validation +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9878'>PHPBB3-9878</a>] - Get rid of Internet Explorer 7 emulation +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9897'>PHPBB3-9897</a>] - Language typos in language/en/acp/board.php +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9922'>PHPBB3-9922</a>] - Posting URL in subsilver 2 +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9937'>PHPBB3-9937</a>] - Feed Icon displays on Forum links +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9980'>PHPBB3-9980</a>] - URLs to javascript should be T_SUPER_TEMPLATE_PATH instead of T_TEMPLATE_PATH +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9989'>PHPBB3-9989</a>] - Skip PM popup in overall_header.html, if there are no new PMs. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10007'>PHPBB3-10007</a>] - Add directive 'internal' to blocked folders in nginx example configuration. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10009'>PHPBB3-10009</a>] - Differentiate published/updated dates in Atom feed +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10014'>PHPBB3-10014</a>] - Make the error message when cache is not writable clearer +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10024'>PHPBB3-10024</a>] - Allow a Style to present Unread PM in different way than read PM +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10040'>PHPBB3-10040</a>] - Continuous integration on PHP 5.2 +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10041'>PHPBB3-10041</a>] - download/file.php needs more use of send_status_line +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10044'>PHPBB3-10044</a>] - Setup github network improvements +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10057'>PHPBB3-10057</a>] - More informative reporting of errors when database connection fails for Firebird and PostgreSQL. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10067'>PHPBB3-10067</a>] - ACP options for account activation are confusing when emails are turned off board-wide +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10069'>PHPBB3-10069</a>] - Improvements in sample nginx config file +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10072'>PHPBB3-10072</a>] - Send the post number to the template as it relates to it's position in the topic +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10101'>PHPBB3-10101</a>] - Compatibility with native phpass hashes +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10126'>PHPBB3-10126</a>] - Replace ^ with &~ in error_reporting calls +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10141'>PHPBB3-10141</a>] - Performance improvement for $auth->_fill_acl() +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10145'>PHPBB3-10145</a>] - Ability to force recompilation of all templates on every page load +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10154'>PHPBB3-10154</a>] - Move "copy permissions from" to below "parent" in forum creation form +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10158'>PHPBB3-10158</a>] - Return link not really useful after sending a Private Message +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10186'>PHPBB3-10186</a>] - UCP signature panel displays when not authed for signatures +</li> +</ul> + +<h4> New Feature +</h4> +<ul> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9942'>PHPBB3-9942</a>] - WinCache Caching Module +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9992'>PHPBB3-9992</a>] - Limit amount of failed login attempts per IP +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10110'>PHPBB3-10110</a>] - Redis caching module +</li> +</ul> + +<h4> Task +</h4> +<ul> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9788'>PHPBB3-9788</a>] - Add README for GitHub +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9805'>PHPBB3-9805</a>] - Add a script for setting up git remotes for a github network +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9806'>PHPBB3-9806</a>] - Script for easy merging +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9824'>PHPBB3-9824</a>] - Git hook quirks +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9859'>PHPBB3-9859</a>] - Remove the years from visible copyright in the footer. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9921'>PHPBB3-9921</a>] - Add sample configuration for lighttpd webserver +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9943'>PHPBB3-9943</a>] - Setup phpDocumentor API documentation generation +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9967'>PHPBB3-9967</a>] - Use phpunit.xml for test suite +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9987'>PHPBB3-9987</a>] - Enforce _test.php suffix for test files +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9990'>PHPBB3-9990</a>] - Integrate utf normalizer tests into test suite +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10043'>PHPBB3-10043</a>] - Refactor phpbb_database_test_case +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10046'>PHPBB3-10046</a>] - Getting rid of register_shutdown_function() in cron.php to prevent path disclosure (reported by lacton) +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10075'>PHPBB3-10075</a>] - Update docs/AUTHORS for 3.0.9-RC1 release +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10079'>PHPBB3-10079</a>] - Add gallery avatars to .gitignore. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10082'>PHPBB3-10082</a>] - Fix Session Test Issues with CHAR vs. VARCHAR. +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10105'>PHPBB3-10105</a>] - Update AIM express link and "Download Application" links +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-10107'>PHPBB3-10107</a>] - Improve docs for non-apache webserver configuration +</li> +</ul> + +<h4> Sub-task +</h4> +<ul> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9732'>PHPBB3-9732</a>] - Cover session code extensively in tests +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9968'>PHPBB3-9968</a>] - Create unit test for word censor regular expression +</li> +<li>[<a href='http://tracker.phpbb.com/browse/PHPBB3-9969'>PHPBB3-9969</a>] - Move word censor regular expression creation into separate function definition in functions.php +</li> +</ul> + + + <a name="v307-PL1"></a><h3>1.ii. Changes since 3.0.7-PL1</h3> <h4> Security </h4> <ul> @@ -547,13 +909,13 @@ </ul> - <a name="v307"></a><h3>1.ii. Changes since 3.0.7</h3> + <a name="v307"></a><h3>1.iii. Changes since 3.0.7</h3> <ul> <li>[Sec] Do not expose forum content of forums with ACL entries but no actual permission in ATOM Feeds. (Bug #58595)</li> </ul> - <a name="v306"></a><h3>1.iii. Changes since 3.0.6</h3> + <a name="v306"></a><h3>1.iv. Changes since 3.0.6</h3> <ul> <li>[Fix] Allow ban reason and length to be selected and copied in ACP and subsilver2 MCP. (Bug #51095)</li> @@ -657,7 +1019,7 @@ </ul> - <a name="v305"></a><h3>1.iv. Changes since 3.0.5</h3> + <a name="v305"></a><h3>1.v. Changes since 3.0.5</h3> <ul> <li>[Fix] Allow whitespaces in avatar gallery names. (Bug #44955)</li> @@ -879,7 +1241,7 @@ <li>[Feature] Send anonymous statistical information to phpBB on installation and update (optional).</li> </ul> - <a name="v304"></a><h3>1.v. Changes since 3.0.4</h3> + <a name="v304"></a><h3>1.vi. Changes since 3.0.4</h3> <ul> <li>[Fix] Delete user entry from ban list table upon user deletion (Bug #40015 - Patch by TerraFrost)</li> @@ -968,7 +1330,7 @@ <li>[Sec] Only use forum id supplied for posting if global announcement detected. (Reported by nickvergessen)</li> </ul> - <a name="v303"></a><h3>1.vi. Changes since 3.0.3</h3> + <a name="v303"></a><h3>1.vii. Changes since 3.0.3</h3> <ul> <li>[Fix] Allow mixed-case template directories to be inherited (Bug #36725)</li> @@ -1000,7 +1362,7 @@ <li>[Sec] Ask for forum password if post within passworded forum quoted in private message. (Reported by nickvergessen)</li> </ul> - <a name="v302"></a><h3>1.vii. Changes since 3.0.2</h3> + <a name="v302"></a><h3>1.viii. Changes since 3.0.2</h3> <ul> <li>[Fix] Correctly set topic starter if first post in topic removed (Bug #30575 - Patch by blueray2048)</li> @@ -1099,7 +1461,7 @@ <li>[Sec Precaution] Stricter validation of the HTTP_HOST header (Thanks to Techie-Micheal et al for pointing out possible issues in derived code)</li> </ul> - <a name="v301"></a><h3>1.viii. Changes since 3.0.1</h3> + <a name="v301"></a><h3>1.ix. Changes since 3.0.1</h3> <ul> <li>[Fix] Ability to set permissions on non-mysql dbms (Bug #24955)</li> @@ -1147,7 +1509,7 @@ <li>[Sec] Only allow urls gone through redirect() being used within login_box(). (thanks nookieman)</li> </ul> - <a name="v300"></a><h3>1.ix Changes since 3.0.0</h3> + <a name="v300"></a><h3>1.x Changes since 3.0.0</h3> <ul> <li>[Change] Validate birthdays (Bug #15004)</li> @@ -1218,7 +1580,7 @@ <li>[Fix] Find and display colliding usernames correctly when converting from one database to another (Bug #23925)</li> </ul> - <a name="v30rc8"></a><h3>1.x. Changes since 3.0.RC8</h3> + <a name="v30rc8"></a><h3>1.xi. Changes since 3.0.RC8</h3> <ul> <li>[Fix] Cleaned usernames contain only single spaces, so "a_name" and "a__name" are treated as the same name (Bug #15634)</li> @@ -1227,7 +1589,7 @@ <li>[Fix] Call garbage_collection() within database updater to correctly close connections (affects Oracle for example)</li> </ul> - <a name="v30rc7"></a><h3>1.xi. Changes since 3.0.RC7</h3> + <a name="v30rc7"></a><h3>1.xii. Changes since 3.0.RC7</h3> <ul> <li>[Fix] Fixed MSSQL related bug in the update system</li> @@ -1262,7 +1624,7 @@ <li>[Fix] No duplication of active topics (Bug #15474)</li> </ul> - <a name="v30rc6"></a><h3>1.xii. Changes since 3.0.RC6</h3> + <a name="v30rc6"></a><h3>1.xiii. Changes since 3.0.RC6</h3> <ul> <li>[Fix] Submitting language changes using acp_language (Bug #14736)</li> @@ -1272,7 +1634,7 @@ <li>[Fix] Able to request new password (Bug #14743)</li> </ul> - <a name="v30rc5"></a><h3>1.xiii. Changes since 3.0.RC5</h3> + <a name="v30rc5"></a><h3>1.xiv. Changes since 3.0.RC5</h3> <ul> <li>[Feature] Removing constant PHPBB_EMBEDDED in favor of using an exit_handler(); the constant was meant to achive this more or less.</li> @@ -1335,7 +1697,7 @@ <li>[Sec] New password hashing mechanism for storing passwords (#i42)</li> </ul> - <a name="v30rc4"></a><h3>1.xiv. Changes since 3.0.RC4</h3> + <a name="v30rc4"></a><h3>1.xv. Changes since 3.0.RC4</h3> <ul> <li>[Fix] MySQL, PostgreSQL and SQLite related database fixes (Bug #13862)</li> @@ -1386,7 +1748,7 @@ <li>[Fix] odbc_autocommit causing existing result sets to be dropped (Bug #14182)</li> </ul> - <a name="v30rc3"></a><h3>1.xv. Changes since 3.0.RC3</h3> + <a name="v30rc3"></a><h3>1.xvi. Changes since 3.0.RC3</h3> <ul> <li>[Fix] Fixing some subsilver2 and prosilver style issues</li> @@ -1495,7 +1857,7 @@ </ul> - <a name="v30rc2"></a><h3>1.xvi. Changes since 3.0.RC2</h3> + <a name="v30rc2"></a><h3>1.xvii. Changes since 3.0.RC2</h3> <ul> <li>[Fix] Re-allow searching within the memberlist</li> @@ -1541,7 +1903,7 @@ </ul> - <a name="v30rc1"></a><h3>1.xvii. Changes since 3.0.RC1</h3> + <a name="v30rc1"></a><h3>1.xviii. Changes since 3.0.RC1</h3> <ul> <li>[Fix] (X)HTML issues within the templates (Bug #11255, #11255)</li> diff --git a/phpBB/docs/FAQ.html b/phpBB/docs/FAQ.html index 83d7a342e0..14925bd530 100644 --- a/phpBB/docs/FAQ.html +++ b/phpBB/docs/FAQ.html @@ -1,14 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en" xml:lang="en"> +<!DOCTYPE html> +<html dir="ltr" lang="en"> <head> - -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="en" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> -<meta name="copyright" content="phpBB Group" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="phpBB 3.0.x frequently asked questions" /> <title>phpBB3 • FAQ</title> diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html index 9f635fe50b..fcd4c759dc 100644 --- a/phpBB/docs/INSTALL.html +++ b/phpBB/docs/INSTALL.html @@ -1,14 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en" xml:lang="en"> +<!DOCTYPE html> +<html dir="ltr" lang="en"> <head> - -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="en" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> -<meta name="copyright" content="phpBB Group" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="phpBB 3.0.x Installation, updating and conversion informations" /> <title>phpBB3 • Install</title> @@ -145,7 +138,7 @@ <li>Oracle</li> </ul> </li> - <li><strong>PHP 4.3.3+ (>=4.3.3, >4.4.x, >5.x.x, >6.0-dev (compatible))</strong> with support for the database you intend to use.</li> + <li><strong>PHP 5.2.0+</strong> with support for the database you intend to use.</li> <li>getimagesize() function need to be enabled.</li> <li>These optional presence of the following modules within PHP will provide access to additional features, but they are not required. <ul> @@ -274,7 +267,7 @@ <p>This package is meant for those wanting to only replace changed files from a previous version to the latest version. This package normally contains the changed files from up to five previous versions.</p> - <p>This package contains a number of archives, each contains the files changed from a given release to the latest version. You should select the appropriate archive for your current version, e.g. if you currently have <samp>3.0.7-PL1</samp> you should select the phpBB-3.0.7-PL1_to_3.0.8.zip/tar.gz file.</p> + <p>This package contains a number of archives, each contains the files changed from a given release to the latest version. You should select the appropriate archive for your current version, e.g. if you currently have <samp>3.0.8</samp> you should select the phpBB-3.0.8_to_3.0.9.zip/tar.gz file.</p> <p>The directory structure has been preserved enabling you (if you wish) to simply upload the contents of the archive to the appropriate location on your server, i.e. simply overwrite the existing files with the new versions. Do not forget that if you have installed any MODs these files will overwrite the originals possibly destroying them in the process. You will need to re-add MODs to any affected file before uploading.</p> @@ -286,7 +279,7 @@ <p>The patch file is one solution for those with many Modifications (MODs) or other changes who do not want to re-add them back to all the changed files if they use the method explained above. To use this you will need command line access to a standard UNIX type <strong>patch</strong> application. If you do not have access to such an application but still want to use this update approach, we strongly recommend the <a href="#update_auto">Automatic update package</a> explained below. It is also the recommended update method.</p> - <p>A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is 3.0.5 you need the phpBB-3.0.7-PL1_to_3.0.8.patch file. Place the correct patch in the parent directory containing the phpBB3 core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: <strong>patch -cl -d [PHPBB DIRECTORY] -p1 < [PATCH NAME]</strong> (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB3, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.</p> + <p>A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is <samp>3.0.8</samp> you need the phpBB-3.0.8_to_3.0.9.patch file. Place the correct patch in the parent directory containing the phpBB3 core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: <strong>patch -cl -d [PHPBB DIRECTORY] -p1 < [PATCH NAME]</strong> (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB3, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.</p> <p>If you do get failures you should look at using the <a href="#update_files">Changed files only</a> package to replace the files which failed to patch, please note that you will need to manually re-add any Modifications (MODs) to these particular files. Alternatively if you know how you can examine the .rej files to determine what failed where and make manual adjustments to the relevant source.</p> diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index 7a0a42b34f..e1d9e80f37 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -1,14 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en" xml:lang="en"> +<!DOCTYPE html> +<html dir="ltr" lang="en"> <head> - -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="en" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> -<meta name="copyright" content="phpBB Group" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="phpBB 3.0.x Readme" /> <title>phpBB3 • Readme</title> @@ -313,11 +306,11 @@ <div class="content"> - <p>phpBB is no longer supported on PHP3 due to several compatibility issues and we recommend that you upgrade to the latest stable release of PHP5 to run phpBB. The minimum version required is PHP 4.3.3.</p> + <p>phpBB is no longer supported on PHP4 due to several compatibility issues and we recommend that you upgrade to the latest stable release of PHP5 to run phpBB. The minimum version required is PHP 5.2.0.</p> <p>Please remember that running any application on a developmental version of PHP can lead to strange/unexpected results which may appear to be bugs in the application (which may not be true). Therefore we recommend you upgrade to the newest stable version of PHP before running phpBB3. If you are running a developmental version of PHP please check any bugs you find on a system running a stable release before submitting.</p> - <p>This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MSSQL Server 2000, PostgreSQL 7.x, Oracle 8, SQLite and Firebird. Versions of PHP used range from 4.3.3 to 6.0.0-dev without problem. </p> + <p>This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MSSQL Server 2000, PostgreSQL 7.x, Oracle 8, SQLite and Firebird. Versions of PHP used range from 5.2.0 to 5.3.x without problem.</p> <a name="phpsec"></a><h3>7.i. Notice on PHP security issues</h3> diff --git a/phpBB/docs/auth_api.html b/phpBB/docs/auth_api.html index 88618fa640..200a8d815c 100644 --- a/phpBB/docs/auth_api.html +++ b/phpBB/docs/auth_api.html @@ -1,14 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en" xml:lang="en"> +<!DOCTYPE html> +<html dir="ltr" lang="en"> <head> - -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="en" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> -<meta name="copyright" content="phpBB Group" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="This is an explanation of how to use the phpBB auth/acl API" /> <title>phpBB3 • Auth API</title> diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index 8365e3c301..6f952368ee 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -1,14 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en" xml:lang="en"> +<!DOCTYPE html> +<html dir="ltr" lang="en"> <head> - -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="en" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> -<meta name="copyright" content="phpBB Group" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="Olympus coding guidelines document" /> <title>phpBB3 • Coding Guidelines</title> @@ -1770,7 +1763,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>With phpBB3, the output encoding for the forum in now UTF-8, a Universal Character Encoding by the Unicode Consortium that is by design a superset to US-ASCII and ISO-8859-1. By using one character set which simultaenously supports all scripts which previously would have required different encodings (eg: ISO-8859-1 to ISO-8859-15 (Latin, Greek, Cyrillic, Thai, Hebrew, Arabic); GB2312 (Simplified Chinese); Big5 (Traditional Chinese), EUC-JP (Japanese), EUC-KR (Korean), VISCII (Vietnamese); et cetera), this removes the need to convert between encodings and improves the accessibility of multilingual forums.</p> - <p>The impact is that the language files for phpBB must now also be encoded as UTF-8, with a caveat that the files must <strong>not contain</strong> a <acronym title="Byte-Order-Mark">BOM</acronym> for compatibility reasons with non-Unicode aware versions of PHP. For those with forums using the Latin character set (ie: most European languages), this change is transparent since UTF-8 is superset to US-ASCII and ISO-8859-1.</p> + <p>The impact is that the language files for phpBB must now also be encoded as UTF-8, with a caveat that the files must <strong>not contain</strong> a <abbr title="Byte-Order-Mark">BOM</abbr> for compatibility reasons with non-Unicode aware versions of PHP. For those with forums using the Latin character set (ie: most European languages), this change is transparent since UTF-8 is superset to US-ASCII and ISO-8859-1.</p> <h4>Language Tag:</h4> @@ -1780,8 +1773,8 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>Most language tags consist of a two- or three-letter language subtag (from <a href="http://www.loc.gov/standards/iso639-2/php/English_list.php">ISO 639-1/ISO 639-2</a>). Sometimes, this is followed by a two-letter or three-digit region subtag (from <a href="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166-1 alpha-2</a> or <a href="http://unstats.un.org/unsd/methods/m49/m49.htm">UN M.49</a>). Some examples are:</p> - <table summary="Examples of various possible language tags as described by RFC 4646 and RFC 4647"> - <caption>Language tag examples</caption> + <table> + <caption>Examples of various possible language tags as described by RFC 4646 and RFC 4647</caption> <thead> <tr> <th scope="col">Language tag</th> @@ -1832,8 +1825,8 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>Next is the <a href="http://www.unicode.org/iso15924/iso15924-codes.html">ISO 15924</a> language script code and when one should or shouldn't use it. For example, whilst <code>en-Latn</code> is syntaxically correct for describing English written with Latin script, real world English writing is <strong>more-or-less exclusively in the Latin script</strong>. For such languages like English that are written in a single script, the <a href="http://www.iana.org/assignments/language-subtag-registry"><abbr title="Internet Assigned Numbers Authority">IANA</abbr> Language Subtag Registry</a> has a "Suppress-Script" field meaning the script code <strong>should be ommitted</strong> unless a specific language tag requires a specific script code. Some languages are <strong>written in more than one script</strong> and in such cases, the script code <strong>is encouraged</strong> since an end-user may be able to read their language in one script, but not the other. Some examples are:</p> - <table summary="Examples of using a language subtag in combination with a script subtag"> - <caption>Language subtag + script subtag examples</caption> + <table> + <caption>Examples of using a language subtag in combination with a script subtag</caption> <thead> <tr> <th scope="col">Language tag</th> @@ -1899,8 +1892,8 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>Examples of English using marco-geographical regions:</p> - <table summary="Examples for English of ISO 3166-1 alpha-2 vs. UN M.49 code"> - <caption>Coding for English using macro-geographical regions</caption> + <table> + <caption>Coding for English using macro-geographical regions (examples for English of ISO 3166-1 alpha-2 vs. UN M.49 code)</caption> <thead> <tr> <th scope="col">ISO 639-1/ISO 639-2 + ISO 3166-1 alpha-2</th> @@ -1925,8 +1918,8 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>Examples of Spanish using marco-geographical regions:</p> - <table summary="Examples for Spanish of ISO 3166-1 alpha-2 vs. UN M.49 code"> - <caption>Coding for Spanish macro-geographical regions</caption> + <table> + <caption>Coding for Spanish macro-geographical regions (examples for Spanish of ISO 3166-1 alpha-2 vs. UN M.49 code)</caption> <thead> <tr> <th scope="col">ISO 639-1/ISO 639-2 + ISO 3166-1 alpha-2</th> @@ -1954,7 +1947,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>Example of where the <a href="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166-1 alpha-2</a> is ambiguous and why <a href="http://unstats.un.org/unsd/methods/m49/m49.htm">UN M.49</a> might be preferred:</p> - <table summary="Example where the ISO 3166-1 alpha-2 is ambiguous"> + <table> <caption>Coding for ambiguous ISO 3166-1 alpha-2 regions</caption> <thead> <tr> @@ -2010,7 +2003,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p><a href="http://tools.ietf.org/html/rfc4646">RFC 4646</a> anticipates features which shall be available in (currently draft) <a href="http://www.sil.org/iso639-3/">ISO 639-3</a> which aims to provide as complete enumeration of languages as possible, including living, extinct, ancient and constructed languages, whether majour, minor or unwritten. A new feature of <a href="http://www.sil.org/iso639-3/">ISO 639-3</a> compared to the previous two revisions is the concept of <a href="http://www.sil.org/iso639-3/macrolanguages.asp">macrolanguages</a> where Arabic and Chinese are two such examples. In such cases, their respective codes of <code>ar</code> and <code>zh</code> is very vague as to which dialect/topolect is used or perhaps some terse classical variant which may be difficult for all but very educated users. For such macrolanguages, it is recommended that the sub-language tag is used as a suffix to the macrolanguage tag, eg:</p> - <table summary="Examples of macrolanguages used with sub-language subtags"> + <table> <caption>Macrolanguage subtag + sub-language subtag examples</caption> <thead> <tr> @@ -2054,7 +2047,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>For phpBB, the language tags are <strong>not</strong> used in their raw form and instead converted to all lower-case and have the hyphen <code>-</code> replaced with an underscore <code>_</code> where appropriate, with some examples below:</p> - <table summary="Normalisation of language tags for usage in phpBB"> + <table> <caption>Language tag normalisation examples</caption> <thead> <tr> @@ -2108,7 +2101,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>For the English language description, the language name is always first and any additional attributes required to describe the subtags within the language code are then listed in order separated with commas and enclosed within parentheses, eg:</p> - <table summary="English language description examples of iso.txt for usage in phpBB"> + <table> <caption>English language description examples for iso.txt</caption> <thead> <tr> @@ -2160,7 +2153,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>The various Unicode control characters for bi-directional text and their HTML enquivalents where appropriate are as follows:</p> - <table summary="Table of the various Unicode bidirectional control characters"> + <table> <caption>Unicode bidirectional control characters & HTML elements/entities</caption> <thead> <tr> @@ -2226,7 +2219,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>For <code>iso.txt</code>, the directionality of the text can be explicitly set using special Unicode characters via any of the three methods provided by left-to-right/right-to-left markers/embeds/overrides, as without them, the ordering of characters will be incorrect, eg:</p> - <table summary="Effect of using Unicode bidirectional control characters within iso.txt"> + <table> <caption>Unicode bidirectional control characters iso.txt</caption> <thead> <tr> @@ -2362,7 +2355,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <div class="codebox"><pre> ... -'FOO_BAR' => 'PHP version < 4.3.3.<br /> +'FOO_BAR' => 'PHP version < 5.2.0.<br /> Visit "Downloads" at <a href="http://www.php.net/">www.php.net</a>.', ... </pre></div> @@ -2371,7 +2364,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <div class="codebox"><pre> ... -'FOO_BAR' => 'PHP version &lt; 4.3.3.<br /> +'FOO_BAR' => 'PHP version &lt; 5.2.0.<br /> Visit &quot;Downloads&quot; at <a href="http://www.php.net/">www.php.net</a>.', ... </pre></div> @@ -2380,7 +2373,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <div class="codebox"><pre> ... -'FOO_BAR' => 'PHP version &lt; 4.3.3.<br /> +'FOO_BAR' => 'PHP version &lt; 5.2.0.<br /> Visit “Downloads” at <a href="http://www.php.net/">www.php.net</a>.', ... </pre></div> diff --git a/phpBB/docs/hook_system.html b/phpBB/docs/hook_system.html index 16774087ac..0dc25630a8 100644 --- a/phpBB/docs/hook_system.html +++ b/phpBB/docs/hook_system.html @@ -1,14 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en" xml:lang="en"> +<!DOCTYPE html> +<html dir="ltr" lang="en"> <head> - -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="en" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> -<meta name="copyright" content="phpBB Group" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="Hook System explanation" /> <title>phpBB3 • Hook System</title> diff --git a/phpBB/download/file.php b/phpBB/download/file.php index d33a50c149..735db70dfc 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -31,12 +31,7 @@ else if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT' if (isset($_GET['avatar'])) { - if (!defined('E_DEPRECATED')) - { - define('E_DEPRECATED', 8192); - } - error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED); - + require($phpbb_root_path . 'includes/startup.' . $phpEx); require($phpbb_root_path . 'config.' . $phpEx); if (!defined('PHPBB_INSTALLED') || empty($dbms) || empty($acm_type)) diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 3179be7de7..c62fefae46 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -61,6 +61,10 @@ class acp_attachments $l_title = 'ACP_ORPHAN_ATTACHMENTS'; break; + case 'manage': + $l_title = 'ACP_MANAGE_ATTACHMENTS'; + break; + default: trigger_error('NO_MODE', E_USER_ERROR); break; @@ -1043,6 +1047,230 @@ class acp_attachments $db->sql_freeresult($result); break; + + case 'manage': + + if ($submit) + { + $delete_files = (isset($_POST['delete'])) ? array_keys(request_var('delete', array('' => 0))) : array(); + + if (sizeof($delete_files)) + { + // Select those attachments we want to delete... + $sql = 'SELECT real_filename + FROM ' . ATTACHMENTS_TABLE . ' + WHERE ' . $db->sql_in_set('attach_id', $delete_files) . ' + AND is_orphan = 0'; + $result = $db->sql_query($sql); + while ($row = $db->sql_fetchrow($result)) + { + $deleted_filenames[] = $row['real_filename']; + } + $db->sql_freeresult($result); + + if ($num_deleted = delete_attachments('attach', $delete_files)) + { + if (sizeof($delete_files) != $num_deleted) + { + $error[] = $user->lang['FILES_GONE']; + } + add_log('admin', 'LOG_ATTACHMENTS_DELETED', implode(', ', $deleted_filenames)); + $notify[] = sprintf($user->lang['LOG_ATTACHMENTS_DELETED'], implode(', ', $deleted_filenames)); + } + else + { + $error[] = $user->lang['NO_FILES_TO_DELETE']; + } + } + } + + $template->assign_vars(array( + 'S_MANAGE' => true) + ); + + $start = request_var('start', 0); + + // Sort keys + $sort_days = request_var('st', 0); + $sort_key = request_var('sk', 't'); + $sort_dir = request_var('sd', 'd'); + + // Sorting + $limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); + $sort_by_text = array('f' => $user->lang['FILENAME'], 't' => $user->lang['FILEDATE'], 's' => $user->lang['FILESIZE'], 'x' => $user->lang['EXTENSION'], 'd' => $user->lang['DOWNLOADS'],'p' => $user->lang['ATTACH_POST_TYPE'], 'u' => $user->lang['AUTHOR']); + $sort_by_sql = array('f' => 'a.real_filename', 't' => 'a.filetime', 's' => 'a.filesize', 'x' => 'a.extension', 'd' => 'a.download_count', 'p' => 'a.in_message', 'u' => 'u.username'); + + $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = ''; + gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param); + + $min_filetime = ($sort_days) ? (time() - ($sort_days * 86400)) : ''; + $limit_filetime = ($min_filetime) ? " AND a.filetime >= $min_filetime " : ''; + $start = ($sort_days && isset($_POST['sort'])) ? 0 : $start; + + $attachments_per_page = (int) $config['topics_per_page']; + + // Handle files stats resync + $action = request_var('action', ''); + $resync_files_stats = false; + if ($action && $action = 'stats') + { + if (!confirm_box(true)) + { + confirm_box(false, $user->lang['RESYNC_FILES_STATS_CONFIRM'], build_hidden_fields(array( + 'i' => $id, + 'mode' => $mode, + 'action' => $action, + ))); + } + else + { + $resync_files_stats = true; + add_log('admin', 'LOG_RESYNC_FILES_STATS'); + } + } + + // Check if files stats are accurate + $sql = 'SELECT COUNT(attach_id) as num_files + FROM ' . ATTACHMENTS_TABLE . ' + WHERE is_orphan = 0'; + $result = $db->sql_query($sql, 600); + $num_files_real = (int) $db->sql_fetchfield('num_files'); + if ($resync_files_stats === true) + { + set_config('num_files', $num_files_real, true); + } + $db->sql_freeresult($result); + + $sql = 'SELECT SUM(filesize) as upload_dir_size + FROM ' . ATTACHMENTS_TABLE . ' + WHERE is_orphan = 0'; + $result = $db->sql_query($sql, 600); + $total_size_real = (float) $db->sql_fetchfield('upload_dir_size'); + if ($resync_files_stats === true) + { + set_config('upload_dir_size', $total_size_real, true); + } + $db->sql_freeresult($result); + + // Get current files stats + $num_files = (int) $config['num_files']; + $total_size = (float) $config['upload_dir_size']; + + // Issue warning message if files stats are inaccurate + if (($num_files != $num_files_real) || ($total_size != $total_size_real)) + { + $error[] = sprintf($user->lang['FILES_STATS_WRONG'], $num_files_real, get_formatted_filesize($total_size_real)); + + $template->assign_vars(array( + 'S_ACTION_OPTIONS' => ($auth->acl_get('a_board')) ? true : false, + 'U_ACTION' => $this->u_action,) + ); + } + + // Make sure $start is set to the last page if it exceeds the amount + if ($start < 0 || $start > $num_files) + { + $start = ($start < 0) ? 0 : floor(($num_files - 1) / $attachments_per_page) * $attachments_per_page; + } + + // If the user is trying to reach the second half of the attachments list, fetch it starting from the end + $store_reverse = false; + $sql_limit = $attachments_per_page; + + if ($start > $num_files / 2) + { + $store_reverse = true; + + if ($start + $attachments_per_page > $num_files) + { + $sql_limit = min($attachments_per_page, max(1, $num_files - $start)); + } + + // Select the sort order. Add time sort anchor for non-time sorting cases + $sql_sort_anchor = ($sort_key != 't') ? ', a.filetime ' . (($sort_dir == 'd') ? 'ASC' : 'DESC') : ''; + $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'ASC' : 'DESC') . $sql_sort_anchor; + $sql_start = max(0, $num_files - $sql_limit - $start); + } + else + { + // Select the sort order. Add time sort anchor for non-time sorting cases + $sql_sort_anchor = ($sort_key != 't') ? ', a.filetime ' . (($sort_dir == 'd') ? 'DESC' : 'ASC') : ''; + $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC') . $sql_sort_anchor; + $sql_start = $start; + + } + + $attachments_list = array(); + + // 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) + LEFT JOIN ' . TOPICS_TABLE . " t ON (a.topic_id = t.topic_id) + WHERE a.is_orphan = 0 + $limit_filetime + ORDER BY $sql_sort_order"; + $result = $db->sql_query_limit($sql, $sql_limit, $sql_start); + + $i = ($store_reverse) ? $sql_limit - 1 : 0; + + // Store increment value in a variable to save some conditional calls + $i_increment = ($store_reverse) ? -1 : 1; + while ($attachment_row = $db->sql_fetchrow($result)) + { + $attachments_list[$i] = $attachment_row; + $i = $i + $i_increment; + } + $db->sql_freeresult($result); + + $template->assign_vars(array( + 'TOTAL_FILES' => $num_files, + 'TOTAL_SIZE' => get_formatted_filesize($total_size), + 'PAGINATION' => generate_pagination($this->u_action . "&$u_sort_param", $num_files, $attachments_per_page, $start, true), + + 'S_ON_PAGE' => on_page($num_files, $attachments_per_page, $start), + 'S_LIMIT_DAYS' => $s_limit_days, + 'S_SORT_KEY' => $s_sort_key, + 'S_SORT_DIR' => $s_sort_dir) + ); + + // Grab extensions + $extensions = $cache->obtain_attach_extensions(true); + + for ($i = 0, $end = sizeof($attachments_list); $i < $end; ++$i) + { + $row = $attachments_list[$i]; + + $row['extension'] = strtolower(trim((string) $row['extension'])); + $comment = ($row['attach_comment'] && !$row['in_message']) ? str_replace(array("\n", "\r"), array('<br />', "\n"), $row['attach_comment']) : ''; + $display_cat = $extensions[$row['extension']]['display_cat']; + $l_downloaded_viewed = ($display_cat == ATTACHMENT_CATEGORY_NONE) ? 'DOWNLOAD_COUNT' : 'VIEWED_COUNT'; + $l_download_count = (!isset($row['download_count']) || (int) $row['download_count'] == 0) ? $user->lang[$l_downloaded_viewed . '_NONE'] : (((int) $row['download_count'] == 1) ? sprintf($user->lang[$l_downloaded_viewed], $row['download_count']) : sprintf($user->lang[$l_downloaded_viewed . 'S'], $row['download_count'])); + + $template->assign_block_vars('attachments', array( + 'ATTACHMENT_POSTER' => get_username_string('full', (int) $row['poster_id'], (string) $row['username'], (string) $row['user_colour'], (string) $row['username']), + 'FILESIZE' => get_formatted_filesize((int) $row['filesize']), + 'FILETIME' => $user->format_date((int) $row['filetime']), + 'REAL_FILENAME' => (!$row['in_message']) ? utf8_wordwrap(utf8_basename((string) $row['real_filename']), 40, '<br />', true) : '', + 'PHYSICAL_FILENAME' => utf8_basename((string) $row['physical_filename']), + 'EXT_GROUP_NAME' => (!empty($extensions[$row['extension']]['group_name'])) ? $user->lang['EXT_GROUP_' . $extensions[$row['extension']]['group_name']] : '', + 'COMMENT' => $comment, + 'TOPIC_TITLE' => (!$row['in_message']) ? (string) $row['topic_title'] : '', + 'ATTACH_ID' => (int) $row['attach_id'], + 'POST_ID' => (int) $row['post_msg_id'], + 'TOPIC_ID' => (int) $row['topic_id'], + 'POST_IDS' => (!empty($post_ids[$row['attach_id']])) ? (int) $post_ids[$row['attach_id']] : '', + + 'L_DOWNLOAD_COUNT' => $l_download_count, + + 'S_IN_MESSAGE' => (bool) $row['in_message'], + + 'U_VIEW_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t={$row['topic_id']}&p={$row['post_msg_id']}") . "#p{$row['post_msg_id']}", + 'U_FILE' => append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'mode=view&id=' . $row['attach_id'])) + ); + } + + break; } if (sizeof($error)) diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 6821073749..f27a133eb5 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -96,6 +96,7 @@ class acp_board 'load_moderators' => array('lang' => 'YES_MODERATORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_jumpbox' => array('lang' => 'YES_JUMPBOX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'load_cpf_pm' => array('lang' => 'LOAD_CPF_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_viewprofile' => array('lang' => 'LOAD_CPF_VIEWPROFILE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_viewtopic' => array('lang' => 'LOAD_CPF_VIEWTOPIC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), @@ -327,6 +328,7 @@ class acp_board 'legend3' => 'CUSTOM_PROFILE_FIELDS', 'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'load_cpf_pm' => array('lang' => 'LOAD_CPF_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_viewprofile' => array('lang' => 'LOAD_CPF_VIEWPROFILE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_viewtopic' => array('lang' => 'LOAD_CPF_VIEWTOPIC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), @@ -387,6 +389,9 @@ class acp_board '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']), + '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_sid_guests' => array('lang' => 'FORM_SID_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), @@ -770,13 +775,20 @@ class acp_board { global $user, $config; - $radio_ary = array(USER_ACTIVATION_DISABLE => 'ACC_DISABLE', USER_ACTIVATION_NONE => 'ACC_NONE'); + $radio_ary = array( + USER_ACTIVATION_DISABLE => 'ACC_DISABLE', + USER_ACTIVATION_NONE => 'ACC_NONE', + ); + if ($config['email_enable']) { - $radio_ary += array(USER_ACTIVATION_SELF => 'ACC_USER', USER_ACTIVATION_ADMIN => 'ACC_ADMIN'); + $radio_ary[USER_ACTIVATION_SELF] = 'ACC_USER'; + $radio_ary[USER_ACTIVATION_ADMIN] = 'ACC_ADMIN'; } - return h_radio('config[require_activation]', $radio_ary, $value, $key); + $radio_text = h_radio('config[require_activation]', $radio_ary, $value, 'require_activation', $key, '<br />'); + + return $radio_text; } /** diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index e4fb695a11..0e4801f630 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -301,7 +301,7 @@ class acp_inactive 'PAGINATION' => generate_pagination($this->u_action . "&$u_sort_param&users_per_page=$per_page", $inactive_count, $per_page, $start, true), 'USERS_PER_PAGE' => $per_page, - 'U_ACTION' => $this->u_action . '&start=' . $start, + 'U_ACTION' => $this->u_action . "&$u_sort_param&users_per_page=$per_page&start=$start", )); $this->tpl_name = 'acp_inactive'; diff --git a/phpBB/includes/acp/acp_logs.php b/phpBB/includes/acp/acp_logs.php index 90c1a10649..065a6d1c22 100644 --- a/phpBB/includes/acp/acp_logs.php +++ b/phpBB/includes/acp/acp_logs.php @@ -128,12 +128,12 @@ class acp_logs // Grab log data $log_data = array(); $log_count = 0; - view_log($mode, $log_data, $log_count, $config['topics_per_page'], $start, $forum_id, 0, 0, $sql_where, $sql_sort, $keywords); + $start = view_log($mode, $log_data, $log_count, $config['topics_per_page'], $start, $forum_id, 0, 0, $sql_where, $sql_sort, $keywords); $template->assign_vars(array( 'L_TITLE' => $l_title, 'L_EXPLAIN' => $l_title_explain, - 'U_ACTION' => $this->u_action, + 'U_ACTION' => $this->u_action . "&$u_sort_param$keywords_param&start=$start", 'S_ON_PAGE' => on_page($log_count, $config['topics_per_page'], $start), 'PAGINATION' => generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start, true), diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index ac375838fd..a922ef570c 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -415,11 +415,8 @@ class acp_main { $latest_version_info = explode("\n", $latest_version_info); - $latest_version = str_replace('rc', 'RC', strtolower(trim($latest_version_info[0]))); - $current_version = str_replace('rc', 'RC', strtolower($config['version'])); - $template->assign_vars(array( - 'S_VERSION_UP_TO_DATE' => version_compare($current_version, $latest_version, '<') ? false : true, + 'S_VERSION_UP_TO_DATE' => phpbb_version_compare(trim($latest_version_info[0]), $config['version'], '<='), )); } @@ -521,7 +518,7 @@ class acp_main 'U_ADMIN_LOG' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=logs&mode=admin'), 'U_INACTIVE_USERS' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=inactive&mode=list'), 'U_VERSIONCHECK' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=update&mode=version_check'), - 'U_VERSIONCHECK_FORCE' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=1&versioncheck_force=1'), + 'U_VERSIONCHECK_FORCE' => append_sid("{$phpbb_admin_path}index.$phpEx", 'versioncheck_force=1'), 'S_ACTION_OPTIONS' => ($auth->acl_get('a_board')) ? true : false, 'S_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false, diff --git a/phpBB/includes/acp/acp_php_info.php b/phpBB/includes/acp/acp_php_info.php index 03561f3e30..65150a40c5 100644 --- a/phpBB/includes/acp/acp_php_info.php +++ b/phpBB/includes/acp/acp_php_info.php @@ -67,6 +67,9 @@ class acp_php_info $output = preg_replace('#<img border="0"#i', '<img', $output); $output = str_replace(array('class="e"', 'class="v"', 'class="h"', '<hr />', '<font', '</font>'), array('class="row1"', 'class="row2"', '', '', '<span', '</span>'), $output); + // Fix invalid anchor names (eg "module_Zend Optimizer") + $output = preg_replace_callback('#<a name="([^"]+)">#', array($this, 'remove_spaces'), $output); + if (empty($output)) { trigger_error('NO_PHPINFO_AVAILABLE', E_USER_WARNING); @@ -79,4 +82,9 @@ class acp_php_info $template->assign_var('PHPINFO', $output); } + + function remove_spaces($matches) + { + return '<a name="' . str_replace(' ', '_', $matches[1]) . '">'; + } } diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index ca6a5f04d2..a18a01c44a 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -370,6 +370,7 @@ class acp_profile 'field_show_profile'=> 0, 'field_no_view' => 0, 'field_show_on_reg' => 0, + 'field_show_on_pm' => 0, 'field_show_on_vt' => 0, 'lang_name' => utf8_normalize_nfc(request_var('field_ident', '', true)), 'lang_explain' => '', @@ -381,7 +382,7 @@ class acp_profile // $exclude contains the data we gather in each step $exclude = array( - 1 => array('field_ident', 'lang_name', 'lang_explain', 'field_option_none', 'field_show_on_reg', 'field_show_on_vt', 'field_required', 'field_hide', 'field_show_profile', 'field_no_view'), + 1 => array('field_ident', 'lang_name', 'lang_explain', 'field_option_none', 'field_show_on_reg', 'field_show_on_pm', 'field_show_on_vt', 'field_required', 'field_hide', 'field_show_profile', 'field_no_view'), 2 => array('field_length', 'field_maxlen', 'field_minlen', 'field_validation', 'field_novalue', 'field_default_value'), 3 => array('l_lang_name', 'l_lang_explain', 'l_lang_default_value', 'l_lang_options') ); @@ -407,6 +408,7 @@ class acp_profile $visibility_ary = array( 'field_required', 'field_show_on_reg', + 'field_show_on_pm', 'field_show_on_vt', 'field_show_profile', 'field_hide', @@ -734,6 +736,7 @@ class acp_profile 'S_STEP_ONE' => true, 'S_FIELD_REQUIRED' => ($cp->vars['field_required']) ? true : false, 'S_SHOW_ON_REG' => ($cp->vars['field_show_on_reg']) ? true : false, + 'S_SHOW_ON_PM' => ($cp->vars['field_show_on_pm']) ? true : false, 'S_SHOW_ON_VT' => ($cp->vars['field_show_on_vt']) ? true : false, 'S_FIELD_HIDE' => ($cp->vars['field_hide']) ? true : false, 'S_SHOW_PROFILE' => ($cp->vars['field_show_profile']) ? true : false, @@ -1050,6 +1053,7 @@ class acp_profile 'field_validation' => $cp->vars['field_validation'], 'field_required' => $cp->vars['field_required'], 'field_show_on_reg' => $cp->vars['field_show_on_reg'], + 'field_show_on_pm' => $cp->vars['field_show_on_pm'], 'field_show_on_vt' => $cp->vars['field_show_on_vt'], 'field_hide' => $cp->vars['field_hide'], 'field_show_profile' => $cp->vars['field_show_profile'], diff --git a/phpBB/includes/acp/acp_send_statistics.php b/phpBB/includes/acp/acp_send_statistics.php index aef67a8b1a..eb7154d114 100644 --- a/phpBB/includes/acp/acp_send_statistics.php +++ b/phpBB/includes/acp/acp_send_statistics.php @@ -16,8 +16,6 @@ if (!defined('IN_PHPBB')) exit; } -include($phpbb_root_path . 'includes/questionnaire/questionnaire.' . $phpEx); - /** * @package acp */ @@ -27,7 +25,9 @@ class acp_send_statistics function main($id, $mode) { - global $config, $template, $phpbb_admin_path, $phpEx; + global $config, $template, $phpbb_admin_path, $phpbb_root_path, $phpEx; + + include($phpbb_root_path . 'includes/questionnaire/questionnaire.' . $phpEx); $collect_url = "http://www.phpbb.com/stats/receive_stats.php"; diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 6a0d4c4c98..18a90fb8e8 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -45,7 +45,7 @@ class acp_styles $bitfield->set(9); $bitfield->set(11); $bitfield->set(12); - define('TEMPLATE_BITFIELD', $bitfield->get_base64()); + $this->template_bitfield = $bitfield->get_base64(); unset($bitfield); $user->add_lang('acp/styles'); @@ -510,6 +510,7 @@ parse_css_file = {PARSE_CSS_FILE} $db->sql_transaction('commit'); $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE); + $cache->destroy('imageset_site_logo_md5'); add_log('admin', 'LOG_IMAGESET_REFRESHED', $imageset_row['imageset_name']); trigger_error($user->lang['IMAGESET_REFRESHED'] . adm_back_link($this->u_action)); @@ -3496,7 +3497,7 @@ parse_css_file = {PARSE_CSS_FILE} } else { - $sql_ary['bbcode_bitfield'] = TEMPLATE_BITFIELD; + $sql_ary['bbcode_bitfield'] = $this->template_bitfield; } // We set a pre-defined bitfield here which we may use further in 3.2 diff --git a/phpBB/includes/acp/acp_update.php b/phpBB/includes/acp/acp_update.php index 41fb0884b7..f0365e8e66 100644 --- a/phpBB/includes/acp/acp_update.php +++ b/phpBB/includes/acp/acp_update.php @@ -69,12 +69,9 @@ class acp_update $current_version = (!empty($version_update_from)) ? $version_update_from : $config['version']; - $up_to_date_automatic = (version_compare(str_replace('rc', 'RC', strtolower($current_version)), str_replace('rc', 'RC', strtolower($latest_version)), '<')) ? false : true; - $up_to_date = (version_compare(str_replace('rc', 'RC', strtolower($config['version'])), str_replace('rc', 'RC', strtolower($latest_version)), '<')) ? false : true; - $template->assign_vars(array( - 'S_UP_TO_DATE' => $up_to_date, - 'S_UP_TO_DATE_AUTO' => $up_to_date_automatic, + 'S_UP_TO_DATE' => phpbb_version_compare($latest_version, $config['version'], '<='), + 'S_UP_TO_DATE_AUTO' => phpbb_version_compare($latest_version, $current_version, '<='), 'S_VERSION_CHECK' => true, 'U_ACTION' => $this->u_action, 'U_VERSIONCHECK_FORCE' => append_sid($this->u_action . '&versioncheck_force=1'), diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 006c3617f7..9bcf1b20db 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1124,7 +1124,7 @@ class acp_users // Grab log data $log_data = array(); $log_count = 0; - view_log('user', $log_data, $log_count, $config['topics_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort); + $start = view_log('user', $log_data, $log_count, $config['topics_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort); $template->assign_vars(array( 'S_FEEDBACK' => true, diff --git a/phpBB/includes/acp/info/acp_attachments.php b/phpBB/includes/acp/info/acp_attachments.php index d5f57ece4e..4bcd7e2ea5 100644 --- a/phpBB/includes/acp/info/acp_attachments.php +++ b/phpBB/includes/acp/info/acp_attachments.php @@ -23,7 +23,8 @@ class acp_attachments_info 'attach' => array('title' => 'ACP_ATTACHMENT_SETTINGS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_BOARD_CONFIGURATION', 'ACP_ATTACHMENTS')), 'extensions' => array('title' => 'ACP_MANAGE_EXTENSIONS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_ATTACHMENTS')), 'ext_groups' => array('title' => 'ACP_EXTENSION_GROUPS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_ATTACHMENTS')), - 'orphan' => array('title' => 'ACP_ORPHAN_ATTACHMENTS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_ATTACHMENTS')) + 'orphan' => array('title' => 'ACP_ORPHAN_ATTACHMENTS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_ATTACHMENTS')), + 'manage' => array('title' => 'ACP_MANAGE_ATTACHMENTS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_ATTACHMENTS')), ), ); } diff --git a/phpBB/includes/auth.php b/phpBB/includes/auth.php index 22aca5faf9..25f26e5334 100644 --- a/phpBB/includes/auth.php +++ b/phpBB/includes/auth.php @@ -349,6 +349,14 @@ class auth /** * Get permission listing based on user_id/options/forum_ids + * + * Be careful when using this function with permissions a_, m_, u_ and f_ ! + * It may not work correctly. When a user group grants an a_* permission, + * e.g. a_foo, but the user's a_foo permission is set to "Never", then + * the user does not in fact have the a_ permission. + * But the user will still be listed as having the a_ permission. + * + * For more information see: http://tracker.phpbb.com/browse/PHPBB3-10252 */ function acl_get_list($user_id = false, $opts = false, $forum_id = false) { @@ -908,7 +916,7 @@ class auth $method = 'login_' . $method; if (function_exists($method)) { - $login = $method($username, $password); + $login = $method($username, $password, $user->ip, $user->browser, $user->forwarded_for); // If the auth module wants us to create an empty profile do so and then treat the status as LOGIN_SUCCESS if ($login['status'] == LOGIN_SUCCESS_CREATE_PROFILE) diff --git a/phpBB/includes/auth/auth_db.php b/phpBB/includes/auth/auth_db.php index 6304d6e49a..b4ae1911cf 100644 --- a/phpBB/includes/auth/auth_db.php +++ b/phpBB/includes/auth/auth_db.php @@ -23,8 +23,21 @@ if (!defined('IN_PHPBB')) /** * Login function +* +* @param string $username +* @param string $password +* @param string $ip IP address the login is taking place from. Used to +* limit the number of login attempts per IP address. +* @param string $browser The user agent used to login +* @param string $forwarded_for X_FORWARDED_FOR header sent with login request +* @return array A associative array of the format +* array( +* 'status' => status constant +* 'error_msg' => string +* 'user_row' => array +* ) */ -function login_db(&$username, &$password) +function login_db($username, $password, $ip = '', $browser = '', $forwarded_for = '') { global $db, $config; global $request; @@ -48,13 +61,51 @@ function login_db(&$username, &$password) ); } + $username_clean = utf8_clean_string($username); + $sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts FROM ' . USERS_TABLE . " - WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'"; + WHERE username_clean = '" . $db->sql_escape($username_clean) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); + if (($ip && !$config['ip_login_limit_use_forwarded']) || + ($forwarded_for && $config['ip_login_limit_use_forwarded'])) + { + $sql = 'SELECT COUNT(*) AS attempts + FROM ' . LOGIN_ATTEMPT_TABLE . ' + WHERE attempt_time > ' . (time() - (int) $config['ip_login_limit_time']); + if ($config['ip_login_limit_use_forwarded']) + { + $sql .= " AND attempt_forwarded_for = '" . $db->sql_escape($forwarded_for) . "'"; + } + else + { + $sql .= " AND attempt_ip = '" . $db->sql_escape($ip) . "' "; + } + + $result = $db->sql_query($sql); + $attempts = (int) $db->sql_fetchfield('attempts'); + $db->sql_freeresult($result); + + $attempt_data = array( + 'attempt_ip' => $ip, + 'attempt_browser' => trim(substr($browser, 0, 149)), + 'attempt_forwarded_for' => $forwarded_for, + 'attempt_time' => time(), + 'user_id' => ($row) ? (int) $row['user_id'] : 0, + 'username' => $username, + 'username_clean' => $username_clean, + ); + $sql = 'INSERT INTO ' . LOGIN_ATTEMPT_TABLE . $db->sql_build_array('INSERT', $attempt_data); + $result = $db->sql_query($sql); + } + else + { + $attempts = 0; + } + if (!$row) { return array( @@ -63,7 +114,9 @@ function login_db(&$username, &$password) 'user_row' => array('user_id' => ANONYMOUS), ); } - $show_captcha = $config['max_login_attempts'] && $row['user_login_attempts'] >= $config['max_login_attempts']; + + $show_captcha = ($config['max_login_attempts'] && $row['user_login_attempts'] >= $config['max_login_attempts']) || + ($config['ip_login_limit_max'] && $attempts >= $config['ip_login_limit_max']); // If there are too much login attempts, we need to check for an confirm image // Every auth module is able to define what to do by itself... @@ -177,6 +230,10 @@ function login_db(&$username, &$password) $row['user_password'] = $hash; } + $sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . ' + WHERE user_id = ' . $row['user_id']; + $db->sql_query($sql); + if ($row['user_login_attempts'] != 0) { // Successful, reset login attempts (the user passed all stages) diff --git a/phpBB/includes/auth/auth_ldap.php b/phpBB/includes/auth/auth_ldap.php index 4f311797b2..66facd0faa 100644 --- a/phpBB/includes/auth/auth_ldap.php +++ b/phpBB/includes/auth/auth_ldap.php @@ -335,7 +335,7 @@ function acp_ldap(&$new) </dl> <dl> <dt><label for="ldap_password">' . $user->lang['LDAP_PASSWORD'] . ':</label><br /><span>' . $user->lang['LDAP_PASSWORD_EXPLAIN'] . '</span></dt> - <dd><input type="password" id="ldap_password" size="40" name="config[ldap_password]" value="' . $new['ldap_password'] . '" /></dd> + <dd><input type="password" id="ldap_password" size="40" name="config[ldap_password]" value="' . $new['ldap_password'] . '" autocomplete="off" /></dd> </dl> '; diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index eeac98d3f3..c3367fbd46 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -572,6 +572,13 @@ class bbcode $code = str_replace("\t", ' ', $code); $code = str_replace(' ', ' ', $code); $code = str_replace(' ', ' ', $code); + $code = str_replace("\n ", "\n ", $code); + + // keep space at the beginning + if (!empty($code) && $code[0] == ' ') + { + $code = ' ' . substr($code, 1); + } // remove newline at the beginning if (!empty($code) && $code[0] == "\n") diff --git a/phpBB/includes/cache/driver/redis.php b/phpBB/includes/cache/driver/redis.php index f0997c3cad..6362938a9e 100755 --- a/phpBB/includes/cache/driver/redis.php +++ b/phpBB/includes/cache/driver/redis.php @@ -25,12 +25,6 @@ if (!defined('PHPBB_ACM_REDIS_HOST')) define('PHPBB_ACM_REDIS_HOST', 'localhost'); } -if (!defined('PHPBB_ACM_REDIS')) -{ - //can define multiple servers with host1/port1,host2/port2 format - define('PHPBB_ACM_REDIS', PHPBB_ACM_REDIS_HOST . '/' . PHPBB_ACM_REDIS_PORT); -} - /** * ACM for Redis * @@ -51,12 +45,8 @@ class phpbb_cache_driver_redis extends phpbb_cache_driver_memory parent::__construct(); $this->redis = new Redis(); - foreach (explode(',', PHPBB_ACM_REDIS) as $server) - { - $parts = explode('/', $server); - $this->redis->connect(trim($parts[0]), trim($parts[1])); - } - + $this->redis->connect(PHPBB_ACM_REDIS_HOST, PHPBB_ACM_REDIS_PORT); + if (defined('PHPBB_ACM_REDIS_PASSWORD')) { if (!$this->redis->auth(PHPBB_ACM_REDIS_PASSWORD)) diff --git a/phpBB/includes/cache/service.php b/phpBB/includes/cache/service.php index 68026c8647..0c01953d55 100644 --- a/phpBB/includes/cache/service.php +++ b/phpBB/includes/cache/service.php @@ -194,6 +194,7 @@ class phpbb_cache_service 'max_filesize' => (int) $row['max_filesize'], 'allow_group' => $row['allow_group'], 'allow_in_pm' => $row['allow_in_pm'], + 'group_name' => $row['group_name'], ); $allowed_forums = ($row['allowed_forums']) ? unserialize(trim($row['allowed_forums'])) : array(); diff --git a/phpBB/includes/captcha/captcha_gd.php b/phpBB/includes/captcha/captcha_gd.php index 15f34aa58f..5e61d6a47b 100644 --- a/phpBB/includes/captcha/captcha_gd.php +++ b/phpBB/includes/captcha/captcha_gd.php @@ -77,7 +77,7 @@ class captcha { $denom = ($code_len - $i); $denom = max(1.3, $denom); - $offset[$i] = mt_rand(0, (1.5 * $width_avail) / $denom); + $offset[$i] = phpbb_mt_rand(0, (int) round((1.5 * $width_avail) / $denom)); $width_avail -= $offset[$i]; } diff --git a/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php index 75fef25a9f..3bc727da41 100644 --- a/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php +++ b/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php @@ -319,7 +319,7 @@ class phpbb_captcha_qa ), 'PRIMARY_KEY' => 'question_id', 'KEYS' => array( - 'lang_iso' => array('INDEX', 'lang_iso'), + 'lang' => array('INDEX', 'lang_iso'), ), ), CAPTCHA_ANSWERS_TABLE => array ( @@ -328,7 +328,7 @@ class phpbb_captcha_qa 'answer_text' => array('STEXT_UNI', ''), ), 'KEYS' => array( - 'question_id' => array('INDEX', 'question_id'), + 'qid' => array('INDEX', 'question_id'), ), ), CAPTCHA_QA_CONFIRM_TABLE => array ( diff --git a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php index 12e3536893..c0db41d5a5 100644 --- a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php +++ b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php @@ -27,9 +27,14 @@ if (!class_exists('phpbb_default_captcha', false)) */ class phpbb_recaptcha extends phpbb_default_captcha { - var $recaptcha_server = 'http://api.recaptcha.net'; - var $recaptcha_server_secure = 'https://api-secure.recaptcha.net'; // class constants :( - var $recaptcha_verify_server = 'api-verify.recaptcha.net'; + var $recaptcha_server = 'http://www.google.com/recaptcha/api'; + var $recaptcha_server_secure = 'https://www.google.com/recaptcha/api'; // class constants :( + + // We are opening a socket to port 80 of this host and send + // the POST request asking for verification to the path specified here. + var $recaptcha_verify_server = 'www.google.com'; + var $recaptcha_verify_path = '/recaptcha/api/verify'; + var $challenge; var $response; @@ -296,7 +301,7 @@ class phpbb_recaptcha extends phpbb_default_captcha return $user->lang['RECAPTCHA_INCORRECT']; } - $response = $this->_recaptcha_http_post($this->recaptcha_verify_server, '/verify', + $response = $this->_recaptcha_http_post($this->recaptcha_verify_server, $this->recaptcha_verify_path, array( 'privatekey' => $config['recaptcha_privkey'], 'remoteip' => $user->ip, diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 216aac7489..8ef1a4655d 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -236,6 +236,7 @@ define('GROUPS_TABLE', $table_prefix . 'groups'); define('ICONS_TABLE', $table_prefix . 'icons'); define('LANG_TABLE', $table_prefix . 'lang'); define('LOG_TABLE', $table_prefix . 'log'); +define('LOGIN_ATTEMPT_TABLE', $table_prefix . 'login_attempts'); define('MODERATOR_CACHE_TABLE', $table_prefix . 'moderator_cache'); define('MODULES_TABLE', $table_prefix . 'modules'); define('POLL_OPTIONS_TABLE', $table_prefix . 'poll_options'); diff --git a/phpBB/includes/cron/manager.php b/phpBB/includes/cron/manager.php index 21dcb91695..31be1a69cb 100644 --- a/phpBB/includes/cron/manager.php +++ b/phpBB/includes/cron/manager.php @@ -73,6 +73,14 @@ class phpbb_cron_manager */ public function __construct($task_path, $phpEx, phpbb_cache_driver_interface $cache = null) { + if (DIRECTORY_SEPARATOR != '/') + { + // Need this on some platforms since the code elsewhere uses / + // to separate directory components, but PHP iterators return + // paths with platform-specific directory separators. + $task_path = str_replace('/', DIRECTORY_SEPARATOR, $task_path); + } + $this->task_path = $task_path; $this->phpEx = $phpEx; $this->cache = $cache; @@ -116,9 +124,9 @@ class phpbb_cron_manager $file = preg_replace('#^' . preg_quote($this->task_path, '#') . '#', '', $fileinfo->getPathname()); // skip directories and files direclty in the task root path - if ($fileinfo->isFile() && strpos($file, '/') !== false) + if ($fileinfo->isFile() && strpos($file, DIRECTORY_SEPARATOR) !== false) { - $task_name = str_replace('/', '_', substr($file, 0, -$ext_length)); + $task_name = str_replace(DIRECTORY_SEPARATOR, '_', substr($file, 0, -$ext_length)); if (substr($file, -$ext_length) == $ext && $this->is_valid_name($task_name)) { $task_names[] = 'phpbb_cron_task_' . $task_name; diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index 88bbd614e6..7c96965a9b 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -417,6 +417,11 @@ class phpbb_db_tools // here lies an array, filled with information compiled on the column's data $prepared_column = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + if (isset($prepared_column['auto_increment']) && strlen($column_name) > 26) // "${column_name}_gen" + { + trigger_error("Index name '${column_name}_gen' on table '$table_name' is too long. The maximum auto increment column length is 26 characters.", E_USER_ERROR); + } + // here we add the definition of the new column to the list of columns switch ($this->sql_layer) { @@ -538,7 +543,7 @@ class phpbb_db_tools break; case 'oracle': - $table_sql .= "\n);"; + $table_sql .= "\n)"; $statements[] = $table_sql; // do we need to add a sequence and a tigger for auto incrementing columns? @@ -556,7 +561,7 @@ class phpbb_db_tools $trigger .= "BEGIN\n"; $trigger .= "\tSELECT {$table_name}_seq.nextval\n"; $trigger .= "\tINTO :new.{$create_sequence}\n"; - $trigger .= "\tFROM dual\n"; + $trigger .= "\tFROM dual;\n"; $trigger .= "END;"; $statements[] = $trigger; @@ -566,7 +571,13 @@ class phpbb_db_tools case 'firebird': if ($create_sequence) { - $statements[] = "CREATE SEQUENCE {$table_name}_seq;"; + $statements[] = "CREATE GENERATOR {$table_name}_gen;"; + $statements[] = "SET GENERATOR {$table_name}_gen TO 0;"; + + $trigger = "CREATE TRIGGER t_$table_name FOR $table_name\n"; + $trigger .= "BEFORE INSERT\nAS\nBEGIN\n"; + $trigger .= "\tNEW.{$create_sequence} = GEN_ID({$table_name}_gen, 1);\nEND;"; + $statements[] = $trigger; } break; } @@ -638,6 +649,19 @@ class phpbb_db_tools $sqlite = true; } + // Add tables? + if (!empty($schema_changes['add_tables'])) + { + foreach ($schema_changes['add_tables'] as $table => $table_data) + { + $result = $this->sql_create_table($table, $table_data); + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + // Change columns? if (!empty($schema_changes['change_columns'])) { @@ -681,10 +705,12 @@ class phpbb_db_tools { foreach ($columns as $column_name => $column_data) { - // Only add the column if it does not exist yet, else change it (to be consistent) + // Only add the column if it does not exist yet if ($column_exists = $this->sql_column_exists($table, $column_name)) { - $result = $this->sql_column_change($table, $column_name, $column_data, true); + continue; + // This is commented out here because it can take tremendous time on updates +// $result = $this->sql_column_change($table, $column_name, $column_data, true); } else { @@ -695,7 +721,8 @@ class phpbb_db_tools { if ($column_exists) { - $sqlite_data[$table]['change_columns'][] = $result; + continue; +// $sqlite_data[$table]['change_columns'][] = $result; } else { @@ -717,6 +744,11 @@ class phpbb_db_tools { foreach ($indexes as $index_name) { + if (!$this->sql_index_exists($table, $index_name)) + { + continue; + } + $result = $this->sql_index_drop($table, $index_name); if ($this->return_statements) @@ -777,6 +809,11 @@ class phpbb_db_tools { foreach ($index_array as $index_name => $column) { + if ($this->sql_unique_index_exists($table, $index_name)) + { + continue; + } + $result = $this->sql_create_unique_index($table, $index_name, $column); if ($this->return_statements) @@ -794,6 +831,11 @@ class phpbb_db_tools { foreach ($index_array as $index_name => $column) { + if ($this->sql_index_exists($table, $index_name)) + { + continue; + } + $result = $this->sql_create_index($table, $index_name, $column); if ($this->return_statements) @@ -1103,6 +1145,236 @@ class phpbb_db_tools } /** + * Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes. + * + * @param string $table_name Table to check the index at + * @param string $index_name The index name to check + * + * @return bool True if index exists, else false + */ + function sql_index_exists($table_name, $index_name) + { + if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') + { + $sql = "EXEC sp_statistics '$table_name'"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + if ($row['TYPE'] == 3) + { + if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + } + $this->db->sql_freeresult($result); + + return false; + } + + switch ($this->sql_layer) + { + case 'firebird': + $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name + FROM RDB\$INDICES + WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "' + AND RDB\$UNIQUE_FLAG IS NULL + AND RDB\$FOREIGN_KEY IS NULL"; + $col = 'index_name'; + break; + + case 'postgres': + $sql = "SELECT ic.relname as index_name + FROM pg_class bc, pg_class ic, pg_index i + WHERE (bc.oid = i.indrelid) + AND (ic.oid = i.indexrelid) + AND (bc.relname = '" . $table_name . "') + AND (i.indisunique != 't') + AND (i.indisprimary != 't')"; + $col = 'index_name'; + break; + + case 'mysql_40': + case 'mysql_41': + $sql = 'SHOW KEYS + FROM ' . $table_name; + $col = 'Key_name'; + break; + + case 'oracle': + $sql = "SELECT index_name + FROM user_indexes + WHERE table_name = '" . strtoupper($table_name) . "' + AND generated = 'N' + AND uniqueness = 'NONUNIQUE'"; + $col = 'index_name'; + break; + + case 'sqlite': + $sql = "PRAGMA index_list('" . $table_name . "');"; + $col = 'name'; + break; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) + { + continue; + } + + // These DBMS prefix index name with the table name + switch ($this->sql_layer) + { + case 'firebird': + case 'oracle': + case 'postgres': + case 'sqlite': + $row[$col] = substr($row[$col], strlen($table_name) + 1); + break; + } + + if (strtolower($row[$col]) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + $this->db->sql_freeresult($result); + + return false; + } + + /** + * Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes. + * + * @param string $table_name Table to check the index at + * @param string $index_name The index name to check + * + * @return bool True if index exists, else false + */ + function sql_unique_index_exists($table_name, $index_name) + { + if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') + { + $sql = "EXEC sp_statistics '$table_name'"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + // Usually NON_UNIQUE is the column we want to check, but we allow for both + if ($row['TYPE'] == 3) + { + if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + } + $this->db->sql_freeresult($result); + return false; + } + + switch ($this->sql_layer) + { + case 'firebird': + $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name + FROM RDB\$INDICES + WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "' + AND RDB\$UNIQUE_FLAG IS NOT NULL + AND RDB\$FOREIGN_KEY IS NULL"; + $col = 'index_name'; + break; + + case 'postgres': + $sql = "SELECT ic.relname as index_name, i.indisunique + FROM pg_class bc, pg_class ic, pg_index i + WHERE (bc.oid = i.indrelid) + AND (ic.oid = i.indexrelid) + AND (bc.relname = '" . $table_name . "') + AND (i.indisprimary != 't')"; + $col = 'index_name'; + break; + + case 'mysql_40': + case 'mysql_41': + $sql = 'SHOW KEYS + FROM ' . $table_name; + $col = 'Key_name'; + break; + + case 'oracle': + $sql = "SELECT index_name, table_owner + FROM user_indexes + WHERE table_name = '" . strtoupper($table_name) . "' + AND generated = 'N' + AND uniqueness = 'UNIQUE'"; + $col = 'index_name'; + break; + + case 'sqlite': + $sql = "PRAGMA index_list('" . $table_name . "');"; + $col = 'name'; + break; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && ($row['Non_unique'] || $row[$col] == 'PRIMARY')) + { + continue; + } + + if ($this->sql_layer == 'sqlite' && !$row['unique']) + { + continue; + } + + if ($this->sql_layer == 'postgres' && $row['indisunique'] != 't') + { + continue; + } + + // These DBMS prefix index name with the table name + switch ($this->sql_layer) + { + case 'oracle': + // Two cases here... prefixed with U_[table_owner] and not prefixed with table_name + if (strpos($row[$col], 'U_') === 0) + { + $row[$col] = substr($row[$col], strlen('U_' . $row['table_owner']) + 1); + } + else if (strpos($row[$col], strtoupper($table_name)) === 0) + { + $row[$col] = substr($row[$col], strlen($table_name) + 1); + } + break; + + case 'firebird': + case 'postgres': + case 'sqlite': + $row[$col] = substr($row[$col], strlen($table_name) + 1); + break; + } + + if (strtolower($row[$col]) == strtolower($index_name)) + { + $this->db->sql_freeresult($result); + return true; + } + } + $this->db->sql_freeresult($result); + + return false; + } + + /** * Private method for performing sql statements (either execute them or return them) * @access private */ @@ -1139,6 +1411,11 @@ class phpbb_db_tools */ function sql_prepare_column_data($table_name, $column_name, $column_data) { + if (strlen($column_name) > 30) + { + trigger_error("Column name '$column_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); + } + // Get type if (strpos($column_data[0], ':') !== false) { @@ -1371,24 +1648,29 @@ class phpbb_db_tools switch ($this->sql_layer) { case 'firebird': + // Does not support AFTER statement, only POSITION (and there you need the column position) $statements[] = 'ALTER TABLE ' . $table_name . ' ADD "' . strtoupper($column_name) . '" ' . $column_data['column_type_sql']; break; case 'mssql': case 'mssqlnative': + // Does not support AFTER, only through temporary table $statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default']; break; case 'mysql_40': case 'mysql_41': - $statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql']; + $after = (!empty($column_data['after'])) ? ' AFTER ' . $column_data['after'] : ''; + $statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql'] . $after; break; case 'oracle': + // Does not support AFTER, only through temporary table $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; break; case 'postgres': + // Does not support AFTER, only through temporary table if (version_compare($this->db->sql_server_info(true), '8.0', '>=')) { $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; @@ -1774,6 +2056,13 @@ class phpbb_db_tools { $statements = array(); + $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) + if (strlen($table_name . $index_name) - strlen($table_prefix) > 24) + { + $max_length = strlen($table_prefix) + 24; + trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); + } + switch ($this->sql_layer) { case 'firebird': @@ -1804,6 +2093,13 @@ class phpbb_db_tools { $statements = array(); + $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) + if (strlen($table_name . $index_name) - strlen($table_prefix) > 24) + { + $max_length = strlen($table_prefix) + 24; + trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); + } + // remove index length unless MySQL4 if ('mysql_40' != $this->sql_layer) { @@ -1957,6 +2253,7 @@ class phpbb_db_tools } else { + // TODO: try to change pkey without removing trigger, generator or constraints. ATM this query may fail. $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql_type']; } break; diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index 148f56b5a8..a61dc5f58a 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -246,7 +246,7 @@ class dbal * * @return bool Whether buffering is required. */ - function sql_buffer_nested_transaction() + function sql_buffer_nested_transactions() { return false; } @@ -767,12 +767,10 @@ class dbal $mtime = explode(' ', microtime()); $totaltime = $mtime[0] + $mtime[1] - $starttime; - echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr"> + echo '<!DOCTYPE html> + <html dir="ltr"> <head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> - <meta http-equiv="Content-Style-Type" content="text/css" /> - <meta http-equiv="imagetoolbar" content="no" /> + <meta charset="utf-8"> <title>SQL Report</title> <link href="' . $phpbb_root_path . 'adm/style/admin.css" rel="stylesheet" type="text/css" media="screen" /> </head> @@ -800,7 +798,7 @@ class dbal </div> </div> <div id="page-footer"> - Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group + Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group </div> </div> </body> diff --git a/phpBB/includes/db/firebird.php b/phpBB/includes/db/firebird.php index 8868d4e317..8acc84b1c0 100644 --- a/phpBB/includes/db/firebird.php +++ b/phpBB/includes/db/firebird.php @@ -497,7 +497,8 @@ class dbal_firebird extends dbal */ function cast_expr_to_bigint($expression) { - return 'CAST(' . $expression . ' as DECIMAL(255, 0))'; + // Precision must be from 1 to 18 + return 'CAST(' . $expression . ' as DECIMAL(18, 0))'; } /** diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index 710a054e5f..2287bc716e 100644 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -261,7 +261,7 @@ class dbal_mssqlnative extends dbal /** * {@inheritDoc} */ - function sql_buffer_nested_transaction() + function sql_buffer_nested_transactions() { return true; } diff --git a/phpBB/includes/db/mysqli.php b/phpBB/includes/db/mysqli.php index 7c72fe9f01..db3846e7f7 100644 --- a/phpBB/includes/db/mysqli.php +++ b/phpBB/includes/db/mysqli.php @@ -33,14 +33,33 @@ class dbal_mysqli extends dbal */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false , $new_link = false) { - $this->persistency = $persistency; + // Mysqli extension supports persistent connection since PHP 5.3.0 + $this->persistency = (version_compare(PHP_VERSION, '5.3.0', '>=')) ? $persistency : false; $this->user = $sqluser; - $this->server = $sqlserver; + + // If persistent connection, set dbhost to localhost when empty and prepend it with 'p:' prefix + $this->server = ($this->persistency) ? 'p:' . (($sqlserver) ? $sqlserver : 'localhost') : $sqlserver; + $this->dbname = $database; $port = (!$port) ? NULL : $port; - // Persistant connections not supported by the mysqli extension? - $this->db_connect_id = @mysqli_connect($this->server, $this->user, $sqlpassword, $this->dbname, $port); + // If port is set and it is not numeric, most likely mysqli socket is set. + // Try to map it to the $socket parameter. + $socket = NULL; + if ($port) + { + if (is_numeric($port)) + { + $port = (int) $port; + } + else + { + $socket = $port; + $port = NULL; + } + } + + $this->db_connect_id = @mysqli_connect($this->server, $this->user, $sqlpassword, $this->dbname, $port, $socket); if ($this->db_connect_id && $this->dbname != '') { diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index e4727b9705..9d27a24c92 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -191,6 +191,43 @@ function unique_id($extra = 'c') } /** +* Wrapper for mt_rand() which allows swapping $min and $max parameters. +* +* PHP does not allow us to swap the order of the arguments for mt_rand() anymore. +* (since PHP 5.3.4, see http://bugs.php.net/46587) +* +* @param int $min Lowest value to be returned +* @param int $max Highest value to be returned +* +* @return int Random integer between $min and $max (or $max and $min) +*/ +function phpbb_mt_rand($min, $max) +{ + return ($min > $max) ? mt_rand($max, $min) : mt_rand($min, $max); +} + +/** +* Wrapper for getdate() which returns the equivalent array for UTC timestamps. +* +* @param int $time Unix timestamp (optional) +* +* @return array Returns an associative array of information related to the timestamp. +* See http://www.php.net/manual/en/function.getdate.php +*/ +function phpbb_gmgetdate($time = false) +{ + if ($time === false) + { + $time = time(); + } + + // getdate() interprets timestamps in local time. + // What follows uses the fact that getdate() and + // date('Z') balance each other out. + return getdate($time - date('Z')); +} + +/** * Return formatted string for filesizes * * @param int $value filesize in bytes @@ -512,6 +549,34 @@ function phpbb_email_hash($email) } /** +* Wrapper for version_compare() that allows using uppercase A and B +* for alpha and beta releases. +* +* See http://www.php.net/manual/en/function.version-compare.php +* +* @param string $version1 First version number +* @param string $version2 Second version number +* @param string $operator Comparison operator (optional) +* +* @return mixed Boolean (true, false) if comparison operator is specified. +* Integer (-1, 0, 1) otherwise. +*/ +function phpbb_version_compare($version1, $version2, $operator = null) +{ + $version1 = strtolower($version1); + $version2 = strtolower($version2); + + if (is_null($operator)) + { + return version_compare($version1, $version2); + } + else + { + return version_compare($version1, $version2, $operator); + } +} + +/** * Global function for chmodding directories and files for internal use * * This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions. @@ -2025,7 +2090,10 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false) /** * Generate board url (example: http://www.example.com/phpBB) +* * @param bool $without_script_path if set to true the script path gets not appended (example: http://www.example.com) +* +* @return string the generated board url */ function generate_board_url($without_script_path = false) { @@ -2229,10 +2297,10 @@ function redirect($url, $return = false, $disable_cd_check = false) { header('Refresh: 0; URL=' . $url); - echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'; - echo '<html xmlns="http://www.w3.org/1999/xhtml" dir="' . $user->lang['DIRECTION'] . '" lang="' . $user->lang['USER_LANG'] . '" xml:lang="' . $user->lang['USER_LANG'] . '">'; + echo '<!DOCTYPE html>'; + echo '<html dir="' . $user->lang['DIRECTION'] . '" lang="' . $user->lang['USER_LANG'] . '">'; echo '<head>'; - echo '<meta http-equiv="content-type" content="text/html; charset=utf-8" />'; + echo '<meta charset="utf-8">'; echo '<meta http-equiv="refresh" content="0; url=' . str_replace('&', '&', $url) . '" />'; echo '<title>' . $user->lang['REDIRECT'] . '</title>'; echo '</head>'; @@ -2411,12 +2479,6 @@ function send_status_line($code, $message) { $version = $_SERVER['SERVER_PROTOCOL']; } - else if (!empty($_SERVER['HTTP_VERSION'])) - { - // I cannot remember where I got this from. - // This code path may never be reachable in reality. - $version = $_SERVER['HTTP_VERSION']; - } else { $version = 'HTTP/1.0'; @@ -3605,10 +3667,19 @@ function phpbb_checkdnsrr($host, $type = 'MX') { return true; } + break; default: - case 'A': case 'AAAA': + // AAAA records returned by nslookup on Windows XP/2003 have this format. + // Later Windows versions use the A record format below for AAAA records. + if (stripos($line, "$host AAAA IPv6 address") === 0) + { + return true; + } + // No break + + case 'A': if (!empty($host_matches)) { // Second line @@ -3677,25 +3748,11 @@ function msg_handler($errno, $msg_text, $errfile, $errline) if (strpos($errfile, 'cache') === false && strpos($errfile, 'template.') === false) { - // flush the content, else we get a white page if output buffering is on - if ((int) @ini_get('output_buffering') === 1 || strtolower(@ini_get('output_buffering')) === 'on') - { - @ob_flush(); - } - - // Another quick fix for those having gzip compression enabled, but do not flush if the coder wants to catch "something". ;) - if (!empty($config['gzip_compress'])) - { - if (@extension_loaded('zlib') && !headers_sent() && !ob_get_level()) - { - @ob_flush(); - } - } - // remove complete path to installation, with the risk of changing backslashes meant to be there $errfile = str_replace(array(phpbb_realpath($phpbb_root_path), '\\'), array('', '/'), $errfile); $msg_text = str_replace(array(phpbb_realpath($phpbb_root_path), '\\'), array('', '/'), $msg_text); - echo '<b>[phpBB Debug] PHP Notice</b>: in file <b>' . $errfile . '</b> on line <b>' . $errline . '</b>: <b>' . $msg_text . '</b><br />' . "\n"; + $error_name = ($errno === E_WARNING) ? 'PHP Warning' : 'PHP Notice'; + echo '<b>[phpBB Debug] ' . $error_name . '</b>: in file <b>' . $errfile . '</b> on line <b>' . $errline . '</b>: <b>' . $msg_text . '</b><br />' . "\n"; // we are writing an image - the user won't see the debug, so let's place it in the log if (defined('IMAGE_OUTPUT') || defined('IN_CRON')) @@ -3751,10 +3808,10 @@ function msg_handler($errno, $msg_text, $errfile, $errline) // Try to not call the adm page data... - echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'; - echo '<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">'; + echo '<!DOCTYPE html>'; + echo '<html dir="ltr">'; echo '<head>'; - echo '<meta http-equiv="content-type" content="text/html; charset=utf-8" />'; + echo '<meta charset="utf-8">'; echo '<title>' . $msg_title . '</title>'; echo '<style type="text/css">' . "\n" . '/* <![CDATA[ */' . "\n"; echo '* { margin: 0; padding: 0; } html { font-size: 100%; height: 100%; margin-bottom: 1px; background-color: #E4EDF0; } body { font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; color: #536482; background: #E4EDF0; font-size: 62.5%; margin: 0; } '; @@ -3784,7 +3841,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline) echo ' </div>'; echo ' </div>'; echo ' <div id="page-footer">'; - echo ' Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group'; + echo ' Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group'; echo ' </div>'; echo '</div>'; echo '</body>'; @@ -4250,7 +4307,21 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 // gzip_compression if ($config['gzip_compress']) { - if (@extension_loaded('zlib') && !headers_sent()) + // to avoid partially compressed output resulting in blank pages in + // the browser or error messages, compression is disabled in a few cases: + // + // 1) if headers have already been sent, this indicates plaintext output + // has been started so further content must not be compressed + // 2) the length of the current output buffer is non-zero. This means + // there is already some uncompressed content in this output buffer + // so further output must not be compressed + // 3) if more than one level of output buffering is used because we + // cannot test all output buffer level content lengths. One level + // could be caused by php.ini output_buffering. Anything + // beyond that is manual, so the code wrapping phpBB in output buffering + // can easily compress the output itself. + // + if (@extension_loaded('zlib') && !headers_sent() && ob_get_level() <= 1 && ob_get_length() == 0) { ob_start('ob_gzhandler'); } @@ -4371,6 +4442,12 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 $user_lang = substr($user_lang, 0, strpos($user_lang, '-x-')); } + $s_search_hidden_fields = array(); + if ($_SID) + { + $s_search_hidden_fields['sid'] = $_SID; + } + // The following assigns all _common_ variables that may be used at any point in a template. $template->assign_vars(array( 'SITENAME' => $config['sitename'], @@ -4460,11 +4537,13 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'S_LOAD_UNREADS' => ($config['load_unreads_search'] && ($config['load_anon_lastread'] || $user->data['is_registered'])) ? true : false, + 'S_SEARCH_HIDDEN_FIELDS' => build_hidden_fields($s_search_hidden_fields), + 'T_THEME_PATH' => "{$web_path}styles/" . $user->theme['theme_path'] . '/theme', 'T_TEMPLATE_PATH' => "{$web_path}styles/" . $user->theme['template_path'] . '/template', 'T_SUPER_TEMPLATE_PATH' => (isset($user->theme['template_inherit_path']) && $user->theme['template_inherit_path']) ? "{$web_path}styles/" . $user->theme['template_inherit_path'] . '/template' : "{$web_path}styles/" . $user->theme['template_path'] . '/template', 'T_IMAGESET_PATH' => "{$web_path}styles/" . $user->theme['imageset_path'] . '/imageset', - 'T_IMAGESET_LANG_PATH' => "{$web_path}styles/" . $user->theme['imageset_path'] . '/imageset/' . $user->data['user_lang'], + 'T_IMAGESET_LANG_PATH' => "{$web_path}styles/" . $user->theme['imageset_path'] . '/imageset/' . $user->lang_name, 'T_IMAGES_PATH' => "{$web_path}images/", 'T_SMILIES_PATH' => "{$web_path}{$config['smilies_path']}/", 'T_AVATAR_PATH' => "{$web_path}{$config['avatar_path']}/", @@ -4472,7 +4551,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'T_ICONS_PATH' => "{$web_path}{$config['icons_path']}/", 'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/", 'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/", - 'T_STYLESHEET_LINK' => (!$user->theme['theme_storedb']) ? "{$web_path}styles/" . $user->theme['theme_path'] . '/theme/stylesheet.css' : append_sid("{$phpbb_root_path}style.$phpEx", 'id=' . $user->theme['style_id'] . '&lang=' . $user->data['user_lang']), + 'T_STYLESHEET_LINK' => (!$user->theme['theme_storedb']) ? "{$web_path}styles/" . $user->theme['theme_path'] . '/theme/stylesheet.css' : append_sid("{$phpbb_root_path}style.$phpEx", 'id=' . $user->theme['style_id'] . '&lang=' . $user->lang_name), 'T_STYLESHEET_NAME' => $user->theme['theme_name'], 'T_THEME_NAME' => $user->theme['theme_path'], @@ -4628,7 +4707,7 @@ function exit_handler() } // As a pre-caution... some setups display a blank page if the flush() is not there. - (empty($config['gzip_compress'])) ? @flush() : @ob_flush(); + (ob_get_level() > 0) ? @ob_flush() : @flush(); exit; } diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php index f28bca91ee..c3806dc786 100644 --- a/phpBB/includes/functions_acp.php +++ b/phpBB/includes/functions_acp.php @@ -164,7 +164,7 @@ function build_select($option_ary, $option_default = false) /** * Build radio fields in acp pages */ -function h_radio($name, &$input_ary, $input_default = false, $id = false, $key = false) +function h_radio($name, $input_ary, $input_default = false, $id = false, $key = false, $separator = '') { global $user; @@ -173,7 +173,7 @@ function h_radio($name, &$input_ary, $input_default = false, $id = false, $key = foreach ($input_ary as $value => $title) { $selected = ($input_default !== false && $value == $input_default) ? ' checked="checked"' : ''; - $html .= '<label><input type="radio" name="' . $name . '"' . (($id && !$id_assigned) ? ' id="' . $id . '"' : '') . ' value="' . $value . '"' . $selected . (($key) ? ' accesskey="' . $key . '"' : '') . ' class="radio" /> ' . $user->lang[$title] . '</label>'; + $html .= '<label><input type="radio" name="' . $name . '"' . (($id && !$id_assigned) ? ' id="' . $id . '"' : '') . ' value="' . $value . '"' . $selected . (($key) ? ' accesskey="' . $key . '"' : '') . ' class="radio" /> ' . $user->lang[$title] . '</label>' . $separator; $id_assigned = true; } @@ -203,7 +203,7 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars) $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 = '<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': @@ -329,7 +329,7 @@ function validate_config_vars($config_vars, &$cfg_array, &$error) switch ($validator[$type]) { case 'string': - $length = strlen($cfg_array[$config_name]); + $length = utf8_strlen($cfg_array[$config_name]); // the column is a VARCHAR $validator[$max] = (isset($validator[$max])) ? min(255, $validator[$max]) : 255; @@ -527,7 +527,7 @@ function validate_range($value_ary, &$error) { case 'string' : $max = (isset($column[1])) ? min($column[1],$type['max']) : $type['max']; - if (strlen($value['value']) > $max) + if (utf8_strlen($value['value']) > $max) { $error[] = sprintf($user->lang['SETTING_TOO_LONG'], $user->lang[$value['lang']], $max); } diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index ee59d77cdb..71f8ab572e 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2596,6 +2596,31 @@ function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id $sql_keywords .= 'LOWER(l.log_data) ' . implode(' OR LOWER(l.log_data) ', $keywords) . ')'; } + if ($log_count !== false) + { + $sql = 'SELECT COUNT(l.log_id) AS total_entries + FROM ' . LOG_TABLE . ' l, ' . USERS_TABLE . " u + WHERE l.log_type = $log_type + AND l.user_id = u.user_id + AND l.log_time >= $limit_days + $sql_keywords + $sql_forum"; + $result = $db->sql_query($sql); + $log_count = (int) $db->sql_fetchfield('total_entries'); + $db->sql_freeresult($result); + } + + if ($log_count == 0) + { + // Save the queries, because there are no logs to display + return 0; + } + + if ($offset >= $log_count) + { + $offset = ($offset - $limit < 0) ? 0 : $offset - $limit; + } + $sql = "SELECT l.*, u.username, u.username_clean, u.user_colour FROM " . LOG_TABLE . " l, " . USERS_TABLE . " u WHERE l.log_type = $log_type @@ -2743,21 +2768,7 @@ function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id } } - if ($log_count !== false) - { - $sql = 'SELECT COUNT(l.log_id) AS total_entries - FROM ' . LOG_TABLE . ' l, ' . USERS_TABLE . " u - WHERE l.log_type = $log_type - AND l.user_id = u.user_id - AND l.log_time >= $limit_days - $sql_keywords - $sql_forum"; - $result = $db->sql_query($sql); - $log_count = (int) $db->sql_fetchfield('total_entries'); - $db->sql_freeresult($result); - } - - return; + return $offset; } /** @@ -2889,6 +2900,12 @@ function view_inactive_users(&$users, &$user_count, $limit = 0, $offset = 0, $li $user_count = (int) $db->sql_fetchfield('user_count'); $db->sql_freeresult($result); + if ($user_count == 0) + { + // Save the queries, because there are no users to display + return 0; + } + if ($offset >= $user_count) { $offset = ($offset - $limit < 0) ? 0 : $offset - $limit; diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index 179fd3c2f8..63e4a16fb6 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -691,6 +691,9 @@ function censor_text($text) return ''; } + // Strip control characters + $text = preg_replace('/[\x00-\x0f]/', '', $text); + // We moved the word censor checks in here because we call this function quite often - and then only need to do the check once if (!isset($censors) || !is_array($censors)) { @@ -1107,7 +1110,7 @@ function extension_allowed($forum_id, $extension, &$extensions) * @param int $max_length Maximum length of string (multibyte character count as 1 char / Html entity count as 1 char) * @param int $max_store_length Maximum character length of string (multibyte character count as 1 char / Html entity count as entity chars). * @param bool $allow_reply Allow Re: in front of string -* NOTE: This parameter can cause undesired behavior (returning strings longer than $max_store_legnth) and is deprecated. +* NOTE: This parameter can cause undesired behavior (returning strings longer than $max_store_length) and is deprecated. * @param string $append String to be appended */ function truncate_string($string, $max_length = 60, $max_store_length = 255, $allow_reply = false, $append = '') diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index abc5b3e29f..26a4e965a7 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -459,7 +459,6 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod 'SUBFORUMS' => $s_subforums_list, 'L_SUBFORUM_STR' => $l_subforums, - 'L_FORUM_FOLDER_ALT' => $folder_alt, 'L_MODERATOR_STR' => $l_moderator, 'U_UNAPPROVED_TOPICS' => ($row['forum_id_unapproved_topics']) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=unapproved_topics&f=' . $row['forum_id_unapproved_topics']) : '', @@ -1041,7 +1040,7 @@ function display_user_activity(&$userdata) /** * Topic and forum watching common code */ -function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, $notify_status = 'unset', $start = 0) +function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, $notify_status = 'unset', $start = 0, $item_title = '') { global $template, $db, $user, $phpEx, $start, $phpbb_root_path; global $request; @@ -1071,32 +1070,46 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, if (!is_null($notify_status) && $notify_status !== '') { - if (isset($_GET['unwatch'])) { $uid = request_var('uid', 0); - if ($uid != $user_id) - { - $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); - $message = $user->lang['ERR_UNWATCHING'] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); - trigger_error($message); - } - if ($request->variable('unwatch', '', false, phpbb_request_interface::GET) == $mode) + $token = request_var('hash', ''); + + if (($token && check_link_hash($token, "{$mode}_$match_id")) || confirm_box(true)) { - $is_watching = 0; + if (($uid != $user_id) || ($request->variable('unwatch', '', false, phpbb_request_interface::GET) != $mode)) + { + $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); + $message = $user->lang['ERR_UNWATCHING'] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); + trigger_error($message); + } $sql = 'DELETE FROM ' . $table_sql . " WHERE $where_sql = $match_id AND user_id = $user_id"; $db->sql_query($sql); - } - - $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); - meta_refresh(3, $redirect_url); + $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); + $message = $user->lang['NOT_WATCHING_' . strtoupper($mode)] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); + meta_refresh(3, $redirect_url); + trigger_error($message); + } + else + { + $s_hidden_fields = array( + 'uid' => $user->data['user_id'], + 'unwatch' => $mode, + 'start' => $start, + 'f' => $forum_id, + ); + if ($mode != 'forum') + { + $s_hidden_fields['t'] = $topic_id; + } - $message = $user->lang['NOT_WATCHING_' . strtoupper($mode)] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); - trigger_error($message); + $confirm_box_message = (($item_title == '') ? 'UNWATCH_' . strtoupper($mode) : $user->lang('UNWATCH_' . strtoupper($mode) . '_DETAILED', $item_title)); + confirm_box(false, $confirm_box_message, build_hidden_fields($s_hidden_fields)); + } } else { @@ -1116,26 +1129,45 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, { if (isset($_GET['watch'])) { + $uid = request_var('uid', 0); $token = request_var('hash', ''); - $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); - if ($request->variable('watch', '', false, phpbb_request_interface::GET) == $mode && check_link_hash($token, "{$mode}_$match_id")) + if (($token && check_link_hash($token, "{$mode}_$match_id")) || confirm_box(true)) { + if (($uid != $user_id) || ($request->variable('watch', '', false, phpbb_request_interface::GET) != $mode)) + { + $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); + $message = $user->lang['ERR_WATCHING'] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); + trigger_error($message); + } + $is_watching = true; $sql = 'INSERT INTO ' . $table_sql . " (user_id, $where_sql, notify_status) VALUES ($user_id, $match_id, " . NOTIFY_YES . ')'; $db->sql_query($sql); + + $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); $message = $user->lang['ARE_WATCHING_' . strtoupper($mode)] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); + meta_refresh(3, $redirect_url); + trigger_error($message); } else { - $message = $user->lang['ERR_WATCHING'] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); - } - - meta_refresh(3, $redirect_url); + $s_hidden_fields = array( + 'uid' => $user->data['user_id'], + 'watch' => $mode, + 'start' => $start, + 'f' => $forum_id, + ); + if ($mode != 'forum') + { + $s_hidden_fields['t'] = $topic_id; + } - trigger_error($message); + $confirm_box_message = (($item_title == '') ? 'WATCH_' . strtoupper($mode) : $user->lang('WATCH_' . strtoupper($mode) . '_DETAILED', $item_title)); + confirm_box(false, $confirm_box_message, build_hidden_fields($s_hidden_fields)); + } } else { @@ -1145,7 +1177,8 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, } else { - if ($request->variable('unwatch', '', false, phpbb_request_interface::GET) == $mode) + if ((isset($_GET['unwatch']) && $request->variable('unwatch', '', false, phpbb_request_interface::GET) == $mode) || + (isset($_GET['watch']) && $request->variable('watch', '', false, phpbb_request_interface::GET) == $mode)) { login_box(); } diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index 94bcb36698..91a09608c7 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -100,10 +100,10 @@ function send_avatar_to_browser($file, $browser) */ function wrap_img_in_html($src, $title) { - echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-Strict.dtd">'; + echo '<!DOCTYPE html>'; echo '<html>'; echo '<head>'; - echo '<meta http-equiv="content-type" content="text/html; charset=UTF-8" />'; + echo '<meta charset="utf-8">'; echo '<title>' . $title . '</title>'; echo '</head>'; echo '<body>'; diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 0bb0ef8722..9e81533cea 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) */ function generate_smilies($mode, $forum_id) { - global $auth, $db, $user, $config, $template; + global $db, $user, $config, $template; global $phpEx, $phpbb_root_path; $start = request_var('start', 0); @@ -803,7 +803,7 @@ function posting_gen_inline_attachments(&$attachment_data) */ function posting_gen_attachment_entry($attachment_data, &$filename_data, $show_attach_box = true) { - global $template, $config, $phpbb_root_path, $phpEx, $user, $auth; + global $template, $config, $phpbb_root_path, $phpEx, $user; // Some default template variables $template->assign_vars(array( @@ -2458,3 +2458,105 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u return $url; } + +/** +* Handle topic bumping +* @param int $forum_id The ID of the forum the topic is being bumped belongs to +* @param int $topic_id The ID of the topic is being bumping +* @param array $post_data Passes some topic parameters: +* - 'topic_title' +* - 'topic_last_post_id' +* - 'topic_last_poster_id' +* - 'topic_last_post_subject' +* - 'topic_last_poster_name' +* - 'topic_last_poster_colour' +* @param int $bump_time The time at which topic was bumped, usually it is a current time as obtained via time(). +* @return string An URL to the bumped topic, example: ./viewtopic.php?forum_id=1&topic_id=2&p=3#p3 +*/ +function phpbb_bump_topic($forum_id, $topic_id, $post_data, $bump_time = false) +{ + global $config, $db, $user, $phpEx, $phpbb_root_path; + + if ($bump_time === false) + { + $bump_time = time(); + } + + // Begin bumping + $db->sql_transaction('begin'); + + // Update the topic's last post post_time + $sql = 'UPDATE ' . POSTS_TABLE . " + SET post_time = $bump_time + WHERE post_id = {$post_data['topic_last_post_id']} + AND topic_id = $topic_id"; + $db->sql_query($sql); + + // Sync the topic's last post time, the rest of the topic's last post data isn't changed + $sql = 'UPDATE ' . TOPICS_TABLE . " + SET topic_last_post_time = $bump_time, + topic_bumped = 1, + topic_bumper = " . $user->data['user_id'] . " + WHERE topic_id = $topic_id"; + $db->sql_query($sql); + + // Update the forum's last post info + $sql = 'UPDATE ' . FORUMS_TABLE . " + SET forum_last_post_id = " . $post_data['topic_last_post_id'] . ", + forum_last_poster_id = " . $post_data['topic_last_poster_id'] . ", + forum_last_post_subject = '" . $db->sql_escape($post_data['topic_last_post_subject']) . "', + forum_last_post_time = $bump_time, + forum_last_poster_name = '" . $db->sql_escape($post_data['topic_last_poster_name']) . "', + forum_last_poster_colour = '" . $db->sql_escape($post_data['topic_last_poster_colour']) . "' + WHERE forum_id = $forum_id"; + $db->sql_query($sql); + + // Update bumper's time of the last posting to prevent flood + $sql = 'UPDATE ' . USERS_TABLE . " + SET user_lastpost_time = $bump_time + WHERE user_id = " . $user->data['user_id']; + $db->sql_query($sql); + + $db->sql_transaction('commit'); + + // Mark this topic as posted to + markread('post', $forum_id, $topic_id, $bump_time); + + // Mark this topic as read + markread('topic', $forum_id, $topic_id, $bump_time); + + // Update forum tracking info + if ($config['load_db_lastread'] && $user->data['is_registered']) + { + $sql = 'SELECT mark_time + FROM ' . FORUMS_TRACK_TABLE . ' + WHERE user_id = ' . $user->data['user_id'] . ' + AND forum_id = ' . $forum_id; + $result = $db->sql_query($sql); + $f_mark_time = (int) $db->sql_fetchfield('mark_time'); + $db->sql_freeresult($result); + } + else if ($config['load_anon_lastread'] || $user->data['is_registered']) + { + $f_mark_time = false; + } + + if (($config['load_db_lastread'] && $user->data['is_registered']) || $config['load_anon_lastread'] || $user->data['is_registered']) + { + // Update forum info + $sql = 'SELECT forum_last_post_time + FROM ' . FORUMS_TABLE . ' + WHERE forum_id = ' . $forum_id; + $result = $db->sql_query($sql); + $forum_last_post_time = (int) $db->sql_fetchfield('forum_last_post_time'); + $db->sql_freeresult($result); + + update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_time, false); + } + + add_log('mod', $forum_id, $topic_id, 'LOG_BUMP_TOPIC', $post_data['topic_title']); + + $url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id&p={$post_data['topic_last_post_id']}") . "#p{$post_data['topic_last_post_id']}"; + + return $url; +} diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php index 44deffa162..ec29a1732d 100644 --- a/phpBB/includes/functions_profile_fields.php +++ b/phpBB/includes/functions_profile_fields.php @@ -149,7 +149,18 @@ class custom_profile case FIELD_DROPDOWN: $field_value = (int) $field_value; - + + // retrieve option lang data if necessary + if (!isset($this->options_lang[$field_data['field_id']]) || !isset($this->options_lang[$field_data['field_id']][$field_data['lang_id']]) || !sizeof($this->options_lang[$file_data['field_id']][$field_data['lang_id']])) + { + $this->get_option_lang($field_data['field_id'], $field_data['lang_id'], FIELD_DROPDOWN, false); + } + + if (!isset($this->options_lang[$field_data['field_id']][$field_data['lang_id']][$field_value])) + { + return 'FIELD_INVALID_VALUE'; + } + if ($field_value == $field_data['field_novalue'] && $field_data['field_required']) { return 'FIELD_REQUIRED'; @@ -302,6 +313,7 @@ class custom_profile switch ($cp_result) { case 'FIELD_INVALID_DATE': + case 'FIELD_INVALID_VALUE': case 'FIELD_REQUIRED': $error = sprintf($user->lang[$cp_result], $row['lang_name']); break; diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php index 01f8584970..dc05ba4110 100644 --- a/phpBB/includes/mcp/mcp_logs.php +++ b/phpBB/includes/mcp/mcp_logs.php @@ -170,7 +170,7 @@ class mcp_logs // Grab log data $log_data = array(); $log_count = 0; - view_log('mod', $log_data, $log_count, $config['topics_per_page'], $start, $forum_list, $topic_id, 0, $sql_where, $sql_sort, $keywords); + $start = view_log('mod', $log_data, $log_count, $config['topics_per_page'], $start, $forum_list, $topic_id, 0, $sql_where, $sql_sort, $keywords); $template->assign_vars(array( 'PAGE_NUMBER' => on_page($log_count, $config['topics_per_page'], $start), @@ -179,7 +179,7 @@ class mcp_logs 'L_TITLE' => $user->lang['MCP_LOGS'], - 'U_POST_ACTION' => $this->u_action, + 'U_POST_ACTION' => $this->u_action . "&$u_sort_param$keywords_param&start=$start", 'S_CLEAR_ALLOWED' => ($auth->acl_get('a_clearlogs')) ? true : false, 'S_SELECT_SORT_DIR' => $s_sort_dir, 'S_SELECT_SORT_KEY' => $s_sort_key, diff --git a/phpBB/includes/mcp/mcp_notes.php b/phpBB/includes/mcp/mcp_notes.php index 0b22ff74fd..dfb6ed3b68 100644 --- a/phpBB/includes/mcp/mcp_notes.php +++ b/phpBB/includes/mcp/mcp_notes.php @@ -198,7 +198,7 @@ class mcp_notes $log_data = array(); $log_count = 0; - view_log('user', $log_data, $log_count, $config['topics_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort, $keywords); + $start = view_log('user', $log_data, $log_count, $config['topics_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort, $keywords); if ($log_count) { diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index c6132d86d4..b3a48112ea 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -102,20 +102,22 @@ class bbcode_firstpass extends bbcode /** * Init bbcode data for later parsing */ - function bbcode_init() + function bbcode_init($allow_custom_bbcode = true) { static $rowset; // This array holds all bbcode data. BBCodes will be processed in this // order, so it is important to keep [code] in first position and // [quote] in second position. + // To parse multiline URL we enable dotall option setting only for URL text + // but not for link itself, thus [url][/url] is not affected. $this->bbcodes = array( 'code' => array('bbcode_id' => 8, 'regexp' => array('#\[code(?:=([a-z]+))?\](.+\[/code\])#uise' => "\$this->bbcode_code('\$1', '\$2')")), 'quote' => array('bbcode_id' => 0, 'regexp' => array('#\[quote(?:="(.*?)")?\](.+)\[/quote\]#uise' => "\$this->bbcode_quote('\$0')")), 'attachment' => array('bbcode_id' => 12, 'regexp' => array('#\[attachment=([0-9]+)\](.*?)\[/attachment\]#uise' => "\$this->bbcode_attachment('\$1', '\$2')")), 'b' => array('bbcode_id' => 1, 'regexp' => array('#\[b\](.*?)\[/b\]#uise' => "\$this->bbcode_strong('\$1')")), 'i' => array('bbcode_id' => 2, 'regexp' => array('#\[i\](.*?)\[/i\]#uise' => "\$this->bbcode_italic('\$1')")), - 'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url(=(.*))?\](.*)\[/url\]#uiUe' => "\$this->validate_url('\$2', '\$3')")), + 'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url(=(.*))?\](?(1)((?s).*(?-s))|(.*))\[/url\]#uiUe' => "\$this->validate_url('\$2', ('\$3') ? '\$3' : '\$4')")), 'img' => array('bbcode_id' => 4, 'regexp' => array('#\[img\](.*)\[/img\]#uiUe' => "\$this->bbcode_img('\$1')")), 'size' => array('bbcode_id' => 5, 'regexp' => array('#\[size=([\-\+]?\d+)\](.*?)\[/size\]#uise' => "\$this->bbcode_size('\$1', '\$2')")), 'color' => array('bbcode_id' => 6, 'regexp' => array('!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+)\](.*?)\[/color\]!uise' => "\$this->bbcode_color('\$1', '\$2')")), @@ -133,6 +135,11 @@ class bbcode_firstpass extends bbcode $this->parsed_items[$tag] = 0; } + if (!$allow_custom_bbcode) + { + return; + } + if (!is_array($rowset)) { global $db; diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index 893ec2c0cc..e36f44ddfa 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -222,7 +222,7 @@ class session // if the forwarded for header shall be checked we have to validate its contents if ($config['forwarded_for_check']) { - $this->forwarded_for = preg_replace('#[ ]{2,}#', ' ', str_replace(array(',', ' '), ' ', $this->forwarded_for)); + $this->forwarded_for = preg_replace('# {2,}#', ' ', str_replace(',', ' ', $this->forwarded_for)); // split the list of IPs $ips = explode(' ', $this->forwarded_for); @@ -268,11 +268,11 @@ class session // Why no forwarded_for et al? Well, too easily spoofed. With the results of my recent requests // it's pretty clear that in the majority of cases you'll at least be left with a proxy/cache ip. - $this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars((string) $_SERVER['REMOTE_ADDR']) : ''; - $this->ip = preg_replace('#[ ]{2,}#', ' ', str_replace(array(',', ' '), ' ', $this->ip)); + $this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? (string) $_SERVER['REMOTE_ADDR'] : ''; + $this->ip = preg_replace('# {2,}#', ' ', str_replace(',', ' ', $this->ip)); // split the list of IPs - $ips = explode(' ', $this->ip); + $ips = explode(' ', trim($this->ip)); // Default IP if REMOTE_ADDR is invalid $this->ip = '127.0.0.1'; @@ -297,26 +297,31 @@ class session continue; } - // check IPv4 first, the IPv6 is hopefully only going to be used very seldomly - if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip)) + if (preg_match(get_preg_expression('ipv4'), $ip)) { - // Just break - break; + $this->ip = $ip; } - - // Quick check for IPv4-mapped address in IPv6 - if (stripos($ip, '::ffff:') === 0) + else if (preg_match(get_preg_expression('ipv6'), $ip)) { - $ipv4 = substr($ip, 7); - - if (preg_match(get_preg_expression('ipv4'), $ipv4)) + // Quick check for IPv4-mapped address in IPv6 + if (stripos($ip, '::ffff:') === 0) { - $ip = $ipv4; + $ipv4 = substr($ip, 7); + + if (preg_match(get_preg_expression('ipv4'), $ipv4)) + { + $ip = $ipv4; + } } - } - // Use the last in chain - $this->ip = $ip; + $this->ip = $ip; + } + else + { + // We want to use the last valid address in the chain + // Leave foreach loop when address is invalid + break; + } } $this->load = false; @@ -602,6 +607,7 @@ class session // otherwise they'll index this page with the SID, duplicate content oh my! if ($bot && isset($_GET['sid'])) { + send_status_line(301, 'Moved Permanently'); redirect(build_url(array('sid'))); } @@ -1013,6 +1019,10 @@ class session include($phpbb_root_path . "includes/captcha/captcha_factory." . $phpEx); } phpbb_captcha_factory::garbage_collect($config['captcha_plugin']); + + $sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . ' + WHERE attempt_time < ' . (time() - (int) $config['ip_login_limit_time']); + $db->sql_query($sql); } return; @@ -1251,6 +1261,12 @@ class session $ip = $this->ip; } + // Neither Spamhaus nor Spamcop supports IPv6 addresses. + if (strpos($ip, ':') !== false) + { + return false; + } + $dnsbl_check = array( 'sbl.spamhaus.org' => 'http://www.spamhaus.org/query/bl?ip=', ); @@ -2287,9 +2303,44 @@ class user extends session // Use URL if told so $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_root_path; - $img_data['src'] = $root_path . 'styles/' . rawurlencode($this->theme['imageset_path']) . '/imageset/' . ($this->img_array[$img]['image_lang'] ? $this->img_array[$img]['image_lang'] .'/' : '') . $this->img_array[$img]['image_filename']; + $path = 'styles/' . rawurlencode($this->theme['imageset_path']) . '/imageset/' . ($this->img_array[$img]['image_lang'] ? $this->img_array[$img]['image_lang'] .'/' : '') . $this->img_array[$img]['image_filename']; + + $img_data['src'] = $root_path . $path; $img_data['width'] = $this->img_array[$img]['image_width']; $img_data['height'] = $this->img_array[$img]['image_height']; + + // We overwrite the width and height to the phpbb logo's width + // and height here if the contents of the site_logo file are + // really equal to the phpbb_logo + // This allows us to change the dimensions of the phpbb_logo without + // modifying the imageset.cfg and causing a conflict for everyone + // who modified it for their custom logo on updating + if ($img == 'site_logo' && file_exists($phpbb_root_path . $path)) + { + global $cache; + + $img_file_hashes = $cache->get('imageset_site_logo_md5'); + + if ($img_file_hashes === false) + { + $img_file_hashes = array(); + } + + $key = $this->theme['imageset_path'] . '::' . $this->img_array[$img]['image_lang']; + if (!isset($img_file_hashes[$key])) + { + $img_file_hashes[$key] = md5(file_get_contents($phpbb_root_path . $path)); + $cache->put('imageset_site_logo_md5', $img_file_hashes); + } + + $phpbb_logo_hash = '0c461a32cd3621643105f0d02a772c10'; + + if ($phpbb_logo_hash == $img_file_hashes[$key]) + { + $img_data['width'] = '149'; + $img_data['height'] = '52'; + } + } } $alt = (!empty($this->lang[$alt])) ? $this->lang[$alt] : $alt; diff --git a/phpBB/includes/startup.php b/phpBB/includes/startup.php new file mode 100644 index 0000000000..ca9665da29 --- /dev/null +++ b/phpBB/includes/startup.php @@ -0,0 +1,150 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +/** +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +// Report all errors, except notices and deprecation messages +if (!defined('E_DEPRECATED')) +{ + define('E_DEPRECATED', 8192); +} +error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED); + +/* +* Remove variables created by register_globals from the global scope +* Thanks to Matt Kavanagh +*/ +function deregister_globals() +{ + $not_unset = array( + 'GLOBALS' => true, + '_GET' => true, + '_POST' => true, + '_COOKIE' => true, + '_REQUEST' => true, + '_SERVER' => true, + '_SESSION' => true, + '_ENV' => true, + '_FILES' => true, + 'phpEx' => true, + 'phpbb_root_path' => true + ); + + // Not only will array_merge and array_keys give a warning if + // a parameter is not an array, array_merge will actually fail. + // So we check if _SESSION has been initialised. + if (!isset($_SESSION) || !is_array($_SESSION)) + { + $_SESSION = array(); + } + + // Merge all into one extremely huge array; unset this later + $input = array_merge( + array_keys($_GET), + array_keys($_POST), + array_keys($_COOKIE), + array_keys($_SERVER), + array_keys($_SESSION), + array_keys($_ENV), + array_keys($_FILES) + ); + + foreach ($input as $varname) + { + if (isset($not_unset[$varname])) + { + // Hacking attempt. No point in continuing unless it's a COOKIE (so a cookie called GLOBALS doesn't lock users out completely) + if ($varname !== 'GLOBALS' || isset($_GET['GLOBALS']) || isset($_POST['GLOBALS']) || isset($_SERVER['GLOBALS']) || isset($_SESSION['GLOBALS']) || isset($_ENV['GLOBALS']) || isset($_FILES['GLOBALS'])) + { + exit; + } + else + { + $cookie = &$_COOKIE; + while (isset($cookie['GLOBALS'])) + { + if (!is_array($cookie['GLOBALS'])) + { + break; + } + + foreach ($cookie['GLOBALS'] as $registered_var => $value) + { + if (!isset($not_unset[$registered_var])) + { + unset($GLOBALS[$registered_var]); + } + } + $cookie = &$cookie['GLOBALS']; + } + } + } + + unset($GLOBALS[$varname]); + } + + unset($input); +} + +// If we are on PHP >= 6.0.0 we do not need some code +if (version_compare(PHP_VERSION, '6.0.0-dev', '>=')) +{ + /** + * @ignore + */ + define('STRIP', false); +} +else +{ + @set_magic_quotes_runtime(0); + + // Be paranoid with passed vars + if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on' || !function_exists('ini_get')) + { + deregister_globals(); + } + + define('STRIP', (get_magic_quotes_gpc()) ? true : false); +} + +// Prevent date/time functions from throwing E_WARNING on PHP 5.3 by setting a default timezone +if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) +{ + // For PHP 5.1.0 the date/time functions have been rewritten + // and setting a timezone is required prior to calling any date/time function. + + // Since PHP 5.2.0 calls to date/time functions without having a timezone set + // result in E_STRICT errors being thrown. + // Note: We already exclude E_STRICT errors + // (to be exact: they are not included in E_ALL in PHP 5.2) + + // In PHP 5.3.0 the error level has been raised to E_WARNING which causes problems + // because we show E_WARNING errors and do not set a default timezone. + // This is because we have our own timezone handling and work in UTC only anyway. + + // So what we basically want to do is set our timezone to UTC, + // but we don't know what other scripts (such as bridges) are involved, + // so we check whether a timezone is already set by calling date_default_timezone_get(). + + // Unfortunately, date_default_timezone_get() itself might throw E_WARNING + // if no timezone has been set, so we have to keep it quiet with @. + + // date_default_timezone_get() tries to guess the correct timezone first + // and then falls back to UTC when everything fails. + // We just set the timezone to whatever date_default_timezone_get() returns. + date_default_timezone_set(@date_default_timezone_get()); +} + +$starttime = explode(' ', microtime()); +$starttime = $starttime[1] + $starttime[0]; diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php index c10516c769..34b0b6d879 100644 --- a/phpBB/includes/ucp/ucp_activate.php +++ b/phpBB/includes/ucp/ucp_activate.php @@ -98,6 +98,13 @@ class ucp_activate SET user_actkey = '' WHERE user_id = {$user_row['user_id']}"; $db->sql_query($sql); + + // Create the correct logs + add_log('user', $user_row['user_id'], 'LOG_USER_ACTIVE_USER'); + if ($auth->acl_get('a_user')) + { + add_log('admin', 'LOG_USER_ACTIVE', $user_row['username']); + } } if ($config['require_activation'] == USER_ACTIVATION_ADMIN && !$update_password) diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php index 84fa9b18dc..87d51ca613 100644 --- a/phpBB/includes/ucp/ucp_pm.php +++ b/phpBB/includes/ucp/ucp_pm.php @@ -115,7 +115,7 @@ class ucp_pm case 'compose': $action = request_var('action', 'post'); - get_folder($user->data['user_id']); + $user_folders = get_folder($user->data['user_id']); if (!$auth->acl_get('u_sendpm')) { @@ -130,7 +130,7 @@ class ucp_pm } include($phpbb_root_path . 'includes/ucp/ucp_pm_compose.' . $phpEx); - compose_pm($id, $mode, $action); + compose_pm($id, $mode, $action, $user_folders); $tpl_file = 'posting_body'; break; diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index 07aa25d67b..92297c1490 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -20,7 +20,7 @@ if (!defined('IN_PHPBB')) * Compose private message * Called from ucp_pm with mode == 'compose' */ -function compose_pm($id, $mode, $action) +function compose_pm($id, $mode, $action, $user_folders = array()) { global $template, $db, $auth, $user; global $phpbb_root_path, $phpEx, $config; @@ -130,6 +130,7 @@ function compose_pm($id, $mode, $action) } $sql = ''; + $folder_id = 0; // What is all this following SQL for? Well, we need to know // some basic information in all cases before we do anything. @@ -393,7 +394,7 @@ function compose_pm($id, $mode, $action) unset($message_text); $s_action = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&mode=$mode&action=$action", true, $user->session_id); - $s_action .= ($msg_id) ? "&p=$msg_id" : ''; + $s_action .= (($folder_id) ? "&f=$folder_id" : '') . (($msg_id) ? "&p=$msg_id" : ''); // Delete triggered ? if ($action == 'delete') @@ -736,10 +737,30 @@ function compose_pm($id, $mode, $action) $msg_id = submit_pm($action, $subject, $pm_data); $return_message_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=view&p=' . $msg_id); - $return_folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=outbox'); - meta_refresh(3, $return_message_url); + $inbox_folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox'); + $outbox_folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=outbox'); + + $folder_url = ''; + if (($folder_id > 0) && isset($user_folders[$folder_id])) + { + $folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=' . $folder_id); + } + + $return_box_url = ($action === 'post' || $action === 'edit') ? $outbox_folder_url : $inbox_folder_url; + $return_box_lang = ($action === 'post' || $action === 'edit') ? 'PM_OUTBOX' : 'PM_INBOX'; + - $message = $user->lang['MESSAGE_STORED'] . '<br /><br />' . sprintf($user->lang['VIEW_PRIVATE_MESSAGE'], '<a href="' . $return_message_url . '">', '</a>') . '<br /><br />' . sprintf($user->lang['CLICK_RETURN_FOLDER'], '<a href="' . $return_folder_url . '">', '</a>', $user->lang['PM_OUTBOX']); + $message = $user->lang['MESSAGE_STORED'] . '<br /><br />' . sprintf($user->lang['VIEW_PRIVATE_MESSAGE'], '<a href="' . $return_message_url . '">', '</a>'); + + $last_click_type = 'CLICK_RETURN_FOLDER'; + if ($folder_url) + { + $message .= '<br /><br />' . sprintf($user->lang['CLICK_RETURN_FOLDER'], '<a href="' . $folder_url . '">', '</a>', $user_folders[$folder_id]['folder_name']); + $last_click_type = 'CLICK_GOTO_FOLDER'; + } + $message .= '<br /><br />' . sprintf($user->lang[$last_click_type], '<a href="' . $return_box_url . '">', '</a>', $user->lang[$return_box_lang]); + + meta_refresh(3, $return_message_url); trigger_error($message); } diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index 74a32a68c9..8b288f5de1 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -59,6 +59,18 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) $bbcode = new bbcode($message_row['bbcode_bitfield']); } + // Load the custom profile fields + if ($config['load_cpf_pm']) + { + if (!class_exists('custom_profile')) + { + include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); + } + $cp = new custom_profile(); + + $profile_fields = $cp->generate_profile_fields_template('grab', $author_id); + } + // Assign TO/BCC Addresses to template write_pm_addresses(array('to' => $message_row['to_address'], 'bcc' => $message_row['bcc_address']), $author_id); @@ -174,6 +186,25 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) $bbcode_status = ($config['allow_bbcode'] && $config['auth_bbcode_pm'] && $auth->acl_get('u_pm_bbcode')) ? true : false; + // Get the profile fields template data + $cp_row = array(); + if ($config['load_cpf_pm'] && isset($profile_fields[$author_id])) + { + // Filter the fields we don't want to show + foreach ($profile_fields[$author_id] as $used_ident => $profile_field) + { + if (!$profile_field['data']['field_show_on_pm']) + { + unset($profile_fields[$author_id][$used_ident]); + } + } + + if (isset($profile_fields[$author_id])) + { + $cp_row = $cp->generate_profile_fields_template('show', false, $profile_fields[$author_id]); + } + } + $template->assign_vars(array( 'MESSAGE_AUTHOR_FULL' => get_username_string('full', $author_id, $user_info['username'], $user_info['user_colour'], $user_info['username']), 'MESSAGE_AUTHOR_COLOUR' => get_username_string('colour', $author_id, $user_info['username'], $user_info['user_colour'], $user_info['username']), @@ -232,11 +263,23 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) 'S_SPECIAL_FOLDER' => in_array($folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)), 'S_PM_RECIPIENTS' => $num_recipients, 'S_BBCODE_ALLOWED' => ($bbcode_status) ? 1 : 0, + 'S_CUSTOM_FIELDS' => (!empty($cp_row['row'])) ? true : false, 'U_PRINT_PM' => ($config['print_pm'] && $auth->acl_get('u_pm_printpm')) ? "$url&f=$folder_id&p=" . $message_row['msg_id'] . "&view=print" : '', 'U_FORWARD_PM' => ($config['forward_pm'] && $auth->acl_get('u_sendpm') && $auth->acl_get('u_pm_forward')) ? "$url&mode=compose&action=forward&f=$folder_id&p=" . $message_row['msg_id'] : '') ); + // Display the custom profile fields + if (!empty($cp_row['row'])) + { + $template->assign_vars($cp_row['row']); + + foreach ($cp_row['blockrow'] as $cp_block_row) + { + $template->assign_block_vars('custom_fields', $cp_block_row); + } + } + // Display not already displayed Attachments for this post, we already parsed them. ;) if (isset($attachments) && sizeof($attachments)) { diff --git a/phpBB/index.php b/phpBB/index.php index 0830dd0686..419b66cfdb 100644 --- a/phpBB/index.php +++ b/phpBB/index.php @@ -81,10 +81,10 @@ $db->sql_freeresult($result); $legend = implode(', ', $legend); // Generate birthday list if required ... -$birthday_list = ''; +$birthday_list = array(); if ($config['load_birthdays'] && $config['allow_birthdays']) { - $now = getdate(time() + $user->timezone + $user->dst - date('Z')); + $now = phpbb_gmgetdate(time() + $user->timezone + $user->dst); $sql = 'SELECT u.user_id, u.username, u.user_colour, u.user_birthday FROM ' . USERS_TABLE . ' u LEFT JOIN ' . BANLIST_TABLE . " b ON (u.user_id = b.ban_userid) @@ -96,12 +96,17 @@ if ($config['load_birthdays'] && $config['allow_birthdays']) while ($row = $db->sql_fetchrow($result)) { - $birthday_list .= (($birthday_list != '') ? ', ' : '') . get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']); + $birthday_username = get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']); + $birthday_year = (int) substr($row['user_birthday'], -4); + $birthday_age = ($birthday_year) ? $now['year'] - $birthday_year : ''; - if ($age = (int) substr($row['user_birthday'], -4)) - { - $birthday_list .= ' (' . ($now['year'] - $age) . ')'; - } + $template->assign_block_vars('birthdays', array( + 'USERNAME' => $birthday_username, + 'AGE' => $birthday_age, + )); + + // For 3.0 compatibility + $birthday_list[] = $birthday_username . (($birthday_year) ? ' (' . $birthday_age . ')' : ''); } $db->sql_freeresult($result); } @@ -114,7 +119,7 @@ $template->assign_vars(array( 'NEWEST_USER' => sprintf($user->lang['NEWEST_USER'], get_username_string('full', $config['newest_user_id'], $config['newest_username'], $config['newest_user_colour'])), 'LEGEND' => $legend, - 'BIRTHDAY_LIST' => $birthday_list, + 'BIRTHDAY_LIST' => (empty($birthday_list)) ? '' : implode(', ', $birthday_list), 'FORUM_IMG' => $user->img('forum_read', 'NO_UNREAD_POSTS'), 'FORUM_UNREAD_IMG' => $user->img('forum_unread', 'UNREAD_POSTS'), diff --git a/phpBB/install/convertors/functions_phpbb20.php b/phpBB/install/convertors/functions_phpbb20.php index 1bf62476bd..9333bfe86d 100644 --- a/phpBB/install/convertors/functions_phpbb20.php +++ b/phpBB/install/convertors/functions_phpbb20.php @@ -94,6 +94,7 @@ function phpbb_insert_forums() { case 'mssql': case 'mssql_odbc': + case 'mssqlnative': $db->sql_query('SET IDENTITY_INSERT ' . FORUMS_TABLE . ' ON'); break; } @@ -291,6 +292,7 @@ function phpbb_insert_forums() case 'mssql': case 'mssql_odbc': + case 'mssqlnative': $db->sql_query('SET IDENTITY_INSERT ' . FORUMS_TABLE . ' OFF'); break; @@ -1727,6 +1729,7 @@ function phpbb_create_userconv_table() case 'mssql': case 'mssql_odbc': + case 'mssqlnative': $map_dbms = 'mssql'; break; diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index ca7ac8aad5..37fe6817d5 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -7,17 +7,21 @@ * */ -$updates_to_version = '3.1.0-dev'; +define('UPDATES_TO_VERSION', '3.1.0-dev'); // Enter any version to update from to test updates. The version within the db will not be updated. -$debug_from_version = false; +define('DEBUG_FROM_VERSION', false); // Which oldest version does this updater support? -$oldest_from_version = '3.0.0'; +define('OLDEST_FROM_VERSION', '3.0.0'); // Return if we "just include it" to find out for which version the database update is responsible for if (defined('IN_PHPBB') && defined('IN_INSTALL')) { + $updates_to_version = UPDATES_TO_VERSION; + $debug_from_version = DEBUG_FROM_VERSION; + $oldest_from_version = OLDEST_FROM_VERSION; + return; } @@ -29,12 +33,32 @@ define('IN_INSTALL', true); $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; $phpEx = substr(strrchr(__FILE__, '.'), 1); -// Report all errors, except notices and deprecation messages -if (!defined('E_DEPRECATED')) +if (!function_exists('phpbb_require_updated')) { - define('E_DEPRECATED', 8192); + function phpbb_require_updated($path, $optional = false) + { + global $phpbb_root_path; + + $new_path = $phpbb_root_path . 'install/update/new/' . $path; + $old_path = $phpbb_root_path . $path; + + if (file_exists($new_path)) + { + require($new_path); + } + else if (!$optional || file_exists($old_path)) + { + require($old_path); + } + } } -//error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED); + +phpbb_require_updated('includes/startup.' . $phpEx); + +$updates_to_version = UPDATES_TO_VERSION; +$debug_from_version = DEBUG_FROM_VERSION; +$oldest_from_version = OLDEST_FROM_VERSION; + error_reporting(E_ALL); @set_time_limit(0); @@ -65,28 +89,20 @@ require($phpbb_root_path . 'includes/auth.' . $phpEx); require($phpbb_root_path . 'includes/functions.' . $phpEx); -if (file_exists($phpbb_root_path . 'includes/functions_content.' . $phpEx)) -{ - require($phpbb_root_path . 'includes/functions_content.' . $phpEx); -} +phpbb_require_updated('includes/functions_content.' . $phpEx, true); require($phpbb_root_path . 'includes/functions_admin.' . $phpEx); require($phpbb_root_path . 'includes/constants.' . $phpEx); require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx); require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); -// If we are on PHP >= 6.0.0 we do not need some code -if (version_compare(PHP_VERSION, '6.0.0-dev', '>=')) -{ - /** - * @ignore - */ - define('STRIP', false); -} -else +phpbb_require_updated('includes/db/db_tools.' . $phpEx); + +// new table constants are separately defined here in case the updater is run +// before the files are updated +if (!defined('LOGIN_ATTEMPT_TABLE')) { - @set_magic_quotes_runtime(0); - define('STRIP', (get_magic_quotes_gpc()) ? true : false); + define('LOGIN_ATTEMPT_TABLE', $table_prefix . 'login_attempts'); } $class_loader = new phpbb_class_loader($phpbb_root_path, '.' . $phpEx); @@ -167,9 +183,9 @@ $config = new phpbb_config_db($db, $cache->get_driver(), CONFIG_TABLE); set_config(null, null, null, $config); set_config_count(null, null, null, $config); -// We do not include DB Tools here, because we can not be sure the file is up-to-date ;) -// Instead, this file defines a clean db_tools version (we are also not able to provide a different file, else the database update will not work standalone) -$db_tools = new updater_db_tools($db, true); +// phpbb_db_tools will be taken from new files (under install/update/new) +// if possible, falling back to the board's copy. +$db_tools = new phpbb_db_tools($db, true); $database_update_info = database_update_info(); @@ -188,14 +204,10 @@ $ga_forum_id = request_var('ga_forum_id', 0); if ($has_global && !$ga_forum_id) { ?> - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - <html xmlns="http://www.w3.org/1999/xhtml" dir="<?php echo $lang['DIRECTION']; ?>" lang="<?php echo $lang['USER_LANG']; ?>" xml:lang="<?php echo $lang['USER_LANG']; ?>"> + <!DOCTYPE html> + <html dir="<?php echo $lang['DIRECTION']; ?>" lang="<?php echo $lang['USER_LANG']; ?>"> <head> - - <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> - <meta http-equiv="content-language" content="<?php echo $lang['USER_LANG']; ?>" /> - <meta http-equiv="content-style-type" content="text/css" /> - <meta http-equiv="imagetoolbar" content="no" /> + <meta charset="utf-8"> <title><?php echo $lang['UPDATING_TO_LATEST_STABLE']; ?></title> @@ -242,14 +254,10 @@ if ($has_global && !$ga_forum_id) header('Content-type: text/html; charset=UTF-8'); ?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="<?php echo $lang['DIRECTION']; ?>" lang="<?php echo $lang['USER_LANG']; ?>" xml:lang="<?php echo $lang['USER_LANG']; ?>"> +<!DOCTYPE html> +<html dir="<?php echo $lang['DIRECTION']; ?>" lang="<?php echo $lang['USER_LANG']; ?>"> <head> - -<meta http-equiv="content-type" content="text/html; charset=UTF-8" /> -<meta http-equiv="content-language" content="<?php echo $lang['USER_LANG']; ?>" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="imagetoolbar" content="no" /> +<meta charset="utf-8"> <title><?php echo $lang['UPDATING_TO_LATEST_STABLE']; ?></title> @@ -577,7 +585,7 @@ function _print_footer() </div> <div id="page-footer"> - Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group + Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group </div> </div> @@ -600,12 +608,23 @@ function _sql($sql, &$errored, &$error_ary, $echo_dot = true) $db->sql_return_on_error(true); - $result = $db->sql_query($sql); - if ($db->sql_error_triggered) + if ($sql === 'begin') + { + $result = $db->sql_transaction('begin'); + } + else if ($sql === 'commit') + { + $result = $db->sql_transaction('commit'); + } + else { - $errored = true; - $error_ary['sql'][] = $db->sql_error_sql; - $error_ary['error_code'][] = $db->sql_error_returned; + $result = $db->sql_query($sql); + if ($db->sql_error_triggered) + { + $errored = true; + $error_ary['sql'][] = $db->sql_error_sql; + $error_ary['error_code'][] = $db->sql_error_returned; + } } $db->sql_return_on_error(false); @@ -982,15 +1001,50 @@ function database_update_info() '3.0.7-PL1' => array(), // No changes from 3.0.8-RC1 to 3.0.8 '3.0.8-RC1' => array(), - // Changes from 3.0.8 to 3.0.9-RC1 '3.0.8' => array( + 'add_tables' => array( + LOGIN_ATTEMPT_TABLE => array( + 'COLUMNS' => array( + // this column was removed from the database updater + // after 3.0.9-RC3 was released. It might still exist + // in 3.0.9-RCX installations and has to be dropped in + // 3.0.10 after the db_tools class is capable of properly + // removing a primary key. + // 'attempt_id' => array('UINT', NULL, 'auto_increment'), + 'attempt_ip' => array('VCHAR:40', ''), + 'attempt_browser' => array('VCHAR:150', ''), + 'attempt_forwarded_for' => array('VCHAR:255', ''), + 'attempt_time' => array('TIMESTAMP', 0), + 'user_id' => array('UINT', 0), + 'username' => array('VCHAR_UNI:255', 0), + 'username_clean' => array('VCHAR_CI', 0), + ), + //'PRIMARY_KEY' => 'attempt_id', + 'KEYS' => array( + 'att_ip' => array('INDEX', array('attempt_ip', 'attempt_time')), + 'att_for' => array('INDEX', array('attempt_forwarded_for', 'attempt_time')), + 'att_time' => array('INDEX', array('attempt_time')), + 'user_id' => array('INDEX', 'user_id'), + ), + ), + ), 'change_columns' => array( BBCODES_TABLE => array( 'bbcode_id' => array('USINT', 0), ), ), ), + // No changes from 3.0.9-RC1 to 3.0.9-RC2 + '3.0.9-RC1' => array(), + // No changes from 3.0.9-RC2 to 3.0.9-RC3 + '3.0.9-RC2' => array(), + // No changes from 3.0.9-RC3 to 3.0.9-RC4 + '3.0.9-RC3' => array(), + // No changes from 3.0.9-RC4 to 3.0.9 + '3.0.9-RC4' => array(), + + /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.10-RC1 */ // Changes from 3.1.0-dev to 3.1.0-A1 '3.1.0-dev' => array( @@ -998,6 +1052,9 @@ function database_update_info() GROUPS_TABLE => array( 'group_teampage' => array('UINT', 0, 'after' => 'group_legend'), ), + PROFILE_FIELDS_TABLE => array( + 'field_show_on_pm' => array('BOOL', 0), + ), ), 'change_columns' => array( GROUPS_TABLE => array( @@ -1950,6 +2007,10 @@ function change_database_data(&$no_updates, $version) // Changes from 3.0.8 to 3.0.9-RC1 case '3.0.8': + set_config('ip_login_limit_max', '50'); + set_config('ip_login_limit_time', '21600'); + set_config('ip_login_limit_use_forwarded', '0'); + // Update file extension group names to use language strings, again. $sql = 'SELECT group_id, group_name FROM ' . EXTENSION_GROUPS_TABLE . ' @@ -1969,9 +2030,46 @@ function change_database_data(&$no_updates, $version) } $db->sql_freeresult($result); + global $db_tools, $table_prefix; + + // Recover from potentially broken Q&A CAPTCHA table on firebird + // Q&A CAPTCHA was uninstallable, so it's safe to remove these + // without data loss + if ($db_tools->sql_layer == 'firebird') + { + $tables = array( + $table_prefix . 'captcha_questions', + $table_prefix . 'captcha_answers', + $table_prefix . 'qa_confirm', + ); + foreach ($tables as $table) + { + if ($db_tools->sql_table_exists($table)) + { + $db_tools->sql_table_drop($table); + } + } + } + $no_updates = false; break; + // No changes from 3.0.9-RC1 to 3.0.9-RC2 + case '3.0.9-RC1': + break; + + // No changes from 3.0.9-RC2 to 3.0.9-RC3 + case '3.0.9-RC2': + break; + + // No changes from 3.0.9-RC3 to 3.0.9-RC4 + case '3.0.9-RC3': + break; + + // No changes from 3.0.9-RC4 to 3.0.9 + case '3.0.9-RC4': + break; + // Changes from 3.1.0-dev to 3.1.0-A1 case '3.1.0-dev': set_config('use_system_cron', 0); @@ -2020,6 +2118,13 @@ function change_database_data(&$no_updates, $version) 'auth' => 'acl_a_group', 'cat' => 'ACP_GROUPS', ), + 'manage' => array( + 'base' => 'attachments', + 'class' => 'acp', + 'title' => 'ACP_MANAGE_ATTACHMENTS', + 'auth' => 'acl_a_attach', + 'cat' => 'ACP_ATTACHMENTS', + ), ); _add_modules($modules_to_install); @@ -2101,1949 +2206,10 @@ function change_database_data(&$no_updates, $version) unset($table_ary); } + // Allow custom profile fields in pm templates + set_config('load_cpf_pm', '0'); + $no_updates = false; break; } } - - -/** -* Database Tools for handling cross-db actions such as altering columns, etc. -* Currently not supported is returning SQL for creating tables. -* -* @package dbal -*/ -class updater_db_tools -{ - /** - * Current sql layer - */ - var $sql_layer = ''; - - /** - * @var object DB object - */ - var $db = NULL; - - /** - * The Column types for every database we support - * @var array - */ - var $dbms_type_map = array( - 'mysql_41' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'mediumint(8) UNSIGNED', - 'UINT:' => 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'smallint(4) UNSIGNED', - 'BOOL' => 'tinyint(1) UNSIGNED', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'text', - 'XSTEXT_UNI'=> 'varchar(100)', - 'STEXT' => 'text', - 'STEXT_UNI' => 'varchar(255)', - 'TEXT' => 'text', - 'TEXT_UNI' => 'text', - 'MTEXT' => 'mediumtext', - 'MTEXT_UNI' => 'mediumtext', - 'TIMESTAMP' => 'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar(255)', - 'VARBINARY' => 'varbinary(255)', - ), - - 'mysql_40' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'mediumint(8) UNSIGNED', - 'UINT:' => 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'smallint(4) UNSIGNED', - 'BOOL' => 'tinyint(1) UNSIGNED', - 'VCHAR' => 'varbinary(255)', - 'VCHAR:' => 'varbinary(%d)', - 'CHAR:' => 'binary(%d)', - 'XSTEXT' => 'blob', - 'XSTEXT_UNI'=> 'blob', - 'STEXT' => 'blob', - 'STEXT_UNI' => 'blob', - 'TEXT' => 'blob', - 'TEXT_UNI' => 'blob', - 'MTEXT' => 'mediumblob', - 'MTEXT_UNI' => 'mediumblob', - 'TIMESTAMP' => 'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'blob', - 'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')), - 'VCHAR_CI' => 'blob', - 'VARBINARY' => 'varbinary(255)', - ), - - 'firebird' => array( - 'INT:' => 'INTEGER', - 'BINT' => 'DOUBLE PRECISION', - 'UINT' => 'INTEGER', - 'UINT:' => 'INTEGER', - 'TINT:' => 'INTEGER', - 'USINT' => 'INTEGER', - 'BOOL' => 'INTEGER', - 'VCHAR' => 'VARCHAR(255) CHARACTER SET NONE', - 'VCHAR:' => 'VARCHAR(%d) CHARACTER SET NONE', - 'CHAR:' => 'CHAR(%d) CHARACTER SET NONE', - 'XSTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'STEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'TEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'MTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8', - 'STEXT_UNI' => 'VARCHAR(255) CHARACTER SET UTF8', - 'TEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8', - 'MTEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8', - 'TIMESTAMP' => 'INTEGER', - 'DECIMAL' => 'DOUBLE PRECISION', - 'DECIMAL:' => 'DOUBLE PRECISION', - 'PDECIMAL' => 'DOUBLE PRECISION', - 'PDECIMAL:' => 'DOUBLE PRECISION', - 'VCHAR_UNI' => 'VARCHAR(255) CHARACTER SET UTF8', - 'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8', - 'VCHAR_CI' => 'VARCHAR(255) CHARACTER SET UTF8', - 'VARBINARY' => 'CHAR(255) CHARACTER SET NONE', - ), - - 'mssql' => array( - 'INT:' => '[int]', - 'BINT' => '[float]', - 'UINT' => '[int]', - 'UINT:' => '[int]', - 'TINT:' => '[int]', - 'USINT' => '[int]', - 'BOOL' => '[int]', - 'VCHAR' => '[varchar] (255)', - 'VCHAR:' => '[varchar] (%d)', - 'CHAR:' => '[char] (%d)', - 'XSTEXT' => '[varchar] (1000)', - 'STEXT' => '[varchar] (3000)', - 'TEXT' => '[varchar] (8000)', - 'MTEXT' => '[text]', - 'XSTEXT_UNI'=> '[varchar] (100)', - 'STEXT_UNI' => '[varchar] (255)', - 'TEXT_UNI' => '[varchar] (4000)', - 'MTEXT_UNI' => '[text]', - 'TIMESTAMP' => '[int]', - 'DECIMAL' => '[float]', - 'DECIMAL:' => '[float]', - 'PDECIMAL' => '[float]', - 'PDECIMAL:' => '[float]', - 'VCHAR_UNI' => '[varchar] (255)', - 'VCHAR_UNI:'=> '[varchar] (%d)', - 'VCHAR_CI' => '[varchar] (255)', - 'VARBINARY' => '[varchar] (255)', - ), - - 'mssqlnative' => array( - 'INT:' => '[int]', - 'BINT' => '[float]', - 'UINT' => '[int]', - 'UINT:' => '[int]', - 'TINT:' => '[int]', - 'USINT' => '[int]', - 'BOOL' => '[int]', - 'VCHAR' => '[varchar] (255)', - 'VCHAR:' => '[varchar] (%d)', - 'CHAR:' => '[char] (%d)', - 'XSTEXT' => '[varchar] (1000)', - 'STEXT' => '[varchar] (3000)', - 'TEXT' => '[varchar] (8000)', - 'MTEXT' => '[text]', - 'XSTEXT_UNI'=> '[varchar] (100)', - 'STEXT_UNI' => '[varchar] (255)', - 'TEXT_UNI' => '[varchar] (4000)', - 'MTEXT_UNI' => '[text]', - 'TIMESTAMP' => '[int]', - 'DECIMAL' => '[float]', - 'DECIMAL:' => '[float]', - 'PDECIMAL' => '[float]', - 'PDECIMAL:' => '[float]', - 'VCHAR_UNI' => '[varchar] (255)', - 'VCHAR_UNI:'=> '[varchar] (%d)', - 'VCHAR_CI' => '[varchar] (255)', - 'VARBINARY' => '[varchar] (255)', - ), - - 'oracle' => array( - 'INT:' => 'number(%d)', - 'BINT' => 'number(20)', - 'UINT' => 'number(8)', - 'UINT:' => 'number(%d)', - 'TINT:' => 'number(%d)', - 'USINT' => 'number(4)', - 'BOOL' => 'number(1)', - 'VCHAR' => 'varchar2(255)', - 'VCHAR:' => 'varchar2(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'varchar2(1000)', - 'STEXT' => 'varchar2(3000)', - 'TEXT' => 'clob', - 'MTEXT' => 'clob', - 'XSTEXT_UNI'=> 'varchar2(300)', - 'STEXT_UNI' => 'varchar2(765)', - 'TEXT_UNI' => 'clob', - 'MTEXT_UNI' => 'clob', - 'TIMESTAMP' => 'number(11)', - 'DECIMAL' => 'number(5, 2)', - 'DECIMAL:' => 'number(%d, 2)', - 'PDECIMAL' => 'number(6, 3)', - 'PDECIMAL:' => 'number(%d, 3)', - 'VCHAR_UNI' => 'varchar2(765)', - 'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')), - 'VCHAR_CI' => 'varchar2(255)', - 'VARBINARY' => 'raw(255)', - ), - - 'sqlite' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED', - 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED', - 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'text(65535)', - 'STEXT' => 'text(65535)', - 'TEXT' => 'text(65535)', - 'MTEXT' => 'mediumtext(16777215)', - 'XSTEXT_UNI'=> 'text(65535)', - 'STEXT_UNI' => 'text(65535)', - 'TEXT_UNI' => 'text(65535)', - 'MTEXT_UNI' => 'mediumtext(16777215)', - 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar(255)', - 'VARBINARY' => 'blob', - ), - - 'postgres' => array( - 'INT:' => 'INT4', - 'BINT' => 'INT8', - 'UINT' => 'INT4', // unsigned - 'UINT:' => 'INT4', // unsigned - 'USINT' => 'INT2', // unsigned - 'BOOL' => 'INT2', // unsigned - 'TINT:' => 'INT2', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'varchar(1000)', - 'STEXT' => 'varchar(3000)', - 'TEXT' => 'varchar(8000)', - 'MTEXT' => 'TEXT', - 'XSTEXT_UNI'=> 'varchar(100)', - 'STEXT_UNI' => 'varchar(255)', - 'TEXT_UNI' => 'varchar(4000)', - 'MTEXT_UNI' => 'TEXT', - 'TIMESTAMP' => 'INT4', // unsigned - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar_ci', - 'VARBINARY' => 'bytea', - ), - ); - - /** - * A list of types being unsigned for better reference in some db's - * @var array - */ - var $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); - - /** - * A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules. - * @var array - */ - var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite'); - - /** - * This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array). - * This mode has no effect on some methods (inserting of data for example). This is expressed within the methods command. - */ - var $return_statements = false; - - /** - * Constructor. Set DB Object and set {@link $return_statements return_statements}. - * - * @param phpbb_dbal $db DBAL object - * @param bool $return_statements True if only statements should be returned and no SQL being executed - */ - function updater_db_tools(&$db, $return_statements = false) - { - $this->db = $db; - $this->return_statements = $return_statements; - - // Determine mapping database type - switch ($this->db->sql_layer) - { - case 'mysql': - $this->sql_layer = 'mysql_40'; - break; - - case 'mysql4': - if (version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) - { - $this->sql_layer = 'mysql_41'; - } - else - { - $this->sql_layer = 'mysql_40'; - } - break; - - case 'mysqli': - $this->sql_layer = 'mysql_41'; - break; - - case 'mssql': - case 'mssql_odbc': - $this->sql_layer = 'mssql'; - break; - - case 'mssqlnative': - $this->sql_layer = 'mssqlnative'; - break; - - default: - $this->sql_layer = $this->db->sql_layer; - break; - } - } - - /** - * Handle passed database update array. - * Expected structure... - * Key being one of the following - * change_columns: Column changes (only type, not name) - * add_columns: Add columns to a table - * drop_keys: Dropping keys - * drop_columns: Removing/Dropping columns - * add_primary_keys: adding primary keys - * add_unique_index: adding an unique index - * add_index: adding an index (can be column:index_size if you need to provide size) - * - * The values are in this format: - * {TABLE NAME} => array( - * {COLUMN NAME} => array({COLUMN TYPE}, {DEFAULT VALUE}, {OPTIONAL VARIABLES}), - * {KEY/INDEX NAME} => array({COLUMN NAMES}), - * ) - * - * For more information have a look at /develop/create_schema_files.php (only available through SVN) - */ - function perform_schema_changes($schema_changes) - { - if (empty($schema_changes)) - { - return; - } - - $statements = array(); - $sqlite = false; - - // For SQLite we need to perform the schema changes in a much more different way - if ($this->db->sql_layer == 'sqlite' && $this->return_statements) - { - $sqlite_data = array(); - $sqlite = true; - } - - // Change columns? - if (!empty($schema_changes['change_columns'])) - { - foreach ($schema_changes['change_columns'] as $table => $columns) - { - foreach ($columns as $column_name => $column_data) - { - // If the column exists we change it, else we add it ;) - if ($column_exists = $this->sql_column_exists($table, $column_name)) - { - $result = $this->sql_column_change($table, $column_name, $column_data, true); - } - else - { - $result = $this->sql_column_add($table, $column_name, $column_data, true); - } - - if ($sqlite) - { - if ($column_exists) - { - $sqlite_data[$table]['change_columns'][] = $result; - } - else - { - $sqlite_data[$table]['add_columns'][] = $result; - } - } - else if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - // Add columns? - if (!empty($schema_changes['add_columns'])) - { - foreach ($schema_changes['add_columns'] as $table => $columns) - { - foreach ($columns as $column_name => $column_data) - { - // Only add the column if it does not exist yet - if ($column_exists = $this->sql_column_exists($table, $column_name)) - { - continue; - // This is commented out here because it can take tremendous time on updates -// $result = $this->sql_column_change($table, $column_name, $column_data, true); - } - else - { - $result = $this->sql_column_add($table, $column_name, $column_data, true); - } - - if ($sqlite) - { - if ($column_exists) - { - continue; -// $sqlite_data[$table]['change_columns'][] = $result; - } - else - { - $sqlite_data[$table]['add_columns'][] = $result; - } - } - else if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - // Remove keys? - if (!empty($schema_changes['drop_keys'])) - { - foreach ($schema_changes['drop_keys'] as $table => $indexes) - { - foreach ($indexes as $index_name) - { - if (!$this->sql_index_exists($table, $index_name)) - { - continue; - } - - $result = $this->sql_index_drop($table, $index_name); - - if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - // Drop columns? - if (!empty($schema_changes['drop_columns'])) - { - foreach ($schema_changes['drop_columns'] as $table => $columns) - { - foreach ($columns as $column) - { - // Only remove the column if it exists... - if ($this->sql_column_exists($table, $column)) - { - $result = $this->sql_column_remove($table, $column, true); - - if ($sqlite) - { - $sqlite_data[$table]['drop_columns'][] = $result; - } - else if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - } - - // Add primary keys? - if (!empty($schema_changes['add_primary_keys'])) - { - foreach ($schema_changes['add_primary_keys'] as $table => $columns) - { - $result = $this->sql_create_primary_key($table, $columns, true); - - if ($sqlite) - { - $sqlite_data[$table]['primary_key'] = $result; - } - else if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - - // Add unqiue indexes? - if (!empty($schema_changes['add_unique_index'])) - { - foreach ($schema_changes['add_unique_index'] as $table => $index_array) - { - foreach ($index_array as $index_name => $column) - { - if ($this->sql_unique_index_exists($table, $index_name)) - { - continue; - } - - $result = $this->sql_create_unique_index($table, $index_name, $column); - - if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - // Add indexes? - if (!empty($schema_changes['add_index'])) - { - foreach ($schema_changes['add_index'] as $table => $index_array) - { - foreach ($index_array as $index_name => $column) - { - if ($this->sql_index_exists($table, $index_name)) - { - continue; - } - - $result = $this->sql_create_index($table, $index_name, $column); - - if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } - } - } - } - - if ($sqlite) - { - foreach ($sqlite_data as $table_name => $sql_schema_changes) - { - // Create temporary table with original data - $statements[] = 'begin'; - - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - continue; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - // Get the columns... - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $plain_table_cols = trim($matches[1]); - $new_table_cols = preg_split('/,(?![\s\w]+\))/m', $plain_table_cols); - $column_list = array(); - - foreach ($new_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - $column_list[] = $entities[0]; - } - - // note down the primary key notation because sqlite only supports adding it to the end for the new table - $primary_key = false; - $_new_cols = array(); - - foreach ($new_table_cols as $key => $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - $primary_key = $declaration; - continue; - } - $_new_cols[] = $declaration; - } - - $new_table_cols = $_new_cols; - - // First of all... change columns - if (!empty($sql_schema_changes['change_columns'])) - { - foreach ($sql_schema_changes['change_columns'] as $column_sql) - { - foreach ($new_table_cols as $key => $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if (strpos($column_sql, $entities[0] . ' ') === 0) - { - $new_table_cols[$key] = $column_sql; - } - } - } - } - - if (!empty($sql_schema_changes['add_columns'])) - { - foreach ($sql_schema_changes['add_columns'] as $column_sql) - { - $new_table_cols[] = $column_sql; - } - } - - // Now drop them... - if (!empty($sql_schema_changes['drop_columns'])) - { - foreach ($sql_schema_changes['drop_columns'] as $column_name) - { - // Remove from column list... - $new_column_list = array(); - foreach ($column_list as $key => $value) - { - if ($value === $column_name) - { - continue; - } - - $new_column_list[] = $value; - } - - $column_list = $new_column_list; - - // Remove from table... - $_new_cols = array(); - foreach ($new_table_cols as $key => $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if (strpos($column_name . ' ', $entities[0] . ' ') === 0) - { - continue; - } - $_new_cols[] = $declaration; - } - $new_table_cols = $_new_cols; - } - } - - // Primary key... - if (!empty($sql_schema_changes['primary_key'])) - { - $new_table_cols[] = 'PRIMARY KEY (' . implode(', ', $sql_schema_changes['primary_key']) . ')'; - } - // Add a new one or the old primary key - else if ($primary_key !== false) - { - $new_table_cols[] = $primary_key; - } - - $columns = implode(',', $column_list); - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $new_table_cols) . ');'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - } - } - - if ($this->return_statements) - { - return $statements; - } - } - - /** - * Check if a specified column exist - * - * @param string $table Table to check the column at - * @param string $column_name The column to check - * - * @return bool True if column exists, else false - */ - function sql_column_exists($table, $column_name) - { - switch ($this->sql_layer) - { - case 'mysql_40': - case 'mysql_41': - - $sql = "SHOW COLUMNS FROM $table"; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - // lower case just in case - if (strtolower($row['Field']) == $column_name) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - return false; - break; - - // PostgreSQL has a way of doing this in a much simpler way but would - // not allow us to support all versions of PostgreSQL - case 'postgres': - $sql = "SELECT a.attname - FROM pg_class c, pg_attribute a - WHERE c.relname = '{$table}' - AND a.attnum > 0 - AND a.attrelid = c.oid"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // lower case just in case - if (strtolower($row['attname']) == $column_name) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - - return false; - break; - - // same deal with PostgreSQL, we must perform more complex operations than - // we technically could - case 'mssql': - case 'mssqlnative': - $sql = "SELECT c.name - FROM syscolumns c - LEFT JOIN sysobjects o ON c.id = o.id - WHERE o.name = '{$table}'"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // lower case just in case - if (strtolower($row['name']) == $column_name) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - return false; - break; - - case 'oracle': - $sql = "SELECT column_name - FROM user_tab_columns - WHERE LOWER(table_name) = '" . strtolower($table) . "'"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // lower case just in case - if (strtolower($row['column_name']) == $column_name) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - return false; - break; - - case 'firebird': - $sql = "SELECT RDB\$FIELD_NAME as FNAME - FROM RDB\$RELATION_FIELDS - WHERE RDB\$RELATION_NAME = '" . strtoupper($table) . "'"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // lower case just in case - if (strtolower($row['fname']) == $column_name) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - return false; - break; - - // ugh, SQLite - case 'sqlite': - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table}'"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - return false; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $cols = trim($matches[1]); - $col_array = preg_split('/,(?![\s\w]+\))/m', $cols); - - foreach ($col_array as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - - if (strtolower($entities[0]) == $column_name) - { - return true; - } - } - return false; - break; - } - } - - /** - * Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes. - * - * @param string $table_name Table to check the index at - * @param string $index_name The index name to check - * - * @return bool True if index exists, else false - */ - function sql_index_exists($table_name, $index_name) - { - if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') - { - $sql = "EXEC sp_statistics '$table_name'"; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - if ($row['TYPE'] == 3) - { - if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) - { - $this->db->sql_freeresult($result); - return true; - } - } - } - $this->db->sql_freeresult($result); - - return false; - } - - switch ($this->sql_layer) - { - case 'firebird': - $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name - FROM RDB\$INDICES - WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "' - AND RDB\$UNIQUE_FLAG IS NULL - AND RDB\$FOREIGN_KEY IS NULL"; - $col = 'index_name'; - break; - - case 'postgres': - $sql = "SELECT ic.relname as index_name - FROM pg_class bc, pg_class ic, pg_index i - WHERE (bc.oid = i.indrelid) - AND (ic.oid = i.indexrelid) - AND (bc.relname = '" . $table_name . "') - AND (i.indisunique != 't') - AND (i.indisprimary != 't')"; - $col = 'index_name'; - break; - - case 'mysql_40': - case 'mysql_41': - $sql = 'SHOW KEYS - FROM ' . $table_name; - $col = 'Key_name'; - break; - - case 'oracle': - $sql = "SELECT index_name - FROM user_indexes - WHERE table_name = '" . strtoupper($table_name) . "' - AND generated = 'N' - AND uniqueness = 'NONUNIQUE'"; - $col = 'index_name'; - break; - - case 'sqlite': - $sql = "PRAGMA index_list('" . $table_name . "');"; - $col = 'name'; - break; - } - - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) - { - continue; - } - - // These DBMS prefix index name with the table name - switch ($this->sql_layer) - { - case 'firebird': - case 'oracle': - case 'postgres': - case 'sqlite': - $row[$col] = substr($row[$col], strlen($table_name) + 1); - break; - } - - if (strtolower($row[$col]) == strtolower($index_name)) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - - return false; - } - - /** - * Check if a specified UNIQUE index exists in table. - * - * @param string $table_name Table to check the index at - * @param string $index_name The index name to check - * - * @return bool True if index exists, else false - */ - function sql_unique_index_exists($table_name, $index_name) - { - if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') - { - $sql = "EXEC sp_statistics '$table_name'"; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - // Usually NON_UNIQUE is the column we want to check, but we allow for both - if ($row['TYPE'] == 3) - { - if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) - { - $this->db->sql_freeresult($result); - return true; - } - } - } - $this->db->sql_freeresult($result); - return false; - } - - switch ($this->sql_layer) - { - case 'firebird': - $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name - FROM RDB\$INDICES - WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "' - AND RDB\$UNIQUE_FLAG IS NOT NULL - AND RDB\$FOREIGN_KEY IS NULL"; - $col = 'index_name'; - break; - - case 'postgres': - $sql = "SELECT ic.relname as index_name, i.indisunique - FROM pg_class bc, pg_class ic, pg_index i - WHERE (bc.oid = i.indrelid) - AND (ic.oid = i.indexrelid) - AND (bc.relname = '" . $table_name . "') - AND (i.indisprimary != 't')"; - $col = 'index_name'; - break; - - case 'mysql_40': - case 'mysql_41': - $sql = 'SHOW KEYS - FROM ' . $table_name; - $col = 'Key_name'; - break; - - case 'oracle': - $sql = "SELECT index_name, table_owner - FROM user_indexes - WHERE table_name = '" . strtoupper($table_name) . "' - AND generated = 'N' - AND uniqueness = 'UNIQUE'"; - $col = 'index_name'; - break; - - case 'sqlite': - $sql = "PRAGMA index_list('" . $table_name . "');"; - $col = 'name'; - break; - } - - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && ($row['Non_unique'] || $row[$col] == 'PRIMARY')) - { - continue; - } - - if ($this->sql_layer == 'sqlite' && !$row['unique']) - { - continue; - } - - if ($this->sql_layer == 'postgres' && $row['indisunique'] != 't') - { - continue; - } - - // These DBMS prefix index name with the table name - switch ($this->sql_layer) - { - case 'oracle': - // Two cases here... prefixed with U_[table_owner] and not prefixed with table_name - if (strpos($row[$col], 'U_') === 0) - { - $row[$col] = substr($row[$col], strlen('U_' . $row['table_owner']) + 1); - } - else if (strpos($row[$col], strtoupper($table_name)) === 0) - { - $row[$col] = substr($row[$col], strlen($table_name) + 1); - } - break; - - case 'firebird': - case 'postgres': - case 'sqlite': - $row[$col] = substr($row[$col], strlen($table_name) + 1); - break; - } - - if (strtolower($row[$col]) == strtolower($index_name)) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - - return false; - } - - /** - * Private method for performing sql statements (either execute them or return them) - * @access private - */ - function _sql_run_sql($statements) - { - if ($this->return_statements) - { - return $statements; - } - - // We could add error handling here... - foreach ($statements as $sql) - { - if ($sql === 'begin') - { - $this->db->sql_transaction('begin'); - } - else if ($sql === 'commit') - { - $this->db->sql_transaction('commit'); - } - else - { - $this->db->sql_query($sql); - } - } - - return true; - } - - /** - * Function to prepare some column information for better usage - * @access private - */ - function sql_prepare_column_data($table_name, $column_name, $column_data) - { - // Get type - if (strpos($column_data[0], ':') !== false) - { - list($orig_column_type, $column_length) = explode(':', $column_data[0]); - if (!is_array($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'])) - { - $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'], $column_length); - } - else - { - if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'])) - { - switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][0]) - { - case 'div': - $column_length /= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][1]; - $column_length = ceil($column_length); - $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); - break; - } - } - - if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'])) - { - switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][0]) - { - case 'mult': - $column_length *= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][1]; - if ($column_length > $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][2]) - { - $column_type = $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][3]; - } - else - { - $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); - } - break; - } - } - } - $orig_column_type .= ':'; - } - else - { - $orig_column_type = $column_data[0]; - $column_type = $this->dbms_type_map[$this->sql_layer][$column_data[0]]; - } - - // Adjust default value if db-dependant specified - if (is_array($column_data[1])) - { - $column_data[1] = (isset($column_data[1][$this->sql_layer])) ? $column_data[1][$this->sql_layer] : $column_data[1]['default']; - } - - $sql = ''; - - $return_array = array(); - - switch ($this->sql_layer) - { - case 'firebird': - $sql .= " {$column_type} "; - $return_array['column_type_sql_type'] = " {$column_type} "; - - if (!is_null($column_data[1])) - { - $sql .= 'DEFAULT ' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' '; - $return_array['column_type_sql_default'] = ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' '; - } - - $sql .= 'NOT NULL'; - - // This is a UNICODE column and thus should be given it's fair share - if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0])) - { - $sql .= ' COLLATE UNICODE'; - } - - $return_array['auto_increment'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $return_array['auto_increment'] = true; - } - - break; - - case 'mssql': - case 'mssqlnative': - $sql .= " {$column_type} "; - $sql_default = " {$column_type} "; - - // For adding columns we need the default definition - if (!is_null($column_data[1])) - { - // For hexadecimal values do not use single quotes - if (strpos($column_data[1], '0x') === 0) - { - $return_array['default'] = 'DEFAULT (' . $column_data[1] . ') '; - $sql_default .= $return_array['default']; - } - else - { - $return_array['default'] = 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; - $sql_default .= $return_array['default']; - } - } - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { -// $sql .= 'IDENTITY (1, 1) '; - $sql_default .= 'IDENTITY (1, 1) '; - } - - $return_array['textimage'] = $column_type === '[text]'; - - $sql .= 'NOT NULL'; - $sql_default .= 'NOT NULL'; - - $return_array['column_type_sql_default'] = $sql_default; - - break; - - case 'mysql_40': - case 'mysql_41': - $sql .= " {$column_type} "; - - // For hexadecimal values do not use single quotes - if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob') - { - $sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' "; - } - $sql .= 'NOT NULL'; - - if (isset($column_data[2])) - { - if ($column_data[2] == 'auto_increment') - { - $sql .= ' auto_increment'; - } - else if ($this->sql_layer === 'mysql_41' && $column_data[2] == 'true_sort') - { - $sql .= ' COLLATE utf8_unicode_ci'; - } - } - - break; - - case 'oracle': - $sql .= " {$column_type} "; - $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : ''; - - // In Oracle empty strings ('') are treated as NULL. - // Therefore in oracle we allow NULL's for all DEFAULT '' entries - // Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields) - if (!preg_match('/number/i', $column_type)) - { - $sql .= ($column_data[1] === '') ? '' : 'NOT NULL'; - } - - $return_array['auto_increment'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $return_array['auto_increment'] = true; - } - - break; - - case 'postgres': - $return_array['column_type'] = $column_type; - - $sql .= " {$column_type} "; - - $return_array['auto_increment'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $default_val = "nextval('{$table_name}_seq')"; - $return_array['auto_increment'] = true; - } - else if (!is_null($column_data[1])) - { - $default_val = "'" . $column_data[1] . "'"; - $return_array['null'] = 'NOT NULL'; - $sql .= 'NOT NULL '; - } - - $return_array['default'] = $default_val; - - $sql .= "DEFAULT {$default_val}"; - - // Unsigned? Then add a CHECK contraint - if (in_array($orig_column_type, $this->unsigned_types)) - { - $return_array['constraint'] = "CHECK ({$column_name} >= 0)"; - $sql .= " CHECK ({$column_name} >= 0)"; - } - - break; - - case 'sqlite': - $return_array['primary_key_set'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $sql .= ' INTEGER PRIMARY KEY'; - $return_array['primary_key_set'] = true; - } - else - { - $sql .= ' ' . $column_type; - } - - $sql .= ' NOT NULL '; - $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : ''; - - break; - } - - $return_array['column_type_sql'] = $sql; - - return $return_array; - } - - /** - * Add new column - */ - function sql_column_add($table_name, $column_name, $column_data, $inline = false) - { - $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); - $statements = array(); - - switch ($this->sql_layer) - { - case 'firebird': - // Does not support AFTER statement, only POSITION (and there you need the column position) - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD "' . strtoupper($column_name) . '" ' . $column_data['column_type_sql']; - break; - - case 'mssql': - case 'mssqlnative': - // Does not support AFTER, only through temporary table - $statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default']; - break; - - case 'mysql_40': - case 'mysql_41': - $after = (!empty($column_data['after'])) ? ' AFTER ' . $column_data['after'] : ''; - $statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql'] . $after; - break; - - case 'oracle': - // Does not support AFTER, only through temporary table - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; - break; - - case 'postgres': - // Does not support AFTER, only through temporary table - - if (version_compare($this->db->sql_server_info(true), '8.0', '>=')) - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; - } - else - { - // old versions cannot add columns with default and null information - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type'] . ' ' . $column_data['constraint']; - - if (isset($column_data['null'])) - { - if ($column_data['null'] == 'NOT NULL') - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET NOT NULL'; - } - } - - if (isset($column_data['default'])) - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; - } - } - break; - - case 'sqlite': - - if ($inline && $this->return_statements) - { - return $column_name . ' ' . $column_data['column_type_sql']; - } - - if (version_compare(sqlite_libversion(), '3.0') == -1) - { - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - break; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $statements[] = 'begin'; - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - $column_list[] = $entities[0]; - } - - $columns = implode(',', $column_list); - - $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols; - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - } - else - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']'; - } - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * Drop column - */ - function sql_column_remove($table_name, $column_name, $inline = false) - { - $statements = array(); - - switch ($this->sql_layer) - { - case 'firebird': - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP "' . strtoupper($column_name) . '"'; - break; - - case 'mssql': - case 'mssqlnative': - $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']'; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`'; - break; - - case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP ' . $column_name; - break; - - case 'postgres': - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"'; - break; - - case 'sqlite': - - if ($inline && $this->return_statements) - { - return $column_name; - } - - if (version_compare(sqlite_libversion(), '3.0') == -1) - { - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - break; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $statements[] = 'begin'; - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name) - { - continue; - } - $column_list[] = $entities[0]; - } - - $columns = implode(',', $column_list); - - $new_table_cols = $new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols); - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - } - else - { - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name; - } - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * Drop Index - */ - function sql_index_drop($table_name, $index_name) - { - $statements = array(); - - switch ($this->sql_layer) - { - case 'mssql': - case 'mssqlnative': - $statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name; - break; - - case 'firebird': - case 'oracle': - case 'postgres': - case 'sqlite': - $statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * Add primary key - */ - function sql_create_primary_key($table_name, $column, $inline = false) - { - $statements = array(); - - switch ($this->sql_layer) - { - case 'firebird': - case 'postgres': - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; - break; - - case 'mssql': - case 'mssqlnative': - $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD "; - $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED ("; - $sql .= '[' . implode("],\n\t\t[", $column) . ']'; - $sql .= ') ON [PRIMARY]'; - - $statements[] = $sql; - break; - - case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; - break; - - case 'sqlite': - - if ($inline && $this->return_statements) - { - return $column; - } - - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - break; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $statements[] = 'begin'; - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - $column_list[] = $entities[0]; - } - - $columns = implode(',', $column_list); - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * Add unique index - */ - function sql_create_unique_index($table_name, $index_name, $column) - { - $statements = array(); - - switch ($this->sql_layer) - { - case 'firebird': - case 'postgres': - case 'oracle': - case 'sqlite': - $statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mssql': - case 'mssqlnative': - $statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]'; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * Add index - */ - function sql_create_index($table_name, $index_name, $column) - { - $statements = array(); - - // remove index length unless MySQL4 - if ('mysql_40' != $this->sql_layer) - { - $column = preg_replace('#:.*$#', '', $column); - } - - switch ($this->sql_layer) - { - case 'firebird': - case 'postgres': - case 'oracle': - case 'sqlite': - $statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mysql_40': - // add index size to definition as required by MySQL4 - foreach ($column as $i => $col) - { - if (false !== strpos($col, ':')) - { - list($col, $index_size) = explode(':', $col); - $column[$i] = "$col($index_size)"; - } - } - // no break - case 'mysql_41': - $statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mssql': - case 'mssqlnative': - $statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]'; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * Change column type (not name!) - */ - function sql_column_change($table_name, $column_name, $column_data, $inline = false) - { - $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); - $statements = array(); - - switch ($this->sql_layer) - { - case 'firebird': - // Change type... - if (!empty($column_data['column_type_sql_default'])) - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql_type']; - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" SET DEFAULT ' . ' ' . $column_data['column_type_sql_default']; - } - else - { - // TODO: try to change pkey without removing trigger, generator or constraints. ATM this query may fail. - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql_type']; - } - break; - - case 'mssql': - case 'mssqlnative': - $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; - - if (!empty($column_data['default'])) - { - // Using TRANSACT-SQL for this statement because we do not want to have colliding data if statements are executed at a later stage - $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) - SET @drop_default_name = - (SELECT so.name FROM sysobjects so - JOIN sysconstraints sc ON so.id = sc.constid - WHERE object_name(so.parent_obj) = '{$table_name}' - AND so.xtype = 'D' - AND sc.colid = (SELECT colid FROM syscolumns - WHERE id = object_id('{$table_name}') - AND name = '{$column_name}')) - IF @drop_default_name <> '' - BEGIN - SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' - EXEC(@cmd) - END - SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]' - EXEC(@cmd)"; - } - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql']; - break; - - case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql']; - break; - - case 'postgres': - $sql = 'ALTER TABLE ' . $table_name . ' '; - - $sql_array = array(); - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type']; - - if (isset($column_data['null'])) - { - if ($column_data['null'] == 'NOT NULL') - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL'; - } - else if ($column_data['null'] == 'NULL') - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL'; - } - } - - if (isset($column_data['default'])) - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; - } - - // we don't want to double up on constraints if we change different number data types - if (isset($column_data['constraint'])) - { - $constraint_sql = "SELECT consrc as constraint_data - FROM pg_constraint, pg_class bc - WHERE conrelid = bc.oid - AND bc.relname = '{$table_name}' - AND NOT EXISTS ( - SELECT * - FROM pg_constraint as c, pg_inherits as i - WHERE i.inhrelid = pg_constraint.conrelid - AND c.conname = pg_constraint.conname - AND c.consrc = pg_constraint.consrc - AND c.conrelid = i.inhparent - )"; - - $constraint_exists = false; - - $result = $this->db->sql_query($constraint_sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if (trim($row['constraint_data']) == trim($column_data['constraint'])) - { - $constraint_exists = true; - break; - } - } - $this->db->sql_freeresult($result); - - if (!$constraint_exists) - { - $sql_array[] = 'ADD ' . $column_data['constraint']; - } - } - - $sql .= implode(', ', $sql_array); - - $statements[] = $sql; - break; - - case 'sqlite': - - if ($inline && $this->return_statements) - { - return $column_name . ' ' . $column_data['column_type_sql']; - } - - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - break; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $statements[] = 'begin'; - - // Create a temp table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $key => $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - $column_list[] = $entities[0]; - if ($entities[0] == $column_name) - { - $old_table_cols[$key] = $column_name . ' ' . $column_data['column_type_sql']; - } - } - - $columns = implode(',', $column_list); - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - - break; - } - - return $this->_sql_run_sql($statements); - } -} diff --git a/phpBB/install/index.php b/phpBB/install/index.php index 0d1f2e1312..e3f9bda372 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -18,111 +18,30 @@ define('IN_INSTALL', true); $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; $phpEx = substr(strrchr(__FILE__, '.'), 1); -// Report all errors, except notices and deprecation messages -if (!defined('E_DEPRECATED')) +if (version_compare(PHP_VERSION, '5.2.0') < 0) { - define('E_DEPRECATED', 8192); + die('You are running an unsupported PHP version. Please upgrade to PHP 5.2.0 or higher before trying to install phpBB 3.1'); } -error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED); -// @todo Review this test and see if we can find out what it is which prevents PHP 4.2.x from even displaying the page with requirements on it -if (version_compare(PHP_VERSION, '4.3.3') < 0) +function phpbb_require_updated($path, $optional = false) { - die('You are running an unsupported PHP version. Please upgrade to PHP 4.3.3 or higher before trying to install phpBB 3.0'); -} + global $phpbb_root_path; -/* -* Remove variables created by register_globals from the global scope -* Thanks to Matt Kavanagh -*/ -function deregister_globals() -{ - $not_unset = array( - 'GLOBALS' => true, - '_GET' => true, - '_POST' => true, - '_COOKIE' => true, - '_REQUEST' => true, - '_SERVER' => true, - '_SESSION' => true, - '_ENV' => true, - '_FILES' => true, - 'phpEx' => true, - 'phpbb_root_path' => true - ); - - // Not only will array_merge and array_keys give a warning if - // a parameter is not an array, array_merge will actually fail. - // So we check if _SESSION has been initialised. - if (!isset($_SESSION) || !is_array($_SESSION)) - { - $_SESSION = array(); - } + $new_path = $phpbb_root_path . 'install/update/new/' . $path; + $old_path = $phpbb_root_path . $path; - // Merge all into one extremely huge array; unset this later - $input = array_merge( - array_keys($_GET), - array_keys($_POST), - array_keys($_COOKIE), - array_keys($_SERVER), - array_keys($_SESSION), - array_keys($_ENV), - array_keys($_FILES) - ); - - foreach ($input as $varname) + if (file_exists($new_path)) { - if (isset($not_unset[$varname])) - { - // Hacking attempt. No point in continuing unless it's a COOKIE - if ($varname !== 'GLOBALS' || isset($_GET['GLOBALS']) || isset($_POST['GLOBALS']) || isset($_SERVER['GLOBALS']) || isset($_SESSION['GLOBALS']) || isset($_ENV['GLOBALS']) || isset($_FILES['GLOBALS'])) - { - exit; - } - else - { - $cookie = &$_COOKIE; - while (isset($cookie['GLOBALS'])) - { - foreach ($cookie['GLOBALS'] as $registered_var => $value) - { - if (!isset($not_unset[$registered_var])) - { - unset($GLOBALS[$registered_var]); - } - } - $cookie = &$cookie['GLOBALS']; - } - } - } - - unset($GLOBALS[$varname]); + require($new_path); } - - unset($input); -} - -// If we are on PHP >= 6.0.0 we do not need some code -if (version_compare(PHP_VERSION, '6.0.0-dev', '>=')) -{ - /** - * @ignore - */ - define('STRIP', false); -} -else -{ - @set_magic_quotes_runtime(0); - - // Be paranoid with passed vars - if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on') + else if (!$optional || file_exists($old_path)) { - deregister_globals(); + require($old_path); } - - define('STRIP', (get_magic_quotes_gpc()) ? true : false); } +phpbb_require_updated('includes/startup.' . $phpEx); + // Try to override some limits - maybe it helps some... @set_time_limit(0); $mem_limit = @ini_get('memory_limit'); @@ -155,10 +74,7 @@ else require($phpbb_root_path . 'includes/class_loader.' . $phpEx); require($phpbb_root_path . 'includes/functions.' . $phpEx); -if (file_exists($phpbb_root_path . 'includes/functions_content.' . $phpEx)) -{ - require($phpbb_root_path . 'includes/functions_content.' . $phpEx); -} +phpbb_require_updated('includes/functions_content.' . $phpEx, true); include($phpbb_root_path . 'includes/auth.' . $phpEx); include($phpbb_root_path . 'includes/session.' . $phpEx); @@ -637,10 +553,10 @@ class module return; } - echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'; - echo '<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">'; + echo '<!DOCTYPE html>'; + echo '<html dir="ltr">'; echo '<head>'; - echo '<meta http-equiv="content-type" content="text/html; charset=utf-8" />'; + echo '<meta charset="utf-8">'; echo '<title>' . $lang['INST_ERR_FATAL'] . '</title>'; echo '<link href="../adm/style/admin.css" rel="stylesheet" type="text/css" media="screen" />'; echo '</head>'; @@ -663,7 +579,7 @@ class module echo ' </div>'; echo ' </div>'; echo ' <div id="page-footer">'; - echo ' Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group'; + echo ' Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group'; echo ' </div>'; echo '</div>'; echo '</body>'; diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index e18ed43778..e36fc1c618 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -141,7 +141,7 @@ class install_install extends module // Test the minimum PHP version $php_version = PHP_VERSION; - if (version_compare($php_version, '4.3.3') < 0) + if (version_compare($php_version, '5.2.0') < 0) { $result = '<strong style="color:red">' . $lang['NO'] . '</strong>'; } diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index e16b4ab64c..b19ece2b7c 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -1,5 +1,5 @@ # -# $Id$ +# $Id: $ # @@ -547,6 +547,22 @@ BEGIN END;; +# Table: 'phpbb_login_attempts' +CREATE TABLE phpbb_login_attempts ( + attempt_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, + attempt_browser VARCHAR(150) CHARACTER SET NONE DEFAULT '' NOT NULL, + attempt_forwarded_for VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + attempt_time INTEGER DEFAULT 0 NOT NULL, + user_id INTEGER DEFAULT 0 NOT NULL, + username VARCHAR(255) CHARACTER SET UTF8 DEFAULT 0 NOT NULL COLLATE UNICODE, + username_clean VARCHAR(255) CHARACTER SET UTF8 DEFAULT 0 NOT NULL COLLATE UNICODE +);; + +CREATE INDEX phpbb_login_attempts_att_ip ON phpbb_login_attempts(attempt_ip, attempt_time);; +CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts(attempt_forwarded_for, attempt_time);; +CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts(attempt_time);; +CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts(user_id);; + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id INTEGER DEFAULT 0 NOT NULL, @@ -793,6 +809,7 @@ CREATE TABLE phpbb_profile_fields ( field_validation VARCHAR(20) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, field_required INTEGER DEFAULT 0 NOT NULL, field_show_on_reg INTEGER DEFAULT 0 NOT NULL, + field_show_on_pm INTEGER DEFAULT 0 NOT NULL, field_show_on_vt INTEGER DEFAULT 0 NOT NULL, field_show_profile INTEGER DEFAULT 0 NOT NULL, field_hide INTEGER DEFAULT 0 NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index a14e246c8f..f823667252 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -1,6 +1,6 @@ /* - $Id$ + $Id: $ */ @@ -654,6 +654,33 @@ GO /* + Table: 'phpbb_login_attempts' +*/ +CREATE TABLE [phpbb_login_attempts] ( + [attempt_ip] [varchar] (40) DEFAULT ('') NOT NULL , + [attempt_browser] [varchar] (150) DEFAULT ('') NOT NULL , + [attempt_forwarded_for] [varchar] (255) DEFAULT ('') NOT NULL , + [attempt_time] [int] DEFAULT (0) NOT NULL , + [user_id] [int] DEFAULT (0) NOT NULL , + [username] [varchar] (255) DEFAULT (0) NOT NULL , + [username_clean] [varchar] (255) DEFAULT (0) NOT NULL +) ON [PRIMARY] +GO + +CREATE INDEX [att_ip] ON [phpbb_login_attempts]([attempt_ip], [attempt_time]) ON [PRIMARY] +GO + +CREATE INDEX [att_for] ON [phpbb_login_attempts]([attempt_forwarded_for], [attempt_time]) ON [PRIMARY] +GO + +CREATE INDEX [att_time] ON [phpbb_login_attempts]([attempt_time]) ON [PRIMARY] +GO + +CREATE INDEX [user_id] ON [phpbb_login_attempts]([user_id]) ON [PRIMARY] +GO + + +/* Table: 'phpbb_moderator_cache' */ CREATE TABLE [phpbb_moderator_cache] ( @@ -950,6 +977,7 @@ CREATE TABLE [phpbb_profile_fields] ( [field_validation] [varchar] (20) DEFAULT ('') NOT NULL , [field_required] [int] DEFAULT (0) NOT NULL , [field_show_on_reg] [int] DEFAULT (0) NOT NULL , + [field_show_on_pm] [int] DEFAULT (0) NOT NULL , [field_show_on_vt] [int] DEFAULT (0) NOT NULL , [field_show_profile] [int] DEFAULT (0) NOT NULL , [field_hide] [int] DEFAULT (0) NOT NULL , @@ -1734,3 +1762,4 @@ ALTER TABLE [phpbb_zebra] WITH NOCHECK ADD ) ON [PRIMARY] GO + diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 3b79afa942..8b603f9572 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -1,5 +1,5 @@ # -# $Id$ +# $Id: $ # # Table: 'phpbb_attachments' @@ -371,6 +371,22 @@ CREATE TABLE phpbb_log ( ); +# Table: 'phpbb_login_attempts' +CREATE TABLE phpbb_login_attempts ( + attempt_ip varbinary(40) DEFAULT '' NOT NULL, + attempt_browser varbinary(150) DEFAULT '' NOT NULL, + attempt_forwarded_for varbinary(255) DEFAULT '' NOT NULL, + attempt_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + username blob NOT NULL, + username_clean blob NOT NULL, + KEY att_ip (attempt_ip, attempt_time), + KEY att_for (attempt_forwarded_for, attempt_time), + KEY att_time (attempt_time), + KEY user_id (user_id) +); + + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, @@ -557,6 +573,7 @@ CREATE TABLE phpbb_profile_fields ( field_validation varbinary(60) DEFAULT '' NOT NULL, field_required tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, field_show_on_reg tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + field_show_on_pm tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, field_show_on_vt tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, field_show_profile tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, field_hide tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index a4b34c05db..f418e1d2a5 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -1,5 +1,5 @@ # -# $Id$ +# $Id: $ # # Table: 'phpbb_attachments' @@ -371,6 +371,22 @@ CREATE TABLE phpbb_log ( ) CHARACTER SET `utf8` COLLATE `utf8_bin`; +# Table: 'phpbb_login_attempts' +CREATE TABLE phpbb_login_attempts ( + attempt_ip varchar(40) DEFAULT '' NOT NULL, + attempt_browser varchar(150) DEFAULT '' NOT NULL, + attempt_forwarded_for varchar(255) DEFAULT '' NOT NULL, + attempt_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + username varchar(255) DEFAULT '0' NOT NULL, + username_clean varchar(255) DEFAULT '0' NOT NULL, + KEY att_ip (attempt_ip, attempt_time), + KEY att_for (attempt_forwarded_for, attempt_time), + KEY att_time (attempt_time), + KEY user_id (user_id) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, @@ -557,6 +573,7 @@ CREATE TABLE phpbb_profile_fields ( field_validation varchar(20) DEFAULT '' NOT NULL, field_required tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, field_show_on_reg tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + field_show_on_pm tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, field_show_on_vt tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, field_show_profile tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, field_hide tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 9b516b4a56..fcd7f9e5d0 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -1,6 +1,6 @@ /* - $Id$ + $Id: $ */ @@ -744,6 +744,29 @@ END; /* + Table: 'phpbb_login_attempts' +*/ +CREATE TABLE phpbb_login_attempts ( + attempt_ip varchar2(40) DEFAULT '' , + attempt_browser varchar2(150) DEFAULT '' , + attempt_forwarded_for varchar2(255) DEFAULT '' , + attempt_time number(11) DEFAULT '0' NOT NULL, + user_id number(8) DEFAULT '0' NOT NULL, + username varchar2(765) DEFAULT '0' NOT NULL, + username_clean varchar2(255) DEFAULT '0' NOT NULL +) +/ + +CREATE INDEX phpbb_login_attempts_att_ip ON phpbb_login_attempts (attempt_ip, attempt_time) +/ +CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwarded_for, attempt_time) +/ +CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time) +/ +CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id) +/ + +/* Table: 'phpbb_moderator_cache' */ CREATE TABLE phpbb_moderator_cache ( @@ -1064,6 +1087,7 @@ CREATE TABLE phpbb_profile_fields ( field_validation varchar2(60) DEFAULT '' , field_required number(1) DEFAULT '0' NOT NULL, field_show_on_reg number(1) DEFAULT '0' NOT NULL, + field_show_on_pm number(1) DEFAULT '0' NOT NULL, field_show_on_vt number(1) DEFAULT '0' NOT NULL, field_show_profile number(1) DEFAULT '0' NOT NULL, field_hide number(1) DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index 1b9c1a75aa..1aa47b4d61 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -1,6 +1,6 @@ /* - $Id$ + $Id: $ */ @@ -527,6 +527,24 @@ CREATE INDEX phpbb_log_reportee_id ON phpbb_log (reportee_id); CREATE INDEX phpbb_log_user_id ON phpbb_log (user_id); /* + Table: 'phpbb_login_attempts' +*/ +CREATE TABLE phpbb_login_attempts ( + attempt_ip varchar(40) DEFAULT '' NOT NULL, + attempt_browser varchar(150) DEFAULT '' NOT NULL, + attempt_forwarded_for varchar(255) DEFAULT '' NOT NULL, + attempt_time INT4 DEFAULT '0' NOT NULL CHECK (attempt_time >= 0), + user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), + username varchar(255) DEFAULT '0' NOT NULL, + username_clean varchar_ci DEFAULT '0' NOT NULL +); + +CREATE INDEX phpbb_login_attempts_att_ip ON phpbb_login_attempts (attempt_ip, attempt_time); +CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwarded_for, attempt_time); +CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); +CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); + +/* Table: 'phpbb_moderator_cache' */ CREATE TABLE phpbb_moderator_cache ( @@ -744,6 +762,7 @@ CREATE TABLE phpbb_profile_fields ( field_validation varchar(20) DEFAULT '' NOT NULL, field_required INT2 DEFAULT '0' NOT NULL CHECK (field_required >= 0), field_show_on_reg INT2 DEFAULT '0' NOT NULL CHECK (field_show_on_reg >= 0), + field_show_on_pm INT2 DEFAULT '0' NOT NULL CHECK (field_show_on_pm >= 0), field_show_on_vt INT2 DEFAULT '0' NOT NULL CHECK (field_show_on_vt >= 0), field_show_profile INT2 DEFAULT '0' NOT NULL CHECK (field_show_profile >= 0), field_hide INT2 DEFAULT '0' NOT NULL CHECK (field_hide >= 0), diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index f3259b8fe3..db66916b98 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -136,6 +136,9 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_max_thumb_widt INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_max_width', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_min_thumb_filesize', '12000'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('ip_check', '3'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ip_login_limit_max', '50'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ip_login_limit_time', '21600'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ip_login_limit_use_forwarded', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_enable', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_host', ''); INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_password', ''); @@ -157,6 +160,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('limit_search_load' INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_anon_lastread', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_birthdays', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_memberlist', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_profile', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_viewprofile', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_viewtopic', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_db_lastread', '1'); @@ -569,7 +573,7 @@ INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT # No Avatar (u_) INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 9, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%' AND auth_option NOT IN ('u_attach', 'u_chgavatar', 'u_viewonline', 'u_chggrp', 'u_chgname', 'u_ignoreflood', 'u_pm_attach', 'u_pm_emailpm', 'u_pm_flash', 'u_savedrafts', 'u_search', 'u_sendemail', 'u_sendim', 'u_masspm', 'u_masspm_group'); -INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 9, auth_option_id, 0 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_chgavatar', 'u_masspm', 'u_masspm_group'); +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 9, auth_option_id, 0 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_chgavatar'); # Full Moderator (m_) INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 10, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%'; diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 9344a29929..382e835767 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -1,5 +1,5 @@ # -# $Id$ +# $Id: $ # BEGIN TRANSACTION; @@ -359,6 +359,22 @@ CREATE INDEX phpbb_log_topic_id ON phpbb_log (topic_id); CREATE INDEX phpbb_log_reportee_id ON phpbb_log (reportee_id); CREATE INDEX phpbb_log_user_id ON phpbb_log (user_id); +# Table: 'phpbb_login_attempts' +CREATE TABLE phpbb_login_attempts ( + attempt_ip varchar(40) NOT NULL DEFAULT '', + attempt_browser varchar(150) NOT NULL DEFAULT '', + attempt_forwarded_for varchar(255) NOT NULL DEFAULT '', + attempt_time INTEGER UNSIGNED NOT NULL DEFAULT '0', + user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', + username varchar(255) NOT NULL DEFAULT '0', + username_clean varchar(255) NOT NULL DEFAULT '0' +); + +CREATE INDEX phpbb_login_attempts_att_ip ON phpbb_login_attempts (attempt_ip, attempt_time); +CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwarded_for, attempt_time); +CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); +CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', @@ -540,6 +556,7 @@ CREATE TABLE phpbb_profile_fields ( field_validation varchar(20) NOT NULL DEFAULT '', field_required INTEGER UNSIGNED NOT NULL DEFAULT '0', field_show_on_reg INTEGER UNSIGNED NOT NULL DEFAULT '0', + field_show_on_pm INTEGER UNSIGNED NOT NULL DEFAULT '0', field_show_on_vt INTEGER UNSIGNED NOT NULL DEFAULT '0', field_show_profile INTEGER UNSIGNED NOT NULL DEFAULT '0', field_hide INTEGER UNSIGNED NOT NULL DEFAULT '0', diff --git a/phpBB/language/en/acp/attachments.php b/phpBB/language/en/acp/attachments.php index 9ae250a95a..eede2c5d50 100644 --- a/phpBB/language/en/acp/attachments.php +++ b/phpBB/language/en/acp/attachments.php @@ -62,6 +62,7 @@ $lang = array_merge($lang, array( 'ATTACH_MAX_PM_FILESIZE_EXPLAIN' => 'Maximum size of each file, with 0 being unlimited, attached to a private message.', 'ATTACH_ORPHAN_URL' => 'Orphan attachments', 'ATTACH_POST_ID' => 'Post ID', + 'ATTACH_POST_TYPE' => 'Post type', 'ATTACH_QUOTA' => 'Total attachment quota', 'ATTACH_QUOTA_EXPLAIN' => 'Maximum drive space available for attachments for the whole board, with 0 being unlimited.', 'ATTACH_TO_POST' => 'Attach file to post', diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index fe023958a9..abf346137d 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -53,7 +53,7 @@ $lang = array_merge($lang, array( 'SYSTEM_TIMEZONE' => 'Guest timezone', 'SYSTEM_TIMEZONE_EXPLAIN' => 'Timezone to use for displaying times to users who are not logged in (guests, bots). Logged in users set their timezone during registration and can change it in their user control panel.', 'WARNINGS_EXPIRE' => 'Warning duration', - 'WARNINGS_EXPIRE_EXPLAIN' => 'Number of days that will elapse before the warning will automatically expire from a user’s record.', + 'WARNINGS_EXPIRE_EXPLAIN' => 'Number of days that will elapse before the warning will automatically expire from a user’s record. Set this value to 0 to make warnings permanent.', )); // Board Features @@ -151,7 +151,7 @@ $lang = array_merge($lang, array( 'ALLOW_POST_FLASH_EXPLAIN' => 'If disallowed the <code>[FLASH]</code> BBCode tag is disabled in posts. Otherwise the permission system controls which users can use the <code>[FLASH]</code> BBCode tag.', 'BUMP_INTERVAL' => 'Bump interval', - 'BUMP_INTERVAL_EXPLAIN' => 'Number of minutes, hours or days between the last post to a topic and the ability to bump this topic. Setting the value to 0 disables this feature.', + 'BUMP_INTERVAL_EXPLAIN' => 'Number of minutes, hours or days between the last post to a topic and the ability to bump that topic. Setting the value to 0 disables bumping entirely.', 'CHAR_LIMIT' => 'Maximum characters per post/message', 'CHAR_LIMIT_EXPLAIN' => 'The number of characters allowed within a post/private message. Set to 0 for unlimited characters.', 'DELETE_TIME' => 'Limit deleting time', @@ -208,16 +208,16 @@ $lang = array_merge($lang, array( 'ACP_REGISTER_SETTINGS_EXPLAIN' => 'Here you are able to define registration and profile related settings.', 'ACC_ACTIVATION' => 'Account activation', - 'ACC_ACTIVATION_EXPLAIN' => 'This determines whether users have immediate access to the board or if confirmation is required. You can also completely disable new registrations.', + 'ACC_ACTIVATION_EXPLAIN' => 'This determines whether users have immediate access to the board or if confirmation is required. You can also completely disable new registrations. “Board-wide e-mail” must be enabled in order to use user or admin activation.', 'NEW_MEMBER_POST_LIMIT' => 'New member post limit', 'NEW_MEMBER_POST_LIMIT_EXPLAIN' => 'New members are within the <em>Newly Registered Users</em> group until they reach this number of posts. You can use this group to keep them from using the PM system or to review their posts. <strong>A value of 0 disables this feature.</strong>', 'NEW_MEMBER_GROUP_DEFAULT' => 'Set Newly Registered Users group to default', 'NEW_MEMBER_GROUP_DEFAULT_EXPLAIN' => 'If set to yes, and a new member post limit is specified, newly registered users will not only be put into the <em>Newly Registered Users</em> group, but this group will also be their default one. This may come in handy if you want to assign a group default rank and/or avatar the user then inherits.', - 'ACC_ADMIN' => 'By Admin', - 'ACC_DISABLE' => 'Disable', - 'ACC_NONE' => 'None', - 'ACC_USER' => 'By User', + 'ACC_ADMIN' => 'By admin', + 'ACC_DISABLE' => 'Disable registration', + 'ACC_NONE' => 'No activation (immediate access)', + 'ACC_USER' => 'By user (e-mail verification)', // 'ACC_USER_ADMIN' => 'User + Admin', 'ALLOW_EMAIL_REUSE' => 'Allow e-mail address re-use', 'ALLOW_EMAIL_REUSE_EXPLAIN' => 'Different users can register with the same e-mail address.', @@ -353,6 +353,7 @@ $lang = array_merge($lang, array( 'LIMIT_SESSIONS' => 'Limit sessions', 'LIMIT_SESSIONS_EXPLAIN' => 'If the number of sessions exceeds this value within a one minute period the board will go offline. Set to 0 for unlimited sessions.', 'LOAD_CPF_MEMBERLIST' => 'Allow styles to display custom profile fields in memberlist', + 'LOAD_CPF_PM' => 'Display custom profile fields in private messages', 'LOAD_CPF_VIEWPROFILE' => 'Display custom profile fields in user profiles', 'LOAD_CPF_VIEWTOPIC' => 'Display custom profile fields on topic pages', 'LOAD_USER_ACTIVITY' => 'Show user’s activity', @@ -460,12 +461,18 @@ $lang = array_merge($lang, array( 'FORM_TIME_MAX_EXPLAIN' => 'The time a user has to submit a form. Use -1 to disable. Note that a form might become invalid if the session expires, regardless of this setting.', 'FORM_SID_GUESTS' => 'Tie forms to guest sessions', 'FORM_SID_GUESTS_EXPLAIN' => 'If enabled, the form token issued to guests will be session-exclusive. This can cause problems with some ISPs.', - 'FORWARDED_FOR_VALID' => 'Validated <var>X_FORWARDED_FOR</var> header', + 'FORWARDED_FOR_VALID' => 'Validate <var>X_FORWARDED_FOR</var> header', 'FORWARDED_FOR_VALID_EXPLAIN' => 'Sessions will only be continued if the sent <var>X_FORWARDED_FOR</var> header equals the one sent with the previous request. Bans will be checked against IPs in <var>X_FORWARDED_FOR</var> too.', 'IP_VALID' => 'Session IP validation', 'IP_VALID_EXPLAIN' => 'Determines how much of the users IP is used to validate a session; <samp>All</samp> compares the complete address, <samp>A.B.C</samp> the first x.x.x, <samp>A.B</samp> the first x.x, <samp>None</samp> disables checking. On IPv6 addresses <samp>A.B.C</samp> compares the first 4 blocks and <samp>A.B</samp> the first 3 blocks.', - 'MAX_LOGIN_ATTEMPTS' => 'Maximum number of login attempts', - 'MAX_LOGIN_ATTEMPTS_EXPLAIN' => 'After this number of failed logins the user needs to additionally solve the anti-spambot task.', + 'IP_LOGIN_LIMIT_MAX' => 'Maximum number of login attempts per IP address', + 'IP_LOGIN_LIMIT_MAX_EXPLAIN' => 'The threshold of login attempts allowed from a single IP address before an anti-spambot task is triggered. Enter 0 to prevent the anti-spambot task from being triggered by IP addresses.', + 'IP_LOGIN_LIMIT_TIME' => 'IP address login attempt expiration time', + 'IP_LOGIN_LIMIT_TIME_EXPLAIN' => 'Login attempts expire after this period.', + 'IP_LOGIN_LIMIT_USE_FORWARDED' => 'Limit login attempts by <var>X_FORWARDED_FOR</var> header', + 'IP_LOGIN_LIMIT_USE_FORWARDED_EXPLAIN' => 'Instead of limiting login attempts by IP address they are limited by <var>X_FORWARDED_FOR</var> values. <br /><em><strong>Warning:</strong> Only enable this if you are operating a proxy server that sets <var>X_FORWARDED_FOR</var> to trustworthy values.</em>', + 'MAX_LOGIN_ATTEMPTS' => 'Maximum number of login attempts per username', + 'MAX_LOGIN_ATTEMPTS_EXPLAIN' => 'The number of login attempts allowed for a single account before the anti-spambot task is triggered. Enter 0 to prevent the anti-spambot task from being triggered for distinct user accounts.', 'NO_IP_VALIDATION' => 'None', 'NO_REF_VALIDATION' => 'None', 'PASSWORD_TYPE' => 'Password complexity', diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index 847e763ae8..2a8ed86175 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -116,6 +116,10 @@ $lang = array_merge($lang, array( 'ACP_LOGGING' => 'Logging', 'ACP_MAIN' => 'ACP index', + + 'ACP_MANAGE_ATTACHMENTS' => 'Manage attachments', + 'ACP_MANAGE_ATTACHMENTS_EXPLAIN' => 'Here you can list and delete files attached to posts and private messages.', + 'ACP_MANAGE_EXTENSIONS' => 'Manage extensions', 'ACP_MANAGE_FORUMS' => 'Manage forums', 'ACP_MANAGE_RANKS' => 'Manage ranks', @@ -227,12 +231,16 @@ $lang = array_merge($lang, array( 'DOWNLOAD_AS' => 'Download as', 'DOWNLOAD_STORE' => 'Download or store file', 'DOWNLOAD_STORE_EXPLAIN' => 'You may directly download the file or save it in your <samp>store/</samp> folder.', + 'DOWNLOADS' => 'Downloads', 'EDIT' => 'Edit', 'ENABLE' => 'Enable', 'EXPORT_DOWNLOAD' => 'Download', 'EXPORT_STORE' => 'Store', + 'FILES_GONE' => 'Some of the attachments you selected for deletion do not exist. They may have been already deleted. Attachments that did exist were deleted.', + 'FILES_STATS_WRONG' => 'Your files statistics are probably inaccurate and need to be resynchronised. Actual values: number of attachments = %1$d, total size of attachments = %2$s.', + 'GENERAL_OPTIONS' => 'General options', 'GENERAL_SETTINGS' => 'General settings', 'GLOBAL_MASK' => 'Global permission mask', @@ -258,6 +266,7 @@ $lang = array_merge($lang, array( 'NOTIFY' => 'Notification', 'NO_ADMIN' => 'You are not authorised to administer this board.', 'NO_EMAILS_DEFINED' => 'No valid e-mail addresses found.', + 'NO_FILES_TO_DELETE' => 'Attachments you selected for deletion do not exist.', 'NO_PASSWORD_SUPPLIED' => 'You need to enter your password to access the Administration Control Panel.', 'OFF' => 'Off', @@ -272,6 +281,8 @@ $lang = array_merge($lang, array( 'REMIND' => 'Remind', 'RESYNC' => 'Resynchronise', + 'RESYNC_FILES_STATS' => 'Resynchronise files statistics', + 'RESYNC_FILES_STATS_EXPLAIN' => 'Recalculates the total number and size of files attached to posts and private messages.', 'RETURN_TO' => 'Return to…', 'SELECT_ANONYMOUS' => 'Select anonymous user', @@ -284,6 +295,8 @@ $lang = array_merge($lang, array( 'SHOW_ALL_OPERATIONS' => 'Show all operations', + 'TOTAL_SIZE' => 'Total size', + 'UCP' => 'User Control Panel', 'USERNAMES_EXPLAIN' => 'Place each username on a separate line.', 'USER_CONTROL_PANEL' => 'User Control Panel', @@ -356,6 +369,7 @@ $lang = array_merge($lang, array( 'RESET_DATE_CONFIRM' => 'Are you sure you wish to reset the board’s start date?', 'RESET_ONLINE' => 'Reset most users ever online', 'RESET_ONLINE_CONFIRM' => 'Are you sure you wish to reset the most users ever online counter?', + 'RESYNC_FILES_STATS_CONFIRM' => 'Are you sure you wish to resynchronise files statistics?', 'RESYNC_POSTCOUNTS' => 'Resynchronise post counts', 'RESYNC_POSTCOUNTS_EXPLAIN' => 'Only existing posts will be taken into consideration. Pruned posts will not be counted.', 'RESYNC_POSTCOUNTS_CONFIRM' => 'Are you sure you wish to resynchronise post counts?', @@ -660,6 +674,7 @@ $lang = array_merge($lang, array( 'LOG_REFERER_INVALID' => '<strong>Referer validation failed</strong><br />»Referer was “<em>%1$s</em>”. The request was rejected and the session killed.', 'LOG_RESET_DATE' => '<strong>Board start date reset</strong>', 'LOG_RESET_ONLINE' => '<strong>Most users online reset</strong>', + 'LOG_RESYNC_FILES_STATS' => '<strong>Files statistics resynchronised</strong>', 'LOG_RESYNC_POSTCOUNTS' => '<strong>User post counts resynchronised</strong>', 'LOG_RESYNC_POST_MARKING' => '<strong>Dotted topics resynchronised</strong>', 'LOG_RESYNC_STATS' => '<strong>Post, topic and user statistics resynchronised</strong>', diff --git a/phpBB/language/en/acp/profile.php b/phpBB/language/en/acp/profile.php index 31a82fd38f..ea643157d8 100644 --- a/phpBB/language/en/acp/profile.php +++ b/phpBB/language/en/acp/profile.php @@ -66,6 +66,8 @@ $lang = array_merge($lang, array( 'DISPLAY_AT_PROFILE_EXPLAIN' => 'The user is able to change this profile field within the user control panel.', 'DISPLAY_AT_REGISTER' => 'Display on registration screen', 'DISPLAY_AT_REGISTER_EXPLAIN' => 'If this option is enabled, the field will be displayed on registration.', + 'DISPLAY_ON_PM' => 'Display on view pm screen', + 'DISPLAY_ON_PM_EXPLAIN' => 'If this option is enabled, the field will be displayed in the mini-profile on the pm screen.', 'DISPLAY_ON_VT' => 'Display on viewtopic screen', 'DISPLAY_ON_VT_EXPLAIN' => 'If this option is enabled, the field will be displayed in the mini-profile on the topic screen.', 'DISPLAY_PROFILE_FIELD' => 'Publicly display profile field', diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php index 1cdf6f7050..2037a2455d 100644 --- a/phpBB/language/en/acp/styles.php +++ b/phpBB/language/en/acp/styles.php @@ -285,9 +285,9 @@ $lang = array_merge($lang, array( 'INSTALLED_TEMPLATE' => 'Installed templates', 'INSTALLED_THEME' => 'Installed themes', - 'KEEP_IMAGESET' => 'Keep "%s" imageset', - 'KEEP_TEMPLATE' => 'Keep "%s" template', - 'KEEP_THEME' => 'Keep "%s" theme', + 'KEEP_IMAGESET' => 'Keep “%s” imageset', + 'KEEP_TEMPLATE' => 'Keep “%s” template', + 'KEEP_THEME' => 'Keep “%s” theme', 'LINE_SPACING' => 'Line spacing', 'LOCALISED_IMAGES' => 'Localised', @@ -325,7 +325,7 @@ $lang = array_merge($lang, array( 'REPLACE_TEMPLATE_EXPLAIN' => 'This template set will replace the one you are deleting in any styles that use it.', 'REPLACE_THEME' => 'Replace theme with', 'REPLACE_THEME_EXPLAIN' => 'This theme will replace the one you are deleting in any styles that use it.', - 'REPLACE_WITH_OPTION' => 'Replace with "%s"', + 'REPLACE_WITH_OPTION' => 'Replace with “%s”', 'REQUIRES_IMAGESET' => 'This style requires the %s imageset to be installed.', 'REQUIRES_TEMPLATE' => 'This style requires the %s template set to be installed.', 'REQUIRES_THEME' => 'This style requires the %s theme to be installed.', diff --git a/phpBB/language/en/captcha_recaptcha.php b/phpBB/language/en/captcha_recaptcha.php index 3dad7a7409..e0550ffcfb 100644 --- a/phpBB/language/en/captcha_recaptcha.php +++ b/phpBB/language/en/captcha_recaptcha.php @@ -37,14 +37,14 @@ if (empty($lang) || !is_array($lang)) $lang = array_merge($lang, array( 'RECAPTCHA_LANG' => 'en', - 'RECAPTCHA_NOT_AVAILABLE' => 'In order to use reCaptcha, you must create an account on <a href="http://recaptcha.net">reCaptcha.net</a>.', + 'RECAPTCHA_NOT_AVAILABLE' => 'In order to use reCaptcha, you must create an account on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.', 'CAPTCHA_RECAPTCHA' => 'reCaptcha', 'RECAPTCHA_INCORRECT' => 'The visual confirmation code you submitted was incorrect', 'RECAPTCHA_PUBLIC' => 'Public reCaptcha key', - 'RECAPTCHA_PUBLIC_EXPLAIN' => 'Your public reCaptcha key. Keys can be obtained on <a href="http://recaptcha.net">reCaptcha.net</a>.', + 'RECAPTCHA_PUBLIC_EXPLAIN' => 'Your public reCaptcha key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.', 'RECAPTCHA_PRIVATE' => 'Private reCaptcha key', - 'RECAPTCHA_PRIVATE_EXPLAIN' => 'Your private reCaptcha key. Keys can be obtained on <a href="http://recaptcha.net">reCaptcha.net</a>.', + 'RECAPTCHA_PRIVATE_EXPLAIN' => 'Your private reCaptcha key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.', 'RECAPTCHA_EXPLAIN' => 'In an effort to prevent automatic submissions, we require that you enter both of the words displayed into the text field underneath.', )); diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 4a17deb32e..e04a194839 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -329,7 +329,7 @@ $lang = array_merge($lang, array( 'MEMBERLIST' => 'Members', 'MEMBERLIST_EXPLAIN' => 'View complete list of members', 'MERGE' => 'Merge', - 'MERGE_POSTS' => 'Merge posts', + 'MERGE_POSTS' => 'Move posts', 'MERGE_TOPIC' => 'Merge topic', 'MESSAGE' => 'Message', 'MESSAGES' => 'Messages', @@ -531,6 +531,7 @@ $lang = array_merge($lang, array( 'SEARCH_TOPIC' => 'Search this topic…', 'SEARCH_UNANSWERED' => 'View unanswered posts', 'SEARCH_UNREAD' => 'View unread posts', + 'SEARCH_USER_POSTS' => 'Search user’s posts', 'SECONDS' => 'Seconds', 'SELECT' => 'Select', 'SELECT_ALL_CODE' => 'Select all', @@ -652,6 +653,10 @@ $lang = array_merge($lang, array( 'UNREAD_PMS' => '<strong>%d</strong> unread messages', 'UNREAD_POST' => 'Unread post', 'UNREAD_POSTS' => 'Unread posts', + 'UNWATCH_FORUM_CONFIRM' => 'Are you sure you wish to unsubscribe from this forum?', + 'UNWATCH_FORUM_DETAILED' => 'Are you sure you wish to unsubscribe from the forum “%s”?', + 'UNWATCH_TOPIC_CONFIRM' => 'Are you sure you wish to unsubscribe from this topic?', + 'UNWATCH_TOPIC_DETAILED' => 'Are you sure you wish to unsubscribe from the topic “%s”?', 'UNWATCHED_FORUMS' => 'You are no longer subscribed to the selected forums.', 'UNWATCHED_TOPICS' => 'You are no longer subscribed to the selected topics.', 'UNWATCHED_FORUMS_TOPICS' => 'You are no longer subscribed to the selected entries.', @@ -700,6 +705,10 @@ $lang = array_merge($lang, array( 'WARNINGS' => 'Warnings', 'WARN_USER' => 'Warn user', + 'WATCH_FORUM_CONFIRM' => 'Are you sure you wish to subscribe to this forum?', + 'WATCH_FORUM_DETAILED' => 'Are you sure you wish to subscribe to the forum “%s”?', + 'WATCH_TOPIC_CONFIRM' => 'Are you sure you wish to subscribe to this topic?', + 'WATCH_TOPIC_DETAILED' => 'Are you sure you wish to subscribe to the topic “%s”?', 'WELCOME_SUBJECT' => 'Welcome to %s forums', 'WEBSITE' => 'Website', 'WHOIS' => 'Whois', diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php index bc5a3ab936..96970dcb23 100644 --- a/phpBB/language/en/install.php +++ b/phpBB/language/en/install.php @@ -300,10 +300,10 @@ $lang = array_merge($lang, array( 'PHP_REGISTER_GLOBALS_EXPLAIN' => 'phpBB will still run if this setting is enabled, but if possible, it is recommended that register_globals is disabled on your PHP install for security reasons.', 'PHP_SAFE_MODE' => 'Safe mode', 'PHP_SETTINGS' => 'PHP version and settings', - 'PHP_SETTINGS_EXPLAIN' => '<strong>Required</strong> - You must be running at least version 4.3.3 of PHP in order to install phpBB. If <var>safe mode</var> is displayed below your PHP installation is running in that mode. This will impose limitations on remote administration and similar features.', + 'PHP_SETTINGS_EXPLAIN' => '<strong>Required</strong> - You must be running at least version 5.2.0 of PHP in order to install phpBB. If <var>safe mode</var> is displayed below your PHP installation is running in that mode. This will impose limitations on remote administration and similar features.', 'PHP_URL_FOPEN_SUPPORT' => 'PHP setting <var>allow_url_fopen</var> is enabled', 'PHP_URL_FOPEN_SUPPORT_EXPLAIN' => '<strong>Optional</strong> - This setting is optional, however certain phpBB functions like off-site avatars will not work properly without it.', - 'PHP_VERSION_REQD' => 'PHP version >= 4.3.3', + 'PHP_VERSION_REQD' => 'PHP version >= 5.2.0', 'POST_ID' => 'Post ID', 'PREFIX_FOUND' => 'A scan of your tables has shown a valid installation using <strong>%s</strong> as table prefix.', 'PREPROCESS_STEP' => 'Executing pre-processing functions/queries', @@ -495,7 +495,7 @@ $lang = array_merge($lang, array( 'SHOW_DIFF_NEW' => 'Show file contents', 'SHOW_DIFF_NEW_CONFLICT' => 'Show differences', 'SHOW_DIFF_NOT_MODIFIED' => 'Show differences', - 'SOME_QUERIES_FAILED' => 'Some queries failed, the statements and errors are listing below.', + 'SOME_QUERIES_FAILED' => 'Some queries failed, the statements and errors are listed below.', 'SQL' => 'SQL', 'SQL_FAILURE_EXPLAIN' => 'This is probably nothing to worry about, update will continue. Should this fail to complete you may need to seek help at our support forums. See <a href="../docs/README.html">README</a> for details on how to obtain advice.', 'STAGE_FILE_CHECK' => 'Check files', diff --git a/phpBB/language/en/mcp.php b/phpBB/language/en/mcp.php index e2c0012430..16d6db061e 100644 --- a/phpBB/language/en/mcp.php +++ b/phpBB/language/en/mcp.php @@ -209,9 +209,8 @@ $lang = array_merge($lang, array( 'MCP_WARN_POST' => 'Warn for specific post', 'MCP_WARN_USER' => 'Warn user', - 'MERGE_POSTS' => 'Merge posts', - 'MERGE_POSTS_CONFIRM' => 'Are you sure you want to merge the selected posts?', - 'MERGE_TOPIC_EXPLAIN' => 'Using the form below you can merge selected posts into another topic. These posts will not be reordered and will appear as if the users posted them to the new topic.<br />Please enter the destination topic id or click on “Select topic” to search for one.', + 'MERGE_POSTS_CONFIRM' => 'Are you sure you want to move the selected posts?', + 'MERGE_TOPIC_EXPLAIN' => 'Using the form below you can move selected posts into another topic. The posts will be split from this topic and merged into the other topic. These posts will not be reordered and will appear as if the users posted them to the new topic.<br />Please enter the destination topic id or click on “Select topic” to search for one.', 'MERGE_TOPIC_ID' => 'Destination topic identification number', 'MERGE_TOPICS' => 'Merge topics', 'MERGE_TOPICS_CONFIRM' => 'Are you sure you want to merge the selected topics?', diff --git a/phpBB/language/en/memberlist.php b/phpBB/language/en/memberlist.php index 07edb2bb85..75c375d9eb 100644 --- a/phpBB/language/en/memberlist.php +++ b/phpBB/language/en/memberlist.php @@ -116,7 +116,6 @@ $lang = array_merge($lang, array( 'REMOVE_FOE' => 'Remove foe', 'REMOVE_FRIEND' => 'Remove friend', - 'SEARCH_USER_POSTS' => 'Search user’s posts', 'SELECT_MARKED' => 'Select marked', 'SELECT_SORT_METHOD' => 'Select sort method', 'SEND_AIM_MESSAGE' => 'Send AIM message', diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php index 76701aaf09..887b9c57dc 100644 --- a/phpBB/language/en/posting.php +++ b/phpBB/language/en/posting.php @@ -48,7 +48,7 @@ $lang = array_merge($lang, array( 'BBCODE_A_HELP' => 'Inline uploaded attachment: [attachment=]filename.ext[/attachment]', 'BBCODE_B_HELP' => 'Bold text: [b]text[/b]', 'BBCODE_C_HELP' => 'Code display: [code]code[/code]', - 'BBCODE_E_HELP' => 'List: Add list element', + 'BBCODE_D_HELP' => 'Flash: [flash=width,height]http://url[/flash]', 'BBCODE_F_HELP' => 'Font size: [size=85]small text[/size]', 'BBCODE_IS_OFF' => '%sBBCode%s is <em>OFF</em>', 'BBCODE_IS_ON' => '%sBBCode%s is <em>ON</em>', @@ -61,7 +61,7 @@ $lang = array_merge($lang, array( 'BBCODE_S_HELP' => 'Font colour: [color=red]text[/color] Tip: you can also use color=#FF0000', 'BBCODE_U_HELP' => 'Underline text: [u]text[/u]', 'BBCODE_W_HELP' => 'Insert URL: [url]http://url[/url] or [url=http://url]URL text[/url]', - 'BBCODE_D_HELP' => 'Flash: [flash=width,height]http://url[/flash]', + 'BBCODE_Y_HELP' => 'List: Add list element', 'BUMP_ERROR' => 'You cannot bump this topic so soon after the last post.', 'CANNOT_DELETE_REPLIED' => 'Sorry but you may only delete posts which have not been replied to.', diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 2bb9025037..f4b1b591d6 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -119,6 +119,7 @@ $lang = array_merge($lang, array( 'CANNOT_REMOVE_FOLDER' => 'This folder cannot be removed.', 'CHANGE_DEFAULT_GROUP' => 'Change default group', 'CHANGE_PASSWORD' => 'Change password', + 'CLICK_GOTO_FOLDER' => '%1$sGo to your “%3$s” folder%2$s', 'CLICK_RETURN_FOLDER' => '%1$sReturn to your “%3$s” folder%2$s', 'CONFIRMATION' => 'Confirmation of registration', 'CONFIRM_CHANGES' => 'Confirm changes', @@ -194,6 +195,7 @@ $lang = array_merge($lang, array( 'FIELD_INVALID_CHARS_ALPHA_ONLY' => 'The field “%s” has invalid characters, only alphanumeric characters are allowed.', 'FIELD_INVALID_CHARS_SPACERS_ONLY' => 'The field “%s” has invalid characters, only alphanumeric, space or -+_[] characters are allowed.', 'FIELD_INVALID_DATE' => 'The field “%s” has an invalid date.', + 'FIELD_INVALID_VALUE' => 'The field “%s” has an invalid value.', 'FOE_MESSAGE' => 'Message from foe', 'FOES_EXPLAIN' => 'Foes are users which will be ignored by default. Posts by these users will not be fully visible. Personal messages from foes are still permitted. Please note that you cannot ignore moderators or administrators.', diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 685830c656..418c1a4417 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -1295,13 +1295,6 @@ switch ($mode) $total_users = $config['num_users']; } - $s_char_options = '<option value=""' . ((!$first_char) ? ' selected="selected"' : '') . '> </option>'; - for ($i = 97; $i < 123; $i++) - { - $s_char_options .= '<option value="' . chr($i) . '"' . (($first_char == chr($i)) ? ' selected="selected"' : '') . '>' . chr($i-32) . '</option>'; - } - $s_char_options .= '<option value="other"' . (($first_char == 'other') ? ' selected="selected"' : '') . '>' . $user->lang['OTHER'] . '</option>'; - // Build a relevant pagination_url $params = $sort_params = array(); @@ -1331,6 +1324,7 @@ switch ($mode) 'first_char' => array('first_char', ''), ); + $u_first_char_params = array(); foreach ($check_params as $key => $call) { if (!isset($_REQUEST[$key])) @@ -1342,6 +1336,10 @@ switch ($mode) $param = urlencode($key) . '=' . ((is_string($param)) ? urlencode($param) : $param); $params[] = $param; + if ($key != 'first_char') + { + $u_first_char_params[] = $param; + } if ($key != 'sk' && $key != 'sd') { $sort_params[] = $param; @@ -1361,6 +1359,27 @@ switch ($mode) unset($search_params, $sort_params); + $u_first_char_params = implode('&', $u_first_char_params); + $u_first_char_params .= ($u_first_char_params) ? '&' : ''; + + $first_characters = array(); + $first_characters[''] = $user->lang['ALL']; + for ($i = 97; $i < 123; $i++) + { + $first_characters[chr($i)] = chr($i - 32); + } + $first_characters['other'] = $user->lang['OTHER']; + + foreach ($first_characters as $char => $desc) + { + $template->assign_block_vars('first_char', array( + 'DESC' => $desc, + 'VALUE' => $char, + 'S_SELECTED' => ($first_char == $char) ? true : false, + 'U_SORT' => append_sid("{$phpbb_root_path}memberlist.$phpEx", $u_first_char_params . 'first_char=' . $char) . '#memberlist', + )); + } + // Some search user specific data if ($mode == 'searchuser' && ($config['load_search'] || $auth->acl_get('a_'))) { @@ -1605,7 +1624,6 @@ switch ($mode) 'S_LEADERS_SET' => $leaders_set, 'S_MODE_SELECT' => $s_sort_key, 'S_ORDER_SELECT' => $s_sort_dir, - 'S_CHAR_OPTIONS' => $s_char_options, 'S_MODE_ACTION' => $pagination_url) ); } @@ -1669,7 +1687,7 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f if ($bday_year) { - $now = getdate(time() + $user->timezone + $user->dst - date('Z')); + $now = phpbb_gmgetdate(time() + $user->timezone + $user->dst); $diff = $now['mon'] - $bday_month; if ($diff == 0) diff --git a/phpBB/posting.php b/phpBB/posting.php index 734e97742c..0809b5a685 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -319,35 +319,7 @@ if ($mode == 'bump') if ($bump_time = bump_topic_allowed($forum_id, $post_data['topic_bumped'], $post_data['topic_last_post_time'], $post_data['topic_poster'], $post_data['topic_last_poster_id']) && check_link_hash(request_var('hash', ''), "topic_{$post_data['topic_id']}")) { - $db->sql_transaction('begin'); - - $sql = 'UPDATE ' . POSTS_TABLE . " - SET post_time = $current_time - WHERE post_id = {$post_data['topic_last_post_id']} - AND topic_id = $topic_id"; - $db->sql_query($sql); - - $sql = 'UPDATE ' . TOPICS_TABLE . " - SET topic_last_post_time = $current_time, - topic_bumped = 1, - topic_bumper = " . $user->data['user_id'] . " - WHERE topic_id = $topic_id"; - $db->sql_query($sql); - - update_post_information('forum', $forum_id); - - $sql = 'UPDATE ' . USERS_TABLE . " - SET user_lastpost_time = $current_time - WHERE user_id = " . $user->data['user_id']; - $db->sql_query($sql); - - $db->sql_transaction('commit'); - - markread('post', $forum_id, $topic_id, $current_time); - - add_log('mod', $forum_id, $topic_id, 'LOG_BUMP_TOPIC', $post_data['topic_title']); - - $meta_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id&p={$post_data['topic_last_post_id']}") . "#p{$post_data['topic_last_post_id']}"; + $meta_url = phpbb_bump_topic($forum_id, $topic_id, $post_data, $current_time); meta_refresh(3, $meta_url); $message = $user->lang['TOPIC_BUMPED'] . '<br /><br />' . sprintf($user->lang['VIEW_MESSAGE'], '<a href="' . $meta_url . '">', '</a>'); diff --git a/phpBB/report.php b/phpBB/report.php index a30914392b..45c1962370 100644 --- a/phpBB/report.php +++ b/phpBB/report.php @@ -39,11 +39,13 @@ if (!$post_id && (!$pm_id || !$config['allow_pm_report'])) if ($post_id) { $redirect_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&p=$post_id") . "#p$post_id"; + $return_forum_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id"); $pm_id = 0; } else { $redirect_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=view&p=$pm_id"); + $return_forum_url = ''; $post_id = 0; $forum_id = 0; } @@ -101,6 +103,7 @@ if ($post_id) { $message = $user->lang['ALREADY_REPORTED']; $message .= '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $redirect_url . '">', '</a>'); + $message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . $return_forum_url . '">', '</a>'); trigger_error($message); } } @@ -209,6 +212,10 @@ if ($submit && $reason_id) meta_refresh(3, $redirect_url); $message = $lang_success . '<br /><br />' . sprintf($lang_return, '<a href="' . $redirect_url . '">', '</a>'); + if ($return_forum_url) + { + $message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . $return_forum_url . '">', '</a>'); + } trigger_error($message); } diff --git a/phpBB/style.php b/phpBB/style.php index 9f8b77c1f5..62be0dde2b 100644 --- a/phpBB/style.php +++ b/phpBB/style.php @@ -15,13 +15,7 @@ define('IN_PHPBB', true); $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './'; $phpEx = substr(strrchr(__FILE__, '.'), 1); -// Report all errors, except notices and deprecation messages -if (!defined('E_DEPRECATED')) -{ - define('E_DEPRECATED', 8192); -} -error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED); - +require($phpbb_root_path . 'includes/startup.' . $phpEx); require($phpbb_root_path . 'config.' . $phpEx); if (!defined('PHPBB_INSTALLED') || empty($dbms) || empty($acm_type)) @@ -29,11 +23,6 @@ if (!defined('PHPBB_INSTALLED') || empty($dbms) || empty($acm_type)) exit; } -if (version_compare(PHP_VERSION, '6.0.0-dev', '<')) -{ - @set_magic_quotes_runtime(0); -} - // Load Extensions if (!empty($load_extensions) && function_exists('dl')) { diff --git a/phpBB/styles/prosilver/imageset/site_logo.gif b/phpBB/styles/prosilver/imageset/site_logo.gif Binary files differindex 909114c377..2517fbedd6 100644 --- a/phpBB/styles/prosilver/imageset/site_logo.gif +++ b/phpBB/styles/prosilver/imageset/site_logo.gif diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index d6596203e5..3227050179 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -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="wrap-content"><!-- 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> @@ -26,7 +26,8 @@ <!-- IF not forumrow.S_IS_CAT --> <li class="row"> <dl class="icon {forumrow.FORUM_IMG_STYLE}"> - <dt title="{forumrow.FORUM_FOLDER_IMG_ALT}"> + <dt title="{forumrow.FORUM_FOLDER_IMG_ALT}"><div class="wrap-content"> + <!-- 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 --> @@ -36,7 +37,7 @@ <br /><strong>{forumrow.L_MODERATOR_STR}:</strong> {forumrow.MODERATORS} <!-- ENDIF --> <!-- IF forumrow.SUBFORUMS and forumrow.S_LIST_SUBFORUMS --><br /><strong>{forumrow.L_SUBFORUM_STR}</strong> {forumrow.SUBFORUMS}<!-- ENDIF --> - </dt> + </div></dt> <!-- IF forumrow.CLICKS --> <dd class="redirect"><span>{L_REDIRECTS}: {forumrow.CLICKS}</span></dd> <!-- ELSEIF not forumrow.S_IS_LINK --> diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html index 539c851d1d..b183cf4372 100644 --- a/phpBB/styles/prosilver/template/index_body.html +++ b/phpBB/styles/prosilver/template/index_body.html @@ -35,9 +35,9 @@ <!-- IF LEGEND --><br /><em>{L_LEGEND}: {LEGEND}</em><!-- ENDIF --></p> <!-- ENDIF --> -<!-- IF S_DISPLAY_BIRTHDAY_LIST and BIRTHDAY_LIST --> +<!-- IF S_DISPLAY_BIRTHDAY_LIST and .birthdays --> <h3>{L_BIRTHDAYS}</h3> - <p><!-- IF BIRTHDAY_LIST -->{L_CONGRATULATIONS}: <strong>{BIRTHDAY_LIST}</strong><!-- ELSE -->{L_NO_BIRTHDAYS}<!-- ENDIF --></p> + <p><!-- IF .birthdays -->{L_CONGRATULATIONS}: <strong><!-- BEGIN birthdays -->{birthdays.USERNAME}<!-- IF birthdays.AGE !== '' --> ({birthdays.AGE})<!-- ENDIF --><!-- IF not birthdays.S_LAST_ROW -->, <!-- ENDIF --><!-- END birthdays --></strong><!-- ELSE -->{L_NO_BIRTHDAYS}<!-- ENDIF --></p> <!-- ENDIF --> <!-- IF NEWEST_USER --> diff --git a/phpBB/styles/prosilver/template/jumpbox.html b/phpBB/styles/prosilver/template/jumpbox.html index f7b4fca609..1029627561 100644 --- a/phpBB/styles/prosilver/template/jumpbox.html +++ b/phpBB/styles/prosilver/template/jumpbox.html @@ -10,7 +10,7 @@ <!-- ENDIF --> <!-- IF S_DISPLAY_JUMPBOX --> - <form method="post" id="jumpbox" action="{S_JUMPBOX_ACTION}" onsubmit="if(document.jumpbox.f.value == -1){return false;}"> + <form method="post" id="jumpbox" action="{S_JUMPBOX_ACTION}" onsubmit="if(this.f.value == -1){return false;}"> <!-- IF $CUSTOM_FIELDSET_CLASS --> <fieldset class="{$CUSTOM_FIELDSET_CLASS}"> diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index ecd650e093..6943dd41b3 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -31,7 +31,7 @@ onload_functions.push('subPanels()'); </li> <li id="merge-panel-tab"<!-- IF S_MERGE_VIEW --> class="activetab"<!-- ENDIF -->> <span class="corners-top"><span></span></span> - <a href="#minitabs" onclick="subPanels('merge-panel'); return false;"><span>{L_MERGE_TOPIC}</span></a> + <a href="#minitabs" onclick="subPanels('merge-panel'); return false;"><span>{L_MERGE_POSTS}</span></a> </li> </ul> </div> diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html index 99e06e37cf..ff53e42119 100644 --- a/phpBB/styles/prosilver/template/memberlist_body.html +++ b/phpBB/styles/prosilver/template/memberlist_body.html @@ -34,34 +34,11 @@ <li> <!-- IF U_FIND_MEMBER and not S_SEARCH_USER --><a href="{U_FIND_MEMBER}">{L_FIND_USERNAME}</a> • <!-- ELSEIF S_SEARCH_USER and U_HIDE_FIND_MEMBER and not S_IN_SEARCH_POPUP --><a href="{U_HIDE_FIND_MEMBER}">{L_HIDE_MEMBER_SEARCH}</a> • <!-- ENDIF --> - <strong style="font-size: 0.95em;"><a href="{S_MODE_ACTION}&first_char=">{L_ALL}</a> - <a href="{S_MODE_ACTION}&first_char=a#memberlist">A</a> - <a href="{S_MODE_ACTION}&first_char=b#memberlist">B</a> - <a href="{S_MODE_ACTION}&first_char=c#memberlist">C</a> - <a href="{S_MODE_ACTION}&first_char=d#memberlist">D</a> - <a href="{S_MODE_ACTION}&first_char=e#memberlist">E</a> - <a href="{S_MODE_ACTION}&first_char=f#memberlist">F</a> - <a href="{S_MODE_ACTION}&first_char=g#memberlist">G</a> - <a href="{S_MODE_ACTION}&first_char=h#memberlist">H</a> - <a href="{S_MODE_ACTION}&first_char=i#memberlist">I</a> - <a href="{S_MODE_ACTION}&first_char=j#memberlist">J</a> - <a href="{S_MODE_ACTION}&first_char=k#memberlist">K</a> - <a href="{S_MODE_ACTION}&first_char=l#memberlist">L</a> - <a href="{S_MODE_ACTION}&first_char=m#memberlist">M</a> - <a href="{S_MODE_ACTION}&first_char=n#memberlist">N</a> - <a href="{S_MODE_ACTION}&first_char=o#memberlist">O</a> - <a href="{S_MODE_ACTION}&first_char=p#memberlist">P</a> - <a href="{S_MODE_ACTION}&first_char=q#memberlist">Q</a> - <a href="{S_MODE_ACTION}&first_char=r#memberlist">R</a> - <a href="{S_MODE_ACTION}&first_char=s#memberlist">S</a> - <a href="{S_MODE_ACTION}&first_char=t#memberlist">T</a> - <a href="{S_MODE_ACTION}&first_char=u#memberlist">U</a> - <a href="{S_MODE_ACTION}&first_char=v#memberlist">V</a> - <a href="{S_MODE_ACTION}&first_char=w#memberlist">W</a> - <a href="{S_MODE_ACTION}&first_char=x#memberlist">X</a> - <a href="{S_MODE_ACTION}&first_char=y#memberlist">Y</a> - <a href="{S_MODE_ACTION}&first_char=z#memberlist">Z</a> - <a href="{S_MODE_ACTION}&first_char=other">#</a></strong> + <strong style="font-size: 0.95em;"> + <!-- BEGIN first_char --> + <a href="{first_char.U_SORT}">{first_char.DESC}</a> + <!-- END first_char --> + </strong> </li> <li class="rightside pagination"> {TOTAL_USERS} • diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index e412896d09..5075c661f3 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -19,7 +19,7 @@ <span class="corners-bottom"><span></span></span></div> </div> - <div class="copyright">Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group + <div class="copyright">Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group <!-- IF TRANSLATION_INFO --><br />{TRANSLATION_INFO}<!-- ENDIF --> <!-- IF DEBUG_OUTPUT --><br />{DEBUG_OUTPUT}<!-- ENDIF --> <!-- IF U_ACP --><br /><strong><a href="{U_ACP}">{L_ACP}</a></strong><!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html index 463ed2b5c1..9f022e215d 100644 --- a/phpBB/styles/prosilver/template/overall_header.html +++ b/phpBB/styles/prosilver/template/overall_header.html @@ -1,16 +1,9 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> - -<meta http-equiv="content-type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="{S_USER_LANG}" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="" /> -<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9" /> {META} <title><!-- IF not S_VIEWTOPIC and not S_VIEWFORUM -->{SITENAME} - <!-- ENDIF --><!-- IF S_IN_MCP -->{L_MCP} - <!-- ELSEIF S_IN_UCP -->{L_UCP} - <!-- ENDIF -->{PAGE_TITLE}<!-- IF S_VIEWTOPIC or S_VIEWFORUM --> - {SITENAME}<!-- ENDIF --></title> @@ -81,16 +74,11 @@ // ]]> </script> -<script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/styleswitcher.js"></script> <script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/forum_fn.js"></script> <link href="{T_THEME_PATH}/print.css" rel="stylesheet" type="text/css" media="print" title="printonly" /> <link href="{T_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" /> -<link href="{T_THEME_PATH}/normal.css" rel="stylesheet" type="text/css" title="A" /> -<link href="{T_THEME_PATH}/medium.css" rel="alternate stylesheet" type="text/css" title="A+" /> -<link href="{T_THEME_PATH}/large.css" rel="alternate stylesheet" type="text/css" title="A++" /> - <!-- IF S_CONTENT_DIRECTION eq 'rtl' --> <link href="{T_THEME_PATH}/bidi.css" rel="stylesheet" type="text/css" media="screen, projection" /> <!-- ENDIF --> @@ -114,7 +102,7 @@ <!-- IF S_DISPLAY_SEARCH and not S_IN_SEARCH --> <div id="search-box"> - <form action="{U_SEARCH}" method="post" id="search"> + <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 class="button2" value="{L_SEARCH}" type="submit" /><br /> @@ -133,8 +121,6 @@ <ul class="linklist navlinks"> <li class="icon-home"><a href="{U_INDEX}" accesskey="h">{L_INDEX}</a> <!-- BEGIN navlinks --> <strong>‹</strong> <a href="{navlinks.U_VIEW_FORUM}">{navlinks.FORUM_NAME}</a><!-- END navlinks --></li> - <li class="rightside"><a href="#" onclick="fontsizeup(); return false;" onkeypress="return fontsizeup(event);" class="fontsize" title="{L_CHANGE_FONT_SIZE}">{L_CHANGE_FONT_SIZE}</a></li> - <!-- IF U_EMAIL_TOPIC --><li class="rightside"><a href="{U_EMAIL_TOPIC}" title="{L_EMAIL_TOPIC}" class="sendemail">{L_EMAIL_TOPIC}</a></li><!-- ENDIF --> <!-- IF U_EMAIL_PM --><li class="rightside"><a href="{U_EMAIL_PM}" title="{L_EMAIL_PM}" class="sendemail">{L_EMAIL_PM}</a></li><!-- ENDIF --> <!-- IF U_PRINT_TOPIC --><li class="rightside"><a href="{U_PRINT_TOPIC}" title="{L_PRINT_TOPIC}" accesskey="p" class="print">{L_PRINT_TOPIC}</a></li><!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/posting_buttons.html b/phpBB/styles/prosilver/template/posting_buttons.html index 19d55d1a4a..78c2a0d9f2 100644 --- a/phpBB/styles/prosilver/template/posting_buttons.html +++ b/phpBB/styles/prosilver/template/posting_buttons.html @@ -25,7 +25,7 @@ a: '{LA_BBCODE_A_HELP}', s: '{LA_BBCODE_S_HELP}', f: '{LA_BBCODE_F_HELP}', - e: '{LA_BBCODE_E_HELP}', + y: '{LA_BBCODE_Y_HELP}', d: '{LA_BBCODE_D_HELP}' <!-- BEGIN custom_tags --> ,cb_{custom_tags.BBCODE_ID}: '{custom_tags.A_BBCODE_HELPLINE}' @@ -79,7 +79,7 @@ <input type="button" class="button2" accesskey="c" name="addbbcode8" value="Code" style="width: 40px" onclick="bbstyle(8)" title="{L_BBCODE_C_HELP}" /> <input type="button" class="button2" accesskey="l" name="addbbcode10" value="List" style="width: 40px" onclick="bbstyle(10)" title="{L_BBCODE_L_HELP}" /> <input type="button" class="button2" accesskey="o" name="addbbcode12" value="List=" style="width: 40px" onclick="bbstyle(12)" title="{L_BBCODE_O_HELP}" /> - <input type="button" class="button2" accesskey="y" name="addlitsitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" title="{L_BBCODE_LISTITEM_HELP}" /> + <input type="button" class="button2" accesskey="y" name="addlistitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" title="{L_BBCODE_LISTITEM_HELP}" /> <!-- IF S_BBCODE_IMG --> <input type="button" class="button2" accesskey="p" name="addbbcode14" value="Img" style="width: 40px" onclick="bbstyle(14)" title="{L_BBCODE_P_HELP}" /> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/simple_footer.html b/phpBB/styles/prosilver/template/simple_footer.html index 1455b05a50..2511db675f 100644 --- a/phpBB/styles/prosilver/template/simple_footer.html +++ b/phpBB/styles/prosilver/template/simple_footer.html @@ -1,6 +1,6 @@ </div> - <div class="copyright">Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group + <div class="copyright">Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group <!-- IF TRANSLATION_INFO --><br />{TRANSLATION_INFO}<!-- ENDIF --> <!-- IF DEBUG_OUTPUT --><br />{DEBUG_OUTPUT}<!-- ENDIF --> </div> diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html index f983a8ef8d..9a196ab7c6 100644 --- a/phpBB/styles/prosilver/template/simple_header.html +++ b/phpBB/styles/prosilver/template/simple_header.html @@ -1,13 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> - -<meta http-equiv="content-type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="{S_USER_LANG}" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="" /> {META} @@ -46,16 +40,11 @@ // ]]> </script> -<script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/styleswitcher.js"></script> <script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/forum_fn.js"></script> <link href="{T_THEME_PATH}/print.css" rel="stylesheet" type="text/css" media="print" title="printonly" /> <link href="{T_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" /> -<link href="{T_THEME_PATH}/normal.css" rel="alternate stylesheet" type="text/css" title="A" /> -<link href="{T_THEME_PATH}/medium.css" rel="alternate stylesheet" type="text/css" title="A+" /> -<link href="{T_THEME_PATH}/large.css" rel="alternate stylesheet" type="text/css" title="A++" /> - <!-- IF S_CONTENT_DIRECTION eq 'rtl' --> <link href="{T_THEME_PATH}/bidi.css" rel="stylesheet" type="text/css" media="screen, projection" /> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/styleswitcher.js b/phpBB/styles/prosilver/template/styleswitcher.js deleted file mode 100644 index bbcac9b69c..0000000000 --- a/phpBB/styles/prosilver/template/styleswitcher.js +++ /dev/null @@ -1,193 +0,0 @@ - -function fontsizeup(event) -{ - // Skip tabs; 9 being the ASCII code for a tab - if (event && getKeyCode(event) == 9) - { - return true; - } - - var active = getActiveStyleSheet(); - - switch (active) - { - case 'A--': - setActiveStyleSheet('A-'); - break; - - case 'A-': - setActiveStyleSheet('A'); - break; - - case 'A': - setActiveStyleSheet('A+'); - break; - - case 'A+': - setActiveStyleSheet('A++'); - break; - - case 'A++': - setActiveStyleSheet('A'); - break; - - default: - setActiveStyleSheet('A'); - break; - } - - return false; -} - -function fontsizedown(event) -{ - // Skip tabs - if (event && getKeyCode(event) == 9) - { - return true; - } - - var active = getActiveStyleSheet(); - - switch (active) - { - case 'A++' : - setActiveStyleSheet('A+'); - break; - - case 'A+' : - setActiveStyleSheet('A'); - break; - - case 'A' : - setActiveStyleSheet('A-'); - break; - - case 'A-' : - setActiveStyleSheet('A--'); - break; - - case 'A--' : - break; - - default : - setActiveStyleSheet('A--'); - break; - } - - return false; -} - -function getKeyCode(event) -{ - // IE doesn't fire the onkeypress event for tabs - // Reference: http://www.quirksmode.org/js/keys.html - - var code = (event.keyCode) ? event.keyCode : 0; - - // Probably using FF - if (!code && event.charCode) - { - code = event.charCode; - } - - return code; -} - -function setActiveStyleSheet(title) -{ - var i, a, main; - - for (i = 0; (a = document.getElementsByTagName('link')[i]); i++) - { - if (a.getAttribute('rel').indexOf('style') != -1 && a.getAttribute('title')) - { - a.disabled = true; - if (a.getAttribute('title') == title) - { - a.disabled = false; - } - } - } -} - -function getActiveStyleSheet() -{ - var i, a; - - for (i = 0; (a = document.getElementsByTagName('link')[i]); i++) - { - if (a.getAttribute('rel').indexOf('style') != -1 && a.getAttribute('title') && !a.disabled) - { - return a.getAttribute('title'); - } - } - - return null; -} - -function getPreferredStyleSheet() -{ - return ('A-'); -} - -function createCookie(name, value, days) -{ - if (days) - { - var date = new Date(); - date.setTime(date.getTime() + (days*24*60*60*1000)); - var expires = '; expires=' + date.toGMTString(); - } - else - { - expires = ''; - } - - document.cookie = name + '=' + value + expires + style_cookie_settings; -} - -function readCookie(name) -{ - var nameEQ = name + '='; - var ca = document.cookie.split(';'); - - for (var i = 0; i < ca.length; i++) - { - var c = ca[i]; - - while (c.charAt(0) == ' ') - { - c = c.substring(1, c.length); - } - - if (c.indexOf(nameEQ) == 0) - { - return c.substring(nameEQ.length, c.length); - } - } - - return null; -} - -function load_cookie() -{ - var cookie = readCookie('style_cookie'); - var title = cookie ? cookie : getPreferredStyleSheet(); - setActiveStyleSheet(title); -} - -function unload_cookie() -{ - var title = getActiveStyleSheet(); - createCookie('style_cookie', title, 365); -} - -onload_functions.push('load_cookie()'); -onunload_functions.push('unload_cookie()'); - -/* -var cookie = readCookie("style"); -var title = cookie ? cookie : getPreferredStyleSheet(); -setActiveStyleSheet(title); -*/ diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index af5213ae30..5317068d89 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -69,7 +69,12 @@ <dd><strong>{L_POSTS}:</strong> {AUTHOR_POSTS}</dd> <!-- IF AUTHOR_JOINED --><dd><strong>{L_JOINED}:</strong> {AUTHOR_JOINED}</dd><!-- ENDIF --> <!-- IF AUTHOR_FROM --><dd><strong>{L_LOCATION}:</strong> {AUTHOR_FROM}</dd><!-- ENDIF --> - + + <!-- BEGIN custom_fields --> + <dd><strong>{custom_fields.PROFILE_FIELD_NAME}:</strong> {custom_fields.PROFILE_FIELD_VALUE}</dd> + <!-- END custom_fields --> + + <!-- IF U_PM or U_EMAIL or U_WWW or U_MSN or U_ICQ or U_YIM or U_AIM or U_JABBER --> <dd> <ul class="profile-icons"> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html index 5e8564e06f..10879c5b14 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html @@ -1,9 +1,6 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta http-equiv="content-type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="{S_USER_LANG}" /> <title>{SITENAME} :: {PAGE_TITLE}</title> <style type="text/css"> @@ -112,7 +109,7 @@ hr.sep { <td align="{S_CONTENT_FLOW_END}"><span class="gensmall">{S_TIMEZONE}</span></td> </tr> <tr> - <td colspan="2" align="center"><span class="gensmall">Powered by phpBB © phpBB Group<br />http://www.phpbb.com/</span></td> + <td colspan="2" align="center"><span class="gensmall">Powered by phpBB® Forum Software © phpBB Group<br />http://www.phpbb.com/</span></td> </tr> </table> diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index b9e222bff1..a6fdaf246d 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -45,11 +45,11 @@ <!-- IF S_DISPLAY_SEARCHBOX --> <div class="search-box"> - <form method="post" id="forum-search" action="{S_SEARCHBOX_ACTION}"> + <form method="get" id="forum-search" action="{S_SEARCHBOX_ACTION}"> <fieldset> <input class="inputbox search tiny" type="text" name="keywords" id="search_keywords" size="20" value="{L_SEARCH_FORUM}" onclick="if (this.value == '{LA_SEARCH_FORUM}') this.value = '';" onblur="if (this.value == '') this.value = '{LA_SEARCH_FORUM}';" /> <input class="button2" type="submit" value="{L_SEARCH}" /> - <input type="hidden" value="{FORUM_ID}" name="fid[]" /> + {S_SEARCH_LOCAL_HIDDEN_FIELDS} </fieldset> </form> </div> @@ -127,7 +127,7 @@ <ul class="topiclist"> <li class="header"> <dl class="icon"> - <dt><!-- IF S_DISPLAY_ACTIVE -->{L_ACTIVE_TOPICS}<!-- ELSEIF topicrow.S_TOPIC_TYPE_SWITCH and (topicrow.S_POST_ANNOUNCE or topicrow.S_POST_GLOBAL) -->{L_ANNOUNCEMENTS}<!-- ELSE -->{L_TOPICS}<!-- ENDIF --></dt> + <dt><div class="wrap-content"><!-- IF S_DISPLAY_ACTIVE -->{L_ACTIVE_TOPICS}<!-- ELSEIF topicrow.S_TOPIC_TYPE_SWITCH and (topicrow.S_POST_ANNOUNCE or topicrow.S_POST_GLOBAL) -->{L_ANNOUNCEMENTS}<!-- ELSE -->{L_TOPICS}<!-- ENDIF --></div></dt> <dd class="posts">{L_REPLIES}</dd> <dd class="views">{L_VIEWS}</dd> <dd class="lastpost"><span>{L_LAST_POST}</span></dd> @@ -139,13 +139,13 @@ <li class="row<!-- IF topicrow.S_ROW_COUNT is even --> bg1<!-- ELSE --> bg2<!-- ENDIF --><!-- IF topicrow.S_POST_GLOBAL --> global-announce<!-- ENDIF --><!-- IF topicrow.S_POST_ANNOUNCE --> announce<!-- ENDIF --><!-- IF topicrow.S_POST_STICKY --> sticky<!-- ENDIF --><!-- IF topicrow.S_TOPIC_REPORTED --> reported<!-- ENDIF -->"> <dl class="icon {topicrow.TOPIC_IMG_STYLE}"> - <dt<!-- IF topicrow.TOPIC_ICON_IMG and S_TOPIC_ICONS --> style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{topicrow.TOPIC_FOLDER_IMG_ALT}"><!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --><a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a> + <dt<!-- IF topicrow.TOPIC_ICON_IMG and S_TOPIC_ICONS --> style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{topicrow.TOPIC_FOLDER_IMG_ALT}"><div class="wrap-content"><!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- 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 --> <!-- IF topicrow.S_TOPIC_REPORTED --><a href="{topicrow.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --><br /> <!-- IF topicrow.PAGINATION --><strong class="pagination"><span>{topicrow.PAGINATION}</span></strong><!-- ENDIF --> <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF -->{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} <!-- IF topicrow.S_POST_GLOBAL and FORUM_ID != topicrow.FORUM_ID --> » {L_IN} <a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a><!-- ENDIF --> - </dt> + </div></dt> <dd class="posts">{topicrow.REPLIES} <dfn>{L_REPLIES}</dfn></dd> <dd class="views">{topicrow.VIEWS} <dfn>{L_VIEWS}</dfn></dd> <dd class="lastpost"><span><dfn>{L_LAST_POST} </dfn>{L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 05c2b91a2e..f7a1ff4f99 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -38,12 +38,11 @@ <!-- IF S_DISPLAY_SEARCHBOX --> <div class="search-box"> - <form method="post" id="topic-search" action="{S_SEARCHBOX_ACTION}"> + <form method="get" id="topic-search" action="{S_SEARCHBOX_ACTION}"> <fieldset> <input class="inputbox search tiny" type="text" name="keywords" id="search_keywords" size="20" value="{L_SEARCH_TOPIC}" onclick="if(this.value=='{LA_SEARCH_TOPIC}')this.value='';" onblur="if(this.value=='')this.value='{LA_SEARCH_TOPIC}';" /> <input class="button2" type="submit" value="{L_SEARCH}" /> - <input type="hidden" value="{TOPIC_ID}" name="t" /> - <input type="hidden" value="msgonly" name="sf" /> + {S_SEARCH_LOCAL_HIDDEN_FIELDS} </fieldset> </form> </div> diff --git a/phpBB/styles/prosilver/template/viewtopic_print.html b/phpBB/styles/prosilver/template/viewtopic_print.html index 7b91ff4bc3..8a8ea87f00 100644 --- a/phpBB/styles/prosilver/template/viewtopic_print.html +++ b/phpBB/styles/prosilver/template/viewtopic_print.html @@ -1,13 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> - -<meta http-equiv="content-type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="content-language" content="{S_USER_LANG}" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="" /> <meta name="robots" content="noindex" /> @@ -44,7 +38,7 @@ <div id="page-footer"> <div class="page-number">{S_TIMEZONE}<br />{PAGE_NUMBER}</div> - <div class="copyright">Powered by phpBB © phpBB Group<br />http://www.phpbb.com/</div> + <div class="copyright">Powered by phpBB® Forum Software © phpBB Group<br />http://www.phpbb.com/</div> </div> </div> diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css index f441784d85..81b916d373 100644 --- a/phpBB/styles/prosilver/theme/bidi.css +++ b/phpBB/styles/prosilver/theme/bidi.css @@ -491,7 +491,7 @@ /* Sub-header (navigation bar) --------------------------------------------- */ -.rtl a.print, .rtl a.sendemail, .rtl a.fontsize { +.rtl a.print, .rtl a.sendemail { text-align: right; } diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index 6cffdc5930..f73c79ff73 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -51,7 +51,7 @@ /* Sub-header (navigation bar) --------------------------------------------- */ -a.print, a.sendemail, a.fontsize { +a.print, a.sendemail { display: block; overflow: hidden; height: 18px; @@ -70,17 +70,6 @@ a.sendemail { width: 22px; } -a.fontsize { - background-image: none; - background-position: 0 -1px; - width: 29px; -} - -a.fontsize:hover { - background-position: 0 -20px; - text-decoration: none; -} - /* Icon images ---------------------------------------- */ .sitehome, .icon-faq, .icon-members, .icon-home, .icon-ucp, .icon-register, .icon-logout, diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index c1c0711fb2..b1cccaab7a 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -298,7 +298,7 @@ a.topictitle:active { .postlink:visited { color: #5D8FBD; - border-bottom-color: #666666; + border-bottom-color: #5D8FBD; } .postlink:active { @@ -676,10 +676,6 @@ a.sendemail { background-image: url("{T_THEME_PATH}/images/icon_sendemail.gif"); } -a.fontsize { - background-image: url("{T_THEME_PATH}/images/icon_fontsize.gif"); -} - /* Icon images ---------------------------------------- */ .sitehome { background-image: url("{T_THEME_PATH}/images/icon_home.gif"); } diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index 955a4a79c0..c7ff57efb5 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -29,10 +29,15 @@ ul.topiclist li.row dl { ul.topiclist dt { display: block; float: left; - width: 50%; + width: 100%; font-size: 1.1em; padding-left: 5px; padding-right: 5px; + margin-right: -465px; +} + +ul.topiclist dt .wrap-content { + padding-right: 465px; } ul.topiclist dd { @@ -96,6 +101,7 @@ li.header dt, li.header dd { li.header dt { font-weight: bold; + margin-right: -465px; } li.header dd { @@ -126,7 +132,7 @@ dl.icon dt { } dd.posts, dd.topics, dd.views { - width: 8%; + width: 90px; text-align: center; line-height: 2.2em; font-size: 1.2em; @@ -145,7 +151,7 @@ dl.icon dt li { } dd.lastpost { - width: 25%; + width: 230px; font-size: 1.1em; } diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css index 1e0edc616f..b574b0ae1f 100644 --- a/phpBB/styles/prosilver/theme/cp.css +++ b/phpBB/styles/prosilver/theme/cp.css @@ -393,13 +393,11 @@ ol.def-rules li { /* PM marking colours */ .pmlist li.bg1 { - border: solid 3px transparent; - border-width: 0 3px; + padding: 0 3px; } .pmlist li.bg2 { - border: solid 3px transparent; - border-width: 0 3px; + padding: 0 3px; } .pmlist li.pm_message_reported_colour, .pm_message_reported_colour { @@ -408,21 +406,25 @@ ol.def-rules li { } .pmlist li.pm_marked_colour, .pm_marked_colour { + padding: 0; border: solid 3px #ffffff; border-width: 0 3px; } .pmlist li.pm_replied_colour, .pm_replied_colour { + padding: 0; border: solid 3px #c2c2c2; - border-width: 0 3px; + border-width: 0 3px; } .pmlist li.pm_friend_colour, .pm_friend_colour { + padding: 0; border: solid 3px #bdbdbd; border-width: 0 3px; } .pmlist li.pm_foe_colour, .pm_foe_colour { + padding: 0; border: solid 3px #000000; border-width: 0 3px; } diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css index 4e48a93a55..803c608bcf 100644 --- a/phpBB/styles/prosilver/theme/forms.css +++ b/phpBB/styles/prosilver/theme/forms.css @@ -262,7 +262,10 @@ fieldset.submit-buttons input { #message-box textarea { font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif; - width: 100%; + width: 450px; + height: 270px; + min-width: 100%; + max-width: 100%; font-size: 1.2em; color: #333333; } diff --git a/phpBB/styles/prosilver/theme/images/icon_fontsize.gif b/phpBB/styles/prosilver/theme/images/icon_fontsize.gif Binary files differdeleted file mode 100644 index 1c7d83527c..0000000000 --- a/phpBB/styles/prosilver/theme/images/icon_fontsize.gif +++ /dev/null diff --git a/phpBB/styles/prosilver/theme/large.css b/phpBB/styles/prosilver/theme/large.css deleted file mode 100644 index 1c3eb42b5d..0000000000 --- a/phpBB/styles/prosilver/theme/large.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - font-size: 12px; -} diff --git a/phpBB/styles/prosilver/theme/links.css b/phpBB/styles/prosilver/theme/links.css index a406114054..1f6c2af550 100644 --- a/phpBB/styles/prosilver/theme/links.css +++ b/phpBB/styles/prosilver/theme/links.css @@ -87,11 +87,7 @@ a.topictitle:active { padding-bottom: 0; } -.postlink:visited { - color: #bdbdbd; - border-bottom-style: dotted; - border-bottom-color: #666666; -} +/* .postlink:visited { color: #bdbdbd; } */ .postlink:active { color: #d2d2d2; diff --git a/phpBB/styles/prosilver/theme/medium.css b/phpBB/styles/prosilver/theme/medium.css deleted file mode 100644 index e3b932b61d..0000000000 --- a/phpBB/styles/prosilver/theme/medium.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - font-size: 11px; -} diff --git a/phpBB/styles/prosilver/theme/normal.css b/phpBB/styles/prosilver/theme/normal.css deleted file mode 100644 index d842feb31b..0000000000 --- a/phpBB/styles/prosilver/theme/normal.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - font-size: 10px; -} diff --git a/phpBB/styles/subsilver2/template/attachment.html b/phpBB/styles/subsilver2/template/attachment.html index b5b547b2e6..fca620b481 100644 --- a/phpBB/styles/subsilver2/template/attachment.html +++ b/phpBB/styles/subsilver2/template/attachment.html @@ -72,7 +72,7 @@ <param name="controller" value="true"> <param name="autoplay" value="false" /> <param name="type" value="video/quicktime"> - <embed name="qtstream_{_file.ATTACH_ID}" src="{_file.U_DOWNLOAD_LINK}" pluginspage="http://www.apple.com/quicktime/download/" enablejavascript="true" controller="true" width="320" height="285" type="video/quicktime" autoplay="false"> + <embed name="qtstream_{_file.ATTACH_ID}" src="{_file.U_DOWNLOAD_LINK}" pluginspage="http://www.apple.com/quicktime/download/" enablejavascript="true" controller="true" width="320" height="285" type="video/quicktime" autoplay="false"></embed> </object> <!-- ELSEIF _file.S_RM_FILE --> <object id="rmstream_{_file.ATTACH_ID}" classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="200" height="50"> diff --git a/phpBB/styles/subsilver2/template/index_body.html b/phpBB/styles/subsilver2/template/index_body.html index e52e357564..100199c209 100644 --- a/phpBB/styles/subsilver2/template/index_body.html +++ b/phpBB/styles/subsilver2/template/index_body.html @@ -50,7 +50,7 @@ </tr> <tr> <td class="row1" align="center" valign="middle"><img src="{T_THEME_PATH}/images/whosonline.gif" alt="{L_BIRTHDAYS}" /></td> - <td class="row1" width="100%"><p class="genmed"><!-- IF BIRTHDAY_LIST -->{L_CONGRATULATIONS}: <b>{BIRTHDAY_LIST}</b><!-- ELSE -->{L_NO_BIRTHDAYS}<!-- ENDIF --></p></td> + <td class="row1" width="100%"><p class="genmed"><!-- IF .birthdays -->{L_CONGRATULATIONS}: <b><!-- BEGIN birthdays -->{birthdays.USERNAME}<!-- IF birthdays.AGE !== '' --> ({birthdays.AGE})<!-- ENDIF --><!-- IF not birthdays.S_LAST_ROW -->, <!-- ENDIF --><!-- END birthdays --></b><!-- ELSE -->{L_NO_BIRTHDAYS}<!-- ENDIF --></p></td> </tr> </table> <!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/mcp_topic.html b/phpBB/styles/subsilver2/template/mcp_topic.html index 12c0f73b97..13865d26ee 100644 --- a/phpBB/styles/subsilver2/template/mcp_topic.html +++ b/phpBB/styles/subsilver2/template/mcp_topic.html @@ -35,7 +35,7 @@ <!-- IF S_CAN_MERGE --> <tr> - <th colspan="3" nowrap="nowrap">{L_MERGE_TOPIC}</th> + <th colspan="3" nowrap="nowrap">{L_MERGE_POSTS}</th> </tr> <tr> <td class="row2" colspan="3" align="center"><span class="gensmall">{L_MERGE_TOPIC_EXPLAIN}</span></td> diff --git a/phpBB/styles/subsilver2/template/memberlist_body.html b/phpBB/styles/subsilver2/template/memberlist_body.html index 7a63154daf..78ffe49111 100644 --- a/phpBB/styles/subsilver2/template/memberlist_body.html +++ b/phpBB/styles/subsilver2/template/memberlist_body.html @@ -14,7 +14,12 @@ <form method="post" name="charsearch" action="{S_MODE_ACTION}"> <table width="100%" cellspacing="1"> <tr> - <td align="{S_CONTENT_FLOW_BEGIN}"><span class="genmed">{L_USERNAME_BEGINS_WITH}: </span><select name="first_char" onchange="this.form.submit();">{S_CHAR_OPTIONS}</select> <input type="submit" name="char" value="{L_DISPLAY}" class="btnlite" /></td> + <td align="{S_CONTENT_FLOW_BEGIN}"><span class="genmed">{L_USERNAME_BEGINS_WITH}: </span> + <select name="first_char" onchange="this.form.submit();"> + <!-- BEGIN first_char --> + <option value="{first_char.VALUE}"<!-- IF first_char.S_SELECTED --> selected="selected"<!-- ENDIF -->>{first_char.DESC}</option> + <!-- END first_char --> + </select> <input type="submit" name="char" value="{L_DISPLAY}" class="btnlite" /></td> <!-- IF U_FIND_MEMBER and not S_SEARCH_USER --> <td class="genmed" align="{S_CONTENT_FLOW_END}"><a href="{U_FIND_MEMBER}">{L_FIND_USERNAME}</a></td> <!-- ELSEIF S_SEARCH_USER and U_HIDE_FIND_MEMBER and not S_IN_SEARCH_POPUP --> diff --git a/phpBB/styles/subsilver2/template/overall_footer.html b/phpBB/styles/subsilver2/template/overall_footer.html index d82e01b888..4494ed83bf 100644 --- a/phpBB/styles/subsilver2/template/overall_footer.html +++ b/phpBB/styles/subsilver2/template/overall_footer.html @@ -3,7 +3,7 @@ <div id="wrapfooter"> <!-- IF U_ACP --><span class="gensmall">[ <a href="{U_ACP}">{L_ACP}</a> ]</span><br /><br /><!-- ENDIF --> - <span class="copyright">Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group + <span class="copyright">Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group <!-- IF TRANSLATION_INFO --><br />{TRANSLATION_INFO}<!-- ENDIF --> <!-- IF DEBUG_OUTPUT --><br /><bdo dir="ltr">[ {DEBUG_OUTPUT} ]</bdo><!-- ENDIF --></span> </div> diff --git a/phpBB/styles/subsilver2/template/overall_header.html b/phpBB/styles/subsilver2/template/overall_header.html index b9c7a604ce..4fca1b6c09 100644 --- a/phpBB/styles/subsilver2/template/overall_header.html +++ b/phpBB/styles/subsilver2/template/overall_header.html @@ -1,16 +1,9 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> - -<meta http-equiv="content-type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="content-language" content="{S_USER_LANG}" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="" /> -<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9" /> {META} <title><!-- IF not S_VIEWTOPIC and not S_VIEWFORUM -->{SITENAME} - <!-- ENDIF --><!-- IF S_IN_MCP -->{L_MCP} - <!-- ELSEIF S_IN_UCP -->{L_UCP} - <!-- ENDIF -->{PAGE_TITLE}<!-- IF S_VIEWTOPIC or S_VIEWFORUM --> - {SITENAME}<!-- ENDIF --></title> diff --git a/phpBB/styles/subsilver2/template/posting_body.html b/phpBB/styles/subsilver2/template/posting_body.html index 7537ad2883..67ef1443ab 100644 --- a/phpBB/styles/subsilver2/template/posting_body.html +++ b/phpBB/styles/subsilver2/template/posting_body.html @@ -210,7 +210,7 @@ <table width="100%" cellspacing="0" cellpadding="0" border="0"> <!-- INCLUDE posting_buttons.html --> <tr> - <td valign="top" style="width: 100%;"><textarea name="message" rows="15" cols="76" tabindex="3" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();" style="width: 98%;">{MESSAGE}</textarea></td> + <td valign="top" style="width: 100%;"><textarea name="message" rows="15" cols="76" tabindex="3" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();" style="width: 700px; height: 270px; min-width: 98%; max-width: 98%;">{MESSAGE}</textarea></td> <!-- IF S_BBCODE_ALLOWED --> <td width="80" align="center" valign="top"> <script type="text/javascript"> diff --git a/phpBB/styles/subsilver2/template/posting_buttons.html b/phpBB/styles/subsilver2/template/posting_buttons.html index 92b4bd3e39..a9105b5eec 100644 --- a/phpBB/styles/subsilver2/template/posting_buttons.html +++ b/phpBB/styles/subsilver2/template/posting_buttons.html @@ -22,9 +22,8 @@ a: '{LA_BBCODE_A_HELP}', s: '{LA_BBCODE_S_HELP}', f: '{LA_BBCODE_F_HELP}', - e: '{LA_BBCODE_E_HELP}', + y: '{LA_BBCODE_Y_HELP}', d: '{LA_BBCODE_D_HELP}', - t: '{LA_BBCODE_T_HELP}', tip: '{L_STYLES_TIP}' <!-- BEGIN custom_tags --> ,cb_{custom_tags.BBCODE_ID}: '{custom_tags.A_BBCODE_HELPLINE}' @@ -45,7 +44,7 @@ <input type="button" class="btnbbcode" accesskey="c" name="addbbcode8" value="Code" style="width: 40px" onclick="bbstyle(8)" onmouseover="helpline('c')" onmouseout="helpline('tip')" /> <input type="button" class="btnbbcode" accesskey="l" name="addbbcode10" value="List" style="width: 40px" onclick="bbstyle(10)" onmouseover="helpline('l')" onmouseout="helpline('tip')" /> <input type="button" class="btnbbcode" accesskey="o" name="addbbcode12" value="List=" style="width: 40px" onclick="bbstyle(12)" onmouseover="helpline('o')" onmouseout="helpline('tip')" /> - <input type="button" class="btnbbcode" accesskey="y" name="addlitsitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" onmouseover="helpline('e')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode" accesskey="y" name="addlistitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" onmouseover="helpline('e')" onmouseout="helpline('tip')" /> <!-- IF S_BBCODE_IMG --> <input type="button" class="btnbbcode" accesskey="p" name="addbbcode14" value="Img" style="width: 40px" onclick="bbstyle(14)" onmouseover="helpline('p')" onmouseout="helpline('tip')" /> <!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/quickreply_editor.html b/phpBB/styles/subsilver2/template/quickreply_editor.html index dd357976d8..de5017280c 100644 --- a/phpBB/styles/subsilver2/template/quickreply_editor.html +++ b/phpBB/styles/subsilver2/template/quickreply_editor.html @@ -10,7 +10,7 @@ </tr> <tr> <td class="row1" width="22%"><b class="genmed">{L_MESSAGE}:</b></td> - <td class="row2" valign="top" align="left" width="78%"><textarea name="message" rows="7" cols="76" tabindex="3" style="width: 98%;"></textarea> </td> + <td class="row2" valign="top" align="left" width="78%"><textarea name="message" rows="7" cols="76" tabindex="3" style="width: 700px; height: 130px; min-width: 98%; max-width: 98%;"></textarea> </td> </tr> <tr> <td class="cat" colspan="2" align="center"> diff --git a/phpBB/styles/subsilver2/template/searchbox.html b/phpBB/styles/subsilver2/template/searchbox.html index cb0bb5ba73..622961c881 100644 --- a/phpBB/styles/subsilver2/template/searchbox.html +++ b/phpBB/styles/subsilver2/template/searchbox.html @@ -1 +1 @@ -<form method="post" name="search" action="{S_SEARCHBOX_ACTION}"><span class="gensmall">{L_SEARCH_FOR}:</span> <input class="post" type="text" name="keywords" size="20" /> <input class="btnlite" type="submit" value="{L_GO}" /></form> +<form method="get" name="search" action="{S_SEARCHBOX_ACTION}"><span class="gensmall">{L_SEARCH_FOR}:</span> <input class="post" type="text" name="keywords" size="20" /> <input class="btnlite" type="submit" value="{L_GO}" />{S_SEARCH_LOCAL_HIDDEN_FIELDS}</form> diff --git a/phpBB/styles/subsilver2/template/simple_footer.html b/phpBB/styles/subsilver2/template/simple_footer.html index 7fbb4f3c13..e2469c4ed4 100644 --- a/phpBB/styles/subsilver2/template/simple_footer.html +++ b/phpBB/styles/subsilver2/template/simple_footer.html @@ -2,7 +2,7 @@ </div> <div id="wrapfooter"> - <span class="copyright">Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group</span> + <span class="copyright">Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group</span> </div> </body> diff --git a/phpBB/styles/subsilver2/template/simple_header.html b/phpBB/styles/subsilver2/template/simple_header.html index 9fcca4eb30..79236434f2 100644 --- a/phpBB/styles/subsilver2/template/simple_header.html +++ b/phpBB/styles/subsilver2/template/simple_header.html @@ -1,13 +1,7 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}" xml:lang="{S_USER_LANG}"> +<!DOCTYPE html> +<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> - -<meta http-equiv="content-type" content="text/html; charset={S_CONTENT_ENCODING}" /> -<meta http-equiv="content-language" content="{S_USER_LANG}" /> -<meta http-equiv="content-style-type" content="text/css" /> -<meta http-equiv="imagetoolbar" content="no" /> -<meta name="resource-type" content="document" /> -<meta name="distribution" content="global" /> +<meta charset="utf-8"> <meta name="keywords" content="" /> <meta name="description" content="" /> {META} diff --git a/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html b/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html index eff4a2a7dd..e52389cc15 100644 --- a/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html +++ b/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html @@ -1,9 +1,7 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!DOCTYPE html> <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta http-equiv="Content-Type" content="text/html; charset={S_CONTENT_ENCODING}"> -<meta http-equiv="Content-Style-Type" content="text/css"> -<meta http-equiv="Content-Language" content="{S_USER_LANG}"> +<meta charset="utf-8"> <title>{SITENAME} :: {PAGE_TITLE}</title> <style type="text/css"> @@ -114,7 +112,7 @@ hr.sep { <td align="{S_CONTENT_FLOW_END}"><span class="gensmall">{S_TIMEZONE}</span></td> </tr> <tr> - <td colspan="2" align="center"><span class="gensmall">Powered by phpBB © phpBB Group<br />http://www.phpbb.com/</span></td> + <td colspan="2" align="center"><span class="gensmall">Powered by phpBB® Forum Software © phpBB Group<br />http://www.phpbb.com/</span></td> </tr> </table> diff --git a/phpBB/styles/subsilver2/template/viewtopic_body.html b/phpBB/styles/subsilver2/template/viewtopic_body.html index a8789e186a..56e03e344c 100644 --- a/phpBB/styles/subsilver2/template/viewtopic_body.html +++ b/phpBB/styles/subsilver2/template/viewtopic_body.html @@ -150,7 +150,7 @@ <!-- IF postrow.POST_ICON_IMG --> <td><img src="{T_ICONS_PATH}{postrow.POST_ICON_IMG}" width="{postrow.POST_ICON_IMG_WIDTH}" height="{postrow.POST_ICON_IMG_HEIGHT}" alt="" title="" /></td> <!-- ENDIF --> - <td class="gensmall" width="100%"><div style="float: {S_CONTENT_FLOW_BEGIN};"> <b>{L_POST_SUBJECT}:</b> {postrow.POST_SUBJECT}</div><div style="float: {S_CONTENT_FLOW_END};"><!-- IF S_IS_BOT -->{postrow.MINI_POST_IMG}<!-- ELSE --><a href="{postrow.U_MINI_POST}">{postrow.MINI_POST_IMG}</a><!-- ENDIF --><b>{L_POSTED}:</b> {postrow.POST_DATE} </div></td> + <td class="gensmall" width="100%"><div style="float: {S_CONTENT_FLOW_BEGIN};"> <b>{L_POST_SUBJECT}:</b> <a href="#p{postrow.POST_ID}">{postrow.POST_SUBJECT}</a></div><div style="float: {S_CONTENT_FLOW_END};"><!-- IF S_IS_BOT -->{postrow.MINI_POST_IMG}<!-- ELSE --><a href="{postrow.U_MINI_POST}">{postrow.MINI_POST_IMG}</a><!-- ENDIF --><b>{L_POSTED}:</b> {postrow.POST_DATE} </div></td> </tr> </table> </td> diff --git a/phpBB/styles/subsilver2/template/viewtopic_print.html b/phpBB/styles/subsilver2/template/viewtopic_print.html index b5383f06ca..07da8ef752 100644 --- a/phpBB/styles/subsilver2/template/viewtopic_print.html +++ b/phpBB/styles/subsilver2/template/viewtopic_print.html @@ -1,9 +1,7 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<!DOCTYPE html> <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> -<meta http-equiv="Content-Type" content="text/html; charset={S_CONTENT_ENCODING}"> -<meta http-equiv="Content-Style-Type" content="text/css"> -<meta http-equiv="Content-Language" content="{S_USER_LANG}"> +<meta charset="utf-8"> <title>{SITENAME} :: {PAGE_TITLE}</title> <style type="text/css"> @@ -128,7 +126,7 @@ hr.sep { <td align="{S_CONTENT_FLOW_END}"><span class="gensmall">{S_TIMEZONE}</span></td> </tr> <tr> - <td colspan="2" align="center"><span class="gensmall">Powered by phpBB © phpBB Group<br />http://www.phpbb.com/</span></td> + <td colspan="2" align="center"><span class="gensmall">Powered by phpBB® Forum Software © phpBB Group<br />http://www.phpbb.com/</span></td> </tr> </table> diff --git a/phpBB/ucp.php b/phpBB/ucp.php index 69e48ac85b..4ec5d01fe0 100644 --- a/phpBB/ucp.php +++ b/phpBB/ucp.php @@ -316,6 +316,12 @@ if (!$config['allow_topic_notify'] && !$config['allow_forum_notify']) $module->set_display('main', 'subscribed', false); } +// Do not display signature panel if not authed to do so +if (!$auth->acl_get('u_sig')) +{ + $module->set_display('profile', 'signature', false); +} + // Select the active module $module->set_active($id, $mode); diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index c53150d89b..fa1ecf841e 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -212,7 +212,7 @@ $s_watching_forum = array( if (($config['email_enable'] || $config['jab_enable']) && $config['allow_forum_notify'] && $forum_data['forum_type'] == FORUM_POST && $auth->acl_get('f_subscribe', $forum_id)) { $notify_status = (isset($forum_data['notify_status'])) ? $forum_data['notify_status'] : NULL; - watch_topic_forum('forum', $s_watching_forum, $user->data['user_id'], $forum_id, 0, $notify_status); + watch_topic_forum('forum', $s_watching_forum, $user->data['user_id'], $forum_id, 0, $notify_status, $start, $forum_data['forum_name']); } $s_forum_rules = ''; @@ -272,6 +272,12 @@ $post_alt = ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->lang['FORUM_LO // Display active topics? $s_display_active = ($forum_data['forum_type'] == FORUM_CAT && ($forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS)) ? true : false; +$s_search_hidden_fields = array('fid' => array($forum_id)); +if ($_SID) +{ + $s_search_hidden_fields['sid'] = $_SID; +} + $template->assign_vars(array( 'MODERATORS' => (!empty($moderators[$forum_id])) ? implode(', ', $moderators[$forum_id]) : '', @@ -309,7 +315,8 @@ $template->assign_vars(array( 'S_WATCHING_FORUM' => $s_watching_forum['is_watching'], 'S_FORUM_ACTION' => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . (($start == 0) ? '' : "&start=$start")), 'S_DISPLAY_SEARCHBOX' => ($auth->acl_get('u_search') && $auth->acl_get('f_search', $forum_id) && $config['load_search']) ? true : false, - 'S_SEARCHBOX_ACTION' => append_sid("{$phpbb_root_path}search.$phpEx", 'fid[]=' . $forum_id), + 'S_SEARCHBOX_ACTION' => append_sid("{$phpbb_root_path}search.$phpEx"), + 'S_SEARCH_LOCAL_HIDDEN_FIELDS' => build_hidden_fields($s_search_hidden_fields), 'S_SINGLE_MODERATOR' => (!empty($moderators[$forum_id]) && sizeof($moderators[$forum_id]) > 1) ? false : true, 'S_IS_LOCKED' => ($forum_data['forum_status'] == ITEM_LOCKED) ? true : false, 'S_VIEWFORUM' => true, diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php index 74ad7eba0d..27038a975e 100644 --- a/phpBB/viewonline.php +++ b/phpBB/viewonline.php @@ -377,7 +377,7 @@ if ($auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) { $sql = 'SELECT group_id, group_name, group_colour, group_type, group_legend FROM ' . GROUPS_TABLE . ' - WHERE group_legend = > 0 + WHERE group_legend > 0 ORDER BY ' . $order_legend . ' ASC'; } else diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 53119e2ae7..3b383210c9 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -175,7 +175,7 @@ $sql_array = array( // The FROM-Order is quite important here, else t.* columns can not be correctly bound. if ($post_id) { - $sql_array['SELECT'] .= ', p.post_approved'; + $sql_array['SELECT'] .= ', p.post_approved, p.post_time'; $sql_array['FROM'][POSTS_TABLE] = 'p'; } @@ -275,12 +275,11 @@ if ($post_id) } else { - $sql = 'SELECT COUNT(p1.post_id) AS prev_posts - FROM ' . POSTS_TABLE . ' p1, ' . POSTS_TABLE . " p2 - WHERE p1.topic_id = {$topic_data['topic_id']} - AND p2.post_id = {$post_id} - " . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p1.post_approved = 1' : '') . ' - AND ' . (($sort_dir == 'd') ? 'p1.post_time >= p2.post_time' : 'p1.post_time <= p2.post_time'); + $sql = 'SELECT COUNT(p.post_id) AS prev_posts + FROM ' . POSTS_TABLE . " p + WHERE p.topic_id = {$topic_data['topic_id']} + " . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p.post_approved = 1' : '') . ' + AND ' . (($sort_dir == 'd') ? "p.post_time >= {$topic_data['post_time']}" : "p.post_time <= {$topic_data['post_time']}"); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); @@ -449,7 +448,7 @@ $s_watching_topic = array( if (($config['email_enable'] || $config['jab_enable']) && $config['allow_topic_notify'] && $user->data['is_registered']) { - watch_topic_forum('topic', $s_watching_topic, $user->data['user_id'], $forum_id, $topic_id, $topic_data['notify_status'], $start); + watch_topic_forum('topic', $s_watching_topic, $user->data['user_id'], $forum_id, $topic_id, $topic_data['notify_status'], $start, $topic_data['topic_title']); // Reset forum notification if forum notify is set if ($config['allow_forum_notify'] && $auth->acl_get('f_subscribe', $forum_id)) @@ -546,6 +545,15 @@ $server_path = (!$view) ? $phpbb_root_path : generate_board_url() . '/'; // Replace naughty words in title $topic_data['topic_title'] = censor_text($topic_data['topic_title']); +$s_search_hidden_fields = array( + 't' => $topic_id, + 'sf' => 'msgonly', +); +if ($_SID) +{ + $s_search_hidden_fields['sid'] = $_SID; +} + // Send vars to template $template->assign_vars(array( 'FORUM_ID' => $forum_id, @@ -597,7 +605,8 @@ $template->assign_vars(array( 'S_VIEWTOPIC' => true, 'S_DISPLAY_SEARCHBOX' => ($auth->acl_get('u_search') && $auth->acl_get('f_search', $forum_id) && $config['load_search']) ? true : false, - 'S_SEARCHBOX_ACTION' => append_sid("{$phpbb_root_path}search.$phpEx", 't=' . $topic_id), + 'S_SEARCHBOX_ACTION' => append_sid("{$phpbb_root_path}search.$phpEx"), + 'S_SEARCH_LOCAL_HIDDEN_FIELDS' => build_hidden_fields($s_search_hidden_fields), 'S_DISPLAY_POST_INFO' => ($topic_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_post', $forum_id) || $user->data['user_id'] == ANONYMOUS)) ? true : false, 'S_DISPLAY_REPLY_INFO' => ($topic_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_reply', $forum_id) || $user->data['user_id'] == ANONYMOUS)) ? true : false, @@ -946,7 +955,7 @@ $sql = $db->sql_build_query('SELECT', array( $result = $db->sql_query($sql); -$now = getdate(time() + $user->timezone + $user->dst - date('Z')); +$now = phpbb_gmgetdate(time() + $user->timezone + $user->dst); // Posts are stored in the $rowset array while $attach_list, $user_cache // and the global bbcode_bitfield are built diff --git a/phpBB/web.config b/phpBB/web.config index 128fe3c98f..a73c328626 100644 --- a/phpBB/web.config +++ b/phpBB/web.config @@ -6,7 +6,7 @@ <hiddenSegments> <add segment="cache" /> <add segment="files" /> - <add segment="store" /> + <add segment="store" /> <add segment="config.php" /> <add segment="common.php" /> </hiddenSegments> diff --git a/phpunit.xml.all b/phpunit.xml.all index 1be2830729..fde3bbb1a7 100644 --- a/phpunit.xml.all +++ b/phpunit.xml.all @@ -21,5 +21,22 @@ <blacklist> <directory>./tests/</directory> </blacklist> + <whitelist> + <directory suffix=".php">./phpBB/includes/</directory> + <exclude> + <file>./phpBB/includes/db/firebird.php</file> + <file>./phpBB/includes/db/mysql.php</file> + <file>./phpBB/includes/db/mysqli.php</file> + <file>./phpBB/includes/db/mssql.php</file> + <file>./phpBB/includes/db/mssql_odbc.php</file> + <file>./phpBB/includes/db/mssqlnative.php</file> + <file>./phpBB/includes/db/oracle.php</file> + <file>./phpBB/includes/db/postgres.php</file> + <file>./phpBB/includes/db/sqlite.php</file> + <file>./phpBB/includes/search/fulltext_native.php</file> + <file>./phpBB/includes/search/fulltext_mysql.php</file> + <directory suffix=".php">./phpBB/includes/captcha/</directory> + </exclude> + </whitelist> </filter> </phpunit> diff --git a/phpunit.xml.dist b/phpunit.xml.dist index de8134da8e..a2bf2288cc 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -27,5 +27,22 @@ <blacklist> <directory>./tests/</directory> </blacklist> + <whitelist> + <directory suffix=".php">./phpBB/includes/</directory> + <exclude> + <file>./phpBB/includes/db/firebird.php</file> + <file>./phpBB/includes/db/mysql.php</file> + <file>./phpBB/includes/db/mysqli.php</file> + <file>./phpBB/includes/db/mssql.php</file> + <file>./phpBB/includes/db/mssql_odbc.php</file> + <file>./phpBB/includes/db/mssqlnative.php</file> + <file>./phpBB/includes/db/oracle.php</file> + <file>./phpBB/includes/db/postgres.php</file> + <file>./phpBB/includes/db/sqlite.php</file> + <file>./phpBB/includes/search/fulltext_native.php</file> + <file>./phpBB/includes/search/fulltext_mysql.php</file> + <directory suffix=".php">./phpBB/includes/captcha/</directory> + </exclude> + </whitelist> </filter> </phpunit> diff --git a/tests/bbcode/url_bbcode_test.php b/tests/bbcode/url_bbcode_test.php new file mode 100644 index 0000000000..cd85dbd0d9 --- /dev/null +++ b/tests/bbcode/url_bbcode_test.php @@ -0,0 +1,63 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2010 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/bbcode.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/message_parser.php'; +require_once dirname(__FILE__) . '/../mock_user.php'; + +class phpbb_url_bbcode_test extends phpbb_test_case +{ + public function url_bbcode_test_data() + { + return array( + array( + 'url only', + '[url]http://www.phpbb.com/community/[/url]', + '[url:]http://www.phpbb.com/community/[/url:]' + ), + array( + 'url with title', + '[url=http://www.phpbb.com/community/]One line URL text[/url]', + '[url=http://www.phpbb.com/community/:]One line URL text[/url:]' + ), + array( + 'url with multiline title', + "[url=http://www.phpbb.com/community/]Multiline\x0AURL\x0Atext[/url]", + "[url=http://www.phpbb.com/community/:]Multiline\x0AURL\x0Atext[/url:]" + ), + array( + 'unclosed url with multiline', + "test [url] test \x0A test [url=http://www.phpbb.com/]test[/url] test", + "test [url] test \x0A test [url=http://www.phpbb.com/:]test[/url:] test" + ), + array( + 'unclosed url with multiline and title', + "test [url=http://www.phpbb.com/]test \x0A [url]http://phpbb.com[/url] test", + "test [url=http://www.phpbb.com/:]test \x0A [url]http://phpbb.com[/url:] test" + ), + ); + } + + /** + * @dataProvider url_bbcode_test_data + */ + public function test_url($description, $message, $expected) + { + global $user; + $user = new phpbb_mock_user; + + $bbcode = new bbcode_firstpass(); + $bbcode->message = $message; + $bbcode->bbcode_init(false); + $bbcode->parse_bbcode(); + $this->assertEquals($expected, $bbcode->message); + } +} diff --git a/tests/config/db_test.php b/tests/config/db_test.php index 5bd5296e5a..e817545a54 100644 --- a/tests/config/db_test.php +++ b/tests/config/db_test.php @@ -139,4 +139,28 @@ class phpbb_config_db_test extends phpbb_database_test_case $cache2->checkVarUnset($this, 'foo'); $this->assertFalse(isset($config2['foo'])); } + + public function test_delete_write_read_not_cacheable() + { + // bar is dynamic + $this->assertTrue(isset($this->config['bar'])); + $this->config->delete('bar'); + $this->cache->checkVarUnset($this, 'bar'); + $this->assertFalse(isset($this->config['bar'])); + + $this->config->set('bar', 'new bar', false); + $this->assertEquals('new bar', $this->config['bar']); + } + + public function test_delete_write_read_cacheable() + { + // foo is not dynamic + $this->assertTrue(isset($this->config['foo'])); + $this->config->delete('foo'); + $this->cache->checkVarUnset($this, 'foo'); + $this->assertFalse(isset($this->config['foo'])); + + $this->config->set('foo', 'new foo', true); + $this->assertEquals('new foo', $this->config['foo']); + } } diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php new file mode 100644 index 0000000000..ddea500f83 --- /dev/null +++ b/tests/dbal/db_tools_test.php @@ -0,0 +1,276 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/db/db_tools.php'; + +class phpbb_dbal_db_tools_test extends phpbb_database_test_case +{ + protected $db; + protected $tools; + protected $table_exists; + protected $table_data; + + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); + } + + protected function setUp() + { + parent::setUp(); + + $this->db = $this->new_dbal(); + $this->tools = new phpbb_db_tools($this->db); + + $this->table_data = array( + 'COLUMNS' => array( + 'c_id' => array('UINT', NULL, 'auto_increment'), + 'c_int_size' => array('INT:4', 4), + 'c_bint' => array('BINT', 4), + 'c_uint' => array('UINT', 4), + 'c_uint_size' => array('UINT:4', 4), + 'c_tint_size' => array('TINT:2', 4), + 'c_usint' => array('USINT', 4), + 'c_bool' => array('BOOL', 1), + 'c_vchar' => array('VCHAR', 'foo'), + 'c_vchar_size' => array('VCHAR:4', 'foo'), + 'c_char_size' => array('CHAR:4', 'foo'), + 'c_xstext' => array('XSTEXT', 'foo'), + 'c_stext' => array('STEXT', 'foo'), + 'c_text' => array('TEXT', 'foo'), + 'c_mtext' => array('MTEXT', 'foo'), + 'c_xstext_uni' => array('XSTEXT_UNI', 'foo'), + 'c_stext_uni' => array('STEXT_UNI', 'foo'), + 'c_text_uni' => array('TEXT_UNI', 'foo'), + 'c_mtext_uni' => array('MTEXT_UNI', 'foo'), + 'c_timestamp' => array('TIMESTAMP', 4), + 'c_decimal' => array('DECIMAL', 4.2), + 'c_decimal_size' => array('DECIMAL:6', 4.2), + 'c_pdecimal' => array('PDECIMAL', 4.2), + 'c_pdecimal_size' => array('PDECIMAL:7', 4.2), + 'c_vchar_uni' => array('VCHAR_UNI', 'foo'), + 'c_vchar_uni_size' => array('VCHAR_UNI:4', 'foo'), + 'c_vchar_ci' => array('VCHAR_CI', 'foo'), + 'c_varbinary' => array('VARBINARY', 'foo'), + ), + 'PRIMARY_KEY' => 'c_id', + 'KEYS' => array( + 'i_simple' => array('INDEX', 'c_uint'), + 'i_uniq' => array('UNIQUE', 'c_vchar'), + 'i_comp' => array('INDEX', array('c_vchar_uni', 'c_bool')), + 'i_comp_uniq' => array('UNIQUE', array('c_vchar_size', 'c_usint')), + ), + ); + $this->tools->sql_create_table('prefix_table_name', $this->table_data); + $this->table_exists = true; + } + + protected function tearDown() + { + if ($this->table_exists) + { + $this->tools->sql_table_drop('prefix_table_name'); + } + + parent::tearDown(); + } + + public function test_created_and_drop_table() + { + // table is empty after creation and queryable + $sql = 'SELECT * FROM prefix_table_name'; + $result = $this->db->sql_query($sql); + $this->assertTrue(! $this->db->sql_fetchrow($result)); + $this->db->sql_freeresult($result); + + $this->table_exists = false; + $this->tools->sql_table_drop('prefix_table_name'); + } + + static protected function get_default_values() + { + return array( + 'c_int_size' => 0, + 'c_bint' => 0, + 'c_uint' => 0, + 'c_uint_size' => 0, + 'c_tint_size' => 0, + 'c_usint' => 0, + 'c_bool' => 0, + 'c_vchar' => '', + 'c_vchar_size' => '', + 'c_char_size' => '', + 'c_xstext' => '', + 'c_stext' => '', + 'c_text' => '', + 'c_mtext' => '', + 'c_xstext_uni' => '', + 'c_stext_uni' => '', + 'c_text_uni' => '', + 'c_mtext_uni' => '', + 'c_timestamp' => 0, + 'c_decimal' => 0, + 'c_decimal_size' => 0, + 'c_pdecimal' => 0, + 'c_pdecimal_size' => 0, + 'c_vchar_uni' => '', + 'c_vchar_uni_size' => '', + 'c_vchar_ci' => '', + 'c_varbinary' => '', + ); + } + + static public function column_values() + { + return array( + array('c_int_size', -9999), + array('c_bint', '99999999999999999'), + array('c_uint', 16777215), + array('c_uint_size', 9999), + array('c_tint_size', -99), + array('c_usint', 99), + array('c_bool', 0), + array('c_vchar', str_repeat('a', 255)), + array('c_vchar_size', str_repeat('a', 4)), + array('c_char_size', str_repeat('a', 4)), + array('c_xstext', str_repeat('a', 1000)), + array('c_stext', str_repeat('a', 3000)), + array('c_text', str_repeat('a', 8000)), + array('c_mtext', str_repeat('a', 10000)), + array('c_xstext_uni', str_repeat("\xC3\x84", 100)), + array('c_stext_uni', str_repeat("\xC3\x84", 255)), + array('c_text_uni', str_repeat("\xC3\x84", 4000)), + array('c_mtext_uni', str_repeat("\xC3\x84", 10000)), + array('c_timestamp', 2147483647), + array('c_decimal', 999.99), + array('c_decimal_size', 9999.99), + array('c_pdecimal', 999.999), + array('c_pdecimal_size', 9999.999), + array('c_vchar_uni', str_repeat("\xC3\x84", 255)), + array('c_vchar_uni_size', str_repeat("\xC3\x84", 4)), + array('c_vchar_ci', str_repeat("\xC3\x84", 255)), + array('c_varbinary', str_repeat("\x00\xFF", 127)), + ); + } + + /** + * @dataProvider column_values + */ + public function test_created_column($column_name, $column_value) + { + $row_insert = self::get_default_values(); + $row_insert[$column_name] = $column_value; + + // empty table + $sql = 'DELETE FROM prefix_table_name'; + $result = $this->db->sql_query($sql); + + $sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row_insert); + $result = $this->db->sql_query($sql); + + $sql = "SELECT * + FROM prefix_table_name"; + $result = $this->db->sql_query($sql); + $row_actual = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $row_expect = $row_insert; + + unset($row_actual['id']); // auto increment id changes, so ignore + + $type = $this->table_data['COLUMNS'][$column_name][0]; + $this->assertEquals($row_expect[$column_name], $row_actual[$column_name], "Column $column_name of type $type should have equal return and input value."); + } + + public function test_auto_increment() + { + $sql = 'DELETE FROM prefix_table_name'; + $result = $this->db->sql_query($sql); + + $row1 = array_merge(self::get_default_values(), array( + 'c_uint' => 1, + 'c_vchar' => '1', // these values are necessary to avoid unique index issues + 'c_vchar_size' => '1', + )); + $row2 = array_merge(self::get_default_values(), array( + 'c_uint' => 2, + 'c_vchar' => '2', + 'c_vchar_size' => '2', + )); + + $sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row1); + $result = $this->db->sql_query($sql); + $id1 = $this->db->sql_nextid(); + + $sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row2); + $result = $this->db->sql_query($sql); + $id2 = $this->db->sql_nextid(); + + $this->assertGreaterThan($id1, $id2, 'Auto increment should increase the id value'); + + $sql = "SELECT * + FROM prefix_table_name WHERE c_id = $id1"; + $result = $this->db->sql_query($sql); + $row_actual = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $row1['c_id'] = $id1; + $this->assertEquals($row1, $row_actual); + + $sql = "SELECT * + FROM prefix_table_name WHERE c_id = $id2"; + $result = $this->db->sql_query($sql); + $row_actual = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $row2['c_id'] = $id2; + $this->assertEquals($row2, $row_actual); + } + + public function test_column_exists() + { + $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_id')); + $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'column_does_not_exist')); + } + + public function test_column_remove() + { + $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_int_size')); + + $this->assertTrue($this->tools->sql_column_remove('prefix_table_name', 'c_int_size')); + + $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_int_size')); + } + + public function test_column_remove_primary() + { + $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_id')); + + $this->assertTrue($this->tools->sql_column_remove('prefix_table_name', 'c_id')); + + $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_id')); + } + + public function test_table_exists() + { + $this->assertTrue($this->tools->sql_table_exists('prefix_table_name')); + $this->assertFalse($this->tools->sql_table_exists('prefix_does_not_exist')); + } + + public function test_table_drop() + { + $this->tools->sql_create_table('prefix_test_table', + array('COLUMNS' => array( + 'foo' => array('UINT', 42))) + ); + + $this->tools->sql_table_drop('prefix_test_table'); + } +} diff --git a/tests/dbal/schema_test.php b/tests/dbal/schema_test.php new file mode 100644 index 0000000000..2475a85708 --- /dev/null +++ b/tests/dbal/schema_test.php @@ -0,0 +1,38 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_dbal_schema_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); + } + + public function test_config_value_multibyte() + { + $db = $this->new_dbal(); + + $value = str_repeat("\xC3\x84", 255); + $sql = "INSERT INTO phpbb_config + (config_name, config_value) + VALUES ('name', '$value')"; + $result = $db->sql_query($sql); + + $sql = "SELECT config_value + FROM phpbb_config + WHERE config_name = 'name'"; + $result = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $this->assertEquals($value, $row['config_value']); + } +} diff --git a/tests/dbal/select_test.php b/tests/dbal/select_test.php index 533416f14b..e0d08d9306 100644 --- a/tests/dbal/select_test.php +++ b/tests/dbal/select_test.php @@ -8,6 +8,7 @@ */ require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; class phpbb_dbal_select_test extends phpbb_database_test_case { @@ -317,4 +318,27 @@ class phpbb_dbal_select_test extends phpbb_database_test_case $db->sql_freeresult($result); } + + function test_nested_transactions() + { + $db = $this->new_dbal(); + + // nested transactions should work on systems that do not require + // buffering of nested transactions, so ignore the ones that need + // buffering + if ($db->sql_buffer_nested_transactions()) + { + return; + } + + $sql = 'SELECT user_id FROM phpbb_users ORDER BY user_id ASC'; + $result1 = $db->sql_query($sql); + + $db->sql_transaction('begin'); + $result2 = $db->sql_query($sql); + $row = $db->sql_fetchrow($result2); + $db->sql_transaction('commit'); + + $this->assertEquals('1', $row['user_id']); + } } diff --git a/tests/functions_acp/build_cfg_template_test.php b/tests/functions_acp/build_cfg_template_test.php index 7bf85a3532..76e133181f 100644 --- a/tests/functions_acp/build_cfg_template_test.php +++ b/tests/functions_acp/build_cfg_template_test.php @@ -29,7 +29,7 @@ class phpbb_functions_acp_build_cfg_template_test extends phpbb_test_case array('config_key_name' => '2'), 'config_key_name', array(), - '<input id="key_name" type="password" size="20" maxlength="128" name="config[config_key_name]" value="2" />', + '<input id="key_name" type="password" size="20" maxlength="128" name="config[config_key_name]" value="2" autocomplete="off" />', ), array( array('text', 0, 255), diff --git a/tests/functions_acp/validate_config_vars_test.php b/tests/functions_acp/validate_config_vars_test.php index aa63bc38df..761788e264 100644 --- a/tests/functions_acp/validate_config_vars_test.php +++ b/tests/functions_acp/validate_config_vars_test.php @@ -13,19 +13,6 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case { /** - * Helper function which returns a string in a given length. - */ - static public function return_string($length) - { - $string = ''; - for ($i = 0; $i < $length; $i++) - { - $string .= 'a'; - } - return $string; - } - - /** * Data sets that don't throw an error. */ public function validate_config_vars_fit_data() @@ -35,8 +22,11 @@ class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case array( 'test_bool' => array('lang' => 'TEST_BOOL', 'validate' => 'bool'), 'test_string' => array('lang' => 'TEST_STRING', 'validate' => 'string'), + 'test_string' => array('lang' => 'TEST_STRING', 'validate' => 'string'), + 'test_string_128' => array('lang' => 'TEST_STRING_128', 'validate' => 'string:128'), 'test_string_128' => array('lang' => 'TEST_STRING_128', 'validate' => 'string:128'), 'test_string_32_64' => array('lang' => 'TEST_STRING_32_64', 'validate' => 'string:32:64'), + 'test_string_32_64' => array('lang' => 'TEST_STRING_32_64', 'validate' => 'string:32:64'), 'test_int' => array('lang' => 'TEST_INT', 'validate' => 'int'), 'test_int_32' => array('lang' => 'TEST_INT', 'validate' => 'int:32'), 'test_int_32_64' => array('lang' => 'TEST_INT', 'validate' => 'int:32:64'), @@ -51,9 +41,12 @@ class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case ), array( 'test_bool' => true, - 'test_string' => self::return_string(255), - 'test_string_128' => self::return_string(128), - 'test_string_32_64' => self::return_string(48), + 'test_string' => str_repeat('a', 255), + 'test_string' => str_repeat("\xC3\x84", 255), + 'test_string_128' => str_repeat('a', 128), + 'test_string_128' => str_repeat("\xC3\x84", 128), + 'test_string_32_64' => str_repeat('a', 48), + 'test_string_32_64' => str_repeat("\xC3\x84", 48), 'test_int' => 128, 'test_int_32' => 32, 'test_int_32_64' => 48, @@ -86,17 +79,32 @@ class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case return array( array( array('test_string_32_64' => array('lang' => 'TEST_STRING_32_64', 'validate' => 'string:32:64')), - array('test_string_32_64' => self::return_string(20)), + array('test_string_32_64' => str_repeat('a', 20)), + array('SETTING_TOO_SHORT'), + ), + array( + array('test_string_32_64' => array('lang' => 'TEST_STRING_32_64', 'validate' => 'string:32:64')), + array('test_string_32_64' => str_repeat("\xC3\x84", 20)), array('SETTING_TOO_SHORT'), ), array( array('test_string' => array('lang' => 'TEST_STRING', 'validate' => 'string')), - array('test_string' => self::return_string(256)), + array('test_string' => str_repeat('a', 256)), + array('SETTING_TOO_LONG'), + ), + array( + array('test_string' => array('lang' => 'TEST_STRING', 'validate' => 'string')), + array('test_string' => str_repeat("\xC3\x84", 256)), + array('SETTING_TOO_LONG'), + ), + array( + array('test_string_32_64' => array('lang' => 'TEST_STRING_32_64', 'validate' => 'string:32:64')), + array('test_string_32_64' => str_repeat('a', 65)), array('SETTING_TOO_LONG'), ), array( array('test_string_32_64' => array('lang' => 'TEST_STRING_32_64', 'validate' => 'string:32:64')), - array('test_string_32_64' => self::return_string(65)), + array('test_string_32_64' => str_repeat("\xC3\x84", 65)), array('SETTING_TOO_LONG'), ), diff --git a/tests/functions_acp/validate_range_test.php b/tests/functions_acp/validate_range_test.php index a9c9612ad7..11b7f87957 100644 --- a/tests/functions_acp/validate_range_test.php +++ b/tests/functions_acp/validate_range_test.php @@ -8,24 +8,12 @@ */ require_once dirname(__FILE__) . '/../mock/lang.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; class phpbb_functions_acp_validate_range_test extends phpbb_test_case { /** - * Helper function which returns a string in a given length. - */ - static public function return_string($length) - { - $string = ''; - for ($i = 0; $i < $length; $i++) - { - $string .= 'a'; - } - return $string; - } - - /** * Data sets that don't throw an error. */ public function validate_range_data_fit() @@ -53,8 +41,10 @@ class phpbb_functions_acp_validate_range_test extends phpbb_test_case array(array(array('column_type' => 'TINT:-32:64', 'lang' => 'TEST', 'value' => 16))), array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => ''))), - array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => self::return_string(255)))), - array(array(array('column_type' => 'VCHAR:128', 'lang' => 'TEST', 'value' => self::return_string(128)))), + array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => str_repeat('a', 255)))), + array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => str_repeat("\xC3\x84", 255)))), + array(array(array('column_type' => 'VCHAR:128', 'lang' => 'TEST', 'value' => str_repeat('a', 128)))), + array(array(array('column_type' => 'VCHAR:128', 'lang' => 'TEST', 'value' => str_repeat("\xC3\x84", 128)))), ); } @@ -157,8 +147,10 @@ class phpbb_functions_acp_validate_range_test extends phpbb_test_case public function validate_range_data_too_long() { return array( - array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => self::return_string(256)))), - array(array(array('column_type' => 'VCHAR:128', 'lang' => 'TEST', 'value' => self::return_string(129)))), + array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => str_repeat('a', 256)))), + array(array(array('column_type' => 'VCHAR', 'lang' => 'TEST', 'value' => str_repeat("\xC3\x84", 256)))), + array(array(array('column_type' => 'VCHAR:128', 'lang' => 'TEST', 'value' => str_repeat('a', 129)))), + array(array(array('column_type' => 'VCHAR:128', 'lang' => 'TEST', 'value' => str_repeat("\xC3\x84", 129)))), ); } diff --git a/tests/mock_user.php b/tests/mock_user.php new file mode 100644 index 0000000000..74d31c4c4a --- /dev/null +++ b/tests/mock_user.php @@ -0,0 +1,20 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +/** +* Mock user class. +* This class is used when tests invoke phpBB code expecting to have a global +* user object, to avoid instantiating the actual user object. +* It has a minimum amount of functionality, just to make tests work. +*/ +class phpbb_mock_user +{ + public $host = "testhost"; + public $page = array('root_script_path' => '/'); +} diff --git a/tests/profile/custom_test.php b/tests/profile/custom_test.php new file mode 100644 index 0000000000..0e0a851243 --- /dev/null +++ b/tests/profile/custom_test.php @@ -0,0 +1,55 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_profile_fields.php'; + +class phpbb_profile_custom_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/profile_fields.xml'); + } + + static public function dropdownFields() + { + return array( + // note, there is an offset of 1 between option_id (0-indexed) + // in the database and values (1-indexed) to avoid problems with + // transmitting 0 in an HTML form + // required, value, expected + array(1, '0', 'FIELD_INVALID_VALUE', 'Required field should throw error for out-of-range value'), + array(1, '1', 'FIELD_REQUIRED', 'Required field should throw error for default value'), + array(1, '2', false, 'Required field should accept non-default value'), + array(0, '0', 'FIELD_INVALID_VALUE', 'Optional field should throw error for out-of-range value'), + array(0, '1', false, 'Optional field should accept default value'), + array(0, '2', false, 'Optional field should accept non-default value'), + ); + } + + /** + * @dataProvider dropdownFields + */ + public function test_dropdown_validate($field_required, $field_value, $expected, $description) + { + global $db; + $db = $this->new_dbal(); + + $field_data = array( + 'field_id' => 1, + 'lang_id' => 1, + 'field_novalue' => 1, + 'field_required' => $field_required, + ); + + $cp = new custom_profile; + $result = $cp->validate_profile_field(FIELD_DROPDOWN, &$field_value, $field_data); + + $this->assertEquals($expected, $result, $description); + } +} diff --git a/tests/profile/fixtures/profile_fields.xml b/tests/profile/fixtures/profile_fields.xml new file mode 100644 index 0000000000..0b2929f625 --- /dev/null +++ b/tests/profile/fixtures/profile_fields.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_profile_fields_lang"> + <column>field_id</column> + <column>lang_id</column> + <column>option_id</column> + <column>field_type</column> + <column>lang_value</column> + <row> + <value>1</value> + <value>1</value> + <value>0</value> + <value>5</value> + <value>Default Option</value> + </row> + <row> + <value>1</value> + <value>1</value> + <value>1</value> + <value>5</value> + <value>First Alternative</value> + </row> + <row> + <value>1</value> + <value>1</value> + <value>2</value> + <value>5</value> + <value>Third Alternative</value> + </row> + </table> +</dataset> diff --git a/tests/utf/normalizer_test.php b/tests/utf/normalizer_test.php index 38b4ec1b6b..f78dba8004 100644 --- a/tests/utf/normalizer_test.php +++ b/tests/utf/normalizer_test.php @@ -298,12 +298,14 @@ class phpbb_utf_normalizer_test extends phpbb_test_case if (!$fpr = fopen($url, 'rb')) { - throw new RuntimeException("Failed to download $url"); + echo "Failed to download $url\n"; + return; } if (!$fpw = fopen($target, 'wb')) { - throw new RuntimeException("Failed to open $target for writing"); + echo "Failed to open $target for writing\n"; + return; } $chunk = 32768; diff --git a/tests/wrapper/gmgetdate_test.php b/tests/wrapper/gmgetdate_test.php new file mode 100644 index 0000000000..0b4c3378a9 --- /dev/null +++ b/tests/wrapper/gmgetdate_test.php @@ -0,0 +1,49 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_wrapper_gmgetdate_test extends phpbb_test_case +{ + public function test_gmgetdate() + { + $this->run_gmgetdate_assertion(); + $this->run_test_with_timezone('UTC'); + $this->run_test_with_timezone('Europe/Berlin'); + $this->run_test_with_timezone('America/Los_Angeles'); + $this->run_test_with_timezone('Antarctica/South_Pole'); + } + + protected function run_test_with_timezone($timezone_identifier) + { + $current_timezone = date_default_timezone_get(); + + date_default_timezone_set($timezone_identifier); + $this->run_gmgetdate_assertion(); + date_default_timezone_set($current_timezone); + } + + protected function run_gmgetdate_assertion() + { + $expected = time(); + + $date_array = phpbb_gmgetdate($expected); + + $actual = gmmktime( + $date_array['hours'], + $date_array['minutes'], + $date_array['seconds'], + $date_array['mon'], + $date_array['mday'], + $date_array['year'] + ); + + $this->assertEquals($expected, $actual); + } +} diff --git a/tests/wrapper/mt_rand_test.php b/tests/wrapper/mt_rand_test.php new file mode 100644 index 0000000000..c8bcb3d14c --- /dev/null +++ b/tests/wrapper/mt_rand_test.php @@ -0,0 +1,46 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_wrapper_mt_rand_test extends phpbb_test_case +{ + public function test_max_equals_min() + { + $result = phpbb_mt_rand(42, 42); + $this->assertEquals(42, $result); + } + + public function test_max_equals_min_negative() + { + $result = phpbb_mt_rand(-42, -42); + $this->assertEquals(-42, $result); + } + + public function test_max_greater_min() + { + $result = phpbb_mt_rand(3, 4); + $this->assertGreaterThanOrEqual(3, $result); + $this->assertLessThanOrEqual(4, $result); + } + + public function test_min_greater_max() + { + $result = phpbb_mt_rand(4, 3); + $this->assertGreaterThanOrEqual(3, $result); + $this->assertLessThanOrEqual(4, $result); + } + + public function test_min_greater_max_negative() + { + $result = phpbb_mt_rand(-3, -4); + $this->assertGreaterThanOrEqual(-4, $result); + $this->assertLessThanOrEqual(-3, $result); + } +} diff --git a/tests/wrapper/version_compare_test.php b/tests/wrapper/version_compare_test.php new file mode 100644 index 0000000000..f718cfd16b --- /dev/null +++ b/tests/wrapper/version_compare_test.php @@ -0,0 +1,130 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_wrapper_version_compare_test extends phpbb_test_case +{ + public function test_two_parameters() + { + $this->assertEquals(-1, phpbb_version_compare('1.0.0', '1.0.1')); + $this->assertEquals(0, phpbb_version_compare('1.0.0', '1.0.0')); + $this->assertEquals(1, phpbb_version_compare('1.0.1', '1.0.0')); + } + + public function test_three_parameters() + { + $this->assertEquals(true, phpbb_version_compare('1.0.0', '1.0.1', '<')); + $this->assertEquals(true, phpbb_version_compare('1.0.0', '1.0.0', '<=')); + $this->assertEquals(true, phpbb_version_compare('1.0.0', '1.0.0', '=')); + $this->assertEquals(true, phpbb_version_compare('1.0.0', '1.0.0', '>=')); + $this->assertEquals(true, phpbb_version_compare('1.0.1', '1.0.0', '>')); + } + + public function test_strict_order() + { + $releases = array( + '2.0.0', + '2.0.1', + // Those are not version_compare() compatible + //'2.0.6a', + //'2.0.6b', + //'2.0.6c', + //'2.0.6d', + '2.0.7', + '2.0.23', + '3.0.A1', + '3.0.A2', + '3.0.A3', + '3.0.B1', + '3.0.B2', + '3.0.B4', + '3.0.B5', + '3.0.RC1', + '3.0.RC5', + '3.0.0', + '3.0.1', + '3.0.2', + '3.0.7', + '3.0.7-PL1', + '3.0.8-RC1', + '3.0.8', + '3.0.9-dev', + '3.0.9-RC1', + '3.0.9-RC2', + '3.0.9-RC4', + '3.0.10-RC1', + '3.1-dev', + '3.2-A1', + ); + + for ($i = 0, $size = sizeof($releases); $i < $size - 1; ++$i) + { + $version1 = $releases[$i]; + $version2 = $releases[$i + 1]; + + $this->assertEquals( + true, + phpbb_version_compare($version1, $version2, '<'), + "Result of version comparison $version1 < $version2 is incorrect." + ); + } + } + + /** + * @dataProvider equality_test_data + */ + public function test_equality($version1, $version2) + { + $this->assertEquals( + 0, + phpbb_version_compare($version1, $version2), + "Result of version comparison $version1 = $version2 is incorrect." + ); + + $this->assertEquals( + true, + phpbb_version_compare($version1, $version2, '='), + "Result of version comparison $version1 = $version2 is incorrect." + ); + } + + public function equality_test_data() + { + return array( + array('1.1.0-A2', '1.1.0-a2'), + array('1.1.0-B1', '1.1.0-b1'), + ); + } + + /** + * @dataProvider alpha_beta_test_data + */ + public function test_alpha_beta($expected, $version1, $version2) + { + $this->assertEquals( + $expected, + phpbb_version_compare($version1, $version2), + "Result of version comparison ($version1, $version2) = $expected is incorrect." + ); + + } + + public function alpha_beta_test_data() + { + return array( + array(-1, '1.1.0-A2', '1.1.0-B1'), + array(-1, '1.1.0-a2', '1.1.0-b1'), + + array(-1, '1.1.0-a2', '1.1.0-B1'), + array(-1, '1.1.0-A2', '1.1.0-b1'), + ); + } + +} |