Dvz shoutbox na podstronie

Błąd   Założony przez  Szogi1910.

wersja skryptu MyBB:1.8.5
adres forum:www.project-games.eu
na czym polega problem (screen, opis, komunikaty, nazwa i wersja wtyczki):

Mam problem z dvz_shoutboxem na podstronie po jego aktualizacji mianowicie po dodaniu hooka do pluginu dostaję błąd na podstronie

$plugins->add_hook('shoutbox_start', ['dvz_shoutbox''dvz_shoutbox_big']); // dvz_shoutbox na podstronie 

Zwraca błąd na pod stronie

Warning [2] call_user_func_array() expects parameter 1 to be a valid callback, class 'dvz_shoutbox' does not have a method 'dvz_shoutbox_big' - Line: 133 - File: inc/class_plugins.php PHP 5.6.6 (Linux)
[PHP]           errorHandler->error
/inc/class_plugins.php     133     call_user_func_array
/gamebox.php     6     pluginSystem->run_hooks

plik dvz_shoutbox
<?php
/* by Tomasz 'Devilshakerz' Mlynski [devilshakerz.com]; Copyright (C) 2014-2015
 released under Creative Commons BY-NC-SA 4.0 license: http://creativecommons.org/licenses/by-nc-sa/4.0/ */

$plugins->add_hook('global_start', ['dvz_shoutbox''global_start']);   // cache shoutbox templates
$plugins->add_hook('global_end',   ['dvz_shoutbox''global_end']);    // catch archive page
$plugins->add_hook('xmlhttp',      ['dvz_shoutbox''xmlhttp']);      // xmlhttp.php listening
$plugins->add_hook('shoutbox_start', ['dvz_shoutbox''dvz_shoutbox_big']); // dvz_shoutbox na podstronie 
$plugins->add_hook('index_end',    ['dvz_shoutbox''load_window']); // load Shoutbox window to {$dvz_shoutbox} variable



$plugins->add_hook('admin_user_users_merge_commit', ['dvz_shoutbox''user_merge']);

$plugins->add_hook('fetch_wol_activity_end', ['dvz_shoutbox''activity']); // catch activity
$plugins->add_hook('build_friendly_wol_location_end', ['dvz_shoutbox''activity_translate']); // translate activity

$plugins->add_hook('misc_clearcookies', ['dvz_shoutbox''clearcookies']);

function 
dvz_shoutbox_info ()
{
    return [
        
'name'          => 'DVZ Shoutbox',
        
'description'   => 'Lightweight AJAX chat.',
        
'website'       => 'http://devilshakerz.com/',
        
'author'        => 'Tomasz \'Devilshakerz\' Mlynski',
        
'authorsite'    => 'http://devilshakerz.com/',
        
'version'       => '2.2',
        
'codename'      => 'dvz_shoutbox',
        
'compatibility' => '18*',
    ];
}

function 
dvz_shoutbox_install ()
{
    global 
$db;

    
// table
    
$db->write_query("
        CREATE TABLE IF NOT EXISTS `" 
TABLE_PREFIX "dvz_shoutbox` (
            `id` int(11) NOT NULL auto_increment,
            `uid` int(11) NOT NULL,
            `text` text NULL,
            `date` int(11) NOT NULL,
            `modified` int(11) NULL DEFAULT NULL,
            `ipaddress` varbinary(16) NOT NULL,
            PRIMARY KEY (`id`)
        ) ENGINE=InnoDB " 
$db->build_create_table_collation() . "
    "
);

    
// example shout
    
$db->insert_query('dvz_shoutbox', [
        
'uid'       => 1,
        
'text'      => 'DVZ Shoutbox!',
        
'date'      => TIME_NOW,
        
'ipaddress' => my_inet_pton('127.0.0.1'),
    ]);

    
// settings
    
$settingGroupId $db->insert_query('settinggroups', [
        
'name'        => 'dvz_shoutbox',
        
'title'       => 'DVZ Shoutbox',
        
'description' => 'Settings for DVZ Shoutbox.',
    ]);

    
$settings = [
        [
            
'name'        => 'dvz_sb_num',
            
'title'       => 'Shouts to display',
            
'description' => 'Number of shouts to be displayed in the Shoutbox window.',
            
'optionscode' => 'numeric',
            
'value'       => '20',
        ],
        [
            
'name'        => 'dvz_sb_num_archive',
            
'title'       => 'Shouts to display on archive',
            
'description' => 'Number of shouts to be displayed per page on Archive view.',
            
'optionscode' => 'numeric',
            
'value'       => '20',
        ],
        [
            
'name'        => 'dvz_sb_reversed',
            
'title'       => 'Reversed order',
            
'description' => 'Reverses the shouts display order in the Shoutbox window so that new ones appear on the bottom. You may also want to move the <b>{$panel}</b> variable below the  window in the <i>dvz_shoutbox</i> template.',
            
'optionscode' => 'yesno',
            
'value'       => '0',
        ],
        [
            
'name'        => 'dvz_sb_height',
            
'title'       => 'Shoutbox height',
            
'description' => 'Height of the Shoutbox window in pixels.',
            
'optionscode' => 'numeric',
            
'value'       => '160',
        ],
        [
            
'name'        => 'dvz_sb_dateformat',
            
'title'       => 'Date format',
            
'description' => 'Format of the date displayed. This format uses the PHP\'s <a href="http://php.net/manual/en/function.date.php#refsect1-function.date-parameters">date() function syntax</a>.',
            
'optionscode' => 'text',
            
'value'       => 'd M H:i',
        ],
        [
            
'name'        => 'dvz_sb_maxlength',
            
'title'       => 'Maximum message length',
            
'description' => 'Set 0 to disable the limit.',
            
'optionscode' => 'numeric',
            
'value'       => '0',
        ],
        [
            
'name'        => 'dvz_sb_mycode',
            
'title'       => 'Parse MyCode',
            
'description' => '',
            
'optionscode' => 'yesno',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_smilies',
            
'title'       => 'Parse smilies',
            
'description' => '',
            
'optionscode' => 'yesno',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_interval',
            
'title'       => 'Refresh interval',
            
'description' => 'Number of seconds between Shoutbox updates (lower values provide better synchronization but cause higher server load). Set 0 to disable the auto-refreshing feature.',
            
'optionscode' => 'numeric',
            
'value'       => '5',
        ],
        [
            
'name'        => 'dvz_sb_away',
            
'title'       => 'Away mode',
            
'description' => 'Number of seconds after last user action (e.g. click) after which shoutbox will be minimized to prevent unnecessary usage of server resources. Set 0 to disable this feature.',
            
'optionscode' => 'numeric',
            
'value'       => '600',
        ],
        [
            
'name'        => 'dvz_sb_antiflood',
            
'title'       => 'Anti-flood interval',
            
'description' => 'Forces a minimum number of seconds to last between user\'s shouts (this does not apply to Shoutbox moderators).',
            
'optionscode' => 'numeric',
            
'value'       => '5',
        ],
        [
            
'name'        => 'dvz_sb_sync',
            
'title'       => 'Moderation synchronization',
            
'description' => 'Applies moderation actions without refreshing the Shoutbox window page.',
            
'optionscode' => 'onoff',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_lazyload',
            
'title'       => 'Lazy load',
            
'description' => 'Start loading data only when the Shoutbox window is actually being displayed on the screen (the page is scrolled to the Shoutbox position).',
            
'optionscode' => 'select
off=Disabled
start=Check if on display to start
always=Always check if on display to refresh'
,
            
'value'       => 'off',
        ],
        [
            
'name'        => 'dvz_sb_status',
            
'title'       => 'Shoutbox default status',
            
'description' => 'Choose whether Shoutbox window should be expanded or collapsed by default.',
            
'optionscode' => 'onoff',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_minposts',
            
'title'       => 'Minimum posts required to shout',
            
'description' => 'Set 0 to allow everyone.',
            
'optionscode' => 'numeric',
            
'value'       => '0',
        ],
        [
            
'name'        => 'dvz_sb_groups_view',
            
'title'       => 'Group permissions: View',
            
'description' => 'User groups that can view Shoutbox.',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_refresh',
            
'title'       => 'Group permissions: Auto-refresh',
            
'description' => 'User groups that shoutbox will be refreshing for.',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_shout',
            
'title'       => 'Group permissions: Shout',
            
'description' => 'User groups that can post shouts in Shoutbox (logged in users only).',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_recall',
            
'title'       => 'Group permissions: Scroll back to show past shouts',
            
'description' => 'User groups that shoutbox will load previous posts when scrolling back for.',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_mod',
            
'title'       => 'Group permissions: Moderation',
            
'description' => 'User groups that can moderate the Shoutbox (edit and delete shouts).',
            
'optionscode' => 'groupselect',
            
'value'       => '',
        ],
        [
            
'name'        => 'dvz_sb_groups_mod_own',
            
'title'       => 'Group permissions: Moderation of own shouts',
            
'description' => 'Users groups whose members can edit and delete their own shouts.',
            
'optionscode' => 'groupselect',
            
'value'       => '',
        ],
        [
            
'name'        => 'dvz_sb_supermods',
            
'title'       => 'Super moderators are Shoutbox moderators',
            
'description' => 'Automatically allow forum super moderators to moderate Shoutbox as well.',
            
'optionscode' => 'yesno',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_blocked_users',
            
'title'       => 'Banned users',
            
'description' => 'Comma-separated list of user IDs that are banned from posting messages.',
            
'optionscode' => 'textarea',
            
'value'       => '',
        ],
    ];

    
$i 1;

    foreach (
$settings as &$row) {
        
$row['gid']         = $settingGroupId;
        
$row['title']       = $db->escape_string($row['title']);
        
$row['description'] = $db->escape_string($row['description']);
        
$row['disporder']   = $i++;
    }

    
$db->insert_query_multiple('settings'$settings);

    
rebuild_settings();

    
// templates
    
$templates = [
        
'dvz_shoutbox_panel' => '<div class="panel">
<form>
<input type="text" class="text" placeholder="{$lang->dvz_sb_default}" maxlength="{$maxlength}" autocomplete="off" />
<input type="submit" style="display:none" />
</form>
</div>'
,

        
'dvz_shoutbox' => '<div id="shoutbox" class="front{$classes}">

<div class="head">
<strong>{$lang->dvz_sb_shoutbox}</strong>
<p class="right"><a href="{$mybb->settings[\'bburl\']}/index.php?action=shoutbox_archive">&laquo; {$lang->dvz_sb_archivelink}</a></p>
</div>

<div class="body">

{$panel}

<div class="window" style="height:{$mybb->settings[\'dvz_sb_height\']}px">
<div class="data">
{$html}
</div>
</div>

</div>

<script type="text/javascript" src="{$mybb->settings[\'bburl\']}/jscripts/dvz_shoutbox.js"></script>
{$javascript}

</div>'
,

        
'dvz_shoutbox_archive' => '<html>
<head>
<title>{$lang->dvz_sb_archive}</title>
{$headerinclude}
</head>
<body>
{$header}

<script type="text/javascript" src="{$mybb->settings[\'bburl\']}/jscripts/dvz_shoutbox.js"></script>
{$javascript}

{$modoptions}

{$multipage}

<br />

<div id="shoutbox">

<div class="head"><strong>{$lang->dvz_sb_archive}</strong></div>

<div class="data">
{$archive}
</div>
</div>

<br />

{$multipage}

{$footer}
</body>
</html>'
,

        
'dvz_shoutbox_archive_modoptions' => '<table border="0" cellspacing="{$theme[\'borderwidth\']}" cellpadding="{$theme[\'tablespace\']}" class="tborder">
<tr><td class="thead" colspan="2"><strong>{$lang->dvz_sb_mod}</strong></td></tr>
<tr><td class="tcat">{$lang->dvz_sb_mod_banlist}</td><td class="tcat">{$lang->dvz_sb_mod_clear}</td></tr>
<tr>
<td class="trow1">
<form action="" method="post">
<input type="text" class="textbox" style="width:80%" name="banlist" value="{$blocked_users}"></textarea>
<input type="hidden" name="postkey" value="{$mybb->post_code}" />
<input type="submit" class="button" value="{$lang->dvz_sb_mod_banlist_button}" />
</form>
</td>
<td class="trow1">
<form action="" method="post">
<select name="days">
<option value="2">2 {$lang->days}</option>
<option value="7">7 {$lang->days}</option>
<option value="30">30 {$lang->days}</option>
<option value="90">90 {$lang->days}</option>
<option value="all">* {$lang->dvz_sb_mod_clear_all} *</option>
</select>
<input type="hidden" name="postkey" value="{$mybb->post_code}" />
<input type="submit" class="button" value="{$lang->dvz_sb_mod_clear_button}" />
</form>
</td>
</tr>
</table>
<br />'
,
    ];

    
$data = [];

    foreach (
$templates as $name => $content) {
        
$data[] = [
            
'title'    => $name,
            
'template' => $db->escape_string($content),
            
'sid'      => -1,
            
'version'  => 1,
            
'status'   => '',
            
'dateline' => TIME_NOW,
        ];
    }

    
$db->insert_query_multiple('templates'$data);
}

function 
dvz_shoutbox_uninstall ()
{
    global 
$db;

    
$settingGroupId $db->fetch_field(
        
$db->simple_select('settinggroups''gid'"name='dvz_shoutbox'"),
        
'gid'
    
);

    
// delete settings
    
$db->delete_query('settinggroups''gid=' $settingGroupId);
    
$db->delete_query('settings''gid=' $settingGroupId);

    
rebuild_settings();

    
// delete templates
    
$db->delete_query('templates'"title IN('dvz_shoutbox', 'dvz_shoutbox_panel', 'dvz_shoutbox_archive', 'dvz_shoutbox_archive_modoptions')");

    
// delete data
    
$db->drop_table('dvz_shoutbox');
}

function 
dvz_shoutbox_is_installed ()
{
    global 
$mybb;
    return 
$mybb->settings['dvz_sb_num'] !== null;
}


