Merge remote-tracking branch 'phpbb/develop' into feature/softdelete-1-permission

* phpbb/develop: (704 commits)
  [ticket/11630] Improvements to the PHP lint pre-commit hook
  [feature/auth-refactor] Move auth providers to separate directory
  [ticket/11619] Use HTTP/1.0 because of lack of chunked-encoding handling.
  [ticket/11619] Some tests for get_remote_file().
  [ticket/11617] Remove spaces and tabs from empty lines
  [ticket/11617] Missing U_ACTION in acp_captcha.php
  [feature/auth-refactor] Fix code style issue
  [feature/auth-refactor] Fix comment grammar
  [feature/auth-refactor] Fix the actual cause of test failures
  [ticket/10838] Fix URL for wiki and remove irrelevant line
  [ticket/10838] Remove php 5.4 and builtin server references
  [ticket/10838] Fix missing data
  [ticket/10838] separate database used mentioned in unit tests
  [ticket/11585] Make $auth_admin class property
  [feature/auth-refactor] A possible fix for the functional test failures
  [ticket/11566] Subsilver template error displayed after table headers
  [ticket/11566] Remove extra pair of brackets from conditional statement
  [ticket/11566] Check that guest doesn't have reporting permission by default
  [ticket/11566] Add captcha to report post template in subsilver
  [ticket/11566] Use the new constant CONFIRM_REPORT for captcha init
  ...

Conflicts:
	phpBB/docs/sphinx.sample.conf
	phpBB/feed.php
	phpBB/styles/prosilver/template/search_results.html
	phpBB/styles/prosilver/template/viewforum_body.html
This commit is contained in:
Joas Schilling 2013-07-11 11:41:48 +02:00
commit bdb7ec0ceb
414 changed files with 15938 additions and 6165 deletions

View file

@ -9,25 +9,18 @@ env:
- DB=mysql - DB=mysql
- DB=postgres - DB=postgres
matrix:
allow_failures:
- php: 5.5
before_script: before_script:
- sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi" - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi" - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi"
- travis/install-php-extensions.sh - travis/install-php-extensions.sh
- pyrus set auto_discover 1
- pyrus install --force phpunit/DbUnit
- phpenv rehash
- cd phpBB - cd phpBB
- php ../composer.phar install --dev - php ../composer.phar install --dev --no-interaction --prefer-source
- cd .. - cd ..
- sh -c "if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.3.19', '>=');"` = "1" ]; then travis/setup-webserver.sh; fi" - sh -c "if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.3.19', '>=');"` = "1" ]; then travis/setup-webserver.sh; fi"
script: script:
- phpunit --configuration travis/phpunit-$DB-travis.xml - phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml
notifications: notifications:
email: email:

View file

@ -56,7 +56,8 @@
<target name="test" depends="clean,prepare,composer"> <target name="test" depends="clean,prepare,composer">
<exec dir="." <exec dir="."
command="phpunit --log-junit build/logs/phpunit.xml command="phpBB/vendor/bin/phpunit
--log-junit build/logs/phpunit.xml
--coverage-clover build/logs/clover.xml --coverage-clover build/logs/clover.xml
--coverage-html build/coverage" --coverage-html build/coverage"
passthru="true" /> passthru="true" />
@ -64,7 +65,8 @@
<target name="test-slow" depends="clean,prepare,composer"> <target name="test-slow" depends="clean,prepare,composer">
<exec dir="." <exec dir="."
command="phpunit --log-junit build/logs/phpunit.xml command="phpBB/vendor/bin/phpunit
--log-junit build/logs/phpunit.xml
--configuration phpunit.xml.all --configuration phpunit.xml.all
--group slow --group slow
--coverage-clover build/logs/clover-slow.xml --coverage-clover build/logs/clover-slow.xml

Binary file not shown.

View file

@ -33,9 +33,7 @@ else
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi fi
error=0
errors="" errors=""
if ! which "$PHP_BIN" >/dev/null 2>&1 if ! which "$PHP_BIN" >/dev/null 2>&1
then then
echo "PHP Syntax check failed:" echo "PHP Syntax check failed:"
@ -73,63 +71,18 @@ do
# check the staged file content for syntax errors # check the staged file content for syntax errors
# using php -l (lint) # using php -l (lint)
# note: if display_errors=stderr in php.ini, result=$(git cat-file -p $sha | "$PHP_BIN" -n -l -ddisplay_errors\=1 -derror_reporting\=E_ALL -dlog_errrors\=0 2>&1)
# parse errors are printed on stderr; otherwise
# they are printed on stdout.
# we filter everything other than parse errors
# with a grep below, therefore it should be safe
# to combine stdout and stderr in all circumstances
result=$(git cat-file -p $sha | "$PHP_BIN" -l 2>&1)
if [ $? -ne 0 ] if [ $? -ne 0 ]
then then
error=1
# Swap back in correct filenames # Swap back in correct filenames
errors=$(echo "$errors"; echo "$result" |sed -e "s@in - on@in $filename on@g") errors=$(echo "$errors"; echo "$result" | grep ':' | sed -e "s@in - on@in $filename on@g")
fi fi
done done
unset IFS unset IFS
if [ $error -eq 1 ] if [ -n "$errors" ]
then then
echo "PHP Syntax check failed: " echo "PHP Syntax check failed: "
# php "display errors" (display_errors php.ini value) $echo_e "$errors"
# and "log errors" (log_errors php.ini value).
# these are independent settings - see main/main.c in php source.
# the "log errors" setting produces output which
# starts with "PHP Parse error:"; the "display errors"
# setting produces output starting with "Parse error:".
# if both are turned on php dumps the parse error twice.
# therefore here we try to grep for one version and
# if that yields no results grep for the other version.
#
# other fun php facts:
#
# 1. in cli, display_errors and log_errors have different
# destinations by default. display_errors prints to
# standard output and log_errors prints to standard error.
# whether these destinations make sense is left
# as an exercise for the reader.
# 2. as mentioned above, with all output turned on
# php will print parse errors twice, one time on stdout
# and one time on stderr.
# 3. it is possible to set both display_errors and log_errors
# to off. if this is done php will print the text
# "Errors parsing <file>" but will not say what
# the errors are. useful behavior, this.
# 4. on my system display_errors defaults to on and
# log_errors defaults to off, therefore providing
# by default one copy of messages. your mileage may vary.
# 5. by setting display_errors=stderr and log_errors=on,
# both sets of messages will be printed on stderr.
# 6. php-cgi binary, given display_errors=stderr and
# log_errors=on, still prints both sets of messages
# on stderr, but formats one set as an html fragment.
# 7. your entry here? ;)
$echo_e "$errors" | grep "^Parse error:"
if [ $? -ne 0 ]
then
# match failed
$echo_e "$errors" | grep "^PHP Parse error:"
fi
exit 1 exit 1
fi fi

View file

@ -78,12 +78,12 @@ function work($pull_id, $remote)
add_remote($pull_user, 'phpbb3'); add_remote($pull_user, 'phpbb3');
run("git fetch $pull_user"); run("git fetch $pull_user");
run("git merge --no-ff $pull_user/$pull_branch"); run("git merge --no-ff $pull_user/$pull_branch");
run("phpunit"); run("phpBB/vendor/bin/phpunit");
run("git checkout develop"); run("git checkout develop");
run("git pull $remote develop"); run("git pull $remote develop");
run("git merge --no-ff develop-olympus"); run("git merge --no-ff develop-olympus");
run("phpunit"); run("phpBB/vendor/bin/phpunit");
break; break;
case 'develop': case 'develop':
@ -93,7 +93,7 @@ function work($pull_id, $remote)
add_remote($pull_user, 'phpbb3'); add_remote($pull_user, 'phpbb3');
run("git fetch $pull_user"); run("git fetch $pull_user");
run("git merge --no-ff $pull_user/$pull_branch"); run("git merge --no-ff $pull_user/$pull_branch");
run("phpunit"); run("phpBB/vendor/bin/phpunit");
break; break;
default: default:
@ -124,19 +124,34 @@ function get_repository_url($username, $repository, $ssh = false)
function api_request($query) function api_request($query)
{ {
$contents = file_get_contents("http://github.com/api/v2/json/$query"); return api_url_request("https://api.github.com/$query?per_page=100");
}
function api_url_request($url)
{
$contents = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'header' => "User-Agent: phpBB/1.0\r\n",
),
)));
if ($contents === false) if ($contents === false)
{ {
throw new RuntimeException("Error: failed to retrieve pull request data\n", 4); throw new RuntimeException("Error: failed to retrieve pull request data\n", 4);
} }
$contents = json_decode($contents);
return json_decode($contents); if (isset($contents->message) && strpos($contents->message, 'API Rate Limit') === 0)
{
throw new RuntimeException('Reached github API Rate Limit. Please try again later' . "\n", 4);
}
return $contents;
} }
function get_pull($username, $repository, $pull_id) function get_pull($username, $repository, $pull_id)
{ {
$request = api_request("pulls/$username/$repository/$pull_id"); $request = api_request("repos/$username/$repository/pulls/$pull_id");
$pull = $request->pull; $pull = $request->pull;

View file

@ -15,14 +15,14 @@ function show_usage()
echo "$filename adds repositories of a github network as remotes to a local git repository.\n"; echo "$filename adds repositories of a github network as remotes to a local git repository.\n";
echo "\n"; echo "\n";
echo "Usage: [php] $filename -s collaborators|organisation|contributors|network [OPTIONS]\n"; echo "Usage: [php] $filename -s collaborators|organisation|contributors|forks [OPTIONS]\n";
echo "\n"; echo "\n";
echo "Scopes:\n"; echo "Scopes:\n";
echo " collaborators Repositories of people who have push access to the specified repository\n"; echo " collaborators Repositories of people who have push access to the specified repository\n";
echo " contributors Repositories of people who have contributed to the specified repository\n"; echo " contributors Repositories of people who have contributed to the specified repository\n";
echo " organisation Repositories of members of the organisation at github\n"; echo " organisation Repositories of members of the organisation at github\n";
echo " network All repositories of the whole github network\n"; echo " forks All repositories of the whole github network\n";
echo "\n"; echo "\n";
echo "Options:\n"; echo "Options:\n";
@ -55,31 +55,31 @@ exit(work($scope, $username, $repository, $developer));
function work($scope, $username, $repository, $developer) function work($scope, $username, $repository, $developer)
{ {
// Get some basic data // Get some basic data
$network = get_network($username, $repository); $forks = get_forks($username, $repository);
$collaborators = get_collaborators($username, $repository); $collaborators = get_collaborators($username, $repository);
if ($network === false || $collaborators === false) if ($forks === false || $collaborators === false)
{ {
echo "Error: failed to retrieve network or collaborators\n"; echo "Error: failed to retrieve forks or collaborators\n";
return 1; return 1;
} }
switch ($scope) switch ($scope)
{ {
case 'collaborators': case 'collaborators':
$remotes = array_intersect_key($network, $collaborators); $remotes = array_intersect_key($forks, $collaborators);
break; break;
case 'organisation': case 'organisation':
$remotes = array_intersect_key($network, get_organisation_members($username)); $remotes = array_intersect_key($forks, get_organisation_members($username));
break; break;
case 'contributors': case 'contributors':
$remotes = array_intersect_key($network, get_contributors($username, $repository)); $remotes = array_intersect_key($forks, get_contributors($username, $repository));
break; break;
case 'network': case 'forks':
$remotes = $network; $remotes = $forks;
break; break;
default: default:
@ -145,26 +145,66 @@ function get_repository_url($username, $repository, $ssh = false)
function api_request($query) function api_request($query)
{ {
$contents = file_get_contents("http://github.com/api/v2/json/$query"); return api_url_request("https://api.github.com/$query?per_page=100");
}
function api_url_request($url)
{
$contents = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'header' => "User-Agent: phpBB/1.0\r\n",
),
)));
$sub_request_result = array();
// Check headers for pagination links
if (!empty($http_response_header))
{
foreach ($http_response_header as $header_element)
{
// Find Link Header which gives us a link to the next page
if (strpos($header_element, 'Link: ') === 0)
{
list($head, $header_content) = explode(': ', $header_element);
foreach (explode(', ', $header_content) as $links)
{
list($url, $rel) = explode('; ', $links);
if ($rel == 'rel="next"')
{
// Found a next link, follow it and merge the results
$sub_request_result = api_url_request(substr($url, 1, -1));
}
}
}
}
}
if ($contents === false) if ($contents === false)
{ {
return false; return false;
} }
return json_decode($contents); $contents = json_decode($contents);
if (isset($contents->message) && strpos($contents->message, 'API Rate Limit') === 0)
{
throw new RuntimeException('Reached github API Rate Limit. Please try again later' . "\n", 4);
}
return ($sub_request_result) ? array_merge($sub_request_result, $contents) : $contents;
} }
function get_contributors($username, $repository) function get_contributors($username, $repository)
{ {
$request = api_request("repos/show/$username/$repository/contributors"); $request = api_request("repos/$username/$repository/stats/contributors");
if ($request === false) if ($request === false)
{ {
return false; return false;
} }
$usernames = array(); $usernames = array();
foreach ($request->contributors as $contributor) foreach ($request as $contribution)
{ {
$usernames[$contributor->login] = $contributor->login; $usernames[$contribution->author->login] = $contribution->author->login;
} }
return $usernames; return $usernames;
@ -172,14 +212,14 @@ function get_contributors($username, $repository)
function get_organisation_members($username) function get_organisation_members($username)
{ {
$request = api_request("organizations/$username/public_members"); $request = api_request("orgs/$username/public_members");
if ($request === false) if ($request === false)
{ {
return false; return false;
} }
$usernames = array(); $usernames = array();
foreach ($request->users as $member) foreach ($request as $member)
{ {
$usernames[$member->login] = $member->login; $usernames[$member->login] = $member->login;
} }
@ -189,35 +229,35 @@ function get_organisation_members($username)
function get_collaborators($username, $repository) function get_collaborators($username, $repository)
{ {
$request = api_request("repos/show/$username/$repository/collaborators"); $request = api_request("repos/$username/$repository/collaborators");
if ($request === false) if ($request === false)
{ {
return false; return false;
} }
$usernames = array(); $usernames = array();
foreach ($request->collaborators as $collaborator) foreach ($request as $collaborator)
{ {
$usernames[$collaborator] = $collaborator; $usernames[$collaborator->login] = $collaborator->login;
} }
return $usernames; return $usernames;
} }
function get_network($username, $repository) function get_forks($username, $repository)
{ {
$request = api_request("repos/show/$username/$repository/network"); $request = api_request("repos/$username/$repository/forks");
if ($request === false) if ($request === false)
{ {
return false; return false;
} }
$usernames = array(); $usernames = array();
foreach ($request->network as $network) foreach ($request as $fork)
{ {
$usernames[$network->owner] = array( $usernames[$fork->owner->login] = array(
'username' => $network->owner, 'username' => $fork->owner->login,
'repository' => $network->name, 'repository' => $fork->name,
); );
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -152,7 +152,7 @@
</dl> </dl>
<dl> <dl>
<dt><label for="forum_desc">{L_FORUM_DESC}{L_COLON}</label><br /><span>{L_FORUM_DESC_EXPLAIN}</span></dt> <dt><label for="forum_desc">{L_FORUM_DESC}{L_COLON}</label><br /><span>{L_FORUM_DESC_EXPLAIN}</span></dt>
<dd><textarea id="forum_desc" name="forum_desc" rows="5" cols="45">{FORUM_DESC}</textarea></dd> <dd><textarea id="forum_desc" name="forum_desc" rows="5" cols="45" data-bbcode="true">{FORUM_DESC}</textarea></dd>
<dd><label><input type="checkbox" class="radio" name="desc_parse_bbcode"<!-- IF S_DESC_BBCODE_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_BBCODE}</label> <dd><label><input type="checkbox" class="radio" name="desc_parse_bbcode"<!-- IF S_DESC_BBCODE_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_BBCODE}</label>
<label><input type="checkbox" class="radio" name="desc_parse_smilies"<!-- IF S_DESC_SMILIES_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_SMILIES}</label> <label><input type="checkbox" class="radio" name="desc_parse_smilies"<!-- IF S_DESC_SMILIES_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_SMILIES}</label>
<label><input type="checkbox" class="radio" name="desc_parse_urls"<!-- IF S_DESC_URLS_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_URLS}</label></dd> <label><input type="checkbox" class="radio" name="desc_parse_urls"<!-- IF S_DESC_URLS_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_URLS}</label></dd>
@ -239,7 +239,7 @@
</dl> </dl>
<dl> <dl>
<dt><label for="topics_per_page">{L_FORUM_TOPICS_PAGE}{L_COLON}</label><br /><span>{L_FORUM_TOPICS_PAGE_EXPLAIN}</span></dt> <dt><label for="topics_per_page">{L_FORUM_TOPICS_PAGE}{L_COLON}</label><br /><span>{L_FORUM_TOPICS_PAGE_EXPLAIN}</span></dt>
<dd><input type="text" id="topics_per_page" name="topics_per_page" value="{TOPICS_PER_PAGE}" size="4" maxlength="4" /></dd> <dd><input type="number" id="topics_per_page" name="topics_per_page" value="{TOPICS_PER_PAGE}" size="4" maxlength="4" min="0" max="9999" /></dd>
</dl> </dl>
<!-- EVENT acp_forums_normal_settings_append --> <!-- EVENT acp_forums_normal_settings_append -->
</fieldset> </fieldset>
@ -253,15 +253,15 @@
</dl> </dl>
<dl> <dl>
<dt><label for="prune_freq">{L_AUTO_PRUNE_FREQ}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_FREQ_EXPLAIN}</span></dt> <dt><label for="prune_freq">{L_AUTO_PRUNE_FREQ}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_FREQ_EXPLAIN}</span></dt>
<dd><input type="text" id="prune_freq" name="prune_freq" value="{PRUNE_FREQ}" maxlength="4" size="4" /> {L_DAYS}</dd> <dd><input type="number" id="prune_freq" name="prune_freq" value="{PRUNE_FREQ}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="prune_days">{L_AUTO_PRUNE_DAYS}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_DAYS_EXPLAIN}</span></dt> <dt><label for="prune_days">{L_AUTO_PRUNE_DAYS}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_DAYS_EXPLAIN}</span></dt>
<dd><input type="text" id="prune_days" name="prune_days" value="{PRUNE_DAYS}" maxlength="4" size="4" /> {L_DAYS}</dd> <dd><input type="number" id="prune_days" name="prune_days" value="{PRUNE_DAYS}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="prune_viewed">{L_AUTO_PRUNE_VIEWED}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_VIEWED_EXPLAIN}</span></dt> <dt><label for="prune_viewed">{L_AUTO_PRUNE_VIEWED}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_VIEWED_EXPLAIN}</span></dt>
<dd><input type="text" id="prune_viewed" name="prune_viewed" value="{PRUNE_VIEWED}" maxlength="4" size="4" /> {L_DAYS}</dd> <dd><input type="number" id="prune_viewed" name="prune_viewed" value="{PRUNE_VIEWED}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="prune_old_polls">{L_PRUNE_OLD_POLLS}{L_COLON}</label><br /><span>{L_PRUNE_OLD_POLLS_EXPLAIN}</span></dt> <dt><label for="prune_old_polls">{L_PRUNE_OLD_POLLS}{L_COLON}</label><br /><span>{L_PRUNE_OLD_POLLS_EXPLAIN}</span></dt>
@ -316,7 +316,7 @@
<!-- ENDIF --> <!-- ENDIF -->
<dl> <dl>
<dt><label for="forum_rules">{L_FORUM_RULES}{L_COLON}</label><br /><span>{L_FORUM_RULES_EXPLAIN}</span></dt> <dt><label for="forum_rules">{L_FORUM_RULES}{L_COLON}</label><br /><span>{L_FORUM_RULES_EXPLAIN}</span></dt>
<dd><textarea id="forum_rules" name="forum_rules" rows="4" cols="70">{FORUM_RULES_PLAIN}</textarea></dd> <dd><textarea id="forum_rules" name="forum_rules" rows="4" cols="70" data-bbcode="true">{FORUM_RULES_PLAIN}</textarea></dd>
<dd><label><input type="checkbox" class="radio" name="rules_parse_bbcode"<!-- IF S_BBCODE_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_BBCODE}</label> <dd><label><input type="checkbox" class="radio" name="rules_parse_bbcode"<!-- IF S_BBCODE_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_BBCODE}</label>
<label><input type="checkbox" class="radio" name="rules_parse_smilies"<!-- IF S_SMILIES_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_SMILIES}</label> <label><input type="checkbox" class="radio" name="rules_parse_smilies"<!-- IF S_SMILIES_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_SMILIES}</label>
<label><input type="checkbox" class="radio" name="rules_parse_urls"<!-- IF S_URLS_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_URLS}</label></dd> <label><input type="checkbox" class="radio" name="rules_parse_urls"<!-- IF S_URLS_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_URLS}</label></dd>

View file

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

View file

@ -108,8 +108,8 @@
<td><input class="text post" type="text" name="code[{items.IMG}]" value="{items.CODE}" size="10" maxlength="50" /></td> <td><input class="text post" type="text" name="code[{items.IMG}]" value="{items.CODE}" size="10" maxlength="50" /></td>
<td><input class="text post" type="text" name="emotion[{items.IMG}]" value="{items.EMOTION}" size="10" maxlength="50" /></td> <td><input class="text post" type="text" name="emotion[{items.IMG}]" value="{items.EMOTION}" size="10" maxlength="50" /></td>
<!-- ENDIF --> <!-- ENDIF -->
<td><input class="text post" type="text" size="3" name="width[{items.IMG}]" value="{items.WIDTH}" /></td> <td><input class="text post" type="number" size="3" name="width[{items.IMG}]" value="{items.WIDTH}" /></td>
<td><input class="text post" type="text" size="3" name="height[{items.IMG}]" value="{items.HEIGHT}" /></td> <td><input class="text post" type="number" size="3" name="height[{items.IMG}]" value="{items.HEIGHT}" /></td>
<td> <td>
<input type="checkbox" class="radio" name="display_on_posting[{items.IMG}]"{items.POSTING_CHECKED} onclick="toggle_select('{items.A_IMG}', this.checked, '{items.S_ROW_COUNT}');"/> <input type="checkbox" class="radio" name="display_on_posting[{items.IMG}]"{items.POSTING_CHECKED} onclick="toggle_select('{items.A_IMG}', this.checked, '{items.S_ROW_COUNT}');"/>
<!-- IF items.S_ID --> <!-- IF items.S_ID -->
@ -136,8 +136,8 @@
<td style="vertical-align: top;"><img src="{IMG_SRC}" id="add_image_src" alt="" title="" /></td> <td style="vertical-align: top;"><img src="{IMG_SRC}" id="add_image_src" alt="" title="" /></td>
<td><input class="text post" type="text" name="add_code" id="add_code" value="{CODE}" size="10" maxlength="50" /></td> <td><input class="text post" type="text" name="add_code" id="add_code" value="{CODE}" size="10" maxlength="50" /></td>
<td><input class="text post" type="text" name="add_emotion" id="add_emotion" value="{EMOTION}" size="10" maxlength="50" /></td> <td><input class="text post" type="text" name="add_emotion" id="add_emotion" value="{EMOTION}" size="10" maxlength="50" /></td>
<td><input class="text post" type="text" size="3" name="add_width" id="add_width" value="{WIDTH}" /></td> <td><input class="text post" type="number" size="3" name="add_width" id="add_width" value="{WIDTH}" /></td>
<td><input class="text post" type="text" size="3" name="add_height" id="add_height" value="{HEIGHT}" /></td> <td><input class="text post" type="number" size="3" name="add_height" id="add_height" value="{HEIGHT}" /></td>
<td><input type="checkbox" class="radio" name="add_display_on_posting" checked="checked" onclick="toggle_select('add', this.checked, 'add_order');"/></td> <td><input type="checkbox" class="radio" name="add_display_on_posting" checked="checked" onclick="toggle_select('add', this.checked, 'add_order');"/></td>
<td><select id="order_add_order" name="add_order"> <td><select id="order_add_order" name="add_order">
<optgroup id="order_disp_add_order" label="{L_DISPLAY_POSTING}">{S_ADD_ORDER_LIST_DISPLAY}</optgroup> <optgroup id="order_disp_add_order" label="{L_DISPLAY_POSTING}">{S_ADD_ORDER_LIST_DISPLAY}</optgroup>
@ -243,8 +243,8 @@
<td style="text-align: center;">{items.EMOTION}</td> <td style="text-align: center;">{items.EMOTION}</td>
<!-- ENDIF --> <!-- ENDIF -->
<td style="text-align: right; white-space: nowrap;"> <td style="text-align: right; white-space: nowrap;">
<!-- IF items.S_FIRST_ROW and not PREVIOUS_PAGE -->{ICON_MOVE_UP_DISABLED}<!-- ELSE --><a href="{items.U_MOVE_UP}">{ICON_MOVE_UP}</a><!-- ENDIF -->&nbsp; <!-- IF items.S_FIRST_ROW and not U_PREVIOUS_PAGE -->{ICON_MOVE_UP_DISABLED}<!-- ELSE --><a href="{items.U_MOVE_UP}">{ICON_MOVE_UP}</a><!-- ENDIF -->&nbsp;
<!-- IF items.S_LAST_ROW and not NEXT_PAGE -->{ICON_MOVE_DOWN_DISABLED}<!-- ELSE --><a href="{items.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a><!-- ENDIF --> <!-- IF items.S_LAST_ROW and not U_NEXT_PAGE -->{ICON_MOVE_DOWN_DISABLED}<!-- ELSE --><a href="{items.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a><!-- ENDIF -->
&nbsp;<a href="{items.U_EDIT}">{ICON_EDIT}</a> <a href="{items.U_DELETE}" data-ajax="row_delete">{ICON_DELETE}</a> &nbsp;<a href="{items.U_EDIT}">{ICON_EDIT}</a> <a href="{items.U_DELETE}" data-ajax="row_delete">{ICON_DELETE}</a>
</td> </td>
</tr> </tr>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -12,7 +12,7 @@
</dl> </dl>
<dl> <dl>
<dt><label for="msn">{L_UCP_MSNM}{L_COLON}</label></dt> <dt><label for="msn">{L_UCP_MSNM}{L_COLON}</label></dt>
<dd><input type="text" id="msn" name="msn" value="{MSN}" /></dd> <dd><input type="email" id="msn" name="msn" value="{MSN}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="yim">{L_UCP_YIM}{L_COLON}</label></dt> <dt><label for="yim">{L_UCP_YIM}{L_COLON}</label></dt>
@ -20,11 +20,11 @@
</dl> </dl>
<dl> <dl>
<dt><label for="jabber">{L_UCP_JABBER}{L_COLON}</label></dt> <dt><label for="jabber">{L_UCP_JABBER}{L_COLON}</label></dt>
<dd><input type="text" id="jabber" name="jabber" value="{JABBER}" /></dd> <dd><input type="email" id="jabber" name="jabber" value="{JABBER}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="website">{L_WEBSITE}{L_COLON}</label></dt> <dt><label for="website">{L_WEBSITE}{L_COLON}</label></dt>
<dd><input type="text" id="website" name="website" value="{WEBSITE}" /></dd> <dd><input type="url" id="website" name="website" value="{WEBSITE}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="location">{L_LOCATION}{L_COLON}</label></dt> <dt><label for="location">{L_LOCATION}{L_COLON}</label></dt>

View file

@ -92,7 +92,7 @@
// ]]> // ]]>
</script> </script>
</dt> </dt>
<dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 90px;"><textarea name="signature" rows="10" cols="60" style="width: 95%;" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();">{SIGNATURE}</textarea></dd> <dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 90px;"><textarea name="signature" rows="10" cols="60" style="width: 95%;" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();" data-bbcode="true">{SIGNATURE}</textarea></dd>
<dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 90px; margin-top: 5px;"> <dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 90px; margin-top: 5px;">
<!-- IF S_BBCODE_ALLOWED --> <!-- IF S_BBCODE_ALLOWED -->
<label><input type="checkbox" class="radio" name="disable_bbcode"{S_BBCODE_CHECKED} /> {L_DISABLE_BBCODE}</label> <label><input type="checkbox" class="radio" name="disable_bbcode"{S_BBCODE_CHECKED} /> {L_DISABLE_BBCODE}</label>

View file

@ -115,9 +115,9 @@ phpbb.addAjaxCallback('activate_deactivate', function(res) {
el.text(res.text); el.text(res.text);
if (newHref.indexOf('deactivate') !== -1) { if (newHref.indexOf('deactivate') !== -1) {
newHref = newHref.replace('deactivate', 'activate') newHref = newHref.replace('deactivate', 'activate');
} else { } else {
newHref = newHref.replace('activate', 'deactivate') newHref = newHref.replace('activate', 'deactivate');
} }
el.attr('href', newHref); el.attr('href', newHref);
@ -148,6 +148,12 @@ $('[data-ajax]').each(function() {
} }
}); });
/**
* Automatically resize textarea
*/
$(document).ready(function() {
phpbb.resizeTextArea($('textarea:not(.no-auto-resize)'), {minHeight: 75});
});
})(jQuery); // Avoid conflicts with other libraries })(jQuery); // Avoid conflicts with other libraries

