Merge commit 'release-3.0.6-RC2'

This commit is contained in:
Nils Adermann 2010-03-02 01:05:40 +01:00
commit f0eb18fffd
48 changed files with 1049 additions and 362 deletions

View file

@ -54,10 +54,12 @@
</fieldset> </fieldset>
<!-- ENDIF --> <!-- ENDIF -->
<fieldset class="submit-buttons"> <fieldset>
<legend>{L_SUBMIT}</legend> <legend>{L_ACP_SUBMIT_CHANGES}</legend>
<input class="button1" type="submit" id="main_submit" name="main_submit" value="{L_SUBMIT}" />&nbsp; <p class="submit-buttons">
<input class="button2" type="reset" id="form_reset" name="reset" value="{L_RESET}" />&nbsp; <input class="button1" type="submit" id="main_submit" name="main_submit" value="{L_SUBMIT}" />&nbsp;
<input class="button2" type="reset" id="form_reset" name="reset" value="{L_RESET}" />&nbsp;
</p>
{S_FORM_TOKEN} {S_FORM_TOKEN}
</fieldset> </fieldset>
</form> </form>

View file

@ -71,8 +71,9 @@
<dl> <dl>
<dt><label for="where">{L_ACTION}:</label></dt> <dt><label for="where">{L_ACTION}:</label></dt>
<dd> <dd>
<label><input type="radio" class="radio" name="where" value="store" checked="checked" /> {L_STORE_LOCAL}</label> <label><input id="where" type="radio" class="radio" name="where" value="store" checked="checked" /> {L_STORE_LOCAL}</label>
<label><input type="radio" class="radio" name="where" value="download" /> {L_DOWNLOAD}</label></dd> <label><input type="radio" class="radio" name="where" value="download" /> {L_DOWNLOAD}</label>
</dd>
</dl> </dl>
<dl> <dl>
<dt><label for="table">{L_TABLE_SELECT}:</label></dt> <dt><label for="table">{L_TABLE_SELECT}:</label></dt>

View file

@ -41,6 +41,7 @@
<td style="vertical-align: top;"> <td style="vertical-align: top;">
{inactive.REASON} {inactive.REASON}
<!-- IF inactive.REMINDED --><br />{inactive.REMINDED_EXPLAIN}<!-- ENDIF --> <!-- IF inactive.REMINDED --><br />{inactive.REMINDED_EXPLAIN}<!-- ENDIF -->
</td>
<td>&nbsp;<input type="checkbox" class="radio" name="mark[]" value="{inactive.USER_ID}" />&nbsp;</td> <td>&nbsp;<input type="checkbox" class="radio" name="mark[]" value="{inactive.USER_ID}" />&nbsp;</td>
</tr> </tr>
<!-- BEGINELSE --> <!-- BEGINELSE -->
@ -67,7 +68,7 @@
<fieldset class="quick"> <fieldset class="quick">
<select name="action">{S_INACTIVE_OPTIONS}</select> <select name="action">{S_INACTIVE_OPTIONS}</select>
<input class="button2" type="submit" name="submit" value="{L_SUBMIT}" /> <input class="button2" type="submit" name="submit" value="{L_SUBMIT}" />
<p class="small"><a href="#" onclick="marklist('inactive', 'mark', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('inactive', 'mark', false); return false;">{L_UNMARK_ALL}</a></p> <p class="small"><a href="#" onclick="marklist('inactive', 'mark', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('inactive', 'mark', false); return false;">{L_UNMARK_ALL}</a></p>
{S_FORM_TOKEN} {S_FORM_TOKEN}
</fieldset> </fieldset>

View file

@ -14,11 +14,12 @@
<!-- IF PAGINATION --> <!-- IF PAGINATION -->
<div class="pagination" style="float: right; margin: 15px 0 2px 0"> <div class="pagination" style="float: right; margin: 15px 0 2px 0">
<a href="#" onclick="jumpto(); return false;" title="{L_JUMP_TO_PAGE}">{S_ON_PAGE}</a> &bull; <span>{PAGINATION}</span> <a href="#" onclick="jumpto(); return false;" title="{L_JUMP_TO_PAGE}">{S_ON_PAGE}</a> &bull; <span>{PAGINATION}</span>
</div> </div>
<!-- ENDIF --> <!-- ENDIF -->
<div class="clearfix">&nbsp;</div><br style="clear: both;" /> <div class="clearfix">&nbsp;</div>
<div><br style="clear: both;" /></div>
<!-- IF .log --> <!-- IF .log -->
<table cellspacing="1"> <table cellspacing="1">

View file

@ -232,6 +232,7 @@
<td style="vertical-align: top;"> <td style="vertical-align: top;">
{inactive.REASON} {inactive.REASON}
<!-- IF inactive.REMINDED --><br />{inactive.REMINDED_EXPLAIN}<!-- ENDIF --> <!-- IF inactive.REMINDED --><br />{inactive.REMINDED_EXPLAIN}<!-- ENDIF -->
</td>
</tr> </tr>
<!-- BEGINELSE --> <!-- BEGINELSE -->
<tr> <tr>

View file

@ -20,7 +20,7 @@
</dl> </dl>
<dl> <dl>
<dt><label for="new_id">{L_REPLACE}:</label><br /><span>{L_REPLACE_EXPLAIN}</span></dt> <dt><label for="new_id">{L_REPLACE}:</label><br /><span>{L_REPLACE_EXPLAIN}</span></dt>
<dd><select name="new_id">{S_REPLACE_OPTIONS}</select></dd> <dd><select id="new_id" name="new_id">{S_REPLACE_OPTIONS}</select></dd>
</dl> </dl>
<p class="quick"> <p class="quick">
@ -135,11 +135,11 @@
<div id="img_dimensions"> <div id="img_dimensions">
<dl> <dl>
<dt><label for="imgwidth">{L_IMAGE_WIDTH}:</label><br /><span>{L_AUTOMATIC_EXPLAIN}</span></dt> <dt><label for="imgwidth">{L_IMAGE_WIDTH}:</label><br /><span>{L_AUTOMATIC_EXPLAIN}</span></dt>
<dd><input type="text" name="imgwidth" value="{IMAGE_SIZE}" /></dd> <dd><input id="imgwidth" type="text" name="imgwidth" value="{IMAGE_SIZE}" /></dd>
</dl> </dl>
<dl> <dl>
<dt><label for="imgheight">{L_IMAGE_HEIGHT}:</label><br /><span>{L_AUTOMATIC_EXPLAIN}</span></dt> <dt><label for="imgheight">{L_IMAGE_HEIGHT}:</label><br /><span>{L_AUTOMATIC_EXPLAIN}</span></dt>
<dd><input type="text" name="imgheight" value="{IMAGE_HEIGHT}" /></dd> <dd><input id="imgheight" type="text" name="imgheight" value="{IMAGE_HEIGHT}" /></dd>
</dl> </dl>
</div> </div>
</fieldset> </fieldset>
@ -266,7 +266,7 @@
<p>{L_TEMPLATE_CACHE_EXPLAIN}</p> <p>{L_TEMPLATE_CACHE_EXPLAIN}</p>
<form name="acp_styles" method="post" action="{U_ACTION}"> <form id="acp_styles" method="post" action="{U_ACTION}">
<fieldset class="tabulated"> <fieldset class="tabulated">
<legend>{L_TEMPLATE_CACHE}</legend> <legend>{L_TEMPLATE_CACHE}</legend>

View file

@ -7,17 +7,16 @@
<th>{L_REPORT_BY}</th> <th>{L_REPORT_BY}</th>
<th>{L_TIME}</th> <th>{L_TIME}</th>
<th>{L_FEEDBACK}</th> <th>{L_FEEDBACK}</th>
<!-- IF S_CLEARLOGS --><th>{L_MARK}</th><!-- ENDIF --> <th>{L_MARK}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<!-- BEGIN warn --> <!-- BEGIN warn -->
<!-- IF warn.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> <!-- IF warn.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF -->
<td>{warn.USERNAME}</td> <td>{warn.USERNAME}</td>
<td style="text-align: center; nowrap: nowrap;">{warn.DATE}</td> <td style="text-align: center; nowrap: nowrap;">{warn.DATE}</td>
<td>{warn.ACTION}</td> <td>{warn.ACTION}</td>
<!-- IF S_CLEARLOGS --><td style="text-align: center;"><input type="checkbox" class="radio" name="mark[]" value="{warn.ID}" /></td><!-- ENDIF --> <td style="text-align: center;"><input type="checkbox" class="radio" name="mark[]" value="{warn.ID}" /></td>
</tr> </tr>
<!-- END warn --> <!-- END warn -->
</tbody> </tbody>
@ -28,12 +27,10 @@
</div> </div>
<!-- ENDIF --> <!-- ENDIF -->
<!-- IF S_CLEARLOGS --> <fieldset class="quick">
<fieldset class="quick"> <input class="button2" type="submit" name="delall" value="{L_DELETE_ALL}" />&nbsp;
<input class="button2" type="submit" name="delall" value="{L_DELETE_ALL}" />&nbsp; <input class="button2" type="submit" name="delmarked" value="{L_DELETE_MARKED}" />
<input class="button2" type="submit" name="delmarked" value="{L_DELETE_MARKED}" /> <p class="small"><a href="#" onclick="marklist('list', 'mark', true);">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('list', 'mark', false);">{L_UNMARK_ALL}</a></p>
<p class="small"><a href="#" onclick="marklist('list', 'mark', true);">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('list', 'mark', false);">{L_UNMARK_ALL}</a></p> </fieldset>
</fieldset>
<!-- ENDIF -->
{S_FORM_TOKEN} {S_FORM_TOKEN}
</form> </form>

View file