class 
dvz_shoutbox
{

    
// hooks
    
static function global_start ()
    {
        global 
$mybb$templatelist;

        if (
THIS_SCRIPT == 'index.php' && self::access_view()) {

            if (!empty(
$templatelist)) {
                
$templatelist .= ',';
            }

            if (
$mybb->input['action'] == 'shoutbox_archive') {
                
// archive templates

                
$templatelist .= 'dvz_shoutbox_archive,multipage,multipage_page,multipage_page_current,multipage_nextpage';

                if (
self::access_mod()) {
                    
$templatelist .= ',dvz_shoutbox_archive_modoptions';
                }

            } else {
                
// index templates
                
$templatelist .= 'dvz_shoutbox,dvz_shoutbox_panel';
            }

        }
    }

    static function 
global_end ()
    {
        global 
$mybb;

        if (
$mybb->input['action'] == 'shoutbox_archive' && self::access_view()) {
            return 
self::show_archive();
        }
    }

    static function 
xmlhttp ()
    {
        global 
$mybb$db$charset;

        switch (
$mybb->input['action']) {

            case 
'dvz_sb_get_updates':

                
$permissions = (
                    
self::access_view() &&
                    
self::access_refresh()
                );

                
$handler = function() use ($mybb$db) {

                    
$syncConditions $mybb->settings['dvz_sb_sync']
                        ? 
"OR s.modified >= " . (time() - $mybb->settings['dvz_sb_interval']) . " AND s.id BETWEEN " abs((int)$mybb->input['first']) . " AND " abs((int)$mybb->input['last'])
                        : 
null
                    
;

                    
$data self::get_multiple("WHERE s.id > " abs((int)$mybb->input['last']) . " AND s.text IS NOT NULL " $syncConditions  " ORDER BY s.id DESC LIMIT " abs((int)$mybb->settings['dvz_sb_num']));

                    
$html   null// JS-handled empty response
                    
$sync   = [];
                    
$lastId 0;

                    while (
$row $db->fetch_array($data)) {

                        if (
$row['id'] <= $mybb->input['last']) {
                            
// sync update

                            
$sync$row['id'] ] = $row['text'] === null
                                
null
                                
self::parse($row['text'], $row['username'])
                            ;

                        } else {
                            
// new shout

                            
if ($lastId == 0) {
                                
$lastId $row['id'];
                            }

                            
$shout self::render_shout($row);

                            
$html $mybb->settings['dvz_sb_reversed']
                                ? 
$shout $html
                                
$html  $shout
                            
;

                        }

                    }

                    if (
$html != null || !empty($sync)) {

                        
$response = [];

                        if (
$html != null) {
                            
$response['html'] = $html;
                            
$response['last'] = $lastId;
                        }

                        if (!empty(
$sync)) {
                            
$response['sync'] = $sync;
                        }

                        echo 
json_encode($response);

                    }
                };

                break;

            case 
'dvz_sb_recall':

                
$permissions = (
                    
self::access_view() &&
                    
self::access_refresh() &&
                    
self::access_recall()
                );

                
$handler = function() use ($mybb$db) {

                    
$data self::get_multiple("WHERE s.id < " abs((int)$mybb->input['first']) . " ORDER BY s.id DESC LIMIT " abs((int)$mybb->settings['dvz_sb_num']));

                    
$response = [];

                    
$html null// JS-handled empty response
                    
$firstId 0;

                    while (
$row $db->fetch_array($data)) {

                        
$firstId $row['id'];

                        
$shout self::render_shout($row);

                        
$html $mybb->settings['dvz_sb_reversed']
                            ? 
$shout $html
                            
$html  $shout
                        
;
                    }

                    if (
$html != null) {
                        
$response['html'] = $html;
                    }

                    if (
$db->num_rows($data) < $mybb->settings['dvz_sb_num']) {
                        
$response['end'] = 1;
                    }

                    if (
$response) {
                        
$response['first'] = $firstId;
                    }

                    echo 
json_encode($response);

                };

                break;

            case 
'dvz_sb_shout':

                
$permissions = (
                    
self::access_shout() &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($mybb) {
                    if (!
self::antiflood_pass() && !self::access_mod()) die('A'); // JS-handled error (Anti-flood)

                    
self::shout([
                        
'uid'       => $mybb->user['uid'],
                        
'text'      => $mybb->input['text'],
                        
'ipaddress' => my_inet_pton(get_ip()),
                    ]);
                };

                break;

            case 
'dvz_sb_get':

                
$data self::get($mybb->input['id']);

                
$permissions = (
                    (
                        
self::access_mod() ||
                        (
self::access_mod_own() && $data['uid'] == $mybb->user['uid'])
                    ) &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($data) {
                    echo 
json_encode([
                        
'text' => $data['text'],
                    ]);
                };

                break;

            case 
'dvz_sb_update':

                
$permissions = (
                    
self::can_mod($mybb->input['id']) &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($mybb) {
                    
self::update($mybb->input['id'], $mybb->input['text']);
                    echo 
self::parse($mybb->input['text'], self::get_username($mybb->input['id']));

                };

                break;

            case 
'dvz_sb_delete':

                
$permissions = (
                    
self::can_mod($mybb->input['id']) &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($mybb) {
                    
self::delete($mybb->input['id']);
                };

                break;

        }

        if (isset(
$permissions)) {

            if (
$permissions == false) {
                echo 
'P'// JS-handled error (Permissions)
            
} else {

                
header('Content-type: text/plain; charset=' $charset);
                
header('Cache-Control: no-store'); // force update on load
                
$handler();

            }

        }
    }

    static function 
load_window ()
    {
        global 
$templates$dvz_shoutbox$lang$mybb$db$theme;

        
$lang->load('dvz_shoutbox');

        
// MyBB template
        
$dvz_shoutbox null;

        
// dvz_shoutbox template
        
$javascript   null;
        
$panel        null;
        
$classes      null;

        if (
self::access_view()) {

            if (
self::is_user()) {

                
// message: blocked
                
if (self::is_blocked()) {
                    
$panel '<div class="panel blocked"><p>' $lang->dvz_sb_user_blocked '</p></div>';
                }
                
// message: minimum posts
                
else if (!self::access_minposts() && !self::access_mod()) {
                    
$panel '<div class="panel minposts"><p>' str_replace('{MINPOSTS}', (int)$mybb->settings['dvz_sb_minposts'], $lang->dvz_sb_minposts) . '</p></div>';
                }
                
// shout form
                
else if (self::access_shout()) {
                    
$maxlength $mybb->settings['dvz_sb_maxlength'] ? (int)$mybb->settings['dvz_sb_maxlength'] : null;
                    eval(
'$panel = "' $templates->get('dvz_shoutbox_panel') . '";');
                }

            }

            
$js null;

            
// configuration
            
$js .= 'dvz_shoutbox.interval = ' . (self::access_refresh() ? (float)$mybb->settings['dvz_sb_interval'] : 0) . ';' PHP_EOL;
            
$js .= 'dvz_shoutbox.antiflood = ' . (self::access_mod() ? : (float)$mybb->settings['dvz_sb_antiflood']) . ';' PHP_EOL;
            
$js .= 'dvz_shoutbox.maxShouts = ' . (int)$mybb->settings['dvz_sb_num'] . ';' PHP_EOL;
            
$js .= 'dvz_shoutbox.awayTime = ' . (float)$mybb->settings['dvz_sb_away'] . '*1000;' PHP_EOL;
            
$js .= 'dvz_shoutbox.lang = [\'' $lang->dvz_sb_delete_confirm '\', \'' str_replace('{ANTIFLOOD}', (float)$mybb->settings['dvz_sb_antiflood'], $lang->dvz_sb_antiflood) . '\', \''.$lang->dvz_sb_permissions.'\'];' PHP_EOL;

            
// reversed order
            
if ($mybb->settings['dvz_sb_reversed']) {
                
$js .= 'dvz_shoutbox.reversed = true;' PHP_EOL;
                
$js .= '$(\'#shoutbox .window\').scrollTop( $(\'#shoutbox .window\')[0].scrollHeight );' PHP_EOL;
            }

            
// lazyload
            
if ($mybb->settings['dvz_sb_lazyload']) {
                
$js .= 'dvz_shoutbox.lazyMode = \'' . (int)$mybb->settings['dvz_sb_lazyload'] . '\';' PHP_EOL;
                
$js .= '$(window).bind(\'scroll resize\', dvz_shoutbox.checkVisibility);' PHP_EOL;
            }

            
// away mode
            
if ($mybb->settings['dvz_sb_away']) {
                
$js .= '$(window).on(\'mousemove click dblclick keydown scroll\', dvz_shoutbox.updateActivity);' PHP_EOL;
            }

            
// shoutbox status
            
$status = isset($_COOKIE['dvz_sb_status'])
                ? (bool)
$_COOKIE['dvz_sb_status']
                : (bool)
$mybb->settings['dvz_sb_status']
            ;

            
$js .= 'dvz_shoutbox.status = ' . (int)$status ';' PHP_EOL;

            if (
$status == false) {
                
$classes .= ' collapsed';
            }

            
// preloaded shouts
            
$data self::get_multiple("WHERE s.text IS NOT NULL ORDER BY s.id DESC LIMIT " abs((int)$mybb->settings['dvz_sb_num']));

            
$html null;
            
$firstId 0;
            
$lastId 0;

            while (
$row $db->fetch_array($data)) {

                
$firstId $row['id'];

                if (
$lastId == 0) {
                    
$lastId $row['id'];
                }

                
$shout self::render_shout($row);

                
$html  $mybb->settings['dvz_sb_reversed']
                    ? 
$shout $html
                    
$html  $shout
                
;
            }

            if (
self::access_refresh()) {
                
$js .= 'setTimeout(\'dvz_shoutbox.loop()\', ' . (float)$mybb->settings['dvz_sb_interval'] . ' * 1000);' PHP_EOL;
            }

            if (
self::access_recall()) {
                
$js .= 'dvz_shoutbox.recalling = true;' PHP_EOL;
            }

            
$javascript '
<script>
$js '
dvz_shoutbox.firstId = ' 
$firstId ';
dvz_shoutbox.lastId = ' 
$lastId ';
dvz_shoutbox.appendControls();
dvz_shoutbox.updateActivity();
</script>'
;

            eval(
'$dvz_shoutbox = "' $templates->get('dvz_shoutbox') . '";');

        }
    }

    static function 
show_archive ()
    {
        global 
$db$mybb$templates$lang$theme$footer$headerinclude$header$charset;

        
$lang->load('dvz_shoutbox');

        
header('Content-type: text/html; charset=' $charset);

        
add_breadcrumb($lang->dvz_sb_shoutbox"index.php?action=shoutbox_archive");

        
// moderation panel
        
if (self::access_mod()) {

            if (isset(
$mybb->input['banlist']) && verify_post_check($mybb->input['postkey'])) {
                
self::banlist_update($mybb->input['banlist']);
            }

            if (isset(
$mybb->input['days']) && verify_post_check($mybb->input['postkey'])) {
                if (
$mybb->input['days'] == 'all') {
                    
self::clear();
                } else {
                    
$allowed = [273090];
                    if (
in_array($mybb->input['days'], $allowed)) {
                        
self::clear($mybb->input['days']);
                    }
                }
            }

            
$blocked_users htmlspecialchars_uni($mybb->settings['dvz_sb_blocked_users']);
            eval(
'$modoptions = "' $templates->get("dvz_shoutbox_archive_modoptions") . '";');

        } else {
            
$modoptions null;
        }

        
// pagination
        
$items   self::count();
        
$page    abs((int)$mybb->input['page']);
        
$perPage abs((int)$mybb->settings['dvz_sb_num_archive']);

        if (
$perPage == 0) {
            
$pages 0;
        } else {
            
$pages   ceil($items $perPage);
        }

        if (!
$page || $page || $page $pages$page 1;

        
$start = ($page 1) * $perPage;

        if (
$items $perPage) {
            
$multipage multipage($items$perPage$page'index.php?action=shoutbox_archive');
        }


        
$data self::get_multiple("WHERE s.text IS NOT NULL ORDER by s.id DESC LIMIT $start,$perPage");

        
$archive null;

        while (
$row $db->fetch_array($data)) {
            
$archive .= self::render_shout($rowtrue);
        }

        
$javascript '
<script>
dvz_shoutbox.lang = [\'' 
$lang->dvz_sb_delete_confirm '\', \'' str_replace('{ANTIFLOOD}', (float)$mybb->settings['dvz_sb_antiflood'], $lang->dvz_sb_antiflood) . '\', \'' $lang->dvz_sb_permissions '\'];
</script>'
;

        eval(
'$content = "' $templates->get("dvz_shoutbox_archive") . '";');

        
output_page($content);

        exit;
    }

    static function 
user_merge ()
    {
        global 
$db$source_user$destination_user;
        return 
$db->update_query('dvz_shoutbox', ['uid' => $destination_user['uid']], 'uid=' . (int)$source_user['uid']);
    }

    static function 
activity (&$user_activity)
    {
        
$location parse_url($user_activity['location']);
        
$filename basename($location['path']);

        
parse_str(html_entity_decode($location['query']), $parameters);

        if (
$filename == 'index.php' && $parameters['action'] == 'shoutbox_archive') {
            
$user_activity['activity'] = 'dvz_shoutbox_archive';
        }
    }

    static function 
activity_translate (&$data)
    {
        global 
$lang;

        
$lang->load('dvz_shoutbox');

        if (
$data['user_activity']['activity'] == 'dvz_shoutbox_archive') {
            
$data['location_name'] = sprintf($lang->dvz_sb_activity'index.php?action=shoutbox_archive');
        }
    }

    static function 
clearcookies ()
    {
        global 
$remove_cookies;
        
$remove_cookies[] = 'dvz_sb_status';
    }

    
// data manipulation
    
static function get ($id)
    {
        global 
$db;
        return 
$db->fetch_array$db->simple_select('dvz_shoutbox''*''id=' . (int)$id) );
    }

    static function 
get_multiple ($clauses)
    {
        global 
$db;
        return 
$db->query("
            SELECT
                s.*, u.username, u.usergroup, u.displaygroup, u.avatar
            FROM
                " 
TABLE_PREFIX "dvz_shoutbox s
                LEFT JOIN " 
TABLE_PREFIX "users u ON u.uid = s.uid
            " 
$clauses "
        "
);
    }

    static function 
get_username ($id)
    {
        global 
$db;
        return 
$db->fetch_field(
            
$db->query("SELECT username FROM " TABLE_PREFIX "users u, " TABLE_PREFIX "dvz_shoutbox s WHERE u.uid=s.uid AND s.id=" . (int)$id),
            
'username'
        
);
    }

    static function 
user_last_shout_time ($uid)
    {
        global 
$db;
        return 
$db->fetch_field(
            
$db->simple_select('dvz_shoutbox''date''uid=' . (int)$uid, [
                
'order_by'  => 'date',
                
'order_dir' => 'desc',
                
'limit'     => 1,
            ]),
            
'date'
        
);
    }

    static function 
count ()
    {
        global 
$db;
        return 
$db->fetch_field(
            
$db->simple_select('dvz_shoutbox''COUNT(*) as n'),
            
'n'
        
);
    }

    static function 
shout ($data)
    {
        global 
$mybb$db;

        if (
$mybb->settings['dvz_sb_maxlength'] > 0) {
            
$data['text'] = mb_substr($data['text'], 0$mybb->settings['dvz_sb_maxlength']);
        }

        foreach (
$data as &$item) {
            
$item $db->escape_string($item);
        }

        
$data['date'] = TIME_NOW;

        return 
$db->insert_query('dvz_shoutbox'$data);
    }

    static function 
update ($id$text)
    {
        global 
$db;
        return 
$db->update_query('dvz_shoutbox', [
            
'text'     => $db->escape_string($text),
            
'modified' => time(),
        ], 
'id=' . (int)$id);
    }

    static function 
banlist_update ($new)
    {
        global 
$db;

        
$db->update_query('settings', ['value' => $db->escape_string($new)], "name='dvz_sb_blocked_users'");

        
rebuild_settings();
    }

    static function 
delete ($id)
    {
        global 
$mybb$db;

        if (
$mybb->settings['dvz_sb_sync']) {
            return 
$db->update_query('dvz_shoutbox', [
                
'text'     => 'NULL',
                
'modified' => time(),
            ], 
'id=' . (int)$idfalsetrue);
        } else {
            return 
$db->delete_query('dvz_shoutbox''id=' . (int)$id);
        }
    }

    static function 
clear ($days false)
    {
        global 
$db;

        if (
$days) {
            
$where 'date < ' . ( TIME_NOW - ((int)$days 86400) );
        } else {
            
$where false;
        }

        return 
$db->delete_query('dvz_shoutbox'$where);
    }

    
// permissions
    
static function is_user ()
    {
        global 
$mybb;
        return 
$mybb->user['uid'] != 0;
    }

    static function 
is_blocked ()
    {
        global 
$mybb;
        return 
in_array($mybb->user['uid'], self::settings_get_csv('blocked_users'));
    }

    static function 
access_view ()
    {
        
$array self::settings_get_csv('groups_view');
        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_refresh ()
    {
        
$array self::settings_get_csv('groups_refresh');
        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_shout ()
    {
        
$array self::settings_get_csv('groups_shout');

        return (
            
self::is_user() &&
            !
self::is_blocked() &&
            (
                
self::access_mod() ||
                (
                    
self::access_view() &&
                    
self::access_minposts() &&
                    
$array[0] == -|| is_member($array)
                )
            )
        );
    }

    static function 
access_recall ()
    {
        
$array self::settings_get_csv('groups_recall');
        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_mod ()
    {
        global 
$mybb;

        
$array self::settings_get_csv('groups_mod');

        return (
            (
$array[0] == -|| is_member($array)) ||
            (
$mybb->settings['dvz_sb_supermods'] && $mybb->usergroup['issupermod'])
        );
    }

    static function 
access_mod_own ()
    {
        
$array self::settings_get_csv('groups_mod_own');

        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_minposts ()
    {
        global 
$mybb;
        return 
$mybb->user['postnum'] >= $mybb->settings['dvz_sb_minposts'];
    }

    static function 
can_mod ($shoutId)
    {
        global 
$mybb;

        if (
self::access_mod()) {
            return 
true;
        } else if (
self::access_mod_own() && self::access_shout()) {

            
$data self::get($shoutId);

            if (
$data['uid'] == $mybb->user['uid']) {
                return 
true;
            }

        }

        return 
false;

    }

    
// core
    
static function render_shout ($data$static false)
    {
        global 
$mybb;

        
$id       $data['id'];
        
$text     self::parse($data['text'], $data['username']);
        
$date     htmlspecialchars_uni(my_date($mybb->settings['dvz_sb_dateformat'], $data['date']));
        
$username htmlspecialchars_uni($data['username']);
        
$user     '<a href="member.php?action=profile&uid=' . (int)$data['uid'] . '">' format_name($username$data['usergroup'], $data['displaygroup']) . '</a>';
        
$avatar   '<img src="' . (empty($data['avatar']) ? htmlspecialchars_uni($mybb->settings['useravatar']) : htmlspecialchars_uni($data['avatar'])) . '" alt="avatar" />';

        
$notes      null;
        
$attributes null;

        
$own $data['uid'] == $mybb->user['uid'];

        if (
$static) {

            if (
self::access_mod()) {
                
$notes .= '<span class="ip">' my_inet_ntop($data['ipaddress']) . '</span>';
            }

            if (
                
self::access_mod() ||
                (
self::access_mod_own() && $own)
            ) {
                
$notes .= '<a href="" class="mod edit">E</a><a href="" class="mod del">X</a>';
            }

        }

        if (
            
self::access_mod() ||
            (
self::access_mod_own() && $own)
        ) {
            
$attributes .= ' data-mod';
        }

        if (
$own) {
            
$attributes .= ' data-own';
        }

        if(
$mybb->user['ignorelist'] != ''
    {
    
$ignlist explode(","$mybb->user['ignorelist']);
    if(!empty(
$ignlist) && in_array($data['uid'], $ignlisttrue)) 
        {
        
$text '<span style="font-style: italic; font-size: 0.85em;">' self::parse('Użytkownik jest przez ciebie ignorowany.'$data['username']) . '</span>';
        }
    } 

        return 
'
<div class="entry" data-id="' 
$id '" data-username="' $username '"' $attributes '>
    <div class="avatar">' 
$avatar '</div>
    <div class="user">' 
$user '</div>
    <div class="text">' 
$text '</div>
    <div class="info">' 
$notes '<span class="date">' $date '</span></div>
</div>'
;
    }

    static function 
parse ($message$me_username)
    {
        global 
$mybb;

        require_once 
MYBB_ROOT 'inc/class_parser.php';

        
$parser = new postParser;
        
$options = [
            
'allow_mycode'    => $mybb->settings['dvz_sb_mycode'],
            
'allow_smilies'   => $mybb->settings['dvz_sb_smilies'],
            
'allow_imgcode'   => 0,
            
'filter_badwords' => 1,
            
'me_username'     => $me_username,
        ];

        return 
$parser->parse_message($message$options);
    }

    static function 
antiflood_pass ()
    {
        global 
$mybb;
        return (
            !
$mybb->settings['dvz_sb_antiflood'] ||
            ( 
TIME_NOW self::user_last_shout_time($mybb->user['uid']) ) > $mybb->settings['dvz_sb_antiflood']
        );
    }

    static function 
settings_get_csv ($name)
    {
        global 
$mybb;
        return 
array_filterexplode(','$mybb->settings['dvz_sb_' $name]) );
    }



plik gamebox.php

<?php
define
('IN_MYBB'1); 
require 
"./global.php"

add_breadcrumb(" GameBox""shoutbox.php");
$plugins->run_hooks("shoutbox_start");

eval(
"\$podstr = \"".$templates->get("dvz_shoutbox_big")."\";");

$plugins->run_hooks("shoutbox_end");
output_page($podstr); 
?>

Szablon dvz_shoutbox_big
<html>
<
head>
{
$headerinclude}
<
title>Project-games.eu Shoutbox!</title>
 
</
head>
<
body>
{
$header}
{
$serversboard_index}

{
$dvz_shoutbox_big}
<
div class="tcat border_forum" style="text-align: center;"><span title="Ilość Twoich wpisów na shoutboxie: {$our_shouts}class="tipTip" style="margin-right: 15px;">Twoje wpisy: <span class="button_summation" style="background-color: #191919;margin-right: 10px;">{$our_shouts}</span></span>
<
span title="Ilość wszystkich wpisów na shoutboxie: {$wpisy}class="tipTip" style="margin-right: 15px;">Wszystkich wpisów: <span class="button_summation" style="background-color: #191919;margin-right: 10px;">{$wpisy}</span></span>
<
span title="Największy spamer na shoutboxie: {$top_spamer_noformatted}class="tipTip">Największy spamer: <span class="button_summation" style="background-color: #191919;margin-right: 10px;">{$top_spamer} ({$shouts})</span></span>
</
div><br />

<
strong>Kto jest online na shoutboxie?</strong> (<a href="/online.php">Szczegóły</a>)<br />
{
$users_online_oużytkowników aktywnych w ciągu ostatnich 15 minut: {$users_onlinezarejestrowanych (w tym 0 niewidocznychoraz {$guests_onlinegości.<br />
{
$onlinemembers}
<
br /> <br />

{
$footer}
</
body>
</
html>{$myalerts_js}{$myalerts_modal

Szablon dvz_shoutbox_shout_big
<div id="shoutbox">
  <
table border="0" cellspacing="{$theme['borderwidth']}cellpadding="{$theme['tablespace']}class="tborder" id="shoutbox">
    <
thead>
      <
tr>
        <
td class="thead" colspan="5">
          <
font color="#fff"><a href="/gamebox.php" style="color: #fff;">GameBox</a> <a href="/index.php?action=shoutbox_archive"><i style="font-size: 14px;" class="fa fa-trash-o fa-fw"></i></a></font>
        </
td>
      </
tr>
    </
thead>
  </
table>

    <
table border="0" cellspacing="{$theme['borderwidth']}cellpadding="{$theme['tablespace']}class="tborder">
        <
tr>
            <
td id="ogloszenie_sb_green">
                
Zanim skorzystasz z shoutboxa przeczytaj <a href="http://gamesing.pl/showthread.php?tid=6">REGULAMIN</a>!
            </
td>
          </
tr>
        <
tr>
          <
td class="trow1">
            <
div class="window" style="height: 400px">
              <
div class="data"></div>
            </
div>
          </
td>
        </
tr>
        <
tr>
          <
td class="trow1">
              {
$panel}
          </
td>
        </
tr>
    </
table>
</
div>

<
script type="text/javascript" src="{$mybb->settings['bburl']}/jscripts/dvz_shoutbox.js"></script>
{
$javascript}{$myalerts_js}{$myalerts_modal
do pliki pluginu shoutboxa dodajesz tylko hook, nic więcej

+ szablon

<html>
<head>
{$headerinclude}
<title>Project-games.eu - Shoutbox!</title>

</head>
<body>
{$header}
{$serversboard_index}

{$dvz_shoutbox}
<div class="tcat border_forum" style="text-align: center;"><span title="Ilość Twoich wpisów na shoutboxie: {$our_shouts}" class="tipTip" style="margin-right: 15px;">Twoje wpisy: <span class="button_summation" style="background-color: #191919;margin-right: 10px;">{$our_shouts}</span></span>
<span title="Ilość wszystkich wpisów na shoutboxie: {$wpisy}" class="tipTip" style="margin-right: 15px;">Wszystkich wpisów: <span class="button_summation" style="background-color: #191919;margin-right: 10px;">{$wpisy}</span></span>
<span title="Największy spamer na shoutboxie: {$top_spamer_noformatted}" class="tipTip">Największy spamer: <span class="button_summation" style="background-color: #191919;margin-right: 10px;">{$top_spamer} ({$shouts})</span></span>
</div><br />

<strong>Kto jest online na shoutboxie?</strong> (<a href="/online.php">Szczegóły</a>)<br />
{$users_online_o} użytkowników aktywnych w ciągu ostatnich 15 minut: {$users_online} zarejestrowanych (w tym 0 niewidocznych) oraz {$guests_online} gości.<br />
{$onlinemembers}
<br /> <br />

{$footer}
</body>
</html>{$myalerts_js}{$myalerts_modal}

<?php
/* by Tomasz 'Devilshakerz' Mlynski [devilshakerz.com]; Copyright (C) 2014-2015
 released under Creative Commons BY-NC-SA 4.0 license: http://creativecommons.org/licenses/by-nc-sa/4.0/ */

$plugins->add_hook('global_start', ['dvz_shoutbox''global_start']);   // cache shoutbox templates
$plugins->add_hook('global_end',   ['dvz_shoutbox''global_end']);    // catch archive page
$plugins->add_hook('xmlhttp',      ['dvz_shoutbox''xmlhttp']);      // xmlhttp.php listening
$plugins->add_hook('index_end',    ['dvz_shoutbox''load_window']); // load Shoutbox window to {$dvz_shoutbox} variable
$plugins->add_hook('shoutbox_start', ['dvz_shoutbox''load_window']); // dvz_shoutbox na podstronie 


$plugins->add_hook('admin_user_users_merge_commit', ['dvz_shoutbox''user_merge']);

$plugins->add_hook('fetch_wol_activity_end', ['dvz_shoutbox''activity']); // catch activity
$plugins->add_hook('build_friendly_wol_location_end', ['dvz_shoutbox''activity_translate']); // translate activity

$plugins->add_hook('misc_clearcookies', ['dvz_shoutbox''clearcookies']);

function 
dvz_shoutbox_info ()
{
    return [
        
'name'          => 'DVZ Shoutbox',
        
'description'   => 'Lightweight AJAX chat.',
        
'website'       => 'http://devilshakerz.com/',
        
'author'        => 'Tomasz \'Devilshakerz\' Mlynski',
        
'authorsite'    => 'http://devilshakerz.com/',
        
'version'       => '2.2',
        
'codename'      => 'dvz_shoutbox',
        
'compatibility' => '18*',
    ];
}

function 
dvz_shoutbox_install ()
{
    global 
$db;

    
// table
    
$db->write_query("
        CREATE TABLE IF NOT EXISTS `" 
TABLE_PREFIX "dvz_shoutbox` (
            `id` int(11) NOT NULL auto_increment,
            `uid` int(11) NOT NULL,
            `text` text NULL,
            `date` int(11) NOT NULL,
            `modified` int(11) NULL DEFAULT NULL,
            `ipaddress` varbinary(16) NOT NULL,
            PRIMARY KEY (`id`)
        ) ENGINE=InnoDB " 
$db->build_create_table_collation() . "
    "
);

    
// example shout
    
$db->insert_query('dvz_shoutbox', [
        
'uid'       => 1,
        
'text'      => 'DVZ Shoutbox!',
        
'date'      => TIME_NOW,
        
'ipaddress' => my_inet_pton('127.0.0.1'),
    ]);

    
// settings
    
$settingGroupId $db->insert_query('settinggroups', [
        
'name'        => 'dvz_shoutbox',
        
'title'       => 'DVZ Shoutbox',
        
'description' => 'Settings for DVZ Shoutbox.',
    ]);

    
$settings = [
        [
            
'name'        => 'dvz_sb_num',
            
'title'       => 'Shouts to display',
            
'description' => 'Number of shouts to be displayed in the Shoutbox window.',
            
'optionscode' => 'numeric',
            
'value'       => '20',
        ],
        [
            
'name'        => 'dvz_sb_num_archive',
            
'title'       => 'Shouts to display on archive',
            
'description' => 'Number of shouts to be displayed per page on Archive view.',
            
'optionscode' => 'numeric',
            
'value'       => '20',
        ],
        [
            
'name'        => 'dvz_sb_reversed',
            
'title'       => 'Reversed order',
            
'description' => 'Reverses the shouts display order in the Shoutbox window so that new ones appear on the bottom. You may also want to move the <b>{$panel}</b> variable below the  window in the <i>dvz_shoutbox</i> template.',
            
'optionscode' => 'yesno',
            
'value'       => '0',
        ],
        [
            
'name'        => 'dvz_sb_height',
            
'title'       => 'Shoutbox height',
            
'description' => 'Height of the Shoutbox window in pixels.',
            
'optionscode' => 'numeric',
            
'value'       => '160',
        ],
        [
            
'name'        => 'dvz_sb_dateformat',
            
'title'       => 'Date format',
            
'description' => 'Format of the date displayed. This format uses the PHP\'s <a href="http://php.net/manual/en/function.date.php#refsect1-function.date-parameters">date() function syntax</a>.',
            
'optionscode' => 'text',
            
'value'       => 'd M H:i',
        ],
        [
            
'name'        => 'dvz_sb_maxlength',
            
'title'       => 'Maximum message length',
            
'description' => 'Set 0 to disable the limit.',
            
'optionscode' => 'numeric',
            
'value'       => '0',
        ],
        [
            
'name'        => 'dvz_sb_mycode',
            
'title'       => 'Parse MyCode',
            
'description' => '',
            
'optionscode' => 'yesno',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_smilies',
            
'title'       => 'Parse smilies',
            
'description' => '',
            
'optionscode' => 'yesno',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_interval',
            
'title'       => 'Refresh interval',
            
'description' => 'Number of seconds between Shoutbox updates (lower values provide better synchronization but cause higher server load). Set 0 to disable the auto-refreshing feature.',
            
'optionscode' => 'numeric',
            
'value'       => '5',
        ],
        [
            
'name'        => 'dvz_sb_away',
            
'title'       => 'Away mode',
            
'description' => 'Number of seconds after last user action (e.g. click) after which shoutbox will be minimized to prevent unnecessary usage of server resources. Set 0 to disable this feature.',
            
'optionscode' => 'numeric',
            
'value'       => '600',
        ],
        [
            
'name'        => 'dvz_sb_antiflood',
            
'title'       => 'Anti-flood interval',
            
'description' => 'Forces a minimum number of seconds to last between user\'s shouts (this does not apply to Shoutbox moderators).',
            
'optionscode' => 'numeric',
            
'value'       => '5',
        ],
        [
            
'name'        => 'dvz_sb_sync',
            
'title'       => 'Moderation synchronization',
            
'description' => 'Applies moderation actions without refreshing the Shoutbox window page.',
            
'optionscode' => 'onoff',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_lazyload',
            
'title'       => 'Lazy load',
            
'description' => 'Start loading data only when the Shoutbox window is actually being displayed on the screen (the page is scrolled to the Shoutbox position).',
            
'optionscode' => 'select
off=Disabled
start=Check if on display to start
always=Always check if on display to refresh'
,
            
'value'       => 'off',
        ],
        [
            
'name'        => 'dvz_sb_status',
            
'title'       => 'Shoutbox default status',
            
'description' => 'Choose whether Shoutbox window should be expanded or collapsed by default.',
            
'optionscode' => 'onoff',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_minposts',
            
'title'       => 'Minimum posts required to shout',
            
'description' => 'Set 0 to allow everyone.',
            
'optionscode' => 'numeric',
            
'value'       => '0',
        ],
        [
            
'name'        => 'dvz_sb_groups_view',
            
'title'       => 'Group permissions: View',
            
'description' => 'User groups that can view Shoutbox.',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_refresh',
            
'title'       => 'Group permissions: Auto-refresh',
            
'description' => 'User groups that shoutbox will be refreshing for.',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_shout',
            
'title'       => 'Group permissions: Shout',
            
'description' => 'User groups that can post shouts in Shoutbox (logged in users only).',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_recall',
            
'title'       => 'Group permissions: Scroll back to show past shouts',
            
'description' => 'User groups that shoutbox will load previous posts when scrolling back for.',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_mod',
            
'title'       => 'Group permissions: Moderation',
            
'description' => 'User groups that can moderate the Shoutbox (edit and delete shouts).',
            
'optionscode' => 'groupselect',
            
'value'       => '',
        ],
        [
            
'name'        => 'dvz_sb_groups_mod_own',
            
'title'       => 'Group permissions: Moderation of own shouts',
            
'description' => 'Users groups whose members can edit and delete their own shouts.',
            
'optionscode' => 'groupselect',
            
'value'       => '',
        ],
        [
            
'name'        => 'dvz_sb_supermods',
            
'title'       => 'Super moderators are Shoutbox moderators',
            
'description' => 'Automatically allow forum super moderators to moderate Shoutbox as well.',
            
'optionscode' => 'yesno',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_blocked_users',
            
'title'       => 'Banned users',
            
'description' => 'Comma-separated list of user IDs that are banned from posting messages.',
            
'optionscode' => 'textarea',
            
'value'       => '',
        ],
    ];

    
$i 1;

    foreach (
$settings as &$row) {
        
$row['gid']         = $settingGroupId;
        
$row['title']       = $db->escape_string($row['title']);
        
$row['description'] = $db->escape_string($row['description']);
        
$row['disporder']   = $i++;
    }

    
$db->insert_query_multiple('settings'$settings);

    
rebuild_settings();

    
// templates
    
$templates = [
        
'dvz_shoutbox_panel' => '<div class="panel">
<form>
<input type="text" class="text" placeholder="{$lang->dvz_sb_default}" maxlength="{$maxlength}" autocomplete="off" />
<input type="submit" style="display:none" />
</form>
</div>'
,

        
'dvz_shoutbox' => '<div id="shoutbox" class="front{$classes}">

<div class="head">
<strong>{$lang->dvz_sb_shoutbox}</strong>
<p class="right"><a href="{$mybb->settings[\'bburl\']}/index.php?action=shoutbox_archive">&laquo; {$lang->dvz_sb_archivelink}</a></p>
</div>

<div class="body">

{$panel}

<div class="window" style="height:{$mybb->settings[\'dvz_sb_height\']}px">
<div class="data">
{$html}
</div>
</div>

</div>

<script type="text/javascript" src="{$mybb->settings[\'bburl\']}/jscripts/dvz_shoutbox.js"></script>
{$javascript}

</div>'
,

        
'dvz_shoutbox_archive' => '<html>
<head>
<title>{$lang->dvz_sb_archive}</title>
{$headerinclude}
</head>
<body>
{$header}

<script type="text/javascript" src="{$mybb->settings[\'bburl\']}/jscripts/dvz_shoutbox.js"></script>
{$javascript}

{$modoptions}

{$multipage}

<br />

<div id="shoutbox">

<div class="head"><strong>{$lang->dvz_sb_archive}</strong></div>

<div class="data">
{$archive}
</div>
</div>

<br />

{$multipage}

{$footer}
</body>
</html>'
,

        
'dvz_shoutbox_archive_modoptions' => '<table border="0" cellspacing="{$theme[\'borderwidth\']}" cellpadding="{$theme[\'tablespace\']}" class="tborder">
<tr><td class="thead" colspan="2"><strong>{$lang->dvz_sb_mod}</strong></td></tr>
<tr><td class="tcat">{$lang->dvz_sb_mod_banlist}</td><td class="tcat">{$lang->dvz_sb_mod_clear}</td></tr>
<tr>
<td class="trow1">
<form action="" method="post">
<input type="text" class="textbox" style="width:80%" name="banlist" value="{$blocked_users}"></textarea>
<input type="hidden" name="postkey" value="{$mybb->post_code}" />
<input type="submit" class="button" value="{$lang->dvz_sb_mod_banlist_button}" />
</form>
</td>
<td class="trow1">
<form action="" method="post">
<select name="days">
<option value="2">2 {$lang->days}</option>
<option value="7">7 {$lang->days}</option>
<option value="30">30 {$lang->days}</option>
<option value="90">90 {$lang->days}</option>
<option value="all">* {$lang->dvz_sb_mod_clear_all} *</option>
</select>
<input type="hidden" name="postkey" value="{$mybb->post_code}" />
<input type="submit" class="button" value="{$lang->dvz_sb_mod_clear_button}" />
</form>
</td>
</tr>
</table>
<br />'
,
    ];

    
$data = [];

    foreach (
$templates as $name => $content) {
        
$data[] = [
            
'title'    => $name,
            
'template' => $db->escape_string($content),
            
'sid'      => -1,
            
'version'  => 1,
            
'status'   => '',
            
'dateline' => TIME_NOW,
        ];
    }

    
$db->insert_query_multiple('templates'$data);
}

function 
dvz_shoutbox_uninstall ()
{
    global 
$db;

    
$settingGroupId $db->fetch_field(
        
$db->simple_select('settinggroups''gid'"name='dvz_shoutbox'"),
        
'gid'
    
);

    
// delete settings
    
$db->delete_query('settinggroups''gid=' $settingGroupId);
    
$db->delete_query('settings''gid=' $settingGroupId);

    
rebuild_settings();

    
// delete templates
    
$db->delete_query('templates'"title IN('dvz_shoutbox', 'dvz_shoutbox_panel', 'dvz_shoutbox_archive', 'dvz_shoutbox_archive_modoptions')");

    
// delete data
    
$db->drop_table('dvz_shoutbox');
}

function 
dvz_shoutbox_is_installed ()
{
    global 
$mybb;
    return 
$mybb->settings['dvz_sb_num'] !== null;
}


class 
dvz_shoutbox
{

    
// hooks
    
static function global_start ()
    {
        global 
$mybb$templatelist;

        if (
THIS_SCRIPT == 'index.php' && self::access_view()) {

            if (!empty(
$templatelist)) {
                
$templatelist .= ',';
            }

            if (
$mybb->input['action'] == 'shoutbox_archive') {
                
// archive templates

                
$templatelist .= 'dvz_shoutbox_archive,multipage,multipage_page,mul​tipage_page_current,multipage_nextpage';

                if (
self::access_mod()) {
                    
$templatelist .= ',dvz_shoutbox_archive_modoptions';
                }

            } else {
                
// index templates
                
$templatelist .= 'dvz_shoutbox,dvz_shoutbox_panel';
            }

        }
    }

    static function 
global_end ()
    {
        global 
$mybb;

        if (
$mybb->input['action'] == 'shoutbox_archive' && self::access_view()) {
            return 
self::show_archive();
        }
    }

    static function 
xmlhttp ()
    {
        global 
$mybb$db$charset;

        switch (
$mybb->input['action']) {

            case 
'dvz_sb_get_updates':

                
$permissions = (
                    
self::access_view() &&
                    
self::access_refresh()
                );

                
$handler = function() use ($mybb$db) {

                    
$syncConditions $mybb->settings['dvz_sb_sync']
                        ? 
"OR s.modified >= " . (time() - $mybb->settings['dvz_sb_interval']) . " AND s.id BETWEEN " abs((int)$mybb->input['first']) . " AND " abs((int)$mybb->input['last'])
                        : 
null
                    
;

                    
$data self::get_multiple("WHERE s.id > " abs((int)$mybb->input['last']) . " AND s.text IS NOT NULL " $syncConditions  " ORDER BY s.id DESC LIMIT " abs((int)$mybb->settings['dvz_sb_num']));

                    
$html   null// JS-handled empty response
                    
$sync   = [];
                    
$lastId 0;

                    while (
$row $db->fetch_array($data)) {

                        if (
$row['id'] <= $mybb->input['last']) {
                            
// sync update

                            
$sync$row['id'] ] = $row['text'] === null
                                
null
                                
self::parse($row['text'], $row['username'])
                            ;

                        } else {
                            
// new shout

                            
if ($lastId == 0) {
                                
$lastId $row['id'];
                            }

                            
$shout self::render_shout($row);

                            
$html $mybb->settings['dvz_sb_reversed']
                                ? 
$shout $html
                                
$html  $shout
                            
;

                        }

                    }

                    if (
$html != null || !empty($sync)) {

                        
$response = [];

                        if (
$html != null) {
                            
$response['html'] = $html;
                            
$response['last'] = $lastId;
                        }

                        if (!empty(
$sync)) {
                            
$response['sync'] = $sync;
                        }

                        echo 
json_encode($response);

                    }
                };

                break;

            case 
'dvz_sb_recall':

                
$permissions = (
                    
self::access_view() &&
                    
self::access_refresh() &&
                    
self::access_recall()
                );

                
$handler = function() use ($mybb$db) {

                    
$data self::get_multiple("WHERE s.id < " abs((int)$mybb->input['first']) . " ORDER BY s.id DESC LIMIT " abs((int)$mybb->settings['dvz_sb_num']));

                    
$response = [];

                    
$html null// JS-handled empty response
                    
$firstId 0;

                    while (
$row $db->fetch_array($data)) {

                        
$firstId $row['id'];

                        
$shout self::render_shout($row);

                        
$html $mybb->settings['dvz_sb_reversed']
                            ? 
$shout $html
                            
$html  $shout
                        
;
                    }

                    if (
$html != null) {
                        
$response['html'] = $html;
                    }

                    if (
$db->num_rows($data) < $mybb->settings['dvz_sb_num']) {
                        
$response['end'] = 1;
                    }

                    if (
$response) {
                        
$response['first'] = $firstId;
                    }

                    echo 
json_encode($response);

                };

                break;

            case 
'dvz_sb_shout':

                
$permissions = (
                    
self::access_shout() &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($mybb) {
                    if (!
self::antiflood_pass() && !self::access_mod()) die('A'); // JS-handled error (Anti-flood)

                    
self::shout([
                        
'uid'       => $mybb->user['uid'],
                        
'text'      => $mybb->input['text'],
                        
'ipaddress' => my_inet_pton(get_ip()),
                    ]);
                };

                break;

            case 
'dvz_sb_get':

                
$data self::get($mybb->input['id']);

                
$permissions = (
                    (
                        
self::access_mod() ||
                        (
self::access_mod_own() && $data['uid'] == $mybb->user['uid'])
                    ) &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($data) {
                    echo 
json_encode([
                        
'text' => $data['text'],
                    ]);
                };

                break;

            case 
'dvz_sb_update':

                
$permissions = (
                    
self::can_mod($mybb->input['id']) &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($mybb) {
                    
self::update($mybb->input['id'], $mybb->input['text']);
                    echo 
self::parse($mybb->input['text'], self::get_username($mybb->input['id']));

                };

                break;

            case 
'dvz_sb_delete':

                
$permissions = (
                    
self::can_mod($mybb->input['id']) &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($mybb) {
                    
self::delete($mybb->input['id']);
                };

                break;

        }

        if (isset(
$permissions)) {

            if (
$permissions == false) {
                echo 
'P'// JS-handled error (Permissions)
            
} else {

                
header('Content-type: text/plain; charset=' $charset);
                
header('Cache-Control: no-store'); // force update on load
                
$handler();

            }

        }
    }

    static function 
load_window ()
    {
        global 
$templates$dvz_shoutbox$lang$mybb$db$theme;

        
$lang->load('dvz_shoutbox');

        
// MyBB template
        
$dvz_shoutbox null;

        
// dvz_shoutbox template
        
$javascript   null;
        
$panel        null;
        
$classes      null;

        if (
self::access_view()) {

            if (
self::is_user()) {

                
// message: blocked
                
if (self::is_blocked()) {
                    
$panel '<div class="panel blocked"><p>' $lang->dvz_sb_user_blocked '</p></div>';
                }
                
// message: minimum posts
                
else if (!self::access_minposts() && !self::access_mod()) {
                    
$panel '<div class="panel minposts"><p>' str_replace('{MINPOSTS}', (int)$mybb->settings['dvz_sb_minposts'], $lang->dvz_sb_minposts) . '</p></div>';
                }
                
// shout form
                
else if (self::access_shout()) {
                    
$maxlength $mybb->settings['dvz_sb_maxlength'] ? (int)$mybb->settings['dvz_sb_maxlength'] : null;
                    eval(
'$panel = "' $templates->get('dvz_shoutbox_panel') . '";');
                }

            }

            
$js null;

            
// configuration
            
$js .= 'dvz_shoutbox.interval = ' . (self::access_refresh() ? (float)$mybb->settings['dvz_sb_interval'] : 0) . ';' PHP_EOL;
            
$js .= 'dvz_shoutbox.antiflood = ' . (self::access_mod() ? : (float)$mybb->settings['dvz_sb_antiflood']) . ';' PHP_EOL;
            
$js .= 'dvz_shoutbox.maxShouts = ' . (int)$mybb->settings['dvz_sb_num'] . ';' PHP_EOL;
            
$js .= 'dvz_shoutbox.awayTime = ' . (float)$mybb->settings['dvz_sb_away'] . '*1000;' PHP_EOL;
            
$js .= 'dvz_shoutbox.lang = [\'' $lang->dvz_sb_delete_confirm '\', \'' str_replace('{ANTIFLOOD}', (float)$mybb->settings['dvz_sb_antiflood'], $lang->dvz_sb_antiflood) . '\', \''.$lang->dvz_sb_permissions.'\'];' PHP_EOL;

            
// reversed order
            
if ($mybb->settings['dvz_sb_reversed']) {
                
$js .= 'dvz_shoutbox.reversed = true;' PHP_EOL;
                
$js .= '$(\'#shoutbox .window\').scrollTop( $(\'#shoutbox .window\')[0].scrollHeight );' PHP_EOL;
            }

            
// lazyload
            
if ($mybb->settings['dvz_sb_lazyload']) {
                
$js .= 'dvz_shoutbox.lazyMode = \'' . (int)$mybb->settings['dvz_sb_lazyload'] . '\';' PHP_EOL;
                
$js .= '$(window).bind(\'scroll resize\', dvz_shoutbox.checkVisibility);' PHP_EOL;
            }

            
// away mode
            
if ($mybb->settings['dvz_sb_away']) {
                
$js .= '$(window).on(\'mousemove click dblclick keydown scroll\', dvz_shoutbox.updateActivity);' PHP_EOL;
            }

            
// shoutbox status
            
$status = isset($_COOKIE['dvz_sb_status'])
                ? (bool)
$_COOKIE['dvz_sb_status']
                : (bool)
$mybb->settings['dvz_sb_status']
            ;

            
$js .= 'dvz_shoutbox.status = ' . (int)$status ';' PHP_EOL;

            if (
$status == false) {
                
$classes .= ' collapsed';
            }

            
// preloaded shouts
            
$data self::get_multiple("WHERE s.text IS NOT NULL ORDER BY s.id DESC LIMIT " abs((int)$mybb->settings['dvz_sb_num']));

            
$html null;
            
$firstId 0;
            
$lastId 0;

            while (
$row $db->fetch_array($data)) {

                
$firstId $row['id'];

                if (
$lastId == 0) {
                    
$lastId $row['id'];
                }

                
$shout self::render_shout($row);

                
$html  $mybb->settings['dvz_sb_reversed']
                    ? 
$shout $html
                    
$html  $shout
                
;
            }

            if (
self::access_refresh()) {
                
$js .= 'setTimeout(\'dvz_shoutbox.loop()\', ' . (float)$mybb->settings['dvz_sb_interval'] . ' * 1000);' PHP_EOL;
            }

            if (
self::access_recall()) {
                
$js .= 'dvz_shoutbox.recalling = true;' PHP_EOL;
            }

            
$javascript '
<script>
$js '
dvz_shoutbox.firstId = ' 
$firstId ';
dvz_shoutbox.lastId = ' 
$lastId ';
dvz_shoutbox.appendControls();
dvz_shoutbox.updateActivity();
</script>'
;

            eval(
'$dvz_shoutbox = "' $templates->get('dvz_shoutbox') . '";');

        }
    }

    static function 
show_archive ()
    {
        global 
$db$mybb$templates$lang$theme$footer$headerinclude$header$charset;

        
$lang->load('dvz_shoutbox');

        
header('Content-type: text/html; charset=' $charset);

        
add_breadcrumb($lang->dvz_sb_shoutbox"index.php?action=shoutbox_archive");

        
// moderation panel
        
if (self::access_mod()) {

            if (isset(
$mybb->input['banlist']) && verify_post_check($mybb->input['postkey'])) {
                
self::banlist_update($mybb->input['banlist']);
            }

            if (isset(
$mybb->input['days']) && verify_post_check($mybb->input['postkey'])) {
                if (
$mybb->input['days'] == 'all') {
                    
self::clear();
                } else {
                    
$allowed = [273090];
                    if (
in_array($mybb->input['days'], $allowed)) {
                        
self::clear($mybb->input['days']);
                    }
                }
            }

            
$blocked_users htmlspecialchars_uni($mybb->settings['dvz_sb_blocked_users']);
            eval(
'$modoptions = "' $templates->get("dvz_shoutbox_archive_modoptions") . '";');

        } else {
            
$modoptions null;
        }

        
// pagination
        
$items   self::count();
        
$page    abs((int)$mybb->input['page']);
        
$perPage abs((int)$mybb->settings['dvz_sb_num_archive']);

        if (
$perPage == 0) {
            
$pages 0;
        } else {
            
$pages   ceil($items $perPage);
        }

        if (!
$page || $page || $page $pages$page 1;

        
$start = ($page 1) * $perPage;

        if (
$items $perPage) {
            
$multipage multipage($items$perPage$page'index.php?action=shoutbox_archive');
        }


        
$data self::get_multiple("WHERE s.text IS NOT NULL ORDER by s.id DESC LIMIT $start,$perPage");

        
$archive null;

        while (
$row $db->fetch_array($data)) {
            
$archive .= self::render_shout($rowtrue);
        }

        
$javascript '
<script>
dvz_shoutbox.lang = [\'' 
$lang->dvz_sb_delete_confirm '\', \'' str_replace('{ANTIFLOOD}', (float)$mybb->settings['dvz_sb_antiflood'], $lang->dvz_sb_antiflood) . '\', \'' $lang->dvz_sb_permissions '\'];
</script>'
;

        eval(
'$content = "' $templates->get("dvz_shoutbox_archive") . '";');

        
output_page($content);

        exit;
    }

    static function 
user_merge ()
    {
        global 
$db$source_user$destination_user;
        return 
$db->update_query('dvz_shoutbox', ['uid' => $destination_user['uid']], 'uid=' . (int)$source_user['uid']);
    }

    static function 
activity (&$user_activity)
    {
        
$location parse_url($user_activity['location']);
        
$filename basename($location['path']);

        
parse_str(html_entity_decode($location['query']), $parameters);

        if (
$filename == 'index.php' && $parameters['action'] == 'shoutbox_archive') {
            
$user_activity['activity'] = 'dvz_shoutbox_archive';
        }
    }

    static function 
activity_translate (&$data)
    {
        global 
$lang;

        
$lang->load('dvz_shoutbox');

        if (
$data['user_activity']['activity'] == 'dvz_shoutbox_archive') {
            
$data['location_name'] = sprintf($lang->dvz_sb_activity'index.php?action=shoutbox_archive');
        }
    }

    static function 
clearcookies ()
    {
        global 
$remove_cookies;
        
$remove_cookies[] = 'dvz_sb_status';
    }

    
// data manipulation
    
static function get ($id)
    {
        global 
$db;
        return 
$db->fetch_array$db->simple_select('dvz_shoutbox''*''id=' . (int)$id) );
    }

    static function 
get_multiple ($clauses)
    {
        global 
$db;
        return 
$db->query("
            SELECT
                s.*, u.username, u.usergroup, u.displaygroup, u.avatar
            FROM
                " 
TABLE_PREFIX "dvz_shoutbox s
                LEFT JOIN " 
TABLE_PREFIX "users u ON u.uid = s.uid
            " 
$clauses "
        "
);
    }

    static function 
get_username ($id)
    {
        global 
$db;
        return 
$db->fetch_field(
            
$db->query("SELECT username FROM " TABLE_PREFIX "users u, " TABLE_PREFIX "dvz_shoutbox s WHERE u.uid=s.uid AND s.id=" . (int)$id),
            
'username'
        
);
    }

    static function 
user_last_shout_time ($uid)
    {
        global 
$db;
        return 
$db->fetch_field(
            
$db->simple_select('dvz_shoutbox''date''uid=' . (int)$uid, [
                
'order_by'  => 'date',
                
'order_dir' => 'desc',
                
'limit'     => 1,
            ]),
            
'date'
        
);
    }

    static function 
count ()
    {
        global 
$db;
        return 
$db->fetch_field(
            
$db->simple_select('dvz_shoutbox''COUNT(*) as n'),
            
'n'
        
);
    }

    static function 
shout ($data)
    {
        global 
$mybb$db;

        if (
$mybb->settings['dvz_sb_maxlength'] > 0) {
            
$data['text'] = mb_substr($data['text'], 0$mybb->settings['dvz_sb_maxlength']);
        }

        foreach (
$data as &$item) {
            
$item $db->escape_string($item);
        }

        
$data['date'] = TIME_NOW;

        return 
$db->insert_query('dvz_shoutbox'$data);
    }

    static function 
update ($id$text)
    {
        global 
$db;
        return 
$db->update_query('dvz_shoutbox', [
            
'text'     => $db->escape_string($text),
            
'modified' => time(),
        ], 
'id=' . (int)$id);
    }

    static function 
banlist_update ($new)
    {
        global 
$db;

        
$db->update_query('settings', ['value' => $db->escape_string($new)], "name='dvz_sb_blocked_users'");

        
rebuild_settings();
    }

    static function 
delete ($id)
    {
        global 
$mybb$db;

        if (
$mybb->settings['dvz_sb_sync']) {
            return 
$db->update_query('dvz_shoutbox', [
                
'text'     => 'NULL',
                
'modified' => time(),
            ], 
'id=' . (int)$idfalsetrue);
        } else {
            return 
$db->delete_query('dvz_shoutbox''id=' . (int)$id);
        }
    }

    static function 
clear ($days false)
    {
        global 
$db;

        if (
$days) {
            
$where 'date < ' . ( TIME_NOW - ((int)$days 86400) );
        } else {
            
$where false;
        }

        return 
$db->delete_query('dvz_shoutbox'$where);
    }

    
// permissions
    
static function is_user ()
    {
        global 
$mybb;
        return 
$mybb->user['uid'] != 0;
    }

    static function 
is_blocked ()
    {
        global 
$mybb;
        return 
in_array($mybb->user['uid'], self::settings_get_csv('blocked_users'));
    }

    static function 
access_view ()
    {
        
$array self::settings_get_csv('groups_view');
        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_refresh ()
    {
        
$array self::settings_get_csv('groups_refresh');
        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_shout ()
    {
        
$array self::settings_get_csv('groups_shout');

        return (
            
self::is_user() &&
            !
self::is_blocked() &&
            (
                
self::access_mod() ||
                (
                    
self::access_view() &&
                    
self::access_minposts() &&
                    
$array[0] == -|| is_member($array)
                )
            )
        );
    }

    static function 
access_recall ()
    {
        
$array self::settings_get_csv('groups_recall');
        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_mod ()
    {
        global 
$mybb;

        
$array self::settings_get_csv('groups_mod');

        return (
            (
$array[0] == -|| is_member($array)) ||
            (
$mybb->settings['dvz_sb_supermods'] && $mybb->usergroup['issupermod'])
        );
    }

    static function 
access_mod_own ()
    {
        
$array self::settings_get_csv('groups_mod_own');

        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_minposts ()
    {
        global 
$mybb;
        return 
$mybb->user['postnum'] >= $mybb->settings['dvz_sb_minposts'];
    }

    static function 
can_mod ($shoutId)
    {
        global 
$mybb;

        if (
self::access_mod()) {
            return 
true;
        } else if (
self::access_mod_own() && self::access_shout()) {

            
$data self::get($shoutId);

            if (
$data['uid'] == $mybb->user['uid']) {
                return 
true;
            }

        }

        return 
false;

    }

    
// core
    
static function render_shout ($data$static false)
    {
        global 
$mybb;

        
$id       $data['id'];
        
$text     self::parse($data['text'], $data['username']);
        
$date     htmlspecialchars_uni(my_date($mybb->settings['dvz_sb_dateformat'], $data['date']));
        
$username htmlspecialchars_uni($data['username']);
        
$user     '<a href="member.php?action=profile&uid=' . (int)$data['uid'] . '">' format_name($username$data['usergroup'], $data['displaygroup']) . '</a>';
        
$avatar   '<img src="' . (empty($data['avatar']) ? htmlspecialchars_uni($mybb->settings['useravatar']) : htmlspecialchars_uni($data['avatar'])) . '" alt="avatar" />';

        
$notes      null;
        
$attributes null;

        
$own $data['uid'] == $mybb->user['uid'];

        if (
$static) {

            if (
self::access_mod()) {
                
$notes .= '<span class="ip">' my_inet_ntop($data['ipaddress']) . '</span>';
            }

            if (
                
self::access_mod() ||
                (
self::access_mod_own() && $own)
            ) {
                
$notes .= '<a href="" class="mod edit">E</a><a href="" class="mod del">X</a>';
            }

        }

        if (
            
self::access_mod() ||
            (
self::access_mod_own() && $own)
        ) {
            
$attributes .= ' data-mod';
        }

        if (
$own) {
            
$attributes .= ' data-own';
        }

        if(
$mybb->user['ignorelist'] != ''
    {
    
$ignlist explode(","$mybb->user['ignorelist']);
    if(!empty(
$ignlist) && in_array($data['uid'], $ignlisttrue)) 
        {
        
$text '<span style="font-style: italic; font-size: 0.85em;">' self::parse('Użytkownik jest przez ciebie ignorowany.'$data['username']) . '</span>';
        }
    } 

        return 
'
<div class="entry" data-id="' 
$id '" data-username="' $username '"' $attributes '>
    <div class="avatar">' 
$avatar '</div>
    <div class="user">' 
$user '</div>
    <div class="text">' 
$text '</div>
    <div class="info">' 
$notes '<span class="date">' $date '</span></div>
</div>'
;
    }

    static function 
parse ($message$me_username)
    {
        global 
$mybb;

        require_once 
MYBB_ROOT 'inc/class_parser.php';

        
$parser = new postParser;
        
$options = [
            
'allow_mycode'    => $mybb->settings['dvz_sb_mycode'],
            
'allow_smilies'   => $mybb->settings['dvz_sb_smilies'],
            
'allow_imgcode'   => 0,
            
'filter_badwords' => 1,
            
'me_username'     => $me_username,
        ];

        return 
$parser->parse_message($message$options);
    }

    static function 
antiflood_pass ()
    {
        global 
$mybb;
        return (
            !
$mybb->settings['dvz_sb_antiflood'] ||
            ( 
TIME_NOW self::user_last_shout_time($mybb->user['uid']) ) > $mybb->settings['dvz_sb_antiflood']
        );
    }

    static function 
settings_get_csv ($name)
    {
        global 
$mybb;
        return 
array_filterexplode(','$mybb->settings['dvz_sb_' $name]) );
    }



ps polącz posty
Wcześniejszy sposób dodania hook działał bez problemu z przed aktualizacji z 2.1 do 2.2 dvz shoutboxa
wcześniej może miałeś powielaną funkcje load_window

to co podalem nie działa?
Działać działa, tylko jeszcze muszę dojść czemu teraz nie pokazuje statystyk na podstronie mianowicie Twoje wpisy: Wszystkich wpisów: Największy spamer: () oraz nie działa kto jest online
Szogi1910 napisał(a):tylko jeszcze muszę dojść czemu teraz nie pokazuje statystyk na podstronie mianowicie Twoje wpisy: Wszystkich wpisów: Największy spamer: () oraz nie działa kto jest online
Pewnie dlatego, że w pliku shoutboxa nie masz użytych zmiennych zawartych w tym kodzie:
<strong>Kto jest online na shoutboxie?</strong> (<a href="/online.php">Szczegóły</a>)<br />
{$users_online_o} użytkowników aktywnych w ciągu ostatnich 15 minut: {$users_online} zarejestrowanych (w tym 0 niewidocznych) oraz {$guests_online} gości.<br />
{$onlinemembers}
<br /> <br />
Prośby na PW dotyczące wsparcia z problemami będą ignorowane. Pomoc poza forum - odpłatna; kontakt: snakemybboard@gmail.com.
No fakt o nich zapomniałem. może znawcą php nie jestem ale po dodaniu tych zmiennych w kodzie pluginu nadal coś mi nie działa

Plik dvz_shoutbox w wersji 2.2 z dodanymi zmiennymi
<?php
/* by Tomasz 'Devilshakerz' Mlynski [devilshakerz.com]; Copyright (C) 2014-2015
 released under Creative Commons BY-NC-SA 4.0 license: http://creativecommons.org/licenses/by-nc-sa/4.0/ */

$plugins->add_hook('global_start', ['dvz_shoutbox''global_start']);   // cache shoutbox templates
$plugins->add_hook('global_end',   ['dvz_shoutbox''global_end']);    // catch archive page
$plugins->add_hook('xmlhttp',      ['dvz_shoutbox''xmlhttp']);      // xmlhttp.php listening
$plugins->add_hook('index_end',    ['dvz_shoutbox''load_window']); // load Shoutbox window to {$dvz_shoutbox} variable
$plugins->add_hook('shoutbox_start', ['dvz_shoutbox''load_window']); // dvz_shoutbox na podstronie 


$plugins->add_hook('admin_user_users_merge_commit', ['dvz_shoutbox''user_merge']);

$plugins->add_hook('fetch_wol_activity_end', ['dvz_shoutbox''activity']); // catch activity
$plugins->add_hook('build_friendly_wol_location_end', ['dvz_shoutbox''activity_translate']); // translate activity

$plugins->add_hook('misc_clearcookies', ['dvz_shoutbox''clearcookies']);

function 
dvz_shoutbox_info ()
{
    return [
        
'name'          => 'DVZ Shoutbox',
        
'description'   => 'Lightweight AJAX chat.',
        
'website'       => 'http://devilshakerz.com/',
        
'author'        => 'Tomasz \'Devilshakerz\' Mlynski',
        
'authorsite'    => 'http://devilshakerz.com/',
        
'version'       => '2.2',
        
'codename'      => 'dvz_shoutbox',
        
'compatibility' => '18*',
    ];
}

function 
dvz_shoutbox_install ()
{
    global 
$db;

    
// table
    
$db->write_query("
        CREATE TABLE IF NOT EXISTS `" 
TABLE_PREFIX "dvz_shoutbox` (
            `id` int(11) NOT NULL auto_increment,
            `uid` int(11) NOT NULL,
            `text` text NULL,
            `date` int(11) NOT NULL,
            `modified` int(11) NULL DEFAULT NULL,
            `ipaddress` varbinary(16) NOT NULL,
            PRIMARY KEY (`id`)
        ) ENGINE=InnoDB " 
$db->build_create_table_collation() . "
    "
);

    
// example shout
    
$db->insert_query('dvz_shoutbox', [
        
'uid'       => 1,
        
'text'      => 'DVZ Shoutbox!',
        
'date'      => TIME_NOW,
        
'ipaddress' => my_inet_pton('127.0.0.1'),
    ]);

    
// settings
    
$settingGroupId $db->insert_query('settinggroups', [
        
'name'        => 'dvz_shoutbox',
        
'title'       => 'DVZ Shoutbox',
        
'description' => 'Settings for DVZ Shoutbox.',
    ]);

    
$settings = [
        [
            
'name'        => 'dvz_sb_num',
            
'title'       => 'Shouts to display',
            
'description' => 'Number of shouts to be displayed in the Shoutbox window.',
            
'optionscode' => 'numeric',
            
'value'       => '20',
        ],
        [
            
'name'        => 'dvz_sb_num_archive',
            
'title'       => 'Shouts to display on archive',
            
'description' => 'Number of shouts to be displayed per page on Archive view.',
            
'optionscode' => 'numeric',
            
'value'       => '20',
        ],
        [
            
'name'        => 'dvz_sb_reversed',
            
'title'       => 'Reversed order',
            
'description' => 'Reverses the shouts display order in the Shoutbox window so that new ones appear on the bottom. You may also want to move the <b>{$panel}</b> variable below the  window in the <i>dvz_shoutbox</i> template.',
            
'optionscode' => 'yesno',
            
'value'       => '0',
        ],
        [
            
'name'        => 'dvz_sb_height',
            
'title'       => 'Shoutbox height',
            
'description' => 'Height of the Shoutbox window in pixels.',
            
'optionscode' => 'numeric',
            
'value'       => '160',
        ],
        [
            
'name'        => 'dvz_sb_dateformat',
            
'title'       => 'Date format',
            
'description' => 'Format of the date displayed. This format uses the PHP\'s <a href="http://php.net/manual/en/function.date.php#refsect1-function.date-parameters">date() function syntax</a>.',
            
'optionscode' => 'text',
            
'value'       => 'd M H:i',
        ],
        [
            
'name'        => 'dvz_sb_maxlength',
            
'title'       => 'Maximum message length',
            
'description' => 'Set 0 to disable the limit.',
            
'optionscode' => 'numeric',
            
'value'       => '0',
        ],
        [
            
'name'        => 'dvz_sb_mycode',
            
'title'       => 'Parse MyCode',
            
'description' => '',
            
'optionscode' => 'yesno',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_smilies',
            
'title'       => 'Parse smilies',
            
'description' => '',
            
'optionscode' => 'yesno',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_interval',
            
'title'       => 'Refresh interval',
            
'description' => 'Number of seconds between Shoutbox updates (lower values provide better synchronization but cause higher server load). Set 0 to disable the auto-refreshing feature.',
            
'optionscode' => 'numeric',
            
'value'       => '5',
        ],
        [
            
'name'        => 'dvz_sb_away',
            
'title'       => 'Away mode',
            
'description' => 'Number of seconds after last user action (e.g. click) after which shoutbox will be minimized to prevent unnecessary usage of server resources. Set 0 to disable this feature.',
            
'optionscode' => 'numeric',
            
'value'       => '600',
        ],
        [
            
'name'        => 'dvz_sb_antiflood',
            
'title'       => 'Anti-flood interval',
            
'description' => 'Forces a minimum number of seconds to last between user\'s shouts (this does not apply to Shoutbox moderators).',
            
'optionscode' => 'numeric',
            
'value'       => '5',
        ],
        [
            
'name'        => 'dvz_sb_sync',
            
'title'       => 'Moderation synchronization',
            
'description' => 'Applies moderation actions without refreshing the Shoutbox window page.',
            
'optionscode' => 'onoff',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_lazyload',
            
'title'       => 'Lazy load',
            
'description' => 'Start loading data only when the Shoutbox window is actually being displayed on the screen (the page is scrolled to the Shoutbox position).',
            
'optionscode' => 'select
off=Disabled
start=Check if on display to start
always=Always check if on display to refresh'
,
            
'value'       => 'off',
        ],
        [
            
'name'        => 'dvz_sb_status',
            
'title'       => 'Shoutbox default status',
            
'description' => 'Choose whether Shoutbox window should be expanded or collapsed by default.',
            
'optionscode' => 'onoff',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_minposts',
            
'title'       => 'Minimum posts required to shout',
            
'description' => 'Set 0 to allow everyone.',
            
'optionscode' => 'numeric',
            
'value'       => '0',
        ],
        [
            
'name'        => 'dvz_sb_groups_view',
            
'title'       => 'Group permissions: View',
            
'description' => 'User groups that can view Shoutbox.',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_refresh',
            
'title'       => 'Group permissions: Auto-refresh',
            
'description' => 'User groups that shoutbox will be refreshing for.',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_shout',
            
'title'       => 'Group permissions: Shout',
            
'description' => 'User groups that can post shouts in Shoutbox (logged in users only).',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_recall',
            
'title'       => 'Group permissions: Scroll back to show past shouts',
            
'description' => 'User groups that shoutbox will load previous posts when scrolling back for.',
            
'optionscode' => 'groupselect',
            
'value'       => '-1',
        ],
        [
            
'name'        => 'dvz_sb_groups_mod',
            
'title'       => 'Group permissions: Moderation',
            
'description' => 'User groups that can moderate the Shoutbox (edit and delete shouts).',
            
'optionscode' => 'groupselect',
            
'value'       => '',
        ],
        [
            
'name'        => 'dvz_sb_groups_mod_own',
            
'title'       => 'Group permissions: Moderation of own shouts',
            
'description' => 'Users groups whose members can edit and delete their own shouts.',
            
'optionscode' => 'groupselect',
            
'value'       => '',
        ],
        [
            
'name'        => 'dvz_sb_supermods',
            
'title'       => 'Super moderators are Shoutbox moderators',
            
'description' => 'Automatically allow forum super moderators to moderate Shoutbox as well.',
            
'optionscode' => 'yesno',
            
'value'       => '1',
        ],
        [
            
'name'        => 'dvz_sb_blocked_users',
            
'title'       => 'Banned users',
            
'description' => 'Comma-separated list of user IDs that are banned from posting messages.',
            
'optionscode' => 'textarea',
            
'value'       => '',
        ],
    ];

    
$i 1;

    foreach (
$settings as &$row) {
        
$row['gid']         = $settingGroupId;
        
$row['title']       = $db->escape_string($row['title']);
        
$row['description'] = $db->escape_string($row['description']);
        
$row['disporder']   = $i++;
    }

    
$db->insert_query_multiple('settings'$settings);

    
rebuild_settings();

    
// templates
    
$templates = [
        
'dvz_shoutbox_panel' => '<div class="panel">
<form>
<input type="text" class="text" placeholder="{$lang->dvz_sb_default}" maxlength="{$maxlength}" autocomplete="off" />
<input type="submit" style="display:none" />
</form>
</div>'
,

        
'dvz_shoutbox' => '<div id="shoutbox" class="front{$classes}">

<div class="head">
<strong>{$lang->dvz_sb_shoutbox}</strong>
<p class="right"><a href="{$mybb->settings[\'bburl\']}/index.php?action=shoutbox_archive">&laquo; {$lang->dvz_sb_archivelink}</a></p>
</div>

<div class="body">

{$panel}

<div class="window" style="height:{$mybb->settings[\'dvz_sb_height\']}px">
<div class="data">
{$html}
</div>
</div>

</div>

<script type="text/javascript" src="{$mybb->settings[\'bburl\']}/jscripts/dvz_shoutbox.js"></script>
{$javascript}

</div>'
,

        
'dvz_shoutbox_archive' => '<html>
<head>
<title>{$lang->dvz_sb_archive}</title>
{$headerinclude}
</head>
<body>
{$header}

<script type="text/javascript" src="{$mybb->settings[\'bburl\']}/jscripts/dvz_shoutbox.js"></script>
{$javascript}

{$modoptions}

{$multipage}

<br />

<div id="shoutbox">

<div class="head"><strong>{$lang->dvz_sb_archive}</strong></div>

<div class="data">
{$archive}
</div>
</div>

<br />

{$multipage}

{$footer}
</body>
</html>'
,

        
'dvz_shoutbox_archive_modoptions' => '<table border="0" cellspacing="{$theme[\'borderwidth\']}" cellpadding="{$theme[\'tablespace\']}" class="tborder">
<tr><td class="thead" colspan="2"><strong>{$lang->dvz_sb_mod}</strong></td></tr>
<tr><td class="tcat">{$lang->dvz_sb_mod_banlist}</td><td class="tcat">{$lang->dvz_sb_mod_clear}</td></tr>
<tr>
<td class="trow1">
<form action="" method="post">
<input type="text" class="textbox" style="width:80%" name="banlist" value="{$blocked_users}"></textarea>
<input type="hidden" name="postkey" value="{$mybb->post_code}" />
<input type="submit" class="button" value="{$lang->dvz_sb_mod_banlist_button}" />
</form>
</td>
<td class="trow1">
<form action="" method="post">
<select name="days">
<option value="2">2 {$lang->days}</option>
<option value="7">7 {$lang->days}</option>
<option value="30">30 {$lang->days}</option>
<option value="90">90 {$lang->days}</option>
<option value="all">* {$lang->dvz_sb_mod_clear_all} *</option>
</select>
<input type="hidden" name="postkey" value="{$mybb->post_code}" />
<input type="submit" class="button" value="{$lang->dvz_sb_mod_clear_button}" />
</form>
</td>
</tr>
</table>
<br />'
,
    ];

    
$data = [];

    foreach (
$templates as $name => $content) {
        
$data[] = [
            
'title'    => $name,
            
'template' => $db->escape_string($content),
            
'sid'      => -1,
            
'version'  => 1,
            
'status'   => '',
            
'dateline' => TIME_NOW,
        ];
    }

    
$db->insert_query_multiple('templates'$data);
}

function 
dvz_shoutbox_uninstall ()
{
    global 
$db;

    
$settingGroupId $db->fetch_field(
        
$db->simple_select('settinggroups''gid'"name='dvz_shoutbox'"),
        
'gid'
    
);

    
// delete settings
    
$db->delete_query('settinggroups''gid=' $settingGroupId);
    
$db->delete_query('settings''gid=' $settingGroupId);

    
rebuild_settings();

    
// delete templates
    
$db->delete_query('templates'"title IN('dvz_shoutbox', 'dvz_shoutbox_panel', 'dvz_shoutbox_archive', 'dvz_shoutbox_archive_modoptions')");

    
// delete data
    
$db->drop_table('dvz_shoutbox');
}

function 
dvz_shoutbox_is_installed ()
{
    global 
$mybb;
    return 
$mybb->settings['dvz_sb_num'] !== null;
}


class 
dvz_shoutbox
{

    
// hooks
    
static function global_start ()
    {
        global 
$mybb$templatelist;

        if (
THIS_SCRIPT == 'index.php' && self::access_view()) {

            if (!empty(
$templatelist)) {
                
$templatelist .= ',';
            }

            if (
$mybb->input['action'] == 'shoutbox_archive') {
                
// archive templates

                
$templatelist .= 'dvz_shoutbox_archive,multipage,multipage_page,mul​​tipage_page_current,multipage_nextpage';

                if (
self::access_mod()) {
                    
$templatelist .= ',dvz_shoutbox_archive_modoptions';
                }

            } else {
                
// index templates
                
$templatelist .= 'dvz_shoutbox,dvz_shoutbox_panel';
            }

        }
    }

    static function 
global_end ()
    {
        global 
$mybb;

        if (
$mybb->input['action'] == 'shoutbox_archive' && self::access_view()) {
            return 
self::show_archive();
        }
    }

    static function 
xmlhttp ()
    {
        global 
$mybb$db$charset;

        switch (
$mybb->input['action']) {

            case 
'dvz_sb_get_updates':

                
$permissions = (
                    
self::access_view() &&
                    
self::access_refresh()
                );

                
$handler = function() use ($mybb$db) {

                    
$syncConditions $mybb->settings['dvz_sb_sync']
                        ? 
"OR s.modified >= " . (time() - $mybb->settings['dvz_sb_interval']) . " AND s.id BETWEEN " abs((int)$mybb->input['first']) . " AND " abs((int)$mybb->input['last'])
                        : 
null
                    
;

                    
$data self::get_multiple("WHERE s.id > " abs((int)$mybb->input['last']) . " AND s.text IS NOT NULL " $syncConditions  " ORDER BY s.id DESC LIMIT " abs((int)$mybb->settings['dvz_sb_num']));

                    
$html   null// JS-handled empty response
                    
$sync   = [];
                    
$lastId 0;

                    while (
$row $db->fetch_array($data)) {

                        if (
$row['id'] <= $mybb->input['last']) {
                            
// sync update

                            
$sync$row['id'] ] = $row['text'] === null
                                
null
                                
self::parse($row['text'], $row['username'])
                            ;

                        } else {
                            
// new shout

                            
if ($lastId == 0) {
                                
$lastId $row['id'];
                            }

                            
$shout self::render_shout($row);

                            
$html $mybb->settings['dvz_sb_reversed']
                                ? 
$shout $html
                                
$html  $shout
                            
;

                        }

                    }

                    if (
$html != null || !empty($sync)) {

                        
$response = [];

                        if (
$html != null) {
                            
$response['html'] = $html;
                            
$response['last'] = $lastId;
                        }

                        if (!empty(
$sync)) {
                            
$response['sync'] = $sync;
                        }

                        echo 
json_encode($response);

                    }
                };

                break;

            case 
'dvz_sb_recall':

                
$permissions = (
                    
self::access_view() &&
                    
self::access_refresh() &&
                    
self::access_recall()
                );

                
$handler = function() use ($mybb$db) {

                    
$data self::get_multiple("WHERE s.id < " abs((int)$mybb->input['first']) . " ORDER BY s.id DESC LIMIT " abs((int)$mybb->settings['dvz_sb_num']));

                    
$response = [];

                    
$html null// JS-handled empty response
                    
$firstId 0;

                    while (
$row $db->fetch_array($data)) {

                        
$firstId $row['id'];

                        
$shout self::render_shout($row);

                        
$html $mybb->settings['dvz_sb_reversed']
                            ? 
$shout $html
                            
$html  $shout
                        
;
                    }

                    if (
$html != null) {
                        
$response['html'] = $html;
                    }

                    if (
$db->num_rows($data) < $mybb->settings['dvz_sb_num']) {
                        
$response['end'] = 1;
                    }

                    if (
$response) {
                        
$response['first'] = $firstId;
                    }

                    echo 
json_encode($response);

                };

                break;

            case 
'dvz_sb_shout':

                
$permissions = (
                    
self::access_shout() &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($mybb) {
                    if (!
self::antiflood_pass() && !self::access_mod()) die('A'); // JS-handled error (Anti-flood)

                    
self::shout([
                        
'uid'       => $mybb->user['uid'],
                        
'text'      => $mybb->input['text'],
                        
'ipaddress' => my_inet_pton(get_ip()),
                    ]);
                };

                break;

            case 
'dvz_sb_get':

                
$data self::get($mybb->input['id']);

                
$permissions = (
                    (
                        
self::access_mod() ||
                        (
self::access_mod_own() && $data['uid'] == $mybb->user['uid'])
                    ) &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($data) {
                    echo 
json_encode([
                        
'text' => $data['text'],
                    ]);
                };

                break;

            case 
'dvz_sb_update':

                
$permissions = (
                    
self::can_mod($mybb->input['id']) &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($mybb) {
                    
self::update($mybb->input['id'], $mybb->input['text']);
                    echo 
self::parse($mybb->input['text'], self::get_username($mybb->input['id']));

                };

                break;

            case 
'dvz_sb_delete':

                
$permissions = (
                    
self::can_mod($mybb->input['id']) &&
                    
verify_post_check($mybb->input['key'], true)
                );

                
$handler = function() use ($mybb) {
                    
self::delete($mybb->input['id']);
                };

                break;

        }

        if (isset(
$permissions)) {

            if (
$permissions == false) {
                echo 
'P'// JS-handled error (Permissions)
            
} else {

                
header('Content-type: text/plain; charset=' $charset);
                
header('Cache-Control: no-store'); // force update on load
                
$handler();

            }

        }
    }

    static function 
load_window ()
    {
        global 
$templates$dvz_shoutbox$lang$mybb$db$theme;

        
$lang->load('dvz_shoutbox');

        
// MyBB template
        
$dvz_shoutbox null;

        
// dvz_shoutbox template
        
$javascript   null;
        
$panel        null;
        
$classes      null;

        if (
self::access_view()) {

            if (
self::is_user()) {

                
// message: blocked
                
if (self::is_blocked()) {
                    
$panel '<div class="panel blocked"><p>' $lang->dvz_sb_user_blocked '</p></div>';
                }
                
// message: minimum posts
                
else if (!self::access_minposts() && !self::access_mod()) {
                    
$panel '<div class="panel minposts"><p>' str_replace('{MINPOSTS}', (int)$mybb->settings['dvz_sb_minposts'], $lang->dvz_sb_minposts) . '</p></div>';
                }
                
// shout form
                
else if (self::access_shout()) {
                    
$maxlength $mybb->settings['dvz_sb_maxlength'] ? (int)$mybb->settings['dvz_sb_maxlength'] : null;
                    eval(
'$panel = "' $templates->get('dvz_shoutbox_panel') . '";');
                }

            }

            
$js null;

            
// configuration
            
$js .= 'dvz_shoutbox.interval = ' . (self::access_refresh() ? (float)$mybb->settings['dvz_sb_interval'] : 0) . ';' PHP_EOL;
            
$js .= 'dvz_shoutbox.antiflood = ' . (self::access_mod() ? : (float)$mybb->settings['dvz_sb_antiflood']) . ';' PHP_EOL;
            
$js .= 'dvz_shoutbox.maxShouts = ' . (int)$mybb->settings['dvz_sb_num'] . ';' PHP_EOL;
            
$js .= 'dvz_shoutbox.awayTime = ' . (float)$mybb->settings['dvz_sb_away'] . '*1000;' PHP_EOL;
            
$js .= 'dvz_shoutbox.lang = [\'' $lang->dvz_sb_delete_confirm '\', \'' str_replace('{ANTIFLOOD}', (float)$mybb->settings['dvz_sb_antiflood'], $lang->dvz_sb_antiflood) . '\', \''.$lang->dvz_sb_permissions.'\'];' PHP_EOL;

            
// reversed order
            
if ($mybb->settings['dvz_sb_reversed']) {
                
$js .= 'dvz_shoutbox.reversed = true;' PHP_EOL;
                
$js .= '$(\'#shoutbox .window\').scrollTop( $(\'#shoutbox .window\')[0].scrollHeight );' PHP_EOL;
            }

            
// lazyload
            
if ($mybb->settings['dvz_sb_lazyload']) {
                
$js .= 'dvz_shoutbox.lazyMode = \'' . (int)$mybb->settings['dvz_sb_lazyload'] . '\';' PHP_EOL;
                
$js .= '$(window).bind(\'scroll resize\', dvz_shoutbox.checkVisibility);' PHP_EOL;
            }

            
// away mode
            
if ($mybb->settings['dvz_sb_away']) {
                
$js .= '$(window).on(\'mousemove click dblclick keydown scroll\', dvz_shoutbox.updateActivity);' PHP_EOL;
            }

            
// shoutbox status
            
$status = isset($_COOKIE['dvz_sb_status'])
                ? (bool)
$_COOKIE['dvz_sb_status']
                : (bool)
$mybb->settings['dvz_sb_status']
            ;

            
$js .= 'dvz_shoutbox.status = ' . (int)$status ';' PHP_EOL;

            if (
$status == false) {
                
$classes .= ' collapsed';
            }

            
// preloaded shouts
            
$data self::get_multiple("WHERE s.text IS NOT NULL ORDER BY s.id DESC LIMIT " abs((int)$mybb->settings['dvz_sb_num']));

            
$html null;
            
$firstId 0;
            
$lastId 0;

            while (
$row $db->fetch_array($data)) {

                
$firstId $row['id'];

                if (
$lastId == 0) {
                    
$lastId $row['id'];
                }

                
$shout self::render_shout($row);

                
$html  $mybb->settings['dvz_sb_reversed']
                    ? 
$shout $html
                    
$html  $shout
                
;
            }

            if (
self::access_refresh()) {
                
$js .= 'setTimeout(\'dvz_shoutbox.loop()\', ' . (float)$mybb->settings['dvz_sb_interval'] . ' * 1000);' PHP_EOL;
            }

            if (
self::access_recall()) {
                
$js .= 'dvz_shoutbox.recalling = true;' PHP_EOL;
            }

            
$javascript '
<script>
$js '
dvz_shoutbox.firstId = ' 
$firstId ';
dvz_shoutbox.lastId = ' 
$lastId ';
dvz_shoutbox.appendControls();
dvz_shoutbox.updateActivity();
</script>'
;

            eval(
'$dvz_shoutbox = "' $templates->get('dvz_shoutbox') . '";');


        }
    }

    static function 
show_archive ()
    {
        global 
$db$mybb$templates$lang$theme$footer$headerinclude$header$charset;

        
$lang->load('dvz_shoutbox');

        
header('Content-type: text/html; charset=' $charset);

        
add_breadcrumb($lang->dvz_sb_shoutbox"index.php?action=shoutbox_archive");

        
// moderation panel
        
if (self::access_mod()) {

            if (isset(
$mybb->input['banlist']) && verify_post_check($mybb->input['postkey'])) {
                
self::banlist_update($mybb->input['banlist']);
            }

            if (isset(
$mybb->input['days']) && verify_post_check($mybb->input['postkey'])) {
                if (
$mybb->input['days'] == 'all') {
                    
self::clear();
                } else {
                    
$allowed = [273090];
                    if (
in_array($mybb->input['days'], $allowed)) {
                        
self::clear($mybb->input['days']);
                    }
                }
            }

            
$blocked_users htmlspecialchars_uni($mybb->settings['dvz_sb_blocked_users']);
            eval(
'$modoptions = "' $templates->get("dvz_shoutbox_archive_modoptions") . '";');

        } else {
            
$modoptions null;
        }

        
// pagination
        
$items   self::count();
        
$page    abs((int)$mybb->input['page']);
        
$perPage abs((int)$mybb->settings['dvz_sb_num_archive']);

        if (
$perPage == 0) {
            
$pages 0;
        } else {
            
$pages   ceil($items $perPage);
        }

        if (!
$page || $page || $page $pages$page 1;

        
$start = ($page 1) * $perPage;

        if (
$items $perPage) {
            
$multipage multipage($items$perPage$page'index.php?action=shoutbox_archive');
        }


        
$data self::get_multiple("WHERE s.text IS NOT NULL ORDER by s.id DESC LIMIT $start,$perPage");

        
$archive null;

        while (
$row $db->fetch_array($data)) {
            
$archive .= self::render_shout($rowtrue);
        }

        
$javascript '
<script>
dvz_shoutbox.lang = [\'' 
$lang->dvz_sb_delete_confirm '\', \'' str_replace('{ANTIFLOOD}', (float)$mybb->settings['dvz_sb_antiflood'], $lang->dvz_sb_antiflood) . '\', \'' $lang->dvz_sb_permissions '\'];
</script>'
;

        eval(
'$content = "' $templates->get("dvz_shoutbox_archive") . '";');

        
output_page($content);

        exit;
    }

    static function 
user_merge ()
    {
        global 
$db$source_user$destination_user;
        return 
$db->update_query('dvz_shoutbox', ['uid' => $destination_user['uid']], 'uid=' . (int)$source_user['uid']);
    }

    static function 
activity (&$user_activity)
    {
        
$location parse_url($user_activity['location']);
        
$filename basename($location['path']);

        
parse_str(html_entity_decode($location['query']), $parameters);

        if (
$filename == 'index.php' && $parameters['action'] == 'shoutbox_archive') {
            
$user_activity['activity'] = 'dvz_shoutbox_archive';
        }
    }

    static function 
activity_translate (&$data)
    {
        global 
$lang;

        
$lang->load('dvz_shoutbox');

        if (
$data['user_activity']['activity'] == 'dvz_shoutbox_archive') {
            
$data['location_name'] = sprintf($lang->dvz_sb_activity'index.php?action=shoutbox_archive');
        }
    }

    static function 
clearcookies ()
    {
        global 
$remove_cookies;
        
$remove_cookies[] = 'dvz_sb_status';
    }

    
// data manipulation
    
static function get ($id)
    {
        global 
$db;
        return 
$db->fetch_array$db->simple_select('dvz_shoutbox''*''id=' . (int)$id) );
    }

    static function 
get_multiple ($clauses)
    {
        global 
$db;
        return 
$db->query("
            SELECT
                s.*, u.username, u.usergroup, u.displaygroup, u.avatar
            FROM
                " 
TABLE_PREFIX "dvz_shoutbox s
                LEFT JOIN " 
TABLE_PREFIX "users u ON u.uid = s.uid
            " 
$clauses "
        "
);
    }

    static function 
get_username ($id)
    {
        global 
$db;
        return 
$db->fetch_field(
            
$db->query("SELECT username FROM " TABLE_PREFIX "users u, " TABLE_PREFIX "dvz_shoutbox s WHERE u.uid=s.uid AND s.id=" . (int)$id),
            
'username'
        
);
    }

    static function 
user_last_shout_time ($uid)
    {
        global 
$db;
        return 
$db->fetch_field(
            
$db->simple_select('dvz_shoutbox''date''uid=' . (int)$uid, [
                
'order_by'  => 'date',
                
'order_dir' => 'desc',
                
'limit'     => 1,
            ]),
            
'date'
        
);
    }

    static function 
count ()
    {
        global 
$db;
        return 
$db->fetch_field(
            
$db->simple_select('dvz_shoutbox''COUNT(*) as n'),
            
'n'
        
);
    }

    static function 
shout ($data)
    {
        global 
$mybb$db;

        if (
$mybb->settings['dvz_sb_maxlength'] > 0) {
            
$data['text'] = mb_substr($data['text'], 0$mybb->settings['dvz_sb_maxlength']);
        }

        foreach (
$data as &$item) {
            
$item $db->escape_string($item);
        }

        
$data['date'] = TIME_NOW;

        return 
$db->insert_query('dvz_shoutbox'$data);
    }

    static function 
update ($id$text)
    {
        global 
$db;
        return 
$db->update_query('dvz_shoutbox', [
            
'text'     => $db->escape_string($text),
            
'modified' => time(),
        ], 
'id=' . (int)$id);
    }

    static function 
banlist_update ($new)
    {
        global 
$db;

        
$db->update_query('settings', ['value' => $db->escape_string($new)], "name='dvz_sb_blocked_users'");

        
rebuild_settings();
    }

    static function 
delete ($id)
    {
        global 
$mybb$db;

        if (
$mybb->settings['dvz_sb_sync']) {
            return 
$db->update_query('dvz_shoutbox', [
                
'text'     => 'NULL',
                
'modified' => time(),
            ], 
'id=' . (int)$idfalsetrue);
        } else {
            return 
$db->delete_query('dvz_shoutbox''id=' . (int)$id);
        }
    }

    static function 
clear ($days false)
    {
        global 
$db;

        if (
$days) {
            
$where 'date < ' . ( TIME_NOW - ((int)$days 86400) );
        } else {
            
$where false;
        }

        return 
$db->delete_query('dvz_shoutbox'$where);
    }

    
// permissions
    
static function is_user ()
    {
        global 
$mybb;
        return 
$mybb->user['uid'] != 0;
    }

    static function 
is_blocked ()
    {
        global 
$mybb;
        return 
in_array($mybb->user['uid'], self::settings_get_csv('blocked_users'));
    }

    static function 
access_view ()
    {
        
$array self::settings_get_csv('groups_view');
        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_refresh ()
    {
        
$array self::settings_get_csv('groups_refresh');
        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_shout ()
    {
        
$array self::settings_get_csv('groups_shout');

        return (
            
self::is_user() &&
            !
self::is_blocked() &&
            (
                
self::access_mod() ||
                (
                    
self::access_view() &&
                    
self::access_minposts() &&
                    
$array[0] == -|| is_member($array)
                )
            )
        );
    }

    static function 
access_recall ()
    {
        
$array self::settings_get_csv('groups_recall');
        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_mod ()
    {
        global 
$mybb;

        
$array self::settings_get_csv('groups_mod');

        return (
            (
$array[0] == -|| is_member($array)) ||
            (
$mybb->settings['dvz_sb_supermods'] && $mybb->usergroup['issupermod'])
        );
    }

    static function 
access_mod_own ()
    {
        
$array self::settings_get_csv('groups_mod_own');

        return 
$array[0] == -|| is_member($array);
    }

    static function 
access_minposts ()
    {
        global 
$mybb;
        return 
$mybb->user['postnum'] >= $mybb->settings['dvz_sb_minposts'];
    }

    static function 
can_mod ($shoutId)
    {
        global 
$mybb;

        if (
self::access_mod()) {
            return 
true;
        } else if (
self::access_mod_own() && self::access_shout()) {

            
$data self::get($shoutId);

            if (
$data['uid'] == $mybb->user['uid']) {
                return 
true;
            }

        }

        return 
false;

    }

    
// core
    
static function render_shout ($data$static false)
    {
        global 
$mybb;

        
$id       $data['id'];
        
$text     self::parse($data['text'], $data['username']);
        
$date     htmlspecialchars_uni(my_date($mybb->settings['dvz_sb_dateformat'], $data['date']));
        
$username htmlspecialchars_uni($data['username']);
        
$user     '<a href="member.php?action=profile&uid=' . (int)$data['uid'] . '">' format_name($username$data['usergroup'], $data['displaygroup']) . '</a>';
        
$avatar   '<img src="' . (empty($data['avatar']) ? htmlspecialchars_uni($mybb->settings['useravatar']) : htmlspecialchars_uni($data['avatar'])) . '" alt="avatar" />';

        
$notes      null;
        
$attributes null;

        
$own $data['uid'] == $mybb->user['uid'];

        if (
$static) {

            if (
self::access_mod()) {
                
$notes .= '<span class="ip">' my_inet_ntop($data['ipaddress']) . '</span>';
            }

            if (
                
self::access_mod() ||
                (
self::access_mod_own() && $own)
            ) {
                
$notes .= '<a href="" class="mod edit">E</a><a href="" class="mod del">X</a>';
            }

        }

        if (
            
self::access_mod() ||
            (
self::access_mod_own() && $own)
        ) {
            
$attributes .= ' data-mod';
        }

        if (
$own) {
            
$attributes .= ' data-own';
        }

        if(
$mybb->user['ignorelist'] != ''
    {
    
$ignlist explode(","$mybb->user['ignorelist']);
    if(!empty(
$ignlist) && in_array($data['uid'], $ignlisttrue)) 
        {
        
$text '<span style="font-style: italic; font-size: 0.85em;">' self::parse('Użytkownik jest przez ciebie ignorowany.'$data['username']) . '</span>';
        }
    } 

        return 
'
<div class="entry" data-id="' 
$id '" data-username="' $username '"' $attributes '>
    <div class="avatar">' 
$avatar '</div>
    <div class="user">' 
$user '</div>
    <div class="text">' 
$text '</div>
    <div class="info">' 
$notes '<span class="date">' $date '</span></div>
</div>'
;
    }

    static function 
parse ($message$me_username)
    {
        global 
$mybb;

        require_once 
MYBB_ROOT 'inc/class_parser.php';

        
$parser = new postParser;
        
$options = [
            
'allow_mycode'    => $mybb->settings['dvz_sb_mycode'],
            
'allow_smilies'   => $mybb->settings['dvz_sb_smilies'],
            
'allow_imgcode'   => 0,
            
'filter_badwords' => 1,
            
'me_username'     => $me_username,
        ];

        return 
$parser->parse_message($message$options);
    }

    static function 
antiflood_pass ()
    {
        global 
$mybb;
        return (
            !
$mybb->settings['dvz_sb_antiflood'] ||
            ( 
TIME_NOW self::user_last_shout_time($mybb->user['uid']) ) > $mybb->settings['dvz_sb_antiflood']
        );
    }

    static function 
settings_get_csv ($name)
    {
        global 
$mybb;
        return 
array_filterexplode(','$mybb->settings['dvz_sb_' $name]) );
    }


function 
dvz_shoutbox_stats()
{
    global 
$db$mybb$templates$theme$wpisy$users$top_spamer$users_online_o$top_spamer_noformatted$shshshs$our_shouts$timesearch$shouts$username$user$users_online$anon_online$invisiblemark$onlinemembers$guests_online$spiders$cache$bots_online;
    
    
// Użytkownicy online
    
    
$timesearch TIME_NOW $mybb->settings['wolcutoff'];
    
$comma '';
    
$query3 $db->query("
        SELECT s.sid, s.ip, s.uid, s.time, s.location, s.location1, u.username, u.invisible, u.usergroup, u.displaygroup
        FROM "
.TABLE_PREFIX."sessions s
        LEFT JOIN "
.TABLE_PREFIX."users u ON (s.uid=u.uid)
        WHERE `location` LIKE '%gamebox.php%' && s.time>'"
.$timesearch."'
        ORDER BY u.username ASC, s.time DESC
    "
);

    
$spiders $cache->read("spiders");
    
    
$users_online 0;
    
$anon_online 0;
    
$guests_online 0;
    
$bots_online 0;
    
$onlinemembers '';
    
    while(
$user $db->fetch_array($query3))
    {
        if(
$user['uid'] > 0)
        {
            if(
$user['invisible'] == 1)
            {
                ++
$anon_online;
            }
            
            if(
$user['invisible'] != || $mybb->usergroup['canviewwolinvis'] == || $user['uid'] == $mybb->user['uid'])
            {
                if(
$user['invisible'] == 1)
                {
                    
$invisiblemark "*";
                }
                else
                {
                    
$invisiblemark '';
                }
                ++
$anon_online;
                
                
$username build_profile_link(format_name($user['username'], $user['usergroup'], $user['displaygroup']), $user['uid']);
                
$onlinemembers .= ''.$comma.' '.$username.''.$invisiblemark.'';
                
$comma " ,";
            }
            ++
$users_online;
        }
        elseif(
my_strpos($user['sid'], "bot=") !== false && $spiders[$botkey])
        {
            
// The user is a search bot.
            
$onlinemembers .= $comma.format_name($spiders[$botkey]['name'], $spiders[$botkey]['usergroup']);
            
$comma ", ";
            ++
$bots_online;
        }
        else
        {
            
// The user is a guest.
            
++$guests_online;
        }
        
        
$users_online_o $users_online $guests_online;
    }
    
// Statystyki
    
    
$query $db->query("SELECT count(id) as id FROM ".TABLE_PREFIX."dvz_shoutbox");
    
    
$row $db->fetch_array($query);
    
$wpisy $row['id'];
    
    
$query3 $db->query("SELECT d.uid, u.username, u.usergroup, u.displaygroup, u.uid, u.avatar, count(*) as shouters 
                          FROM "
.TABLE_PREFIX."dvz_shoutbox d
                          LEFT JOIN "
.TABLE_PREFIX."users u ON (u.uid=d.uid)
                          GROUP BY d.uid 
                          ORDER BY shouters
                          DESC LIMIT 1"
);
    
$row3 $db->fetch_array($query3);
    
    
$shouts $row3['shouters'];
    
$top_spamer_noformatted $row3['username'];
    
$top_spamer build_profile_link(format_name($row3['username'], $row3['usergroup'], $row3['displaygroup']), $row3['uid']);
    
    
$query4 $db->query("SELECT count(id) as id, uid FROM ".TABLE_PREFIX."dvz_shoutbox WHERE uid='".$mybb->user['uid']."'");
    
    
$our_shouts $db->fetch_field($query4"id");
}

function 
dvz_shoutbox_users_on_sb()
{
    global 
$db$mybb$templates$theme$users_o_sb$timesearch;
    
    
$timesearch TIME_NOW $mybb->settings['wolcutoff'];
    
$query $db->query("SELECT count(*) as guid, time FROM ".TABLE_PREFIX."sessions WHERE `location` LIKE '%gamebox.php%' && uid!=0 && time>".$timesearch."");
    
$users_o_sb $db->fetch_field($query'guid');


Plik dvz_shoutbox w wersji 2.1 z tymi samymi zmiennymi
http://wklejto.pl/231219
W dwóch ostatnich funkcjach (tych dodatkowych) globalizujesz zmienną $templates. Mam rozumieć, że używałeś do tego jakiegoś szablonu. Więc teraz użyj eval(), tak jak to jest np. w linii 582 kodu, który wrzuciłeś na wklejto.pl.
Oczywiście używając prawidłowej zmiennej oraz szablonu.
Prośby na PW dotyczące wsparcia z problemami będą ignorowane. Pomoc poza forum - odpłatna; kontakt: snakemybboard@gmail.com.
Niej więcej mam coś takiego tylko pytanie czy jak podepnę się we fragment kodu pluginu koło 743 linii z zapisem, będzie prawidłowy
<script>
' . $js . '
dvz_shoutbox.firstId ' . $firstId . ';
dvz_shoutbox.lastId ' . $lastId . ';
dvz_shoutbox.appendControls();
dvz_shoutbox.updateActivity();
</
script>';

            eval('
$dvz_shoutbox "' . $templates->get('dvz_shoutbox') . '";');
            eval('
$dvz_shoutbox_big "' . $templates->get('dvz_shoutbox_shout_big') . '";');


        }
    } 
Nie. Tego drugiego eval() musisz wprowadzić w funkcjach dodanych przez Ciebie. O ile w ogóle dążę w kierunku prawidłowym...
Prośby na PW dotyczące wsparcia z problemami będą ignorowane. Pomoc poza forum - odpłatna; kontakt: snakemybboard@gmail.com.



Użytkownicy przeglądający ten wątek:

1 gości