Webboard

Pełna wersja: Dvz shoutbox na podstronie
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
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

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

Zwraca błąd na pod stronie

Kod:
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
Kod PHP:
<?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

Kod 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
Kod PHP:
<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
Kod PHP:
<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

Kod:
<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}

Kod PHP:
<?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:
Kod:
<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 />
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
Kod PHP:
<?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.
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
Kod PHP:
<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...