RE: Problème DVZ shoutbox 
				
					Citation :<?php 
/* by Tomasz 'Devilshakerz' Mlynski [devilshakerz.com]; Copyright © 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('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">« {$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() ? 0 : (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 = [2, 7, 30, 90]; 
                    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 < 1 || $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($row, true); 
        } 
 
        $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)$id, false, true); 
        } 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] == -1 || is_member($array); 
    } 
 
    static function access_refresh () 
    { 
        $array = self::settings_get_csv('groups_refresh'); 
        return $array[0] == -1 || 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] == -1 || is_member($array) 
                ) 
            ) 
        ); 
    } 
 
    static function access_recall () 
    { 
        $array = self::settings_get_csv('groups_recall'); 
        return $array[0] == -1 || is_member($array); 
    } 
 
    static function access_mod () 
    { 
        global $mybb; 
 
        $array = self::settings_get_csv('groups_mod'); 
 
        return ( 
            ($array[0] == -1 || 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] == -1 || 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'; 
        } 
 
        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_filter( explode(',', $mybb->settings['dvz_sb_' . $name]) ); 
    } 
 
} 
 
				 
				
				
				
				
				 
			 |