1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-04-14 04:42:04 +02:00

Merge remote-tracking branch 'upstream/develop-ascraeus' into ticket/12594

Conflicts:
	phpBB/docs/hook_system.html
This commit is contained in:
Yuriy Rusko 2014-05-27 21:55:40 +02:00
commit 1d61bcedfd
39 changed files with 507 additions and 2465 deletions

View File

@ -1,14 +1,30 @@
language: php
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
env:
- DB=mysqli
matrix:
include:
- php: 5.3.3
env: DB=mysqli
- php: 5.3
env: DB=mysqli # MyISAM
- php: 5.4
env: DB=mysqli
- php: 5.4
env: DB=mysql
- php: 5.4
env: DB=mariadb
- php: 5.4
env: DB=postgres
- php: 5.4
env: DB=sqlite3
- php: 5.5
env: DB=mysqli
- php: 5.6
env: DB=mysqli
- php: hhvm
env: DB=mysql
allow_failures:
- php: hhvm
fast_finish: true
services:
- redis-server
@ -24,16 +40,3 @@ script:
- phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml
- sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.5' -a '$DB' = 'mysqli' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..FETCH_HEAD; fi"
matrix:
include:
- php: 5.4
env: DB=mysql
- php: 5.4
env: DB=mariadb
- php: 5.4
env: DB=postgres
- php: 5.4
env: DB=sqlite3
allow_failures:
- php: hhvm
fast_finish: true

View File

@ -2,29 +2,7 @@
<a id="maincontent"></a>
<!-- IF S_SELECT_METHOD -->
<a href="{U_BACK}" style="float: {S_CONTENT_FLOW_END};">&laquo; {L_BACK}</a>
<h1>{L_SELECT_DOWNLOAD_FORMAT}</h1>
<form id="selectmethod" method="post" action="{U_ACTION}">
<fieldset>
<legend>{L_DOWNLOAD_AS}</legend>
<dl>
<dt><label for="use_method">{L_DOWNLOAD_AS}{L_COLON}</label></dt>
<dd>{RADIO_BUTTONS}</dd>
</dl>
<p class="quick">
<input type="submit" class="button2" value="{L_DOWNLOAD}" name="download" />
</p>
</fieldset>
</form>
<!-- ELSEIF S_DETAILS -->
<!-- IF S_DETAILS -->
<a href="{U_BACK}" style="float: {S_CONTENT_FLOW_END};">&laquo; {L_BACK}</a>
@ -58,153 +36,32 @@
</fieldset>
</form>
<br /><br />
<!-- IF .missing_files -->
<h3 class="error">{L_MISSING_FILES}</h3>
<!-- IF S_MISSING_FILES -->
<div class="errorbox">
<h3>{L_MISSING_FILES}</h3>
<p>{MISSING_FILES}</p>
</div>
<br /><br />
<!-- ENDIF -->
<!-- IF S_MISSING_VARS -->
<h1>{L_MISSING_LANG_VARIABLES}</h1>
<p>{L_MISSING_VARS_EXPLAIN}</p>
<form id="missing" method="post" action="{U_MISSING_ACTION}">
<table class="table1">
<thead>
<tr>
<th>{L_LANGUAGE_KEY}</th>
<th>{L_LANGUAGE_VARIABLE}</th>
</tr>
</thead>
<tbody>
<!-- BEGIN missing -->
<tr class="row4">
<td><strong>{missing.FILE}</strong></td>
<td style="text-align: right;"><input type="submit" name="missing_file[{missing.KEY}]" value="{L_SELECT}" class="button2" /></td>
</tr>
{missing.TPL}
<!-- END missing -->
</tbody>
</table>
<div>{S_FORM_TOKEN}</div>
</form>
<br /><br />
<!-- ENDIF -->
<a id="entries"></a>
<h1>{L_LANGUAGE_ENTRIES}</h1>
<p>{L_LANGUAGE_ENTRIES_EXPLAIN}</p>
<form id="lang_entries" method="post" action="{U_ENTRY_ACTION}">
<!-- IF S_FROM_STORE -->
<fieldset class="quick" style="float: {S_CONTENT_FLOW_BEGIN};">
<input type="submit" name="remove_store" value="{L_REMOVE_FROM_STORAGE_FOLDER}" class="button2" />
<fieldset>
<legend>{L_MISSING_LANG_FILES}</legend>
<!-- BEGIN missing_files -->
&raquo; {missing_files.FILE_NAME}<br />
<!-- END missing_files -->
</fieldset>
<!-- ENDIF -->
<fieldset class="quick" style="float: {S_CONTENT_FLOW_END};">
<select name="language_file">{S_LANG_OPTIONS}</select>&nbsp;<input type="submit" class="button2" name="change" value="{L_SELECT}" />
</fieldset>
<!-- IF .missing_varfile -->
<h3 class="error">{L_MISSING_VARS_EXPLAIN}</h3>
<p>&nbsp;<br />&nbsp;</p>
<!--[if lt IE 8]>
<style type="text/css">
/* <![CDATA[ */
input.langvalue, textarea.langvalue {
width: 450px;
}
/* ]]> */
</style>
<![endif]-->
<table class="table1">
<thead>
<!-- IF S_EMAIL_FILE -->
<tr>
<th colspan="2">{L_FILE_CONTENTS}</th>
</tr>
<!-- ELSE -->
<tr>
<th>{L_LANGUAGE_KEY}</th>
<th>{L_LANGUAGE_VARIABLE}</th>
</tr>
<fieldset>
<legend>{L_MISSING_LANG_VARIABLES}</legend>
<!-- BEGIN missing_varfile -->
<dl>
<dt><label>{missing_varfile.FILE_NAME}</label></dt>
<!-- BEGIN variable -->
<dd>{missing_varfile.variable.VAR_NAME}</dd>
<!-- END variable -->
</dl>
<!-- END missing_varfile -->
</fieldset>
<!-- ENDIF -->
<tr>
<td rowspan="2" class="row3"><strong>{PRINT_MESSAGE}<!-- IF S_FROM_STORE --><br /><span style="color: red;">{L_FILE_FROM_STORAGE}</span><!-- ENDIF --></strong></td>
<td class="row3" style="text-align: right;"><input type="submit" name="download_file" class="button2" value="{L_SUBMIT_AND_DOWNLOAD}" />&nbsp;&nbsp;<input type="submit" name="submit_file" class="button2" value="{L_SUBMIT}" /></td>
</tr>
<tr>
<td class="row3" style="text-align: right;">
<!-- IF ALLOW_UPLOAD -->&nbsp;&nbsp;{L_UPLOAD_METHOD}{L_COLON}&nbsp;<!-- BEGIN buttons --><input type="radio" class="radio"<!-- IF buttons.S_FIRST_ROW --> id="method" checked="checked"<!-- ENDIF --> value="{buttons.VALUE}" name="method" />&nbsp;{buttons.VALUE}&nbsp;<!-- END buttons --><input type="submit" name="upload_file" class="button2" value="{L_SUBMIT_AND_UPLOAD}" /><!-- ENDIF --></td>
</tr>
</thead>
<tbody>
<!-- IF S_EMAIL_FILE -->
<tr>
<td class="row2" colspan="2" style="text-align: center;"><textarea name="entry" id="entry" cols="80" rows="20">{LANG}</textarea></td>
</tr>
<!-- ELSE -->
{TPL}
<!-- ENDIF -->
<tr>
<td class="row3" colspan="3" style="text-align: right;">{S_FORM_TOKEN}<input type="submit" name="download_file" class="button2" value="{L_SUBMIT_AND_DOWNLOAD}" />&nbsp;&nbsp;<input type="submit" name="submit_file" class="button2" value="{L_SUBMIT}" /></td>
</tr>
</tbody>
</table>
</form>
<!-- ELSEIF S_UPLOAD -->
<a href="{U_BACK}" style="float: {S_CONTENT_FLOW_END};">&laquo; {L_BACK}</a>
<h1>{L_UPLOAD_SETTINGS}</h1>
<form id="upload" method="post" action="{U_ACTION}">
<!-- IF S_CONNECTION_SUCCESS -->
<div class="successbox">
<p>{L_CONNECTION_SUCCESS}</p>
</div>
<!-- ELSEIF S_CONNECTION_FAILED -->
<div class="errorbox">
<p>{L_CONNECTION_FAILED}</p>
</div>
<!-- ENDIF -->
<fieldset>
<legend>{L_UPLOAD_SETTINGS}</legend>
<dl>
<dt><label>{L_UPLOAD_METHOD}{L_COLON}</label></dt>
<dd><strong>{NAME}</strong></dd>
</dl>
<!-- BEGIN data -->
<dl>
<dt><label for="{data.DATA}">{data.NAME}{L_COLON}</label><br /><span>{data.EXPLAIN}</span></dt>
<dd><input type="<!-- IF data.DATA == 'password' -->password<!-- ELSE -->text<!-- ENDIF -->" id="{data.DATA}" name="{data.DATA}" value="{data.DEFAULT}" /></dd>
</dl>
<!-- END data -->
</fieldset>
<fieldset class="quick">
{HIDDEN}
{S_FORM_TOKEN}
<input class="button1" type="submit" name="update" value="{L_SUBMIT}" />
<input class="button1" type="submit" name="test_connection" value="{L_TEST_CONNECTION}" />
</fieldset>
</form>
<!-- ELSE -->
<h1>{L_ACP_LANGUAGE_PACKS}</h1>
@ -231,7 +88,7 @@
<td>{lang.LOCAL_NAME}</td>
<td style="text-align: center;"><strong>{lang.ISO}</strong></td>
<td style="text-align: center;">{lang.USED_BY}</td>
<td style="text-align: center;">&nbsp;<a href="{lang.U_DOWNLOAD}">{L_DOWNLOAD}</a>&nbsp;|&nbsp;<a href="{lang.U_DELETE}">{L_DELETE}</a></td>
<td style="text-align: center;"><a href="{lang.U_DELETE}">{L_DELETE}</a></td>
</tr>
<!-- END lang -->
<!-- IF .notinst -->

View File