View file

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

View file

@ -10,18 +10,16 @@ var theSelection = false;
// Check for Browser & Platform for PC & IE specific bits // Check for Browser & Platform for PC & IE specific bits
// More details from: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html // More details from: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html
var clientPC = navigator.userAgent.toLowerCase(); // Get client info var clientPC = navigator.userAgent.toLowerCase(); // Get client info
var clientVer = parseInt(navigator.appVersion); // Get browser version var clientVer = parseInt(navigator.appVersion, 10); // Get browser version
var is_ie = ((clientPC.indexOf('msie') != -1) && (clientPC.indexOf('opera') == -1));
var is_win = ((clientPC.indexOf('win') != -1) || (clientPC.indexOf('16bit') != -1));
var is_ie = ((clientPC.indexOf('msie') !== -1) && (clientPC.indexOf('opera') === -1));
var is_win = ((clientPC.indexOf('win') !== -1) || (clientPC.indexOf('16bit') !== -1));
var baseHeight; var baseHeight;
/** /**
* Shows the help messages in the helpline window * Shows the help messages in the helpline window
*/ */
function helpline(help) function helpline(help) {
{
document.forms[form_name].helpbox.value = help_line[help]; document.forms[form_name].helpbox.value = help_line[help];
} }
@ -29,26 +27,22 @@ function helpline(help)
* Fix a bug involving the TextRange object. From * Fix a bug involving the TextRange object. From
* http://www.frostjedi.com/terra/scripts/demo/caretBug.html * http://www.frostjedi.com/terra/scripts/demo/caretBug.html
*/ */
function initInsertions() function initInsertions() {
{
var doc; var doc;
if(document.forms[form_name])
{ if (document.forms[form_name]) {
doc = document; doc = document;
} } else {
else
{
doc = opener.document; doc = opener.document;
} }
var textarea = doc.forms[form_name].elements[text_name]; var textarea = doc.forms[form_name].elements[text_name];
if (is_ie && typeof(baseHeight) != 'number')
{ if (is_ie && typeof(baseHeight) !== 'number') {
textarea.focus(); textarea.focus();
baseHeight = doc.selection.createRange().duplicate().boundingHeight; baseHeight = doc.selection.createRange().duplicate().boundingHeight;
if (!document.forms[form_name]) if (!document.forms[form_name]) {
{
document.body.focus(); document.body.focus();
} }
} }
@ -57,14 +51,10 @@ function initInsertions()
/** /**
* bbstyle * bbstyle
*/ */
function bbstyle(bbnumber) function bbstyle(bbnumber) {
{ if (bbnumber !== -1) {
if (bbnumber != -1)
{
bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]); bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]);
} } else {
else
{
insert_text('[*]'); insert_text('[*]');
document.forms[form_name].elements[text_name].focus(); document.forms[form_name].elements[text_name].focus();
} }
@ -73,30 +63,26 @@ function bbstyle(bbnumber)
/** /**
* Apply bbcodes * Apply bbcodes
*/ */
function bbfontstyle(bbopen, bbclose) function bbfontstyle(bbopen, bbclose) {
{
theSelection = false; theSelection = false;
var textarea = document.forms[form_name].elements[text_name]; var textarea = document.forms[form_name].elements[text_name];
textarea.focus(); textarea.focus();
if ((clientVer >= 4) && is_ie && is_win) if ((clientVer >= 4) && is_ie && is_win) {
{
// Get text selection // Get text selection
theSelection = document.selection.createRange().text; theSelection = document.selection.createRange().text;
if (theSelection) if (theSelection) {
{
// Add tags around selection // Add tags around selection
document.selection.createRange().text = bbopen + theSelection + bbclose; document.selection.createRange().text = bbopen + theSelection + bbclose;
document.forms[form_name].elements[text_name].focus(); document.forms[form_name].elements[text_name].focus();
theSelection = ''; theSelection = '';
return; return;
} }
} } else if (document.forms[form_name].elements[text_name].selectionEnd
else if (document.forms[form_name].elements[text_name].selectionEnd && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) {
{
mozWrap(document.forms[form_name].elements[text_name], bbopen, bbclose); mozWrap(document.forms[form_name].elements[text_name], bbopen, bbclose);
document.forms[form_name].elements[text_name].focus(); document.forms[form_name].elements[text_name].focus();
theSelection = ''; theSelection = '';
@ -112,14 +98,12 @@ function bbfontstyle(bbopen, bbclose)
// Center the cursor when we don't have a selection // Center the cursor when we don't have a selection
// Gecko and proper browsers // Gecko and proper browsers
if (!isNaN(textarea.selectionStart)) if (!isNaN(textarea.selectionStart)) {
{
textarea.selectionStart = new_pos; textarea.selectionStart = new_pos;
textarea.selectionEnd = new_pos; textarea.selectionEnd = new_pos;
} }
// IE // IE
else if (document.selection) else if (document.selection) {
{
var range = textarea.createTextRange(); var range = textarea.createTextRange();
range.move("character", new_pos); range.move("character", new_pos);
range.select(); range.select();
@ -133,62 +117,47 @@ function bbfontstyle(bbopen, bbclose)
/** /**
* Insert text at position * Insert text at position
*/ */
function insert_text(text, spaces, popup) function insert_text(text, spaces, popup) {
{
var textarea; var textarea;
if (!popup) if (!popup) {
{
textarea = document.forms[form_name].elements[text_name]; textarea = document.forms[form_name].elements[text_name];
} } else {
else
{
textarea = opener.document.forms[form_name].elements[text_name]; textarea = opener.document.forms[form_name].elements[text_name];
} }
if (spaces) if (spaces) {
{
text = ' ' + text + ' '; text = ' ' + text + ' ';
} }
if (!isNaN(textarea.selectionStart)) if (!isNaN(textarea.selectionStart)) {
{
var sel_start = textarea.selectionStart; var sel_start = textarea.selectionStart;
var sel_end = textarea.selectionEnd; var sel_end = textarea.selectionEnd;
mozWrap(textarea, text, ''); mozWrap(textarea, text, '');
textarea.selectionStart = sel_start + text.length; textarea.selectionStart = sel_start + text.length;
textarea.selectionEnd = sel_end + text.length; textarea.selectionEnd = sel_end + text.length;
} } else if (textarea.createTextRange && textarea.caretPos) {
if (baseHeight !== textarea.caretPos.boundingHeight) {
else if (textarea.createTextRange && textarea.caretPos)
{
if (baseHeight != textarea.caretPos.boundingHeight)
{
textarea.focus(); textarea.focus();
storeCaret(textarea); storeCaret(textarea);
} }
var caret_pos = textarea.caretPos;
caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) == ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text;
} var caret_pos = textarea.caretPos;
else caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text;
{ } else {
textarea.value = textarea.value + text; textarea.value = textarea.value + text;
} }
if (!popup) if (!popup) {
{
textarea.focus(); textarea.focus();
} }
} }
/** /**
* Add inline attachment at position * Add inline attachment at position
*/ */
function attach_inline(index, filename) function attach_inline(index, filename) {
{
insert_text('[attachment=' + index + ']' + filename + '[/attachment]'); insert_text('[attachment=' + index + ']' + filename + '[/attachment]');
document.forms[form_name].elements[text_name].focus(); document.forms[form_name].elements[text_name].focus();
} }
@ -202,56 +171,39 @@ function addquote(post_id, username)
var theSelection = ''; var theSelection = '';
var divarea = false; var divarea = false;
if (document.all) if (document.all) {
{
divarea = document.all[message_name]; divarea = document.all[message_name];
} } else {
else
{
divarea = document.getElementById(message_name); divarea = document.getElementById(message_name);
} }
// Get text selection - not only the post content :( // Get text selection - not only the post content :(
if (window.getSelection) if (window.getSelection) {
{
theSelection = window.getSelection().toString(); theSelection = window.getSelection().toString();
} } else if (document.getSelection) {
else if (document.getSelection)
{
theSelection = document.getSelection(); theSelection = document.getSelection();
} } else if (document.selection) {
else if (document.selection)
{
theSelection = document.selection.createRange().text; theSelection = document.selection.createRange().text;
} }
if (theSelection == '' || typeof theSelection == 'undefined' || theSelection == null) if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) {
{ if (divarea.innerHTML) {
if (divarea.innerHTML)
{
theSelection = divarea.innerHTML.replace(/<br>/ig, '\n'); theSelection = divarea.innerHTML.replace(/<br>/ig, '\n');
theSelection = theSelection.replace(/<br\/>/ig, '\n'); theSelection = theSelection.replace(/<br\/>/ig, '\n');
theSelection = theSelection.replace(/&lt\;/ig, '<'); theSelection = theSelection.replace(/&lt\;/ig, '<');
theSelection = theSelection.replace(/&gt\;/ig, '>'); theSelection = theSelection.replace(/&gt\;/ig, '>');
theSelection = theSelection.replace(/&amp\;/ig, '&'); theSelection = theSelection.replace(/&amp\;/ig, '&');
theSelection = theSelection.replace(/&nbsp\;/ig, ' '); theSelection = theSelection.replace(/&nbsp\;/ig, ' ');
} } else if (document.all) {
else if (document.all)
{
theSelection = divarea.innerText; theSelection = divarea.innerText;
} } else if (divarea.textContent) {
else if (divarea.textContent)
{
theSelection = divarea.textContent; theSelection = divarea.textContent;
} } else if (divarea.firstChild.nodeValue) {
else if (divarea.firstChild.nodeValue)
{
theSelection = divarea.firstChild.nodeValue; theSelection = divarea.firstChild.nodeValue;
} }
} }
if (theSelection) if (theSelection) {
{
insert_text('[quote="' + username + '"]' + theSelection + '[/quote]'); insert_text('[quote="' + username + '"]' + theSelection + '[/quote]');
} }
@ -261,15 +213,13 @@ function addquote(post_id, username)
/** /**
* From http://www.massless.org/mozedit/ * From http://www.massless.org/mozedit/
*/ */
function mozWrap(txtarea, open, close) function mozWrap(txtarea, open, close) {
{ var selLength = (typeof(txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength;
var selLength = (typeof(txtarea.textLength) == 'undefined') ? txtarea.value.length : txtarea.textLength;
var selStart = txtarea.selectionStart; var selStart = txtarea.selectionStart;
var selEnd = txtarea.selectionEnd; var selEnd = txtarea.selectionEnd;
var scrollTop = txtarea.scrollTop; var scrollTop = txtarea.scrollTop;
if (selEnd == 1 || selEnd == 2) if (selEnd === 1 || selEnd === 2) {
{
selEnd = selLength; selEnd = selLength;
} }
@ -290,10 +240,8 @@ function mozWrap(txtarea, open, close)
* Insert at Caret position. Code from * Insert at Caret position. Code from
* http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130 * http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130
*/ */
function storeCaret(textEl) function storeCaret(textEl) {
{ if (textEl.createTextRange) {
if (textEl.createTextRange)
{
textEl.caretPos = document.selection.createRange().duplicate(); textEl.caretPos = document.selection.createRange().duplicate();
} }
} }
@ -301,8 +249,7 @@ function storeCaret(textEl)
/** /**
* Color pallette * Color pallette
*/ */
function colorPalette(dir, width, height) function colorPalette(dir, width, height) {
{
var r = 0, g = 0, b = 0; var r = 0, g = 0, b = 0;
var numberList = new Array(6); var numberList = new Array(6);
var color = ''; var color = '';
@ -315,69 +262,56 @@ function colorPalette(dir, width, height)
document.writeln('<table class="type2">'); document.writeln('<table class="type2">');
for (r = 0; r < 5; r++) for (r = 0; r < 5; r++) {
{ if (dir === 'h') {
if (dir == 'h')
{
document.writeln('<tr>'); document.writeln('<tr>');
} }
for (g = 0; g < 5; g++) for (g = 0; g < 5; g++) {
{ if (dir === 'v') {
if (dir == 'v')
{
document.writeln('<tr>'); document.writeln('<tr>');
} }
for (b = 0; b < 5; b++) for (b = 0; b < 5; b++) {
{
color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]);
document.write('<td bgcolor="#' + color + '" style="width: ' + width + 'px; height: ' + height + 'px;">'); document.write('<td bgcolor="#' + color + '" style="width: ' + width + 'px; height: ' + height + 'px;">');
document.write('<a href="#" onclick="bbfontstyle(\'[color=#' + color + ']\', \'[/color]\'); return false;"><img src="images/spacer.gif" width="' + width + '" height="' + height + '" alt="#' + color + '" title="#' + color + '" /></a>'); document.write('<a href="#" onclick="bbfontstyle(\'[color=#' + color + ']\', \'[/color]\'); return false;"><img src="images/spacer.gif" width="' + width + '" height="' + height + '" alt="#' + color + '" title="#' + color + '" /></a>');
document.writeln('</td>'); document.writeln('</td>');
} }
if (dir == 'v') if (dir === 'v') {
{
document.writeln('</tr>'); document.writeln('</tr>');
} }
} }
if (dir == 'h') if (dir === 'h') {
{
document.writeln('</tr>'); document.writeln('</tr>');
} }
} }
document.writeln('</table>'); document.writeln('</table>');
} }
/** /**
* Caret Position object * Caret Position object
*/ */
function caretPosition() function caretPosition() {
{
var start = null; var start = null;
var end = null; var end = null;
} }
/** /**
* Get the caret position in an textarea * Get the caret position in an textarea
*/ */
function getCaretPosition(txtarea) function getCaretPosition(txtarea) {
{
var caretPos = new caretPosition(); var caretPos = new caretPosition();
// simple Gecko/Opera way // simple Gecko/Opera way
if (txtarea.selectionStart || txtarea.selectionStart == 0) if (txtarea.selectionStart || txtarea.selectionStart === 0) {
{
caretPos.start = txtarea.selectionStart; caretPos.start = txtarea.selectionStart;
caretPos.end = txtarea.selectionEnd; caretPos.end = txtarea.selectionEnd;
} }
// dirty and slow IE way // dirty and slow IE way
else if (document.selection) else if (document.selection) {
{
// get current selection // get current selection
var range = document.selection.createRange(); var range = document.selection.createRange();
@ -387,8 +321,7 @@ function getCaretPosition(txtarea)
// calculate selection start point by moving beginning of range_all to beginning of range // calculate selection start point by moving beginning of range_all to beginning of range
var sel_start; var sel_start;
for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) {
{
range_all.moveStart('character', 1); range_all.moveStart('character', 1);
} }

View file

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

View file

@ -2,35 +2,27 @@
* Hide and show all checkboxes * Hide and show all checkboxes
* status = true (show boxes), false (hide boxes) * status = true (show boxes), false (hide boxes)
*/ */
function display_checkboxes(status) function display_checkboxes(status) {
{
var form = document.getElementById('set-permissions'); var form = document.getElementById('set-permissions');
var cb = document.getElementsByTagName('input'); var cb = document.getElementsByTagName('input');
var display; var display;
//show //show
if (status) if (status) {
{
display = 'inline'; display = 'inline';
} }
//hide //hide
else else {
{
display = 'none'; display = 'none';
} }
for (var i = 0; i < cb.length; i++ ) for (var i = 0; i < cb.length; i++ ) {
{ if (cb[i].className === 'permissions-checkbox') {
if (cb[i].className == 'permissions-checkbox')
{
cb[i].style.display = display; cb[i].style.display = display;
} }
} }
} }
/** /**
* Change opacity of element * Change opacity of element
* e = element * e = element
@ -51,12 +43,9 @@ function toggle_opacity(block_id) {
var cb = document.getElementById('checkbox' + block_id); var cb = document.getElementById('checkbox' + block_id);
var fs = document.getElementById('perm' + block_id); var fs = document.getElementById('perm' + block_id);
if (cb.checked) if (cb.checked) {
{
set_opacity(fs, 5); set_opacity(fs, 5);
} } else {
else
{
set_opacity(fs, 10); set_opacity(fs, 10);
} }
} }
@ -71,21 +60,17 @@ function reset_opacity(status, except_id) {
var fs = perm.getElementsByTagName('fieldset'); var fs = perm.getElementsByTagName('fieldset');
var opacity = 5; var opacity = 5;
if (status) if (status) {
{
opacity = 10; opacity = 10;
} }
for (var i = 0; i < fs.length; i++ ) for (var i = 0; i < fs.length; i++ ) {
{ if (fs[i].className !== 'quick') {
if (fs[i].className != 'quick')
{
set_opacity(fs[i], opacity); set_opacity(fs[i], opacity);
} }
} }
if (typeof(except_id) != 'undefined') if (typeof(except_id) !== 'undefined') {
{
set_opacity(document.getElementById('perm' + except_id), 10); set_opacity(document.getElementById('perm' + except_id), 10);
} }
@ -93,20 +78,15 @@ function reset_opacity(status, except_id) {
marklist('set-permissions', 'inherit', !status); marklist('set-permissions', 'inherit', !status);
} }
/** /**
* Check whether we have a full radiobutton row of true * Check whether we have a full radiobutton row of true
* index = offset for the row of inputs (0 == first row, 1 == second, 2 == third), * index = offset for the row of inputs (0 == first row, 1 == second, 2 == third),
* rb = array of radiobuttons * rb = array of radiobuttons
*/ */
function get_radio_status(index, rb) function get_radio_status(index, rb) {
{ for (var i = index; i < rb.length; i = i + 3 ) {
for (var i = index; i < rb.length; i = i + 3 ) if (rb[i].checked !== true) {
{ if (i > index) {
if (rb[i].checked != true)
{
if (i > index)
{
//at least one is true, but not all (custom) //at least one is true, but not all (custom)
return 2; return 2;
} }
@ -125,13 +105,11 @@ function get_radio_status(index, rb)
* init = initialising on open, * init = initialising on open,
* quick = If no calculation needed, this contains the colour * quick = If no calculation needed, this contains the colour
*/ */
function set_colours(id, init, quick) function set_colours(id, init, quick) {
{
var table = document.getElementById('table' + id); var table = document.getElementById('table' + id);
var tab = document.getElementById('tab' + id); var tab = document.getElementById('tab' + id);
if (typeof(quick) != 'undefined') if (typeof(quick) !== 'undefined') {
{
tab.className = 'permissions-preset-' + quick + ' activetab'; tab.className = 'permissions-preset-' + quick + ' activetab';
return; return;
} }
@ -141,37 +119,27 @@ function set_colours(id, init, quick)
var status = get_radio_status(0, rb); var status = get_radio_status(0, rb);
if (status == 1) if (status === 1) {
{
colour = 'yes'; colour = 'yes';
} } else if (status === 0) {
else if (status == 0)
{
// We move on to No // We move on to No
status = get_radio_status(1, rb); status = get_radio_status(1, rb);
if (status == 1) if (status === 1) {
{
colour = 'no'; colour = 'no';
} } else if (status === 0) {
else if (status == 0)
{
// We move on to Never // We move on to Never
status = get_radio_status(2, rb); status = get_radio_status(2, rb);
if (status == 1) if (status === 1) {
{
colour = 'never'; colour = 'never';
} }
} }
} }
if (init) if (init) {
{
tab.className = 'permissions-preset-' + colour; tab.className = 'permissions-preset-' + colour;
} } else {
else
{
tab.className = 'permissions-preset-' + colour + ' activetab'; tab.className = 'permissions-preset-' + colour + ' activetab';
} }
} }
@ -180,16 +148,13 @@ function set_colours(id, init, quick)
* Initialise advanced tab colours on first load * Initialise advanced tab colours on first load
* block_id = block that is opened * block_id = block that is opened
*/ */
function init_colours(block_id) function init_colours(block_id) {
{
var block = document.getElementById('advanced' + block_id); var block = document.getElementById('advanced' + block_id);
var panels = block.getElementsByTagName('div'); var panels = block.getElementsByTagName('div');
var tab = document.getElementById('tab' + id); var tab = document.getElementById('tab' + id);
for (var i = 0; i < panels.length; i++) for (var i = 0; i < panels.length; i++) {
{ if (panels[i].className === 'permissions-panel') {
if(panels[i].className == 'permissions-panel')
{
set_colours(panels[i].id.replace(/options/, ''), true); set_colours(panels[i].id.replace(/options/, ''), true);
} }
} }
@ -203,8 +168,7 @@ function init_colours(block_id)
* adv = we are opening advanced permissions * adv = we are opening advanced permissions
* view = called from view permissions * view = called from view permissions
*/ */
function swap_options(pmask, fmask, cat, adv, view) function swap_options(pmask, fmask, cat, adv, view) {
{
id = pmask + fmask + cat; id = pmask + fmask + cat;
active_option = active_pmask + active_fmask + active_cat; active_option = active_pmask + active_fmask + active_cat;
@ -212,8 +176,7 @@ function swap_options(pmask, fmask, cat, adv, view)
var new_tab = document.getElementById('tab' + id); var new_tab = document.getElementById('tab' + id);
var adv_block = document.getElementById('advanced' + pmask + fmask); var adv_block = document.getElementById('advanced' + pmask + fmask);
if (adv_block.style.display == 'block' && adv == true) if (adv_block.style.display === 'block' && adv === true) {
{
dE('advanced' + pmask + fmask, -1); dE('advanced' + pmask + fmask, -1);
reset_opacity(1); reset_opacity(1);
display_checkboxes(false); display_checkboxes(false);
@ -221,20 +184,16 @@ function swap_options(pmask, fmask, cat, adv, view)
} }
// no need to set anything if we are clicking on the same tab again // no need to set anything if we are clicking on the same tab again
if (new_tab == old_tab && !adv) if (new_tab === old_tab && !adv) {
{
return; return;
} }
// init colours // init colours
if (adv && (pmask + fmask) != (active_pmask + active_fmask)) if (adv && (pmask + fmask) !== (active_pmask + active_fmask)) {
{
init_colours(pmask + fmask); init_colours(pmask + fmask);
display_checkboxes(true); display_checkboxes(true);
reset_opacity(1); reset_opacity(1);
} } else if (adv) {
else if (adv)
{
//Checkbox might have been clicked, but we need full visibility //Checkbox might have been clicked, but we need full visibility
display_checkboxes(true); display_checkboxes(true);
reset_opacity(1); reset_opacity(1);
@ -244,31 +203,26 @@ function swap_options(pmask, fmask, cat, adv, view)
old_tab.className = old_tab.className.replace(/\ activetab/g, ''); old_tab.className = old_tab.className.replace(/\ activetab/g, '');
new_tab.className = new_tab.className + ' activetab'; new_tab.className = new_tab.className + ' activetab';
if (id == active_option && adv != true) if (id === active_option && adv !== true) {
{
return; return;
} }
dE('options' + active_option, -1); dE('options' + active_option, -1);
//hiding and showing the checkbox //hiding and showing the checkbox
if (document.getElementById('checkbox' + active_pmask + active_fmask)) if (document.getElementById('checkbox' + active_pmask + active_fmask)) {
{
dE('checkbox' + pmask + fmask, -1); dE('checkbox' + pmask + fmask, -1);
if ((pmask + fmask) != (active_pmask + active_fmask)) if ((pmask + fmask) !== (active_pmask + active_fmask)) {
{
document.getElementById('checkbox' + active_pmask + active_fmask).style.display = 'inline'; document.getElementById('checkbox' + active_pmask + active_fmask).style.display = 'inline';
} }
} }
if (!view) if (!view) {
{
dE('advanced' + active_pmask + active_fmask, -1); dE('advanced' + active_pmask + active_fmask, -1);
} }
if (!view) if (!view) {
{
dE('advanced' + pmask + fmask, 1); dE('advanced' + pmask + fmask, 1);
} }
dE('options' + id, 1); dE('options' + id, 1);
@ -282,41 +236,33 @@ function swap_options(pmask, fmask, cat, adv, view)
* Mark all radio buttons in one panel * Mark all radio buttons in one panel
* id = table ID container, s = status ['y'/'u'/'n'] * id = table ID container, s = status ['y'/'u'/'n']
*/ */
function mark_options(id, s) function mark_options(id, s) {
{
var t = document.getElementById(id); var t = document.getElementById(id);
if (!t) if (!t) {
{
return; return;
} }
var rb = t.getElementsByTagName('input'); var rb = t.getElementsByTagName('input');
for (var r = 0; r < rb.length; r++) for (var r = 0; r < rb.length; r++) {
{ if (rb[r].id.substr(rb[r].id.length-1) === s) {
if (rb[r].id.substr(rb[r].id.length-1) == s)
{
rb[r].checked = true; rb[r].checked = true;
} }
} }
} }
function mark_one_option(id, field_name, s) function mark_one_option(id, field_name, s) {
{
var t = document.getElementById(id); var t = document.getElementById(id);
if (!t) if (!t) {
{
return; return;
} }
var rb = t.getElementsByTagName('input'); var rb = t.getElementsByTagName('input');
for (var r = 0; r < rb.length; r++) for (var r = 0; r < rb.length; r++) {
{ if (rb[r].id.substr(rb[r].id.length-field_name.length-3, field_name.length) === field_name && rb[r].id.substr(rb[r].id.length-1) === s) {
if (rb[r].id.substr(rb[r].id.length-field_name.length-3, field_name.length) == field_name && rb[r].id.substr(rb[r].id.length-1) == s)
{
rb[r].checked = true; rb[r].checked = true;
} }
} }
@ -325,12 +271,10 @@ function mark_one_option(id, field_name, s)
/** /**
* Reset role dropdown field to Select role... if an option gets changed * Reset role dropdown field to Select role... if an option gets changed
*/ */
function reset_role(id) function reset_role(id) {
{
var t = document.getElementById(id); var t = document.getElementById(id);
if (!t) if (!t) {
{
return; return;
} }
@ -340,20 +284,17 @@ function reset_role(id)
/** /**
* Load role and set options accordingly * Load role and set options accordingly
*/ */
function set_role_settings(role_id, target_id) function set_role_settings(role_id, target_id) {
{
settings = role_options[role_id]; settings = role_options[role_id];
if (!settings) if (!settings) {
{
return; return;
} }
// Mark all options to no (unset) first... // Mark all options to no (unset) first...
mark_options(target_id, 'u'); mark_options(target_id, 'u');
for (var r in settings) for (var r in settings) {
{ mark_one_option(target_id, r, (settings[r] === 1) ? 'y' : 'n');
mark_one_option(target_id, r, (settings[r] == 1) ? 'y' : 'n');
} }
} }

View file

@ -1,5 +1,7 @@
(function($) { // Avoid conflicts with other libraries (function($) { // Avoid conflicts with other libraries
"use strict";
$('#tz_date').change(function() { $('#tz_date').change(function() {
phpbb.timezoneSwitchDate(false); phpbb.timezoneSwitchDate(false);
}); });

View file

@ -15,14 +15,12 @@ var head_text, tooltip_mode;
/** /**
* Enable tooltip replacements for links * Enable tooltip replacements for links
*/ */
function enable_tooltips_link(id, headline, sub_id) function enable_tooltips_link(id, headline, sub_id) {
{
var links, i, hold; var links, i, hold;
head_text = headline; head_text = headline;
if (!document.getElementById || !document.getElementsByTagName) if (!document.getElementById || !document.getElementsByTagName) {
{
return; return;
} }
@ -33,26 +31,18 @@ function enable_tooltips_link(id, headline, sub_id)
document.getElementsByTagName('body')[0].appendChild(hold); document.getElementsByTagName('body')[0].appendChild(hold);
if (id == null) if (id === null) {
{
links = document.getElementsByTagName('a'); links = document.getElementsByTagName('a');
} } else {
else
{
links = document.getElementById(id).getElementsByTagName('a'); links = document.getElementById(id).getElementsByTagName('a');
} }
for (i = 0; i < links.length; i++) for (i = 0; i < links.length; i++) {
{ if (sub_id) {
if (sub_id) if (links[i].id.substr(0, sub_id.length) === sub_id) {
{
if (links[i].id.substr(0, sub_id.length) == sub_id)
{
prepare(links[i]); prepare(links[i]);
} }
} } else {
else
{
prepare(links[i]); prepare(links[i]);
} }
} }
@ -63,14 +53,12 @@ function enable_tooltips_link(id, headline, sub_id)
/** /**
* Enable tooltip replacements for selects * Enable tooltip replacements for selects
*/ */
function enable_tooltips_select(id, headline, sub_id) function enable_tooltips_select(id, headline, sub_id) {
{
var links, i, hold; var links, i, hold;
head_text = headline; head_text = headline;
if (!document.getElementById || !document.getElementsByTagName) if (!document.getElementById || !document.getElementsByTagName) {
{
return; return;
} }
@ -81,26 +69,18 @@ function enable_tooltips_select(id, headline, sub_id)
document.getElementsByTagName('body')[0].appendChild(hold); document.getElementsByTagName('body')[0].appendChild(hold);
if (id == null) if (id === null) {
{
links = document.getElementsByTagName('option'); links = document.getElementsByTagName('option');
} } else {
else
{
links = document.getElementById(id).getElementsByTagName('option'); links = document.getElementById(id).getElementsByTagName('option');
} }
for (i = 0; i < links.length; i++) for (i = 0; i < links.length; i++) {
{ if (sub_id) {
if (sub_id) if (links[i].parentNode.id.substr(0, sub_id.length) === sub_id) {
{
if (links[i].parentNode.id.substr(0, sub_id.length) == sub_id)
{
prepare(links[i]); prepare(links[i]);
} }
} } else {
else
{
prepare(links[i]); prepare(links[i]);
} }
} }
@ -111,14 +91,12 @@ function enable_tooltips_select(id, headline, sub_id)
/** /**
* Prepare elements to replace * Prepare elements to replace
*/ */
function prepare(element) function prepare(element) {
{
var tooltip, text, desc, title; var tooltip, text, desc, title;
text = element.getAttribute('title'); text = element.getAttribute('title');
if (text == null || text.length == 0) if (text === null || text.length === 0) {
{
return; return;
} }
@ -139,8 +117,7 @@ function prepare(element)
element.onmouseover = show_tooltip; element.onmouseover = show_tooltip;
element.onmouseout = hide_tooltip; element.onmouseout = hide_tooltip;
if (tooltip_mode == 'link') if (tooltip_mode === 'link') {
{
element.onmousemove = locate; element.onmousemove = locate;
} }
} }
@ -148,8 +125,7 @@ function prepare(element)
/** /**
* Show tooltip * Show tooltip
*/ */
function show_tooltip(e) function show_tooltip(e) {
{
document.getElementById('_tooltip_container').appendChild(this.tooltip); document.getElementById('_tooltip_container').appendChild(this.tooltip);
locate(this); locate(this);
} }
@ -157,11 +133,9 @@ function show_tooltip(e)
/** /**
* Hide tooltip * Hide tooltip
*/ */
function hide_tooltip(e) function hide_tooltip(e) {
{
var d = document.getElementById('_tooltip_container'); var d = document.getElementById('_tooltip_container');
if (d.childNodes.length > 0) if (d.childNodes.length > 0) {
{
d.removeChild(d.firstChild); d.removeChild(d.firstChild);
} }
} }
@ -169,8 +143,7 @@ function hide_tooltip(e)
/** /**
* Set opacity on tooltip element * Set opacity on tooltip element
*/ */
function set_opacity(element) function set_opacity(element) {
{
element.style.filter = 'alpha(opacity:95)'; element.style.filter = 'alpha(opacity:95)';
element.style.KHTMLOpacity = '0.95'; element.style.KHTMLOpacity = '0.95';
element.style.MozOpacity = '0.95'; element.style.MozOpacity = '0.95';
@ -180,8 +153,7 @@ function set_opacity(element)
/** /**
* Create new element * Create new element
*/ */
function create_element(tag, c) function create_element(tag, c) {
{
var x = document.createElement(tag); var x = document.createElement(tag);
x.className = c; x.className = c;
x.style.display = 'block'; x.style.display = 'block';
@ -191,34 +163,26 @@ function create_element(tag, c)
/** /**
* Correct positioning of tooltip container * Correct positioning of tooltip container
*/ */
function locate(e) function locate(e) {
{
var posx = 0; var posx = 0;
var posy = 0; var posy = 0;
e = e.parentNode; e = e.parentNode;
if (e.offsetParent) if (e.offsetParent) {
{ for (posx = 0, posy = 0; e.offsetParent; e = e.offsetParent) {
for (var posx = 0, posy = 0; e.offsetParent; e = e.offsetParent)
{
posx += e.offsetLeft; posx += e.offsetLeft;
posy += e.offsetTop; posy += e.offsetTop;
} }
} } else {
else
{
posx = e.offsetLeft; posx = e.offsetLeft;
posy = e.offsetTop; posy = e.offsetTop;
} }
if (tooltip_mode == 'link') if (tooltip_mode === 'link') {
{
document.getElementById('_tooltip_container').style.top=(posy+20) + 'px'; document.getElementById('_tooltip_container').style.top=(posy+20) + 'px';
document.getElementById('_tooltip_container').style.left=(posx-20) + 'px'; document.getElementById('_tooltip_container').style.left=(posx-20) + 'px';
} } else {
else
{
document.getElementById('_tooltip_container').style.top=(posy+30) + 'px'; document.getElementById('_tooltip_container').style.top=(posy+30) + 'px';
document.getElementById('_tooltip_container').style.left=(posx-205) + 'px'; document.getElementById('_tooltip_container').style.left=(posx-205) + 'px';
} }

View file

@ -136,7 +136,7 @@ phpbb.confirm = function(msg, callback, fadedark) {
}); });
var clickHandler = function(e) { var clickHandler = function(e) {
var res = this.className === 'button1'; var res = this.name === 'confirm';
var fade = (typeof fadedark !== 'undefined' && !fadedark && res) ? div : dark; var fade = (typeof fadedark !== 'undefined' && !fadedark && res) ? div : dark;
fade.fadeOut(phpbb.alertTime, function() { fade.fadeOut(phpbb.alertTime, function() {
div.hide(); div.hide();
@ -164,11 +164,11 @@ phpbb.confirm = function(msg, callback, fadedark) {
$(document).bind('keydown', function(e) { $(document).bind('keydown', function(e) {
if (e.keyCode === keymap.ENTER) { if (e.keyCode === keymap.ENTER) {
$('input[type="button"].button1').trigger('click'); $('input[name="confirm"]').trigger('click');
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
} else if (e.keyCode === keymap.ESC) { } else if (e.keyCode === keymap.ESC) {
$('input[type="button"].button2').trigger('click'); $('input[name="cancel"]').trigger('click');
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
} }
@ -252,6 +252,26 @@ phpbb.ajaxify = function(options) {
return; return;
} }
/**
* Handler for AJAX errors
*/
function errorHandler(jqXHR, textStatus, errorThrown) {
if (console && console.log) {
console.log('AJAX error. status: ' + textStatus + ', message: ' + errorThrown);
}
phpbb.clearLoadingTimeout();
var errorText = false;
if (typeof errorThrown === 'string' && errorThrown.length > 0) {
errorText = errorThrown;
}
else {
errorText = dark.attr('data-ajax-error-text-' + textStatus);
if (typeof errorText !== 'string' || !errorText.length)
errorText = dark.attr('data-ajax-error-text');
}
phpbb.alert(dark.attr('data-ajax-error-title'), errorText);
}
/** /**
* This is a private function used to handle the callbacks, refreshes * This is a private function used to handle the callbacks, refreshes
* and alert. It calls the callback, refreshes the page if necessary, and * and alert. It calls the callback, refreshes the page if necessary, and
@ -320,13 +340,6 @@ phpbb.ajaxify = function(options) {
} }
} }
function errorHandler() {
var alert;
phpbb.clearLoadingTimeout();
alert = phpbb.alert(dark.attr('data-ajax-error-title'), dark.attr('data-ajax-error-text'));
}
// If the element is a form, POST must be used and some extra data must // If the element is a form, POST must be used and some extra data must
// be taken from the form. // be taken from the form.
var runFilter = (typeof options.filter === 'function'); var runFilter = (typeof options.filter === 'function');
@ -355,8 +368,7 @@ phpbb.ajaxify = function(options) {
return; return;
} }
if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') == 'true')) if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) {
{
phpbb.loadingAlert(); phpbb.loadingAlert();
} }
@ -389,7 +401,7 @@ phpbb.ajaxify = function(options) {
* @param bool keepSelection Shall we keep the value selected, or shall the user be forced to repick one. * @param bool keepSelection Shall we keep the value selected, or shall the user be forced to repick one.
*/ */
phpbb.timezoneSwitchDate = function(keepSelection) { phpbb.timezoneSwitchDate = function(keepSelection) {
if ($('#timezone_copy').length == 0) { if ($('#timezone_copy').length === 0) {
// We make a backup of the original dropdown, so we can remove optgroups // We make a backup of the original dropdown, so we can remove optgroups
// instead of setting display to none, because IE and chrome will not // instead of setting display to none, because IE and chrome will not
// hide options inside of optgroups and selects via css // hide options inside of optgroups and selects via css
@ -399,17 +411,17 @@ phpbb.timezoneSwitchDate = function(keepSelection) {
$('#timezone').replaceWith($('#timezone_copy').clone().attr('id', 'timezone').css('display', 'block').attr('name', 'tz')); $('#timezone').replaceWith($('#timezone_copy').clone().attr('id', 'timezone').css('display', 'block').attr('name', 'tz'));
} }
if ($('#tz_date').val() != '') { if ($('#tz_date').val() !== '') {
$('#timezone > optgroup').remove(":not([label='" + $('#tz_date').val() + "'])"); $('#timezone > optgroup').remove(":not([label='" + $('#tz_date').val() + "'])");
} }
if ($('#tz_date').val() == $('#tz_select_date_suggest').attr('data-suggested-tz')) { if ($('#tz_date').val() === $('#tz_select_date_suggest').attr('data-suggested-tz')) {
$('#tz_select_date_suggest').css('display', 'none'); $('#tz_select_date_suggest').css('display', 'none');
} else { } else {
$('#tz_select_date_suggest').css('display', 'inline'); $('#tz_select_date_suggest').css('display', 'inline');
} }
if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() == 1) { if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() === 1) {
// If there is only one timezone for the selected date, we just select that automatically. // If there is only one timezone for the selected date, we just select that automatically.
$("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").attr('selected', true); $("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").attr('selected', true);
keepSelection = true; keepSelection = true;
@ -440,12 +452,11 @@ phpbb.timezonePreselectSelect = function(forceSelector) {
// The offset returned here is in minutes and negated. // The offset returned here is in minutes and negated.
// http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp // http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp
var offset = (new Date()).getTimezoneOffset(); var offset = (new Date()).getTimezoneOffset();
var sign = '-';
if (offset < 0) { if (offset < 0) {
var sign = '+'; sign = '+';
offset = -offset; offset = -offset;
} else {
var sign = '-';
} }
var minutes = offset % 60; var minutes = offset % 60;
@ -466,12 +477,13 @@ phpbb.timezonePreselectSelect = function(forceSelector) {
var prefix = 'GMT' + sign + hours + ':' + minutes; var prefix = 'GMT' + sign + hours + ':' + minutes;
var prefixLength = prefix.length; var prefixLength = prefix.length;
var selectorOptions = $('#tz_date > option'); var selectorOptions = $('#tz_date > option');
var i;
for (var i = 0; i < selectorOptions.length; ++i) { for (i = 0; i < selectorOptions.length; ++i) {
var option = selectorOptions[i]; var option = selectorOptions[i];
if (option.value.substring(0, prefixLength) == prefix) { if (option.value.substring(0, prefixLength) === prefix) {
if ($('#tz_date').val() != option.value && !forceSelector) { if ($('#tz_date').val() !== option.value && !forceSelector) {
// We do not select the option for the user, but notify him, // We do not select the option for the user, but notify him,
// that we would suggest a different setting. // that we would suggest a different setting.
phpbb.timezoneSwitchDate(true); phpbb.timezoneSwitchDate(true);
@ -571,4 +583,259 @@ phpbb.addAjaxCallback('toggle_link', function() {
el.parent().attr('class', toggleClass); el.parent().attr('class', toggleClass);
}); });
/**
* Automatically resize textarea
*
* This function automatically resizes textarea elements when user
* types text.
*
* @param {jQuery} items jQuery object(s) to resize
* @param {object} options Optional parameter that adjusts default
* configuration. See configuration variable
*
* Optional parameters:
* minWindowHeight {number} Minimum browser window height when textareas are resized. Default = 500
* minHeight {number} Minimum height of textarea. Default = 200
* maxHeight {number} Maximum height of textarea. Default = 500
* heightDiff {number} Minimum difference between window and textarea height. Default = 200
* resizeCallback {function} Function to call after resizing textarea
* resetCallback {function} Function to call when resize has been canceled
* Callback function format: function(item) {}
* this points to DOM object
* item is a jQuery object, same as this
*/
phpbb.resizeTextArea = function(items, options) {
// Configuration
var configuration = {
minWindowHeight: 500,
minHeight: 200,
maxHeight: 500,
heightDiff: 200,
resizeCallback: function(item) { },
resetCallback: function(item) { }
};
if (arguments.length > 1)
{
configuration = $.extend(configuration, options);
}
function resetAutoResize(item)
{
var $item = $(item);
if ($item.hasClass('auto-resized'))
{
$(item).css({height: '', resize: ''}).removeClass('auto-resized');
configuration.resetCallback.call(item, $item);
}
}
function autoResize(item)
{
function setHeight(height)
{
$item.css({height: height + 'px', resize: 'none'}).addClass('auto-resized');
configuration.resizeCallback.call(item, $item);
}
var windowHeight = $(window).height();
if (windowHeight < configuration.minWindowHeight)
{
resetAutoResize(item);
return;
}
var maxHeight = Math.min(Math.max(windowHeight - configuration.heightDiff, configuration.minHeight), configuration.maxHeight),
$item = $(item),
height = parseInt($item.height()),
scrollHeight = (item.scrollHeight) ? item.scrollHeight : 0;
if (height > maxHeight)
{
setHeight(maxHeight);
}
else if (scrollHeight > (height + 5))
{
setHeight(Math.min(maxHeight, scrollHeight));
}
}
items.bind('focus change keyup', function() {
$(this).each(function() {
autoResize(this);
});
}).change();
$(window).resize(function() {
items.each(function() {
if ($(this).hasClass('auto-resized'))
{
autoResize(this);
}
});
});
};
/**
* Check if cursor in textarea is currently inside a bbcode tag
*
* @param {object} textarea Textarea DOM object
* @param {Array} startTags List of start tags to look for
* For example, Array('[code]', '[code=')
* @param {Array} endTags List of end tags to look for
* For example, Array('[/code]')
*
* @return {boolean} True if cursor is in bbcode tag
*/
phpbb.inBBCodeTag = function(textarea, startTags, endTags) {
var start = textarea.selectionStart,
lastEnd = -1,
lastStart = -1,
i, index, value;
if (typeof start !== 'number') {
return false;
}
value = textarea.value.toLowerCase();
for (i = 0; i < startTags.length; i++) {
var tagLength = startTags[i].length;
if (start >= tagLength) {
index = value.lastIndexOf(startTags[i], start - tagLength);
lastStart = Math.max(lastStart, index);
}
}
if (lastStart == -1) return false;
if (start > 0) {
for (i = 0; i < endTags.length; i++) {
index = value.lastIndexOf(endTags[i], start - 1);
lastEnd = Math.max(lastEnd, index);
}
}
return (lastEnd < lastStart);
}
/**
* Adjust textarea to manage code bbcode
*
* This function allows to use tab characters when typing code
* and keeps indentation of previous line of code when adding new
* line while typing code.
*
* Editor's functionality is changed only when cursor is between
* [code] and [/code] bbcode tags.
*
* @param {object} textarea Textarea DOM object to apply editor to
*/
phpbb.applyCodeEditor = function(textarea) {
// list of allowed start and end bbcode code tags, in lower case
var startTags = ['[code]', '[code='],
startTagsEnd = ']',
endTags = ['[/code]'];
if (!textarea || typeof textarea.selectionStart !== 'number') {
return;
}
if ($(textarea).data('code-editor') === true) {
return;
}
function inTag() {
return phpbb.inBBCodeTag(textarea, startTags, endTags);
}
/**
* Get line of text before cursor
*
* @param {boolean} stripCodeStart If true, only part of line
* after [code] tag will be returned.
*
* @return {string} Line of text
*/
function getLastLine(stripCodeStart) {
var start = textarea.selectionStart,
value = textarea.value,
index = value.lastIndexOf("\n", start - 1);
value = value.substring(index + 1, start);
if (stripCodeStart) {
for (var i = 0; i < startTags.length; i++) {
index = value.lastIndexOf(startTags[i]);
if (index >= 0) {
var tagLength = startTags[i].length;
value = value.substring(index + tagLength);
if (startTags[i].lastIndexOf(startTagsEnd) != tagLength) {
index = value.indexOf(startTagsEnd);
if (index >= 0) {
value = value.substr(index + 1);
}
}
}
}
}
return value;
}
/**
* Append text at cursor position
*
* @param {string} Text Text to append
*/
function appendText(text) {
var start = textarea.selectionStart,
end = textarea.selectionEnd,
value = textarea.value;
textarea.value = value.substr(0, start) + text + value.substr(end);
textarea.selectionStart = textarea.selectionEnd = start + text.length;
}
$(textarea).data('code-editor', true).on('keydown', function(event) {
var key = event.keyCode || event.which;
// intercept tabs
if (key == 9) {
if (inTag()) {
appendText("\t");
event.preventDefault();
return;
}
}
// intercept new line characters
if (key == 13) {
if (inTag()) {
var lastLine = getLastLine(true),
code = '' + /^\s*/g.exec(lastLine);
if (code.length > 0) {
appendText("\n" + code);
event.preventDefault();
return;
}
}
}
});
};
/**
* Apply code editor to all textarea elements with data-bbcode attribute
*/
$(document).ready(function() {
$('textarea[data-bbcode]').each(function() {
phpbb.applyCodeEditor(this);
});
});
})(jQuery); // Avoid conflicts with other libraries })(jQuery); // Avoid conflicts with other libraries

File diff suppressed because one or more lines are too long

View file

@ -44,8 +44,11 @@ if (!defined('PHPBB_INSTALLED'))
// Replace any number of consecutive backslashes and/or slashes with a single slash // Replace any number of consecutive backslashes and/or slashes with a single slash
// (could happen on some proxy setups and/or Windows servers) // (could happen on some proxy setups and/or Windows servers)
$script_path = preg_replace('#[\\\\/]{2,}#', '/', $script_path); $script_path = preg_replace('#[\\\\/]{2,}#', '/', $script_path);
// Eliminate . and .. from the path // Eliminate . and .. from the path
$script_path = phpbb_clean_path($script_path); require($phpbb_root_path . 'includes/filesystem.' . $phpEx);
$phpbb_filesystem = new phpbb_filesystem();
$script_path = $phpbb_filesystem->clean_path($script_path);
$url = (($secure) ? 'https://' : 'http://') . $server_name; $url = (($secure) ? 'https://' : 'http://') . $server_name;
@ -82,9 +85,9 @@ require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);
set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler');
// Setup class loader first // Setup class loader first
$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", ".$phpEx"); $phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", $phpEx);
$phpbb_class_loader->register(); $phpbb_class_loader->register();
$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", ".$phpEx"); $phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", $phpEx);
$phpbb_class_loader_ext->register(); $phpbb_class_loader_ext->register();
// Set up container // Set up container

View file

@ -9,6 +9,8 @@
"symfony/yaml": "2.1.*" "symfony/yaml": "2.1.*"
}, },
"require-dev": { "require-dev": {
"fabpot/goutte": "v0.1.0" "fabpot/goutte": "v0.1.0",
"phpunit/dbunit": "1.2.*",
"phpunit/phpunit": "3.7.*"
} }
} }

755
phpBB/composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,37 @@
services:
auth.provider_collection:
class: phpbb_di_service_collection
arguments:
- @service_container
tags:
- { name: service_collection, tag: auth.provider }
auth.provider.db:
class: phpbb_auth_provider_db
arguments:
- @dbal.conn
- @config
- @request
- @user
- %core.root_path%
- %core.php_ext%
tags:
- { name: auth.provider }
auth.provider.apache:
class: phpbb_auth_provider_apache
arguments:
- @dbal.conn
- @config
- @request
- @user
- %core.root_path%
- %core.php_ext%
tags:
- { name: auth.provider }
auth.provider.ldap:
class: phpbb_auth_provider_ldap
arguments:
- @dbal.conn
- @config
- @user
tags:
- { name: auth.provider }

View file

@ -4,7 +4,7 @@ services:
arguments: arguments:
- @config - @config
- %core.root_path% - %core.root_path%
- .%core.php_ext% - %core.php_ext%
- @cache.driver - @cache.driver
calls: calls:
- [set_name, [avatar.driver.gravatar]] - [set_name, [avatar.driver.gravatar]]
@ -16,7 +16,7 @@ services:
arguments: arguments:
- @config - @config
- %core.root_path% - %core.root_path%
- .%core.php_ext% - %core.php_ext%
- @cache.driver - @cache.driver
calls: calls:
- [set_name, [avatar.driver.local]] - [set_name, [avatar.driver.local]]
@ -28,7 +28,7 @@ services:
arguments: arguments:
- @config - @config
- %core.root_path% - %core.root_path%
- .%core.php_ext% - %core.php_ext%
- @cache.driver - @cache.driver
calls: calls:
- [set_name, [avatar.driver.remote]] - [set_name, [avatar.driver.remote]]
@ -40,7 +40,7 @@ services:
arguments: arguments:
- @config - @config
- %core.root_path% - %core.root_path%
- .%core.php_ext% - %core.php_ext%
- @cache.driver - @cache.driver
calls: calls:
- [set_name, [avatar.driver.upload]] - [set_name, [avatar.driver.upload]]

98
phpBB/config/feed.yml Normal file
View file

@ -0,0 +1,98 @@
services:
feed.helper:
class: phpbb_feed_helper
arguments:
- @config
- @user
- %core.root_path%
feed.factory:
class: phpbb_feed_factory
arguments:
- @service_container
- @config
- @dbal.conn
feed.forum:
class: phpbb_feed_forum
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.forums:
class: phpbb_feed_forums
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.news:
class: phpbb_feed_news
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.overall:
class: phpbb_feed_overall
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.topic:
class: phpbb_feed_topic
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.topics:
class: phpbb_feed_topics
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.topics_active:
class: phpbb_feed_topics_active
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%

View file

@ -4,6 +4,8 @@ imports:
- { resource: notifications.yml } - { resource: notifications.yml }
- { resource: migrator.yml } - { resource: migrator.yml }
- { resource: avatars.yml } - { resource: avatars.yml }
- { resource: feed.yml }
- { resource: auth_providers.yml }
services: services:
auth: auth:
@ -36,7 +38,7 @@ services:
arguments: arguments:
- phpbb_ - phpbb_
- %core.root_path%includes/ - %core.root_path%includes/
- .%core.php_ext% - %core.php_ext%
calls: calls:
- [register, []] - [register, []]
- [set_cache, [@cache.driver]] - [set_cache, [@cache.driver]]
@ -46,7 +48,7 @@ services:
arguments: arguments:
- phpbb_ext_ - phpbb_ext_
- %core.root_path%ext/ - %core.root_path%ext/
- .%core.php_ext% - %core.php_ext%
calls: calls:
- [register, []] - [register, []]
- [set_cache, [@cache.driver]] - [set_cache, [@cache.driver]]
@ -70,7 +72,7 @@ services:
- @template - @template
- @user - @user
- %core.root_path% - %core.root_path%
- .%core.php_ext% - %core.php_ext%
controller.resolver: controller.resolver:
class: phpbb_controller_resolver class: phpbb_controller_resolver
@ -130,21 +132,25 @@ services:
- @service_container - @service_container
- @dbal.conn - @dbal.conn
- @config - @config
- @migrator - @filesystem
- %tables.ext% - %tables.ext%
- %core.root_path% - %core.root_path%
- .%core.php_ext% - %core.php_ext%
- @cache.driver - @cache.driver
ext.finder: ext.finder:
class: phpbb_extension_finder class: phpbb_extension_finder
arguments: arguments:
- @ext.manager - @ext.manager
- @filesystem
- %core.root_path% - %core.root_path%
- @cache.driver - @cache.driver
- .%core.php_ext% - %core.php_ext%
- _ext_finder - _ext_finder
filesystem:
class: phpbb_filesystem
groupposition.legend: groupposition.legend:
class: phpbb_groupposition_legend class: phpbb_groupposition_legend
arguments: arguments:
@ -168,7 +174,7 @@ services:
class: phpbb_hook_finder class: phpbb_hook_finder
arguments: arguments:
- %core.root_path% - %core.root_path%
- .%core.php_ext% - %core.php_ext%
- @cache.driver - @cache.driver
kernel_request_subscriber: kernel_request_subscriber:
@ -176,7 +182,7 @@ services:
arguments: arguments:
- @ext.finder - @ext.finder
- %core.root_path% - %core.root_path%
- .%core.php_ext% - %core.php_ext%
tags: tags:
- { name: kernel.event_subscriber } - { name: kernel.event_subscriber }
@ -213,6 +219,7 @@ services:
- @service_container - @service_container
- @user_loader - @user_loader
- @dbal.conn - @dbal.conn
- @cache
- @user - @user
- %core.root_path% - %core.root_path%
- %core.php_ext% - %core.php_ext%
@ -242,6 +249,7 @@ services:
arguments: arguments:
- @ext.manager - @ext.manager
- @style.path_provider - @style.path_provider
- %core.root_path%
style.path_provider: style.path_provider:
class: phpbb_style_path_provider class: phpbb_style_path_provider

View file

@ -3,9 +3,9 @@ parameters:
tables.config_text: %core.table_prefix%config_text tables.config_text: %core.table_prefix%config_text
tables.ext: %core.table_prefix%ext tables.ext: %core.table_prefix%ext
tables.log: %core.table_prefix%log tables.log: %core.table_prefix%log
tables.migrations: %core.table_prefix%migrations
tables.modules: %core.table_prefix%modules
tables.notification_types: %core.table_prefix%notification_types tables.notification_types: %core.table_prefix%notification_types
tables.notifications: %core.table_prefix%notifications tables.notifications: %core.table_prefix%notifications
tables.user_notifications: %core.table_prefix%user_notifications tables.user_notifications: %core.table_prefix%user_notifications
tables.users: %core.table_prefix%users tables.users: %core.table_prefix%users
tables.migrations: %core.table_prefix%migrations
tables.modules: %core.table_prefix%modules

View file

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

View file

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

View file

@ -34,7 +34,7 @@
<!-- BEGIN DOCUMENT --> <!-- BEGIN DOCUMENT -->
<p>Thank you for downloading phpBB3. This README will guide through the basics of installation and operation of phpBB3. Please ensure you read this and the accompanying documentation fully <strong>before</strong> proceeding with the installation.</p> <p>Thank you for downloading phpBB3. This README will guide you through the basics of installation and operation of phpBB3. Please ensure you read this and the accompanying documentation fully <strong>before</strong> proceeding with the installation.</p>
<h1>Readme</h1> <h1>Readme</h1>
@ -61,7 +61,7 @@
</ol> </ol>
</li> </li>
<li><a href="#status">Status of this version</a></li> <li><a href="#status">Status of this version</a></li>
<li><a href="#bugs">Reporting Bugs</a> <li><a href="#bugs">Reporting bugs</a>
<ol style="list-style-type: lower-roman;"> <ol style="list-style-type: lower-roman;">
<li><a href="#securitybugs">Security related bugs</a></li> <li><a href="#securitybugs">Security related bugs</a></li>
</ol> </ol>
@ -84,12 +84,11 @@
<div class="inner"><span class="corners-top"><span></span></span> <div class="inner"><span class="corners-top"><span></span></span>
<div class="content"> <div class="content">
<p>Installation, update and conversion instructions can be found in the <a href="INSTALL.html">INSTALL</a> document in this directory. If you are intending on converting from a phpBB 2.0.x or 3.0.x installation we highly recommend that you backup any existing data before proceeding!</p>
<p>Installation, update and conversion instructions can be found in the <a href="INSTALL.html">INSTALL</a> document contained in this distribution. If you are intending to convert from a previous phpBB 2.0.x or 3.0.x installation we highly recommend you backup any existing data before proceeding!</p>
<p>Users of phpBB 3.0 and 3.1 Beta versions cannot directly update.</p> <p>Users of phpBB 3.0 and 3.1 Beta versions cannot directly update.</p>
<p>Please note that we won't support the following installation types:</p> <p>Please note that we don't support the following installation types:</p>
<ul> <ul>
<li>Updates from phpBB 3.0 Beta versions to phpBB 3.0 RC1 and higher</li> <li>Updates from phpBB 3.0 Beta versions to phpBB 3.0 RC1 and higher</li>
<li>Updates from phpBB 3.1 Beta versions to phpBB 3.1 RC1 and higher</li> <li>Updates from phpBB 3.1 Beta versions to phpBB 3.1 RC1 and higher</li>
@ -103,8 +102,8 @@
<li>Updates from phpBB 3.0 RC1 and 3.1 RC1 to the latest version</li> <li>Updates from phpBB 3.0 RC1 and 3.1 RC1 to the latest version</li>
<li>Note: if using the <em>Automatic Update Package</em>, updates are supported from phpBB 3.0.2 onward. To update a pre-3.0.2 installation, first update to 3.0.2 and then update to the current version.</li> <li>Note: if using the <em>Automatic Update Package</em>, updates are supported from phpBB 3.0.2 onward. To update a pre-3.0.2 installation, first update to 3.0.2 and then update to the current version.</li>
<li>Conversions from phpBB 2.0.x to the latest version</li> <li>Conversions from phpBB 2.0.x to the latest version</li>
<li>New installations of phpBB 3.0.x - always only the latest released version</li> <li>New installations of phpBB 3.0.x - only the latest released version</li>
<li>New installations of phpBB 3.1.x - always only the latest released version</li> <li>New installations of phpBB 3.1.x - only the latest released version</li>
</ul> </ul>
</div> </div>
@ -131,7 +130,7 @@
<p>For more information about language packs, please see: <a href="http://www.phpbb.com/languages/">http://www.phpbb.com/languages/</a></p> <p>For more information about language packs, please see: <a href="http://www.phpbb.com/languages/">http://www.phpbb.com/languages/</a></p>
<p>This is the <em>official</em> location for all supported language sets. If you download a package from a 3rd party site you do so with the understanding that we cannot offer support. So please, do not ask for help in these cases!</p> <p>This is the <em>official</em> location for all supported language sets. If you download a package from a 3rd party site you do so with the understanding that we cannot offer support. Please do not ask for support if you download a language pack from a 3rd party site.</p>
<p>Installation of these packages is straightforward: simply download the required language pack, uncompress (unzip) it and via FTP transfer the included <code>language</code> and <code>styles</code> folders to the root of your board installation. The language can then be installed via the Administration Control Panel of your board: <code>System tab -&gt; General Tasks -&gt; Language packs</code>. A more detailed description of the process is in the Knowledge Base article, <a href="http://www.phpbb.com/kb/article/how-to-install-a-language-pack/">How to Install a Language Pack</a>.</p> <p>Installation of these packages is straightforward: simply download the required language pack, uncompress (unzip) it and via FTP transfer the included <code>language</code> and <code>styles</code> folders to the root of your board installation. The language can then be installed via the Administration Control Panel of your board: <code>System tab -&gt; General Tasks -&gt; Language packs</code>. A more detailed description of the process is in the Knowledge Base article, <a href="http://www.phpbb.com/kb/article/how-to-install-a-language-pack/">How to Install a Language Pack</a>.</p>
@ -175,15 +174,15 @@
<div class="content"> <div class="content">
<p>phpBB3 can seem a little daunting to new users in places, particularly with regard the permission system. The first thing you should do is check the <a href="FAQ.html">FAQ</a> which covers a few basic getting started questions. If you need additional help there are several places you should look.</p> <p>phpBB3 can sometimes seem a little daunting to new users, particularly with regards to the permission system. The first thing you should do is check the <a href="FAQ.html">FAQ</a>, which covers a few basic getting started questions. If you need additional help there are several places you can find it.</p>
<a name="docs"></a><h3>3.i. phpBB3 Documentation</h3> <a name="docs"></a><h3>3.i. phpBB3 Documentation</h3>
<p>A comprehensive documentation is now available online and can be accessed from the following location:</p> <p>Comprehensive documentation is now available on the phpBB website:</p>
<p><a href="http://www.phpbb.com/support/documentation/3.0/">http://www.phpbb.com/support/documentation/3.0/</a></p> <p><a href="http://www.phpbb.com/support/documentation/3.0/">http://www.phpbb.com/support/documentation/3.0/</a></p>
<p>This covers everything from installation through setting permissions and managing users.</p> <p>This covers everything from installation to setting permissions and managing users.</p>
<a name="kb"></a><h3>3.ii. Knowledge Base</h3> <a name="kb"></a><h3>3.ii. Knowledge Base</h3>
@ -197,7 +196,7 @@
<p><a href="http://www.phpbb.com/community/">http://www.phpbb.com/community/</a></p> <p><a href="http://www.phpbb.com/community/">http://www.phpbb.com/community/</a></p>
<p>If you do seek help via our forums please be sure to do a Search before posting. This may well save both you and us time and allow the developer, moderator and support groups to spend more time responding to people with unknown issues and problems. Please also remember that phpBB is an entirely volunteer effort, no one receives any compensation for the time they give, this includes moderators as well as developers. So please be respectful and mindful when awaiting responses.</p> <p>If you do seek help via our forums please be sure to do a search before posting; if someone has experienced the issue before, then you may find that your question has already been answered. Please remember that phpBB is entirely staffed by volunteers, no one receives any compensation for the time they give, including moderators as well as developers; please be respectful and mindful when awaiting responses and receiving support.</p>
<a name="irc"></a><h3>3.iv Internet Relay Chat</h3> <a name="irc"></a><h3>3.iv Internet Relay Chat</h3>
@ -268,7 +267,7 @@
<p>The relevant database type/version is listed within the administration control panel.</p> <p>The relevant database type/version is listed within the administration control panel.</p>
<p>Please also be as detailed as you can in your report, if possible list the steps required to duplicate the problem. If you have a patch that fixes the issue, please attach it to the ticket or submit a pull request <a href="https://github.com/phpbb/phpbb3">on GitHub</a>.</p> <p>Please be as detailed as you can in your report, and if possible, list the steps required to duplicate the problem. If you have a patch that fixes the issue, please attach it to the ticket or submit a pull request to our repository <a href="https://github.com/phpbb/phpbb3">on GitHub</a>.</p>
<p>If you create a patch, it is very much appreciated (but not required) if you follow the phpBB coding guidelines. Please note that the coding guidelines are somewhat different between different versions of phpBB. For phpBB 3.1.x the coding guidelines may be found here: <a href="http://area51.phpbb.com/docs/31x/coding-guidelines.html">http://area51.phpbb.com/docs/31x/coding-guidelines.html</a></p> <p>If you create a patch, it is very much appreciated (but not required) if you follow the phpBB coding guidelines. Please note that the coding guidelines are somewhat different between different versions of phpBB. For phpBB 3.1.x the coding guidelines may be found here: <a href="http://area51.phpbb.com/docs/31x/coding-guidelines.html">http://area51.phpbb.com/docs/31x/coding-guidelines.html</a></p>
@ -299,8 +298,8 @@
<p>This list is not complete but does represent those bugs which may affect users on a wider scale. Other bugs listed in the tracker have typically been shown to be limited to certain setups or methods of installation, updating and/or conversions.</p> <p>This list is not complete but does represent those bugs which may affect users on a wider scale. Other bugs listed in the tracker have typically been shown to be limited to certain setups or methods of installation, updating and/or conversions.</p>
<ul> <ul>
<li>Conversions may fail to complete on large boards under some hosts</li> <li>Conversions may fail to complete on large boards under some hosts.</li>
<li>Updates may fail to complete on large update sets under some hosts</li> <li>Updates may fail to complete on large update sets under some hosts.</li>
<li>Smilies placed directly after bbcode tags will not get parsed. Smilies always need to be separated by spaces.</li> <li>Smilies placed directly after bbcode tags will not get parsed. Smilies always need to be separated by spaces.</li>
</ul> </ul>
@ -322,7 +321,7 @@
<p>phpBB 3.1.x takes advantage of new features added in PHP 5.3. We recommend that you upgrade to the latest stable release of PHP5 to run phpBB. The minimum version required is PHP 5.3.3.</p> <p>phpBB 3.1.x takes advantage of new features added in PHP 5.3. We recommend that you upgrade to the latest stable release of PHP5 to run phpBB. The minimum version required is PHP 5.3.3.</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>Please remember that running any application on a development (unstable, e.g. a beta release) version of PHP can lead to strange/unexpected results which may appear to be bugs in the application. Therefore, we recommend you upgrade to the newest stable version of PHP before running phpBB3. If you are running a development 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 8.x, Oracle 8, SQLite 2 and Firebird. Versions of PHP used range from 5.3.x to 5.4.x 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 8.x, Oracle 8, SQLite 2 and Firebird. Versions of PHP used range from 5.3.x to 5.4.x without problem.</p>

View file

@ -1060,6 +1060,8 @@ $action_ary = request_var('action', array('' =&gt; 0));
<h4>Login checks/redirection: </h4> <h4>Login checks/redirection: </h4>
<p>To show a forum login box use <code>login_forum_box($forum_data)</code>, else use the <code>login_box()</code> function.</p> <p>To show a forum login box use <code>login_forum_box($forum_data)</code>, else use the <code>login_box()</code> function.</p>
<p><code>$forum_data</code> should contain at least the <code>forum_id</code> and <code>forum_password</code> fields. If the field <code>forum_name</code> is available, then it is displayed on the forum login page.</p>
<p>The <code>login_box()</code> function can have a redirect as the first parameter. As a thumb of rule, specify an empty string if you want to redirect to the users current location, else do not add the <code>$SID</code> to the redirect string (for example within the ucp/login we redirect to the board index because else the user would be redirected to the login screen).</p> <p>The <code>login_box()</code> function can have a redirect as the first parameter. As a thumb of rule, specify an empty string if you want to redirect to the users current location, else do not add the <code>$SID</code> to the redirect string (for example within the ucp/login we redirect to the board index because else the user would be redirected to the login screen).</p>
<h4>Sensitive Operations: </h4> <h4>Sensitive Operations: </h4>
@ -2490,7 +2492,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2))
<hr /> <hr />
<a name="disclaimer"></a><h2>8. Copyright and disclaimer</h2> <a name="disclaimer"></a><h2>7. Copyright and disclaimer</h2>
<div class="paragraph"> <div class="paragraph">
<div class="inner"><span class="corners-top"><span></span></span> <div class="inner"><span class="corners-top"><span></span></span>

View file

@ -124,6 +124,15 @@ viewtopic_print_head_append
* Location: styles/prosilver/template/viewtopic_print.html * Location: styles/prosilver/template/viewtopic_print.html
* Purpose: Add asset calls directly before the `</head>` tag of the Print Topic screen * Purpose: Add asset calls directly before the `</head>` tag of the Print Topic screen
viewtopic_body_footer_before
===
* Locations:
+ styles/prosilver/template/viewtopic_body.html
+ styles/subsilver2/template/viewtopic_body.html
* Purpose: Add content to the bottom of the View topic screen below the posts
and quick reply, directly before the jumpbox in Prosilver, breadcrumbs in
Subsilver2.
viewtopic_topic_title_prepend viewtopic_topic_title_prepend
=== ===
* Locations: * Locations:

View file

@ -7,41 +7,25 @@ source source_phpbb_{SPHINX_ID}_main
sql_db = db_name sql_db = db_name
sql_port = 3306 # optional, default is 3306 for mysql and 5432 for pgsql sql_port = 3306 # optional, default is 3306 for mysql and 5432 for pgsql
sql_query_pre = SET NAMES 'utf8' sql_query_pre = SET NAMES 'utf8'
sql_query_pre = UPDATE phpbb_sphinx SET max_doc_id = MAX(post_id) WHERE counter_id = 1 sql_query_pre = UPDATE phpbb_sphinx SET max_doc_id = (SELECT MAX(post_id) FROM phpbb_posts) WHERE counter_id = 1
sql_query_range = SELECT MIN(post_id), MAX(post_id) FROM phpbb_posts sql_query_range = SELECT MIN(post_id), MAX(post_id) FROM phpbb_posts
sql_range_step = 5000 sql_range_step = 5000
sql_query = SELECT sql_query = SELECT \
\ p.post_id AS id, \
p.post_id AS id, p.forum_id, \
\ p.topic_id, \
p.forum_id, p.poster_id, \
\ p.post_visibility, \
p.topic_id, CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, \
\ p.post_time, \
p.poster_id, p.post_subject, \
\ p.post_subject as title, \
p.post_visibility, p.post_text as data, \
\ t.topic_last_post_time, \
CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, 0 as deleted\
\ FROM phpbb_posts p, phpbb_topics t \
p.post_time, WHERE \
\ p.topic_id = t.topic_id \
p.post_subject,
\
p.post_subject as title,
\
p.post_text as data,
\
t.topic_last_post_time,
\
0 as deleted
\
FROM phpbb_posts p, phpbb_topics t
\
WHERE
\
p.topic_id = t.topic_id
\
AND p.post_id >= $start AND p.post_id <= $end AND p.post_id >= $start AND p.post_id <= $end
sql_query_post = sql_query_post =
sql_query_post_index = UPDATE phpbb_sphinx SET max_doc_id = $maxid WHERE counter_id = 1 sql_query_post_index = UPDATE phpbb_sphinx SET max_doc_id = $maxid WHERE counter_id = 1
@ -58,40 +42,25 @@ source source_phpbb_{SPHINX_ID}_main
} }
source source_phpbb_{SPHINX_ID}_delta : source_phpbb_{SPHINX_ID}_main source source_phpbb_{SPHINX_ID}_delta : source_phpbb_{SPHINX_ID}_main
{ {
sql_query_pre =
sql_query_range = sql_query_range =
sql_range_step = sql_range_step =
sql_query = SELECT sql_query = SELECT \
\ p.post_id AS id, \
p.post_id AS id, p.forum_id, \
\ p.topic_id, \
p.forum_id, p.poster_id, \
\ p.post_visibility, \
p.topic_id, CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, \
\ p.post_time, \
p.poster_id, p.post_subject, \
\ p.post_subject as title, \
p.post_visibility, p.post_text as data, \
\ t.topic_last_post_time, \
CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, 0 as deleted \
\ FROM phpbb_posts p, phpbb_topics t \
p.post_time, WHERE \
\ p.topic_id = t.topic_id \
p.post_subject,
\
p.post_subject as title,
\
p.post_text as data,
\
t.topic_last_post_time,
\
0 as deleted
\
FROM phpbb_posts p, phpbb_topics t
\
WHERE
\
p.topic_id = t.topic_id
\
AND p.post_id >= ( SELECT max_doc_id FROM phpbb_sphinx WHERE counter_id=1 ) AND p.post_id >= ( SELECT max_doc_id FROM phpbb_sphinx WHERE counter_id=1 )
sql_query_pre = sql_query_pre =
} }

View file

@ -50,9 +50,9 @@ if (isset($_GET['avatar']))
require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);
// Setup class loader first // Setup class loader first
$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", ".$phpEx"); $phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", $phpEx);
$phpbb_class_loader->register(); $phpbb_class_loader->register();
$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", ".$phpEx"); $phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", $phpEx);
$phpbb_class_loader_ext->register(); $phpbb_class_loader_ext->register();
// Set up container // Set up container
@ -279,7 +279,7 @@ else if ($download_id)
phpbb_increment_downloads($db, $attachment['attach_id']); phpbb_increment_downloads($db, $attachment['attach_id']);
} }
if ($display_cat == ATTACHMENT_CATEGORY_IMAGE && $mode === 'view' && (strpos($attachment['mimetype'], 'image') === 0) && ((strpos(strtolower($user->browser), 'msie') !== false) && (strpos(strtolower($user->browser), 'msie 8.0') === false))) if ($display_cat == ATTACHMENT_CATEGORY_IMAGE && $mode === 'view' && (strpos($attachment['mimetype'], 'image') === 0) && (strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($user->browser, 7))
{ {
wrap_img_in_html(append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'id=' . $attachment['attach_id']), $attachment['real_filename']); wrap_img_in_html(append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'id=' . $attachment['attach_id']), $attachment['real_filename']);
file_gc(); file_gc();

File diff suppressed because it is too large Load diff

View file

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

View file

@ -53,8 +53,9 @@ class acp_board
'legend1' => 'ACP_BOARD_SETTINGS', 'legend1' => 'ACP_BOARD_SETTINGS',
'sitename' => array('lang' => 'SITE_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false), 'sitename' => array('lang' => 'SITE_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false),
'site_desc' => array('lang' => 'SITE_DESC', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false), 'site_desc' => array('lang' => 'SITE_DESC', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false),
'site_home_url' => array('lang' => 'SITE_HOME_URL', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'site_home_url' => array('lang' => 'SITE_HOME_URL', 'validate' => 'string', 'type' => 'url:40:255', 'explain' => true),
'site_home_text' => array('lang' => 'SITE_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'site_home_text' => array('lang' => 'SITE_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true),
'board_index_text' => array('lang' => 'BOARD_INDEX_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true),
'board_disable' => array('lang' => 'DISABLE_BOARD', 'validate' => 'bool', 'type' => 'custom', 'method' => 'board_disable', 'explain' => true), 'board_disable' => array('lang' => 'DISABLE_BOARD', 'validate' => 'bool', 'type' => 'custom', 'method' => 'board_disable', 'explain' => true),
'board_disable_msg' => false, 'board_disable_msg' => false,
'default_lang' => array('lang' => 'DEFAULT_LANGUAGE', 'validate' => 'lang', 'type' => 'select', 'function' => 'language_select', 'params' => array('{CONFIG_VALUE}'), 'explain' => false), 'default_lang' => array('lang' => 'DEFAULT_LANGUAGE', 'validate' => 'lang', 'type' => 'select', 'function' => 'language_select', 'params' => array('{CONFIG_VALUE}'), 'explain' => false),
@ -64,7 +65,7 @@ class acp_board
'override_user_style' => array('lang' => 'OVERRIDE_STYLE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'override_user_style' => array('lang' => 'OVERRIDE_STYLE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend2' => 'WARNINGS', 'legend2' => 'WARNINGS',
'warnings_expire_days' => array('lang' => 'WARNINGS_EXPIRE', 'validate' => 'int', 'type' => 'text:3:4', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'warnings_expire_days' => array('lang' => 'WARNINGS_EXPIRE', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
'legend3' => 'ACP_SUBMIT_CHANGES', 'legend3' => 'ACP_SUBMIT_CHANGES',
) )
@ -135,8 +136,8 @@ class acp_board
'avatar_max_height' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false), 'avatar_max_height' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false),
'allow_avatar' => array('lang' => 'ALLOW_AVATARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_avatar' => array('lang' => 'ALLOW_AVATARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'avatar_min' => array('lang' => 'MIN_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'avatar_min' => array('lang' => 'MIN_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:0', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'avatar_max' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'avatar_max' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:0', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
) )
); );
@ -153,11 +154,11 @@ class acp_board
'vars' => array( 'vars' => array(
'legend1' => 'GENERAL_SETTINGS', 'legend1' => 'GENERAL_SETTINGS',
'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'pm_max_boxes' => array('lang' => 'BOXES_MAX', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'pm_max_boxes' => array('lang' => 'BOXES_MAX', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'pm_max_msgs' => array('lang' => 'BOXES_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'pm_max_msgs' => array('lang' => 'BOXES_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'full_folder_action' => array('lang' => 'FULL_FOLDER_ACTION', 'validate' => 'int', 'type' => 'select', 'method' => 'full_folder_select', 'explain' => true), 'full_folder_action' => array('lang' => 'FULL_FOLDER_ACTION', 'validate' => 'int', 'type' => 'select', 'method' => 'full_folder_select', 'explain' => true),
'pm_edit_time' => array('lang' => 'PM_EDIT_TIME', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'pm_edit_time' => array('lang' => 'PM_EDIT_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'pm_max_recipients' => array('lang' => 'PM_MAX_RECIPIENTS', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true), 'pm_max_recipients' => array('lang' => 'PM_MAX_RECIPIENTS', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true),
'legend2' => 'GENERAL_OPTIONS', 'legend2' => 'GENERAL_OPTIONS',
'allow_mass_pm' => array('lang' => 'ALLOW_MASS_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_mass_pm' => array('lang' => 'ALLOW_MASS_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
@ -194,24 +195,24 @@ class acp_board
'legend2' => 'POSTING', 'legend2' => 'POSTING',
'bump_type' => false, 'bump_type' => false,
'edit_time' => array('lang' => 'EDIT_TIME', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'edit_time' => array('lang' => 'EDIT_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'delete_time' => array('lang' => 'DELETE_TIME', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'delete_time' => array('lang' => 'DELETE_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'display_last_edited' => array('lang' => 'DISPLAY_LAST_EDITED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'display_last_edited' => array('lang' => 'DISPLAY_LAST_EDITED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'flood_interval' => array('lang' => 'FLOOD_INTERVAL', 'validate' => 'int:0', 'type' => 'text:3:10', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'flood_interval' => array('lang' => 'FLOOD_INTERVAL', 'validate' => 'int:0:9999999999', 'type' => 'number:0:9999999999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
'bump_interval' => array('lang' => 'BUMP_INTERVAL', 'validate' => 'int:0', 'type' => 'custom', 'method' => 'bump_interval', 'explain' => true), 'bump_interval' => array('lang' => 'BUMP_INTERVAL', 'validate' => 'int:0', 'type' => 'custom', 'method' => 'bump_interval', 'explain' => true),
'topics_per_page' => array('lang' => 'TOPICS_PER_PAGE', 'validate' => 'int:1', 'type' => 'text:3:4', 'explain' => false), 'topics_per_page' => array('lang' => 'TOPICS_PER_PAGE', 'validate' => 'int:1:9999', 'type' => 'number:1:9999', 'explain' => false),
'posts_per_page' => array('lang' => 'POSTS_PER_PAGE', 'validate' => 'int:1', 'type' => 'text:3:4', 'explain' => false), 'posts_per_page' => array('lang' => 'POSTS_PER_PAGE', 'validate' => 'int:1:9999', 'type' => 'number:1:9999', 'explain' => false),
'smilies_per_page' => array('lang' => 'SMILIES_PER_PAGE', 'validate' => 'int:1', 'type' => 'text:3:4', 'explain' => false), 'smilies_per_page' => array('lang' => 'SMILIES_PER_PAGE', 'validate' => 'int:1:9999', 'type' => 'number:1:9999', 'explain' => false),
'hot_threshold' => array('lang' => 'HOT_THRESHOLD', 'validate' => 'int:0', 'type' => 'text:3:4', 'explain' => true), 'hot_threshold' => array('lang' => 'HOT_THRESHOLD', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_poll_options' => array('lang' => 'MAX_POLL_OPTIONS', 'validate' => 'int:2:127', 'type' => 'text:4:4', 'explain' => false), 'max_poll_options' => array('lang' => 'MAX_POLL_OPTIONS', 'validate' => 'int:2:127', 'type' => 'number:2:127', 'explain' => false),
'max_post_chars' => array('lang' => 'CHAR_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:6', 'explain' => true), 'max_post_chars' => array('lang' => 'CHAR_LIMIT', 'validate' => 'int:0:999999', 'type' => 'number:0:999999', 'explain' => true),
'min_post_chars' => array('lang' => 'MIN_CHAR_LIMIT', 'validate' => 'int:1', 'type' => 'text:4:6', 'explain' => true), 'min_post_chars' => array('lang' => 'MIN_CHAR_LIMIT', 'validate' => 'int:1:999999', 'type' => 'number:1:999999', 'explain' => true),
'max_post_smilies' => array('lang' => 'SMILIES_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'max_post_smilies' => array('lang' => 'SMILIES_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_post_urls' => array('lang' => 'MAX_POST_URLS', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true), 'max_post_urls' => array('lang' => 'MAX_POST_URLS', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_post_font_size' => array('lang' => 'MAX_POST_FONT_SIZE', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' %'), 'max_post_font_size' => array('lang' => 'MAX_POST_FONT_SIZE', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' %'),
'max_quote_depth' => array('lang' => 'QUOTE_DEPTH_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'max_quote_depth' => array('lang' => 'QUOTE_DEPTH_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_post_img_width' => array('lang' => 'MAX_POST_IMG_WIDTH', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'max_post_img_width' => array('lang' => 'MAX_POST_IMG_WIDTH', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'max_post_img_height' => array('lang' => 'MAX_POST_IMG_HEIGHT', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'max_post_img_height' => array('lang' => 'MAX_POST_IMG_HEIGHT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'legend3' => 'ACP_SUBMIT_CHANGES', 'legend3' => 'ACP_SUBMIT_CHANGES',
) )
@ -231,12 +232,12 @@ class acp_board
'allow_sig_links' => array('lang' => 'ALLOW_SIG_LINKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_sig_links' => array('lang' => 'ALLOW_SIG_LINKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend2' => 'GENERAL_SETTINGS', 'legend2' => 'GENERAL_SETTINGS',
'max_sig_chars' => array('lang' => 'MAX_SIG_LENGTH', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true), 'max_sig_chars' => array('lang' => 'MAX_SIG_LENGTH', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_sig_urls' => array('lang' => 'MAX_SIG_URLS', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true), 'max_sig_urls' => array('lang' => 'MAX_SIG_URLS', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_sig_font_size' => array('lang' => 'MAX_SIG_FONT_SIZE', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' %'), 'max_sig_font_size' => array('lang' => 'MAX_SIG_FONT_SIZE', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' %'),
'max_sig_smilies' => array('lang' => 'MAX_SIG_SMILIES', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true), 'max_sig_smilies' => array('lang' => 'MAX_SIG_SMILIES', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'max_sig_img_width' => array('lang' => 'MAX_SIG_IMG_WIDTH', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'max_sig_img_width' => array('lang' => 'MAX_SIG_IMG_WIDTH', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'max_sig_img_height' => array('lang' => 'MAX_SIG_IMG_HEIGHT', 'validate' => 'int:0', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'max_sig_img_height' => array('lang' => 'MAX_SIG_IMG_HEIGHT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'legend3' => 'ACP_SUBMIT_CHANGES', 'legend3' => 'ACP_SUBMIT_CHANGES',
) )
@ -252,20 +253,20 @@ class acp_board
'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,), 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,),
'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'select', 'method' => 'select_acc_activation', 'explain' => true), 'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'select', 'method' => 'select_acc_activation', 'explain' => true),
'new_member_post_limit' => array('lang' => 'NEW_MEMBER_POST_LIMIT', 'validate' => 'int:0:255', 'type' => 'text:4:4', 'explain' => true, 'append' => ' ' . $user->lang['POSTS']), 'new_member_post_limit' => array('lang' => 'NEW_MEMBER_POST_LIMIT', 'validate' => 'int:0:255', 'type' => 'number:0:255', 'explain' => true, 'append' => ' ' . $user->lang['POSTS']),
'new_member_group_default'=> array('lang' => 'NEW_MEMBER_GROUP_DEFAULT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'new_member_group_default'=> array('lang' => 'NEW_MEMBER_GROUP_DEFAULT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'min_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:1', 'type' => 'custom:5:180', 'method' => 'username_length', 'explain' => true), 'min_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:1', 'type' => 'custom:5:180', 'method' => 'username_length', 'explain' => true),
'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true), 'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true),
'allow_name_chars' => array('lang' => 'USERNAME_CHARS', 'validate' => 'string', 'type' => 'select', 'method' => 'select_username_chars', 'explain' => true), 'allow_name_chars' => array('lang' => 'USERNAME_CHARS', 'validate' => 'string', 'type' => 'select', 'method' => 'select_username_chars', 'explain' => true),
'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true), 'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true),
'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
'legend2' => 'GENERAL_OPTIONS', 'legend2' => 'GENERAL_OPTIONS',
'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'allow_emailreuse' => array('lang' => 'ALLOW_EMAIL_REUSE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_emailreuse' => array('lang' => 'ALLOW_EMAIL_REUSE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'enable_confirm' => array('lang' => 'VISUAL_CONFIRM_REG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'enable_confirm' => array('lang' => 'VISUAL_CONFIRM_REG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true), 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true),
'max_reg_attempts' => array('lang' => 'REG_LIMIT', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'max_reg_attempts' => array('lang' => 'REG_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'legend3' => 'COPPA', 'legend3' => 'COPPA',
'coppa_enable' => array('lang' => 'ENABLE_COPPA', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'coppa_enable' => array('lang' => 'ENABLE_COPPA', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
@ -287,13 +288,13 @@ class acp_board
'feed_http_auth' => array('lang' => 'ACP_FEED_HTTP_AUTH', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'feed_http_auth' => array('lang' => 'ACP_FEED_HTTP_AUTH', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true),
'legend2' => 'ACP_FEED_POST_BASED', 'legend2' => 'ACP_FEED_POST_BASED',
'feed_limit_post' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5', 'type' => 'text:3:4', 'explain' => true), 'feed_limit_post' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5:9999', 'type' => 'number:5:9999', 'explain' => true),
'feed_overall' => array('lang' => 'ACP_FEED_OVERALL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_overall' => array('lang' => 'ACP_FEED_OVERALL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ),
'feed_forum' => array('lang' => 'ACP_FEED_FORUM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_forum' => array('lang' => 'ACP_FEED_FORUM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ),
'feed_topic' => array('lang' => 'ACP_FEED_TOPIC', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_topic' => array('lang' => 'ACP_FEED_TOPIC', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ),
'legend3' => 'ACP_FEED_TOPIC_BASED', 'legend3' => 'ACP_FEED_TOPIC_BASED',
'feed_limit_topic' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5', 'type' => 'text:3:4', 'explain' => true), 'feed_limit_topic' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5:9999', 'type' => 'number:5:9999', 'explain' => true),
'feed_topics_new' => array('lang' => 'ACP_FEED_TOPICS_NEW', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_topics_new' => array('lang' => 'ACP_FEED_TOPICS_NEW', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ),
'feed_topics_active' => array('lang' => 'ACP_FEED_TOPICS_ACTIVE', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_topics_active' => array('lang' => 'ACP_FEED_TOPICS_ACTIVE', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ),
'feed_news_id' => array('lang' => 'ACP_FEED_NEWS', 'validate' => 'string', 'type' => 'custom', 'method' => 'select_news_forums', 'explain' => true), 'feed_news_id' => array('lang' => 'ACP_FEED_NEWS', 'validate' => 'string', 'type' => 'custom', 'method' => 'select_news_forums', 'explain' => true),
@ -323,10 +324,10 @@ class acp_board
'title' => 'ACP_LOAD_SETTINGS', 'title' => 'ACP_LOAD_SETTINGS',
'vars' => array( 'vars' => array(
'legend1' => 'GENERAL_SETTINGS', 'legend1' => 'GENERAL_SETTINGS',
'limit_load' => array('lang' => 'LIMIT_LOAD', 'validate' => 'string', 'type' => 'text:4:4', 'explain' => true), 'limit_load' => array('lang' => 'LIMIT_LOAD', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'session_length' => array('lang' => 'SESSION_LENGTH', 'validate' => 'int:60', 'type' => 'text:5:10', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'session_length' => array('lang' => 'SESSION_LENGTH', 'validate' => 'int:60:9999999999', 'type' => 'number:60:9999999999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
'active_sessions' => array('lang' => 'LIMIT_SESSIONS', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'active_sessions' => array('lang' => 'LIMIT_SESSIONS', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true),
'load_online_time' => array('lang' => 'ONLINE_LENGTH', 'validate' => 'int:0', 'type' => 'text:4:3', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'load_online_time' => array('lang' => 'ONLINE_LENGTH', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
'legend2' => 'GENERAL_OPTIONS', 'legend2' => 'GENERAL_OPTIONS',
'load_notifications' => array('lang' => 'LOAD_NOTIFICATIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_notifications' => array('lang' => 'LOAD_NOTIFICATIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
@ -383,7 +384,7 @@ class acp_board
'force_server_vars' => array('lang' => 'FORCE_SERVER_VARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'force_server_vars' => array('lang' => 'FORCE_SERVER_VARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'server_protocol' => array('lang' => 'SERVER_PROTOCOL', 'validate' => 'string', 'type' => 'text:10:10', 'explain' => true), 'server_protocol' => array('lang' => 'SERVER_PROTOCOL', 'validate' => 'string', 'type' => 'text:10:10', 'explain' => true),
'server_name' => array('lang' => 'SERVER_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'server_name' => array('lang' => 'SERVER_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true),
'server_port' => array('lang' => 'SERVER_PORT', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true), 'server_port' => array('lang' => 'SERVER_PORT', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true),
'script_path' => array('lang' => 'SCRIPT_PATH', 'validate' => 'script_path', 'type' => 'text::255', 'explain' => true), 'script_path' => array('lang' => 'SCRIPT_PATH', 'validate' => 'script_path', 'type' => 'text::255', 'explain' => true),
'legend4' => 'ACP_SUBMIT_CHANGES', 'legend4' => 'ACP_SUBMIT_CHANGES',
@ -397,7 +398,8 @@ class acp_board
'vars' => array( 'vars' => array(
'legend1' => 'ACP_SECURITY_SETTINGS', 'legend1' => 'ACP_SECURITY_SETTINGS',
'allow_autologin' => array('lang' => 'ALLOW_AUTOLOGIN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_autologin' => array('lang' => 'ALLOW_AUTOLOGIN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'max_autologin_time' => array('lang' => 'AUTOLOGIN_LENGTH', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'allow_password_reset' => array('lang' => 'ALLOW_PASSWORD_RESET', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'max_autologin_time' => array('lang' => 'AUTOLOGIN_LENGTH', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
'ip_check' => array('lang' => 'IP_VALID', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_ip_check', 'explain' => true), 'ip_check' => array('lang' => 'IP_VALID', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_ip_check', 'explain' => true),
'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'forwarded_for_check' => array('lang' => 'FORWARDED_FOR_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'forwarded_for_check' => array('lang' => 'FORWARDED_FOR_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
@ -407,13 +409,13 @@ class acp_board
'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,), 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,),
'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true), 'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true),
'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true), 'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true),
'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true), 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true),
'ip_login_limit_max' => array('lang' => 'IP_LOGIN_LIMIT_MAX', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true), 'ip_login_limit_max' => array('lang' => 'IP_LOGIN_LIMIT_MAX', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true),
'ip_login_limit_time' => array('lang' => 'IP_LOGIN_LIMIT_TIME', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'ip_login_limit_time' => array('lang' => 'IP_LOGIN_LIMIT_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
'ip_login_limit_use_forwarded' => array('lang' => 'IP_LOGIN_LIMIT_USE_FORWARDED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'ip_login_limit_use_forwarded' => array('lang' => 'IP_LOGIN_LIMIT_USE_FORWARDED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'tpl_allow_php' => array('lang' => 'TPL_ALLOW_PHP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'tpl_allow_php' => array('lang' => 'TPL_ALLOW_PHP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'form_token_lifetime' => array('lang' => 'FORM_TIME_MAX', 'validate' => 'int:-1', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'form_token_lifetime' => array('lang' => 'FORM_TIME_MAX', 'validate' => 'int:-1:99999', 'type' => 'number:-1:99999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
'form_token_sid_guests' => array('lang' => 'FORM_SID_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'form_token_sid_guests' => array('lang' => 'FORM_SID_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
) )
@ -428,16 +430,16 @@ class acp_board
'email_enable' => array('lang' => 'ENABLE_EMAIL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'email_enable' => array('lang' => 'ENABLE_EMAIL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true),
'board_email_form' => array('lang' => 'BOARD_EMAIL_FORM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'board_email_form' => array('lang' => 'BOARD_EMAIL_FORM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true),
'email_function_name' => array('lang' => 'EMAIL_FUNCTION_NAME', 'validate' => 'string', 'type' => 'text:20:50', 'explain' => true), 'email_function_name' => array('lang' => 'EMAIL_FUNCTION_NAME', 'validate' => 'string', 'type' => 'text:20:50', 'explain' => true),
'email_package_size' => array('lang' => 'EMAIL_PACKAGE_SIZE', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true), 'email_package_size' => array('lang' => 'EMAIL_PACKAGE_SIZE', 'validate' => 'int:0', 'type' => 'number:0:99999', 'explain' => true),
'board_contact' => array('lang' => 'CONTACT_EMAIL', 'validate' => 'email', 'type' => 'text:25:100', 'explain' => true), 'board_contact' => array('lang' => 'CONTACT_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true),
'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'email', 'type' => 'text:25:100', 'explain' => true), 'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true),
'board_email_sig' => array('lang' => 'EMAIL_SIG', 'validate' => 'string', 'type' => 'textarea:5:30', 'explain' => true), 'board_email_sig' => array('lang' => 'EMAIL_SIG', 'validate' => 'string', 'type' => 'textarea:5:30', 'explain' => true),
'board_hide_emails' => array('lang' => 'BOARD_HIDE_EMAILS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'board_hide_emails' => array('lang' => 'BOARD_HIDE_EMAILS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend2' => 'SMTP_SETTINGS', 'legend2' => 'SMTP_SETTINGS',
'smtp_delivery' => array('lang' => 'USE_SMTP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'smtp_delivery' => array('lang' => 'USE_SMTP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'smtp_host' => array('lang' => 'SMTP_SERVER', 'validate' => 'string', 'type' => 'text:25:50', 'explain' => false), 'smtp_host' => array('lang' => 'SMTP_SERVER', 'validate' => 'string', 'type' => 'text:25:50', 'explain' => false),
'smtp_port' => array('lang' => 'SMTP_PORT', 'validate' => 'int:0', 'type' => 'text:4:5', 'explain' => true), 'smtp_port' => array('lang' => 'SMTP_PORT', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true),
'smtp_auth_method' => array('lang' => 'SMTP_AUTH_METHOD', 'validate' => 'string', 'type' => 'select', 'method' => 'mail_auth_select', 'explain' => true), 'smtp_auth_method' => array('lang' => 'SMTP_AUTH_METHOD', 'validate' => 'string', 'type' => 'select', 'method' => 'mail_auth_select', 'explain' => true),
'smtp_username' => array('lang' => 'SMTP_USERNAME', 'validate' => 'string', 'type' => 'text:25:255', 'explain' => true), 'smtp_username' => array('lang' => 'SMTP_USERNAME', 'validate' => 'string', 'type' => 'text:25:255', 'explain' => true),
'smtp_password' => array('lang' => 'SMTP_PASSWORD', 'validate' => 'string', 'type' => 'password:25:255', 'explain' => true), 'smtp_password' => array('lang' => 'SMTP_PASSWORD', 'validate' => 'string', 'type' => 'password:25:255', 'explain' => true),
@ -520,36 +522,13 @@ class acp_board
if ($mode == 'auth') if ($mode == 'auth')
{ {
// Retrieve a list of auth plugins and check their config values // Retrieve a list of auth plugins and check their config values
$auth_plugins = array(); $auth_providers = $phpbb_container->get('auth.provider_collection');
$dp = @opendir($phpbb_root_path . 'includes/auth');
if ($dp)
{
while (($file = readdir($dp)) !== false)
{
if (preg_match('#^auth_(.*?)\.' . $phpEx . '$#', $file))
{
$auth_plugins[] = basename(preg_replace('#^auth_(.*?)\.' . $phpEx . '$#', '\1', $file));
}
}
closedir($dp);
sort($auth_plugins);
}
$updated_auth_settings = false; $updated_auth_settings = false;
$old_auth_config = array(); $old_auth_config = array();
foreach ($auth_plugins as $method) foreach ($auth_providers as $provider)
{ {
if ($method && file_exists($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx)) if ($fields = $provider->acp($this->new_config))
{
include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
$method = 'acp_' . $method;
if (function_exists($method))
{
if ($fields = $method($this->new_config))
{ {
// Check if we need to create config fields for this plugin and save config when submit was pressed // Check if we need to create config fields for this plugin and save config when submit was pressed
foreach ($fields['config'] as $field) foreach ($fields['config'] as $field)
@ -577,20 +556,14 @@ class acp_board
} }
unset($fields); unset($fields);
} }
}
}
if ($submit && (($cfg_array['auth_method'] != $this->new_config['auth_method']) || $updated_auth_settings)) if ($submit && (($cfg_array['auth_method'] != $this->new_config['auth_method']) || $updated_auth_settings))
{ {
$method = basename($cfg_array['auth_method']); $method = basename($cfg_array['auth_method']);
if ($method && in_array($method, $auth_plugins)) if (array_key_exists('auth.provider.' . $method, $auth_providers))
{ {
include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx); $provider = $auth_providers['auth.provider.' . $method];
if ($error = $provider->init())
$method = 'init_' . $method;
if (function_exists($method))
{
if ($error = $method())
{ {
foreach ($old_auth_config as $config_name => $config_value) foreach ($old_auth_config as $config_name => $config_value)
{ {
@ -598,7 +571,6 @@ class acp_board
} }
trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING); trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
} }
}
set_config('auth_method', basename($cfg_array['auth_method'])); set_config('auth_method', basename($cfg_array['auth_method']));
} }
else else
@ -681,53 +653,36 @@ class acp_board
{ {
$template->assign_var('S_AUTH', true); $template->assign_var('S_AUTH', true);
foreach ($auth_plugins as $method) foreach ($auth_providers as $provider)
{ {
if ($method && file_exists($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx)) $fields = $provider->acp($this->new_config);
{
$method = 'acp_' . $method;
if (function_exists($method))
{
$fields = $method($this->new_config);
if ($fields['tpl']) if ($fields['tpl'])
{ {
$template->assign_block_vars('auth_tpl', array( $template->assign_block_vars('auth_tpl', array(
'TPL' => $fields['tpl']) 'TPL' => $fields['tpl'],
); ));
} }
unset($fields); unset($fields);
} }
} }
} }
}
}
/** /**
* Select auth method * Select auth method
*/ */
function select_auth_method($selected_method, $key = '') function select_auth_method($selected_method, $key = '')
{ {
global $phpbb_root_path, $phpEx; global $phpbb_root_path, $phpEx, $phpbb_container;
$auth_plugins = array(); $auth_plugins = array();
$auth_providers = $phpbb_container->get('auth.provider_collection');
$dp = @opendir($phpbb_root_path . 'includes/auth'); foreach($auth_providers as $key => $value)
if (!$dp)
{ {
return ''; $auth_plugins[] = str_replace('auth.provider.', '', $key);
} }
while (($file = readdir($dp)) !== false)
{
if (preg_match('#^auth_(.*?)\.' . $phpEx . '$#', $file))
{
$auth_plugins[] = preg_replace('#^auth_(.*?)\.' . $phpEx . '$#', '\1', $file);
}
}
closedir($dp);
sort($auth_plugins); sort($auth_plugins);
$auth_select = ''; $auth_select = '';
@ -822,7 +777,7 @@ class acp_board
{ {
global $user; global $user;
return '<input id="' . $key . '" type="text" size="3" maxlength="3" name="config[min_name_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . '&nbsp;&nbsp;<input type="text" size="3" maxlength="3" name="config[max_name_chars]" value="' . $this->new_config['max_name_chars'] . '" /> ' . $user->lang['MAX_CHARS']; return '<input id="' . $key . '" type="number" size="3" maxlength="3" min="1" max="999" name="config[min_name_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . '&nbsp;&nbsp;<input type="number" size="3" maxlength="3" min="8" max="180" name="config[max_name_chars]" value="' . $this->new_config['max_name_chars'] . '" /> ' . $user->lang['MAX_CHARS'];
} }
/** /**
@ -850,7 +805,7 @@ class acp_board
{ {
global $user; global $user;
return '<input id="' . $key . '" type="text" size="3" maxlength="3" name="config[min_pass_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . '&nbsp;&nbsp;<input type="text" size="3" maxlength="3" name="config[max_pass_chars]" value="' . $this->new_config['max_pass_chars'] . '" /> ' . $user->lang['MAX_CHARS']; return '<input id="' . $key . '" type="number" size="3" maxlength="3" min="1" max="999" name="config[min_pass_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . '&nbsp;&nbsp;<input type="number" size="3" maxlength="3" min="8" max="255" name="config[max_pass_chars]" value="' . $this->new_config['max_pass_chars'] . '" /> ' . $user->lang['MAX_CHARS'];
} }
/** /**

View file

@ -124,6 +124,8 @@ class acp_captcha
'CAPTCHA_PREVIEW_TPL' => $demo_captcha->get_demo_template($id), 'CAPTCHA_PREVIEW_TPL' => $demo_captcha->get_demo_template($id),
'S_CAPTCHA_HAS_CONFIG' => $demo_captcha->has_config(), 'S_CAPTCHA_HAS_CONFIG' => $demo_captcha->has_config(),
'CAPTCHA_SELECT' => $captcha_select, 'CAPTCHA_SELECT' => $captcha_select,
'U_ACTION' => $this->u_action,
)); ));
} }
} }

View file

@ -44,6 +44,10 @@ class acp_extensions
$action = $request->variable('action', 'list'); $action = $request->variable('action', 'list');
$ext_name = $request->variable('ext_name', ''); $ext_name = $request->variable('ext_name', '');
// What is a safe limit of execution time? Half the max execution time should be safe.
$safe_time_limit = (ini_get('max_execution_time') / 2);
$start_time = time();
// Cancel action // Cancel action
if ($request->is_set_post('cancel')) if ($request->is_set_post('cancel'))
{ {
@ -54,7 +58,7 @@ class acp_extensions
// If they've specified an extension, let's load the metadata manager and validate it. // If they've specified an extension, let's load the metadata manager and validate it.
if ($ext_name) if ($ext_name)
{ {
$md_manager = new phpbb_extension_metadata_manager($ext_name, $db, $phpbb_extension_manager, $phpbb_root_path, ".$phpEx", $template, $config); $md_manager = new phpbb_extension_metadata_manager($ext_name, $config, $phpbb_extension_manager, $template, $phpbb_root_path);
try try
{ {
@ -81,7 +85,7 @@ class acp_extensions
case 'enable_pre': case 'enable_pre':
if (!$md_manager->validate_enable()) if (!$md_manager->validate_enable())
{ {
trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action)); trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
} }
if ($phpbb_extension_manager->enabled($ext_name)) if ($phpbb_extension_manager->enabled($ext_name))
@ -100,18 +104,22 @@ class acp_extensions
case 'enable': case 'enable':
if (!$md_manager->validate_enable()) if (!$md_manager->validate_enable())
{ {
trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action)); trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
} }
try try
{ {
if ($phpbb_extension_manager->enable_step($ext_name)) while ($phpbb_extension_manager->enable_step($ext_name))
{
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{ {
$template->assign_var('S_NEXT_STEP', true); $template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=enable&amp;ext_name=' . urlencode($ext_name)); meta_refresh(0, $this->u_action . '&amp;action=enable&amp;ext_name=' . urlencode($ext_name));
} }
} }
}
catch (phpbb_db_migration_exception $e) catch (phpbb_db_migration_exception $e)
{ {
$template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user)); $template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user));
@ -139,12 +147,16 @@ class acp_extensions
break; break;
case 'disable': case 'disable':
if ($phpbb_extension_manager->disable_step($ext_name)) while ($phpbb_extension_manager->disable_step($ext_name))
{
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{ {
$template->assign_var('S_NEXT_STEP', true); $template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=disable&amp;ext_name=' . urlencode($ext_name)); meta_refresh(0, $this->u_action . '&amp;action=disable&amp;ext_name=' . urlencode($ext_name));
} }
}
$this->tpl_name = 'acp_ext_disable'; $this->tpl_name = 'acp_ext_disable';
@ -165,13 +177,17 @@ class acp_extensions
case 'purge': case 'purge':
try try
{ {
if ($phpbb_extension_manager->purge_step($ext_name)) while ($phpbb_extension_manager->purge_step($ext_name))
{
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{ {
$template->assign_var('S_NEXT_STEP', true); $template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=purge&amp;ext_name=' . urlencode($ext_name)); meta_refresh(0, $this->u_action . '&amp;action=purge&amp;ext_name=' . urlencode($ext_name));
} }
} }
}
catch (phpbb_db_migration_exception $e) catch (phpbb_db_migration_exception $e)
{ {
$template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user)); $template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user));

View file

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

View file

@ -115,7 +115,7 @@ class acp_inactive
{ {
$messenger->template('admin_welcome_activated', $row['user_lang']); $messenger->template('admin_welcome_activated', $row['user_lang']);
$messenger->to($row['user_email'], $row['username']); $messenger->set_addresses($row);
$messenger->anti_abuse_headers($config, $user); $messenger->anti_abuse_headers($config, $user);
@ -203,8 +203,7 @@ class acp_inactive
{ {
$messenger->template('user_remind_inactive', $row['user_lang']); $messenger->template('user_remind_inactive', $row['user_lang']);
$messenger->to($row['user_email'], $row['username']); $messenger->set_addresses($row);
$messenger->im($row['user_jabber'], $row['username']);
$messenger->anti_abuse_headers($config, $user); $messenger->anti_abuse_headers($config, $user);

View file

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

View file

@ -21,6 +21,7 @@ if (!defined('IN_PHPBB'))
class acp_permission_roles class acp_permission_roles
{ {
var $u_action; var $u_action;
protected $auth_admin;
function main($id, $mode) function main($id, $mode)
{ {
@ -30,7 +31,7 @@ class acp_permission_roles
include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
$auth_admin = new auth_admin(); $this->auth_admin = new auth_admin();
$user->add_lang('acp/permissions'); $user->add_lang('acp/permissions');
add_permission_language(); add_permission_language();
@ -210,7 +211,7 @@ class acp_permission_roles
} }
// Now add the auth settings // Now add the auth settings
$auth_admin->acl_set_role($role_id, $auth_settings); $this->auth_admin->acl_set_role($role_id, $auth_settings);
$role_name = (!empty($user->lang[$role_name])) ? $user->lang[$role_name] : $role_name; $role_name = (!empty($user->lang[$role_name])) ? $user->lang[$role_name] : $role_name;
add_log('admin', 'LOG_' . strtoupper($permission_type) . 'ROLE_' . strtoupper($action), $role_name); add_log('admin', 'LOG_' . strtoupper($permission_type) . 'ROLE_' . strtoupper($action), $role_name);
@ -343,7 +344,7 @@ class acp_permission_roles
// Get users/groups/forums using this preset... // Get users/groups/forums using this preset...
if ($action == 'edit') if ($action == 'edit')
{ {
$hold_ary = $auth_admin->get_role_mask($role_id); $hold_ary = $this->auth_admin->get_role_mask($role_id);
if (sizeof($hold_ary)) if (sizeof($hold_ary))
{ {
@ -354,7 +355,7 @@ class acp_permission_roles
'L_ROLE_ASSIGNED_TO' => sprintf($user->lang['ROLE_ASSIGNED_TO'], $role_name)) 'L_ROLE_ASSIGNED_TO' => sprintf($user->lang['ROLE_ASSIGNED_TO'], $role_name))
); );
$auth_admin->display_role_mask($hold_ary); $this->auth_admin->display_role_mask($hold_ary);
} }
} }
@ -445,8 +446,8 @@ class acp_permission_roles
'S_DISPLAY_ROLE_MASK' => true) 'S_DISPLAY_ROLE_MASK' => true)
); );
$hold_ary = $auth_admin->get_role_mask($display_item); $hold_ary = $this->auth_admin->get_role_mask($display_item);
$auth_admin->display_role_mask($hold_ary); $this->auth_admin->display_role_mask($hold_ary);
} }
} }
@ -462,7 +463,7 @@ class acp_permission_roles
$auth_options = array(0 => $auth_options); $auth_options = array(0 => $auth_options);
// Making use of auth_admin method here (we do not really want to change two similar code fragments) // Making use of auth_admin method here (we do not really want to change two similar code fragments)
auth_admin::build_permission_array($auth_options, $content_array, $categories, $key_sort_array); $this->auth_admin->build_permission_array($auth_options, $content_array, $categories, $key_sort_array);
$content_array = $content_array[0]; $content_array = $content_array[0];
@ -500,8 +501,6 @@ class acp_permission_roles
{ {
global $db; global $db;
$auth_admin = new auth_admin();
// Get complete auth array // Get complete auth array
$sql = 'SELECT auth_option, auth_option_id $sql = 'SELECT auth_option, auth_option_id
FROM ' . ACL_OPTIONS_TABLE . " FROM ' . ACL_OPTIONS_TABLE . "
@ -529,19 +528,19 @@ class acp_permission_roles
$db->sql_freeresult($result); $db->sql_freeresult($result);
// Get role assignments // Get role assignments
$hold_ary = $auth_admin->get_role_mask($role_id); $hold_ary = $this->auth_admin->get_role_mask($role_id);
// Re-assign permissions // Re-assign permissions
foreach ($hold_ary as $forum_id => $forum_ary) foreach ($hold_ary as $forum_id => $forum_ary)
{ {
if (isset($forum_ary['users'])) if (isset($forum_ary['users']))
{ {
$auth_admin->acl_set('user', $forum_id, $forum_ary['users'], $auth_settings, 0, false); $this->auth_admin->acl_set('user', $forum_id, $forum_ary['users'], $auth_settings, 0, false);
} }
if (isset($forum_ary['groups'])) if (isset($forum_ary['groups']))
{ {
$auth_admin->acl_set('group', $forum_id, $forum_ary['groups'], $auth_settings, 0, false); $this->auth_admin->acl_set('group', $forum_id, $forum_ary['groups'], $auth_settings, 0, false);
} }
} }
@ -563,6 +562,6 @@ class acp_permission_roles
WHERE role_id = ' . $role_id; WHERE role_id = ' . $role_id;
$db->sql_query($sql); $db->sql_query($sql);
$auth_admin->acl_clear_prefetch(); $this->auth_admin->acl_clear_prefetch();
} }
} }

View file

@ -331,7 +331,7 @@ class acp_prune
$s_find_active_time .= '<option value="' . $key . '">' . $value . '</option>'; $s_find_active_time .= '<option value="' . $key . '">' . $value . '</option>';
} }
$s_group_list = ''; $s_group_list = '<option value="0"></option>';
$sql = 'SELECT group_id, group_name $sql = 'SELECT group_id, group_name
FROM ' . GROUPS_TABLE . ' FROM ' . GROUPS_TABLE . '
WHERE group_type <> ' . GROUP_SPECIAL . ' WHERE group_type <> ' . GROUP_SPECIAL . '
@ -340,7 +340,7 @@ class acp_prune
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
{ {
$s_group_list .= '<option value="' . $row['group_id'] . '">' . $row['group_name'] . '</select>'; $s_group_list .= '<option value="' . $row['group_id'] . '">' . $row['group_name'] . '</option>';
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
@ -491,11 +491,12 @@ class acp_prune
if ($group_id) if ($group_id)
{ {
$sql = 'SELECT user_id $sql = 'SELECT u.user_id, u.username
FROM ' . USER_GROUP_TABLE . ' FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . ' u
WHERE group_id = ' . (int) $group_id . ' WHERE ug.group_id = ' . (int) $group_id . '
AND user_pending = 0 AND ug.user_pending = 0
AND ' . $db->sql_in_set('user_id', $user_ids, false, true); AND ' . $db->sql_in_set('ug.user_id', $user_ids, false, true) . '
AND u.user_id = ug.user_id';
$result = $db->sql_query($sql); $result = $db->sql_query($sql);
// we're performing an intersection operation, so all the relevant users // we're performing an intersection operation, so all the relevant users
@ -504,24 +505,19 @@ class acp_prune
$user_ids = $usernames = array(); $user_ids = $usernames = array();
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
{ {
$user_ids[] = $row['poster_id']; $user_ids[] = $row['user_id'];
$usernames[$row['user_id']] = $row['username'];
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
// only get usernames if they are needed (not part of some later query)
if (!$posts_on_queue)
{
// this is an additional query aginst the users table
user_get_id_name($user_ids, $usernames);
}
} }
if ($posts_on_queue) if ($posts_on_queue)
{ {
$sql = 'SELECT poster_id, COUNT(post_id) AS queue_posts $sql = 'SELECT u.user_id, u.username, COUNT(p.post_id) AS queue_posts
FROM ' . POSTS_TABLE . ' FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
WHERE ' . $db->sql_in_set('poster_id', $user_ids, false, true) . ' WHERE ' . $db->sql_in_set('p.poster_id', $user_ids, false, true) . '
GROUP BY poster_id AND u.user_id = p.poster_id
GROUP BY p.poster_id
HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue; HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue;
$result = $db->sql_query($result); $result = $db->sql_query($result);
@ -529,12 +525,10 @@ class acp_prune
$user_ids = $usernames = array(); $user_ids = $usernames = array();
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
{ {
$user_ids[] = $row['poster_id']; $user_ids[] = $row['user_id'];
$usernames[$row['user_id']] = $row['username'];
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
// do an additional query to get the correct set of usernames
user_get_id_name($user_ids, $usernames);
} }
} }
} }

View file

@ -68,13 +68,20 @@ class acp_styles
$action = $this->request->variable('action', ''); $action = $this->request->variable('action', '');
$post_actions = array('install', 'activate', 'deactivate', 'uninstall'); $post_actions = array('install', 'activate', 'deactivate', 'uninstall');
if ($action && in_array($action, $post_actions) && !check_link_hash($request->variable('hash', ''), $action))
{
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
foreach ($post_actions as $key) foreach ($post_actions as $key)
{ {
if (isset($_POST[$key])) if ($this->request->is_set_post($key))
{ {
$action = $key; $action = $key;
} }
} }
if ($action != '') if ($action != '')
{ {
$this->s_hidden_fields['action'] = $action; $this->s_hidden_fields['action'] = $action;
@ -921,21 +928,23 @@ class acp_styles
'L_ACTION' => $this->user->lang['DETAILS'] 'L_ACTION' => $this->user->lang['DETAILS']
); );
// Activate // Activate/Deactive
$action_name = ($style['style_active'] ? 'de' : '') . 'activate';
$actions[] = array( $actions[] = array(
'U_ACTION' => $this->u_action . '&amp;action=' . ($style['style_active'] ? 'de' : '') . 'activate&amp;id=' . $style['style_id'], 'U_ACTION' => $this->u_action . '&amp;action=' . $action_name . '&amp;hash=' . generate_link_hash($action_name) . '&amp;id=' . $style['style_id'],
'L_ACTION' => $this->user->lang['STYLE_' . ($style['style_active'] ? 'DE' : '') . 'ACTIVATE'] 'L_ACTION' => $this->user->lang['STYLE_' . ($style['style_active'] ? 'DE' : '') . 'ACTIVATE']
); );
/* // Export /* // Export
$actions[] = array( $actions[] = array(
'U_ACTION' => $this->u_action . '&amp;action=export&amp;id=' . $style['style_id'], 'U_ACTION' => $this->u_action . '&amp;action=export&amp;hash=' . generate_link_hash('export') . '&amp;id=' . $style['style_id'],
'L_ACTION' => $this->user->lang['EXPORT'] 'L_ACTION' => $this->user->lang['EXPORT']
); */ ); */
// Uninstall // Uninstall
$actions[] = array( $actions[] = array(
'U_ACTION' => $this->u_action . '&amp;action=uninstall&amp;id=' . $style['style_id'], 'U_ACTION' => $this->u_action . '&amp;action=uninstall&amp;hash=' . generate_link_hash('uninstall') . '&amp;id=' . $style['style_id'],
'L_ACTION' => $this->user->lang['STYLE_UNINSTALL'] 'L_ACTION' => $this->user->lang['STYLE_UNINSTALL']
); );
@ -957,7 +966,7 @@ class acp_styles
else else
{ {
$actions[] = array( $actions[] = array(
'U_ACTION' => $this->u_action . '&amp;action=install&amp;dir=' . urlencode($style['style_path']), 'U_ACTION' => $this->u_action . '&amp;action=install&amp;hash=' . generate_link_hash('install') . '&amp;dir=' . urlencode($style['style_path']),
'L_ACTION' => $this->user->lang['INSTALL_STYLE'] 'L_ACTION' => $this->user->lang['INSTALL_STYLE']
); );
} }

View file

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

View file

@ -347,7 +347,7 @@ class acp_users
$messenger->template($email_template, $user_row['user_lang']); $messenger->template($email_template, $user_row['user_lang']);
$messenger->to($user_row['user_email'], $user_row['username']); $messenger->set_addresses($user_row);
$messenger->anti_abuse_headers($config, $user); $messenger->anti_abuse_headers($config, $user);
@ -402,7 +402,7 @@ class acp_users
$messenger->template('admin_welcome_activated', $user_row['user_lang']); $messenger->template('admin_welcome_activated', $user_row['user_lang']);
$messenger->to($user_row['user_email'], $user_row['username']); $messenger->set_addresses($user_row);
$messenger->anti_abuse_headers($config, $user); $messenger->anti_abuse_headers($config, $user);

View file

@ -927,15 +927,14 @@ class phpbb_auth
*/ */
function login($username, $password, $autologin = false, $viewonline = 1, $admin = 0) function login($username, $password, $autologin = false, $viewonline = 1, $admin = 0)
{ {
global $config, $db, $user, $phpbb_root_path, $phpEx; global $config, $db, $user, $phpbb_root_path, $phpEx, $phpbb_container;
$method = trim(basename($config['auth_method'])); $method = trim(basename($config['auth_method']));
include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
$method = 'login_' . $method; $provider = $phpbb_container->get('auth.provider.' . $method);
if (function_exists($method)) if ($provider)
{ {
$login = $method($username, $password, $user->ip, $user->browser, $user->forwarded_for); $login = $provider->login($username, $password);
// If the auth module wants us to create an empty profile do so and then treat the status as LOGIN_SUCCESS // 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) if ($login['status'] == LOGIN_SUCCESS_CREATE_PROFILE)

View file

@ -1,247 +0,0 @@
<?php
/**
* Apache auth plug-in for phpBB3
*
* Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him.
*
* @package login
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Checks whether the user is identified to apache
* Only allow changing authentication to apache if the user is identified
* Called in acp_board while setting authentication plugins
*
* @return boolean|string false if the user is identified and else an error message
*/
function init_apache()
{
global $user, $request;
if (!$request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER) || $user->data['username'] !== htmlspecialchars_decode($request->server('PHP_AUTH_USER')))
{
return $user->lang['APACHE_SETUP_BEFORE_USE'];
}
return false;
}
/**
* Login function
*/
function login_apache(&$username, &$password)
{
global $db, $request;
// do not allow empty password
if (!$password)
{
return array(
'status' => LOGIN_ERROR_PASSWORD,
'error_msg' => 'NO_PASSWORD_SUPPLIED',
'user_row' => array('user_id' => ANONYMOUS),
);
}
if (!$username)
{
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
if (!$request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
{
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE',
'user_row' => array('user_id' => ANONYMOUS),
);
}
$php_auth_user = htmlspecialchars_decode($request->server('PHP_AUTH_USER'));
$php_auth_pw = htmlspecialchars_decode($request->server('PHP_AUTH_PW'));
if (!empty($php_auth_user) && !empty($php_auth_pw))
{
if ($php_auth_user !== $username)
{
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
$sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type
FROM ' . USERS_TABLE . "
WHERE username = '" . $db->sql_escape($php_auth_user) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
// User inactive...
if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
{
return array(
'status' => LOGIN_ERROR_ACTIVE,
'error_msg' => 'ACTIVE_ERROR',
'user_row' => $row,
);
}
// Successful login...
return array(
'status' => LOGIN_SUCCESS,
'error_msg' => false,
'user_row' => $row,
);
}
// this is the user's first login so create an empty profile
return array(
'status' => LOGIN_SUCCESS_CREATE_PROFILE,
'error_msg' => false,
'user_row' => user_row_apache($php_auth_user, $php_auth_pw),
);
}
// Not logged into apache
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE',
'user_row' => array('user_id' => ANONYMOUS),
);
}
/**
* Autologin function
*
* @return array containing the user row or empty if no auto login should take place
*/
function autologin_apache()
{
global $db, $request;
if (!$request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
{
return array();
}
$php_auth_user = htmlspecialchars_decode($request->server('PHP_AUTH_USER'));
$php_auth_pw = htmlspecialchars_decode($request->server('PHP_AUTH_PW'));
if (!empty($php_auth_user) && !empty($php_auth_pw))
{
set_var($php_auth_user, $php_auth_user, 'string', true);
set_var($php_auth_pw, $php_auth_pw, 'string', true);
$sql = 'SELECT *
FROM ' . USERS_TABLE . "
WHERE username = '" . $db->sql_escape($php_auth_user) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
return ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE) ? array() : $row;
}
if (!function_exists('user_add'))
{
global $phpbb_root_path, $phpEx;
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
}
// create the user if he does not exist yet
user_add(user_row_apache($php_auth_user, $php_auth_pw));
$sql = 'SELECT *
FROM ' . USERS_TABLE . "
WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($php_auth_user)) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
return $row;
}
}
return array();
}
/**
* This function generates an array which can be passed to the user_add function in order to create a user
*/
function user_row_apache($username, $password)
{
global $db, $config, $user;
// first retrieve default group id
$sql = 'SELECT group_id
FROM ' . GROUPS_TABLE . "
WHERE group_name = '" . $db->sql_escape('REGISTERED') . "'
AND group_type = " . GROUP_SPECIAL;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$row)
{
trigger_error('NO_GROUP');
}
// generate user account data
return array(
'username' => $username,
'user_password' => phpbb_hash($password),
'user_email' => '',
'group_id' => (int) $row['group_id'],
'user_type' => USER_NORMAL,
'user_ip' => $user->ip,
'user_new' => ($config['new_member_post_limit']) ? 1 : 0,
);
}
/**
* The session validation function checks whether the user is still logged in
*
* @return boolean true if the given user is authenticated or false if the session should be closed
*/
function validate_session_apache(&$user)
{
global $request;
// Check if PHP_AUTH_USER is set and handle this case
if ($request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
{
$php_auth_user = $request->server('PHP_AUTH_USER');
return ($php_auth_user === $user['username']) ? true : false;
}
// PHP_AUTH_USER is not set. A valid session is now determined by the user type (anonymous/bot or not)
if ($user['user_type'] == USER_IGNORE)
{
return true;
}
return false;
}

View file

@ -1,289 +0,0 @@
<?php
/**
* Database auth plug-in for phpBB3
*
* Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him.
*
* This is for authentication via the integrated user table
*
* @package login
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* 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, $ip = '', $browser = '', $forwarded_for = '')
{
global $db, $config;
global $request;
// Auth plugins get the password untrimmed.
// For compatibility we trim() here.
$password = trim($password);
// do not allow empty password
if (!$password)
{
return array(
'status' => LOGIN_ERROR_PASSWORD,
'error_msg' => 'NO_PASSWORD_SUPPLIED',
'user_row' => array('user_id' => ANONYMOUS),
);
}
if (!$username)
{
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
$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($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)
{
if ($config['ip_login_limit_max'] && $attempts >= $config['ip_login_limit_max'])
{
return array(
'status' => LOGIN_ERROR_ATTEMPTS,
'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
'user_row' => array('user_id' => ANONYMOUS),
);
}
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
$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...
if ($show_captcha)
{
// Visual Confirmation handling
if (!class_exists('phpbb_captcha_factory', false))
{
global $phpbb_root_path, $phpEx;
include ($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
}
$captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
$vc_response = $captcha->validate($row);
if ($vc_response)
{
return array(
'status' => LOGIN_ERROR_ATTEMPTS,
'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
'user_row' => $row,
);
}
else
{
$captcha->reset();
}
}
// If the password convert flag is set we need to convert it
if ($row['user_pass_convert'])
{
// enable super globals to get literal value
// this is needed to prevent unicode normalization
$super_globals_disabled = $request->super_globals_disabled();
if ($super_globals_disabled)
{
$request->enable_super_globals();
}
// in phpBB2 passwords were used exactly as they were sent, with addslashes applied
$password_old_format = isset($_REQUEST['password']) ? (string) $_REQUEST['password'] : '';
$password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format;
$password_new_format = $request->variable('password', '', true);
if ($super_globals_disabled)
{
$request->disable_super_globals();
}
if ($password == $password_new_format)
{
if (!function_exists('utf8_to_cp1252'))
{
global $phpbb_root_path, $phpEx;
include($phpbb_root_path . 'includes/utf/data/recode_basic.' . $phpEx);
}
// cp1252 is phpBB2's default encoding, characters outside ASCII range might work when converted into that encoding
// plain md5 support left in for conversions from other systems.
if ((strlen($row['user_password']) == 34 && (phpbb_check_hash(md5($password_old_format), $row['user_password']) || phpbb_check_hash(md5(utf8_to_cp1252($password_old_format)), $row['user_password'])))
|| (strlen($row['user_password']) == 32 && (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password'])))
{
$hash = phpbb_hash($password_new_format);
// Update the password in the users table to the new format and remove user_pass_convert flag
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_password = \'' . $db->sql_escape($hash) . '\',
user_pass_convert = 0
WHERE user_id = ' . $row['user_id'];
$db->sql_query($sql);
$row['user_pass_convert'] = 0;
$row['user_password'] = $hash;
}
else
{
// Although we weren't able to convert this password we have to
// increase login attempt count to make sure this cannot be exploited
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_login_attempts = user_login_attempts + 1
WHERE user_id = ' . (int) $row['user_id'] . '
AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
$db->sql_query($sql);
return array(
'status' => LOGIN_ERROR_PASSWORD_CONVERT,
'error_msg' => 'LOGIN_ERROR_PASSWORD_CONVERT',
'user_row' => $row,
);
}
}
}
// Check password ...
if (!$row['user_pass_convert'] && phpbb_check_hash($password, $row['user_password']))
{
// Check for old password hash...
if (strlen($row['user_password']) == 32)
{
$hash = phpbb_hash($password);
// Update the password in the users table to the new format
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_password = '" . $db->sql_escape($hash) . "',
user_pass_convert = 0
WHERE user_id = {$row['user_id']}";
$db->sql_query($sql);
$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)
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_login_attempts = 0
WHERE user_id = ' . $row['user_id'];
$db->sql_query($sql);
}
// User inactive...
if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
{
return array(
'status' => LOGIN_ERROR_ACTIVE,
'error_msg' => 'ACTIVE_ERROR',
'user_row' => $row,
);
}
// Successful login... set user_login_attempts to zero...
return array(
'status' => LOGIN_SUCCESS,
'error_msg' => false,
'user_row' => $row,
);
}
// Password incorrect - increase login attempts
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_login_attempts = user_login_attempts + 1
WHERE user_id = ' . (int) $row['user_id'] . '
AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
$db->sql_query($sql);
// Give status about wrong password...
return array(
'status' => ($show_captcha) ? LOGIN_ERROR_ATTEMPTS : LOGIN_ERROR_PASSWORD,
'error_msg' => ($show_captcha) ? 'LOGIN_ERROR_ATTEMPTS' : 'LOGIN_ERROR_PASSWORD',
'user_row' => $row,
);
}

View file

@ -1,350 +0,0 @@
<?php
/**
*
* LDAP auth plug-in for phpBB3
*
* Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him.
*
* @package login
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Connect to ldap server
* Only allow changing authentication to ldap if we can connect to the ldap server
* Called in acp_board while setting authentication plugins
*/
function init_ldap()
{
global $config, $user;
if (!@extension_loaded('ldap'))
{
return $user->lang['LDAP_NO_LDAP_EXTENSION'];
}
$config['ldap_port'] = (int) $config['ldap_port'];
if ($config['ldap_port'])
{
$ldap = @ldap_connect($config['ldap_server'], $config['ldap_port']);
}
else
{
$ldap = @ldap_connect($config['ldap_server']);
}
if (!$ldap)
{
return $user->lang['LDAP_NO_SERVER_CONNECTION'];
}
@ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
@ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
if ($config['ldap_user'] || $config['ldap_password'])
{
if (!@ldap_bind($ldap, htmlspecialchars_decode($config['ldap_user']), htmlspecialchars_decode($config['ldap_password'])))
{
return $user->lang['LDAP_INCORRECT_USER_PASSWORD'];
}
}
// ldap_connect only checks whether the specified server is valid, so the connection might still fail
$search = @ldap_search(
$ldap,
htmlspecialchars_decode($config['ldap_base_dn']),
ldap_user_filter($user->data['username']),
(empty($config['ldap_email'])) ?
array(htmlspecialchars_decode($config['ldap_uid'])) :
array(htmlspecialchars_decode($config['ldap_uid']), htmlspecialchars_decode($config['ldap_email'])),
0,
1
);
if ($search === false)
{
return $user->lang['LDAP_SEARCH_FAILED'];
}
$result = @ldap_get_entries($ldap, $search);
@ldap_close($ldap);
if (!is_array($result) || sizeof($result) < 2)
{
return sprintf($user->lang['LDAP_NO_IDENTITY'], $user->data['username']);
}
if (!empty($config['ldap_email']) && !isset($result[0][htmlspecialchars_decode($config['ldap_email'])]))
{
return $user->lang['LDAP_NO_EMAIL'];
}
return false;
}
/**
* Login function
*/
function login_ldap(&$username, &$password)
{
global $db, $config, $user;
// do not allow empty password
if (!$password)
{
return array(
'status' => LOGIN_ERROR_PASSWORD,
'error_msg' => 'NO_PASSWORD_SUPPLIED',
'user_row' => array('user_id' => ANONYMOUS),
);
}
if (!$username)
{
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
if (!@extension_loaded('ldap'))
{
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LDAP_NO_LDAP_EXTENSION',
'user_row' => array('user_id' => ANONYMOUS),
);
}
$config['ldap_port'] = (int) $config['ldap_port'];
if ($config['ldap_port'])
{
$ldap = @ldap_connect($config['ldap_server'], $config['ldap_port']);
}
else
{
$ldap = @ldap_connect($config['ldap_server']);
}
if (!$ldap)
{
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LDAP_NO_SERVER_CONNECTION',
'user_row' => array('user_id' => ANONYMOUS),
);
}
@ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
@ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
if ($config['ldap_user'] || $config['ldap_password'])
{
if (!@ldap_bind($ldap, htmlspecialchars_decode($config['ldap_user']), htmlspecialchars_decode($config['ldap_password'])))
{
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LDAP_NO_SERVER_CONNECTION',
'user_row' => array('user_id' => ANONYMOUS),
);
}
}
$search = @ldap_search(
$ldap,
htmlspecialchars_decode($config['ldap_base_dn']),
ldap_user_filter($username),
(empty($config['ldap_email'])) ?
array(htmlspecialchars_decode($config['ldap_uid'])) :
array(htmlspecialchars_decode($config['ldap_uid']), htmlspecialchars_decode($config['ldap_email'])),
0,
1
);
$ldap_result = @ldap_get_entries($ldap, $search);
if (is_array($ldap_result) && sizeof($ldap_result) > 1)
{
if (@ldap_bind($ldap, $ldap_result[0]['dn'], htmlspecialchars_decode($password)))
{
@ldap_close($ldap);
$sql ='SELECT user_id, username, user_password, user_passchg, user_email, user_type
FROM ' . USERS_TABLE . "
WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
unset($ldap_result);
// User inactive...
if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
{
return array(
'status' => LOGIN_ERROR_ACTIVE,
'error_msg' => 'ACTIVE_ERROR',
'user_row' => $row,
);
}
// Successful login... set user_login_attempts to zero...
return array(
'status' => LOGIN_SUCCESS,
'error_msg' => false,
'user_row' => $row,
);
}
else
{
// retrieve default group id
$sql = 'SELECT group_id
FROM ' . GROUPS_TABLE . "
WHERE group_name = '" . $db->sql_escape('REGISTERED') . "'
AND group_type = " . GROUP_SPECIAL;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$row)
{
trigger_error('NO_GROUP');
}
// generate user account data
$ldap_user_row = array(
'username' => $username,
'user_password' => phpbb_hash($password),
'user_email' => (!empty($config['ldap_email'])) ? utf8_htmlspecialchars($ldap_result[0][htmlspecialchars_decode($config['ldap_email'])][0]) : '',
'group_id' => (int) $row['group_id'],
'user_type' => USER_NORMAL,
'user_ip' => $user->ip,
'user_new' => ($config['new_member_post_limit']) ? 1 : 0,
);
unset($ldap_result);
// this is the user's first login so create an empty profile
return array(
'status' => LOGIN_SUCCESS_CREATE_PROFILE,
'error_msg' => false,
'user_row' => $ldap_user_row,
);
}
}
else
{
unset($ldap_result);
@ldap_close($ldap);
// Give status about wrong password...
return array(
'status' => LOGIN_ERROR_PASSWORD,
'error_msg' => 'LOGIN_ERROR_PASSWORD',
'user_row' => array('user_id' => ANONYMOUS),
);
}
}
@ldap_close($ldap);
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
/**
* Generates a filter string for ldap_search to find a user
*
* @param $username string Username identifying the searched user
*
* @return string A filter string for ldap_search
*/
function ldap_user_filter($username)
{
global $config;
$filter = '(' . $config['ldap_uid'] . '=' . ldap_escape(htmlspecialchars_decode($username)) . ')';
if ($config['ldap_user_filter'])
{
$_filter = ($config['ldap_user_filter'][0] == '(' && substr($config['ldap_user_filter'], -1) == ')') ? $config['ldap_user_filter'] : "({$config['ldap_user_filter']})";
$filter = "(&{$filter}{$_filter})";
}
return $filter;
}
/**
* Escapes an LDAP AttributeValue
*/
function ldap_escape($string)
{
return str_replace(array('*', '\\', '(', ')'), array('\\*', '\\\\', '\\(', '\\)'), $string);
}
/**
* This function is used to output any required fields in the authentication
* admin panel. It also defines any required configuration table fields.
*/
function acp_ldap(&$new)
{
global $user;
$tpl = '
<dl>
<dt><label for="ldap_server">' . $user->lang['LDAP_SERVER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_SERVER_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_server" size="40" name="config[ldap_server]" value="' . $new['ldap_server'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_port">' . $user->lang['LDAP_PORT'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_PORT_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_port" size="40" name="config[ldap_port]" value="' . $new['ldap_port'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_dn">' . $user->lang['LDAP_DN'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_DN_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_dn" size="40" name="config[ldap_base_dn]" value="' . $new['ldap_base_dn'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_uid">' . $user->lang['LDAP_UID'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_UID_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_uid" size="40" name="config[ldap_uid]" value="' . $new['ldap_uid'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_user_filter">' . $user->lang['LDAP_USER_FILTER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_USER_FILTER_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_user_filter" size="40" name="config[ldap_user_filter]" value="' . $new['ldap_user_filter'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_email">' . $user->lang['LDAP_EMAIL'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_EMAIL_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_email" size="40" name="config[ldap_email]" value="' . $new['ldap_email'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_user">' . $user->lang['LDAP_USER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_USER_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_user" size="40" name="config[ldap_user]" value="' . $new['ldap_user'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_password">' . $user->lang['LDAP_PASSWORD'] . $user->lang['COLON'] . '</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'] . '" autocomplete="off" /></dd>
</dl>
';
// These are fields required in the config table
return array(
'tpl' => $tpl,
'config' => array('ldap_server', 'ldap_port', 'ldap_base_dn', 'ldap_uid', 'ldap_user_filter', 'ldap_email', 'ldap_user', 'ldap_password')
);
}

View file

@ -0,0 +1,275 @@
<?php
/**
*
* @package auth
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Apache authentication provider for phpBB3
*
* @package auth
*/
class phpbb_auth_provider_apache implements phpbb_auth_provider_interface
{
/**
* Apache Authentication Constructor
*
* @param phpbb_db_driver $db
* @param phpbb_config $config
* @param phpbb_request $request
* @param phpbb_user $user
* @param string $phpbb_root_path
* @param string $php_ext
*/
public function __construct(phpbb_db_driver $db, phpbb_config $config, phpbb_request $request, phpbb_user $user, $phpbb_root_path, $php_ext)
{
$this->db = $db;
$this->config = $config;
$this->request = $request;
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
}
/**
* {@inheritdoc}
*/
public function init()
{
if (!$this->request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER) || $this->user->data['username'] !== htmlspecialchars_decode($this->request->server('PHP_AUTH_USER')))
{
return $this->user->lang['APACHE_SETUP_BEFORE_USE'];
}
return false;
}
/**
* {@inheritdoc}
*/
public function login($username, $password)
{
// do not allow empty password
if (!$password)
{
return array(
'status' => LOGIN_ERROR_PASSWORD,
'error_msg' => 'NO_PASSWORD_SUPPLIED',
'user_row' => array('user_id' => ANONYMOUS),
);
}
if (!$username)
{
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
if (!$this->request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
{
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE',
'user_row' => array('user_id' => ANONYMOUS),
);
}
$php_auth_user = htmlspecialchars_decode($this->request->server('PHP_AUTH_USER'));
$php_auth_pw = htmlspecialchars_decode($this->request->server('PHP_AUTH_PW'));
if (!empty($php_auth_user) && !empty($php_auth_pw))
{
if ($php_auth_user !== $username)
{
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
$sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type
FROM ' . USERS_TABLE . "
WHERE username = '" . $this->db->sql_escape($php_auth_user) . "'";
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if ($row)
{
// User inactive...
if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
{
return array(
'status' => LOGIN_ERROR_ACTIVE,
'error_msg' => 'ACTIVE_ERROR',
'user_row' => $row,
);
}
// Successful login...
return array(
'status' => LOGIN_SUCCESS,
'error_msg' => false,
'user_row' => $row,
);
}
// this is the user's first login so create an empty profile
return array(
'status' => LOGIN_SUCCESS_CREATE_PROFILE,
'error_msg' => false,
'user_row' => user_row_apache($php_auth_user, $php_auth_pw),
);
}
// Not logged into apache
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE',
'user_row' => array('user_id' => ANONYMOUS),
);
}
/**
* {@inheritdoc}
*/
public function autologin()
{
if (!$this->request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
{
return array();
}
$php_auth_user = htmlspecialchars_decode($this->request->server('PHP_AUTH_USER'));
$php_auth_pw = htmlspecialchars_decode($this->request->server('PHP_AUTH_PW'));
if (!empty($php_auth_user) && !empty($php_auth_pw))
{
set_var($php_auth_user, $php_auth_user, 'string', true);
set_var($php_auth_pw, $php_auth_pw, 'string', true);
$sql = 'SELECT *
FROM ' . USERS_TABLE . "
WHERE username = '" . $this->db->sql_escape($php_auth_user) . "'";
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if ($row)
{
return ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE) ? array() : $row;
}
if (!function_exists('user_add'))
{
include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
}
// create the user if he does not exist yet
user_add(user_row_apache($php_auth_user, $php_auth_pw));
$sql = 'SELECT *
FROM ' . USERS_TABLE . "
WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($php_auth_user)) . "'";
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if ($row)
{
return $row;
}
}
return array();
}
/**
* This function generates an array which can be passed to the user_add
* function in order to create a user
*
* @param string $username The username of the new user.
* @param string $password The password of the new user.
* @return array Contains data that can be passed directly to
* the user_add function.
*/
private function user_row($username, $password)
{
// first retrieve default group id
$sql = 'SELECT group_id
FROM ' . GROUPS_TABLE . "
WHERE group_name = '" . $this->db->sql_escape('REGISTERED') . "'
AND group_type = " . GROUP_SPECIAL;
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if (!$row)
{
trigger_error('NO_GROUP');
}
// generate user account data
return array(
'username' => $username,
'user_password' => phpbb_hash($password),
'user_email' => '',
'group_id' => (int) $row['group_id'],
'user_type' => USER_NORMAL,
'user_ip' => $this->user->ip,
'user_new' => ($this->config['new_member_post_limit']) ? 1 : 0,
);
}
/**
* {@inheritdoc}
*/
public function validate_session($user)
{
// Check if PHP_AUTH_USER is set and handle this case
if ($this->request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
{
$php_auth_user = $this->request->server('PHP_AUTH_USER');
return ($php_auth_user === $user['username']) ? true : false;
}
// PHP_AUTH_USER is not set. A valid session is now determined by the user type (anonymous/bot or not)
if ($user['user_type'] == USER_IGNORE)
{
return true;
}
return false;
}
/**
* {@inheritdoc}
*/
public function acp($new)
{
return;
}
/**
* {@inheritdoc}
*/
public function logout($data, $new_session)
{
return;
}
}

View file

@ -0,0 +1,337 @@
<?php
/**
*
* @package auth
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Database authentication provider for phpBB3
*
* This is for authentication via the integrated user table
*
* @package auth
*/
class phpbb_auth_provider_db implements phpbb_auth_provider_interface
{
/**
* Database Authentication Constructor
*
* @param phpbb_db_driver $db
* @param phpbb_config $config
* @param phpbb_request $request
* @param phpbb_user $user
* @param string $phpbb_root_path
* @param string $php_ext
*/
public function __construct(phpbb_db_driver $db, phpbb_config $config, phpbb_request $request, phpbb_user $user, $phpbb_root_path, $php_ext)
{
$this->db = $db;
$this->config = $config;
$this->request = $request;
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
}
/**
* {@inheritdoc}
*/
public function init()
{
return;
}
/**
* {@inheritdoc}
*/
public function login($username, $password)
{
// Auth plugins get the password untrimmed.
// For compatibility we trim() here.
$password = trim($password);
// do not allow empty password
if (!$password)
{
return array(
'status' => LOGIN_ERROR_PASSWORD,
'error_msg' => 'NO_PASSWORD_SUPPLIED',
'user_row' => array('user_id' => ANONYMOUS),
);
}
if (!$username)
{
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
$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 = '" . $this->db->sql_escape($username_clean) . "'";
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if (($this->user->ip && !$this->config['ip_login_limit_use_forwarded']) ||
($this->user->forwarded_for && $this->config['ip_login_limit_use_forwarded']))
{
$sql = 'SELECT COUNT(*) AS attempts
FROM ' . LOGIN_ATTEMPT_TABLE . '
WHERE attempt_time > ' . (time() - (int) $this->config['ip_login_limit_time']);
if ($this->config['ip_login_limit_use_forwarded'])
{
$sql .= " AND attempt_forwarded_for = '" . $this->db->sql_escape($this->user->forwarded_for) . "'";
}
else
{
$sql .= " AND attempt_ip = '" . $this->db->sql_escape($this->user->ip) . "' ";
}
$result = $this->db->sql_query($sql);
$attempts = (int) $this->db->sql_fetchfield('attempts');
$this->db->sql_freeresult($result);
$attempt_data = array(
'attempt_ip' => $this->user->ip,
'attempt_browser' => trim(substr($this->user->browser, 0, 149)),
'attempt_forwarded_for' => $this->user->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 . $this->db->sql_build_array('INSERT', $attempt_data);
$result = $this->db->sql_query($sql);
}
else
{
$attempts = 0;
}
if (!$row)
{
if ($this->config['ip_login_limit_max'] && $attempts >= $this->config['ip_login_limit_max'])
{
return array(
'status' => LOGIN_ERROR_ATTEMPTS,
'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
'user_row' => array('user_id' => ANONYMOUS),
);
}
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
$show_captcha = ($this->config['max_login_attempts'] && $row['user_login_attempts'] >= $this->config['max_login_attempts']) ||
($this->config['ip_login_limit_max'] && $attempts >= $this->config['ip_login_limit_max']);
// If there are too many login attempts, we need to check for a confirm image
// Every auth module is able to define what to do by itself...
if ($show_captcha)
{
// Visual Confirmation handling
if (!class_exists('phpbb_captcha_factory', false))
{
include ($this->phpbb_root_path . 'includes/captcha/captcha_factory.' . $this->php_ext);
}
$captcha = phpbb_captcha_factory::get_instance($this->config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
$vc_response = $captcha->validate($row);
if ($vc_response)
{
return array(
'status' => LOGIN_ERROR_ATTEMPTS,
'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
'user_row' => $row,
);
}
else
{
$captcha->reset();
}
}
// If the password convert flag is set we need to convert it
if ($row['user_pass_convert'])
{
// enable super globals to get literal value
// this is needed to prevent unicode normalization
$super_globals_disabled = $this->request->super_globals_disabled();
if ($super_globals_disabled)
{
$this->request->enable_super_globals();
}
// in phpBB2 passwords were used exactly as they were sent, with addslashes applied
$password_old_format = isset($_REQUEST['password']) ? (string) $_REQUEST['password'] : '';
$password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format;
$password_new_format = $this->request->variable('password', '', true);
if ($super_globals_disabled)
{
$this->request->disable_super_globals();
}
if ($password == $password_new_format)
{
if (!function_exists('utf8_to_cp1252'))
{
include($this->phpbb_root_path . 'includes/utf/data/recode_basic.' . $this->php_ext);
}
// cp1252 is phpBB2's default encoding, characters outside ASCII range might work when converted into that encoding
// plain md5 support left in for conversions from other systems.
if ((strlen($row['user_password']) == 34 && (phpbb_check_hash(md5($password_old_format), $row['user_password']) || phpbb_check_hash(md5(utf8_to_cp1252($password_old_format)), $row['user_password'])))
|| (strlen($row['user_password']) == 32 && (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password'])))
{
$hash = phpbb_hash($password_new_format);
// Update the password in the users table to the new format and remove user_pass_convert flag
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_password = \'' . $this->db->sql_escape($hash) . '\',
user_pass_convert = 0
WHERE user_id = ' . $row['user_id'];
$this->db->sql_query($sql);
$row['user_pass_convert'] = 0;
$row['user_password'] = $hash;
}
else
{
// Although we weren't able to convert this password we have to
// increase login attempt count to make sure this cannot be exploited
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_login_attempts = user_login_attempts + 1
WHERE user_id = ' . (int) $row['user_id'] . '
AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
$this->db->sql_query($sql);
return array(
'status' => LOGIN_ERROR_PASSWORD_CONVERT,
'error_msg' => 'LOGIN_ERROR_PASSWORD_CONVERT',
'user_row' => $row,
);
}
}
}
// Check password ...
if (!$row['user_pass_convert'] && phpbb_check_hash($password, $row['user_password']))
{
// Check for old password hash...
if (strlen($row['user_password']) == 32)
{
$hash = phpbb_hash($password);
// Update the password in the users table to the new format
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_password = '" . $this->db->sql_escape($hash) . "',
user_pass_convert = 0
WHERE user_id = {$row['user_id']}";
$this->db->sql_query($sql);
$row['user_password'] = $hash;
}
$sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . '
WHERE user_id = ' . $row['user_id'];
$this->db->sql_query($sql);
if ($row['user_login_attempts'] != 0)
{
// Successful, reset login attempts (the user passed all stages)
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_login_attempts = 0
WHERE user_id = ' . $row['user_id'];
$this->db->sql_query($sql);
}
// User inactive...
if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
{
return array(
'status' => LOGIN_ERROR_ACTIVE,
'error_msg' => 'ACTIVE_ERROR',
'user_row' => $row,
);
}
// Successful login... set user_login_attempts to zero...
return array(
'status' => LOGIN_SUCCESS,
'error_msg' => false,
'user_row' => $row,
);
}
// Password incorrect - increase login attempts
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_login_attempts = user_login_attempts + 1
WHERE user_id = ' . (int) $row['user_id'] . '
AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
$this->db->sql_query($sql);
// Give status about wrong password...
return array(
'status' => ($show_captcha) ? LOGIN_ERROR_ATTEMPTS : LOGIN_ERROR_PASSWORD,
'error_msg' => ($show_captcha) ? 'LOGIN_ERROR_ATTEMPTS' : 'LOGIN_ERROR_PASSWORD',
'user_row' => $row,
);
}
/**
* {@inheritdoc}
*/
public function autologin()
{
return;
}
/**
* {@inheritdoc}
*/
public function acp($new)
{
return;
}
/**
* {@inheritdoc}
*/
public function logout($data, $new_session)
{
return;
}
/**
* {@inheritdoc}
*/
public function validate_session($user)
{
return;
}
}

View file

@ -0,0 +1,10 @@
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
</body>
</html>

View file

@ -0,0 +1,93 @@
<?php
/**
*
* @package auth
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* The interface authentication provider classes have to implement.
*
* @package auth
*/
interface phpbb_auth_provider_interface
{
/**
* Checks whether the user is currently identified to the authentication
* provider.
* Called in acp_board while setting authentication plugins.
* Changing to an authentication provider will not be permitted in acp_board
* if there is an error.
*
* @return boolean|string False if the user is identified, otherwise an
* error message, or null if not implemented.
*/
public function init();
/**
* Performs login.
*
* @param string $username The name of the user being authenticated.
* @param string $password The password of the user.
* @return array An associative array of the format:
* array(
* 'status' => status constant
* 'error_msg' => string
* 'user_row' => array
* )
*/
public function login($username, $password);
/**
* Autologin function
*
* @return array|null containing the user row, empty if no auto login
* should take place, or null if not impletmented.
*/
public function autologin();
/**
* This function is used to output any required fields in the authentication
* admin panel. It also defines any required configuration table fields.
*
* @param array $new Contains the new configuration values that have
* been set in acp_board.
* @return array|null Returns null if not implemented or an array of the
* form:
* array(
* 'tpl' => string
* 'config' => array
* )
*/
public function acp($new);
/**
* Performs additional actions during logout.
*
* @param array $data An array corresponding to
* phpbb_session::data
* @param boolean $new_session True for a new session, false for no new
* session.
*/
public function logout($data, $new_session);
/**
* The session validation function checks whether the user is still logged
* into phpBB.
*
* @param array $user
* @return boolean true if the given user is authenticated, false if the
* session should be closed, or null if not implemented.
*/
public function validate_session($user);
}

View file

@ -0,0 +1,386 @@
<?php
/**
*
* @package auth
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Database authentication provider for phpBB3
*
* This is for authentication via the integrated user table
*
* @package auth
*/
class phpbb_auth_provider_ldap implements phpbb_auth_provider_interface
{
/**
* LDAP Authentication Constructor
*
* @param phpbb_db_driver $db
* @param phpbb_config $config
* @param phpbb_user $user
*/
public function __construct(phpbb_db_driver $db, phpbb_config $config, phpbb_user $user)
{
$this->db = $db;
$this->config = $config;
$this->user = $user;
}
/**
* {@inheritdoc}
*/
public function init()
{
if (!@extension_loaded('ldap'))
{
return $this->user->lang['LDAP_NO_LDAP_EXTENSION'];
}
$this->config['ldap_port'] = (int) $this->config['ldap_port'];
if ($this->config['ldap_port'])
{
$ldap = @ldap_connect($this->config['ldap_server'], $this->config['ldap_port']);
}
else
{
$ldap = @ldap_connect($this->config['ldap_server']);
}
if (!$ldap)
{
return $this->user->lang['LDAP_NO_SERVER_CONNECTION'];
}
@ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
@ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
if ($this->config['ldap_user'] || $this->config['ldap_password'])
{
if (!@ldap_bind($ldap, htmlspecialchars_decode($this->config['ldap_user']), htmlspecialchars_decode($this->config['ldap_password'])))
{
return $this->user->lang['LDAP_INCORRECT_USER_PASSWORD'];
}
}
// ldap_connect only checks whether the specified server is valid, so the connection might still fail
$search = @ldap_search(
$ldap,
htmlspecialchars_decode($this->config['ldap_base_dn']),
$this->ldap_user_filter($this->user->data['username']),
(empty($this->config['ldap_email'])) ?
array(htmlspecialchars_decode($this->config['ldap_uid'])) :
array(htmlspecialchars_decode($this->config['ldap_uid']), htmlspecialchars_decode($this->config['ldap_email'])),
0,
1
);
if ($search === false)
{
return $this->user->lang['LDAP_SEARCH_FAILED'];
}
$result = @ldap_get_entries($ldap, $search);
@ldap_close($ldap);
if (!is_array($result) || sizeof($result) < 2)
{
return sprintf($this->user->lang['LDAP_NO_IDENTITY'], $this->user->data['username']);
}
if (!empty($this->config['ldap_email']) && !isset($result[0][htmlspecialchars_decode($this->config['ldap_email'])]))
{
return $this->user->lang['LDAP_NO_EMAIL'];
}
return false;
}
/**
* {@inheritdoc}
*/
public function login($username, $password)
{
// do not allow empty password
if (!$password)
{
return array(
'status' => LOGIN_ERROR_PASSWORD,
'error_msg' => 'NO_PASSWORD_SUPPLIED',
'user_row' => array('user_id' => ANONYMOUS),
);
}
if (!$username)
{
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
if (!@extension_loaded('ldap'))
{
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LDAP_NO_LDAP_EXTENSION',
'user_row' => array('user_id' => ANONYMOUS),
);
}
$this->config['ldap_port'] = (int) $this->config['ldap_port'];
if ($this->config['ldap_port'])
{
$ldap = @ldap_connect($this->config['ldap_server'], $this->config['ldap_port']);
}
else
{
$ldap = @ldap_connect($this->config['ldap_server']);
}
if (!$ldap)
{
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LDAP_NO_SERVER_CONNECTION',
'user_row' => array('user_id' => ANONYMOUS),
);
}
@ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
@ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
if ($this->config['ldap_user'] || $this->config['ldap_password'])
{
if (!@ldap_bind($ldap, htmlspecialchars_decode($this->config['ldap_user']), htmlspecialchars_decode($this->config['ldap_password'])))
{
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LDAP_NO_SERVER_CONNECTION',
'user_row' => array('user_id' => ANONYMOUS),
);
}
}
$search = @ldap_search(
$ldap,
htmlspecialchars_decode($this->config['ldap_base_dn']),
$this->ldap_user_filter($username),
(empty($this->config['ldap_email'])) ?
array(htmlspecialchars_decode($this->config['ldap_uid'])) :
array(htmlspecialchars_decode($this->config['ldap_uid']), htmlspecialchars_decode($this->config['ldap_email'])),
0,
1
);
$ldap_result = @ldap_get_entries($ldap, $search);
if (is_array($ldap_result) && sizeof($ldap_result) > 1)
{
if (@ldap_bind($ldap, $ldap_result[0]['dn'], htmlspecialchars_decode($password)))
{
@ldap_close($ldap);
$sql ='SELECT user_id, username, user_password, user_passchg, user_email, user_type
FROM ' . USERS_TABLE . "
WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($username)) . "'";
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if ($row)
{
unset($ldap_result);
// User inactive...
if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
{
return array(
'status' => LOGIN_ERROR_ACTIVE,
'error_msg' => 'ACTIVE_ERROR',
'user_row' => $row,
);
}
// Successful login... set user_login_attempts to zero...
return array(
'status' => LOGIN_SUCCESS,
'error_msg' => false,
'user_row' => $row,
);
}
else
{
// retrieve default group id
$sql = 'SELECT group_id
FROM ' . GROUPS_TABLE . "
WHERE group_name = '" . $this->db->sql_escape('REGISTERED') . "'
AND group_type = " . GROUP_SPECIAL;
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if (!$row)
{
trigger_error('NO_GROUP');
}
// generate user account data
$ldap_user_row = array(
'username' => $username,
'user_password' => phpbb_hash($password),
'user_email' => (!empty($this->config['ldap_email'])) ? utf8_htmlspecialchars($ldap_result[0][htmlspecialchars_decode($this->config['ldap_email'])][0]) : '',
'group_id' => (int) $row['group_id'],
'user_type' => USER_NORMAL,
'user_ip' => $this->user->ip,
'user_new' => ($this->config['new_member_post_limit']) ? 1 : 0,
);
unset($ldap_result);
// this is the user's first login so create an empty profile
return array(
'status' => LOGIN_SUCCESS_CREATE_PROFILE,
'error_msg' => false,
'user_row' => $ldap_user_row,
);
}
}
else
{
unset($ldap_result);
@ldap_close($ldap);
// Give status about wrong password...
return array(
'status' => LOGIN_ERROR_PASSWORD,
'error_msg' => 'LOGIN_ERROR_PASSWORD',
'user_row' => array('user_id' => ANONYMOUS),
);
}
}
@ldap_close($ldap);
return array(
'status' => LOGIN_ERROR_USERNAME,
'error_msg' => 'LOGIN_ERROR_USERNAME',
'user_row' => array('user_id' => ANONYMOUS),
);
}
/**
* {@inheritdoc}
*/
public function autologin()
{
return;
}
/**
* {@inheritdoc}
*/
public function acp($new)
{
$tpl = '
<dl>
<dt><label for="ldap_server">' . $this->user->lang['LDAP_SERVER'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_SERVER_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_server" size="40" name="config[ldap_server]" value="' . $new['ldap_server'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_port">' . $this->user->lang['LDAP_PORT'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_PORT_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_port" size="40" name="config[ldap_port]" value="' . $new['ldap_port'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_dn">' . $this->user->lang['LDAP_DN'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_DN_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_dn" size="40" name="config[ldap_base_dn]" value="' . $new['ldap_base_dn'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_uid">' . $this->user->lang['LDAP_UID'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_UID_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_uid" size="40" name="config[ldap_uid]" value="' . $new['ldap_uid'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_user_filter">' . $this->user->lang['LDAP_USER_FILTER'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_USER_FILTER_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_user_filter" size="40" name="config[ldap_user_filter]" value="' . $new['ldap_user_filter'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_email">' . $this->user->lang['LDAP_EMAIL'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_EMAIL_EXPLAIN'] . '</span></dt>
<dd><input type="email" id="ldap_email" size="40" name="config[ldap_email]" value="' . $new['ldap_email'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_user">' . $this->user->lang['LDAP_USER'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_USER_EXPLAIN'] . '</span></dt>
<dd><input type="text" id="ldap_user" size="40" name="config[ldap_user]" value="' . $new['ldap_user'] . '" /></dd>
</dl>
<dl>
<dt><label for="ldap_password">' . $this->user->lang['LDAP_PASSWORD'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_PASSWORD_EXPLAIN'] . '</span></dt>
<dd><input type="password" id="ldap_password" size="40" name="config[ldap_password]" value="' . $new['ldap_password'] . '" autocomplete="off" /></dd>
</dl>
';
// These are fields required in the config table
return array(
'tpl' => $tpl,
'config' => array('ldap_server', 'ldap_port', 'ldap_base_dn', 'ldap_uid', 'ldap_user_filter', 'ldap_email', 'ldap_user', 'ldap_password')
);
}
/**
* Generates a filter string for ldap_search to find a user
*
* @param $username string Username identifying the searched user
*
* @return string A filter string for ldap_search
*/
private function ldap_user_filter($username)
{
$filter = '(' . $this->config['ldap_uid'] . '=' . $this->ldap_escape(htmlspecialchars_decode($username)) . ')';
if ($this->config['ldap_user_filter'])
{
$_filter = ($this->config['ldap_user_filter'][0] == '(' && substr($this->config['ldap_user_filter'], -1) == ')') ? $this->config['ldap_user_filter'] : "({$this->config['ldap_user_filter']})";
$filter = "(&{$filter}{$_filter})";
}
return $filter;
}
/**
* Escapes an LDAP AttributeValue
*
* @param string $string The string to be escaped
* @return string The escaped string
*/
private function ldap_escape($string)
{
return str_replace(array('*', '\\', '(', ')'), array('\\*', '\\\\', '\\(', '\\)'), $string);
}
/**
* {@inheritdoc}
*/
public function logout($data, $new_session)
{
return;
}
/**
* {@inheritdoc}
*/
public function validate_session($user)
{
return;
}
}

View file

@ -74,7 +74,7 @@ class phpbb_avatar_driver_gravatar extends phpbb_avatar_driver
if (!function_exists('validate_data')) if (!function_exists('validate_data'))
{ {
require($this->phpbb_root_path . 'includes/functions_user' . $this->php_ext); require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
} }
$validate_array = validate_data( $validate_array = validate_data(

View file

@ -63,7 +63,7 @@ class phpbb_avatar_driver_remote extends phpbb_avatar_driver
if (!function_exists('validate_data')) if (!function_exists('validate_data'))
{ {
require($this->phpbb_root_path . 'includes/functions_user' . $this->php_ext); require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
} }
$validate_array = validate_data( $validate_array = validate_data(
@ -117,7 +117,7 @@ class phpbb_avatar_driver_remote extends phpbb_avatar_driver
if (!class_exists('fileupload')) if (!class_exists('fileupload'))
{ {
include($this->phpbb_root_path . 'includes/functions_upload' . $this->php_ext); include($this->phpbb_root_path . 'includes/functions_upload.' . $this->php_ext);
} }
$types = fileupload::image_types(); $types = fileupload::image_types();

View file

@ -27,7 +27,7 @@ class phpbb_avatar_driver_upload extends phpbb_avatar_driver
public function get_data($row, $ignore_config = false) public function get_data($row, $ignore_config = false)
{ {
return array( return array(
'src' => $this->phpbb_root_path . 'download/file' . $this->php_ext . '?avatar=' . $row['avatar'], 'src' => $this->phpbb_root_path . 'download/file.' . $this->php_ext . '?avatar=' . $row['avatar'],
'width' => $row['avatar_width'], 'width' => $row['avatar_width'],
'height' => $row['avatar_height'], 'height' => $row['avatar_height'],
); );
@ -63,7 +63,7 @@ class phpbb_avatar_driver_upload extends phpbb_avatar_driver
if (!class_exists('fileupload')) if (!class_exists('fileupload'))
{ {
include($this->phpbb_root_path . 'includes/functions_upload' . $this->php_ext); include($this->phpbb_root_path . 'includes/functions_upload.' . $this->php_ext);
} }
$upload = new fileupload('AVATAR_', $this->allowed_extensions, $this->config['avatar_filesize'], $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], (isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false)); $upload = new fileupload('AVATAR_', $this->allowed_extensions, $this->config['avatar_filesize'], $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], (isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false));
@ -126,7 +126,7 @@ class phpbb_avatar_driver_upload extends phpbb_avatar_driver
{ {
return array( return array(
'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'text:4:10', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), 'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true), 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true),
); );
} }

View file

@ -45,6 +45,17 @@ class phpbb_avatar_manager
*/ */
protected $container; protected $container;
/**
* Default avatar data row
* @var array
*/
static protected $default_row = array(
'avatar' => '',
'avatar_type' => '',
'avatar_width' => '',
'avatar_height' => '',
);
/** /**
* Construct an avatar manager object * Construct an avatar manager object
* *
@ -174,6 +185,12 @@ class phpbb_avatar_manager
*/ */
static public function clean_row($row) static public function clean_row($row)
{ {
// Upon creation of a user/group $row might be empty
if (empty($row))
{
return self::$default_row;
}
$keys = array_keys($row); $keys = array_keys($row);
$values = array_values($row); $values = array_values($row);

View file

@ -133,7 +133,7 @@ class bbcode
$this->template_bitfield = new bitfield($user->style['bbcode_bitfield']); $this->template_bitfield = new bitfield($user->style['bbcode_bitfield']);
$style_resource_locator = new phpbb_style_resource_locator(); $style_resource_locator = new phpbb_style_resource_locator();
$style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider(), $phpbb_root_path);
$template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, new phpbb_template_context(), $phpbb_extension_manager); $template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, new phpbb_template_context(), $phpbb_extension_manager);
$style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $template); $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $template);
$style->set_style(); $style->set_style();

View file

@ -270,7 +270,7 @@ class phpbb_recaptcha extends phpbb_default_captcha
$response = ''; $response = '';
if (false == ($fs = @fsockopen($host, $port, $errno, $errstr, 10))) if (false == ($fs = @fsockopen($host, $port, $errno, $errstr, 10)))
{ {
trigger_error('Could not open socket', E_USER_ERROR); trigger_error('RECAPTCHA_SOCKET_ERROR', E_USER_ERROR);
} }
fwrite($fs, $http_request); fwrite($fs, $http_request);

View file

@ -52,7 +52,7 @@ class phpbb_class_loader
* @param string $php_ext The file extension for PHP files * @param string $php_ext The file extension for PHP files
* @param phpbb_cache_driver_interface $cache An implementation of the phpBB cache interface. * @param phpbb_cache_driver_interface $cache An implementation of the phpBB cache interface.
*/ */
public function __construct($prefix, $path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null) public function __construct($prefix, $path, $php_ext = 'php', phpbb_cache_driver_interface $cache = null)
{ {
$this->prefix = $prefix; $this->prefix = $prefix;
$this->path = $path; $this->path = $path;
@ -111,7 +111,7 @@ class phpbb_class_loader
{ {
if (isset($this->cached_paths[$class])) if (isset($this->cached_paths[$class]))
{ {
return $this->path . $this->cached_paths[$class] . $this->php_ext; return $this->path . $this->cached_paths[$class] . '.' . $this->php_ext;
} }
if (!preg_match('/^' . $this->prefix . '[a-zA-Z0-9_]+$/', $class)) if (!preg_match('/^' . $this->prefix . '[a-zA-Z0-9_]+$/', $class))
@ -136,7 +136,7 @@ class phpbb_class_loader
$relative_path = $dirs . implode(array_slice($parts, $i, sizeof($parts) - $i), '_'); $relative_path = $dirs . implode(array_slice($parts, $i, sizeof($parts) - $i), '_');
if (!file_exists($this->path . $relative_path . $this->php_ext)) if (!file_exists($this->path . $relative_path . '.' . $this->php_ext))
{ {
return false; return false;
} }
@ -147,7 +147,7 @@ class phpbb_class_loader
$this->cache->put('class_loader_' . $this->prefix, $this->cached_paths); $this->cache->put('class_loader_' . $this->prefix, $this->cached_paths);
} }
return $this->path . $relative_path . $this->php_ext; return $this->path . $relative_path . '.' . $this->php_ext;
} }
/** /**

View file

@ -160,6 +160,7 @@ define('PHYSICAL_LINK', 2);
define('CONFIRM_REG', 1); define('CONFIRM_REG', 1);
define('CONFIRM_LOGIN', 2); define('CONFIRM_LOGIN', 2);
define('CONFIRM_POST', 3); define('CONFIRM_POST', 3);
define('CONFIRM_REPORT', 4);
// Categories - Attachments // Categories - Attachments
define('ATTACHMENT_CATEGORY_NONE', 0); define('ATTACHMENT_CATEGORY_NONE', 0);

View file

@ -85,17 +85,39 @@ class phpbb_controller_helper
} }
/** /**
* Easily generate a URL * Generate a URL
* *
* @param array $url_parts Each array element is a 'folder' * @param string $route The route to travel
* i.e. array('my', 'ext') maps to ./app.php/my/ext * @param mixed $params String or array of additional url parameters
* @param mixed $query The Query string, passed directly into the second * @param bool $is_amp Is url using &amp; (true) or & (false)
* argument of append_sid() * @param string $session_id Possibility to use a custom session id instead of the global one
* @return string A URL that has already been run through append_sid() * @return string The URL already passed through append_sid()
*/ */
public function url(array $url_parts, $query = '') public function url($route, $params = false, $is_amp = true, $session_id = false)
{ {
return append_sid($this->phpbb_root_path . implode('/', $url_parts), $query); $route_params = '';
if (($route_delim = strpos($route, '?')) !== false)
{
$route_params = substr($route, $route_delim);
$route = substr($route, 0, $route_delim);
}
if (is_array($params) && !empty($params))
{
$params = array_merge(array(
'controller' => $route,
), $params);
}
else if (is_string($params) && $params)
{
$params = 'controller=' . $route . (($is_amp) ? '&amp;' : '&') . $params;
}
else
{
$params = array('controller' => $route);
}
return append_sid($this->phpbb_root_path . 'app.' . $this->php_ext . $route_params, $params, $is_amp, $session_id);
} }
/** /**

View file

@ -568,12 +568,12 @@ class phpbb_db_driver
* Run more than one insert statement. * Run more than one insert statement.
* *
* @param string $table table name to run the statements on * @param string $table table name to run the statements on
* @param array &$sql_ary multi-dimensional array holding the statement data. * @param array $sql_ary multi-dimensional array holding the statement data.
* *
* @return bool false if no statements were executed. * @return bool false if no statements were executed.
* @access public * @access public
*/ */
function sql_multi_insert($table, &$sql_ary) function sql_multi_insert($table, $sql_ary)
{ {
if (!sizeof($sql_ary)) if (!sizeof($sql_ary))
{ {

View file

@ -0,0 +1,65 @@
<?php
/**
*
* @package dbal
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* MSSQL Database Base Abstraction Layer
* @package dbal
*/
abstract class phpbb_db_driver_mssql_base extends phpbb_db_driver
{
/**
* {@inheritDoc}
*/
public function sql_concatenate($expr1, $expr2)
{
return $expr1 . ' + ' . $expr2;
}
/**
* Escape string used in sql query
*/
function sql_escape($msg)
{
return str_replace(array("'", "\0"), array("''", ''), $msg);
}
/**
* {@inheritDoc}
*/
function sql_lower_text($column_name)
{
return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))";
}
/**
* Build LIKE expression
* @access private
*/
function _sql_like_expression($expression)
{
return $expression . " ESCAPE '\\'";
}
/**
* Build db-specific query data
* @access private
*/
function _sql_custom_build($stage, $data)
{
return $data;
}
}

View file

@ -26,7 +26,7 @@ if (!defined('IN_PHPBB'))
* *
* @package dbal * @package dbal
*/ */
class phpbb_db_driver_mssql_odbc extends phpbb_db_driver class phpbb_db_driver_mssql_odbc extends phpbb_db_driver_mssql_base
{ {
var $last_query_text = ''; var $last_query_text = '';
var $connect_error = ''; var $connect_error = '';
@ -125,14 +125,6 @@ class phpbb_db_driver_mssql_odbc extends phpbb_db_driver
return ($this->sql_server_version) ? 'MSSQL (ODBC)<br />' . $this->sql_server_version : 'MSSQL (ODBC)'; return ($this->sql_server_version) ? 'MSSQL (ODBC)<br />' . $this->sql_server_version : 'MSSQL (ODBC)';
} }
/**
* {@inheritDoc}
*/
public function sql_concatenate($expr1, $expr2)
{
return $expr1 . ' + ' . $expr2;
}
/** /**
* SQL Transaction * SQL Transaction
* @access private * @access private
@ -261,7 +253,7 @@ class phpbb_db_driver_mssql_odbc extends phpbb_db_driver
* Fetch current row * Fetch current row
* @note number of bytes returned depends on odbc.defaultlrl php.ini setting. If it is limited to 4K for example only 4K of data is returned max. * @note number of bytes returned depends on odbc.defaultlrl php.ini setting. If it is limited to 4K for example only 4K of data is returned max.
*/ */
function sql_fetchrow($query_id = false, $debug = false) function sql_fetchrow($query_id = false)
{ {
global $cache; global $cache;
@ -325,40 +317,6 @@ class phpbb_db_driver_mssql_odbc extends phpbb_db_driver
return false; return false;
} }
/**
* Escape string used in sql query
*/
function sql_escape($msg)
{
return str_replace(array("'", "\0"), array("''", ''), $msg);
}
/**
* {@inheritDoc}
*/
function sql_lower_text($column_name)
{
return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))";
}
/**
* Build LIKE expression
* @access private
*/
function _sql_like_expression($expression)
{
return $expression . " ESCAPE '\\'";
}
/**
* Build db-specific query data
* @access private
*/
function _sql_custom_build($stage, $data)
{
return $data;
}
/** /**
* return sql error array * return sql error array
* @access private * @access private

View file

@ -191,7 +191,7 @@ class result_mssqlnative
/** /**
* @package dbal * @package dbal
*/ */
class phpbb_db_driver_mssqlnative extends phpbb_db_driver class phpbb_db_driver_mssqlnative extends phpbb_db_driver_mssql_base
{ {
var $m_insert_id = NULL; var $m_insert_id = NULL;
var $last_query_text = ''; var $last_query_text = '';
@ -256,14 +256,6 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver
return ($this->sql_server_version) ? 'MSSQL<br />' . $this->sql_server_version : 'MSSQL'; return ($this->sql_server_version) ? 'MSSQL<br />' . $this->sql_server_version : 'MSSQL';
} }
/**
* {@inheritDoc}
*/
public function sql_concatenate($expr1, $expr2)
{
return $expr1 . ' + ' . $expr2;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -334,7 +326,7 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver
$this->sql_report('stop', $query); $this->sql_report('stop', $query);
} }
if ($cache_ttl) if ($cache && $cache_ttl)
{ {
$this->open_queries[(int) $this->query_result] = $this->query_result; $this->open_queries[(int) $this->query_result] = $this->query_result;
$this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
@ -402,7 +394,7 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver
*/ */
function sql_affectedrows() function sql_affectedrows()
{ {
return (!empty($this->query_result)) ? @sqlsrv_rows_affected($this->query_result) : false; return ($this->db_connect_id) ? @sqlsrv_rows_affected($this->query_result) : false;
} }
/** /**
@ -417,7 +409,7 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver
$query_id = $this->query_result; $query_id = $this->query_result;
} }
if ($cache->sql_exists($query_id)) if ($cache && $cache->sql_exists($query_id))
{ {
return $cache->sql_fetchrow($query_id); return $cache->sql_fetchrow($query_id);
} }
@ -482,39 +474,14 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver
return $cache->sql_freeresult($query_id); return $cache->sql_freeresult($query_id);
} }
if (isset($this->open_queries[$query_id])) if (isset($this->open_queries[(int) $query_id]))
{ {
unset($this->open_queries[$query_id]); unset($this->open_queries[(int) $query_id]);
return @sqlsrv_free_stmt($query_id); return @sqlsrv_free_stmt($query_id);
} }
return false; return false;
} }
/**
* Escape string used in sql query
*/
function sql_escape($msg)
{
return str_replace(array("'", "\0"), array("''", ''), $msg);
}
/**
* {@inheritDoc}
*/
function sql_lower_text($column_name)
{
return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))";
}
/**
* Build LIKE expression
* @access private
*/
function _sql_like_expression($expression)
{
return $expression . " ESCAPE '\\'";
}
/** /**
* return sql error array * return sql error array
* @access private * @access private
@ -560,15 +527,6 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver
return $error; return $error;
} }
/**
* Build db-specific query data
* @access private
*/
function _sql_custom_build($stage, $data)
{
return $data;
}
/** /**
* Close sql connection * Close sql connection
* @access private * @access private

View file

@ -24,7 +24,7 @@ if (!defined('IN_PHPBB'))
* MySQL 5.0+ * MySQL 5.0+
* @package dbal * @package dbal
*/ */
class phpbb_db_driver_mysql extends phpbb_db_driver class phpbb_db_driver_mysql extends phpbb_db_driver_mysql_base
{ {
var $multi_insert = true; var $multi_insert = true;
var $connect_error = ''; var $connect_error = '';
@ -135,14 +135,6 @@ class phpbb_db_driver_mysql extends phpbb_db_driver
return ($raw) ? $this->sql_server_version : 'MySQL ' . $this->sql_server_version; return ($raw) ? $this->sql_server_version : 'MySQL ' . $this->sql_server_version;
} }
/**
* {@inheritDoc}
*/
public function sql_concatenate($expr1, $expr2)
{
return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')';
}
/** /**
* SQL Transaction * SQL Transaction
* @access private * @access private
@ -226,25 +218,6 @@ class phpbb_db_driver_mysql extends phpbb_db_driver
return $this->query_result; return $this->query_result;
} }
/**
* Build LIMIT query
*/
function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
{
$this->query_result = false;
// if $total is set to 0 we do not want to limit the number of rows
if ($total == 0)
{
// Having a value of -1 was always a bug
$total = '18446744073709551615';
}
$query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
return $this->sql_query($query, $cache_ttl);
}
/** /**
* Return number of affected rows * Return number of affected rows
*/ */
@ -341,101 +314,6 @@ class phpbb_db_driver_mysql extends phpbb_db_driver
return @mysql_real_escape_string($msg, $this->db_connect_id); return @mysql_real_escape_string($msg, $this->db_connect_id);
} }
/**
* Gets the estimated number of rows in a specified table.
*
* @param string $table_name Table name
*
* @return string Number of rows in $table_name.
* Prefixed with ~ if estimated (otherwise exact).
*
* @access public
*/
function get_estimated_row_count($table_name)
{
$table_status = $this->get_table_status($table_name);
if (isset($table_status['Engine']))
{
if ($table_status['Engine'] === 'MyISAM')
{
return $table_status['Rows'];
}
else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000)
{
return '~' . $table_status['Rows'];
}
}
return parent::get_row_count($table_name);
}
/**
* Gets the exact number of rows in a specified table.
*
* @param string $table_name Table name
*
* @return string Exact number of rows in $table_name.
*
* @access public
*/
function get_row_count($table_name)
{
$table_status = $this->get_table_status($table_name);
if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM')
{
return $table_status['Rows'];
}
return parent::get_row_count($table_name);
}
/**
* Gets some information about the specified table.
*
* @param string $table_name Table name
*
* @return array
*
* @access protected
*/
function get_table_status($table_name)
{
$sql = "SHOW TABLE STATUS
LIKE '" . $this->sql_escape($table_name) . "'";
$result = $this->sql_query($sql);
$table_status = $this->sql_fetchrow($result);
$this->sql_freeresult($result);
return $table_status;
}
/**
* Build LIKE expression
* @access private
*/
function _sql_like_expression($expression)
{
return $expression;
}
/**
* Build db-specific query data
* @access private
*/
function _sql_custom_build($stage, $data)
{
switch ($stage)
{
case 'FROM':
$data = '(' . $data . ')';
break;
}
return $data;
}
/** /**
* return sql error array * return sql error array
* @access private * @access private

View file

@ -0,0 +1,145 @@
<?php
/**
*
* @package dbal
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Abstract MySQL Database Base Abstraction Layer
* @package dbal
*/
abstract class phpbb_db_driver_mysql_base extends phpbb_db_driver
{
/**
* {@inheritDoc}
*/
public function sql_concatenate($expr1, $expr2)
{
return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')';
}
/**
* Build LIMIT query
*/
function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
{
$this->query_result = false;
// if $total is set to 0 we do not want to limit the number of rows
if ($total == 0)
{
// MySQL 4.1+ no longer supports -1 in limit queries
$total = '18446744073709551615';
}
$query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
return $this->sql_query($query, $cache_ttl);
}
/**
* Gets the estimated number of rows in a specified table.
*
* @param string $table_name Table name
*
* @return string Number of rows in $table_name.
* Prefixed with ~ if estimated (otherwise exact).
*
* @access public
*/
function get_estimated_row_count($table_name)
{
$table_status = $this->get_table_status($table_name);
if (isset($table_status['Engine']))
{
if ($table_status['Engine'] === 'MyISAM')
{
return $table_status['Rows'];
}
else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000)
{
return '~' . $table_status['Rows'];
}
}
return parent::get_row_count($table_name);
}
/**
* Gets the exact number of rows in a specified table.
*
* @param string $table_name Table name
*
* @return string Exact number of rows in $table_name.
*
* @access public
*/
function get_row_count($table_name)
{
$table_status = $this->get_table_status($table_name);
if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM')
{
return $table_status['Rows'];
}
return parent::get_row_count($table_name);
}
/**
* Gets some information about the specified table.
*
* @param string $table_name Table name
*
* @return array
*
* @access protected
*/
function get_table_status($table_name)
{
$sql = "SHOW TABLE STATUS
LIKE '" . $this->sql_escape($table_name) . "'";
$result = $this->sql_query($sql);
$table_status = $this->sql_fetchrow($result);
$this->sql_freeresult($result);
return $table_status;
}
/**
* Build LIKE expression
* @access private
*/
function _sql_like_expression($expression)
{
return $expression;
}
/**
* Build db-specific query data
* @access private
*/
function _sql_custom_build($stage, $data)
{
switch ($stage)
{
case 'FROM':
$data = '(' . $data . ')';
break;
}
return $data;
}
}

View file

@ -21,7 +21,7 @@ if (!defined('IN_PHPBB'))
* MySQL 4.1+ or MySQL 5.0+ * MySQL 4.1+ or MySQL 5.0+
* @package dbal * @package dbal
*/ */
class phpbb_db_driver_mysqli extends phpbb_db_driver class phpbb_db_driver_mysqli extends phpbb_db_driver_mysql_base
{ {
var $multi_insert = true; var $multi_insert = true;
var $connect_error = ''; var $connect_error = '';
@ -103,6 +103,7 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver
/** /**
* Version information about used database * Version information about used database
* @param bool $raw if true, only return the fetched sql_server_version
* @param bool $use_cache If true, it is safe to retrieve the value from the cache * @param bool $use_cache If true, it is safe to retrieve the value from the cache
* @return string sql server version * @return string sql server version
*/ */
@ -127,14 +128,6 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver
return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version; return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version;
} }
/**
* {@inheritDoc}
*/
public function sql_concatenate($expr1, $expr2)
{
return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')';
}
/** /**
* SQL Transaction * SQL Transaction
* @access private * @access private
@ -217,25 +210,6 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver
return $this->query_result; return $this->query_result;
} }
/**
* Build LIMIT query
*/
function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
{
$this->query_result = false;
// if $total is set to 0 we do not want to limit the number of rows
if ($total == 0)
{
// MySQL 4.1+ no longer supports -1 in limit queries
$total = '18446744073709551615';
}
$query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
return $this->sql_query($query, $cache_ttl);
}
/** /**
* Return number of affected rows * Return number of affected rows
*/ */
@ -327,101 +301,6 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver
return @mysqli_real_escape_string($this->db_connect_id, $msg); return @mysqli_real_escape_string($this->db_connect_id, $msg);
} }
/**
* Gets the estimated number of rows in a specified table.
*
* @param string $table_name Table name
*
* @return string Number of rows in $table_name.
* Prefixed with ~ if estimated (otherwise exact).
*
* @access public
*/
function get_estimated_row_count($table_name)
{
$table_status = $this->get_table_status($table_name);
if (isset($table_status['Engine']))
{
if ($table_status['Engine'] === 'MyISAM')
{
return $table_status['Rows'];
}
else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000)
{
return '~' . $table_status['Rows'];
}
}
return parent::get_row_count($table_name);
}
/**
* Gets the exact number of rows in a specified table.
*
* @param string $table_name Table name
*
* @return string Exact number of rows in $table_name.
*
* @access public
*/
function get_row_count($table_name)
{
$table_status = $this->get_table_status($table_name);
if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM')
{
return $table_status['Rows'];
}
return parent::get_row_count($table_name);
}
/**
* Gets some information about the specified table.
*
* @param string $table_name Table name
*
* @return array
*
* @access protected
*/
function get_table_status($table_name)
{
$sql = "SHOW TABLE STATUS
LIKE '" . $this->sql_escape($table_name) . "'";
$result = $this->sql_query($sql);
$table_status = $this->sql_fetchrow($result);
$this->sql_freeresult($result);
return $table_status;
}
/**
* Build LIKE expression
* @access private
*/
function _sql_like_expression($expression)
{
return $expression;
}
/**
* Build db-specific query data
* @access private
*/
function _sql_custom_build($stage, $data)
{
switch ($stage)
{
case 'FROM':
$data = '(' . $data . ')';
break;
}
return $data;
}
/** /**
* return sql error array * return sql error array
* @access private * @access private

View file

@ -0,0 +1,23 @@
<?php
/**
*
* @package migration
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
*
*/
class phpbb_db_migration_data_310_boardindex extends phpbb_db_migration
{
public function effectively_installed()
{
return isset($this->config['board_index_text']);
}
public function update_data()
{
return array(
array('config.add', array('board_index_text', '')),
);
}
}

View file

@ -0,0 +1,28 @@
<?php
/**
*
* @package migration
* @copyright (c) 2012 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
*
*/
class phpbb_db_migration_data_310_forgot_password extends phpbb_db_migration
{
public function effectively_installed()
{
return isset($this->config['allow_password_reset']);
}
static public function depends_on()
{
return array('phpbb_db_migration_data_30x_3_0_11');
}
public function update_data()
{
return array(
array('config.add', array('allow_password_reset', 1)),
);
}
}

View file

@ -0,0 +1,31 @@
<?php
/**
*
* @package migration
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
*
*/
class phpbb_db_migration_data_310_jquery_update extends phpbb_db_migration
{
public function effectively_installed()
{
return $this->config['load_jquery_url'] !== '//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js';
}
static public function depends_on()
{
return array(
'phpbb_db_migration_data_310_dev',
);
}
public function update_data()
{
return array(
array('config.update', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js')),
);
}
}

View file

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

View file

@ -0,0 +1,51 @@
<?php
/**
*
* @package migration
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2
*
*/
class phpbb_db_migration_data_310_signature_module_auth extends phpbb_db_migration
{
public function effectively_installed()
{
$sql = 'SELECT module_auth
FROM ' . MODULES_TABLE . "
WHERE module_class = 'ucp'
AND module_basename = 'ucp_profile'
AND module_mode = 'signature'";
$result = $this->db->sql_query($sql);
$module_auth = $this->db_sql_fetchfield('module_auth');
$this->db->sql_freeresult($result);
return $module_auth === 'acl_u_sig' || $module_auth === false;
}
static public function depends_on()
{
return array('phpbb_db_migration_data_31x_dev');
}
public function update_data()
{
return array(
array('custom', array(
array($this, 'update_signature_module_auth'),
),
),
);
}
public function update_signature_module_auth()
{
$sql = 'UPDATE ' . MODULES_TABLE . "
SET module_auth = 'acl_u_sig'
WHERE module_class = 'ucp'
AND module_basename = 'ucp_profile'
AND module_mode = 'signature'
AND module_auth = ''";
$this->db->sql_query($sql);
}
}

View file

@ -19,6 +19,34 @@ class phpbb_db_migration_data_310_style_update_p1 extends phpbb_db_migration
return array('phpbb_db_migration_data_30x_3_0_11'); return array('phpbb_db_migration_data_30x_3_0_11');
} }
public function update_schema()
{
return array(
'add_columns' => array(
$this->table_prefix . 'styles' => array(
'style_path' => array('VCHAR:100', ''),
'bbcode_bitfield' => array('VCHAR:255', 'kNg='),
'style_parent_id' => array('UINT', 0),
'style_parent_tree' => array('TEXT', ''),
),
),
);
}
public function revert_schema()
{
return array(
'drop_columns' => array(
$this->table_prefix . 'styles' => array(
'style_path',
'bbcode_bitfield',
'style_parent_id',
'style_parent_tree',
),
),
);
}
public function update_data() public function update_data()
{ {
return array( return array(

View file

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

View file

@ -362,6 +362,12 @@ class phpbb_db_migrator
{ {
$state = ($state) ? unserialize($state) : false; $state = ($state) ? unserialize($state) : false;
// reverse order of steps if reverting
if ($revert === true)
{
$steps = array_reverse($steps);
}
foreach ($steps as $step_identifier => $step) foreach ($steps as $step_identifier => $step)
{ {
$last_result = false; $last_result = false;

View file

@ -0,0 +1,150 @@
<?php
/**
*
* @package dbal
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Collects rows for insert into a database until the buffer size is reached.
* Then flushes the buffer to the database and starts over again.
*
* Benefits over collecting a (possibly huge) insert array and then using
* $db->sql_multi_insert() include:
*
* - Going over max packet size of the database connection is usually prevented
* because the data is submitted in batches.
*
* - Reaching database connection timeout is usually prevented because
* submission of batches talks to the database every now and then.
*
* - Usage of less PHP memory because data no longer needed is discarded on
* buffer flush.
*
* Attention:
* Please note that users of this class have to call flush() to flush the
* remaining rows to the database after their batch insert operation is
* finished.
*
* Usage:
* <code>
* $buffer = new phpbb_db_sql_insert_buffer($db, 'test_table', 1234);
*
* while (do_stuff())
* {
* $buffer->insert(array(
* 'column1' => 'value1',
* 'column2' => 'value2',
* ));
* }
*
* $buffer->flush();
* </code>
*
* @package dbal
*/
class phpbb_db_sql_insert_buffer
{
/** @var phpbb_db_driver */
protected $db;
/** @var string */
protected $table_name;
/** @var int */
protected $max_buffered_rows;
/** @var array */
protected $buffer = array();
/**
* @param phpbb_db_driver $db
* @param string $table_name
* @param int $max_buffered_rows
*/
public function __construct(phpbb_db_driver $db, $table_name, $max_buffered_rows = 500)
{
$this->db = $db;
$this->table_name = $table_name;
$this->max_buffered_rows = $max_buffered_rows;
}
/**
* Inserts a single row into the buffer if multi insert is supported by the
* database (otherwise an insert query is sent immediately). Then flushes
* the buffer if the number of rows in the buffer is now greater than or
* equal to $max_buffered_rows.
*
* @param array $row
*
* @return bool True when some data was flushed to the database.
* False otherwise.
*/
public function insert(array $row)
{
$this->buffer[] = $row;
// Flush buffer if it is full or when DB does not support multi inserts.
// In the later case, the buffer will always only contain one row.
if (!$this->db->multi_insert || sizeof($this->buffer) >= $this->max_buffered_rows)
{
return $this->flush();
}
return false;
}
/**
* Inserts a row set, i.e. an array of rows, by calling insert().
*
* Please note that it is in most cases better to use insert() instead of
* first building a huge rowset. Or at least sizeof($rows) should be kept
* small.
*
* @param array $rows
*
* @return bool True when some data was flushed to the database.
* False otherwise.
*/
public function insert_all(array $rows)
{
// Using bitwise |= because PHP does not have logical ||=
$result = 0;
foreach ($rows as $row)
{
$result |= (int) $this->insert($row);
}
return (bool) $result;
}
/**
* Flushes the buffer content to the DB and clears the buffer.
*
* @return bool True when some data was flushed to the database.
* False otherwise.
*/
public function flush()
{
if (!empty($this->buffer))
{
$this->db->sql_multi_insert($this->table_name, $this->buffer);
$this->buffer = array();
return true;
}
return false;
}
}

View file

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

View file

@ -23,6 +23,7 @@ if (!defined('IN_PHPBB'))
class phpbb_extension_finder class phpbb_extension_finder
{ {
protected $extension_manager; protected $extension_manager;
protected $filesystem;
protected $phpbb_root_path; protected $phpbb_root_path;
protected $cache; protected $cache;
protected $php_ext; protected $php_ext;
@ -54,15 +55,17 @@ class phpbb_extension_finder
* @param phpbb_extension_manager $extension_manager An extension manager * @param phpbb_extension_manager $extension_manager An extension manager
* instance that provides the finder with a list of active * instance that provides the finder with a list of active
* extensions and their locations * extensions and their locations
* @param phpbb_filesystem $filesystem Filesystem instance
* @param string $phpbb_root_path Path to the phpbb root directory * @param string $phpbb_root_path Path to the phpbb root directory
* @param phpbb_cache_driver_interface $cache A cache instance or null * @param phpbb_cache_driver_interface $cache A cache instance or null
* @param string $php_ext php file extension * @param string $php_ext php file extension
* @param string $cache_name The name of the cache variable, defaults to * @param string $cache_name The name of the cache variable, defaults to
* _ext_finder * _ext_finder
*/ */
public function __construct(phpbb_extension_manager $extension_manager, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $php_ext = '.php', $cache_name = '_ext_finder') public function __construct(phpbb_extension_manager $extension_manager, phpbb_filesystem $filesystem, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $php_ext = 'php', $cache_name = '_ext_finder')
{ {
$this->extension_manager = $extension_manager; $this->extension_manager = $extension_manager;
$this->filesystem = $filesystem;
$this->phpbb_root_path = $phpbb_root_path; $this->phpbb_root_path = $phpbb_root_path;
$this->cache = $cache; $this->cache = $cache;
$this->php_ext = $php_ext; $this->php_ext = $php_ext;
@ -227,7 +230,7 @@ class phpbb_extension_finder
*/ */
protected function sanitise_directory($directory) protected function sanitise_directory($directory)
{ {
$directory = preg_replace('#(?:^|/)\./#', '/', $directory); $directory = $this->filesystem->clean_path($directory);
$dir_len = strlen($directory); $dir_len = strlen($directory);
if ($dir_len > 1 && $directory[$dir_len - 1] === '/') if ($dir_len > 1 && $directory[$dir_len - 1] === '/')
@ -253,8 +256,8 @@ class phpbb_extension_finder
*/ */
public function get_classes($cache = true, $use_all_available = false) public function get_classes($cache = true, $use_all_available = false)
{ {
$this->query['extension_suffix'] .= $this->php_ext; $this->query['extension_suffix'] .= '.' . $this->php_ext;
$this->query['core_suffix'] .= $this->php_ext; $this->query['core_suffix'] .= '.' . $this->php_ext;
$files = $this->find($cache, false, $use_all_available); $files = $this->find($cache, false, $use_all_available);
@ -274,7 +277,7 @@ class phpbb_extension_finder
{ {
$file = preg_replace('#^includes/#', '', $file); $file = preg_replace('#^includes/#', '', $file);
$classes[] = 'phpbb_' . str_replace('/', '_', substr($file, 0, -strlen($this->php_ext))); $classes[] = 'phpbb_' . str_replace('/', '_', substr($file, 0, -strlen('.' . $this->php_ext)));
} }
return $classes; return $classes;
} }
@ -375,6 +378,34 @@ class phpbb_extension_finder
return $files; return $files;
} }
/**
* Finds all file system entries matching the configured options for one
* specific extension
*
* @param string $extension_name Name of the extension
* @param string $extension_path Relative path to the extension root directory
* @param bool $cache Whether the result should be cached
* @param bool $is_dir Directories will be returned when true, only files
* otherwise
* @return array An array of paths to found items
*/
public function find_from_extension($extension_name, $extension_path, $cache = true, $is_dir = false)
{
$extensions = array(
$extension_name => $extension_path,
);
$files = array();
$file_list = $this->find_from_paths($extensions, $cache, $is_dir);
foreach ($file_list as $file)
{
$files[$file['named_path']] = $file['ext_name'];
}
return $files;
}
/** /**
* Finds all file system entries matching the configured options from * Finds all file system entries matching the configured options from
* an array of paths * an array of paths

View file

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

View file

@ -22,31 +22,64 @@ if (!defined('IN_PHPBB'))
*/ */
class phpbb_extension_metadata_manager class phpbb_extension_metadata_manager
{ {
protected $phpEx; /**
* phpBB Config instance
* @var phpbb_config
*/
protected $config;
/**
* phpBB Extension Manager
* @var phpbb_extension_manager
*/
protected $extension_manager; protected $extension_manager;
protected $db;
protected $phpbb_root_path; /**
* phpBB Template instance
* @var phpbb_template
*/
protected $template; protected $template;
/**
* phpBB root path
* @var string
*/
protected $phpbb_root_path;
/**
* Name (including vendor) of the extension
* @var string
*/
protected $ext_name; protected $ext_name;
/**
* Metadata from the composer.json file
* @var array
*/
protected $metadata; protected $metadata;
/**
* Link (including root path) to the metadata file
* @var string
*/
protected $metadata_file; protected $metadata_file;
/** /**
* Creates the metadata manager * Creates the metadata manager
* *
* @param phpbb_db_driver $db A database connection * @param string $ext_name Name (including vendor) of the extension
* @param string $extension_manager An instance of the phpbb extension manager * @param phpbb_config $config phpBB Config instance
* @param phpbb_extension_manager $extension_manager An instance of the phpBBb extension manager
* @param phpbb_template $template phpBB Template instance
* @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $phpbb_root_path Path to the phpbb includes directory.
* @param string $phpEx php file extension
*/ */
public function __construct($ext_name, phpbb_db_driver $db, phpbb_extension_manager $extension_manager, $phpbb_root_path, $phpEx = '.php', phpbb_template $template, phpbb_config $config) public function __construct($ext_name, phpbb_config $config, phpbb_extension_manager $extension_manager, phpbb_template $template, $phpbb_root_path)
{ {
$this->phpbb_root_path = $phpbb_root_path;
$this->db = $db;
$this->config = $config; $this->config = $config;
$this->phpEx = $phpEx;
$this->template = $template;
$this->extension_manager = $extension_manager; $this->extension_manager = $extension_manager;
$this->template = $template;
$this->phpbb_root_path = $phpbb_root_path;
$this->ext_name = $ext_name; $this->ext_name = $ext_name;
$this->metadata = array(); $this->metadata = array();
$this->metadata_file = ''; $this->metadata_file = '';

View file

@ -0,0 +1,259 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Base class with some generic functions and settings.
*
* @package phpBB3
*/
abstract class phpbb_feed_base
{
/**
* Feed helper object
* @var phpbb_feed_helper
*/
protected $helper;
/** @var phpbb_config */
protected $config;
/** @var phpbb_db_driver */
protected $db;
/** @var phpbb_cache_driver_interface */
protected $cache;
/** @var phpbb_user */
protected $user;
/** @var phpbb_auth */
protected $auth;
/** @var string */
protected $phpEx;
/**
* SQL Query to be executed to get feed items
*/
var $sql = array();
/**
* Keys specified for retrieval of title, content, etc.
*/
var $keys = array();
/**
* Number of items to fetch. Usually overwritten by $config['feed_something']
*/
var $num_items = 15;
/**
* Separator for title elements to separate items (for example forum / topic)
*/
var $separator = "\xE2\x80\xA2"; // &bull;
/**
* Separator for the statistics row (Posted by, post date, replies, etc.)
*/
var $separator_stats = "\xE2\x80\x94"; // &mdash;
/**
* Constructor
*
* @param phpbb_feed_helper $helper Feed helper
* @param phpbb_config $config Config object
* @param phpbb_db_driver $db Database connection
* @param phpbb_cache_driver_interface $cache Cache object
* @param phpbb_user $user User object
* @param phpbb_auth $auth Auth object
* @param string $phpEx php file extension
* @return null
*/
function __construct(phpbb_feed_helper $helper, phpbb_config $config, phpbb_db_driver $db, phpbb_cache_driver_interface $cache, phpbb_user $user, phpbb_auth $auth, $phpEx)
{
$this->config = $config;
$this->helper = $helper;
$this->db = $db;
$this->cache = $cache;
$this->user = $user;
$this->auth = $auth;
$this->phpEx = $phpEx;
$this->set_keys();
// Allow num_items to be string
if (is_string($this->num_items))
{
$this->num_items = (int) $this->config[$this->num_items];
// A precaution
if (!$this->num_items)
{
$this->num_items = 10;
}
}
}
/**
* Set keys.
*/
function set_keys()
{
}
/**
* Open feed
*/
function open()
{
}
/**
* Close feed
*/
function close()
{
if (!empty($this->result))
{
$this->db->sql_freeresult($this->result);
}
}
/**
* Set key
*/
function set($key, $value)
{
$this->keys[$key] = $value;
}
/**
* Get key
*/
function get($key)
{
return (isset($this->keys[$key])) ? $this->keys[$key] : NULL;
}
function get_readable_forums()
{
static $forum_ids;
if (!isset($forum_ids))
{
$forum_ids = array_keys($this->auth->acl_getf('f_read', true));
}
return $forum_ids;
}
function get_moderator_approve_forums()
{
static $forum_ids;
if (!isset($forum_ids))
{
$forum_ids = array_keys($this->auth->acl_getf('m_approve', true));
}
return $forum_ids;
}
function is_moderator_approve_forum($forum_id)
{
static $forum_ids;
if (!isset($forum_ids))
{
$forum_ids = array_flip($this->get_moderator_approve_forums());
}
return (isset($forum_ids[$forum_id])) ? true : false;
}
function get_excluded_forums()
{
static $forum_ids;
// Matches acp/acp_board.php
$cache_name = 'feed_excluded_forum_ids';
if (!isset($forum_ids) && ($forum_ids = $this->cache->get('_' . $cache_name)) === false)
{
$sql = 'SELECT forum_id
FROM ' . FORUMS_TABLE . '
WHERE ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_EXCLUDE, '<> 0');
$result = $this->db->sql_query($sql);
$forum_ids = array();
while ($forum_id = (int) $this->db->sql_fetchfield('forum_id'))
{
$forum_ids[$forum_id] = $forum_id;
}
$this->db->sql_freeresult($result);
$this->cache->put('_' . $cache_name, $forum_ids);
}
return $forum_ids;
}
function is_excluded_forum($forum_id)
{
$forum_ids = $this->get_excluded_forums();
return isset($forum_ids[$forum_id]) ? true : false;
}
function get_passworded_forums()
{
return $this->user->get_passworded_forums();
}
function get_item()
{
static $result;
if (!isset($result))
{
if (!$this->get_sql())
{
return false;
}
// Query database
$sql = $this->db->sql_build_query('SELECT', $this->sql);
$result = $this->db->sql_query_limit($sql, $this->num_items);
}
return $this->db->sql_fetchrow($result);
}
function user_viewprofile($row)
{
$author_id = (int) $row[$this->get('author_id')];
if ($author_id == ANONYMOUS)
{
// Since we cannot link to a profile, we just return GUEST
// instead of $row['username']
return $this->user->lang['GUEST'];
}
return '<a href="' . $this->helper->append_sid('memberlist.' . $this->phpEx, 'mode=viewprofile&amp;u=' . $author_id) . '">' . $row[$this->get('creator')] . '</a>';
}
}

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