@ -69,8 +69,8 @@ h2, caption {
h3, h4 { h3, h4 {
font-family: "Trebuchet MS", Helvetica, sans-serif; font-family: "Trebuchet MS", Helvetica, sans-serif;
font-size: 1.20em; font-size: 1.20em;
text-decoration: none; text-decoration: none;
line-height: 1.20em; line-height: 1.20em;
margin-top: 25px; margin-top: 25px;
} }
@ -97,8 +97,8 @@ hr {
height: 1px; height: 1px;
} }
.small { .small {
font-size: 0.85em; font-size: 0.85em;
} }
/* General links */ /* General links */
@ -195,7 +195,7 @@ li {
width: 76%; width: 76%;
margin: 0 0 0 3%; margin: 0 0 0 3%;
min-height: 350px; min-height: 350px;
overflow-y: auto; overflow-x: auto;
} }
.rtl #main { .rtl #main {
@ -203,8 +203,9 @@ li {
margin: 0 3% 0 0; margin: 0 3% 0 0;
} }
* html #main { * html #main {
height: 350px; height: 350px;
overflow-x: visible;
} }
#page-body.simple-page-body { #page-body.simple-page-body {
@ -316,7 +317,7 @@ li {
padding: 0; padding: 0;
} }
span.corners-top, span.corners-bottom, span.corners-top, span.corners-bottom,
span.corners-top span, span.corners-bottom span { span.corners-top span, span.corners-bottom span {
font-size: 1px; font-size: 1px;
line-height: 1px; line-height: 1px;
@ -795,7 +796,7 @@ label img {
fieldset.quick, p.quick { fieldset.quick, p.quick {
margin: 0 0 5px; margin: 0 0 5px;
padding: 5px 0 0; padding: 5px 0 0;
border: none; border: none;
background-color: transparent; background-color: transparent;
text-align: right; text-align: right;
@ -848,7 +849,7 @@ select option.disabled {
} }
/* Special case inputs */ /* Special case inputs */
select#board_timezone, select#board_timezone,
select#full_folder_action { select#full_folder_action {
width: 95%; width: 95%;
} }
@ -1245,12 +1246,12 @@ input.disabled {
} }
/* Nice method for clearing floated blocks without having to insert any extra markup /* Nice method for clearing floated blocks without having to insert any extra markup
From http://www.positioniseverything.net/easyclearing.html From http://www.positioniseverything.net/easyclearing.html
.clearfix:after, #tabs:after, .row:after, #content:after, fieldset dl:after, #page-body:after { .clearfix:after, #tabs:after, .row:after, #content:after, fieldset dl:after, #page-body:after {
content: "."; content: ".";
display: block; display: block;
height: 0; height: 0;
clear: both; clear: both;
visibility: hidden; visibility: hidden;
}*/ }*/
@ -1317,7 +1318,7 @@ fieldset.permissions legend input{
height: 1.1em; height: 1.1em;
} }
/* Permission sections */ /* Permission sections */
fieldset.permissions .permissions-simple { fieldset.permissions .permissions-simple {
text-align: left; text-align: left;
padding-top: 3px; padding-top: 3px;
@ -1528,7 +1529,7 @@ fieldset.permissions .padding {
background-image: url("../images/corners_right2.gif"); background-image: url("../images/corners_right2.gif");
} }
.permissions-panel span.corners-top, .permissions-panel span.corners-bottom, .permissions-panel span.corners-top, .permissions-panel span.corners-bottom,
.permissions-panel span.corners-top span, .permissions-panel span.corners-bottom span { .permissions-panel span.corners-top span, .permissions-panel span.corners-bottom span {
font-size: 1px; font-size: 1px;
line-height: 1px; line-height: 1px;
@ -1606,7 +1607,7 @@ fieldset.permissions .padding {
} }
.permissions-panel th.row4 { .permissions-panel th.row4 {
background-image: none; background-image: none;
background-color: #E4E8EB; background-color: #E4E8EB;
color: #536482; color: #536482;
border: none; border: none;
@ -1614,8 +1615,8 @@ fieldset.permissions .padding {
.permissions-panel th a:link, .permissions-panel th a:hover, .permissions-panel th a:visited { .permissions-panel th a:link, .permissions-panel th a:hover, .permissions-panel th a:visited {
display: block; display: block;
color: #FFFFFF; color: #FFFFFF;
text-decoration: underline; text-decoration: underline;
} }
.permissions-panel td.permissions-yes label:hover { .permissions-panel td.permissions-yes label:hover {

View file

@ -56,11 +56,13 @@
</fieldset> </fieldset>
<fieldset class="submit-buttons"> <fieldset>
<legend>{L_SUBMIT}</legend> <legend>{L_ACP_SUBMIT_CHANGES}</legend>
<input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" />&nbsp; <p class="submit-buttons">
<input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" />&nbsp; <input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" />&nbsp;
<input class="button2" type="submit" id="preview" name="preview" value="{L_PREVIEW}" />&nbsp; <input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" />&nbsp;
<input class="button2" type="submit" id="preview" name="preview" value="{L_PREVIEW}" />&nbsp;
</p>
<input type="hidden" name="select_captcha" value="{CAPTCHA_NAME}" /> <input type="hidden" name="select_captcha" value="{CAPTCHA_NAME}" />
<input type="hidden" name="configure" value="1" /> <input type="hidden" name="configure" value="1" />

View file

@ -34,10 +34,12 @@
<!-- INCLUDE {CAPTCHA_PREVIEW} --> <!-- INCLUDE {CAPTCHA_PREVIEW} -->
</fieldset> </fieldset>
<fieldset class="submit-buttons"> <fieldset>
<legend>{L_SUBMIT}</legend> <legend>{L_ACP_SUBMIT_CHANGES}</legend>
<input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" />&nbsp; <p class="submit-buttons">
<input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" />&nbsp; <input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" />&nbsp;
<input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" />&nbsp;
</p>
<input type="hidden" name="select_captcha" value="{CAPTCHA_NAME}" /> <input type="hidden" name="select_captcha" value="{CAPTCHA_NAME}" />
<input type="hidden" name="configure" value="1" /> <input type="hidden" name="configure" value="1" />

View file

@ -15,9 +15,9 @@
// <![CDATA[ // <![CDATA[
function resize_panel() function resize_panel()
{ {
var block = document.getElementById('codepanel'); var block = document.getElementById('codepanel');
var height; var height;
if (window.innerHeight) if (window.innerHeight)
{ {
height = window.innerHeight - 150; height = window.innerHeight - 150;
@ -26,7 +26,7 @@ function resize_panel()
else else
{ {
//whatever IE needs to do this //whatever IE needs to do this
} }
} }
window.onresize = resize_panel; window.onresize = resize_panel;
@ -54,7 +54,7 @@ div#codepanel {
width: 100%; width: 100%;
} }
<!-- ELSE --> <!-- ELSE -->
div#codepanel { div#codepanel {
background-color: #eee; background-color: #eee;
} }
<!-- ENDIF --> <!-- ENDIF -->
@ -149,10 +149,10 @@ table.hrdiff tbody th {
table.hrdiff tbody td.old { table.hrdiff tbody td.old {
border-left: 1px solid #999; border-left: 1px solid #999;
border-right: 1px solid #999; border-right: 1px solid #999;
} }
table.hrdiff tbody td.new { table.hrdiff tbody td.new {
border-right: 1px solid #999; border-right: 1px solid #999;
} }
table.hrdiff td pre { table.hrdiff td pre {
@ -237,19 +237,19 @@ table.hrdiff caption span {
<input class="button1" type="submit" id="submit" name="submit" value="{L_CHANGE}" /> <input class="button1" type="submit" id="submit" name="submit" value="{L_CHANGE}" />
</fieldset> </fieldset>
</form> </form>
<!-- ENDIF -->
<!-- IF S_DIFF_CONFLICT_FILE -->
<div style="float: {S_CONTENT_FLOW_BEGIN};"><strong>{L_NUM_CONFLICTS}: {NUM_CONFLICTS}</strong></div>
<br style="clear: both;" />
<!-- ENDIF --> <!-- ENDIF -->
</div> </div>
<div id="page-body"> <div id="page-body">
<div id="acp"> <div id="acp">
<div class="panel" id="codepanel"> <div class="panel" id="codepanel">
<span class="corners-top"><span></span></span> <span class="corners-top"><span></span></span>
<div id="diff_content"> <div id="diff_content">
<div id="main"> <div id="main">
<!-- IF S_DIFF_CONFLICT_FILE -->
<div style="float: {S_CONTENT_FLOW_END};"><strong>{L_NUM_CONFLICTS}: {NUM_CONFLICTS}</strong></div>
<!-- ENDIF -->
{DIFF_CONTENT} {DIFF_CONTENT}
</div> </div>
</div> </div>
@ -257,6 +257,6 @@ table.hrdiff caption span {
</div> </div>
</div> </div>
</div> </div>
<!-- INCLUDE simple_footer.html --> <!-- INCLUDE simple_footer.html -->

View file

@ -210,9 +210,12 @@
<li>[Fix] Do not display links to user/post search if search is disabled. (Bug #50685 - Patch by HardStyle)</li> <li>[Fix] Do not display links to user/post search if search is disabled. (Bug #50685 - Patch by HardStyle)</li>
<li>[Fix] Fix icon alignment for forums with large descriptions in subsilver2. (Bug #50445)</li> <li>[Fix] Fix icon alignment for forums with large descriptions in subsilver2. (Bug #50445)</li>
<li>[Fix] Correctly display underlined links placed in last line in viewtopic. (Bug #14811 - Patch by primehalo)</li> <li>[Fix] Correctly display underlined links placed in last line in viewtopic. (Bug #14811 - Patch by primehalo)</li>
<li>[Fix] Only check whether forum image exists if forum image is specified. (Bug #51905)</li>
<li>[Fix] Fixed database backup and restore with Oracle DBMS.</li>
<li>[Fix] Fixed database updater for changes to columns having default value in MSSQL (adding/dropping constraints)</li>
<li>[Change] Database updater now supports checking for existing/missing indexes.</li>
<li>[Change] submit_post() now accepts force_approved_state key passed to $data to indicate new posts being approved (true) or unapproved (false).</li> <li>[Change] submit_post() now accepts force_approved_state key passed to $data to indicate new posts being approved (true) or unapproved (false).</li>
<li>[Change] Change the data format of the default file ACM to be more secure from tampering and have better performance.</li> <li>[Change] Change the data format of the default file ACM to be more secure from tampering and have better performance.</li>
<li>[Change] Add index on log_time to the log table to prevent slowdown on boards with many log entries. (Bug #44665 - Patch by bantu)</li>
<li>[Change] Template engine now permits to a limited extent variable includes.</li> <li>[Change] Template engine now permits to a limited extent variable includes.</li>
<li>[Change] Quote BBCode no longer requires the f_reply permission. (Bug #16079)</li> <li>[Change] Quote BBCode no longer requires the f_reply permission. (Bug #16079)</li>
<li>[Change] Banning/unbanning users now generates an entry in their user notes (Bug #21825 - Patch by nickvergessen)</li> <li>[Change] Banning/unbanning users now generates an entry in their user notes (Bug #21825 - Patch by nickvergessen)</li>
@ -243,7 +246,8 @@
<li>[Change] Do not take edit post time into account for determining permission to delete last post in topic. (Bug #48615)</li> <li>[Change] Do not take edit post time into account for determining permission to delete last post in topic. (Bug #48615)</li>
<li>[Change] Resize oversized Topic icons (Bug #44415)</li> <li>[Change] Resize oversized Topic icons (Bug #44415)</li>
<li>[Change] Banned IPs are now sorted (Bug #43045 - Patch by DavidIQ)</li> <li>[Change] Banned IPs are now sorted (Bug #43045 - Patch by DavidIQ)</li>
<li>[Change] phpBB updater now skips sole whitespace changes. This reduces the chance of conflicts tremendously.</li> <li>[Change] phpBB updater now skips sole whitespace/tab changes while computing differences. This reduces the chance of conflicts tremendously.</li>
<li>[Change] phpBB updater now solves common conflicts on it's own. This further reduces the chance of conflicts.</li>
<li>[Feature] Add language selection on the registration terms page (Bug #15085 - Patch by leviatan21)</li> <li>[Feature] Add language selection on the registration terms page (Bug #15085 - Patch by leviatan21)</li>
<li>[Feature] Backported 3.2 captcha plugins. <li>[Feature] Backported 3.2 captcha plugins.
<ul> <ul>
@ -300,6 +304,7 @@
<li>[Feature] Added function to generate Email hash. (Bug #49195)</li> <li>[Feature] Added function to generate Email hash. (Bug #49195)</li>
<li>[Feature] Style authors are now able to define the default submit button used for form submission on ENTER keypress on forms using more than one. Prosilver uses this for the posting page(s) and registration screen.</li> <li>[Feature] Style authors are now able to define the default submit button used for form submission on ENTER keypress on forms using more than one. Prosilver uses this for the posting page(s) and registration screen.</li>
<li>[Feature] Ability to specify amount of time user is able to delete his last post in topic.</li> <li>[Feature] Ability to specify amount of time user is able to delete his last post in topic.</li>
<li>[Feature] Send anonymous statistical information to phpBB on installation and update (optional).</li>
</ul> </ul>
<a name="v304"></a><h3>1.ii. Changes since 3.0.4</h3> <a name="v304"></a><h3>1.ii. Changes since 3.0.4</h3>

View file

@ -30,10 +30,13 @@ class acp_captcha
$user->add_lang('acp/board'); $user->add_lang('acp/board');
include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx); include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
$captchas = phpbb_captcha_factory::get_captcha_types();
$selected = request_var('select_captcha', $config['captcha_plugin']); $selected = request_var('select_captcha', $config['captcha_plugin']);
$selected = (isset($captchas['available'][$selected]) || isset($captchas['unavailable'][$selected])) ? $selected : $config['captcha_plugin'];
$configure = request_var('configure', false); $configure = request_var('configure', false);
// Oh, they are just here for the view // Oh, they are just here for the view
if (isset($_GET['captcha_demo'])) if (isset($_GET['captcha_demo']))
{ {
@ -45,12 +48,9 @@ class acp_captcha
{ {
$config_captcha =& phpbb_captcha_factory::get_instance($selected); $config_captcha =& phpbb_captcha_factory::get_instance($selected);
$config_captcha->acp_page($id, $this); $config_captcha->acp_page($id, $this);
add_log('admin', 'LOG_CONFIG_VISUAL');
} }
else else
{ {
$captchas = phpbb_captcha_factory::get_captcha_types();
$config_vars = array( $config_vars = array(
'enable_confirm' => array('tpl' => 'REG_ENABLE', 'default' => false), 'enable_confirm' => array('tpl' => 'REG_ENABLE', 'default' => false),
'enable_post_confirm' => array('tpl' => 'POST_ENABLE', 'default' => false), 'enable_post_confirm' => array('tpl' => 'POST_ENABLE', 'default' => false),

View file

@ -142,7 +142,7 @@ class acp_database
break; break;
case 'oracle': case 'oracle':
$extractor->flush('TRUNCATE TABLE ' . $table_name . "\\\n"); $extractor->flush('TRUNCATE TABLE ' . $table_name . "/\n");
break; break;
default: default:
@ -1716,8 +1716,7 @@ class oracle_extractor extends base_extractor
{ {
global $db; global $db;
$sql_data = '-- Table: ' . $table_name . "\n"; $sql_data = '-- Table: ' . $table_name . "\n";
$sql_data .= "DROP TABLE $table_name;\n"; $sql_data .= "DROP TABLE $table_name\n/\n";
$sql_data .= '\\' . "\n";
$sql_data .= "\nCREATE TABLE $table_name (\n"; $sql_data .= "\nCREATE TABLE $table_name (\n";
$sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT $sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT
@ -1732,7 +1731,7 @@ class oracle_extractor extends base_extractor
if ($row['data_type'] !== 'CLOB') if ($row['data_type'] !== 'CLOB')
{ {
if ($row['data_type'] !== 'VARCHAR2') if ($row['data_type'] !== 'VARCHAR2' && $row['data_type'] !== 'CHAR')
{ {
$line .= '(' . $row['data_precision'] . ')'; $line .= '(' . $row['data_precision'] . ')';
} }
@ -1762,12 +1761,20 @@ class oracle_extractor extends base_extractor
AND A.TABLE_NAME = '{$table_name}'"; AND A.TABLE_NAME = '{$table_name}'";
$result = $db->sql_query($sql); $result = $db->sql_query($sql);
$primary_key = array();
$contraint_name = '';
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
{ {
$rows[] = " CONSTRAINT {$row['constraint_name']} PRIMARY KEY ({$row['column_name']})"; $constraint_name = '"' . $row['constraint_name'] . '"';
$primary_key[] = '"' . $row['column_name'] . '"';
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
if (sizeof($primary_key))
{
$rows[] = " CONSTRAINT {$constraint_name} PRIMARY KEY (" . implode(', ', $primary_key) . ')';
}
$sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
@ -1775,24 +1782,44 @@ class oracle_extractor extends base_extractor
AND A.TABLE_NAME = '{$table_name}'"; AND A.TABLE_NAME = '{$table_name}'";
$result = $db->sql_query($sql); $result = $db->sql_query($sql);
$unique = array();
$contraint_name = '';
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
{ {
$rows[] = " CONSTRAINT {$row['constraint_name']} UNIQUE ({$row['column_name']})"; $constraint_name = '"' . $row['constraint_name'] . '"';
$unique[] = '"' . $row['column_name'] . '"';
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
$sql_data .= implode(",\n", $rows); if (sizeof($unique))
$sql_data .= "\n)\n\\"; {
$rows[] = " CONSTRAINT {$constraint_name} UNIQUE (" . implode(', ', $unique) . ')';
}
$sql = "SELECT A.REFERENCED_NAME $sql_data .= implode(",\n", $rows);
FROM USER_DEPENDENCIES A, USER_TRIGGERS B $sql_data .= "\n)\n/\n";
$sql = "SELECT A.REFERENCED_NAME, C.*
FROM USER_DEPENDENCIES A, USER_TRIGGERS B, USER_SEQUENCES C
WHERE A.REFERENCED_TYPE = 'SEQUENCE' WHERE A.REFERENCED_TYPE = 'SEQUENCE'
AND A.NAME = B.TRIGGER_NAME AND A.NAME = B.TRIGGER_NAME
AND B. TABLE_NAME = '{$table_name}'"; AND B.TABLE_NAME = '{$table_name}'
AND C.SEQUENCE_NAME = A.REFERENCED_NAME";
$result = $db->sql_query($sql); $result = $db->sql_query($sql);
$type = request_var('type', '');
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
{ {
$sql_data .= "\nCREATE SEQUENCE {$row['referenced_name']}\\\n"; $sql_data .= "\nDROP SEQUENCE \"{$row['referenced_name']}\"\n/\n";
$sql_data .= "\nCREATE SEQUENCE \"{$row['referenced_name']}\"";
if ($type == 'full')
{
$sql_data .= ' START WITH ' . $row['last_number'];
}
$sql_data .= "\n/\n";
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
@ -1802,7 +1829,7 @@ class oracle_extractor extends base_extractor
$result = $db->sql_query($sql); $result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
{ {
$sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\\"; $sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\n/\n";
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
@ -1822,7 +1849,7 @@ class oracle_extractor extends base_extractor
foreach ($index as $index_name => $column_names) foreach ($index as $index_name => $column_names)
{ {
$sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n\\"; $sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n/\n";
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
$this->flush($sql_data); $this->flush($sql_data);
@ -1858,7 +1885,7 @@ class oracle_extractor extends base_extractor
// Oracle uses uppercase - we use lowercase // Oracle uses uppercase - we use lowercase
$str_val = $row[strtolower($ary_name[$i])]; $str_val = $row[strtolower($ary_name[$i])];
if (preg_match('#char|text|bool|raw#i', $ary_type[$i])) if (preg_match('#char|text|bool|raw|clob#i', $ary_type[$i]))
{ {
$str_quote = ''; $str_quote = '';
$str_empty = "''"; $str_empty = "''";
@ -1892,7 +1919,7 @@ class oracle_extractor extends base_extractor
// Take the ordered fields and their associated data and build it // Take the ordered fields and their associated data and build it
// into a valid sql statement to recreate that field in the data. // into a valid sql statement to recreate that field in the data.
$sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n"; $sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ")\n/\n";
$this->flush($sql_data); $this->flush($sql_data);
} }
@ -2211,8 +2238,10 @@ function sanitize_data_mssql($text)
function sanitize_data_oracle($text) function sanitize_data_oracle($text)
{ {
$data = preg_split('/[\0\n\t\r\b\f\'"\\\]/', $text); // $data = preg_split('/[\0\n\t\r\b\f\'"\/\\\]/', $text);
preg_match_all('/[\0\n\t\r\b\f\'"\\\]/', $text, $matches); // preg_match_all('/[\0\n\t\r\b\f\'"\/\\\]/', $text, $matches);
$data = preg_split('/[\0\b\f\'\/]/', $text);
preg_match_all('/[\0\r\b\f\'\/]/', $text, $matches);
$val = array(); $val = array();

View file

@ -171,7 +171,7 @@ class acp_forums
$forum_data['forum_status'] = ITEM_UNLOCKED; $forum_data['forum_status'] = ITEM_UNLOCKED;
} }
$forum_data['show_active'] = ($forum_data['forum_type'] == FORUM_POST) ? request_var('display_recent', false) : request_var('display_active', false); $forum_data['show_active'] = ($forum_data['forum_type'] == FORUM_POST) ? request_var('display_recent', true) : request_var('display_active', true);
// Get data for forum rules if specified... // Get data for forum rules if specified...
if ($forum_data['forum_rules']) if ($forum_data['forum_rules'])
@ -443,7 +443,7 @@ class acp_forums
'prune_days' => 7, 'prune_days' => 7,
'prune_viewed' => 7, 'prune_viewed' => 7,
'prune_freq' => 1, 'prune_freq' => 1,
'forum_flags' => FORUM_FLAG_POST_REVIEW, 'forum_flags' => FORUM_FLAG_POST_REVIEW + FORUM_FLAG_ACTIVE_TOPICS,
'forum_options' => 0, 'forum_options' => 0,
'forum_password' => '', 'forum_password' => '',
'forum_password_confirm'=> '', 'forum_password_confirm'=> '',
@ -907,7 +907,7 @@ class acp_forums
array('lang' => 'FORUM_TOPICS_PAGE', 'value' => $forum_data['forum_topics_per_page'], 'column_type' => 'TINT:0'), array('lang' => 'FORUM_TOPICS_PAGE', 'value' => $forum_data['forum_topics_per_page'], 'column_type' => 'TINT:0'),
); );
if (!file_exists($phpbb_root_path . $forum_data['forum_image'])) if (!empty($forum_data['forum_image']) && !file_exists($phpbb_root_path . $forum_data['forum_image']))
{ {
$errors[] = $user->lang['FORUM_IMAGE_NO_EXIST']; $errors[] = $user->lang['FORUM_IMAGE_NO_EXIST'];
} }

View file

@ -43,6 +43,7 @@ class acp_update
$latest_version = trim($info[0]); $latest_version = trim($info[0]);
$announcement_url = trim($info[1]); $announcement_url = trim($info[1]);
$announcement_url = (strpos($announcement_url, '&amp;') === false) ? str_replace('&', '&amp;', $announcement_url) : $announcement_url;
$update_link = append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=update'); $update_link = append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=update');
// Determine automatic update... // Determine automatic update...

View file

@ -1167,13 +1167,7 @@ class acp_users
$deleteall = request_var('delall', 0); $deleteall = request_var('delall', 0);
if ($deletemark && $marked) if ($deletemark && $marked)
{ {
$sql_in = array(); $where_sql = ' AND ' . $db->sql_in_set('warning_id', array_values($marked));
foreach ($marked as $mark)
{
$sql_in[] = $mark;
}
$where_sql = ' AND ' . $db->sql_in_set('warning_id', $sql_in);
unset($sql_in);
} }
if ($where_sql || $deleteall) if ($where_sql || $deleteall)
@ -1291,7 +1285,6 @@ class acp_users
$template->assign_vars(array( $template->assign_vars(array(
'S_WARNINGS' => true, 'S_WARNINGS' => true,
'S_CLEARLOGS' => $auth->acl_get('a_clearlogs'),
)); ));
break; break;
@ -1715,6 +1708,7 @@ class acp_users
$template->assign_vars(array( $template->assign_vars(array(
'S_AVATAR' => true, 'S_AVATAR' => true,
'S_CAN_UPLOAD' => $can_upload,
'S_UPLOAD_FILE' => ($config['allow_avatar'] && $can_upload && $config['allow_avatar_upload']) ? true : false, 'S_UPLOAD_FILE' => ($config['allow_avatar'] && $can_upload && $config['allow_avatar_upload']) ? true : false,
'S_REMOTE_UPLOAD' => ($config['allow_avatar'] && $can_upload && $config['allow_avatar_remote_upload']) ? true : false, 'S_REMOTE_UPLOAD' => ($config['allow_avatar'] && $can_upload && $config['allow_avatar_remote_upload']) ? true : false,
'S_ALLOW_REMOTE' => ($config['allow_avatar'] && $config['allow_avatar_remote']) ? true : false, 'S_ALLOW_REMOTE' => ($config['allow_avatar'] && $config['allow_avatar_remote']) ? true : false,

View file

@ -67,10 +67,12 @@ function login_db(&$username, &$password)
// Every auth module is able to define what to do by itself... // Every auth module is able to define what to do by itself...
if ($config['max_login_attempts'] && $row['user_login_attempts'] >= $config['max_login_attempts']) if ($config['max_login_attempts'] && $row['user_login_attempts'] >= $config['max_login_attempts'])
{ {
$confirm_id = request_var('confirm_id', '');
// Visual Confirmation handling // Visual Confirmation handling
if (!$confirm_id)
$captcha =& phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
$vc_response = $captcha->validate();
if ($vc_response)
{ {
return array( return array(
'status' => LOGIN_ERROR_ATTEMPTS, 'status' => LOGIN_ERROR_ATTEMPTS,
@ -78,21 +80,7 @@ function login_db(&$username, &$password)
'user_row' => $row, 'user_row' => $row,
); );
} }
else
{
$captcha =& phpbb_captcha_factory::get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
$vc_response = $captcha->validate();
if ($vc_response)
{
return array(
'status' => LOGIN_ERROR_ATTEMPTS,
'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
'user_row' => $row,
);
}
}
} }
// If the password convert flag is set we need to convert it // If the password convert flag is set we need to convert it

View file

@ -128,7 +128,7 @@ class bbcode
*/ */
function bbcode_cache_init() function bbcode_cache_init()
{ {
global $user, $phpbb_root_path; global $phpbb_root_path, $template, $user;
if (empty($this->template_filename)) if (empty($this->template_filename))
{ {
@ -137,7 +137,7 @@ class bbcode
if (!@file_exists($this->template_filename)) if (!@file_exists($this->template_filename))
{ {
if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id']) if (isset($template->orig_tpl_inherits_id) && $template->orig_tpl_inherits_id)
{ {
$this->template_filename = $phpbb_root_path . 'styles/' . $user->theme['template_inherit_path'] . '/template/bbcode.html'; $this->template_filename = $phpbb_root_path . 'styles/' . $user->theme['template_inherit_path'] . '/template/bbcode.html';
if (!@file_exists($this->template_filename)) if (!@file_exists($this->template_filename))

View file

@ -80,7 +80,7 @@ class phpbb_captcha_gd extends phpbb_default_captcha
{ {
return true; return true;
} }
function get_name() function get_name()
{ {
return 'CAPTCHA_GD'; return 'CAPTCHA_GD';
@ -123,6 +123,8 @@ class phpbb_captcha_gd extends phpbb_default_captcha
set_config($captcha_var, $value); set_config($captcha_var, $value);
} }
} }
add_log('admin', 'LOG_CONFIG_VISUAL');
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action)); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action));
} }
else if ($submit) else if ($submit)
@ -148,7 +150,7 @@ class phpbb_captcha_gd extends phpbb_default_captcha
function execute_demo() function execute_demo()
{ {
global $config; global $config;
$config_old = $config; $config_old = $config;
foreach ($this->captcha_vars as $captcha_var => $template_var) foreach ($this->captcha_vars as $captcha_var => $template_var)
{ {

View file

@ -56,13 +56,13 @@ class phpbb_captcha_qa
$this->answer = request_var('qa_answer', '', true); $this->answer = request_var('qa_answer', '', true);
$this->type = (int) $type; $this->type = (int) $type;
$this->question_lang = $user->data['user_lang']; $this->question_lang = $user->lang_name;
// we need all defined questions - shouldn't be too many, so we can just grab them // we need all defined questions - shouldn't be too many, so we can just grab them
// try the user's lang first // try the user's lang first
$sql = 'SELECT question_id $sql = 'SELECT question_id
FROM ' . CAPTCHA_QUESTIONS_TABLE . " FROM ' . CAPTCHA_QUESTIONS_TABLE . "
WHERE lang_iso = '" . $db->sql_escape($user->data['user_lang']) . "'"; WHERE lang_iso = '" . $db->sql_escape($user->lang_name) . "'";
$result = $db->sql_query($sql, 3600); $result = $db->sql_query($sql, 3600);
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
@ -685,6 +685,7 @@ class phpbb_captcha_qa
$this->acp_add_question($data); $this->acp_add_question($data);
} }
add_log('admin', 'LOG_CONFIG_VISUAL');
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($list_url)); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($list_url));
} }
} }

View file

@ -100,6 +100,8 @@ class phpbb_recaptcha extends phpbb_default_captcha
set_config($captcha_var, $value); set_config($captcha_var, $value);
} }
} }
add_log('admin', 'LOG_CONFIG_VISUAL');
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action)); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action));
} }
else if ($submit) else if ($submit)

View file

@ -25,7 +25,7 @@ if (!defined('IN_PHPBB'))
*/ */
// phpBB Version // phpBB Version
define('PHPBB_VERSION', '3.0.6-RC1'); define('PHPBB_VERSION', '3.0.6-RC2');
// QA-related // QA-related
// define('PHPBB_QA', 1); // define('PHPBB_QA', 1);

View file

@ -1190,11 +1190,13 @@ class phpbb_db_tools
// For hexadecimal values do not use single quotes // For hexadecimal values do not use single quotes
if (strpos($column_data[1], '0x') === 0) if (strpos($column_data[1], '0x') === 0)
{ {
$sql_default .= 'DEFAULT (' . $column_data[1] . ') '; $return_array['default'] = 'DEFAULT (' . $column_data[1] . ') ';
$sql_default .= $return_array['default'];
} }
else else
{ {
$sql_default .= 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; $return_array['default'] = 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') ';
$sql_default .= $return_array['default'];
} }
} }
@ -1781,7 +1783,7 @@ class phpbb_db_tools
case 'firebird': case 'firebird':
$sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
FROM RDB\$INDICES FROM RDB\$INDICES
WHERE RDB\$RELATION_NAME = " . strtoupper($table_name) . " WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "'
AND RDB\$UNIQUE_FLAG IS NULL AND RDB\$UNIQUE_FLAG IS NULL
AND RDB\$FOREIGN_KEY IS NULL"; AND RDB\$FOREIGN_KEY IS NULL";
$col = 'index_name'; $col = 'index_name';
@ -1808,8 +1810,9 @@ class phpbb_db_tools
case 'oracle': case 'oracle':
$sql = "SELECT index_name $sql = "SELECT index_name
FROM user_indexes FROM user_indexes
WHERE table_name = '" . $table_name . "' WHERE table_name = '" . strtoupper($table_name) . "'
AND generated = 'N'"; AND generated = 'N'
AND uniqueness = 'NONUNIQUE'";
$col = 'index_name'; $col = 'index_name';
break; break;
@ -1870,6 +1873,27 @@ class phpbb_db_tools
case 'mssql': case 'mssql':
$statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql'];
if (!empty($column_data['default']))
{
// Using TRANSACT-SQL for this statement because we do not want to have colliding data if statements are executed at a later stage
$statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000)
SET @drop_default_name =
(SELECT so.name FROM sysobjects so
JOIN sysconstraints sc ON so.id = sc.constid
WHERE object_name(so.parent_obj) = '{$table_name}'
AND so.xtype = 'D'
AND sc.colid = (SELECT colid FROM syscolumns
WHERE id = object_id('{$table_name}')
AND name = '{$column_name}'))
IF @drop_default_name <> ''
BEGIN
SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']'
EXEC(@cmd)
END
SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]'
EXEC(@cmd)";
}
break; break;
case 'mysql_40': case 'mysql_40':

View file

@ -255,13 +255,62 @@ class dbal_oracle extends dbal
// We overcome Oracle's 4000 char limit by binding vars // We overcome Oracle's 4000 char limit by binding vars
if (strlen($query) > 4000) if (strlen($query) > 4000)
{ {
if (preg_match('/^(INSERT INTO[^(]++)\\(([^()]+)\\) VALUES[^(]++\\((.*?)\\)$/s', $query, $regs)) if (preg_match('/^(INSERT INTO[^(]++)\\(([^()]+)\\) VALUES[^(]++\\((.*?)\\)$/sU', $query, $regs))
{ {
if (strlen($regs[3]) > 4000) if (strlen($regs[3]) > 4000)
{ {
$cols = explode(', ', $regs[2]); $cols = explode(', ', $regs[2]);
preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER); preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER);
if (sizeof($cols) !== sizeof($vals))
{
// Try to replace some common data we know is from our restore script or from other sources
$regs[3] = str_replace("'||chr(47)||'", '/', $regs[3]);
$_vals = explode(', ', $regs[3]);
$vals = array();
$is_in_val = false;
$i = 0;
$string = '';
foreach ($_vals as $value)
{
if (strpos($value, "'") === false && !$is_in_val)
{
$vals[$i++] = $value;
continue;
}
if (substr($value, -1) === "'")
{
$vals[$i] = $string . (($is_in_val) ? ', ' : '') . $value;
$string = '';
$is_in_val = false;
if ($vals[$i][0] !== "'")
{
$vals[$i] = "''" . $vals[$i];
}
$i++;
continue;
}
else
{
$string .= (($is_in_val) ? ', ' : '') . $value;
$is_in_val = true;
}
}
if ($string)
{
// New value if cols != value
$vals[(sizeof($cols) !== sizeof($vals)) ? $i : $i - 1] .= $string;
}
$vals = array(0 => $vals);
}
$inserts = $vals[0]; $inserts = $vals[0];
unset($vals); unset($vals);

View file

@ -71,8 +71,10 @@ class diff
{ {
$count = 0; $count = 0;
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if (is_a($edit, 'diff_op_add') || is_a($edit, 'diff_op_change')) if (is_a($edit, 'diff_op_add') || is_a($edit, 'diff_op_change'))
{ {
$count += $edit->nfinal(); $count += $edit->nfinal();
@ -92,8 +94,10 @@ class diff
{ {
$count = 0; $count = 0;
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if (is_a($edit, 'diff_op_delete') || is_a($edit, 'diff_op_change')) if (is_a($edit, 'diff_op_delete') || is_a($edit, 'diff_op_change'))
{ {
$count += $edit->norig(); $count += $edit->norig();
@ -128,8 +132,9 @@ class diff
$rev->_edits = array(); $rev->_edits = array();
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
$rev->_edits[] = $edit->reverse(); $rev->_edits[] = $edit->reverse();
} }
@ -143,13 +148,36 @@ class diff
*/ */
function is_empty() function is_empty()
{ {
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
if (!is_a($edit, 'diff_op_copy')) $edit = $this->_edits[$i];
// skip diff_op_copy
if (is_a($edit, 'diff_op_copy'))
{ {
continue;
}
if (is_a($edit, 'diff_op_delete') || is_a($edit, 'diff_op_add'))
{
$orig = $edit->orig;
$final = $edit->final;
// We can simplify one case where the array is usually supposed to be empty...
if (sizeof($orig) == 1 && trim($orig[0]) === '') $orig = array();
if (sizeof($final) == 1 && trim($final[0]) === '') $final = array();
if (!$orig && !$final)
{
continue;
}
return false; return false;
} }
return false;
} }
return true; return true;
} }
@ -164,8 +192,10 @@ class diff
{ {
$lcs = 0; $lcs = 0;
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if (is_a($edit, 'diff_op_copy')) if (is_a($edit, 'diff_op_copy'))
{ {
$lcs += sizeof($edit->orig); $lcs += sizeof($edit->orig);
@ -185,8 +215,10 @@ class diff
{ {
$lines = array(); $lines = array();
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if ($edit->orig) if ($edit->orig)
{ {
array_splice($lines, sizeof($lines), 0, $edit->orig); array_splice($lines, sizeof($lines), 0, $edit->orig);
@ -206,8 +238,10 @@ class diff
{ {
$lines = array(); $lines = array();
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if ($edit->final) if ($edit->final)
{ {
array_splice($lines, sizeof($lines), 0, $edit->final); array_splice($lines, sizeof($lines), 0, $edit->final);
@ -258,8 +292,10 @@ class diff
$prevtype = null; $prevtype = null;
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if ($prevtype == get_class($edit)) if ($prevtype == get_class($edit))
{ {
trigger_error("[diff] Edit sequence is non-optimal", E_USER_ERROR); trigger_error("[diff] Edit sequence is non-optimal", E_USER_ERROR);
@ -456,14 +492,14 @@ class diff3 extends diff
* @param array $final1 The first version to compare to. * @param array $final1 The first version to compare to.
* @param array $final2 The second version to compare to. * @param array $final2 The second version to compare to.
*/ */
function diff3(&$orig, &$final1, &$final2) function diff3(&$orig, &$final1, &$final2, $preserve_cr = true)
{ {
$diff_engine = new diff_engine(); $diff_engine = new diff_engine();
$diff_1 = $diff_engine->diff($orig, $final1); $diff_1 = $diff_engine->diff($orig, $final1, $preserve_cr);
$diff_2 = $diff_engine->diff($orig, $final2); $diff_2 = $diff_engine->diff($orig, $final2, $preserve_cr);
unset($engine); unset($diff_engine);
$this->_edits = $this->_diff3($diff_1, $diff_2); $this->_edits = $this->_diff3($diff_1, $diff_2);
} }
@ -475,8 +511,10 @@ class diff3 extends diff
{ {
$conflicts = 0; $conflicts = 0;
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if ($edit->is_conflict()) if ($edit->is_conflict())
{ {
$conflicts++; $conflicts++;
@ -506,8 +544,10 @@ class diff3 extends diff
$lines = array(); $lines = array();
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if ($edit->is_conflict()) if ($edit->is_conflict())
{ {
// Start conflict label // Start conflict label
@ -544,8 +584,10 @@ class diff3 extends diff
{ {
$lines = array(); $lines = array();
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if ($edit->is_conflict()) if ($edit->is_conflict())
{ {
$lines = array_merge($lines, $edit->final2); $lines = array_merge($lines, $edit->final2);
@ -566,8 +608,10 @@ class diff3 extends diff
{ {
$lines = array(); $lines = array();
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if ($edit->is_conflict()) if ($edit->is_conflict())
{ {
$lines = array_merge($lines, $edit->final1); $lines = array_merge($lines, $edit->final1);
@ -588,8 +632,10 @@ class diff3 extends diff
{ {
$conflicts = array(); $conflicts = array();
foreach ($this->_edits as $edit) for ($i = 0, $size = sizeof($this->_edits); $i < $size; $i++)
{ {
$edit = $this->_edits[$i];
if ($edit->is_conflict()) if ($edit->is_conflict())
{ {
$conflicts[] = array($edit->final1, $edit->final2); $conflicts[] = array($edit->final1, $edit->final2);
@ -713,6 +759,9 @@ class diff3_op
{ {
if (!isset($this->_merged)) if (!isset($this->_merged))
{ {
// Prepare the arrays before we compare them. ;)
$this->solve_prepare();
if ($this->final1 === $this->final2) if ($this->final1 === $this->final2)
{ {
$this->_merged = &$this->final1; $this->_merged = &$this->final1;
@ -727,7 +776,9 @@ class diff3_op
} }
else else
{ {
// The following tries to aggressively solve conflicts...
$this->_merged = false; $this->_merged = false;
$this->solve_conflict();
} }
} }
@ -738,6 +789,267 @@ class diff3_op
{ {
return ($this->merged() === false) ? true : false; return ($this->merged() === false) ? true : false;
} }
/**
* Function to prepare the arrays for comparing - we want to skip over newline changes
* @author acydburn
*/
function solve_prepare()
{
// We can simplify one case where the array is usually supposed to be empty...
if (sizeof($this->orig) == 1 && trim($this->orig[0]) === '') $this->orig = array();
if (sizeof($this->final1) == 1 && trim($this->final1[0]) === '') $this->final1 = array();
if (sizeof($this->final2) == 1 && trim($this->final2[0]) === '') $this->final2 = array();
// Now we only can have the case where the only difference between arrays are newlines, so compare all cases
// First, some strings we can compare...
$orig = $final1 = $final2 = '';
foreach ($this->orig as $null => $line) $orig .= trim($line);
foreach ($this->final1 as $null => $line) $final1 .= trim($line);
foreach ($this->final2 as $null => $line) $final2 .= trim($line);
// final1 === final2
if ($final1 === $final2)
{
// We preserve the part which will be used in the merge later
$this->final2 = $this->final1;
}
// final1 === orig
else if ($final1 === $orig)
{
// Here it does not really matter what we choose, but we will use the new code
$this->orig = $this->final1;
}
// final2 === orig
else if ($final2 === $orig)
{
// Here it does not really matter too (final1 will be used), but we will use the new code
$this->orig = $this->final2;
}
}
/**
* Find code portions from $orig in $final1 and use $final2 as merged instance if provided
* @author acydburn
*/
function _compare_conflict_seq($orig, $final1, $final2 = false)
{
$result = array('merge_found' => false, 'merge' => array());
$_orig = &$this->$orig;
$_final1 = &$this->$final1;
// Ok, we basically search for $orig in $final1
$compare_seq = sizeof($_orig);
// Go through the conflict code
for ($i = 0, $j = 0, $size = sizeof($_final1); $i < $size; $i++, $j = $i)
{
$line = $_final1[$i];
$skip = 0;
for ($x = 0; $x < $compare_seq; $x++)
{
// Try to skip all matching lines
if (trim($line) === trim($_orig[$x]))
{
$line = (++$j < $size) ? $_final1[$j] : $line;
$skip++;
}
}
if ($skip === $compare_seq)
{
$result['merge_found'] = true;
if ($final2 !== false)
{
$result['merge'] = array_merge($result['merge'], $this->$final2);
}
$i += ($skip - 1);
}
else if ($final2 !== false)
{
$result['merge'][] = $line;
}
}
return $result;
}
/**
* Tries to solve conflicts aggressively based on typical "assumptions"
* @author acydburn
*/
function solve_conflict()
{
$this->_merged = false;
// CASE ONE: orig changed into final2, but modified/unknown code in final1.
// IF orig is found "as is" in final1 we replace the code directly in final1 and populate this as final2/merge
if (sizeof($this->orig) && sizeof($this->final2))
{
$result = $this->_compare_conflict_seq('orig', 'final1', 'final2');
if ($result['merge_found'])
{
$this->final2 = $result['merge'];
$this->_merged = &$this->final2;
return;
}
$result = $this->_compare_conflict_seq('final2', 'final1');
if ($result['merge_found'])
{
$this->_merged = &$this->final1;
return;
}
// Try to solve $Id$ issues. ;)
if (sizeof($this->orig) == 1 && sizeof($this->final1) == 1 && sizeof($this->final2) == 1)
{
$match = '#^' . preg_quote('* @version $Id: ', '#') . '[a-z\._\- ]+[0-9]+ [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9\:Z]+ [a-z0-9_\- ]+\$$#';
if (preg_match($match, $this->orig[0]) && preg_match($match, $this->final1[0]) && preg_match($match, $this->final2[0]))
{
$this->_merged = &$this->final2;
return;
}
}
$second_run = false;
// Try to solve issues where the only reason why the above did not work is a newline being removed in the final1 code but exist in the orig/final2 code
if (trim($this->orig[0]) === '' && trim($this->final2[0]) === '')
{
unset($this->orig[0], $this->final2[0]);
$this->orig = array_values($this->orig);
$this->final2 = array_values($this->final2);
$second_run = true;
}
// The same is true for a line at the end. ;)
if (sizeof($this->orig) && sizeof($this->final2) && sizeof($this->orig) === sizeof($this->final2) && trim($this->orig[sizeof($this->orig)-1]) === '' && trim($this->final2[sizeof($this->final2)-1]) === '')
{
unset($this->orig[sizeof($this->orig)-1], $this->final2[sizeof($this->final2)-1]);
$this->orig = array_values($this->orig);
$this->final2 = array_values($this->final2);
$second_run = true;
}
if ($second_run)
{
$result = $this->_compare_conflict_seq('orig', 'final1', 'final2');
if ($result['merge_found'])
{
$this->final2 = $result['merge'];
$this->_merged = &$this->final2;
return;
}
$result = $this->_compare_conflict_seq('final2', 'final1');
if ($result['merge_found'])
{
$this->_merged = &$this->final1;
return;
}
}
return;
}
// CASE TWO: Added lines from orig to final2 but final1 had added lines too. Just merge them.
if (!sizeof($this->orig) && $this->final1 !== $this->final2 && sizeof($this->final1) && sizeof($this->final2))
{
$result = $this->_compare_conflict_seq('final2', 'final1');
if ($result['merge_found'])
{
$this->final2 = $this->final1;
$this->_merged = &$this->final1;
}
else
{
$result = $this->_compare_conflict_seq('final1', 'final2');
if (!$result['merge_found'])
{
$this->final2 = array_merge($this->final1, $this->final2);
$this->_merged = &$this->final2;
}
else
{
$this->final2 = $this->final1;
$this->_merged = &$this->final1;
}
}
return;
}
// CASE THREE: Removed lines (orig has the to-remove line(s), but final1 has additional lines which does not need to be removed). Just remove orig from final1 and then use final1 as final2/merge
if (!sizeof($this->final2) && sizeof($this->orig) && sizeof($this->final1) && $this->orig !== $this->final1)
{
$result = $this->_compare_conflict_seq('orig', 'final1');
if (!$result['merge_found'])
{
return;
}
// First of all, try to find the code in orig in final1. ;)
$compare_seq = sizeof($this->orig);
$begin = $end = -1;
$j = 0;
for ($i = 0, $size = sizeof($this->final1); $i < $size; $i++)
{
$line = $this->final1[$i];
if (trim($line) === trim($this->orig[$j]))
{
// Mark begin
if ($begin === -1)
{
$begin = $i;
}
// End is always $i, the last found line
$end = $i;
if (isset($this->orig[$j+1]))
{
$j++;
}
}
}
if ($begin !== -1 && $begin + ($compare_seq - 1) == $end)
{
foreach ($this->final1 as $i => $line)
{
if ($i < $begin || $i > $end)
{
$merged[] = $line;
}
}
$this->final2 = $merged;
$this->_merged = &$this->final2;
}
return;
}
return;
}
} }
/** /**

View file

@ -49,6 +49,9 @@ if (!defined('IN_PHPBB'))
*/ */
class diff_engine class diff_engine
{ {
/**
* If set to true we trim all lines before we compare them. This ensures that sole space/tab changes do not trigger diffs.
*/
var $skip_whitespace_changes = true; var $skip_whitespace_changes = true;
function diff(&$from_lines, &$to_lines, $preserve_cr = true) function diff(&$from_lines, &$to_lines, $preserve_cr = true)
@ -87,7 +90,7 @@ class diff_engine
// Skip leading common lines. // Skip leading common lines.
for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++)
{ {
if ($from_lines[$skip] !== $to_lines[$skip]) if (trim($from_lines[$skip]) !== trim($to_lines[$skip]))
{ {
break; break;
} }
@ -100,7 +103,7 @@ class diff_engine
for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++)
{ {
if ($from_lines[$xi] !== $to_lines[$yi]) if (trim($from_lines[$xi]) !== trim($to_lines[$yi]))
{ {
break; break;
} }
@ -110,12 +113,12 @@ class diff_engine
// Ignore lines which do not exist in both files. // Ignore lines which do not exist in both files.
for ($xi = $skip; $xi < $n_from - $endskip; $xi++) for ($xi = $skip; $xi < $n_from - $endskip; $xi++)
{ {
$xhash[$from_lines[$xi]] = 1; if ($this->skip_whitespace_changes) $xhash[trim($from_lines[$xi])] = 1; else $xhash[$from_lines[$xi]] = 1;
} }
for ($yi = $skip; $yi < $n_to - $endskip; $yi++) for ($yi = $skip; $yi < $n_to - $endskip; $yi++)
{ {
$line = $to_lines[$yi]; $line = ($this->skip_whitespace_changes) ? trim($to_lines[$yi]) : $to_lines[$yi];
if (($this->ychanged[$yi] = empty($xhash[$line]))) if (($this->ychanged[$yi] = empty($xhash[$line])))
{ {
@ -128,7 +131,7 @@ class diff_engine
for ($xi = $skip; $xi < $n_from - $endskip; $xi++) for ($xi = $skip; $xi < $n_from - $endskip; $xi++)
{ {
$line = $from_lines[$xi]; $line = ($this->skip_whitespace_changes) ? trim($from_lines[$xi]) : $from_lines[$xi];
if (($this->xchanged[$xi] = empty($yhash[$line]))) if (($this->xchanged[$xi] = empty($yhash[$line])))
{ {
@ -142,8 +145,21 @@ class diff_engine
$this->_compareseq(0, sizeof($this->xv), 0, sizeof($this->yv)); $this->_compareseq(0, sizeof($this->xv), 0, sizeof($this->yv));
// Merge edits when possible. // Merge edits when possible.
$this->_shift_boundaries($from_lines, $this->xchanged, $this->ychanged); if ($this->skip_whitespace_changes)
$this->_shift_boundaries($to_lines, $this->ychanged, $this->xchanged); {
$from_lines_clean = array_map('trim', $from_lines);
$to_lines_clean = array_map('trim', $to_lines);
$this->_shift_boundaries($from_lines_clean, $this->xchanged, $this->ychanged);
$this->_shift_boundaries($to_lines_clean, $this->ychanged, $this->xchanged);
unset($from_lines_clean, $to_lines_clean);
}
else
{
$this->_shift_boundaries($from_lines, $this->xchanged, $this->ychanged);
$this->_shift_boundaries($to_lines, $this->ychanged, $this->xchanged);
}
// Compute the edit operations. // Compute the edit operations.
$edits = array(); $edits = array();
@ -178,20 +194,6 @@ class diff_engine
$add[] = $to_lines[$yi++]; $add[] = $to_lines[$yi++];
} }
// Here we are a bit naughty. Naughty Boy... Naughty Boy...
// We check if delete and add is filled and only consist of one item
if ($this->skip_whitespace_changes && sizeof($delete) == 1 && sizeof($add) == 1)
{
// Now we simply trim the string and see if the lines are identical
// If they are identical we do not need to take them into account for the merge (less conflicts in phpBB)
if (trim($delete[0]) === trim($add[0]))
{
// This line ensures the line found here is correctly copied later (remember: we naughty boys like loops)
$xi--; $yi--; $this->xchanged[$xi] = $this->ychanged[$yi] = false;
$delete = $add = array();
}
}
if ($delete && $add) if ($delete && $add)
{ {
$edits[] = new diff_op_change($delete, $add); $edits[] = new diff_op_change($delete, $add);

View file

@ -1693,11 +1693,11 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s
'LEFT_JOIN' => array( 'LEFT_JOIN' => array(
array( array(
'FROM' => array(TOPICS_TRACK_TABLE => 'tt'), 'FROM' => array(TOPICS_TRACK_TABLE => 'tt'),
'ON' => "tt.user_id = $user_id AND t.topic_id = tt.topic_id AND tt.mark_time > $last_mark", 'ON' => "tt.user_id = $user_id AND t.topic_id = tt.topic_id",
), ),
array( array(
'FROM' => array(FORUMS_TRACK_TABLE => 'ft'), 'FROM' => array(FORUMS_TRACK_TABLE => 'ft'),
'ON' => "ft.user_id = $user_id AND t.forum_id = ft.forum_id AND ft.mark_time > $last_mark", 'ON' => "ft.user_id = $user_id AND t.forum_id = ft.forum_id",
), ),
), ),
@ -1705,10 +1705,7 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s
( (
(tt.mark_time IS NOT NULL AND t.topic_last_post_time > tt.mark_time) OR (tt.mark_time IS NOT NULL AND t.topic_last_post_time > tt.mark_time) OR
(tt.mark_time IS NULL AND ft.mark_time IS NOT NULL AND t.topic_last_post_time > ft.mark_time) OR (tt.mark_time IS NULL AND ft.mark_time IS NOT NULL AND t.topic_last_post_time > ft.mark_time) OR
( (tt.mark_time IS NULL AND ft.mark_time IS NULL AND t.topic_last_post_time > $last_mark)
((tt.mark_time IS NULL AND ft.mark_time IS NULL) OR (tt.mark_time < $last_mark AND ft.mark_time < $last_mark))
AND t.topic_last_post_time > $last_mark
)
) )
$sql_extra $sql_extra
$sql_sort", $sql_sort",
@ -3050,6 +3047,7 @@ function login_forum_box($forum_data)
page_header($user->lang['LOGIN'], false); page_header($user->lang['LOGIN'], false);
$template->assign_vars(array( $template->assign_vars(array(
'S_LOGIN_ACTION' => build_url(array('f')),
'S_HIDDEN_FIELDS' => build_hidden_fields(array('f' => $forum_data['forum_id']))) 'S_HIDDEN_FIELDS' => build_hidden_fields(array('f' => $forum_data['forum_id'])))
); );
@ -4034,16 +4032,6 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
} }
} }
// Which timezone?
$tz = ($user->data['user_id'] != ANONYMOUS) ? strval(doubleval($user->data['user_timezone'])) : strval(doubleval($config['board_timezone']));
// Send a proper content-language to the output
$user_lang = $user->lang['USER_LANG'];
if (strpos($user_lang, '-x-') !== false)
{
$user_lang = substr($user_lang, 0, strpos($user_lang, '-x-'));
}
$forum_id = request_var('f', 0); $forum_id = request_var('f', 0);
$topic_id = request_var('t', 0); $topic_id = request_var('t', 0);
@ -4064,6 +4052,16 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
$board_url = generate_board_url() . '/'; $board_url = generate_board_url() . '/';
$web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $phpbb_root_path; $web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $phpbb_root_path;
// Which timezone?
$tz = ($user->data['user_id'] != ANONYMOUS) ? strval(doubleval($user->data['user_timezone'])) : strval(doubleval($config['board_timezone']));
// Send a proper content-language to the output
$user_lang = $user->lang['USER_LANG'];
if (strpos($user_lang, '-x-') !== false)
{
$user_lang = substr($user_lang, 0, strpos($user_lang, '-x-'));
}
// The following assigns all _common_ variables that may be used at any point in a template. // The following assigns all _common_ variables that may be used at any point in a template.
$template->assign_vars(array( $template->assign_vars(array(
'SITENAME' => $config['sitename'], 'SITENAME' => $config['sitename'],

View file

@ -254,7 +254,7 @@ function get_forum_list($acl_list = 'f_list', $id_only = true, $postable_only =
if ($acl_list == '' || ($acl_list != '' && $auth->acl_gets($acl_list, $row['forum_id']))) if ($acl_list == '' || ($acl_list != '' && $auth->acl_gets($acl_list, $row['forum_id'])))
{ {
$rowset[] = ($id_only) ? $row['forum_id'] : $row; $rowset[] = ($id_only) ? (int) $row['forum_id'] : $row;
} }
} }
@ -2514,6 +2514,7 @@ function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id
case 'mod': case 'mod':
$log_type = LOG_MOD; $log_type = LOG_MOD;
$sql_forum = '';
if ($topic_id) if ($topic_id)
{ {

View file

@ -199,7 +199,7 @@ class messenger
$template_path .= $template_lang . '/email'; $template_path .= $template_lang . '/email';
} }
$tpl->set_custom_template($template_path, $template_lang . '_email'); $tpl->set_custom_template($template_path, $template_lang . '_email', 'email');
$tpl->set_filenames(array( $tpl->set_filenames(array(
'body' => $template_file . '.txt', 'body' => $template_file . '.txt',
@ -1134,7 +1134,24 @@ class smtp_class
global $user; global $user;
$err_msg = ''; $err_msg = '';
$local_host = (function_exists('php_uname')) ? gethostbyaddr(gethostbyname(php_uname('n'))) : $user->host;
// Here we try to determine the *real* hostname (reverse DNS entry preferrably)
$local_host = $user->host;
if (function_exists('php_uname'))
{
$local_host = php_uname('n');
// Able to resolve name to IP
if (($addr = @gethostbyname($local_host)) !== $local_host)
{
// Able to resolve IP back to name
if (($name = @gethostbyaddr($addr)) !== $addr)
{
$local_host = $name;
}
}
}
// If we are authenticating through pop-before-smtp, we // If we are authenticating through pop-before-smtp, we
// have to login ones before we get authenticated // have to login ones before we get authenticated

View file

@ -1900,7 +1900,7 @@ function set_user_message_limit()
*/ */
function get_recipient_strings($pm_by_id) function get_recipient_strings($pm_by_id)
{ {
global $user, $db; global $db, $phpbb_root_path, $phpEx, $user;
$address_list = $recipient_list = $address = array(); $address_list = $recipient_list = $address = array();

View file

@ -349,7 +349,6 @@ class filespec
} }
phpbb_chmod($this->destination_file, $chmod); phpbb_chmod($this->destination_file, $chmod);
return true;
} }
// Try to get real filesize from destination folder // Try to get real filesize from destination folder

View file

@ -593,7 +593,7 @@ function close_report($report_id_list, $mode, $action, $pm = false)
$db->sql_query($sql); $db->sql_query($sql);
if ($action == 'delete') if ($action == 'delete')
{echo "aha"; {
delete_pm(ANONYMOUS, $close_report_posts, PRIVMSGS_INBOX); delete_pm(ANONYMOUS, $close_report_posts, PRIVMSGS_INBOX);
} }
} }

View file

@ -259,7 +259,7 @@ function mcp_topic_view($id, $mode, $action)
// Display topic icons for split topic // Display topic icons for split topic
$s_topic_icons = false; $s_topic_icons = false;
if ($auth->acl_get('m_split', $topic_info['forum_id'])) if ($auth->acl_gets('m_split', 'm_merge', (int) $topic_info['forum_id']))
{ {
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx); include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
$s_topic_icons = posting_gen_topic_icons('', $icon_id); $s_topic_icons = posting_gen_topic_icons('', $icon_id);

View file

@ -1345,7 +1345,7 @@ class parse_message extends bbcode_firstpass
/** /**
* Parse Attachments * Parse Attachments
*/ */
function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false, $post_msg_id = 0, $topic_id = 0) function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false)
{ {
global $config, $auth, $user, $phpbb_root_path, $phpEx, $db; global $config, $auth, $user, $phpbb_root_path, $phpEx, $db;
@ -1498,25 +1498,16 @@ class parse_message extends bbcode_firstpass
'filesize' => $filedata['filesize'], 'filesize' => $filedata['filesize'],
'filetime' => $filedata['filetime'], 'filetime' => $filedata['filetime'],
'thumbnail' => $filedata['thumbnail'], 'thumbnail' => $filedata['thumbnail'],
'is_orphan' => ($post_msg_id) ? 0 : 1, 'is_orphan' => 1,
'in_message' => ($is_message) ? 1 : 0, 'in_message' => ($is_message) ? 1 : 0,
'poster_id' => $user->data['user_id'], 'poster_id' => $user->data['user_id'],
); );
if ($post_msg_id)
{
$sql_ary['post_msg_id'] = $post_msg_id;
if ($topic_id)
{
$sql_ary['topic_id'] = $topic_id;
}
}
$db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
$new_entry = array( $new_entry = array(
'attach_id' => $db->sql_nextid(), 'attach_id' => $db->sql_nextid(),
'is_orphan' => ($post_msg_id) ? 0 : 1, 'is_orphan' => 1,
'real_filename' => $filedata['real_filename'], 'real_filename' => $filedata['real_filename'],
'attach_comment'=> $this->filename_data['filecomment'], 'attach_comment'=> $this->filename_data['filecomment'],
); );

View file

@ -182,7 +182,7 @@ class session
else else
{ {
// Set to OS hostname or localhost // Set to OS hostname or localhost
$host = (function_exists('php_uname')) ? gethostbyaddr(gethostbyname(php_uname('n'))) : 'localhost'; $host = (function_exists('php_uname')) ? php_uname('n') : 'localhost';
} }
} }

View file

@ -90,7 +90,7 @@ class template
* Set custom template location (able to use directory outside of phpBB) * Set custom template location (able to use directory outside of phpBB)
* @access public * @access public
*/ */
function set_custom_template($template_path, $template_name) function set_custom_template($template_path, $template_name, $template_mode = 'template')
{ {
global $phpbb_root_path, $user; global $phpbb_root_path, $user;
@ -102,8 +102,13 @@ class template
$this->root = $template_path; $this->root = $template_path;
$this->cachepath = $phpbb_root_path . 'cache/ctpl_' . str_replace('_', '-', $template_name) . '_'; $this->cachepath = $phpbb_root_path . 'cache/ctpl_' . str_replace('_', '-', $template_name) . '_';
$user->theme['template_storedb'] = false;
$user->theme['template_inherits_id'] = false; // As the template-engine is used for more than the template (emails, etc.), we should not set $user->theme in all cases, but only on the real template.
if ($template_mode == 'template')
{
$user->theme['template_storedb'] = false;
$user->theme['template_inherits_id'] = false;
}
$this->_rootref = &$this->_tpldata['.'][0]; $this->_rootref = &$this->_tpldata['.'][0];

View file

@ -708,7 +708,6 @@ class ucp_groups
'S_UPLOAD_AVATAR_FILE' => ($config['allow_avatar'] && $config['allow_avatar_upload'] && $can_upload) ? true : false, 'S_UPLOAD_AVATAR_FILE' => ($config['allow_avatar'] && $config['allow_avatar_upload'] && $can_upload) ? true : false,
'S_UPLOAD_AVATAR_URL' => ($config['allow_avatar'] && $config['allow_avatar_remote_upload'] && $can_upload) ? true : false, 'S_UPLOAD_AVATAR_URL' => ($config['allow_avatar'] && $config['allow_avatar_remote_upload'] && $can_upload) ? true : false,
'S_LINK_AVATAR' => ($config['allow_avatar'] && $config['allow_avatar_remote']) ? true : false, 'S_LINK_AVATAR' => ($config['allow_avatar'] && $config['allow_avatar_remote']) ? true : false,
'S_DISPLAY_GALLERY' => ($config['allow_avatar'] && $config['allow_avatar_local']) ? true : false,
'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '', 'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '',
'GROUP_RECEIVE_PM' => (isset($group_row['group_receive_pm']) && $group_row['group_receive_pm']) ? ' checked="checked"' : '', 'GROUP_RECEIVE_PM' => (isset($group_row['group_receive_pm']) && $group_row['group_receive_pm']) ? ' checked="checked"' : '',

View file

@ -669,22 +669,7 @@ function compose_pm($id, $mode, $action)
} }
// Parse Attachments - before checksum is calculated // Parse Attachments - before checksum is calculated
if ($action == 'edit') $message_parser->parse_attachments('fileupload', $action, 0, $submit, $preview, $refresh, true);
{
$message_parser->parse_attachments('fileupload', $action, 0, $submit, $preview, $refresh, true, $msg_id);
if (sizeof($message_parser->attachment_data))
{
// Update attachment indicators for pms having attachments now, as a precaution if the pm does not get stored by submit
$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
SET message_attachment = 1
WHERE msg_id = ' . $msg_id;
$db->sql_query($sql);
}
}
else
{
$message_parser->parse_attachments('fileupload', $action, 0, $submit, $preview, $refresh, true);
}
if (sizeof($message_parser->warn_msg) && !($remove_u || $remove_g || $add_to || $add_bcc)) if (sizeof($message_parser->warn_msg) && !($remove_u || $remove_g || $add_to || $add_bcc))
{ {

View file

@ -31,8 +31,8 @@ unset($dbpasswd);
*/ */
$convertor_data = array( $convertor_data = array(
'forum_name' => 'phpBB 2.0.x', 'forum_name' => 'phpBB 2.0.x',
'version' => '1.0.2', 'version' => '1.0.3',
'phpbb_version' => '3.0.4', 'phpbb_version' => '3.0.6',
'author' => '<a href="http://www.phpbb.com/">phpBB Group</a>', 'author' => '<a href="http://www.phpbb.com/">phpBB Group</a>',
'dbms' => $dbms, 'dbms' => $dbms,
'dbhost' => $dbhost, 'dbhost' => $dbhost,
@ -129,7 +129,7 @@ $config_schema = array(
'board_timezone' => 'board_timezone', 'board_timezone' => 'board_timezone',
'allow_privmsg' => 'not(privmsg_disable)', 'allow_privmsg' => 'not(privmsg_disable)',
'gzip_compress' => 'gzip_compress', 'gzip_compress' => 'gzip_compress',
'coppa_enable' => 'is_empty(coppa_mail)', 'coppa_enable' => '!is_empty(coppa_mail)',
'coppa_fax' => 'coppa_fax', 'coppa_fax' => 'coppa_fax',
'coppa_mail' => 'coppa_mail', 'coppa_mail' => 'coppa_mail',
'record_online_users' => 'record_online_users', 'record_online_users' => 'record_online_users',

View file

@ -8,7 +8,7 @@
* *
*/ */
$updates_to_version = '3.0.6-RC1'; $updates_to_version = '3.0.6-RC2';
// Enter any version to update from to test updates. The version within the db will not be updated. // Enter any version to update from to test updates. The version within the db will not be updated.
$debug_from_version = false; $debug_from_version = false;
@ -868,9 +868,6 @@ function database_update_info()
), ),
), ),
'add_index' => array( 'add_index' => array(
LOG_TABLE => array(
'log_time' => array('log_time'),
),
REPORTS_TABLE => array( REPORTS_TABLE => array(
'post_id' => array('post_id'), 'post_id' => array('post_id'),
'pm_id' => array('pm_id'), 'pm_id' => array('pm_id'),
@ -880,6 +877,12 @@ function database_update_info()
), ),
), ),
), ),
// Changes from 3.0.6-RC1 to 3.0.6-RC2
'3.0.6-RC1' => array(
'drop_keys' => array(
LOG_TABLE => array('log_time'),
),
),
); );
} }
@ -1506,6 +1509,10 @@ function change_database_data(&$no_updates, $version)
$no_updates = false; $no_updates = false;
break; break;
// No changes from 3.0.6-RC1 to 3.0.6-RC2
case '3.0.6-RC1':
break;
} }
} }
@ -1902,7 +1909,8 @@ class updater_db_tools
{ {
if ($column_exists) if ($column_exists)
{ {
$sqlite_data[$table]['change_columns'][] = $result; continue;
// $sqlite_data[$table]['change_columns'][] = $result;
} }
else else
{ {
@ -1924,6 +1932,11 @@ class updater_db_tools
{ {
foreach ($indexes as $index_name) foreach ($indexes as $index_name)
{ {
if (!$this->sql_index_exists($table, $index_name))
{
continue;
}
$result = $this->sql_index_drop($table, $index_name); $result = $this->sql_index_drop($table, $index_name);
if ($this->return_statements) if ($this->return_statements)
@ -1984,6 +1997,11 @@ class updater_db_tools
{ {
foreach ($index_array as $index_name => $column) foreach ($index_array as $index_name => $column)
{ {
if ($this->sql_unique_index_exists($table, $index_name))
{
continue;
}
$result = $this->sql_create_unique_index($table, $index_name, $column); $result = $this->sql_create_unique_index($table, $index_name, $column);
if ($this->return_statements) if ($this->return_statements)
@ -2001,6 +2019,11 @@ class updater_db_tools
{ {
foreach ($index_array as $index_name => $column) foreach ($index_array as $index_name => $column)
{ {
if ($this->sql_index_exists($table, $index_name))
{
continue;
}
$result = $this->sql_create_index($table, $index_name, $column); $result = $this->sql_create_index($table, $index_name, $column);
if ($this->return_statements) if ($this->return_statements)
@ -2308,6 +2331,229 @@ class updater_db_tools
} }
} }
/**
* Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes.
*
* @param string $table_name Table to check the index at
* @param string $index_name The index name to check
*
* @return bool True if index exists, else false
*/
function sql_index_exists($table_name, $index_name)
{
if ($this->sql_layer == 'mssql')
{
$sql = "EXEC sp_statistics '$table_name'";
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
if ($row['TYPE'] == 3)
{
if (strtolower($row['INDEX_NAME']) == strtolower($index_name))
{
$this->db->sql_freeresult($result);
return true;
}
}
}
$this->db->sql_freeresult($result);
return false;
}
switch ($this->sql_layer)
{
case 'firebird':
$sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
FROM RDB\$INDICES
WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "'
AND RDB\$UNIQUE_FLAG IS NULL
AND RDB\$FOREIGN_KEY IS NULL";
$col = 'index_name';
break;
case 'postgres':
$sql = "SELECT ic.relname as index_name
FROM pg_class bc, pg_class ic, pg_index i
WHERE (bc.oid = i.indrelid)
AND (ic.oid = i.indexrelid)
AND (bc.relname = '" . $table_name . "')
AND (i.indisunique != 't')
AND (i.indisprimary != 't')";
$col = 'index_name';
break;
case 'mysql_40':
case 'mysql_41':
$sql = 'SHOW KEYS
FROM ' . $table_name;
$col = 'Key_name';
break;
case 'oracle':
$sql = "SELECT index_name
FROM user_indexes
WHERE table_name = '" . strtoupper($table_name) . "'
AND generated = 'N'
AND uniqueness = 'NONUNIQUE'";
$col = 'index_name';
break;
case 'sqlite':
$sql = "PRAGMA index_list('" . $table_name . "');";
$col = 'name';
break;
}
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique'])
{
continue;
}
// These DBMS prefix index name with the table name
switch ($this->sql_layer)
{
case 'firebird':
case 'oracle':
case 'postgres':
case 'sqlite':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
if (strtolower($row[$col]) == strtolower($index_name))
{
$this->db->sql_freeresult($result);
return true;
}
}
$this->db->sql_freeresult($result);
return false;
}
/**
* Check if a specified UNIQUE index exists in table.
*
* @param string $table_name Table to check the index at
* @param string $index_name The index name to check
*
* @return bool True if index exists, else false
*/
function sql_unique_index_exists($table_name, $index_name)
{
if ($this->sql_layer == 'mssql')
{
$sql = "EXEC sp_statistics '$table_name'";
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
// Usually NON_UNIQUE is the column we want to check, but we allow for both
if ($row['TYPE'] == 3)
{
if (strtolower($row['INDEX_NAME']) == strtolower($index_name))
{
$this->db->sql_freeresult($result);
return true;
}
}
}
$this->db->sql_freeresult($result);
return false;
}
switch ($this->sql_layer)
{
case 'firebird':
$sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
FROM RDB\$INDICES
WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "'
AND RDB\$UNIQUE_FLAG IS NOT NULL
AND RDB\$FOREIGN_KEY IS NULL";
$col = 'index_name';
break;
case 'postgres':
$sql = "SELECT ic.relname as index_name, i.indisunique
FROM pg_class bc, pg_class ic, pg_index i
WHERE (bc.oid = i.indrelid)
AND (ic.oid = i.indexrelid)
AND (bc.relname = '" . $table_name . "')
AND (i.indisprimary != 't')";
$col = 'index_name';
break;
case 'mysql_40':
case 'mysql_41':
$sql = 'SHOW KEYS
FROM ' . $table_name;
$col = 'Key_name';
break;
case 'oracle':
$sql = "SELECT index_name, table_owner
FROM user_indexes
WHERE table_name = '" . strtoupper($table_name) . "'
AND generated = 'N'
AND uniqueness = 'UNIQUE'
AND index_name LIKE 'U_%'";
$col = 'index_name';
break;
case 'sqlite':
$sql = "PRAGMA index_list('" . $table_name . "') WHERE unique = 1;";
$col = 'name';
break;
}
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && ($row['Non_unique'] || $row[$col] == 'PRIMARY'))
{
continue;
}
if ($this->sql_layer == 'sqlite' && !$row['unique'])
{
continue;
}
if ($this->sql_layer == 'postgres' && $row['indisunique'] != 't')
{
continue;
}
// These DBMS prefix index name with the table name
switch ($this->sql_layer)
{
case 'oracle':
$row[$col] = substr($row[$col], strlen('U_' . $row['table_owner']) + 1);
break;
case 'firebird':
case 'postgres':
case 'sqlite':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
if (strtolower($row[$col]) == strtolower($index_name))
{
$this->db->sql_freeresult($result);
return true;
}
}
$this->db->sql_freeresult($result);
return false;
}
/** /**
* Private method for performing sql statements (either execute them or return them) * Private method for performing sql statements (either execute them or return them)
* @access private * @access private
@ -2441,11 +2687,13 @@ class updater_db_tools
// For hexadecimal values do not use single quotes // For hexadecimal values do not use single quotes
if (strpos($column_data[1], '0x') === 0) if (strpos($column_data[1], '0x') === 0)
{ {
$sql_default .= 'DEFAULT (' . $column_data[1] . ') '; $return_array['default'] = 'DEFAULT (' . $column_data[1] . ') ';
$sql_default .= $return_array['default'];
} }
else else
{ {
$sql_default .= 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; $return_array['default'] = 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') ';
$sql_default .= $return_array['default'];
} }
} }
@ -2965,6 +3213,27 @@ class updater_db_tools
case 'mssql': case 'mssql':
$statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql'];
if (!empty($column_data['default']))
{
// Using TRANSACT-SQL for this statement because we do not want to have colliding data if statements are executed at a later stage
$statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000)
SET @drop_default_name =
(SELECT so.name FROM sysobjects so
JOIN sysconstraints sc ON so.id = sc.constid
WHERE object_name(so.parent_obj) = '{$table_name}'
AND so.xtype = 'D'
AND sc.colid = (SELECT colid FROM syscolumns
WHERE id = object_id('{$table_name}')
AND name = '{$column_name}'))
IF @drop_default_name <> ''
BEGIN
SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']'
EXEC(@cmd)
END
SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]'
EXEC(@cmd)";
}
break; break;
case 'mysql_40': case 'mysql_40':

View file

@ -687,7 +687,7 @@ class install_update extends module
default: default:
$diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename);
$contents = implode("\n", $diff->merged_new_output()); $contents = implode("\n", $diff->merged_output());
unset($diff); unset($diff);
break; break;
} }
@ -1104,24 +1104,6 @@ class install_update extends module
break; break;
/*
$diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $file, $this->new_location . $original_file);
$tmp = array(
'file1' => array(),
'file2' => ($option == MERGE_NEW_FILE) ? implode("\n", $diff->merged_new_output()) : implode("\n", $diff->merged_orig_output()),
);
$diff = new diff($tmp['file1'], $tmp['file2']);
unset($tmp);
$template->assign_var('S_DIFF_NEW_FILE', true);
$diff_mode = 'inline';
$this->page_title = 'VIEWING_FILE_CONTENTS';
break;
*/
// Merge differences and use new phpBB code for conflicted blocks // Merge differences and use new phpBB code for conflicted blocks
case MERGE_NEW_FILE: case MERGE_NEW_FILE:
case MERGE_MOD_FILE: case MERGE_MOD_FILE:
@ -1175,6 +1157,7 @@ class install_update extends module
default: default:
$diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $original_file, $this->new_location . $file); $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $original_file, $this->new_location . $file);
$diff = $this->return_diff($phpbb_root_path . $file, $diff->merged_output());
break; break;
} }
break; break;
@ -1362,6 +1345,9 @@ class install_update extends module
$update_ary['original'] = $original_file; $update_ary['original'] = $original_file;
} }
// we only want to know if the files are successfully merged and newlines could result in errors (duplicate addition of lines and such things)
// Therefore we check for empty diffs with two methods, preserving newlines and not preserving them (which mostly works best, therefore the first option)
// On a successfull update the new location file exists but the old one does not exist. // On a successfull update the new location file exists but the old one does not exist.
// Check for this circumstance, the new file need to be up-to-date with the current file then... // Check for this circumstance, the new file need to be up-to-date with the current file then...
if (!file_exists($this->old_location . $original_file) && file_exists($this->new_location . $original_file) && file_exists($phpbb_root_path . $file)) if (!file_exists($this->old_location . $original_file) && file_exists($this->new_location . $original_file) && file_exists($phpbb_root_path . $file))
@ -1401,104 +1387,141 @@ class install_update extends module
trigger_error($user->lang['INCOMPLETE_UPDATE_FILES'], E_USER_ERROR); trigger_error($user->lang['INCOMPLETE_UPDATE_FILES'], E_USER_ERROR);
} }
$tmp = array( $preserve_cr_ary = array(false, true);
'file1' => file_get_contents($this->old_location . $original_file),
'file2' => file_get_contents($phpbb_root_path . $file),
);
// We need to diff the contents here to make sure the file is really the one we expect foreach ($preserve_cr_ary as $preserve_cr)
$diff = new diff($tmp['file1'], $tmp['file2'], false);
$empty_1 = $diff->is_empty();
unset($tmp, $diff);
$tmp = array(
'file1' => file_get_contents($this->new_location . $original_file),
'file2' => file_get_contents($phpbb_root_path . $file),
);
// We need to diff the contents here to make sure the file is really the one we expect
$diff = new diff($tmp['file1'], $tmp['file2'], false);
$empty_2 = $diff->is_empty();
unset($tmp, $diff);
// If the file is not modified we are finished here...
if ($empty_1)
{ {
// Further check if it is already up to date - it could happen that non-modified files $tmp = array(
// slip through 'file1' => file_get_contents($this->old_location . $original_file),
'file2' => file_get_contents($phpbb_root_path . $file),
);
// We need to diff the contents here to make sure the file is really the one we expect
$diff = new diff($tmp['file1'], $tmp['file2'], $preserve_cr);
$empty_1 = $diff->is_empty();
unset($tmp, $diff);
$tmp = array(
'file1' => file_get_contents($this->new_location . $original_file),
'file2' => file_get_contents($phpbb_root_path . $file),
);
$diff = new diff($tmp['file1'], $tmp['file2'], $preserve_cr);
$empty_2 = $diff->is_empty();
unset($tmp, $diff);
// If the file is not modified we are finished here...
if ($empty_1)
{
// Further check if it is already up to date - it could happen that non-modified files
// slip through
if ($empty_2)
{
$update_list['up_to_date'][] = $update_ary;
return;
}
$update_list['not_modified'][] = $update_ary;
return;
}
// If the file had been modified then we need to check if it is already up to date
// if there are no differences we have an up-to-date file...
if ($empty_2) if ($empty_2)
{ {
$update_list['up_to_date'][] = $update_ary; $update_list['up_to_date'][] = $update_ary;
return; return;
} }
$update_list['not_modified'][] = $update_ary;
return;
} }
// If the file had been modified then we need to check if it is already up to date $conflicts = false;
// if there are no differences we have an up-to-date file... foreach ($preserve_cr_ary as $preserve_cr)
if ($empty_2)
{ {
$update_list['up_to_date'][] = $update_ary; // if the file is modified we try to make sure a merge succeed
return;
}
// if the file is modified we try to make sure a merge succeed
$tmp = array(
'file1' => file_get_contents($this->old_location . $original_file),
'file2' => file_get_contents($phpbb_root_path . $file),
'file3' => file_get_contents($this->new_location . $original_file),
);
$diff = new diff3($tmp['file1'], $tmp['file2'], $tmp['file3'], false);
unset($tmp);
if ($diff->get_num_conflicts())
{
$update_ary['conflicts'] = $diff->get_num_conflicts();
// There is one special case... users having merged with a conflicting file... we need to check this
$tmp = array( $tmp = array(
'file1' => file_get_contents($phpbb_root_path . $file), 'orig' => file_get_contents($this->old_location . $original_file),
'file2' => implode("\n", $diff->merged_orig_output()), 'final1' => file_get_contents($phpbb_root_path . $file),
'final2' => file_get_contents($this->new_location . $original_file),
); );
$diff = new diff($tmp['file1'], $tmp['file2'], false); $diff = new diff3($tmp['orig'], $tmp['final1'], $tmp['final2'], $preserve_cr);
$empty = $diff->is_empty(); unset($tmp);
if ($empty) if (!$diff->get_num_conflicts())
{ {
unset($update_ary['conflicts']); $tmp = array(
unset($diff); 'file1' => file_get_contents($phpbb_root_path . $file),
$update_list['up_to_date'][] = $update_ary; 'file2' => implode("\n", $diff->merged_output()),
return; );
// now compare the merged output with the original file to see if the modified file is up to date
$diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr);
$empty = $diff2->is_empty();
unset($diff, $diff2);
if ($empty)
{
$update_list['up_to_date'][] = $update_ary;
return;
}
// If we preserve cr tag it as modified because the conflict would not show in this mode anyway
if ($preserve_cr)
{
$update_list['modified'][] = $update_ary;
return;
}
} }
else
{
// There is one special case... users having merged with a conflicting file... we need to check this
$tmp = array(
'file1' => file_get_contents($phpbb_root_path . $file),
'file2' => implode("\n", $diff->merged_new_output()),
);
$update_list['conflict'][] = $update_ary; $diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr);
unset($diff); $empty = $diff2->is_empty();
return; if (!$empty)
{
unset($tmp, $diff2);
// We check if the user merged with his output
$tmp = array(
'file1' => file_get_contents($phpbb_root_path . $file),
'file2' => implode("\n", $diff->merged_orig_output()),
);
$diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr);
$empty = $diff2->is_empty();
}
if (!$empty)
{
$conflicts = $diff->get_num_conflicts();
}
unset($diff, $diff2);
if ($empty)
{
// A conflict got resolved...
$update_list['up_to_date'][] = $update_ary;
return;
}
}
} }
$tmp = array( if ($conflicts !== false)
'file1' => file_get_contents($phpbb_root_path . $file),
'file2' => implode("\n", $diff->merged_new_output()),
);
// now compare the merged output with the original file to see if the modified file is up to date
$diff = new diff($tmp['file1'], $tmp['file2'], false);
$empty = $diff->is_empty();
if ($empty)
{ {
unset($diff); $update_ary['conflicts'] = $conflicts;
$update_list['conflict'][] = $update_ary;
$update_list['up_to_date'][] = $update_ary;
return; return;
} }
@ -1650,7 +1673,7 @@ class install_update extends module
/** /**
* Wrapper for returning a diff object * Wrapper for returning a diff object
*/ */
function &return_diff() function return_diff()
{ {
$args = func_get_args(); $args = func_get_args();
$three_way_diff = (func_num_args() > 2) ? true : false; $three_way_diff = (func_num_args() > 2) ? true : false;

View file

@ -239,7 +239,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('topics_per_page',
INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.0.6-RC1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.0.6-RC2');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400');

View file

@ -451,8 +451,8 @@ $lang = array_merge($lang, array(
'MERGE_NO_MERGE_NEW_OPTION' => 'Do not merge - use new file', 'MERGE_NO_MERGE_NEW_OPTION' => 'Do not merge - use new file',
'MERGE_NO_MERGE_MOD_OPTION' => 'Do not merge - use currently installed file', 'MERGE_NO_MERGE_MOD_OPTION' => 'Do not merge - use currently installed file',
'MERGE_MOD_FILE_OPTION' => 'Merge modifications (Loose new phpBB code within conflicting block)', 'MERGE_MOD_FILE_OPTION' => 'Merge modifications (removes new phpBB code within conflicting block)',
'MERGE_NEW_FILE_OPTION' => 'Merge modifications (Loose modified code within conflicting block)', 'MERGE_NEW_FILE_OPTION' => 'Merge modifications (removes modified code within conflicting block)',
'MERGE_SELECT_ERROR' => 'Conflicting file merge modes are not correctly selected.', 'MERGE_SELECT_ERROR' => 'Conflicting file merge modes are not correctly selected.',
'MERGING_FILES' => 'Merging differences', 'MERGING_FILES' => 'Merging differences',
'MERGING_FILES_EXPLAIN' => 'Currently collecting final file changes.<br /><br />Please wait until phpBB has completed all operations on changed files.', 'MERGING_FILES_EXPLAIN' => 'Currently collecting final file changes.<br /><br />Please wait until phpBB has completed all operations on changed files.',

View file

@ -742,28 +742,7 @@ if ($submit || $preview || $refresh)
} }
// Parse Attachments - before checksum is calculated // Parse Attachments - before checksum is calculated
if ($mode == 'edit') $message_parser->parse_attachments('fileupload', $mode, $forum_id, $submit, $preview, $refresh);
{
$message_parser->parse_attachments('fileupload', $mode, $forum_id, $submit, $preview, $refresh, false, $post_id, $topic_id);
if (sizeof($message_parser->attachment_data))
{
// Update attachment indicators for post/topic having attachments now, as a precaution if the post does not get stored by submit
$sql = 'UPDATE ' . POSTS_TABLE . '
SET post_attachment = 1
WHERE post_id = ' . $post_id;
$db->sql_query($sql);
$sql = 'UPDATE ' . TOPICS_TABLE . '
SET topic_attachment = 1
WHERE topic_id = ' . $topic_id;
$db->sql_query($sql);
}
}
else
{
$message_parser->parse_attachments('fileupload', $mode, $forum_id, $submit, $preview, $refresh);
}
// Grab md5 'checksum' of new message // Grab md5 'checksum' of new message
$message_md5 = md5($message_parser->message); $message_md5 = md5($message_parser->message);
@ -1121,13 +1100,13 @@ if ($submit || $preview || $refresh)
// The last parameter tells submit_post if search indexer has to be run // The last parameter tells submit_post if search indexer has to be run
$redirect_url = submit_post($mode, $post_data['post_subject'], $post_data['username'], $post_data['topic_type'], $poll, $data, $update_message, ($update_message || $update_subject) ? true : false); $redirect_url = submit_post($mode, $post_data['post_subject'], $post_data['username'], $post_data['topic_type'], $poll, $data, $update_message, ($update_message || $update_subject) ? true : false);
if ($config['enable_post_confirm'] && !$user->data['is_registered'] && (isset($captcha) && $captcha->is_solved() === true) && ($mode == 'post' || $mode == 'reply' || $mode == 'quote')) if ($config['enable_post_confirm'] && !$user->data['is_registered'] && (isset($captcha) && $captcha->is_solved() === true) && ($mode == 'post' || $mode == 'reply' || $mode == 'quote'))
{ {
$captcha->reset(); $captcha->reset();
} }
// Check the permissions for post approval. Moderators are not affected. // Check the permissions for post approval. Moderators are not affected.
if (!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) if ((!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id'])) || !empty($post_data['force_approved_state']))
{ {
meta_refresh(10, $redirect_url); meta_refresh(10, $redirect_url);
$message = ($mode == 'edit') ? $user->lang['POST_EDITED_MOD'] : $user->lang['POST_STORED_MOD']; $message = ($mode == 'edit') ? $user->lang['POST_EDITED_MOD'] : $user->lang['POST_STORED_MOD'];
@ -1569,17 +1548,18 @@ function handle_post_delete($forum_id, $topic_id, $post_id, &$post_data)
); );
$next_post_id = delete_post($forum_id, $topic_id, $post_id, $data); $next_post_id = delete_post($forum_id, $topic_id, $post_id, $data);
$post_username = ($post_data['poster_id'] == ANONYMOUS && !empty($post_data['post_username'])) ? $post_data['post_username'] : $post_data['username'];
if ($next_post_id === false) if ($next_post_id === false)
{ {
add_log('mod', $forum_id, $topic_id, 'LOG_DELETE_TOPIC', $post_data['topic_title'], $post_data['username']); add_log('mod', $forum_id, $topic_id, 'LOG_DELETE_TOPIC', $post_data['topic_title'], $post_username);
$meta_info = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id"); $meta_info = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id");
$message = $user->lang['POST_DELETED']; $message = $user->lang['POST_DELETED'];
} }
else else
{ {
add_log('mod', $forum_id, $topic_id, 'LOG_DELETE_POST', $post_data['post_subject'], $post_data['username']); add_log('mod', $forum_id, $topic_id, 'LOG_DELETE_POST', $post_data['post_subject'], $post_username);
$meta_info = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;p=$next_post_id") . "#p$next_post_id"; $meta_info = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;p=$next_post_id") . "#p$next_post_id";
$message = $user->lang['POST_DELETED'] . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $meta_info . '">', '</a>'); $message = $user->lang['POST_DELETED'] . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $meta_info . '">', '</a>');

View file

@ -118,7 +118,8 @@ else
if (!$report_data) if (!$report_data)
{ {
trigger_error('PM_NOT_EXIST'); $user->add_lang('ucp');
trigger_error('NO_MESSAGE');
} }
if ($report_data['message_reported']) if ($report_data['message_reported'])

View file

@ -27,7 +27,7 @@
<li class="row"> <li class="row">
<dl class="icon" style="background-image: url({forumrow.FORUM_FOLDER_IMG_SRC}); background-repeat: no-repeat;"> <dl class="icon" style="background-image: url({forumrow.FORUM_FOLDER_IMG_SRC}); background-repeat: no-repeat;">
<dt title="{forumrow.FORUM_FOLDER_IMG_ALT}"> <dt title="{forumrow.FORUM_FOLDER_IMG_ALT}">
<!-- IF S_ENABLE_FEEDS and forumrow.S_FEED_ENABLED --><!-- <a class="feed-icon-forum" title="{L_FEED} - {forumrow.FORUM_NAME}" href="{U_FEED}?f={forumrow.FORUM_ID}"><img src="{T_THEME_PATH}/images/feed.gif" title="{L_FEED} - {forumrow.FORUM_NAME}" /></a> --><!-- ENDIF --> <!-- IF S_ENABLE_FEEDS and forumrow.S_FEED_ENABLED --><!-- <a class="feed-icon-forum" title="{L_FEED} - {forumrow.FORUM_NAME}" href="{U_FEED}?f={forumrow.FORUM_ID}"><img src="{T_THEME_PATH}/images/feed.gif" alt="{L_FEED} - {forumrow.FORUM_NAME}" /></a> --><!-- ENDIF -->
<!-- IF forumrow.FORUM_IMAGE --><span class="forum-image">{forumrow.FORUM_IMAGE}</span><!-- ENDIF --> <!-- IF forumrow.FORUM_IMAGE --><span class="forum-image">{forumrow.FORUM_IMAGE}</span><!-- ENDIF -->
<a href="{forumrow.U_VIEWFORUM}" class="forumtitle">{forumrow.FORUM_NAME}</a><br /> <a href="{forumrow.U_VIEWFORUM}" class="forumtitle">{forumrow.FORUM_NAME}</a><br />

View file

@ -1678,7 +1678,8 @@ else if (!$all_marked_read)
} }
// let's set up quick_reply // let's set up quick_reply
$s_quick_reply = $user->data['is_registered'] && $config['allow_quick_reply'] && ($topic_data['forum_flags'] & FORUM_FLAG_QUICK_REPLY) && $auth->acl_get('f_reply', $forum_id); $s_allowed_reply = ((!$auth->acl_get('f_reply', $forum_id) || ($topic_data['forum_status'] == ITEM_LOCKED) || ($topic_data['topic_status'] == ITEM_LOCKED)) && !$auth->acl_get('m_edit', $forum_id)) ? false : true;
$s_quick_reply = $s_allowed_reply && $user->data['is_registered'] && $config['allow_quick_reply'] && ($topic_data['forum_flags'] & FORUM_FLAG_QUICK_REPLY);
if ($s_can_vote || $s_quick_reply) if ($s_can_vote || $s_quick_reply)
{ {
@ -1704,6 +1705,7 @@ if ($s_can_vote || $s_quick_reply)
(!$config['allow_post_links']) ? $qr_hidden_fields['disable_magic_url'] = 1 : true; (!$config['allow_post_links']) ? $qr_hidden_fields['disable_magic_url'] = 1 : true;
($s_attach_sig) ? $qr_hidden_fields['attach_sig'] = 1 : true; ($s_attach_sig) ? $qr_hidden_fields['attach_sig'] = 1 : true;
($s_notify) ? $qr_hidden_fields['notify'] = 1 : true; ($s_notify) ? $qr_hidden_fields['notify'] = 1 : true;
($topic_data['topic_status'] == ITEM_LOCKED) ? $qr_hidden_fields['lock_topic'] = 1 : true;
$template->assign_vars(array( $template->assign_vars(array(
'S_QUICK_REPLY' => true, 'S_QUICK_REPLY' => true,