@ -15,7 +15,7 @@ var dark = $('#darkenwrapper');
var loadingIndicator = $('#loading_indicator');
var phpbbAlertTimer = null;
var isTouch = (window && typeof window.ontouchstart !== 'undefined');
phpbb.isTouch = (window && typeof window.ontouchstart !== 'undefined');
/**
* Display a loading screen
@ -1011,7 +1011,7 @@ phpbb.resizeTextArea = function(items, options) {
resetCallback: function(item) { }
};
if (isTouch) return;
if (phpbb.isTouch) return;
if (arguments.length > 1) {
configuration = $.extend(configuration, options);

View File

@ -86,6 +86,7 @@ services:
class: phpbb\console\command\extension\show
arguments:
- @ext.manager
- @log
tags:
- { name: console.command }

View File

@ -1,883 +0,0 @@
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8">
<meta name="keywords" content="" />
<meta name="description" content="Hook System explanation" />
<title>phpBB3 &bull; Hook System</title>
<style type="text/css">
/* <![CDATA[ */
/*
The original "prosilver" theme for phpBB3
Created by subBlue design :: http://www.subBlue.com
*/
* { margin: 0; padding: 0; }
html { font-size: 100%; height: 100%; margin-bottom: 1px; }
body {
font-family: Verdana, Helvetica, Arial, sans-serif;
color: #828282;
background-color: #FFFFFF;
font-size: 12px;
margin: 0;
padding: 12px 0;
}
img { border-width: 0; }
p {
line-height: 1.3em;
font-size: 1.1em;
margin-bottom: 1.5em;
}
hr {
border: 0 none #FFFFFF;
border-top: 1px solid #CCCCCC;
height: 1px;
margin: 5px 0;
display: block;
clear: both;
}
html, body {
color: #536482;
background-color: #FFFFFF;
}
#doc-description h1 {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
margin-right: 200px;
color: #FFFFFF;
margin-top: 15px;
font-weight: bold;
font-size: 2em;
color: #fff;
}
h1 {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
font-weight: normal;
color: #000;
font-size: 2em;
margin: 0.8em 0 0.2em 0;
}
h2 {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
font-weight: normal;
color: #28313F;
font-size: 1.5em;
margin: 0.8em 0 0.2em 0;
}
h3 {
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
border-bottom: 1px solid #CCCCCC;
margin-bottom: 3px;
padding-bottom: 2px;
font-size: 1.05em;
color: #115098;
margin-top: 20px;
}
.good { color: green; }
.bad { color: red; }
.version {
margin-top: 20px;
text-align: left;
font-size: 70%;
color: #006600;
border-top: 1px solid #ccc;
}
code {
color: #006600;
font-weight: normal;
font-family: 'Courier New', monospace;
border-color: #D1D7DC;
border-width: 1px;
border-style: solid;
background-color: #FAFAFA;
}
#wrap {
padding: 0 20px;
min-width: 650px;
}
#simple-wrap {
padding: 6px 10px;
}
#page-body {
margin: 4px 0;
clear: both;
}
#page-footer {
clear: both;
}
#logo {
float: left;
width: auto;
padding: 10px 13px 0 10px;
}
a#logo:hover {
text-decoration: none;
}
#doc-description {
float: left;
width: 70%;
}
#doc-description h1 {
margin-right: 0;
}
.headerbar {
background: #ebebeb none repeat-x 0 0;
color: #FFFFFF;
margin-bottom: 4px;
padding: 0 5px;
}
span.corners-top, span.corners-bottom, span.corners-top span, span.corners-bottom span {
font-size: 1px;
line-height: 1px;
display: block;
height: 5px;
background-repeat: no-repeat;
}
span.corners-top {
background-image: none;
background-position: 0 0;
margin: 0 -5px;
}
span.corners-top span {
background-image: none;
background-position: 100% 0;
}
span.corners-bottom {
background-image: none;
background-position: 0 100%;
margin: 0 -5px;
clear: both;
}
span.corners-bottom span {
background-image: none;
background-position: 100% 100%;
}
.paragraph {
padding: 0 10px;
margin-bottom: 4px;
background-repeat: no-repeat;
background-position: 100% 0;
background-color: #ECF3F7;
}
.paragraph:target .content {
color: #000000;
}
.paragraph:target h3 a {
color: #000000;
}
.content {
color: #333333;
}
.content h2, .panel h2 {
color: #115098;
border-bottom-color: #CCCCCC;
}
a:link { color: #898989; text-decoration: none; }
a:visited { color: #898989; text-decoration: none; }
a:hover { color: #d3d3d3; text-decoration: underline; }
a:active { color: #d2d2d2; text-decoration: none; }
hr {
border-color: #FFFFFF;
border-top-color: #CCCCCC;
}
.menu {
background-color: #cadceb;
}
.headerbar {
background-color: #12A3EB;
background-image: url("bg_header.gif");
color: #FFFFFF;
}
.panel {
background-color: #ECF1F3;
color: #28313F;
}
span.corners-top {
background-image: url("corners_left.png");
}
span.corners-top span {
background-image: url("corners_right.png");
}
span.corners-bottom {
background-image: url("corners_left.png");
}
span.corners-bottom span {
background-image: url("corners_right.png");
}
.error {
color: #BC2A4D;
}
a:link { color: #105289; }
a:visited { color: #105289; }
a:hover { color: #D31141; }
a:active { color: #368AD2; }
.paragraph span.corners-top, .paragraph span.corners-bottom {
margin: 0 -10px;
}
.content {
padding: 0;
line-height: 1.48em;
color: #333333;
}
.content h2, .panel h2 {
color: #115098;
border-bottom-color: #CCCCCC;
}
.notice {
border-top-color: #CCCCCC;
}
.codebox {
padding: 3px;
background-color: #FFFFFF;
border: 1px solid #C9D2D8;
font-size: 1em;
margin-bottom: 10px;
display: block;
font: 0.9em Monaco, "Andale Mono","Courier New", Courier, mono;
line-height: 1.3em;
}
* html hr { margin: 0; }
* html span.corners-top, * html span.corners-bottom { background-image: url("corners_left.gif"); }
* html span.corners-top span, * html span.corners-bottom span { background-image: url("corners_right.gif"); }
.back2top {
clear: both;
height: 11px;
text-align: right;
}
.content ol {
margin-left: 25px;
}
/* ]]> */
</style>
</head>
<body id="phpbb" class="section-docs">
<div id="wrap">
<a id="top" name="top" accesskey="t"></a>
<div id="page-header">
<div class="headerbar">
<div class="inner"><span class="corners-top"><span></span></span>
<div id="doc-description">
<a href="../index.php" id="logo"><img src="site_logo.gif" alt="" /></a>
<h1>Hook System</h1>
<p>This is an explanation of how to use the phpBB3 hook system.</p>
<p style="display: none;"><a href="#start_here">Skip</a></p>
</div>
<span class="corners-bottom"><span></span></span></div>
</div>
</div>
<a name="start_here"></a>
<div id="page-body">
<h1>Hook System</h1>
<div class="paragraph menu">
<div class="inner"><span class="corners-top"><span></span></span>
<div class="content">
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#use">Allow hooks in functions/methods</a></li>
<li><a href="#register">Registering hooks</a></li>
<li><a href="#return">Result returning</a></li>
<li><a href="#embed">Embedding your hook files/classes/methods</a></li>
<li><a href="#disclaimer">Copyright and disclaimer</a></li>
</ol>
</div>
<span class="corners-bottom"><span></span></span></div>
</div>
<hr />
<a name="intro"></a><h2>1. Introduction</h2>
<div class="paragraph">
<div class="inner"><span class="corners-top"><span></span></span>
<div class="content">
<h3>What is it?</h3>
<p>The hook system allows applicaton and mod developers to hook into phpBB's or their own functions.</p>
<h3>Pre-defined hookable phpBB3 functions</h3>
<p>In phpBB3 there are four functions you are able to hook into with your custom functions:</p>
<p><code>phpbb_user_session_handler();</code> which is called within phpbb_user::setup after the session and the user object is correctly initialized.<br />
<code>append_sid($url, $params = false, $is_amp = true, $session_id = false);</code> which is called for building urls (appending the session id)<br />
<code>$template-&gt;display($handle, $template);</code> which is called directly before outputting the (not-yet-compiled) template.<br />
<code>exit_handler();</code> which is called at the very end of phpBB3's execution.</p>
<p>Please note: The <code>$template-&gt;display</code> hook takes a <code>$template</code> argument, which is the template instance being used, which should be used instead of the global.</p>
<p>There are also valid external constants you may want to use if you embed phpBB3 into your application:</p>
<div class="codebox"><pre>
PHPBB_MSG_HANDLER (overwrite message handler)
PHPBB_DB_NEW_LINK (overwrite new_link parameter for sql_connect)
PHPBB_ROOT_PATH (overwrite $phpbb_root_path)
PHPBB_ADMIN_PATH (overwrite $phpbb_admin_path)
PHPBB_USE_BOARD_URL_PATH (use generate_board_url() for image paths instead of $phpbb_root_path)
</pre></div>
<p>If the <code>PHPBB_USE_BOARD_URL_PATH</code> constant is set to true, phpBB uses generate_board_url() (this will return the boards url with the script path included) on all instances where web-accessible images are loaded. The exact locations are:</p>
<ul>
<li>/includes/user.php - phpbb_user::img()</li>
<li>/includes/functions_content.php - smiley_text()</li>
</ul>
<p>Path locations for the following template variables are affected by this too:</p>
<ul>
<li>{T_ASSETS_PATH} - assets</li>
<li>{T_THEME_PATH} - styles/xxx/theme</li>
<li>{T_TEMPLATE_PATH} - styles/xxx/template</li>
<li>{T_SUPER_TEMPLATE_PATH} - styles/xxx/template</li>
<li>{T_IMAGESET_PATH} - styles/xxx/imageset</li>
<li>{T_IMAGESET_LANG_PATH} - styles/xxx/imageset/yy</li>
<li>{T_IMAGES_PATH} - images/</li>
<li>{T_SMILIES_PATH} - $config['smilies_path']/</li>
<li>{T_AVATAR_PATH} - $config['avatar_path']/</li>
<li>{T_AVATAR_GALLERY_PATH} - $config['avatar_gallery_path']/</li>
<li>{T_ICONS_PATH} - $config['icons_path']/</li>
<li>{T_RANKS_PATH} - $config['ranks_path']/</li>
<li>{T_UPLOAD_PATH} - $config['upload_path']/</li>
<li>{T_STYLESHEET_LINK} - styles/xxx/theme/stylesheet.css (or link to style.php if css is parsed dynamically)</li>
<li>New template variable {BOARD_URL} for the board url + script path.</li>
</ul>
</div>
<div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
<span class="corners-bottom"><span></span></span></div>
</div>
<a name="use"></a><h2>2. Allow hooks in functions/methods</h2>
<div class="paragraph">
<div class="inner"><span class="corners-top"><span></span></span>
<div class="content">
<p>The following examples explain how phpBB3 utilize the in-build hook system. You will be more interested in registering your hooks, but showing you this may help you understand the system better along the way.</p>
<p>First of all, this is how a function need to be layed out if you want to allow it to be hookable...</p>
<div class="codebox"><pre>
function my_own_function($my_first_parameter, $my_second_parameter)
{
global $phpbb_hook;
if ($phpbb_hook-&gt;call_hook(__FUNCTION__, $my_first_parameter, $my_second_parameter))
{
if ($phpbb_hook-&gt;hook_return(__FUNCTION__))
{
return $phpbb_hook-&gt;hook_return_result(__FUNCTION__);
}
}
[YOUR CODE HERE]
}
</pre></div>
<p>Above, the call_hook function should always be mapping your function call... in regard to the number of parameters passed.</p>
<p>This is how you could make a method being hookable...</p>
<div class="codebox"><pre>
class my_hookable_object
{
function hook_me($my_first_parameter, $my_second_parameter)
{
global $phpbb_hook;
if ($phpbb_hook-&gt;call_hook(array(__CLASS__, __FUNCTION__), $my_first_parameter, $my_second_parameter))
{
if ($phpbb_hook-&gt;hook_return(array(__CLASS__, __FUNCTION__)))
{
return $phpbb_hook-&gt;hook_return_result(array(__CLASS__, __FUNCTION__));
}
}
[YOUR CODE HERE]
}
}
</pre></div>
<p>The only difference about calling it is the way you define the first parameter. For a function it is only <code>__FUNCTION__</code>, for a method it is <code>array(__CLASS__, __FUNCTION__)</code>. In PHP4 __CLASS__ is always returning the class in lowercase.</p>
<p>Now, in phpBB there are some pre-defined hooks available, but how do you make your own hookable function available (and therefore allowing others to hook into it)? For this, there is the add_hook() method:</p>
<div class="codebox"><pre>
// Adding your own hookable function:
$phpbb_hook-&gt;add_hook('my_own_function');
// Adding your own hookable method:
$phpbb_hook-&gt;add_hook(array('my_hookable_object', 'hook_me'));
</pre></div>
<p>You are also able to remove the possibility of hooking a function/method by calling <code>$phpbb_hook-&gt;remove_hook()</code> with the same parameters as add_hook().<br />
This comes in handy if you want to force some hooks not to be called - at all.</p>
</div>
<div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
<span class="corners-bottom"><span></span></span></div>
</div>
<a name="register"></a><h2>3. Registering hooks</h2>
<div class="paragraph">
<div class="inner"><span class="corners-top"><span></span></span>
<div class="content">
<h3>Registering hooks</h3>
<p>Now to actually defining your functions which should be called. For this we take the append_sid() function as an example (this function is able to be hooked by default). We create two classes, one being static and a function:</p>
<div class="codebox"><pre>
class my_append_sid_class
{
// Our functions
function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
{
// Get possible previous results
$result = $hook-&gt;previous_hook_result('append_sid');
return $result['result'] . '&lt;br /&gt;And i was the second one.';
}
}
// Yet another class :o
class my_second_append_sid_class
{
function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
{
// Get possible previous results
$result = $hook-&gt;previous_hook_result('append_sid');
echo $result['result'] . '&lt;br /&gt;I was called as the third one.';
}
}
// And a normal function
function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
{
// Get possible previous results
$result = $hook-&gt;previous_hook_result('append_sid');
return 'I was called as the first one';
}
// Initializing the second class
$my_second_append_sid_class = new my_second_append_sid_class();
</pre></div>
<p>Make sure you add the same parameters to your function as is defined for the hookable function with one exception: The first variable is always <code>&amp;$hook</code>... this is the hook object itself you are able to operate on.</p>
<p>Now we register the hooks one by one with the <code>$phpbb_hook-&gt;register()</code> method:</p>
<div class="codebox"><pre>
// Now, we register our append_sid &quot;replacements&quot; in a stacked way...
// Registering the function (this is called first)
$phpbb_hook-&gt;register('append_sid', 'my_append_sid');
// Registering the first class
$phpbb_hook-&gt;register('append_sid', array('my_append_sid_class', 'my_append_sid'));
$phpbb_hook-&gt;register('append_sid', array(&amp;$my_second_append_sid_class, 'my_append_sid'));
</pre></div>
<p>With this you are even able to make your own functions that are already hooked itself being hooked again...</p>
<div class="codebox"><pre>
// Registering hook, which will be called
$phpbb_hook-&gt;register('append_sid', 'my_own_append_sid');
// Add hook to our called hook function
$phpbb_hook-&gt;add_hook('my_own_append_sid');
// Register added hook
$phpbb_hook-&gt;register('my_own_append_sid', 'also_my_own_append_sid');
</pre></div>
<h3>Special treatment/chains</h3>
<p>The <code>register</code> method is able to take a third argument to specify a special 'chain' mode. The valid modes are <code>first</code>, <code>last</code> and <code>standalone</code></p>
<p><code>$phpbb_hook-&gt;register('append_sid', 'my_own_append_sid', 'first')</code> would make sure that the function is called in the beginning of the chain. It is possible that more than one function is called within the first block - here the FIFO principle is used.</p>
<p><code>$phpbb_hook-&gt;register('append_sid', 'my_own_append_sid', 'last')</code> would make sure that the function is called at the very end of the chain. It is possible that more than one function is called within the last block - here the FIFO principle is used.</p>
<p><code>$phpbb_hook-&gt;register('append_sid', 'my_own_append_sid', 'standalone')</code> makes sure only the defined function is called. All other functions are removed from the chain and no other functions are added to it later on. If two applications try to trigger the standalone mode a PHP notice will be printed and the second function being discarded.</p>
<h3>Only allowing hooks for some objects</h3>
<p>Because the hook system is not able to differate between initialized objects and only operate on the class, you need to solve this on the code level.</p>
<p>One possibility would be to use a property:</p>
<div class="codebox"><pre>
class my_hookable_object
{
function blabla()
{
}
}
class my_hookable_object2 extends my_hookable_object
{
var $call_hook = true;
function hook_me($my_first_parameter, $my_second_parameter)
{
if ($this-&gt;call_hook)
{
global $phpbb_hook;
if ($phpbb_hook-&gt;call_hook(array(__CLASS__, __FUNCTION__), $my_first_parameter, $my_second_parameter))
{
if ($phpbb_hook-&gt;hook_return(array(__CLASS__, __FUNCTION__)))
{
return $phpbb_hook-&gt;hook_return_result(array(__CLASS__, __FUNCTION__));
}
}
}
return 'not hooked';
}
}
function hooking(&amp;$hook, $first, $second)
{
return 'hooked';
}
$first_object = new my_hookable_object2();
$second_object = new my_hookable_object2();
$phpbb_hook-&gt;add_hook(array('my_hookable_object2', 'hook_me'));
$phpbb_hook-&gt;register(array('my_hookable_object2', 'hook_me'), 'hooking');
// Do not call the hook for $first_object
$first_object-&gt;call_hook = false;
echo $first_object-&gt;hook_me('first', 'second') . '&lt;br /&gt;';
echo $second_object-&gt;hook_me('first', 'second') . '&lt;br /&gt;';
</pre></div>
<p>OUTPUT:</p>
<div class="codebox"><pre>
not hooked
hooked
</pre></div>
<p>A different possibility would be using a function variable (which could be left out on passing the function variables to the hook):</p>
<div class="codebox"><pre>
class my_hookable_object
{
function blabla()
{
}
}
class my_hookable_object2 extends my_hookable_object
{
function hook_me($my_first_parameter, $my_second_parameter, $hook_me = true)
{
if ($hook_me)
{
global $phpbb_hook;
if ($phpbb_hook-&gt;call_hook(array(__CLASS__, __FUNCTION__), $my_first_parameter, $my_second_parameter))
{
if ($phpbb_hook-&gt;hook_return(array(__CLASS__, __FUNCTION__)))
{
return $phpbb_hook-&gt;hook_return_result(array(__CLASS__, __FUNCTION__));
}
}
}
return 'not hooked';
}
}
function hooking(&amp;$hook, $first, $second)
{
return 'hooked';
}
$first_object = new my_hookable_object2();
$second_object = new my_hookable_object2();
$phpbb_hook-&gt;add_hook(array('my_hookable_object2', 'hook_me'));
$phpbb_hook-&gt;register(array('my_hookable_object2', 'hook_me'), 'hooking');
echo $first_object-&gt;hook_me('first', 'second', false) . '&lt;br /&gt;';
echo $second_object-&gt;hook_me('first', 'second') . '&lt;br /&gt;';
</pre></div>
<p>OUTPUT:</p>
<div class="codebox"><pre>
not hooked
hooked
</pre></div>
</div>
<div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
<span class="corners-bottom"><span></span></span></div>
</div>
<a name="return"></a><h2>4. Result returning</h2>
<div class="paragraph">
<div class="inner"><span class="corners-top"><span></span></span>
<div class="content">
<p>Generally, the distinction has to be made if a function returns the result obtained from the called function or continue the execution. Based on the needs of the application this may differ. Therefore, the function returns the results only if the called hook function is returning a result.</p>
<h3>Case 1 - Returning the result</h3>
<p>Imagine the following function supporting hooks:</p>
<div class="codebox"><pre>
function append_sid($url, $params = false, $is_amp = true, $session_id = false)
{
global $_SID, $_EXTRA_URL, $phpbb_hook;
// Developers using the hook function need to globalise the $_SID and $_EXTRA_URL on their own and also handle it appropiatly.
// They could mimick most of what is within this function
if ($phpbb_hook-&gt;call_hook(__FUNCTION__, $url, $params, $is_amp, $session_id))
{
if ($phpbb_hook-&gt;hook_return(__FUNCTION__))
{
return $phpbb_hook-&gt;hook_return_result(__FUNCTION__);
}
}
[...]
}
</pre></div>
<p>Now, the following function is yours. Since you return a value, the append_sid() function itself is returning it as is:</p>
<div class="codebox"><pre>
// The function called
function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
{
// Get possible previous results
$result = $hook-&gt;previous_hook_result('append_sid');
return 'Since i return something the append_sid() function will return my result.';
}
</pre></div>
<p>To be able to get the results returned from functions higher in the change the <code>previous_hook_result()</code> method should always be used, it returns an <code>array('result' => [your result])</code> construct.</p>
<h3>Case 2 - Not Returning any result</h3>
<p>Sometimes applications want to return nothing and therefore force the underlying function to continue it's execution:</p>
<div class="codebox"><pre>
function append_sid($url, $params = false, $is_amp = true, $session_id = false)
{
global $_SID, $_EXTRA_URL, $phpbb_hook;
// Developers using the hook function need to globalise the $_SID and $_EXTRA_URL on their own and also handle it appropiatly.
// They could mimick most of what is within this function
if ($phpbb_hook-&gt;call_hook(__FUNCTION__, $url, $params, $is_amp, $session_id))
{
if ($phpbb_hook-&gt;hook_return(__FUNCTION__))
{
return $phpbb_hook-&gt;hook_return_result(__FUNCTION__);
}
}
[...]
}
// The function called
function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
{
// Get possible previous results
$result = $hook-&gt;previous_hook_result('append_sid');
[...]
// I only rewrite some variables, but return nothing. Therefore, the append_sid() function will not return my (non)result.
}
</pre></div>
<p>Please Note: The decision to return or not return is solely made of the very last function call within the hook chain. An example:</p>
<div class="codebox"><pre>
// The function called
function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
{
// Get possible previous results
$result = $hook-&gt;previous_hook_result('append_sid');
// $result is not filled
return 'FILLED';
}
// This function is registered too and gets executed after my_append_sid()
function my_own_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
{
$result = $hook->previous_hook_result('append_sid');
// $result is actually filled with $result['result'] = 'FILLED'
// But i return nothing, therefore append_sid() continues it's execution.
}
// The way both functions are registered.
$phpbb_hook->register('append_sid', 'my_append_sid');
$phpbb_hook->register('append_sid', 'my_own_append_sid');
</pre></div>
</div>
<div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
<span class="corners-bottom"><span></span></span></div>
</div>
<a name="embed"></a><h2>5. Embedding your hook files/classes/methods</h2>
<div class="paragraph">
<div class="inner"><span class="corners-top"><span></span></span>
<div class="content">
<p>There are basically two methods you are able to choose from:</p>
<p>1) Add a file to includes/hooks/. The file need to be prefixed by <code>hook_</code>. This file is included within common.php, you are able to register your hooks, include other files or functions, etc. It is advised to only include other files if needed (within a function call for example).</p>
<p>Please be aware that you need to purge your cache within the ACP to make your newly placed file available to phpBB3.</p>
<p>2) The second method is meant for those wanting to wrap phpBB3 without placing a custom file to the hooks directory. This is mostly done by including phpBB's files within the application file. To be able to register your hooks you need to create a function within your application:</p>
<div class="codebox"><pre>
// My function which gets executed within the hooks constuctor
function phpbb_hook_register(&amp;$hook)
{
$hook-&gt;register('append_sid', 'my_append_sid');
}
[...]
</pre></div>
<p>You should get the idea. ;)</p>
</div>
<div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
<span class="corners-bottom"><span></span></span></div>
</div>
<a name="disclaimer"></a><h2>6. Copyright and disclaimer</h2>
<div class="paragraph">
<div class="inner"><span class="corners-top"><span></span></span>
<div class="content">
<p>phpBB is free software, released under the terms of the <a href="http://opensource.org/licenses/gpl-2.0.php">GNU General Public License, version 2 (GPL-2.0)</a>. Copyright © <a href="https://www.phpbb.com">phpBB Limited</a>. For full copyright and license information, please see the docs/CREDITS.txt file.</p>
</div>
<div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
<span class="corners-bottom"><span></span></span></div>
</div>
<div id="page-footer">
<div class="version">&nbsp;</div>
</div>
</div></div>
<div>
<a id="bottom" name="bottom" accesskey="z"></a>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -40,26 +40,15 @@ $lang = array_merge($lang, array(
'ACP_FILES' => 'Admin language files',
'ACP_LANGUAGE_PACKS_EXPLAIN' => 'Here you are able to install/remove language packs. The default language pack is marked with an asterisk (*).',
'EMAIL_FILES' => 'Email templates',
'DELETE_LANGUAGE_CONFIRM' => 'Are you sure you wish to delete “%s”?',
'FILE_CONTENTS' => 'File contents',
'FILE_FROM_STORAGE' => 'File from storage folder',
'HELP_FILES' => 'Help files',
'INSTALLED_LANGUAGE_PACKS' => 'Installed language packs',
'INVALID_LANGUAGE_PACK' => 'The selected language pack seems to be not valid. Please verify the language pack and upload it again if necessary.',
'INVALID_UPLOAD_METHOD' => 'The selected upload method is not valid, please choose a different method.',
'INSTALLED_LANGUAGE_PACKS' => 'Installed language packs',
'LANGUAGE_DETAILS_UPDATED' => 'Language details successfully updated.',
'LANGUAGE_ENTRIES' => 'Language entries',
'LANGUAGE_ENTRIES_EXPLAIN' => 'Here you are able to change existing language pack entries or not already translated ones.<br /><strong>Note:</strong> Once you changed a language file, the changes will be stored within a separate folder for you to download. The changes will not be seen by your users until you replace the original language files at your webspace (by uploading them).',
'LANGUAGE_FILES' => 'Language files',
'LANGUAGE_KEY' => 'Language key',
'LANGUAGE_PACK_ALREADY_INSTALLED' => 'This language pack is already installed.',
'LANGUAGE_PACK_DELETED' => 'The language pack <strong>%s</strong> has been removed successfully. All users using this language have been reset to the boards default language.',
'LANGUAGE_PACK_DELETED' => 'The language pack “%s” has been removed successfully. All users using this language have been reset to the boards default language.',
'LANGUAGE_PACK_DETAILS' => 'Language pack details',
'LANGUAGE_PACK_INSTALLED' => 'The language pack <strong>%s</strong> has been successfully installed.',
'LANGUAGE_PACK_INSTALLED' => 'The language pack “%s” has been successfully installed.',
'LANGUAGE_PACK_CPF_UPDATE' => 'The custom profile fields language strings were copied from the default language. Please change them if necessary.',
'LANGUAGE_PACK_ISO' => 'ISO',
'LANGUAGE_PACK_LOCALNAME' => 'Local name',
@ -72,31 +61,16 @@ $lang = array_merge($lang, array(
'LANG_ISO_CODE' => 'ISO code',
'LANG_LOCAL_NAME' => 'Local name',
'MISSING_LANGUAGE_FILE' => 'Missing language file: <strong style="color:red">%s</strong>',
'MISSING_LANG_FILES' => 'Missing language files',
'MISSING_LANG_VARIABLES' => 'Missing language variables',
'MODS_FILES' => 'MODs language files',
'NO_FILE_SELECTED' => 'You havent specified a language file.',
'NO_LANG_ID' => 'You havent specified a language pack.',
'NO_REMOVE_DEFAULT_LANG' => 'You are not able to remove the default language pack.<br />If you want to remove this language pack, change your boards default language first.',
'NO_REMOVE_DEFAULT_LANG' => 'You are not able to remove the default language pack.<br />If you want to remove this language pack, change your boards default language first.',
'NO_UNINSTALLED_LANGUAGE_PACKS' => 'No uninstalled language packs',
'REMOVE_FROM_STORAGE_FOLDER' => 'Remove from storage folder',
'SELECT_DOWNLOAD_FORMAT' => 'Select download format',
'SUBMIT_AND_DOWNLOAD' => 'Submit and download file',
'SUBMIT_AND_UPLOAD' => 'Submit and upload file',
'THOSE_MISSING_LANG_FILES' => 'The following language files are missing from the %s language folder',
'THOSE_MISSING_LANG_VARIABLES' => 'The following language variables are missing from the <strong>%s</strong> language pack',
'THOSE_MISSING_LANG_FILES' => 'The following language files are missing from the “%s” language folder',
'THOSE_MISSING_LANG_VARIABLES' => 'The following language variables are missing from the “%s” language pack',
'UNINSTALLED_LANGUAGE_PACKS' => 'Uninstalled language packs',
'UNABLE_TO_WRITE_FILE' => 'The file could not be written to %s.',
'UPLOAD_COMPLETED' => 'The upload was completed successfully.',
'UPLOAD_FAILED' => 'The upload failed for unknown reasons. You may need to replace the relevant file manually.',
'UPLOAD_METHOD' => 'Upload method',
'UPLOAD_SETTINGS' => 'Upload settings',
'WRONG_LANGUAGE_FILE' => 'Selected language file is invalid.',
));

View File

@ -210,7 +210,26 @@ class mysql extends \phpbb\db\driver\mysql_base
*/
function sql_affectedrows()
{
return ($this->db_connect_id) ? @mysql_affected_rows($this->db_connect_id) : false;
if ($this->db_connect_id)
{
// We always want the number of matched rows
// instead of changed rows, when running an update.
// So when mysql_info() returns the number of matched rows
// we return that one instead of mysql_affected_rows()
$mysql_info = @mysql_info($this->db_connect_id);
if ($mysql_info !== false)
{
$match = array();
preg_match('#^Rows matched: (\d)+ Changed: (\d)+ Warnings: (\d)+$#', $mysql_info, $match);
if (isset($match[1]))
{
return $match[1];
}
}
return @mysql_affected_rows($this->db_connect_id);
}
return false;
}
/**

View File

@ -60,7 +60,8 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
}
$this->db_connect_id = @mysqli_connect($this->server, $this->user, $sqlpassword, $this->dbname, $port, $socket);
$this->db_connect_id = mysqli_init();
@mysqli_real_connect($this->db_connect_id, $this->server, $this->user, $sqlpassword, $this->dbname, $port, $socket, MYSQLI_CLIENT_FOUND_ROWS);
if ($this->db_connect_id && $this->dbname != '')
{

View File

@ -681,7 +681,7 @@ function parse_document(container)
/**
* Responsive link lists
*/
container.find('.linklist:not(.navlinks, [data-skip-responsive]), .postbody ul.profile-icons:not([data-skip-responsive])').each(function() {
container.find('.linklist:not(.navlinks, [data-skip-responsive]), .postbody .post-buttons:not([data-skip-responsive])').each(function() {
var $this = $(this),
$body = $('body'),
filterSkip = '.breadcrumbs, [data-skip-responsive]',
@ -769,6 +769,11 @@ function parse_document(container)
menu.prepend(clone.not('.rightside'));
menu.find('li.leftside, li.rightside').removeClass('leftside rightside');
menu.find('.inputbox').parents('li:first').css('white-space', 'normal');
if ($this.hasClass('post-buttons')) {
$('.button', menu).removeClass('button icon-button');
$('.responsive-menu-link', item).addClass('button icon-button').prepend('<span></span>');
}
copied = true;
}
else {
@ -914,6 +919,8 @@ function parse_document(container)
$(document).ready(function() {
// Swap .nojs and .hasjs
$('#phpbb.nojs').toggleClass('nojs hasjs');
$('#phpbb').toggleClass('hastouch', phpbb.isTouch);
$('#phpbb.hastouch').removeClass('notouch');
// Focus forms
$('form[data-focus]:first').each(function() {

View File

@ -50,13 +50,20 @@
<div class="postbody">
<h3><a href="{U_VIEW_POST}">{POST_SUBJECT}</a></h3>
<!-- IF U_EDIT -->
<ul class="profile-icons">
<li class="edit-icon"><a href="{U_EDIT}" title="{L_EDIT_POST}"><span>{L_EDIT_POST}</span></a></li>
<ul class="post-buttons">
<li id="expand">
<a href="#post_details" onclick="viewableArea(getElementById('post_details'), true); var rev_text = getElementById('expand').getElementsByTagName('a').item(0).firstChild; if (rev_text.data.trim() == '{LA_EXPAND_VIEW}'){rev_text.data = '{LA_COLLAPSE_VIEW}'; } else if (rev_text.data.trim() == '{LA_COLLAPSE_VIEW}'){rev_text.data = '{LA_EXPAND_VIEW}';} return false;">
{L_EXPAND_VIEW}
</a>
</li>
<!-- IF U_EDIT -->
<li>
<a href="{U_EDIT}" title="{L_EDIT_POST}" class="button icon-button edit-icon">
<span>{L_EDIT_POST}</span>
</a>
</li>
<!-- ENDIF -->
</ul>
<!-- ENDIF -->
<span class="right-box" id="expand"><a href="#post_details" onclick="viewableArea(getElementById('post_details'), true); var rev_text = getElementById('expand').getElementsByTagName('a').item(0).firstChild; if (rev_text.data == '{LA_EXPAND_VIEW}'){rev_text.data = '{LA_COLLAPSE_VIEW}'; } else if (rev_text.data == '{LA_COLLAPSE_VIEW}'){rev_text.data = '{LA_EXPAND_VIEW}'}; return false;">{L_EXPAND_VIEW}</a></span>
<!-- IF S_PM -->
<p class="author">

View File

@ -96,7 +96,18 @@
<div class="inner">
<div class="postbody" id="pr{postrow.POST_ID}">
<ul class="profile-icons"><li class="info-icon"><a href="{postrow.U_POST_DETAILS}" title="{L_POST_DETAILS}"><span>{L_POST_DETAILS}</span></a></li><li><label for="post_id_list_select_{postrow.POST_ID}">{L_SELECT}{L_COLON} <input type="checkbox" id="post_id_list_select_{postrow.POST_ID}" name="post_id_list[]" value="{postrow.POST_ID}"<!-- IF postrow.S_CHECKED --> checked="checked"<!-- ENDIF --> /></label></li></ul>
<ul class="post-buttons">
<li>
<a href="{postrow.U_POST_DETAILS}" title="{L_POST_DETAILS}" class="button icon-button info-icon">
<span>{L_POST_DETAILS}</span>
</a>
</li>
<li>
<label for="post_id_list_select_{postrow.POST_ID}">{L_SELECT}{L_COLON}
<input type="checkbox" id="post_id_list_select_{postrow.POST_ID}" name="post_id_list[]" value="{postrow.POST_ID}"<!-- IF postrow.S_CHECKED --> checked="checked"<!-- ENDIF --> />
</label>
</li>
</ul>
<h3><a href="{postrow.U_POST_DETAILS}">{postrow.POST_SUBJECT}</a></h3>
<p class="author"><a href="#pr{postrow.POST_ID}">{postrow.MINI_POST_IMG}</a> {L_POSTED} {postrow.POST_DATE} {L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong><!-- IF postrow.U_MCP_DETAILS --> [ <a href="{postrow.U_MCP_DETAILS}">{L_POST_DETAILS}</a> ]<!-- ENDIF --></p>

View File

@ -52,7 +52,7 @@
{$STYLESHEETS}
</head>
<body id="phpbb" class="nojs section-{SCRIPT_NAME} {S_CONTENT_DIRECTION} {BODY_CLASS}">
<body id="phpbb" class="nojs notouch section-{SCRIPT_NAME} {S_CONTENT_DIRECTION} {BODY_CLASS}">
<!-- EVENT overall_header_body_before -->

View File

@ -24,14 +24,25 @@
<div class="postbody" id="pr{topic_review_row.POST_ID}">
<h3><a href="#pr{topic_review_row.POST_ID}">{topic_review_row.POST_SUBJECT}</a></h3>
<!-- IF (topic_review_row.POSTER_QUOTE and topic_review_row.DECODED_MESSAGE) or topic_review_row.U_MCP_DETAILS -->
<ul class="post-buttons">
<!-- IF topic_review_row.U_MCP_DETAILS -->
<li>
<a href="{topic_review_row.U_MCP_DETAILS}" title="{L_POST_DETAILS}" class="button icon-button info-icon">
<span>{L_POST_DETAILS}</span>
</a>
<li>
<!-- ENDIF -->
<!-- IF topic_review_row.POSTER_QUOTE and topic_review_row.DECODED_MESSAGE -->
<ul class="profile-icons">
<li class="quote-icon"><a href="#postingbox" onclick="addquote({topic_review_row.POST_ID}, '{topic_review_row.POSTER_QUOTE}', '{LA_WROTE}');" title="{L_QUOTE} {topic_review_row.POST_AUTHOR}"><span>{L_QUOTE} {topic_review_row.POST_AUTHOR}</span></a></li>
<li>
<a href="#postingbox" onclick="addquote({topic_review_row.POST_ID}, '{topic_review_row.POSTER_QUOTE}', '{LA_WROTE}');" title="{L_QUOTE} {topic_review_row.POST_AUTHOR}" class="button icon-button quote-icon">
<span>{L_QUOTE} {topic_review_row.POST_AUTHOR}</span>
</a>
</li>
<!-- ENDIF -->
</ul>
<!-- ENDIF -->
<!-- IF topic_review_row.U_MCP_DETAILS --><div class="right-box"><a href="{topic_review_row.U_MCP_DETAILS}">{L_POST_DETAILS}</a></div><!-- ENDIF -->
<p class="author"><!-- IF S_IS_BOT -->{topic_review_row.MINI_POST_IMG}<!-- ELSE --><a href="{topic_review_row.U_MINI_POST}">{topic_review_row.MINI_POST_IMG}</a><!-- ENDIF --> {L_POST_BY_AUTHOR} <strong>{topic_review_row.POST_AUTHOR_FULL}</strong> &raquo; {topic_review_row.POST_DATE} </p>
<div class="content">{topic_review_row.MESSAGE}</div>

View File

@ -18,8 +18,12 @@
<h3><a href="{history_row.U_VIEW_MESSAGE}" <!-- IF history_row.S_CURRENT_MSG -->class="current"<!-- ENDIF -->>{history_row.SUBJECT}</a></h3>
<!-- IF history_row.U_QUOTE or history_row.MESSAGE_AUTHOR_QUOTE -->
<ul class="profile-icons">
<li class="quote-icon"><a <!-- IF history_row.U_QUOTE -->href="{history_row.U_QUOTE}"<!-- ELSE -->href="#postingbox" onclick="addquote({history_row.MSG_ID}, '{history_row.MESSAGE_AUTHOR_QUOTE}', '{LA_WROTE}');"<!-- ENDIF --> title="{L_QUOTE} {history_row.MESSAGE_AUTHOR}"><span>{L_QUOTE} {history_row.MESSAGE_AUTHOR}</span></a></li>
<ul class="post-buttons">
<li>
<a <!-- IF history_row.U_QUOTE -->href="{history_row.U_QUOTE}"<!-- ELSE -->href="#postingbox" onclick="addquote({history_row.MSG_ID}, '{history_row.MESSAGE_AUTHOR_QUOTE}', '{LA_WROTE}');"<!-- ENDIF --> title="{L_QUOTE} {history_row.MESSAGE_AUTHOR}" class="button icon-button quote-icon">
<span>{L_QUOTE} {history_row.MESSAGE_AUTHOR}</span>
</a>
</li>
</ul>
<!-- ENDIF -->

View File

@ -8,16 +8,31 @@
<!-- IF FOLDER_STATUS and FOLDER_MAX_MESSAGES neq 0 --><p>{FOLDER_STATUS}</p><!-- ENDIF -->
<!-- IF U_POST_REPLY_PM or U_POST_NEW_TOPIC or U_FORWARD_PM -->
<div class="buttons">
<!-- IF U_POST_REPLY_PM --><div class="pmreply-icon"><a title="{L_POST_REPLY_PM}" href="{U_POST_REPLY_PM}"><span></span>{L_BUTTON_PM_REPLY}</a></div>
<!-- ELSEIF U_POST_NEW_TOPIC --><div class="newpm-icon"><a href="{U_POST_NEW_TOPIC}" accesskey="n" title="{L_UCP_PM_COMPOSE}"><span></span>{L_BUTTON_PM_NEW}</a></div><!-- ENDIF -->
<!-- IF U_FORWARD_PM --><div class="forwardpm-icon"><a title="{L_POST_FORWARD_PM}" href="{U_FORWARD_PM}"><span></span>{L_BUTTON_PM_FORWARD}</a></div><!-- ENDIF -->
<!-- IF U_POST_REPLY_PM and S_PM_RECIPIENTS gt 1 --><div class="reply-all"><a title="{L_REPLY_TO_ALL}" href="{U_POST_REPLY_ALL}">{L_BUTTON_PM_REPLY_ALL}</a></div><!-- ENDIF -->
<!-- IF U_POST_REPLY_PM -->
<a title="{L_POST_REPLY_PM}" href="{U_POST_REPLY_PM}" class="button icon-button pmreply-icon">
{L_BUTTON_PM_REPLY}
</a>
<!-- ELSEIF U_POST_NEW_TOPIC -->
<a href="{U_POST_NEW_TOPIC}" accesskey="n" title="{L_UCP_PM_COMPOSE}" class="button icon-button newpm-icon">
{L_BUTTON_PM_NEW}
</a>
<!-- ENDIF -->
<!-- IF U_FORWARD_PM -->
<a title="{L_POST_FORWARD_PM}" href="{U_FORWARD_PM}" class="button icon-button forwardpm-icon">
{L_BUTTON_PM_FORWARD}
</a>
<!-- ENDIF -->
<!-- IF U_POST_REPLY_PM and S_PM_RECIPIENTS gt 1 -->
<a title="{L_REPLY_TO_ALL}" href="{U_POST_REPLY_ALL}" class="button icon-button reply-all">
{L_BUTTON_PM_REPLY_ALL}
</a>
<!-- ENDIF -->
</div>
<!-- ENDIF -->
<!-- IF not S_IS_BOT and U_PRINT_PM -->
<div class="dropdown-container dropdown-button-control topic-tools">
<span title="{L_PM_TOOLS}" class="dropdown-trigger dropdown-select dropdown-select-icon tools-icon"><span></span></span>
<span title="{L_PM_TOOLS}" class="dropdown-trigger dropdown-select button icon-button tools-icon"></span>
<div class="dropdown hidden">
<div class="pointer"><div class="pointer-inner"></div></div>
<ul class="dropdown-contents">

View File

@ -66,11 +66,27 @@
<h3 class="first">{SUBJECT}</h3>
<!-- IF U_DELETE or U_EDIT or U_QUOTE or U_REPORT -->
<ul class="profile-icons">
<!-- IF U_EDIT --><li class="edit-icon"><a href="{U_EDIT}" title="{L_POST_EDIT_PM}"><span>{L_POST_EDIT_PM}</span></a></li><!-- ENDIF -->
<!-- IF U_DELETE --><li class="delete-icon"><a href="{U_DELETE}" title="{L_DELETE_MESSAGE}"><span>{L_DELETE_MESSAGE}</span></a></li><!-- ENDIF -->
<!-- IF U_REPORT --><li class="report-icon"><a href="{U_REPORT}" title="{L_REPORT_PM}"><span>{L_REPORT_PM}</span></a></li><!-- ENDIF -->
<!-- IF U_QUOTE --><li class="quote-icon"><a href="{U_QUOTE}" title="{L_POST_QUOTE_PM}"><span>{L_POST_QUOTE_PM}</span></a></li><!-- ENDIF -->
<ul class="post-buttons">
<!-- IF U_EDIT -->
<li>
<a href="{U_EDIT}" title="{L_POST_EDIT_PM}" class="button icon-button edit-icon"><span>{L_POST_EDIT_PM}</span></a>
</li>
<!-- ENDIF -->
<!-- IF U_DELETE -->
<li>
<a href="{U_DELETE}" title="{L_DELETE_MESSAGE}" class="button icon-button delete-icon"><span>{L_DELETE_MESSAGE}</span></a>
</li>
<!-- ENDIF -->
<!-- IF U_REPORT -->
<li>
<a href="{U_REPORT}" title="{L_REPORT_PM}" class="button icon-button report-icon"><span>{L_REPORT_PM}</span></a>
</li>
<!-- ENDIF -->
<!-- IF U_QUOTE -->
<li>
<a href="{U_QUOTE}" title="{L_POST_QUOTE_PM}" class="button icon-button quote-icon"><span>{L_POST_QUOTE_PM}</span></a>
</li>
<!-- ENDIF -->
</ul>
<!-- ENDIF -->

View File

@ -39,7 +39,9 @@
<!-- IF not S_IS_BOT and S_DISPLAY_POST_INFO -->
<div class="buttons">
<div class="<!-- IF S_IS_LOCKED -->locked-icon<!-- ELSE -->post-icon<!-- ENDIF -->" title="<!-- IF S_IS_LOCKED -->{L_FORUM_LOCKED}<!-- ELSE -->{L_POST_TOPIC}<!-- ENDIF -->"><a href="{U_POST_NEW_TOPIC}"><span></span><!-- IF S_IS_LOCKED -->{L_BUTTON_FORUM_LOCKED}<!-- ELSE -->{L_BUTTON_NEW_TOPIC}<!-- ENDIF --></a></div>
<a href="{U_POST_NEW_TOPIC}" class="button icon-button <!-- IF S_IS_LOCKED -->locked-icon<!-- ELSE -->post-icon<!-- ENDIF -->" title="<!-- IF S_IS_LOCKED -->{L_FORUM_LOCKED}<!-- ELSE -->{L_POST_TOPIC}<!-- ENDIF -->">
<!-- IF S_IS_LOCKED -->{L_BUTTON_FORUM_LOCKED}<!-- ELSE -->{L_BUTTON_NEW_TOPIC}<!-- ENDIF -->
</a>
</div>
<!-- ENDIF -->
@ -222,9 +224,11 @@
<!-- IF .topicrow and not S_DISPLAY_ACTIVE -->
<div class="topic-actions">
<!-- IF not S_IS_BOT and S_DISPLAY_POST_INFO -->
<div class="buttons">
<div class="<!-- IF S_IS_LOCKED -->locked-icon<!-- ELSE -->post-icon<!-- ENDIF -->" title="<!-- IF S_IS_LOCKED -->{L_FORUM_LOCKED}<!-- ELSE -->{L_POST_TOPIC}<!-- ENDIF -->"><a href="{U_POST_NEW_TOPIC}"><span></span><!-- IF S_IS_LOCKED -->{L_BUTTON_FORUM_LOCKED}<!-- ELSE -->{L_BUTTON_NEW_TOPIC}<!-- ENDIF --></a></div>
</div>
<div class="buttons">
<a href="{U_POST_NEW_TOPIC}" class="button icon-button <!-- IF S_IS_LOCKED -->locked-icon<!-- ELSE -->post-icon<!-- ENDIF -->" title="<!-- IF S_IS_LOCKED -->{L_FORUM_LOCKED}<!-- ELSE -->{L_POST_TOPIC}<!-- ENDIF -->">
<!-- IF S_IS_LOCKED -->{L_BUTTON_FORUM_LOCKED}<!-- ELSE -->{L_BUTTON_NEW_TOPIC}<!-- ENDIF -->
</a>
</div>
<!-- ENDIF -->
<div class="pagination">

View File

@ -29,7 +29,9 @@
<div class="buttons">
<!-- IF not S_IS_BOT and S_DISPLAY_REPLY_INFO -->
<div class="<!-- IF S_IS_LOCKED -->locked-icon<!-- ELSE -->reply-icon<!-- ENDIF -->"><a href="{U_POST_REPLY_TOPIC}" title="<!-- IF S_IS_LOCKED -->{L_TOPIC_LOCKED}<!-- ELSE -->{L_POST_REPLY}<!-- ENDIF -->"><span></span><!-- IF S_IS_LOCKED -->{L_BUTTON_TOPIC_LOCKED}<!-- ELSE -->{L_BUTTON_POST_REPLY}<!-- ENDIF --></a></div>
<a href="{U_POST_REPLY_TOPIC}" class="button icon-button <!-- IF S_IS_LOCKED -->locked-icon<!-- ELSE -->reply-icon<!-- ENDIF -->" title="<!-- IF S_IS_LOCKED -->{L_TOPIC_LOCKED}<!-- ELSE -->{L_POST_REPLY}<!-- ENDIF -->">
<!-- IF S_IS_LOCKED -->{L_BUTTON_TOPIC_LOCKED}<!-- ELSE -->{L_BUTTON_POST_REPLY}<!-- ENDIF -->
</a>
<!-- ENDIF -->
</div>
@ -197,14 +199,38 @@
<!-- IF not S_IS_BOT -->
<!-- IF postrow.U_EDIT or postrow.U_DELETE or postrow.U_REPORT or postrow.U_WARN or postrow.U_INFO or postrow.U_QUOTE -->
<ul class="profile-icons">
<ul class="post-buttons">
<!-- EVENT viewtopic_body_post_buttons_before -->
<!-- IF postrow.U_EDIT --><li class="edit-icon"><a href="{postrow.U_EDIT}" title="{L_EDIT_POST}"><span>{L_EDIT_POST}</span></a></li><!-- ENDIF -->
<!-- IF postrow.U_DELETE --><li class="delete-icon"><a href="{postrow.U_DELETE}" title="{L_DELETE_POST}"><span>{L_DELETE_POST}</span></a></li><!-- ENDIF -->
<!-- IF postrow.U_REPORT --><li class="report-icon"><a href="{postrow.U_REPORT}" title="{L_REPORT_POST}"><span>{L_REPORT_POST}</span></a></li><!-- ENDIF -->
<!-- IF postrow.U_WARN --><li class="warn-icon"><a href="{postrow.U_WARN}" title="{L_WARN_USER}"><span>{L_WARN_USER}</span></a></li><!-- ENDIF -->
<!-- IF postrow.U_INFO --><li class="info-icon"><a href="{postrow.U_INFO}" title="{L_INFORMATION}"><span>{L_INFORMATION}</span></a></li><!-- ENDIF -->
<!-- IF postrow.U_QUOTE --><li class="quote-icon"><a href="{postrow.U_QUOTE}" title="{L_REPLY_WITH_QUOTE}"><span>{L_REPLY_WITH_QUOTE}</span></a></li><!-- ENDIF -->
<!-- IF postrow.U_EDIT -->
<li>
<a href="{postrow.U_EDIT}" title="{L_EDIT_POST}" class="button icon-button edit-icon"><span>{L_BUTTON_EDIT}</span></a>
</li>
<!-- ENDIF -->
<!-- IF postrow.U_DELETE -->
<li>
<a href="{postrow.U_DELETE}" title="{L_DELETE_POST}" class="button icon-button delete-icon"><span>{L_DELETE_POST}</span></a>
</li>
<!-- ENDIF -->
<!-- IF postrow.U_REPORT -->
<li>
<a href="{postrow.U_REPORT}" title="{L_REPORT_POST}" class="button icon-button report-icon"><span>{L_REPORT_POST}</span></a>
</li>
<!-- ENDIF -->
<!-- IF postrow.U_WARN -->
<li>
<a href="{postrow.U_WARN}" title="{L_WARN_USER}" class="button icon-button warn-icon"><span>{L_WARN_USER}</span></a>
</li>
<!-- ENDIF -->
<!-- IF postrow.U_INFO -->
<li>
<a href="{postrow.U_INFO}" title="{L_INFORMATION}" class="button icon-button info-icon"><span>{L_INFORMATION}</span></a>
</li>
<!-- ENDIF -->
<!-- IF postrow.U_QUOTE -->
<li>
<a href="{postrow.U_QUOTE}" title="{L_REPLY_WITH_QUOTE}" class="button icon-button quote-icon"><span>{L_QUOTE}</span></a>
</li>
<!-- ENDIF -->
<!-- EVENT viewtopic_body_post_buttons_after -->
</ul>
<!-- ENDIF -->
@ -316,7 +342,9 @@
<div class="topic-actions">
<div class="buttons">
<!-- IF not S_IS_BOT and S_DISPLAY_REPLY_INFO -->
<div class="<!-- IF S_IS_LOCKED -->locked-icon<!-- ELSE -->reply-icon<!-- ENDIF -->"><a href="{U_POST_REPLY_TOPIC}" title="<!-- IF S_IS_LOCKED -->{L_TOPIC_LOCKED}<!-- ELSE -->{L_POST_REPLY}<!-- ENDIF -->"><span></span><!-- IF S_IS_LOCKED -->{L_BUTTON_TOPIC_LOCKED}<!-- ELSE -->{L_BUTTON_POST_REPLY}<!-- ENDIF --></a></div>
<a href="{U_POST_REPLY_TOPIC}" class="button icon-button <!-- IF S_IS_LOCKED -->locked-icon<!-- ELSE -->reply-icon<!-- ENDIF -->" title="<!-- IF S_IS_LOCKED -->{L_TOPIC_LOCKED}<!-- ELSE -->{L_POST_REPLY}<!-- ENDIF -->">
<!-- IF S_IS_LOCKED -->{L_BUTTON_TOPIC_LOCKED}<!-- ELSE -->{L_BUTTON_POST_REPLY}<!-- ENDIF -->
</a>
<!-- ENDIF -->
</div>

View File

@ -1,6 +1,6 @@
<!-- IF not S_IS_BOT and (U_WATCH_TOPIC or U_BOOKMARK_TOPIC or U_BUMP_TOPIC or S_HAS_ATTACHMENTS or U_EMAIL_TOPIC or U_PRINT_TOPIC or S_DISPLAY_TOPIC_TOOLS) -->
<div class="dropdown-container dropdown-button-control topic-tools">
<span title="{L_TOPIC_TOOLS}" class="dropdown-trigger dropdown-select dropdown-select-icon tools-icon"><span></span></span>
<span title="{L_TOPIC_TOOLS}" class="button icon-button tools-icon dropdown-trigger dropdown-select"></span>
<div class="dropdown hidden">
<div class="pointer"><div class="pointer-inner"></div></div>
<ul class="dropdown-contents">

View File

@ -554,13 +554,27 @@ ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a {
/* Rollover buttons
Based on: http://wellstyled.com/css-nopreload-rollovers.html
----------------------------------------*/
.rtl .buttons {
float: right;
.rtl .icon-button.dropdown-select {
padding-left: 26px;
padding-right: 8px;
}
/* Rollover state */
.rtl .buttons div {
margin: 0 1px 0 5px;
.rtl .icon-button:before {
float: left;
margin-left: 0;
margin-right: 2px;
}
.dropdown-select:after {
border-left: 0;
border-right-style: solid;
border-right-width: 1px;
left: 0;
right: auto;
}
.rtl .buttons, .rtl .buttons .button {
float: right;
}
/* Icon images
@ -574,17 +588,18 @@ ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a {
padding-right: 0;
}
/* Poster profile icons
----------------------------------------*/
/* Rollover state */
.rtl .postprofile ul.profile-icons li {
float: right;
margin: 0 0 3px 6px;
/* Post control buttons
--------------------------------------------- */
.rtl .post-buttons {
float: left;
}
/* Positioning of moderator icons */
.rtl .postbody ul.profile-icons {
float: left;
.rtl .post-buttons li {
float: right;
}
.post-buttons .icon-button:before {
margin-right: 0;
}
/**

View File

@ -4,102 +4,84 @@
/* Rollover buttons
Based on: http://wellstyled.com/css-nopreload-rollovers.html
----------------------------------------*/
.buttons {
float: left;
width: auto;
height: auto;
}
/* Rollover state */
.buttons div, .dropdown-select {
float: left;
margin: 0 5px 0 0;
}
/* Rolloff state */
.buttons div a, .dropdown-select {
.button {
cursor: pointer;
display: inline-block;
line-height: 17.5px;
height: 18px;
font-size: 13px;
white-space: nowrap;
border: 1px solid transparent;
border-radius: 4px;
background: transparent none 0 0 repeat-x;
padding: 2px 22px 2px 8px;
padding: 2px 8px;
font-family: "Open Sans", "Droid Sans", Verdana, Arial, Helvetica;
font-weight: 600;
position: relative;
text-decoration: none !important;
outline-style: none !important;
vertical-align: bottom;
*padding-right: 8px;
}
.buttons div span { display: none; }
.icon-button.dropdown-select {
padding-right: 28px;
}
.buttons div a:after, .dropdown-select:after {
content: '';
display: block;
position: absolute;
top: 50%;
right: 6px;
width: 12px;
height: 12px;
margin-top: -6px;
.icon-button:before {
background: transparent 0 0 no-repeat;
}
.buttons div a:hover:after {
background-position: 0 -20px;
}
.dropdown-select {
cursor: pointer;
font-family: inherit;
font-size: 1em;
font-weight: normal;
content: '';
display: inline-block;
float: right;
height: 12px;
margin: 3px 0 0 2px;
width: 12px;
}
.dropdown-select:after {
background-position: -103px 10px;
border-left: 1px solid;
margin-top: 0;
content: '';
position: absolute;
top: 0;
right: 0;
height: 21px;
width: 15px;
height: 22px;
width: 16px;
}
.dropdown-visible .dropdown-select:after, .nojs .dropdown-container:hover .dropdown-select:after {
background-position: -103px -10px;
}
.dropdown-select-icon:before {
content: '';
display: block;
.buttons, .buttons .button {
float: left;
margin-right: 4px;
margin-top: 2px;
}
.buttons .button, .dropdown-select {
margin-right: 5px;
}
/* Big button images */
.buttons div.reply-icon a:after, .buttons div.pmreply-icon a:after { background-position: -20px 0; }
.buttons div.reply-icon a:hover:after, .buttons div.pmreply-icon a:hover:after { background-position: -20px -20px; }
.reply-icon:before, .pmreply-icon:before { background-position: -20px 0; }
.reply-icon:hover:before, .pmreply-icon:hover:before { background-position: -20px -20px; }
.buttons div.post-icon a:after, .buttons div.newpm-icon a:after { background-position: 0 0; }
.buttons div.post-icon a:hover:after, .buttons div.newpm-icon a:hover:after { background-position: 0 -20px; }
.post-icon:before, .newpm-icon:before, .reply-all:before { background-position: 0 0; }
.post-icon:hover:before,
.newpm-icon:hover:before,
.reply-all:hover:before { background-position: 0 -20px; }
.buttons div.locked-icon a:after { background-position: -60px 0; }
.buttons div.locked-icon a:hover:after { background-position: -60px -20px; }
.locked-icon:before { background-position: -60px 0; }
.locked-icon:hover:before { background-position: -60px -20px; }
.buttons div.forwardpm-icon a:after { background-position: -40px 0; }
.buttons div.forwardpm-icon a:hover:after { background-position: -40px -20px; }
.forwardpm-icon:before { background-position: -40px 0; }
.forwardpm-icon:hover:before { background-position: -40px -20px; }
.dropdown-select.tools-icon:before { background-position: -80px 0; height: 16px; width: 16px; }
.tools-icon:before {
background-position: -80px 0;
height: 16px;
margin-top: 2px;
width: 16px;
}
.dropdown-visible .dropdown-select.tools-icon:before,
.nojs .dropdown-container:hover .dropdown-select.tools-icon:before { background-position: -80px -20px; }
.dropdown-visible .tools-icon:before,
.nojs .dropdown-container:hover .tools-icon:before { background-position: -80px -20px; }
/* Icon images
---------------------------------------- */
@ -118,102 +100,8 @@ ul.linklist.bulletin li.small-icon:before {
display: none;
}
/* Poster profile icons
/* Poster contact icons
----------------------------------------*/
ul.profile-icons {
padding-top: 10px;
list-style: none;
}
/* Rollover state */
ul.profile-icons li {
float: left;
margin: 0 6px 3px 0;
background-position: 0 100%;
}
/* Rolloff state */
ul.profile-icons li a {
display: block;
width: 100%;
height: 100%;
background-position: 0 0;
}
/* Hide <a> text and hide off-state image when rolling over (prevents flicker in IE) */
ul.profile-icons li span { display:none; }
ul.profile-icons li a:hover { background: none; }
/* Positioning of moderator icons */
.postbody ul.profile-icons {
float: right;
width: auto;
padding: 0;
}
.postbody ul.profile-icons li {
margin: 0 3px;
}
/* Responsive icons in postbody */
.postbody ul.profile-icons.responsive .responsive-menu {
position: relative;
}
ul.profile-icons.responsive a.responsive-menu-link {
display: inline-block;
position: relative;
margin: 0 5px;
width: 20px;
height: 20px;
text-decoration: none;
background: none top left no-repeat;
}
ul.profile-icons.responsive a.responsive-menu-link:hover {
background-position: 0 -20px;
}
ul.profile-icons.responsive a.responsive-menu-link:before {
content: '';
position: absolute;
left: 0;
top: 7px;
height: .125em;
width: 14px;
border-bottom: 0.125em solid transparent;
border-top: 0.375em double transparent;
}
.postbody ul.profile-icons.responsive .popup-pointer {
left: auto;
right: 7px;
top: 20px;
}
.postbody ul.profile-icons .dropdown li, .postbody ul.profile-icons .dropdown li a {
display: block;
background: transparent none;
width: auto;
height: auto;
margin: 0;
padding: 0;
float: none;
list-style-type: none;
}
.postbody ul.profile-icons .dropdown li span {
display: block;
text-align: right;
font-size: 1.2em;
line-height: 1.8em;
white-space: nowrap;
}
.hasjs .postbody ul.profile-icons {
max-width: 40%;
}
.contact-icons.dropdown-contents {
min-width: 0;
padding: 0;
@ -245,8 +133,7 @@ ul.profile-icons.responsive a.responsive-menu-link:before {
clear: left;
}
/* Profile & navigation icons */
/* Profile icons */
.pm-icon { background-position: 0 0; }
.email-icon { background-position: -21px 0; }
.jabber-icon { background-position: -80px 0; }
@ -261,39 +148,74 @@ ul.profile-icons.responsive a.responsive-menu-link:before {
.phpbb_twitter-icon { background-position: -203px 0; }
.phpbb_yahoo-icon { background-position: -224px 0; }
.quote-icon, .quote-icon a { background: none top left no-repeat; }
/* Post control buttons
--------------------------------------------- */
.post-buttons {
float: right;
list-style: none;
margin-top: 2px;
}
/* Moderator icons */
.report-icon, .report-icon a { background: none top left no-repeat; }
.warn-icon, .warn-icon a { background: none top left no-repeat; }
.edit-icon, .edit-icon a { background: none top left no-repeat; }
.delete-icon, .delete-icon a { background: none top left no-repeat; }
.info-icon, .info-icon a { background: none top left no-repeat; }
.notouch.section-viewtopic .post-buttons {
opacity: 0;
transition: opacity .5s;
}
/* Set profile icon dimensions */
ul.profile-icons li.email-icon { width: 20px; height: 20px; }
ul.profile-icons li.phpbb_aol-icon { width: 20px; height: 20px; }
ul.profile-icons li.aim-icon { width: 20px; height: 20px; }
ul.profile-icons li.yahoo-icon { width: 20px; height: 20px; }
ul.profile-icons li.phpbb_yahoo-icon { width: 20px; height: 20px; }
ul.profile-icons li.web-icon { width: 20px; height: 20px; }
ul.profile-icons li.phpbb_website-icon { width: 20px; height: 20px; }
ul.profile-icons li.msnm-icon { width: 20px; height: 20px; }
ul.profile-icons li.phpbb_wlm-icon { width: 20px; height: 20px; }
ul.profile-icons li.icq-icon { width: 20px; height: 20px; }
ul.profile-icons li.phpbb_icq-icon { width: 20px; height: 20px; }
ul.profile-icons li.jabber-icon { width: 20px; height: 20px; }
ul.profile-icons li.pm-icon { width: 28px; height: 20px; }
ul.profile-icons li.quote-icon { width: 54px; height: 20px; }
ul.profile-icons li.report-icon { width: 20px; height: 20px; }
ul.profile-icons li.edit-icon { width: 42px; height: 20px; }
ul.profile-icons li.delete-icon { width: 20px; height: 20px; }
ul.profile-icons li.info-icon { width: 20px; height: 20px; }
ul.profile-icons li.warn-icon { width: 20px; height: 20px; }
ul.profile-icons a.responsive-menu-link { width: 20px; height: 20px; }
.notouch.section-viewtopic .post:hover .post-buttons {
opacity: 1;
}
/* Fix profile icon default margins */
ul.profile-icons li.edit-icon { margin: 0 0 0 3px; }
ul.profile-icons li.quote-icon { margin: 0 0 0 10px; }
ul.profile-icons li.info-icon, ul.profile-icons li.report-icon { margin: 0 3px 0 0; }
.post-buttons li {
float: left;
margin-right: 3px;
}
.post-buttons .icon-button {
padding: 0 5px;
}
.hastouch .post-buttons .icon-button {
padding: 2px 8px;
}
.post-buttons .icon-button span {
display: block;
height: 0;
overflow: hidden;
position: absolute;
width: 1px;
}
.post-buttons .icon-button:before {
margin-left: 0;
}
.quote-icon:before { background-position: -122px 0; }
.quote-icon:hover:before { background-position: -122px -21px; }
.edit-icon:before { background-position: -137px 0; }
.edit-icon:hover:before { background-position: -137px -21px; }
.warn-icon:before { background-position: -208px 0; }
.warn-icon:hover:before { background-position: -208px -21px; }
.delete-icon:before { background-position: -152px 0; }
.delete-icon:hover:before { background-position: -152px -21px; }
.report-icon:before { background-position: -165px 0; }
.report-icon:hover:before { background-position: -165px -21px; }
.info-icon:before { background-position: -175px 0; }
.info-icon:hover:before { background-position: -175px -21px; }
.button.responsive-menu-link:before { background-position: -191px 0; }
.button.responsive-menu-link:hover:before { background-position: -191px -21px; }
/* Responsive buttons in post body */
.post-buttons .dropdown {
top: 18px;
}
.post-buttons .dropdown a {
display: block;
font-size: 1.2em;
text-align: right;
}
.hasjs .postbody .post-buttons {
max-width: 40%;
}

View File

@ -250,7 +250,7 @@ p.post-notice.reported:before, p.post-notice.error:before {
Colours and backgrounds for links.css
-------------------------------------------------------------- */
a:link { color: #105289; }
a { color: #105289; }
a:visited { color: #105289; }
a:hover { color: #D31141; }
a:active { color: #368AD2; }
@ -668,8 +668,7 @@ dd.profile-warnings {
--------------------------------------------------------------
Colours and backgrounds for buttons.css
-------------------------------------------------------------- */
.buttons div a, .dropdown-select {
.button, .button:visited {
border-color: #C7C3BF;
background-color: #FFFFFF;
background-image: -moz-linear-gradient(top, #FFFFFF, #E9E9E9);
@ -679,19 +678,10 @@ Colours and backgrounds for buttons.css
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#FFFFFF', EndColorStr='#E9E9E9')";
box-shadow: 0 0 0 1px #FFFFFF inset;
-webkit-box-shadow: 0 0 0 1px #FFFFFF inset;
color: #BC2A4D !important;
color: #BC2A4D;
}
.dropdown-select {
color: #5C6482 !important;
}
.dropdown-select:after {
border-color: #DADADA;
}
.buttons div a:hover, .dropdown-select:hover, .dropdown-visible .dropdown-select,
.dropdown-visible .dropdown-select:hover, .nojs .dropdown-container:hover .dropdown-select {
.button:hover, .dropdown-visible .dropdown-select, .nojs .dropdown-container:hover .dropdown-select {
border-color: #0a8ed0;
background-image: -moz-linear-gradient(top, #E9E9E9, #FFFFFF);
background-image: -webkit-linear-gradient(top, #E9E9E9, #FFFFFF);
@ -701,26 +691,16 @@ Colours and backgrounds for buttons.css
text-shadow: 1px 1px 0 #FFFFFF, -1px -1px 0 #FFFFFF, -1px -1px 0 rgba(188, 42, 77, 0.2);
}
.dropdown-select:hover {
border-color: #C7C3BF;
}
.dropdown-select:after { border-color: #DADADA; }
.dropdown-select:hover { border-color: #C7C3BF; }
.dropdown-visible .dropdown-select, .dropdown-visible .dropdown-select:hover, .nojs .dropdown-container:hover .dropdown-select {
border-color: #A6B2BA;
color: #105289 !important;
color: #105289;
}
.buttons div a:after, .dropdown-select-icon:before, .dropdown-select:after {
background-image: url("images/buttons.png");
}
.contact-icons a {
border-color: #DCDCDC;
}
.contact-icons a:hover {
background-color: #F2F6F9;
}
.contact-icons a { border-color: #DCDCDC; }
.contact-icons a:hover { background-color: #F2F6F9; }
/* Icon images
---------------------------------------- */
@ -744,17 +724,8 @@ Colours and backgrounds for buttons.css
.icon-print { background-image: url("./images/icon_print.gif"); }
/* Profile & navigation icons */
.contact-icon { background-image: url("./images/icons_contact.png"); }
.quote-icon, .quote-icon a { background-image: url("./en/icon_post_quote.gif"); }
ul.profile-icons.responsive a.responsive-menu-link { background-image: url("./images/icon_post_menu.png"); }
/* Moderator icons */
.report-icon, .report-icon a { background-image: url("./images/icon_post_report.gif"); }
.edit-icon, .edit-icon a { background-image: url("./en/icon_post_edit.gif"); }
.delete-icon, .delete-icon a { background-image: url("./images/icon_post_delete.gif"); }
.info-icon, .info-icon a { background-image: url("./images/icon_post_info.gif"); }
.warn-icon, .warn-icon a { background-image: url("./images/icon_user_warn.gif"); } /* Need updated warn icon */
.contact-icon { background-image: url("./images/icons_contact.png"); }
.icon-button:before, .dropdown-select:after { background-image: url("./images/icons_button.png"); }
/* Forum icons & Topic icons */
.global_read { background-image: url("./images/announce_read.gif"); }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,26 +1,6 @@
/* Set profile icon dimensions */
ul.profile-icons li.pm-icon { width: 28px; height: 20px; }
ul.profile-icons li.quote-icon { width: 54px; height: 20px; }
ul.profile-icons li.edit-icon { width: 42px; height: 20px; }
/* Online image */
.online { background-image: url("./icon_user_online.gif"); }
/* Icon images */
.quote-icon, .quote-icon a { background-image: url("./icon_post_quote.gif"); }
.edit-icon, .edit-icon a { background-image: url("./icon_post_edit.gif"); }
/* EN Language Pack */
.imageset.icon_post_edit {
background-image: url("./icon_post_edit.gif");
padding-left: 42px;
padding-top: 20px;
}
.imageset.icon_post_quote {
background-image: url("./icon_post_quote.gif");
padding-left: 54px;
padding-top: 20px;
}
.imageset.icon_user_online {
background-image: url("./icon_user_online.gif");
padding-left: 58px;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -369,16 +369,6 @@ span.imageset {
/* English images for fallback */
.imageset.icon_post_edit {
background-image: url("./en/icon_post_edit.gif");
padding-left: 42px;
padding-top: 20px;
}
.imageset.icon_post_quote {
background-image: url("./en/icon_post_quote.gif");
padding-left: 54px;
padding-top: 20px;
}
.imageset.icon_user_online {
background-image: url("./en/icon_user_online.gif");
padding-left: 58px;

View File

@ -423,10 +423,6 @@ fieldset.polls dd.resultbar, fieldset.polls dd.poll_option_percent {
margin: 0;
}
.postprofile ul.profile-icons {
display: none;
}
.postprofile .avatar {
display: block;
float: left;

View File

@ -13,8 +13,8 @@
class phpbb_config_db_text_test extends phpbb_database_test_case
{
private $db;
private $config_text;
/** @var \phpbb\config\db_text */
protected $config_text;
public function getDataSet()
{
@ -52,6 +52,12 @@ class phpbb_config_db_text_test extends phpbb_database_test_case
$this->assertSame('24', $this->config_text->get('foo'));
}
public function test_set_same_value_get()
{
$this->config_text->set('foo', '23');
$this->assertSame('23', $this->config_text->get('foo'));
}
public function test_set_get_long_string()
{
$expected = str_repeat('ABC', 10000);
@ -93,6 +99,8 @@ class phpbb_config_db_text_test extends phpbb_database_test_case
'baby' => 'phpBB',
// Entry update
'bar' => '64',
// Entry update - same value
'foo' => '23',
);
$this->config_text->set_array($set_array_param);

View File

@ -0,0 +1,64 @@
<?php
/**
*
* @package testing
* @copyright (c) 2014 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
class phpbb_dbal_sql_affected_rows_test extends phpbb_database_test_case
{
/** @var \phpbb\db\driver\driver_interface */
protected $db;
public function setUp()
{
parent::setUp();
$this->db = $this->new_dbal();
}
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/config.xml');
}
public function test_update()
{
$sql = 'UPDATE ' . CONFIG_TABLE . "
SET config_value = 'bertie'";
$this->db->sql_query($sql);
$this->assertEquals(2, $this->db->sql_affectedrows());
}
public function test_update_all_matched_unequal_updated()
{
$sql = 'UPDATE ' . CONFIG_TABLE . "
SET config_value = 'foo'";
$this->db->sql_query($sql);
$this->assertEquals(2, $this->db->sql_affectedrows());
}
public function test_update_same_value_matched_unequal_updated()
{
$sql = 'UPDATE ' . CONFIG_TABLE . "
SET config_value = 'foo'
WHERE config_value = 'foo'";
$this->db->sql_query($sql);
$this->assertEquals(1, $this->db->sql_affectedrows());
}
public function test_insert()
{
$sql = 'INSERT INTO ' . CONFIG_TABLE . ' ' . $this->db->sql_build_array('INSERT', array(
'config_name' => 'bertie',
'config_value' => 'rules',
));
$this->db->sql_query($sql);
$this->assertEquals(1, $this->db->sql_affectedrows());
}
}

View File

@ -33,10 +33,6 @@ then
# Upgrade to a recent stable version of HHVM
sudo apt-get -o Dpkg::Options::="--force-confnew" install -y hhvm-nightly
# MySQLi is broken in HHVM 3.0.0~precise and still does not work for us in
# 2014.03.28~saucy, i.e. needs more work. Use MySQL extension for now.
sed -i "s/mysqli/mysql/" "$DIR/phpunit-mysql-travis.xml"
HHVM_LOG=$(realpath "$DIR")/hhvm.log
sudo hhvm \