function event_hook($event, &$bag, &$eventData, $addData = null)
 {
     global $serendipity;
     $hooks =& $bag->get('event_hooks');
     if (isset($hooks[$event])) {
         switch ($event) {
             case 'entry_display':
                 if (!is_array($eventData)) {
                     return false;
                 }
                 $elements = count($eventData);
                 for ($i = 0; $i < $elements; $i++) {
                     if (empty($eventData[$i]['body'])) {
                         continue;
                     }
                     # see if we want the edit link.  (Only in extended mode)
                     /* Disable because Serendipity 0.8 delivers this.
                        if ($addData['extended']) {
                            if ($_SESSION['serendipityAuthedUser'] === true && ($_SESSION['serendipityUserlevel'] >= USERLEVEL_CHIEF || $_SESSION['serendipityAuthorid'] == $eventData[$i]['authorid'])) {
                                $eventData[$i]['add_footer'] .= ' | ';
                                $eventData[$i]['add_footer'] .= '<a href="' . $serendipity['baseURL'] . 'serendipity_admin.php?serendipity[action]=admin&amp;serendipity[adminModule]=entries&amp;serendipity[adminAction]=edit&amp;serendipity[id]=' . $eventData[$i]['id'] . '">';
                                $eventData[$i]['add_footer'] .= EDIT;
                                $eventData[$i]['add_footer'] .= '</a>';
                            }
                        }
                        */
                     if ($_SESSION['serendipityAuthedUser'] === true && ($_SESSION['serendipityUserlevel'] >= USERLEVEL_CHIEF || $_SESSION['serendipityAuthorid'] == $eventData[$i]['authorid'])) {
                         if (!isset($eventData[$i]['add_footer'])) {
                             $eventData[$i]['add_footer'] = '';
                         }
                         $eventData[$i]['add_footer'] .= ' | ';
                         $eventData[$i]['add_footer'] .= '<a href="' . $serendipity['baseURL'] . 'serendipity_admin.php?serendipity[action]=admin&amp;serendipity[adminModule]=entries&amp;serendipity[adminAction]=delete&amp;serendipity[id]=' . $eventData[$i]['id'] . '&amp;' . serendipity_setFormToken('url') . '">';
                         $eventData[$i]['add_footer'] .= DELETE;
                         $eventData[$i]['add_footer'] .= '</a>';
                     }
                 }
                 return true;
                 break;
             default:
                 return false;
         }
     } else {
         return false;
     }
 }
    function showElementEntrylist($filter = array(), $limit = 0)
    {
        global $serendipity;
        $filter_sql = implode(' AND ', $filter);
        $orderby = 'timestamp DESC';
        // Fetch the entries
        $entries = serendipity_fetchEntries(false, false, $limit, true, false, $orderby, $filter_sql);
        $rows = 0;
        if (!is_array($entries)) {
            return;
        }
        foreach ($entries as $entry) {
            $rows++;
            // Find out if the entry has been modified later than 30 minutes after creation
            if ($entry['timestamp'] <= $entry['last_modified'] - 60 * 30) {
                $lm = '<a href="#" title="' . LAST_UPDATED . ': ' . serendipity_formatTime(DATE_FORMAT_SHORT, $entry['last_modified']) . '" onclick="alert(this.title)"><img src="' . serendipity_getTemplateFile('admin/img/clock.png') . '" alt="*" style="border: 0px none ; vertical-align: bottom;" /></a>';
            } else {
                $lm = '';
            }
            if (!$serendipity['showFutureEntries'] && $entry['timestamp'] >= serendipity_serverOffsetHour()) {
                $entry_pre = '<a href="#" title="' . ENTRY_PUBLISHED_FUTURE . '" onclick="alert(this.title)"><img src="' . serendipity_getTemplateFile('admin/img/clock_future.png') . '" alt="*" style="border: 0px none ; vertical-align: bottom;" /></a> ';
            } else {
                $entry_pre = '';
            }
            if (serendipity_db_bool($entry['properties']['ep_is_sticky'])) {
                $entry_pre .= ' ' . STICKY_POSTINGS . ': ';
            }
            if (serendipity_db_bool($entry['isdraft'])) {
                $entry_pre .= ' ' . DRAFT . ': ';
            }
            ?>
            <div class="serendipity_admin_list_item serendipity_admin_list_item_<?php 
            echo $rows % 2 ? 'even' : 'uneven';
            ?>
">

                <table width="100%" cellspacing="0" cellpadding="3">
                    <tr>
                        <td>
                            <strong><?php 
            echo $entry_pre;
            ?>
<a href="?serendipity[action]=admin&amp;serendipity[adminModule]=entries&amp;serendipity[adminAction]=edit&amp;serendipity[id]=<?php 
            echo $entry['id'];
            ?>
" title="#<?php 
            echo $entry['id'];
            ?>
"><?php 
            echo serendipity_truncateString(function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['title']) : htmlspecialchars($entry['title'], ENT_COMPAT, LANG_CHARSET), 50);
            ?>
</a></strong>
                        </td>
                        <td align="right">
                            <?php 
            echo serendipity_formatTime(DATE_FORMAT_SHORT, $entry['timestamp']) . ' ' . $lm;
            ?>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <?php 
            echo POSTED_BY . ' ' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['author']) : htmlspecialchars($entry['author'], ENT_COMPAT, LANG_CHARSET));
            if (count($entry['categories'])) {
                echo ' ' . IN . ' ';
                $cats = array();
                foreach ($entry['categories'] as $cat) {
                    $caturl = serendipity_categoryURL($cat);
                    $cats[] = '<a href="' . $caturl . '">' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($cat['category_name']) : htmlspecialchars($cat['category_name'], ENT_COMPAT, LANG_CHARSET)) . '</a>';
                }
                echo implode(', ', $cats);
            }
            $entry['link'] = serendipity_archiveURL($entry['id'], $entry['title'], 'serendipityHTTPPath', true, array('timestamp' => $entry['timestamp']));
            $entry['preview_link'] = '?serendipity[noBanner]=true&amp;serendipity[noSidebar]=true&amp;serendipity[action]=admin&amp;serendipity[adminModule]=entries&amp;serendipity[adminAction]=preview&amp;serendipity[id]=' . $entry['id'];
            ?>

                        </td>
                        <td align="right">
                            <?php 
            if (serendipity_db_bool($entry['isdraft']) || !$serendipity['showFutureEntries'] && $entry['timestamp'] >= serendipity_serverOffsetHour()) {
                ?>
                            <a target="_blank" href="<?php 
                echo $entry['preview_link'];
                ?>
&amp;<?php 
                echo serendipity_setFormToken('url');
                ?>
" title="<?php 
                echo PREVIEW . ' #' . $entry['id'];
                ?>
" class="serendipityIconLink"><img src="<?php 
                echo serendipity_getTemplateFile('admin/img/zoom.png');
                ?>
" alt="<?php 
                echo PREVIEW;
                ?>
" /><?php 
                echo PREVIEW;
                ?>
</a>
                            <?php 
            } else {
                ?>
                            <a target="_blank" href="<?php 
                echo $entry['link'];
                ?>
" title="<?php 
                echo VIEW . ' #' . $entry['id'];
                ?>
" class="serendipityIconLink"><img src="<?php 
                echo serendipity_getTemplateFile('admin/img/zoom.png');
                ?>
" alt="<?php 
                echo VIEW;
                ?>
" /><?php 
                echo VIEW;
                ?>
</a>
                            <?php 
            }
            ?>
                            <a href="?serendipity[action]=admin&amp;serendipity[adminModule]=entries&amp;serendipity[adminAction]=edit&amp;serendipity[id]=<?php 
            echo $entry['id'];
            ?>
" title="<?php 
            echo EDIT . ' #' . $entry['id'];
            ?>
" class="serendipityIconLink"><img src="<?php 
            echo serendipity_getTemplateFile('admin/img/edit.png');
            ?>
" alt="<?php 
            echo EDIT;
            ?>
" /><?php 
            echo EDIT;
            ?>
</a>
                        </td>
                    </tr>
                </table>
            </div>
<?php 
        }
        // end entries output
    }
/**
 * Show the list of plugins
 *
 * Shows a HTML list of all installed plugins, complete with config/delete/sort order options
 *
 * @access public
 * @param  boolean  Indicates if event plugins (TRUE) or sidebar plugins (FALSE) shall be shown
 * @return null
 */
function show_plugins($event_only = false, $sidebars = null)
{
    static $opts = array('event' => PLUGIN_ACTIVE, 'eventh' => PLUGIN_INACTIVE);
    global $serendipity;
    $sql_filter = '';
    if (is_array($sidebars)) {
        foreach ($sidebars as $sidebar) {
            $up = strtoupper($sidebar);
            if ($sidebar == 'hide') {
                $opts[$sidebar] = HIDDEN;
            } elseif (defined('SIDEBAR_' . $up)) {
                $opts[$sidebar] = constant('SIDEBAR_' . $up);
            } elseif (defined($up)) {
                $opts[$sidebar] = constant($up);
            } else {
                $opts[$sidebar] = $up;
            }
            $sql_filter .= "AND placement != '" . serendipity_db_escape_string($sidebar) . "' ";
        }
    }
    if (!$event_only) {
        $sql = "SELECT * from {$serendipity['dbPrefix']}plugins\n                   WHERE placement != 'event'\n                     AND placement != 'eventh'\n                         " . $sql_filter;
        $invisible_plugins = serendipity_db_query($sql);
        if (is_array($invisible_plugins)) {
            $sidebars[] = 'NONE';
            $opts['NONE'] = NONE;
        }
    }
    $eyecandy = !isset($serendipity['eyecandy']) || serendipity_db_bool($serendipity['eyecandy']);
    if (!$eyecandy) {
        echo '    <form action="?serendipity[adminModule]=plugins" method="post">';
    } elseif (!$event_only) {
        echo '<script type="text/javascript"> function templatePluginMoverInit() { ';
        $is_first = true;
        foreach ($sidebars as $sidebar) {
            ?>
    <?php 
            echo $is_first ? 'var ' : '';
            ?>
 list = document.getElementById("<?php 
            echo $sidebar;
            ?>
_col");
    DragDrop.makeListContainer(list, 'g1');
    list.onDragOver = function() { this.style["border"] = "1px solid #4d759b"; };
    list.onDragOut = function() { this.style["border"] = "none"; };
<?php 
            $is_first = false;
        }
        echo ' } addLoadEvent(templatePluginMoverInit);</script>';
        echo '    <form action="?serendipity[adminModule]=plugins" method="post" onsubmit="pluginMovergetSort(); return true">';
        echo '        <input type="hidden" name="serendipity[pluginorder]" id="order" value="" />';
    } else {
        echo '<script type="text/javascript">addLoadEvent(pluginMoverInitEvent);</script>';
        echo '    <form action="?serendipity[adminModule]=plugins" method="post" onsubmit="pluginMovergetSortEvent(); return true">';
        echo '        <input type="hidden" name="serendipity[pluginorder]" id="eventorder" value="" />';
    }
    echo serendipity_setFormToken();
    ?>
    <table class="pluginmanager" border="0" cellpadding="5" cellspacing="3" width="100%">
        <tr>
<?php 
    $errors = array();
    /* Block display the plugins per placement location. */
    if ($event_only) {
        $plugin_placements = array('event', 'eventh');
    } else {
        $plugin_placements = $sidebars;
    }
    $total = 0;
    foreach ($plugin_placements as $plugin_placement) {
        if (!$event_only && $plugin_placement == 'NONE') {
            $is_invisible = true;
        } else {
            $is_invisible = false;
        }
        $ptitle = $opts[$plugin_placement];
        $pid = $plugin_placement;
        echo '<td class="pluginmanager_side pluginmanager_' . ($event_only ? 'event' : 'sidebar') . '">';
        echo '<div class="heading">' . $ptitle . '</div>';
        echo '<ol id="' . $pid . '_col" class="pluginmanager_container">';
        if ($is_invisible) {
            $plugins = $invisible_plugins;
        } else {
            $plugins = serendipity_plugin_api::enum_plugins($plugin_placement);
        }
        if (!is_array($plugins)) {
            continue;
        }
        $sort_idx = 0;
        foreach ($plugins as $plugin_data) {
            $total++;
            $plugin =& serendipity_plugin_api::load_plugin($plugin_data['name'], $plugin_data['authorid']);
            $key = urlencode($plugin_data['name']);
            $css_key = 's9ycid' . str_replace('%', '-', $key);
            $is_plugin_owner = $plugin_data['authorid'] == $serendipity['authorid'] || serendipity_checkPermission('adminPluginsMaintainOthers');
            $is_plugin_editable = $is_plugin_owner || $plugin_data['authorid'] == '0';
            if (!is_object($plugin)) {
                $name = $title = ERROR . '!';
                $desc = ERROR . ': ' . $plugin_data['name'];
                $can_configure = false;
            } else {
                /* query for its name, description and configuration data */
                $bag = new serendipity_property_bag();
                $plugin->introspect($bag);
                $name = htmlspecialchars($bag->get('name'));
                $desc = htmlspecialchars($bag->get('description'));
                $desc .= '<br />' . VERSION . ': <em>' . $bag->get('version') . '</em>';
                $title = serendipity_plugin_api::get_plugin_title($plugin, '[' . $name . ']');
                if ($bag->is_set('configuration') && ($plugin->protected === FALSE || $plugin_data['authorid'] == '0' || $plugin_data['authorid'] == $serendipity['authorid'] || serendipity_checkPermission('adminPluginsMaintainOthers'))) {
                    $can_configure = true;
                } else {
                    $can_configure = false;
                }
            }
            if ($event_only) {
                $place = placement_box('serendipity[placement][' . $plugin_data['name'] . ']', $plugin_data['placement'], $is_plugin_editable, true, $opts);
                $event_only_uri = '&amp;serendipity[event_plugin]=true';
            } else {
                $place = placement_box('serendipity[placement][' . $plugin_data['name'] . ']', $plugin_data['placement'], $is_plugin_editable, false, $opts);
                $event_only_uri = '';
            }
            /* Only display UP/DOWN links if there's somewhere for the plugin to go */
            if ($sort_idx == 0) {
                $moveup = '&nbsp;';
            } else {
                $moveup = '<a href="?' . serendipity_setFormToken('url') . '&amp;serendipity[adminModule]=plugins&amp;submit=move+up&amp;serendipity[plugin_to_move]=' . $key . $event_only_uri . '" style="border: 0"><img src="' . serendipity_getTemplateFile('admin/img/uparrow.png') . '" height="16" width="16" border="0" alt="' . UP . '" /></a>';
            }
            if ($sort_idx == count($plugins) - 1) {
                $movedown = '&nbsp;';
            } else {
                $movedown = ($moveup != '' ? '&nbsp;' : '') . '<a href="?' . serendipity_setFormToken('url') . '&amp;serendipity[adminModule]=plugins&amp;submit=move+down&amp;serendipity[plugin_to_move]=' . $key . $event_only_uri . '" style="border: 0"><img src="' . serendipity_getTemplateFile('admin/img/downarrow.png') . '" height="16" width="16" alt="' . DOWN . '" border="0" /></a>';
            }
            ?>
            <li class="pluginmanager_item_<?php 
            echo $sort_idx % 2 ? 'even' : 'uneven';
            ?>
" id="<?php 
            echo $css_key;
            ?>
">
                <div id="g<?php 
            echo $css_key;
            ?>
" class="pluginmanager_grablet">
                    <a href="#" id="grab<?php 
            echo $css_key;
            ?>
"></a>
                </div>
                <?php 
            if ($is_plugin_editable) {
                ?>
                    <input class="input_checkbox" type="checkbox" name="serendipity[plugin_to_remove][]" value="<?php 
                echo $plugin_data['name'];
                ?>
" />
                <?php 
            }
            ?>

                <?php 
            if ($can_configure) {
                ?>
                    <a class="pluginmanager_configure" href="?serendipity[adminModule]=plugins&amp;serendipity[plugin_to_conf]=<?php 
                echo $key;
                ?>
"><img src="<?php 
                echo serendipity_getTemplateFile('admin/img/configure.png');
                ?>
" style="border: 0; vertical-align: bottom;" alt="[C]" /></a>
                <?php 
            }
            ?>

                    <span class="pluginmanager_title">
                <?php 
            if ($can_configure) {
                ?>
                    <a title="<?php 
                echo $plugin_data['name'];
                ?>
" href="?serendipity[adminModule]=plugins&amp;serendipity[plugin_to_conf]=<?php 
                echo $key;
                ?>
"><?php 
                echo $title;
                ?>
</a>
                <?php 
            } else {
                ?>
                    <?php 
                echo $title;
                ?>
                <?php 
            }
            ?>
</span><br />
                    <div class="pluginmanager_description" style="font-size: 8pt"><?php 
            echo $desc;
            ?>
</div>
                    <div class="pluginmanager_ownership"><?php 
            ownership($plugin_data['authorid'], $plugin_data['name'], $is_plugin_owner);
            ?>
</div>
                    <?php 
            echo $eyecandy ? '<noscript>' : '';
            ?>
                    <div class="pluginmanager_place"><?php 
            echo $place;
            ?>
</div>
                    <div class="pluginmanager_move"><?php 
            echo $moveup;
            ?>
 <?php 
            echo $movedown;
            ?>
</div>
                    <?php 
            echo $eyecandy ? '</noscript>' : '';
            ?>
            </li>
<?php 
            $sort_idx++;
        }
        echo '</ol></td>';
    }
    ?>
        </tr>
        <tr>
            <td colspan="3" align="right"><?php 
    printf(PLUGIN_AVAILABLE_COUNT, $total);
    ?>
</td>
        </tr>
        </table>
        <br />
        <div>
            <input type="submit" name="REMOVE" title="<?php 
    echo DELETE;
    ?>
"  value="<?php 
    echo REMOVE_TICKED_PLUGINS;
    ?>
" class="serendipityPrettyButton input_button" />
            <input type="submit" name="SAVE"   title="<?php 
    echo SAVE_CHANGES_TO_LAYOUT;
    ?>
" value="<?php 
    echo SAVE;
    ?>
" class="serendipityPrettyButton input_button" />
        </div>
</form>
<?php 
}
/**
 * Prints a media item
 *
 * @param  array    Array of image metadata
 * @param  string   URL for maintenance tasks
 * @param  boolean  Whether to show maintenance task items
 * @param  int      how many media items to display per row
 * @param  boolean  Enclose within a table cell?
 * @param  array    Additional Smarty variables
 * @return string   Generated HTML
 *
 */
function serendipity_showMedia(&$file, &$paths, $url = '', $manage = false, $lineBreak = 3, $enclose = true, $smarty_vars = array())
{
    global $serendipity;
    $form_hidden = '';
    // do not add, if not for the default media list form
    if (($serendipity['GET']['adminAction'] == 'default' || empty($serendipity['GET']['adminAction'])) && !$serendipity['GET']['fid']) {
        foreach ($serendipity['GET'] as $g_key => $g_val) {
            // do not add token, since this is assigned separately to properties and list forms
            if (!is_array($g_val) && $g_key != 'page' && $g_key != 'token') {
                $form_hidden .= '        <input type="hidden" name="serendipity[' . $g_key . ']" value="' . serendipity_specialchars($g_val) . '">' . "\n";
            }
        }
    }
    if (!is_object($serendipity['smarty'])) {
        serendipity_smarty_init();
    }
    $order_fields = serendipity_getImageFields();
    // reset filename for building template filters, since this is hardcoded as 'only_filename'
    unset($order_fields['i.name']);
    $media = array('manage' => $manage, 'multiperm' => serendipity_checkPermission('adminImagesDirectories'), 'lineBreak' => $lineBreak, 'lineBreakP' => round(1 / $lineBreak * 100), 'url' => $url, 'enclose' => $enclose, 'token' => serendipity_setFormToken(), 'form_hidden' => $form_hidden, 'blimit_path' => empty($smarty_vars['limit_path']) ? '' : basename($smarty_vars['limit_path']), 'only_path' => $serendipity['GET']['only_path'], 'only_filename' => $serendipity['GET']['only_filename'], 'sortorder' => $serendipity['GET']['sortorder'], 'keywords_selected' => $serendipity['GET']['keywords'], 'filter' => $serendipity['GET']['filter'], 'sort_order' => $order_fields, 'simpleFilters' => $serendipity['simpleFilters'], 'hideSubdirFiles' => $serendipity['GET']['hideSubdirFiles'], 'authors' => serendipity_fetchUsers(), 'sort_row_interval' => array(8, 16, 50, 100), 'nr_files' => count($file), 'keywords' => explode(';', $serendipity['mediaKeywords']), 'thumbSize' => $serendipity['thumbSize'], 'sortParams' => array('perpage', 'order', 'ordermode'));
    $media = array_merge($media, $smarty_vars);
    $media['files'] =& $file;
    if (count($paths) > 0) {
        $media['paths'] =& $paths;
    } else {
        $media['paths'] =& serendipity_getMediaPaths();
    }
    $serendipity['smarty']->assignByRef('media', $media);
    if ($enclose) {
        serendipity_smarty_fetch('MEDIA_ITEMS', 'admin/media_items.tpl');
        return serendipity_smarty_show('admin/media_pane.tpl');
    } else {
        serendipity_smarty_fetch('MEDIA_ITEMS', 'admin/media_items.tpl');
        return serendipity_smarty_show('admin/media_properties.tpl');
    }
}
/**
 * Prints the form for editing/creating new blog entries
 *
 * This is the core file where your edit form appears. The Heart Of Gold, so to say.
 *
 * @access public
 * @param   string      The URL where the entry form is submitted to
 * @param   array       An array of hidden input fields that should be passed on to the HTML FORM
 * @param   array       The entry superarray with your entry's contents
 * @param   string      Any error messages that might have occured on the last run
 * @return null
 */
function serendipity_printEntryForm($targetURL, $hiddens = array(), $entry = array(), $errMsg = "")
{
    global $serendipity;
    $draftD = '';
    $draftP = '';
    $categoryselector_expanded = false;
    $template_vars = array();
    serendipity_plugin_api::hook_event('backend_entryform', $entry);
    if (isset($entry['isdraft']) && serendipity_db_bool($entry['isdraft']) || !isset($entry['isdraft']) && $serendipity['publishDefault'] == 'draft') {
        $draftD = ' selected="selected"';
        $template_vars['draft_mode'] = 'draft';
    } else {
        $draftP = ' selected="selected"';
        $template_vars['draft_mode'] = 'publish';
    }
    if (isset($entry['moderate_comments']) && serendipity_db_bool($entry['moderate_comments'])) {
        $template_vars['moderate_comments'] = true;
        $moderate_comments = ' checked="checked"';
    } elseif (!isset($entry['moderate_comments']) && ($serendipity['moderateCommentsDefault'] == 'true' || $serendipity['moderateCommentsDefault'] === true)) {
        // This is the default on creation of a new entry and depends on the "moderateCommentsDefault" variable of the configuration.
        $moderate_comments = ' checked="checked"';
        $template_vars['moderate_comments'] = true;
    } else {
        $moderate_comments = '';
        $template_vars['moderate_comments'] = false;
    }
    if (isset($entry['allow_comments']) && serendipity_db_bool($entry['allow_comments'])) {
        $template_vars['allow_comments'] = true;
        $allow_comments = ' checked="checked"';
    } elseif ((!isset($entry['allow_comments']) || $entry['allow_comments'] !== 'false') && (!isset($serendipity['allowCommentsDefault']) || $serendipity['allowCommentsDefault'] == 'true' || $serendipity['allowCommentsDefault'] === true)) {
        // This is the default on creation of a new entry and depends on the "allowCommentsDefault" variable of the configuration.
        $template_vars['allow_comments'] = true;
        $allow_comments = ' checked="checked"';
    } else {
        $template_vars['allow_comments'] = false;
        $allow_comments = '';
    }
    // Fix category list. If the entryForm is displayed after a POST request, the additional category information is lost.
    if (is_array($entry['categories']) && !is_array($entry['categories'][0])) {
        $categories = (array) $entry['categories'];
        $entry['categories'] = array();
        foreach ($categories as $catid) {
            $entry['categories'][] = serendipity_fetchCategoryInfo($catid);
        }
    }
    $selected = array();
    if (is_array($entry['categories'])) {
        if (count($entry['categories']) > 1) {
            $categoryselector_expanded = true;
        }
        foreach ($entry['categories'] as $cat) {
            $selected[] = $cat['categoryid'];
        }
    }
    if (count($selected) > 1 || isset($serendipity['POST']['categories']) && is_array($serendipity['POST']['categories']) && sizeof($serendipity['POST']['categories']) > 1) {
        $categoryselector_expanded = true;
    }
    if (is_array($cats = serendipity_fetchCategories())) {
        $cats = serendipity_walkRecursive($cats, 'categoryid', 'parentid', VIEWMODE_THREADED);
        foreach ($cats as $cat) {
            if (in_array($cat['categoryid'], $selected)) {
                $cat['is_selected'] = true;
            }
            $cat['depth_pad'] = str_repeat('&nbsp;', $cat['depth']);
            $template_vars['category_options'][] = $cat;
        }
    }
    if (!empty($serendipity['GET']['title'])) {
        $entry['title'] = utf8_decode(urldecode($serendipity['GET']['title']));
    }
    if (!empty($serendipity['GET']['body'])) {
        $entry['body'] = utf8_decode(urldecode($serendipity['GET']['body']));
    }
    if (!empty($serendipity['GET']['url'])) {
        $entry['body'] .= "\n" . '<a class="block_level" href="' . serendipity_specialchars(utf8_decode(urldecode($serendipity['GET']['url']))) . '">' . $entry['title'] . '</a>';
    }
    $template_vars['formToken'] = serendipity_setFormToken();
    if (isset($serendipity['allowDateManipulation']) && $serendipity['allowDateManipulation']) {
        $template_vars['allowDateManipulation'] = true;
    }
    if ((!empty($entry['extended']) || !empty($serendipity['COOKIE']['toggle_extended'])) && !$serendipity['wysiwyg']) {
        $template_vars['show_wysiwyg'] = true;
    }
    $template_vars['wysiwyg_advanced'] = true;
    $template_vars['timestamp'] = serendipity_serverOffsetHour(isset($entry['timestamp']) && $entry['timestamp'] > 0 ? $entry['timestamp'] : time());
    $template_vars['reset_timestamp'] = serendipity_serverOffsetHour(time());
    $template_vars['hiddens'] = $hiddens;
    $template_vars['errMsg'] = $errMsg;
    $template_vars['entry'] =& $entry;
    $template_vars['targetURL'] = $targetURL;
    $template_vars['cat_count'] = count($cats) + 1;
    $template_vars['wysiwyg'] = $serendipity['wysiwyg'];
    $template_vars['serendipityRightPublish'] = $_SESSION['serendipityRightPublish'];
    $template_vars['wysiwyg_blocks'] = array('body' => 'serendipity[body]', 'extended' => 'serendipity[extended]');
    $template_vars['entry_template'] = serendipity_getTemplateFile('admin/entries.tpl', 'serendipityPath');
    if (!is_object($serendipity['smarty'])) {
        serendipity_smarty_init();
    }
    $serendipity['smarty']->registerPlugin('modifier', 'emit_htmlarea_code', 'serendipity_emit_htmlarea_code');
    $serendipity['smarty']->assign('admin_view', 'entryform');
    serendipity_plugin_api::hook_event('backend_entryform_smarty', $template_vars);
    $serendipity['smarty']->assignByRef('entry_vars', $template_vars);
    return serendipity_smarty_show('admin/entries.tpl');
}
/**
 * Prints a media item
 *
 * @param  array    Array of image metadata
 * @param  string   URL for maintenance tasks
 * @param  boolean  Whether to show maintenance task items
 * @param  int      how many media items to display per row
 * @param  boolean  Enclose within a table cell?
 * @param  array    Additional Smarty variables
 * @param  boolean  If TRUE, will echo Smarty output.
 * @return string   Smarty block name
 *
 */
function serendipity_showMedia(&$file, &$paths, $url = '', $manage = false, $lineBreak = 3, $enclose = true, $smarty_vars = array(), $smarty_display = true)
{
    global $serendipity;
    $form_hidden = '';
    foreach ($serendipity['GET'] as $g_key => $g_val) {
        if (!is_array($g_val) && $g_key != 'page') {
            $form_hidden .= '<input type="hidden" name="serendipity[' . $g_key . ']" value="' . htmlspecialchars($g_val) . '" />';
        }
    }
    serendipity_smarty_init();
    $media = array('manage' => $manage, 'lineBreak' => $lineBreak, 'lineBreakP' => round(1 / $lineBreak * 100), 'url' => $url, 'enclose' => $enclose, 'zoomIMG' => serendipity_getTemplateFile('admin/img/big_zoom.png'), 'renameIMG' => serendipity_getTemplateFile('admin/img/big_rename.png'), 'resizeIMG' => serendipity_getTemplateFile('admin/img/big_resize.png'), 'rotatecwIMG' => serendipity_getTemplateFile('admin/img/big_rotate_cw.png'), 'rotateccwIMG' => serendipity_getTemplateFile('admin/img/big_rotate_ccw.png'), 'configureIMG' => serendipity_getTemplateFile('admin/img/configure.png'), 'deleteIMG' => serendipity_getTemplateFile('admin/img/big_delete.png'), 'prevIMG' => serendipity_getTemplateFile('admin/img/previous.png'), 'nextIMG' => serendipity_getTemplateFile('admin/img/next.png'), 'token' => serendipity_setFormToken(), 'form_hidden' => $form_hidden, 'blimit_path' => basename($limit_path), 'only_path' => $serendipity['GET']['only_path'], 'only_filename' => $serendipity['GET']['only_filename'], 'sortorder' => $serendipity['GET']['sortorder'], 'keywords_selected' => $serendipity['GET']['keywords'], 'filter' => $serendipity['GET']['filter'], 'sort_order' => serendipity_getImageFields(), 'authors' => serendipity_fetchUsers(), 'sort_row_interval' => array(8, 16, 50, 100), 'nr_files' => count($file), 'keywords' => explode(';', $serendipity['mediaKeywords']));
    $media = array_merge($media, $smarty_vars);
    $media['files'] =& $file;
    if (count($paths) > 0) {
        $media['paths'] =& $paths;
    } else {
        $media['paths'] =& serendipity_getMediaPaths();
    }
    $serendipity['smarty']->assign_by_ref('media', $media);
    if ($enclose) {
        serendipity_smarty_fetch('MEDIA_ITEMS', 'admin/media_items.tpl');
        $block = 'admin/media_pane.tpl';
        if ($smarty_display) {
            $serendipity['smarty']->display(serendipity_getTemplateFile('admin/media_pane.tpl', 'serendipityPath'));
        }
    } else {
        serendipity_smarty_fetch('MEDIA_ITEMS', 'admin/media_items.tpl');
        $block = 'admin/media_properties.tpl';
        if ($smarty_display) {
            $serendipity['smarty']->display(serendipity_getTemplateFile('admin/media_properties.tpl', 'serendipityPath'));
        }
    }
    return $block;
}
Esempio n. 7
0
        $comment['fullBody'] = $comment['body'];
        $comment['summary'] = serendipity_mb('substr', $comment['body'], 0, 100);
        if (strlen($comment['fullBody']) > strlen($comment['summary'])) {
            $comment['excerpt'] = true;
            // When summary is not the full body, strip HTML tags from summary, as it might break and leave unclosed HTML.
            $comment['fullBody'] = nl2br(serendipity_specialchars($comment['fullBody']));
            $comment['summary'] = nl2br(strip_tags($comment['summary']));
        }
    }
}
$data['comments'] = $comments;
$entries = serendipity_fetchEntries(false, false, (int) $serendipity['dashboardLimit'], true, false, 'timestamp DESC', 'e.timestamp >= ' . serendipity_serverOffsetHour());
$entriesAmount = count($entries);
if ($entriesAmount < (int) $serendipity['dashboardDraftLimit']) {
    // there is still space for drafts
    $drafts = serendipity_fetchEntries(false, false, (int) $serendipity['dashboardDraftLimit'] - $entriesAmount, true, false, 'timestamp DESC', "isdraft = 'true' AND e.timestamp <= " . serendipity_serverOffsetHour());
    if (is_array($entries) && is_array($drafts)) {
        $entries = array_merge($entries, $drafts);
    } else {
        if (is_array($drafts)) {
            // $entries is not an array, thus empty
            $entries = $drafts;
        }
    }
}
$data['entries'] = $entries;
$data['urltoken'] = serendipity_setFormToken('url');
$data['token'] = serendipity_setFormToken();
$data['no_create'] = $serendipity['no_create'];
echo serendipity_smarty_show('admin/overview.inc.tpl', $data);
/* vim: set sts=4 ts=4 expandtab : */
/**
 * Prints the form for editing/creating new blog entries
 *
 * This is the core file where your edit form appears. The Heart Of Gold, so to say.
 *
 * @access public
 * @param   string      The URL where the entry form is submitted to
 * @param   array       An array of hidden input fields that should be passed on to the HTML FORM
 * @param   array       The entry superarray with your entry's contents
 * @param   string      Any error messages that might have occured on the last run
 * @return null
 */
function serendipity_printEntryForm($targetURL, $hiddens = array(), $entry = array(), $errMsg = "")
{
    global $serendipity;
    $serendipity['EditorBrowsers'] = '@(IE|Mozilla|Opera)@i';
    $draftD = '';
    $draftP = '';
    $categoryselector_expanded = false;
    $template_vars = array();
    serendipity_plugin_api::hook_event('backend_entryform', $entry);
    if (isset($entry['isdraft']) && serendipity_db_bool($entry['isdraft']) || !isset($entry['isdraft']) && $serendipity['publishDefault'] == 'draft') {
        $draftD = ' selected="selected"';
        $template_vars['draft_mode'] = 'draft';
    } else {
        $draftP = ' selected="selected"';
        $template_vars['draft_mode'] = 'publish';
    }
    if (isset($entry['moderate_comments']) && serendipity_db_bool($entry['moderate_comments'])) {
        $template_vars['moderate_comments'] = true;
        $moderate_comments = ' checked="checked"';
    } elseif (!isset($entry['moderate_comments']) && ($serendipity['moderateCommentsDefault'] == 'true' || $serendipity['moderateCommentsDefault'] === true)) {
        // This is the default on creation of a new entry and depends on the "moderateCommentsDefault" variable of the configuration.
        $moderate_comments = ' checked="checked"';
        $template_vars['moderate_comments'] = true;
    } else {
        $moderate_comments = '';
        $template_vars['moderate_comments'] = false;
    }
    if (isset($entry['allow_comments']) && serendipity_db_bool($entry['allow_comments'])) {
        $template_vars['allow_comments'] = true;
        $allow_comments = ' checked="checked"';
    } elseif ((!isset($entry['allow_comments']) || $entry['allow_comments'] !== 'false') && (!isset($serendipity['allowCommentsDefault']) || $serendipity['allowCommentsDefault'] == 'true' || $serendipity['allowCommentsDefault'] === true)) {
        // This is the default on creation of a new entry and depends on the "allowCommentsDefault" variable of the configuration.
        $template_vars['allow_comments'] = true;
        $allow_comments = ' checked="checked"';
    } else {
        $template_vars['allow_comments'] = false;
        $allow_comments = '';
    }
    // Fix category list. If the entryForm is displayed after a POST request, the additional category information is lost.
    if (is_array($entry['categories']) && !is_array($entry['categories'][0])) {
        $categories = (array) $entry['categories'];
        $entry['categories'] = array();
        foreach ($categories as $catid) {
            $entry['categories'][] = serendipity_fetchCategoryInfo($catid);
        }
    }
    $n = "\n";
    $cat_list = '<select id="categoryselector" name="serendipity[categories][]" style="vertical-align: middle;" multiple="multiple">' . $n;
    $cat_list .= '    <option value="0">[' . NO_CATEGORY . ']</option>' . $n;
    $selected = array();
    if (is_array($entry['categories'])) {
        if (count($entry['categories']) > 1) {
            $categoryselector_expanded = true;
        }
        foreach ($entry['categories'] as $cat) {
            $selected[] = $cat['categoryid'];
        }
    }
    if (count($selected) > 1 || isset($serendipity['POST']['categories']) && is_array($serendipity['POST']['categories']) && sizeof($serendipity['POST']['categories']) > 1) {
        $categoryselector_expanded = true;
    }
    if (is_array($cats = serendipity_fetchCategories())) {
        $cats = serendipity_walkRecursive($cats, 'categoryid', 'parentid', VIEWMODE_THREADED);
        foreach ($cats as $cat) {
            if (in_array($cat['categoryid'], $selected)) {
                $cat['is_selected'] = true;
            }
            $cat['depth_pad'] = str_repeat('&nbsp;', $cat['depth']);
            $template_vars['category_options'][] = $cat;
            $cat_list .= '<option value="' . $cat['categoryid'] . '"' . ($cat['is_selected'] ? ' selected="selected"' : '') . '>' . $cat['depth_pad'] . $cat['category_name'] . '</option>' . "\n";
        }
    }
    $cat_list .= '</select>' . $n;
    if (!empty($serendipity['GET']['title'])) {
        $entry['title'] = utf8_decode(urldecode($serendipity['GET']['title']));
    }
    if (!empty($serendipity['GET']['body'])) {
        $entry['body'] = utf8_decode(urldecode($serendipity['GET']['body']));
    }
    if (!empty($serendipity['GET']['url'])) {
        $entry['body'] .= "\n" . '<br /><a href="' . htmlspecialchars(utf8_decode(urldecode($serendipity['GET']['url']))) . '">' . $entry['title'] . '</a>';
    }
    $hidden = '';
    foreach ($hiddens as $key => $value) {
        $hidden .= '        <input type="hidden" name="' . $key . '" value="' . $value . '" />' . $n;
    }
    $hidden .= '        <input type="hidden" id="entryid" name="serendipity[id]" value="' . (isset($entry['id']) ? $entry['id'] : '') . '" />' . $n;
    $hidden .= '        <input type="hidden" name="serendipity[timestamp]" value="' . (isset($entry['timestamp']) ? serendipity_serverOffsetHour($entry['timestamp']) : serendipity_serverOffsetHour(time())) . '" />' . $n;
    $hidden .= '        <input type="hidden" name="serendipity[preview]" value="false" />';
    $hidden .= '        ' . serendipity_setFormToken();
    if (is_object($serendipity['smarty']) || !$_SESSION['no_smarty'] && serendipity_smarty_init()) {
        $use_smarty = true;
    } else {
        $use_smarty = false;
    }
    if (is_object($serendipity['smarty'])) {
        if (isset($serendipity['allowDateManipulation']) && $serendipity['allowDateManipulation']) {
            $template_vars['allowDateManipulation'] = true;
        }
        if ((!empty($entry['extended']) || !empty($serendipity['COOKIE']['toggle_extended'])) && !$serendipity['wysiwyg']) {
            $template_vars['show_wysiwyg'] = true;
        }
        if (preg_match($serendipity['EditorBrowsers'], $_SERVER['HTTP_USER_AGENT'])) {
            $template_vars['wysiwyg_advanced'] = true;
        }
        $template_vars['timestamp'] = serendipity_serverOffsetHour(isset($entry['timestamp']) && $entry['timestamp'] > 0 ? $entry['timestamp'] : time());
        $template_vars['reset_timestamp'] = serendipity_serverOffsetHour(time());
        $template_vars['hidden'] = $hidden;
        $template_vars['errMsg'] = $errMsg;
        $template_vars['entry'] =& $entry;
        $template_vars['targetURL'] = $targetURL;
        $template_vars['cat_count'] = count($cats) + 1;
        $template_vars['cat_state'] = $categoryselector_expanded ? 'on' : 'off';
        $template_vars['wysiwyg'] = $serendipity['wysiwyg'];
        $template_vars['serendipityRightPublish'] = $_SESSION['serendipityRightPublish'];
        $template_vars['wysiwyg_blocks'] = array('body' => 'serendipity[body]', 'extended' => 'serendipity[extended]');
        $template_vars['entry_template'] = serendipity_getTemplateFile('admin/entries.tpl', 'serendipityPath');
        $serendipity['smarty']->registerPlugin('modifier', 'emit_htmlarea_code', 'serendipity_emit_htmlarea_code');
        $serendipity['smarty']->assign('admin_view', 'entryform');
        serendipity_plugin_api::hook_event('backend_entryform_smarty', $template_vars);
        $serendipity['smarty']->assignByRef('entry_vars', $template_vars);
        $serendipity['smarty']->display($template_vars['entry_template']);
        return true;
    }
    /* HTML CODE BELOW IS FOR FALLBACK PORTABILITY ONLY - MODIFY CODE IN TEMPLATE ADMIN/ENTRIES.TPL INSTEAD! */
    if (!empty($errMsg)) {
        ?>
        <div class="serendipityAdminMsgError"><img style="width: 22px; height: 22px; border: 0px; padding-right: 4px; vertical-align: middle" src="<?php 
        echo serendipity_getTemplateFile('admin/img/admin_msg_error.png');
        ?>
" alt="" /><?php 
        echo $errMsg;
        ?>
</div>
<?php 
    }
    ?>
        <form <?php 
    echo $entry['entry_form'];
    ?>
 action="<?php 
    echo $targetURL;
    ?>
" method="post" id="serendipityEntry" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px">
        <?php 
    echo $hidden;
    ?>

        <table class="serendipityEntryEdit" border="0" width="100%">
            <tr>
                <td>
                   <b><?php 
    echo TITLE;
    ?>
:</b>
                </td>
                <td colspan="2">
                    <table width="100%" cellspacing="0" cellpadding="0" border="0">
                        <tr>
                            <td><input class="input_textbox" type="text" id="entryTitle" name="serendipity[title]" value="<?php 
    echo isset($entry['title']) ? htmlspecialchars($entry['title']) : '';
    ?>
" size="60" /></td>
                            <td align="right">
                                <select name="serendipity[isdraft]">
                                    <?php 
    if ($_SESSION['serendipityRightPublish']) {
        ?>
<option  value="false" <?php 
        echo $draftP;
        ?>
><?php 
        echo PUBLISH;
        ?>
</option><?php 
    }
    ?>
                                    <option  value="true"  <?php 
    echo $draftD;
    ?>
><?php 
    echo DRAFT;
    ?>
</option>
                                </select>
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
            <tr>
<?php 
    if (isset($serendipity['allowDateManipulation']) && $serendipity['allowDateManipulation']) {
        ?>
                <td>
                    <b><?php 
        echo DATE;
        ?>
:</b>
                </td>
                <td>
                    <input type="hidden" name="serendipity[chk_timestamp]" value="<?php 
        echo serendipity_serverOffsetHour(isset($entry['timestamp']) && $entry['timestamp'] > 0 ? $entry['timestamp'] : time());
        ?>
" />
                    <input class="input_textbox" type="text" name="serendipity[new_timestamp]" id="serendipityNewTimestamp" value="<?php 
        echo date(DATE_FORMAT_2, serendipity_serverOffsetHour(isset($entry['timestamp']) && $entry['timestamp'] > 0 ? $entry['timestamp'] : time()));
        ?>
" />
                    <a href="#" onclick="document.getElementById('serendipityNewTimestamp').value = '<?php 
        echo date(DATE_FORMAT_2, serendipity_serverOffsetHour(time()));
        ?>
'; return false;" title="<?php 
        echo RESET_DATE_DESC;
        ?>
"><img src="<?php 
        echo serendipity_getTemplateFile('admin/img/clock.png');
        ?>
" border="0"  style="vertical-align: text-top;" alt="<?php 
        echo RESET_DATE;
        ?>
" /></a>
                </td>
                <td align="right">
<?php 
    } else {
        ?>
                <td align="right" colspan="3">
<?php 
    }
    ?>
                    <a style="border:0; text-decoration: none" href="#" onclick="showItem('categoryselector'); return false" title="<?php 
    echo TOGGLE_OPTION;
    ?>
"><img src="<?php 
    echo serendipity_getTemplateFile('img/plus.png');
    ?>
" id="option_categoryselector" style="border: 20px" alt="" border="0" /></a> <b><?php 
    echo CATEGORY;
    ?>
:</b> <?php 
    echo $cat_list;
    ?>
                    <script type="text/javascript" language="JavaScript">

                    function toggle_extended(setCookie) {
                        var textarea = document.getElementById('serendipity[extended]');
                        var button   = document.getElementById('option_extended');
                        var tools    = document.getElementById('tools_extended');
                        if ( textarea.style.display == 'none' ) {
                            textarea.style.display = '';
                            tools.style.display = '';
                            button.src = '<?php 
    echo serendipity_getTemplateFile('img/minus.png');
    ?>
';
                            if (setCookie == true) {
                                document.cookie = 'serendipity[toggle_extended]=true;';
                            }
                        } else {
                            textarea.style.display = 'none';
                            tools.style.display = 'none';
                            button.src = '<?php 
    echo serendipity_getTemplateFile('img/plus.png');
    ?>
';
                            if (setCookie == true) {
                                document.cookie = 'serendipity[toggle_extended]=;';
                            }
                        }
                    }

                    var selector_toggle  = new Array();
                    var selector_store   = new Array();
                    var selector_restore = new Array();

                    function showItem(id) {
                        var selected = 0;
                        if (typeof(id) == 'undefined' || typeof(id) == 'object') {
                            id = 'categoryselector';
                        }

                        if (document.getElementById) {
                            el = document.getElementById(id);
                            if (selector_toggle[id] && selector_toggle[id] == 'off') {
                                selector_restore[id] = new Array();
                                selector_toggle[id]  = 'on';

                                /* Hack to make sure that when the single dropdown is shown, don't have multiple selections */
                                last = 0;

                                for (i=0; i < el.options.length; i++) {
                                    if (el.options[i].selected == true) {
                                        selected++;
                                        last = i;
                                        selector_restore[id][last] = 'on';
                                    }

                                    if (selected > 1) {
                                        /* If there is more than one selected, we reset all those to false
                                           This is because otherwise the label will say 'No Category', but the categories will still be selected */
                                        for (j=0; j < el.options.length; j++) {
                                            /* Save selection in array to later restore them */
                                            if (el.options[j].selected == true) {
                                                el.options[j].selected = false;
                                                selector_restore[id][j] = 'on';
                                                last = j;
                                            } else {
                                                selector_restore[id][j] = false;
                                            }
                                        }
                                        break;
                                    }
                                }

                                el.selectedIndex = null;
                                if (last > 0) {
                                    el.selectedIndex = last;
                                }

                                el.size = 1;

                                /* Show a normal dropdown */
                                if (el.multiple) {
                                    el.multiple = false;
                                }

                                document.getElementById('option_' + id).src = '<?php 
    echo serendipity_getTemplateFile('img/plus.png');
    ?>
';
                            } else {
                                selector_store[id] = el.size;
                                if (selector_store[id] == 0) {
                                    selector_store[id] = 5;
                                }

                                last = 0;
                                if (el.selectedIndex > 0) {
                                    if (!selector_restore[id]) {
                                        selector_restore[id] = new Array();
                                    }

                                    for (j=0; j < el.options.length; j++) {
                                        /* Save selection in array to later restore them */
                                        if (el.options[j].selected == true) {
                                            selector_restore[id][j] = 'on';
                                            last = j;
                                        }
                                    }
                                }
                                el.selectedIndex = -1;
                                el.size = <?php 
    echo count($cats) + 1;
    ?>
;
                                selector_toggle[id] = 'off';

                                /* Show multiple items */
                                el.multiple = true;

                                /* Restore previously selected items? */
                                last = 0;
                                for (i = 0; i < el.options.length; i++) {
                                    if (selector_restore && selector_restore[id] && selector_restore[id][i] && selector_restore[id][i] == 'on') {
                                        val = el.options[i].value;
                                        if (el.options[i].selected != true) {
                                            el.options[i].selected = true;
                                            last = i;
                                            // [TODO] IE Bug: Don't ask me why, but this restoring only works in Internet Explorer if you put this:
                                            // alert('it doesnt matter what, just the alert is important');
                                        }
                                    }
                                }

                                document.getElementById('option_' + id).src = '<?php 
    echo serendipity_getTemplateFile('img/minus.png');
    ?>
';
                            }
                        }
                    }

                    function checkSave() {
<?php 
    $void = null;
    serendipity_plugin_api::hook_event('backend_entry_checkSave', $void);
    ?>
                        return true;
                    }

                    selector_toggle['categoryselector'] = '<?php 
    echo $categoryselector_expanded ? 'on' : 'off';
    ?>
';
                    addLoadEvent(showItem);
                    </script>
                    </td>
            </tr>
            <tr>
<?php 
    if (!$serendipity['wysiwyg']) {
        ?>
                <td colspan="2"><b><?php 
        echo ENTRY_BODY;
        ?>
</b></td>
                <td align="right">
<?php 
        /* Since the user has WYSIWYG editor disabled, we want to check if we should use the "better" non-WYSIWYG editor */
        if (!$serendipity['wysiwyg'] && preg_match($serendipity['EditorBrowsers'], $_SERVER['HTTP_USER_AGENT'])) {
            ?>
                  <script type="text/javascript" language="JavaScript">
                        document.write('<input type="button" class="serendipityPrettyButton input_button" name="insI" value="I" accesskey="i" style="font-style: italic" onclick="wrapSelection(document.forms[\'serendipityEntry\'][\'serendipity[body]\'],\'<em>\',\'</em>\')" />');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" name="insB" value="B" accesskey="b" style="font-weight: bold" onclick="wrapSelection(document.forms[\'serendipityEntry\'][\'serendipity[body]\'],\'<strong>\',\'</strong>\')" />');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" name="insU" value="U" accesskey="u" style="text-decoration: underline;" onclick="wrapSelection(document.forms[\'serendipityEntry\'][\'serendipity[body]\'],\'<u>\',\'</u>\')" />');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" name="insQ" value="<?php 
            echo QUOTE;
            ?>
" accesskey="q" style="font-style: italic" onclick="wrapSelection(document.forms[\'serendipityEntry\'][\'serendipity[body]\'],\'<blockquote>\',\'</blockquote>\')" />');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" name="insJ" value="img" accesskey="j" onclick="wrapInsImage(document.forms[\'serendipityEntry\'][\'serendipity[body]\'])" />');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" name="insImage" value="<?php 
            echo MEDIA;
            ?>
" style="" onclick="window.open(\'serendipity_admin_image_selector.php?serendipity[textarea]=body\', \'ImageSel\', \'width=800,height=600,toolbar=no,scrollbars=1,scrollbars,resize=1,resizable=1\');" />');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" name="insURL" value="URL" accesskey="l" onclick="wrapSelectionWithLink(document.forms[\'serendipityEntry\'][\'serendipity[body]\'])" />');
                  </script>
<?php 
            /* Do the "old" non-WYSIWYG editor */
        } elseif (!$serendipity['wysiwyg']) {
            ?>
                  <script type="text/javascript" language="JavaScript">
                        document.write('<input type="button" class="serendipityPrettyButton input_button" value=" B " onclick="serendipity_insBasic(document.forms[\'serendipityEntry\'][\'serendipity[body]\'], \'b\')">');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" value=" U " onclick="serendipity_insBasic(document.forms[\'serendipityEntry\'][\'serendipity[body]\'], \'u\')">');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" value=" I " onclick="serendipity_insBasic(document.forms[\'serendipityEntry\'][\'serendipity[body]\'], \'i\')">');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" value="<img>" onclick="serendipity_insImage(document.forms[\'serendipityEntry\'][\'serendipity[body]\'])">');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" value="<?php 
            echo MEDIA;
            ?>
" onclick="window.open(\'serendipity_admin_image_selector.php?serendipity[textarea]=body\', \'ImageSel\', \'width=800,height=600,toolbar=no\');">');
                        document.write('<input type="button" class="serendipityPrettyButton input_button" value="Link" onclick="serendipity_insLink(document.forms[\'serendipityEntry\'][\'serendipity[body]\'])">');
                </script>
<?php 
        }
        serendipity_plugin_api::hook_event('backend_entry_toolbar_body', $entry);
    } else {
        ?>
            <td colspan="2"><b><?php 
        echo ENTRY_BODY;
        ?>
</b></td>
            <td><?php 
        serendipity_plugin_api::hook_event('backend_entry_toolbar_body', $entry);
        ?>

<?php 
    }
    ?>
                </td>
            </tr>

            <tr>
                <td colspan="3">
                    <textarea style="width: 100%" name="serendipity[body]" id="serendipity[body]" cols="80" rows="20"><?php 
    echo isset($entry['body']) ? htmlspecialchars($entry['body']) : '';
    ?>
</textarea>
                </td>
            </tr>

            <tr>
                <td colspan="3">
                    <table width="100%" cellpadding="0" cellspacing="0">
                        <tr>
                            <td align="left" width="70%">
                                <input class="input_checkbox" id="checkbox_allow_comments" type="checkbox" name="serendipity[allow_comments]" value="true" <?php 
    echo $allow_comments;
    ?>
 /><label for="checkbox_allow_comments"><?php 
    echo COMMENTS_ENABLE;
    ?>
</label><br />
                                <input class="input_checkbox" id="checkbox_moderate_comments" type="checkbox" name="serendipity[moderate_comments]" value="true" <?php 
    echo $moderate_comments;
    ?>
 /><label for="checkbox_moderate_comments"><?php 
    echo COMMENTS_MODERATE;
    ?>
</label>
                            </td>
                            <td align="right" rowspan="2" valign="middle" width="30%">
                                <input accesskey="p" type="submit" value="- <?php 
    echo PREVIEW;
    ?>
 -" class="serendipityPrettyButton input_button"  style="width: 150px" onclick="document.forms['serendipityEntry'].elements['serendipity[preview]'].value='true';" /><br />
                                <input accesskey="s" type="submit" onclick="return checkSave();" value="- <?php 
    echo SAVE;
    ?>
 -" class="serendipityPrettyButton input_button" style="width: 150px" />
                            </td>
                        </tr>
                    </table>
                    <br />
                </td>
            </tr>

            <tr>
                <td colspan="2">
<?php 
    if (!$serendipity['wysiwyg']) {
        ?>
                    <a style="border:0; text-decoration: none" href="#" onclick="toggle_extended(true); return false;" title="<?php 
        echo TOGGLE_OPTION;
        ?>
"><img src="<?php 
        echo serendipity_getTemplateFile('img/plus.png');
        ?>
" id="option_extended" alt="+/-" border="0" /></a>
<?php 
    }
    ?>
 <b><?php 
    echo EXTENDED_BODY;
    ?>
</b></td>
                <td align="right">
                <?php 
    if (!$serendipity['wysiwyg']) {
        ?>
                    <div id="tools_extended" style="display: none">
<?php 
        /* Since the user has WYSIWYG editor disabled, we want to check if we should use the "better" non-WYSIWYG editor */
        if (preg_match($serendipity['EditorBrowsers'], $_SERVER['HTTP_USER_AGENT'])) {
            ?>
                        <input type="button" class="serendipityPrettyButton input_button" name="insI" value="I" accesskey="i" style="font-style: italic" onclick="wrapSelection(document.forms['serendipityEntry']['serendipity[extended]'],'<em>','</em>')" />
                        <input type="button" class="serendipityPrettyButton input_button" name="insB" value="B" accesskey="b" style="font-weight: bold" onclick="wrapSelection(document.forms['serendipityEntry']['serendipity[extended]'],'<strong>','</strong>')" />
                        <input type="button" class="serendipityPrettyButton input_button" name="insU" value="U" accesskey="u" style="text-decoration: underline;" onclick="wrapSelection(document.forms['serendipityEntry']['serendipity[extended]'],'<u>','</u>')" />
                        <input type="button" class="serendipityPrettyButton input_button" name="insQ" value="<?php 
            echo QUOTE;
            ?>
" accesskey="q" style="font-style: italic" onclick="wrapSelection(document.forms['serendipityEntry']['serendipity[extended]'],'<blockquote>','</blockquote>')" />
                        <input type="button" class="serendipityPrettyButton input_button" name="insJ" value="img" accesskey="j" onclick="wrapInsImage(document.forms['serendipityEntry']['serendipity[extended]'])" />
                        <input type="button" class="serendipityPrettyButton input_button" name="insImage" value="<?php 
            echo MEDIA;
            ?>
" onclick="window.open('serendipity_admin_image_selector.php?serendipity[textarea]=extended', 'ImageSel', 'width=800,height=600,toolbar=no,scrollbars=1,scrollbars,resize=1,resizable=1');" />
                        <input type="button" class="serendipityPrettyButton input_button" name="insURL" value="URL" accesskey="l" onclick="wrapSelectionWithLink(document.forms['serendipityEntry']['serendipity[extended]'])" />
<?php 
            /* Do the "old" non-WYSIWYG editor */
        } else {
            ?>
                        <input type="button" class="serendipityPrettyButton input_button" value=" B " onclick="serendipity_insBasic(document.forms['serendipityEntry']['serendipity[extended]'], 'b')">
                        <input type="button" class="serendipityPrettyButton input_button" value=" U " onclick="serendipity_insBasic(document.forms['serendipityEntry']['serendipity[extended]'], 'u')">
                        <input type="button" class="serendipityPrettyButton input_button" value=" I " onclick="serendipity_insBasic(document.forms['serendipityEntry']['serendipity[extended]'], 'i')">
                        <input type="button" class="serendipityPrettyButton input_button" value="<img>" onclick="serendipity_insImage(document.forms['serendipityEntry']['serendipity[extended]'])">
                        <input type="button" class="serendipityPrettyButton input_button" value="<?php 
            echo MEDIA;
            ?>
" onclick="window.open('serendipity_admin_image_selector.php?serendipity[textarea]=extended', 'ImageSel', 'width=800,height=600,toolbar=no');">
                        <input type="button" class="serendipityPrettyButton input_button" value="Link" onclick="serendipity_insLink(document.forms['serendipityEntry']['serendipity[extended]'])">
<?php 
        }
        serendipity_plugin_api::hook_event('backend_entry_toolbar_extended', $entry);
        ?>
                    </div>
<?php 
    } else {
        serendipity_plugin_api::hook_event('backend_entry_toolbar_extended', $entry);
    }
    ?>
               </td>
            </tr>

            <tr>
                <td colspan="3">
                    <textarea style="width: 100%;" name="serendipity[extended]" id="serendipity[extended]" cols="80" rows="20"><?php 
    echo isset($entry['extended']) ? htmlspecialchars($entry['extended']) : '';
    ?>
</textarea>
<?php 
    if (!$serendipity['wysiwyg']) {
        ?>
                    <script type="text/javascript" language="JavaScript">
                       toggle_extended();
                    </script>
<?php 
    }
    ?>
                </td>
            </tr>

            <tr>
                <td colspan="3">
                    <br />
                    <fieldset>
                        <legend><b><?php 
    echo ADVANCED_OPTIONS;
    ?>
</b></legend>
<?php 
    serendipity_plugin_api::hook_event('backend_display', $entry);
    ?>
                    </fieldset>
                </td>
            </tr>
        </table>
    </form>
<?php 
    if ((!empty($entry['extended']) || !empty($serendipity['COOKIE']['toggle_extended'])) && !$serendipity['wysiwyg']) {
        ?>
    <script type="text/javascript" language="JavaScript">
        toggle_extended();
    </script>
<?php 
    }
    if ($serendipity['wysiwyg']) {
        $fields = array('body' => 'serendipity[body]', 'extended' => 'serendipity[extended]');
        foreach ($fields as $f_jsname => $f_item) {
            serendipity_emit_htmlarea_code($f_item, $f_jsname);
        }
        serendipity_plugin_api::hook_event('backend_wysiwyg_finish', $fields);
    }
    echo '    <script type="text/javascript" language="JavaScript" src="serendipity_define.js.php"></script>';
    echo '    <script type="text/javascript" language="JavaScript" src="serendipity_editor.js"></script>';
}
Esempio n. 9
0
function showMediaLibrary($messages = false, $addvar_check = false)
{
    global $serendipity;
    if (!serendipity_checkPermission('adminImagesView')) {
        return;
    }
    if (!empty($messages)) {
        echo '<div class="imageMessage"><ul>';
        foreach ($messages as $message) {
            echo '<li>' . $message . '</li>';
        }
        echo '</ul></div>';
    }
    // After upload, do not show the list to be able to proceed to
    // media selection.
    if ($addvar_check && !empty($GLOBALS['image_selector_addvars'])) {
        return true;
    }
    ?>
<script type="text/javascript" language="javascript">
    <!--
        function rename(id, fname) {
            if(newname = prompt('<?php 
    echo ENTER_NEW_NAME;
    ?>
' + fname, fname)) {
                location.href='?<?php 
    echo serendipity_setFormToken('url');
    ?>
&serendipity[adminModule]=images&serendipity[adminAction]=rename&serendipity[fid]='+ escape(id) + '&serendipity[newname]='+ escape(newname);
            }
        }
    //-->
</script>

<?php 
    if (!isset($serendipity['thumbPerPage'])) {
        $serendipity['thumbPerPage'] = 2;
    }
    serendipity_displayImageList(isset($serendipity['GET']['page']) ? $serendipity['GET']['page'] : 1, $serendipity['thumbPerPage'], true);
}
    function showevents()
    {
        global $serendipity;
        if (!empty($serendipity['POST']['mycalendarAction']) || !empty($serendipity['POST']['event'])) {
            $this->createevents();
        }
        $events = $this->getevents();
        $events[] = array('eventid' => 0, 'eventname' => '', 'eventurl' => '', 'eventurltitle' => '', 'eventdate' => time(), 'eventdate2' => time());
        echo '<h2>' . PLUGIN_MYCALENDAR_TITLE . '</h2>';
        echo PLUGIN_MYCALENDAR_DESC . '<br /><br />';
        echo PLUGIN_MYCALENDAR_EVENTLIST . '<br /><br />';
        echo '
            <script type="text/javascript">
            function removeEvent(id) {
                document.getElementById(\'eventname_\' + id).value = \'\';
                document.getElementById(\'eventurl_\' + id).value = \'\';
                document.getElementById(\'eventaction\').value = \'GO\';
                document.getElementById(\'eventform\').submit();
            }
            isOneDayEvent = new Array();
            function changeDate(id) {
                if (isOneDayEvent[id]) {
                    document.getElementsByName(\'serendipity[event][\' + id + \'][day2]\')[0].selectedIndex =
                        document.getElementsByName(\'serendipity[event][\' + id + \'][day]\')[0].selectedIndex;
                    document.getElementsByName(\'serendipity[event][\' + id + \'][month2]\')[0].selectedIndex =
                        document.getElementsByName(\'serendipity[event][\' + id + \'][month]\')[0].selectedIndex;
                    document.getElementsByName(\'serendipity[event][\' + id + \'][year2]\')[0].selectedIndex =
                        document.getElementsByName(\'serendipity[event][\' + id + \'][year]\')[0].selectedIndex;
                }
            }
            function changeDate2(id) {
                isOneDayEvent[id] = false;
            }
            </script>

            <form id="eventform" action="?" method="post">';
        echo serendipity_setFormToken();
        echo '<div>
                <input type="hidden" name="serendipity[adminModule]" value="event_display" />
                <input type="hidden" name="serendipity[adminAction]" value="mycalendar" />
            </div>
            <table align="center" width="100%" cellpadding="10" cellspacing="0">
                <tr>
                    <th>#</th>
                    <th>' . PLUGIN_MYCALENDAR_EVENTNAME . '</th>
                    <th>' . PLUGIN_MYCALENDAR_EVENTURI . '</th>
                    <th>' . PLUGIN_MYCALENDAR_EVENTDATE . '</th>
                    <th>' . PLUGIN_MYCALENDAR_EVENTDATE2 . '</th>
                </tr>';
        foreach ($events as $idx => $event) {
            $even = $idx % 2 ? 'even' : 'uneven';
            $year = date('Y', $event['eventdate']);
            $month = date('m', $event['eventdate']);
            $day = date('d', $event['eventdate']);
            $year2 = date('Y', $event['eventdate2']);
            $month2 = date('m', $event['eventdate2']);
            $day2 = date('d', $event['eventdate2']);
            echo "<tr style='padding: 10px;' class='serendipity_admin_list_item serendipity_admin_list_item_{$even}'>\n";
            echo "  <td><em>{$idx}</em></td>\n";
            echo "  <td><input class='input_textbox' id='eventname_{$event['eventid']}' type='text' name=\"serendipity[event][{$event['eventid']}][eventname]\" value=\"" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($event['eventname']) : htmlspecialchars($event['eventname'], ENT_COMPAT, LANG_CHARSET)) . "\" /></td>\n";
            echo "  <td><input class='input_textbox' id='eventurl_{$event['eventid']}' style='width: 100%' type='text' name=\"serendipity[event][{$event['eventid']}][eventurl]\" value=\"" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($event['eventurl']) : htmlspecialchars($event['eventurl'], ENT_COMPAT, LANG_CHARSET)) . "\" /></td>\n";
            echo "  <td>";
            echo $this->getDropdown('day', $event['eventid'], range(1, 31), $day, false, 'changeDate(' . $event['eventid'] . ')') . ".";
            echo $this->getDropdown('month', $event['eventid'], range(1, 12), $month, false, 'changeDate(' . $event['eventid'] . ')') . ".";
            echo $this->getDropdown('year', $event['eventid'], range(date('Y'), date('Y') + 2), $year, false, 'changeDate(' . $event['eventid'] . ')');
            if ($event['eventdate'] < time() - 86400) {
                echo ' <a href="#" onclick="javascript:removeEvent(\'' . $event['eventid'] . '\');"><img src="' . serendipity_getTemplateFile('admin/img/delete.png') . '" alt="' . DELETE . '" border="0" /></a>';
            }
            echo "  </td>\n";
            echo "  <td>";
            echo $this->getDropdown('day2', $event['eventid'], range(1, 31), $day2, false, 'changeDate2(' . $event['eventid'] . ')') . ".";
            echo $this->getDropdown('month2', $event['eventid'], range(1, 12), $month2, false, 'changeDate2(' . $event['eventid'] . ')') . ".";
            echo $this->getDropdown('year2', $event['eventid'], range(date('Y'), date('Y') + 2), $year2, false, 'changeDate2(' . $event['eventid'] . ')');
            echo '<script type="text/javascript">';
            if ($event['eventdate'] == $event['eventdate2']) {
                echo "isOneDayEvent[{$event['eventid']}] = true;";
            } else {
                echo "isOneDayEvent[{$event['eventid']}] = false;";
            }
            echo "</script>";
            echo "  </td>\n";
            echo "</tr>\n";
            echo "<tr style='padding: 10px;' class='serendipity_admin_list_item serendipity_admin_list_item_{$even}'>\n";
            echo "  <td>&nbsp;</td>\n";
            echo "  <td>" . PLUGIN_MYCALENDAR_EVENTURI_TITLE . ": </td>\n";
            echo "  <td colspan='3'><input class='input_textbox' style='width: 100%' type='text' name=\"serendipity[event][{$event['eventid']}][eventurltitle]\" value=\"" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($event['eventurltitle']) : htmlspecialchars($event['eventurltitle'], ENT_COMPAT, LANG_CHARSET)) . "\" /></td>\n";
            echo "</tr>\n";
        }
        echo '
                <tr>
                    <td colspan="4"><br />
                        <input class="serendipityPrettyButton input_button" type="submit" id="eventaction" name="serendipity[mycalendarAction]" value="' . GO . '" />
                    </td>
                </tr>
              </table>
              </form>';
    }
    function event_hook($event, &$bag, &$eventData, $addData = null)
    {
        global $serendipity;
        $hooks =& $bag->get('event_hooks');
        if (isset($hooks[$event])) {
            // Moved from above: only get image data if we're actually going to do something
            $this->set_valid_image_data();
            // Get dimensions of image, only if not text-only
            if ($this->image_name) {
                // Is this a single-image bar, or a single segment?
                $ratio = $this->image_width / $this->image_height;
                if ($ratio < $max_segment_ratio) {
                    // This is probably a single segment. Square segments
                    // will have a ratio of 0.3; long, flat segments won't
                    // get up to 1.0 unless they're 3 times as wide as they
                    // are tall; full-bar images with square segments will
                    // be 1.666; and full-bar images with tall, narrow
                    // segments will be greater than 1.0 unless they're
                    // nearly twice as high as they are wide.
                    $this->image_width = $this->image_width * 5;
                }
            }
            switch ($event) {
                // Early hook, before any page is displayed
                case 'frontend_configure':
                    // Make sure the karmaVote cookie is set, even if empty <a name="#1" />
                    if (!isset($serendipity['COOKIE']['karmaVote'])) {
                        serendipity_setCookie('karmaVote', serialize(array()));
                    }
                    // If user didn't vote, we're done.
                    if (!isset($serendipity['GET']['karmaId']) || !isset($serendipity['GET']['karmaVote'])) {
                        return;
                    }
                    // Get URL vote data
                    $this->karmaId = (int) $serendipity['GET']['karmaId'];
                    $this->karmaVoting = (int) $serendipity['GET']['karmaVote'];
                    // karmaVote cookie was just set (see name="#1"); this boils down to
                    // "if check cookie isn't 1, there's no real cookie".
                    // The check cookie gets set when a rater is displayed,
                    // so you've got no business voting if you haven't even
                    // seen the rater yet.
                    if (!isset($serendipity['COOKIE']['karmaVote']) or $serendipity['COOKIE']['check'] != '1') {
                        $this->karmaVote = 'nocookie';
                        return;
                    }
                    // Everything is ready.  Get the cookie vote data.
                    $karma = unserialize($serendipity['COOKIE']['karmaVote']);
                    // Stop on invalid votes (cookie invalid, or URL data incorrect)
                    if (!is_array($karma) || !is_numeric($this->karmaVoting) || !is_numeric($this->karmaId) || $this->karmaVoting > 2 || $this->karmaVoting < -2) {
                        $this->karmaVote = 'invalid1';
                        return;
                    }
                    // Stop if the cookie says we already voted
                    if (!empty($karma[$this->karmaId])) {
                        $this->karmaVote = 'alreadyvoted';
                        return;
                    }
                    // We don't want bots hitting the karma-voting
                    $agent = $_SERVER['HTTP_USER_AGENT'];
                    if (stristr($agent, 'google') || stristr($agent, 'LinkWalker') || stristr($agent, 'zermelo') || stristr($agent, 'NimbleCrawler')) {
                        $this->karmaVote = 'invalid1';
                        return;
                    }
                    // Voting takes place here.
                    //
                    // Get voting data from the database (keeps all entries,
                    // even if no karma match)
                    $q = 'SELECT *
                            FROM ' . $serendipity['dbPrefix'] . 'entries AS e
                 LEFT OUTER JOIN ' . $serendipity['dbPrefix'] . 'karma   AS k
                              ON e.id = k.entryid
                           WHERE e.id = ' . serendipity_db_escape_string($this->karmaId) . ' LIMIT 1';
                    $row = serendipity_db_query($q, true);
                    // If there's no entry with this ID, we're done
                    //
                    // --TODO: Modify the plugin to allow arbitrary voting with generated IDs
                    if (!isset($row) || !is_array($row)) {
                        $this->karmaVote = 'invalid2';
                        return;
                    }
                    $now = time();
                    if ($row['votes'] === '0' || $row['votes'] > 0) {
                        // Votes for this entry already exist. Do some checking.
                        $max_entrytime = $this->get_config('max_entrytime', 1440) * 60;
                        $max_votetime = $this->get_config('max_votetime', 5) * 60;
                        $max_karmatime = $this->get_config('max_karmatime', 7) * 24 * 60 * 60;
                        // Allow infinite voting when 0 or negative
                        if ($max_karmatime <= 0) {
                            $max_karmatime = $now;
                        }
                        // If the entry's timestamp is too old for voting,
                        // we're done.
                        if ($row['timestamp'] < $now - $max_karmatime) {
                            $this->karmaVote = 'timeout2';
                            return;
                        }
                        // If the entry is in the grace period, or votes
                        // aren't too close together, record the vote.
                        if ($row['timestamp'] > $now - $max_entrytime || $row['lastvote'] + $max_votetime < $now || $row['lastvote'] == 0) {
                            // Update votes
                            $q = sprintf("UPDATE {$serendipity['dbPrefix']}karma\n                                  SET points   = %s,\n                                      votes    = %s,\n                                      lastvote = %s\n                                WHERE entryid  = %s", $row['points'] + $this->karmaVoting, $row['votes'] + 1, $now, $this->karmaId);
                            serendipity_db_query($q);
                        } else {
                            // Entry was too recently voted upon.  Figure out
                            // how long until voting will be allowed (in minutes).
                            $this->karmaVote = 'timeout';
                            $this->karmaTimeOut = abs(ceil(($now - ($row['lastvote'] + $max_votetime)) / 60));
                            return;
                        }
                    } else {
                        // No row. Use INSERT instead of UPDATE.
                        $q = sprintf("INSERT INTO {$serendipity['dbPrefix']}karma\n                                       (entryid, points, votes, lastvote, visits)\n                                VALUES (%s,      %s,     %s,    %s,       %s)", $this->karmaId, $this->karmaVoting, 1, $now, 0);
                        $sql = serendipity_db_query($q);
                    }
                    // Log the vote
                    if (serendipity_db_bool($this->get_config('logging', false))) {
                        $q = sprintf("INSERT INTO {$serendipity['dbPrefix']}karmalog\n                                       (entryid, points, ip, user_agent, votetime)\n                                VALUES (%s, %s, '%s', '%s', %s)", $this->karmaId, $this->karmaVoting, serendipity_db_escape_string($_SERVER['REMOTE_ADDR']), substr(serendipity_db_escape_string($_SERVER['HTTP_USER_AGENT']), 0, 255), $now);
                        $sql = serendipity_db_query($q);
                        if (is_string($sql)) {
                            mail($serendipity['serendipityEmail'], 'KARMA ERROR', $q . '<br />' . $sql . '<br />');
                        }
                    }
                    // Set the cookie that we already voted for this entry
                    $karma[$this->karmaId] = $this->karmaVoting;
                    $this->karmaVote = 'voted';
                    serendipity_setCookie('karmaVote', serialize($karma));
                    return true;
                    break;
                    // CSS generation hooks
                // CSS generation hooks
                case 'backend_header':
                    // Generate the CSS for the graphical rating bar selector
                    //
                    // The CSS appears to be generated in a completely
                    // different instance of Serendipity, as if index.php gets
                    // called separately for the CSS.
                    //
                    // Note that the css_backend hook adds properties to the
                    // serendipity_admin.css, but that file is *always*
                    // cached.  We use backend_header and add the CSS to the
                    // HEAD styles to make it dynamic.
                    // Get the CSS, set $this->image_name so we'll output the
                    // standard graphical CSS prologue if any images are found.
                    $this->createRatingSelector();
                    print "<style type='text/css'>\n";
                    $align = 'center';
                    $bg = $this->get_config('preview_bg', false);
                    if (!empty($bg)) {
                        if (strpos($bg, ';') !== false || strpos($bg, ',') !== false) {
                            $bg = 'red';
                        }
                        print "\n.serendipity_karmaVote_selectorTable {\n    background: {$bg};\n}\n";
                    }
                    print "\n.serendipityAdminContent .serendipity_karmaVoting_links {\n    margin: 5px;\n}\n";
                case 'css':
                    // Some CSS notes:
                    //
                    // .serendipity_karmaVoting is the class for the karma wrapper/container,
                    //      including the text explanations, messages, and rating bar.
                    //      (currently a div)
                    // .serendipity_karmaVoting a specifies the links for the text-mode
                    //      rating bar
                    // .serendipity_karmaError is the class for any text indicating an
                    //      error condition
                    // .serendipity_karmaSuccess is the class for any text indicating
                    //      successful operation
                    // .serendipity_karmaVoting_links is the container for the graphical
                    //      rating bar (currently an ol)
                    // .serendipity_karmaVoting_links a indicates the various voting links in
                    //      the graphical rating bar
                    // .serendipity_karmaVoting_current-rating is the class for the current
                    //      rating in the graphical rating bar
                    //  a.serendipity_karmaVoting_link1, _link2, etc are the classes applied
                    //      to the individual voting links
                    // Note that there are two possible template types: early
                    // templates that only handle the text rating bars, and
                    // newer templates that understand the graphical raters.
                    // We check for both types and act appropriately.
                    /*--JAM: Let's just skip this whole hassle
                      if (!$align) {
                          $align = $this->get_config('alignment', 'detect');
                      }
                      if ($align == 'detect') {
                      */
                    $align = $this->get_config('alignment', 'center');
                    // Try to let the template take care of it
                    if ($this->image_name == '0') {
                        // Text-only rating bar is used
                        if (strpos($eventData, '.serendipity_karmaVoting')) {
                            // Template is handling all our CSS
                            return true;
                        }
                    }
                    /* --JAM: else {
                               // Graphical rating bar is used
                               if (strpos($eventData, '.serendipity_karmaVoting_images')) {
                                   // Template is handling all our CSS
                                   return true;
                               }
                               // Check for old text-only templates
                               $pos = strpos($eventData, '.serendipity_karmaVoting');
                               while ($pos && ($align == 'detect')) {
                                   // Find text-align: in the current block
                                   $endpos = strpos($eventData, '}', $pos);
                                   if (!$endpos) {
                                       // Broken CSS
                                       break;
                                   }
                                   $alignpos = strpos($eventData, 'text-align:', $pos);
                                   // Can't check for comments, or I would.  Hope
                                   // the first is the correct one.
                                   if ($alignpos && $alignpos < $endpos) {
                                       $start = $alignpos + 11;
                                       $alignend = strpos($eventData, ';', $alignpos);
                                       if ($alignend)
                                       {
                                           // All valid.  Pull out the alignment.
                                           $len = $alignend - $start;
                                           $align = trim(substr($eventData, $start, $len));
                                       }
                                   }
                                   $pos = strpos($eventData, '.serendipity_karmaVoting', $endpos);
                               }
                               // I should have a valid alignment or 'detect' in $align now. 
                           }
                       }
                       // If we couldn't detect the alignment, guess 'right'
                       if ($align == 'detect') {
                           $align = 'right';
                       }
                       --JAM: END COMMENT BLOCK */
                    // Since errors might be printed at any time, always
                    // output the text-mode CSS
                    print <<<EOS
.serendipity_karmaVoting {
    text-align: {$align};
    font-size: 7pt;
    margin: 0px;
}

.serendipity_karmaVoting a {
    font-size: 7pt;
    text-decoration: none;
}

.serendipity_karmaVoting a:hover {
    color: green;
}

.serendipity_karmaError {
    color: #FF8000;
}
.serendipity_karmaSuccess {
    color: green;
}
EOS;
                    // Only output the image CSS if it's needed
                    if ($this->image_name != '0') {
                        $img = $serendipity['baseURL'] . "plugins/serendipity_event_karma/img/" . $this->image_name;
                        $h = $this->image_height / 3;
                        $w = $this->image_width;
                        switch ($align) {
                            case 'left':
                                $margin = '0px auto 0px 0px';
                                break;
                            case 'center':
                                $margin = '0px auto';
                                break;
                            case 'right':
                            default:
                                $margin = '0px 0px 0px auto';
                                break;
                        }
                        // The CSS here is lifted largely from
                        // http://komodomedia.com/blog/index.php/2007/01/20/css-star-rating-redux/
                        //
                        // Note, however that margin has been changed for
                        // multiple cases and all unitless measurements have
                        // been specified in pixels.  Additionally, measures
                        // have been taken to align the text.
                        print <<<END_IMG_CSS

.serendipity_karmaVoting_links,
.serendipity_karmaVoting_links a:hover,
.serendipity_karmaVoting_current-rating {
    background: url({$img}) left;
    font-size: 0;
}
.serendipity_karmaVoting_links {
    position: relative;
    width: {$w}px;
    height: {$h}px;
    overflow: hidden;
    list-style: none;
    margin: {$margin};
    padding: 0px;
    background-position: left top;     
    text-align: center;
}
.serendipity_karmaVoting_links li {
   display: inline; 
}
.serendipity_karmaVoting_links a ,
.serendipity_karmaVoting_current-rating {
    position:absolute;
    top: 0px;
    left: 0px;
    text-indent: -9000em;
    height: {$h}px;
    line-height: {$h}px;
    outline: none;
    overflow: hidden;
    border: none;
}
.serendipity_karmaVoting_links a:hover {
    background-position: left bottom;
}
.serendipity_karmaVoting_links a.serendipity_karmaVoting_link1 {
    width: 20%;
    z-index: 6;
}
.serendipity_karmaVoting_links a.serendipity_karmaVoting_link2 {
    width: 40%;
    z-index: 5;
}
.serendipity_karmaVoting_links a.serendipity_karmaVoting_link3 {
    width: 60%;
    z-index: 4;
}
.serendipity_karmaVoting_links a.serendipity_karmaVoting_link4 {
    width: 80%;
    z-index: 3;
}
.serendipity_karmaVoting_links a.serendipity_karmaVoting_link5 {
  width: 100%;
    z-index: 2;
}
.serendipity_karmaVoting_links .serendipity_karmaVoting_current-rating {
    z-index: 1;
    background-position: left center;
}

END_IMG_CSS;
                        // Add selector images CSS, if necessary
                        if (!empty($this->select_css)) {
                            print $this->select_css;
                        }
                    }
                    // End if image bar defined
                    if ($event == 'backend_header') {
                        print "\n</style>\n";
                    }
                    return true;
                    break;
                    //--TODO: Comment the functionality of this event hook.
                //--TODO: Comment the functionality of this event hook.
                case 'event_additional_statistics':
                    $sql = array();
                    $sql['visits_top'] = array('visits', 'DESC');
                    $sql['visits_bottom'] = array('visits', 'ASC');
                    $sql['votes_top'] = array('votes', 'DESC');
                    $sql['votes_bottom'] = array('votes', 'ASC');
                    $sql['points_top'] = array('points', 'DESC');
                    $sql['points_bottom'] = array('points', 'ASC');
                    foreach ($sql as $key => $rows) {
                        $q = "SELECT e.id,\n                                     e.title,\n                                     e.timestamp,\n                                     SUM(k.{$rows[0]}) AS no\n                                FROM {$serendipity['dbPrefix']}karma\n                                     AS k\n                                JOIN {$serendipity['dbPrefix']}entries\n                                     AS e\n                                  ON k.entryid = e.id\n                            WHERE k.{$rows[0]} IS NOT NULL AND k.{$rows[0]} != 0\n                            GROUP BY e.id, e.title, e.timestamp ORDER BY no {$rows[1]} LIMIT {$addData['maxitems']}";
                        $sql_rows = serendipity_db_query($q);
                        ?>
    <dt><strong><?php 
                        echo constant('PLUGIN_KARMA_STATISTICS_' . strtoupper($key));
                        ?>
</strong></dt>
    <dl>
<?php 
                        if (is_array($sql_rows)) {
                            foreach ($sql_rows as $id => $row) {
                                ?>
        <dt><strong><a href="<?php 
                                echo serendipity_archiveURL($row['id'], $row['title'], 'serendipityHTTPPath', true, array('timestamp' => $row['timestamp']));
                                ?>
"><?php 
                                echo htmlspecialchars($row['title']);
                                ?>
</a></strong></dt>
        <dd><?php 
                                echo $row['no'];
                                ?>
 <?php 
                                echo constant('PLUGIN_KARMA_STATISTICS_' . strtoupper($rows[0]) . '_NO');
                                ?>
</dd>
    <?php 
                            }
                        }
                        ?>
    </dl>
<?php 
                    }
                    return true;
                    break;
                    // Add voting information to entries
                // Add voting information to entries
                case 'entry_display':
                    // Update database if necessary
                    if ($this->get_config('dbversion', 0) != PLUGIN_KARMA_DB_VERSION) {
                        $this->checkScheme();
                    }
                    // Find the ID of this entry
                    if (isset($serendipity['GET']['id'])) {
                        $entryid = (int) serendipity_db_escape_string($serendipity['GET']['id']);
                    } elseif (preg_match(PAT_COMMENTSUB, $_SERVER['REQUEST_URI'], $matches)) {
                        $entryid = (int) $matches[1];
                    } else {
                        $entryid = false;
                    }
                    // If we're actually reading the entry, not voting or editing it...
                    if ($entryid && empty($serendipity['GET']['adminAction']) && !$serendipity['GET']['karmaVote']) {
                        // Update the number of visits
                        // Are we supposed to track visits?
                        $track_clicks = serendipity_db_bool($this->get_config('visits_active', true)) && $this->track_clicks_allowed_by_user();
                        if ($track_clicks && $_SERVER['REQUEST_METHOD'] == 'GET') {
                            $sql = serendipity_db_query("UPDATE {$serendipity['dbPrefix']}karma \n                                    SET visits = visits + 1 \n                                  WHERE entryid = {$entryid}", true);
                            if (serendipity_db_affected_rows() < 1) {
                                serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}karma (entryid, points, votes, lastvote, visits) \n                                              VALUES ('{$entryid}', 0, 0, 0, 1)");
                            }
                        }
                    }
                    // Set a cookie to look for later, verifying that cookies are enabled
                    serendipity_setCookie('check', '1');
                    switch ($this->karmaVote) {
                        case 'nocookie':
                            // Users with no cookies won't be able to vote.
                            $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_NOCOOKIE . '</div>';
                            // Continue until output
                        // Continue until output
                        case 'timeout2':
                            if (!isset($msg)) {
                                $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_CLOSED . '</div>';
                            }
                            // Continue until output
                        // Continue until output
                        case 'timeout':
                            if (!isset($msg)) {
                                $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . sprintf(PLUGIN_KARMA_TIMEOUT, $this->karmaTimeOut) . '</div>';
                            }
                            // Continue until output
                        // Continue until output
                        case 'alreadyvoted':
                            if (!isset($msg)) {
                                $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_ALREADYVOTED . '</div>';
                            }
                            // Continue until output
                        // Continue until output
                        case 'invalid1':
                        case 'invalid2':
                        case 'invalid':
                            // Set message
                            if (!isset($msg)) {
                                $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_INVALID . '</div>';
                            }
                            // Continue until output
                            /* OUTPUT MESSAGE */
                            //--TODO: Shouldn't this work with the cache plugin, too?
                            if ($addData['extended']) {
                                $eventData[0]['exflag'] = 1;
                                $eventData[0]['add_footer'] .= $msg;
                            } else {
                                $elements = count($eventData);
                                // Find the right container to store our message in.
                                for ($i = 0; $i < $elements; $i++) {
                                    if ($eventData[$i]['id'] == $this->karmaId) {
                                        $eventData[$i]['add_footer'] .= $msg;
                                    }
                                }
                            }
                            break;
                        case 'voted':
                        default:
                            // If there's no data, there's no need to go on
                            if (!is_array($eventData)) {
                                return;
                            }
                            // Find out what the admin wants
                            $track_clicks = serendipity_db_bool($this->get_config('visits_active', true));
                            $track_karma = serendipity_db_bool($this->get_config('karma_active', true));
                            if (serendipity_db_bool($this->get_config('karma_active_registered', false))) {
                                if (!serendipity_userLoggedIn()) {
                                    $track_karma = false;
                                }
                            }
                            $track_exits = serendipity_db_bool($this->get_config('exits_active', true));
                            // Get the limits
                            $now = time();
                            $karmatime = $this->get_config('max_karmatime', 7);
                            $max_karmatime = $karmatime * 24 * 60 * 60;
                            // Accept infinite voting
                            if ($max_karmatime <= 0) {
                                $max_karmatime = $now;
                            }
                            //--TODO: Ensure that this works with the Custom Permalinks plugin
                            // (We've seen trouble; it votes correctly, but redirects to the front page)
                            $url = serendipity_currentURL(true);
                            // Voting is only allowed on entries.  Therefore voting URLs must be
                            // either single-entry URLs or summary URLs.  serendipity_currentURL
                            // converts them to an "ErrorDocument-URI", so we can focus on the
                            // query portion of the URI.
                            //
                            // Single-entry URLs should be well-defined.  They can be permalinks,
                            // of course; otherwise they're of the configured pattern.
                            //
                            // Summary URLs could be a little harder.  The summary pages that
                            // include entries are: frontpage, category, author, and archives.
                            // It's possible a plugin would show entries, but if that's the case
                            // we don't need to allow the user to vote on them.  Still, that's
                            // a lot of URLs to check for.
                            //
                            // Then there's the problem of the rest of the query.  It could
                            // include stuff we really want to keep around, like template
                            // overrides or something.  One can even add serendipity variables
                            // to the URL in extreme cases.
                            //
                            // It seems that canonicalizing the URL will be quite difficult.
                            // The only thing we can say for certain is that whatever the
                            // current URL is, it got us to this page, and we'd like to return
                            // to this page after we cast our vote.
                            // Remove any clutter from our previous voting activity
                            $url_parts = parse_url(serendipity_currentURL(true));
                            if (!empty($url_parts['query'])) {
                                $exclude = array('serendipity[karmaVote]', 'serendipity[karmaId]');
                                // I tried using parse_str, but it gave me very weird results
                                // with embedded arrays
                                //parse_str($url_parts['query'], $q_parts);
                                $q_parts = array();
                                // I don't know why this URL has been HTML encoded.  Oh well.
                                $pairs = explode('&amp;', $url_parts['query']);
                                foreach ($pairs as $pair) {
                                    $parts = explode('=', $pair);
                                    $q_parts[$parts[0]] = $parts[1];
                                }
                                foreach ($q_parts as $key => $value) {
                                    if (in_array($key, $exclude)) {
                                        $rm = preg_quote("{$key}={$value}");
                                        $url = preg_replace("@(&amp;|&)?{$rm}@", '', $url);
                                    }
                                }
                            }
                            if (substr($url, -1) != '?') {
                                $url .= '&amp;';
                            }
                            // Get the cookie data (past votes, etc)
                            $karma = isset($serendipity['COOKIE']['karmaVote']) ? unserialize($serendipity['COOKIE']['karmaVote']) : array();
                            // Get all required entry IDs, making keys match keys in eventData
                            $entries = array();
                            if ($addData['extended'] || $addData['preview']) {
                                // We're in extended or preview mode, we only need the current ID
                                $eventData[0]['exflag'] = 1;
                                $entries[0] = (int) $eventData[0]['id'];
                            } elseif (!serendipity_db_bool($this->get_config('extended_only', false))) {
                                // We're in overview mode, and we want rating bars for all the entry IDs
                                foreach (array_keys($eventData) as $key) {
                                    if (isset($eventData[$key]['id'])) {
                                        $entries[$key] = (int) $eventData[$key]['id'];
                                    }
                                }
                            }
                            // Fetch votes for all entry IDs. Store them in an array for later usage.
                            $q = 'SELECT k.entryid, SUM(votes) AS votes, SUM(points) AS points, SUM(visits) AS visits
                                    FROM ' . $serendipity['dbPrefix'] . 'karma   AS k
                                   WHERE k.entryid IN (' . implode(', ', $entries) . ') GROUP BY k.entryid';
                            $sql = serendipity_db_query($q);
                            $rows = array();
                            if ($sql && is_array($sql)) {
                                foreach ($sql as $row) {
                                    $rows[$row['entryid']] = array('votes' => $row['votes'], 'points' => $row['points'], 'visits' => $row['visits']);
                                }
                            }
                            $this->prepareExits($entries);
                            // Add karma block to the footer of each entry
                            //
                            // The entries array was populated, above, so its keys match the eventData array,
                            // and overview entries are skipped if "extended only" is enabled
                            foreach (array_keys($entries) as $i) {
                                // Get the statistics
                                $entryid = $eventData[$i]['id'];
                                $votes = !empty($rows[$entryid]['votes']) ? $rows[$entryid]['votes'] : 0;
                                $points = !empty($rows[$entryid]['points']) ? $rows[$entryid]['points'] : 0;
                                $visits = !empty($rows[$entryid]['visits']) ? $rows[$entryid]['visits'] : 0;
                                $enough_votes = $track_karma && $votes >= $this->get_config('min_disp_votes', 0);
                                $enough_visits = $track_clicks && $visits >= $this->get_config('min_disp_visits', 0);
                                $textual_msg = true;
                                $textual_current = true;
                                $textual_visits = true;
                                if ($this->image_name != '0') {
                                    $textual_msg = $this->get_config('textual_msg', 'true');
                                    $textual_current = $this->get_config('textual_current', 'true');
                                    $textual_visits = $this->get_config('textual_visits', 'true');
                                }
                                // Where's the footer?  Normally it would be
                                // in eventData[n]['add_footer'] but if the
                                // cache plugin is used, it's in
                                // eventData[n]['properties']['ep_cache_add_footer'].
                                // This method retrieves it either way.
                                $footer =& $this->getFieldReference('add_footer', $eventData[$i]);
                                // Depending on what existed, $footer could
                                // be referencing the cached version, the
                                // uncached version, or even a new empty
                                // string.  In particular, if $eventData[$i]
                                // has no properties, and no 'add_footer' key,
                                // $footer is referencing a new empty string,
                                // so adding a karma bar to $footer would do
                                // nothing.
                                //
                                // We could be referencing an empty uncached
                                // 'add_footer', but empty cache entries are
                                // never returned.
                                //
                                // Reference a footer that will be printed
                                if (empty($footer) && !isset($eventData[$i]['add_footer']) && is_array($eventData[$i])) {
                                    $eventData[$i]['add_footer'] = '';
                                    $footer =& $eventData[$i]['add_footer'];
                                    // It's still empty, but it's referencing
                                    // the right place.
                                }
                                if ($track_exits) {
                                    $footer .= $this->getExits($entryid, true);
                                }
                                // Pick the appropriate intro msg and rating bar
                                // No msg or bar if karma is disabled
                                if ($track_karma) {
                                    if (isset($karma[$entryid])) {
                                        // We already voted for this one
                                        $msg = '<div class="serendipity_karmaSuccess">' . PLUGIN_KARMA_VOTED . '</div>';
                                        $myvote = $karma[$entryid];
                                        if ($this->get_config('rate_with_words', false)) {
                                            $myvote = $this->wordRating($myvote, 1);
                                        } elseif ($this->image_name != '0') {
                                            $myvote = $this->imageRating($myvote, 1);
                                        }
                                        // Just a current rating bar, if any
                                        $bar = $this->createRatingBar(null, $points, $votes);
                                    } elseif ($eventData[$i]['timestamp'] < $now - $max_karmatime) {
                                        // Too late to vote for this one
                                        $msg = '<div class="serendipity_karmaClosed">' . sprintf(PLUGIN_KARMA_CLOSED, $karmatime) . '</div>';
                                        // Just a current rating bar, if any
                                        $bar = $this->createRatingBar(null, $points, $votes);
                                    } else {
                                        // We can vote for this; make the whole voting block
                                        $rate_msg = $this->get_config('rate_msg', PLUGIN_KARMA_VOTETEXT);
                                        $msg = '<div class="serendipity_karmaVoting_text">' . $rate_msg . '</div>';
                                        // Full voting bar
                                        $bar = $this->createRatingBar($entryid, $points, $votes);
                                    }
                                }
                                // Create the karma block
                                $image_class = '';
                                if ($this->image_name != '0') {
                                    $image_class = ' serendipity_karmaVoting_images';
                                }
                                $karma_block = "<div class='serendipity_karmaVoting{$image_class}'><a id='karma_vote{$entryid}'></a>";
                                if ($textual_msg) {
                                    $karma_block .= $msg;
                                }
                                $karma_block .= $bar;
                                if ($enough_votes && $textual_current) {
                                    $curr_msg = $this->get_config('curr_msg', PLUGIN_KARMA_CURRENT);
                                    $karma_block .= '<span class="serendipity_karmaVoting_current">' . $curr_msg . '</span>';
                                }
                                if ($enough_visits && $textual_visits) {
                                    $karma_block .= '<span class="serendipity_karmaVoting_visits">' . PLUGIN_KARMA_VISITSCOUNT . '</span>';
                                }
                                $karma_block .= "\n</div>\n";
                                // Adjust rating points
                                if ($this->get_config('rate_with_words', false)) {
                                    $points = $this->wordRating($points, $votes);
                                } elseif ($this->image_name != '0') {
                                    $points = $this->imageRating($points, $votes);
                                }
                                /*
                                  print("<h3>--DEBUG: Karma block code:</h3>\n<pre>\n");
                                  print_r(htmlspecialchars($karma_block));
                                  print("\n</pre>\n");
                                */
                                // Substitute the % stuff and add it to the footer
                                $eventData[$i]['properties']['myvote'] = $myvote;
                                $eventData[$i]['properties']['points'] = $points;
                                $eventData[$i]['properties']['votes'] = $votes;
                                $eventData[$i]['properties']['visits'] = $visits;
                                $footer .= sprintf($karma_block, $myvote, $points, $votes, $visits, $url);
                            }
                            // foreach key in entries
                    }
                    // End switch on karma voting status
                    return true;
                    break;
                    // Display the Karma Log link on the sidebar
                // Display the Karma Log link on the sidebar
                case 'backend_sidebar_entries':
                    ?>
<li class="serendipitySideBarMenuLink serendipitySideBarMenuEntryLinks">
    <a href="?serendipity[adminModule]=event_display&amp;serendipity[adminAction]=karmalog">
        <?php 
                    echo PLUGIN_KARMA_DISPLAY_LOG;
                    ?>
    </a>
</li>
<?php 
                    return true;
                    break;
                    // Display the Karma Log!
                    //case 'external_plugin':
                // Display the Karma Log!
                //case 'external_plugin':
                case 'backend_sidebar_entries_event_display_karmalog':
                    // Print any stored messages
                    //foreach ($serendipity['karma_messages'] as $msg) {
                    //    print("<div class='serendipityAdminInfo'>$msg</div>\n");
                    //}
                    // Was I asked to process any votes?
                    if (($serendipity['POST']['delete_button'] || $serendipity['POST']['approve_button']) && sizeof($serendipity['POST']['delete']) != 0 && serendipity_checkFormToken()) {
                        foreach ($serendipity['POST']['delete'] as $d => $i) {
                            $kdata = $serendipity['POST']['karmalog' . $i];
                            // validate posted variables
                            // posted points
                            $ppoints = $kdata['points'];
                            if (!is_numeric($ppoints) || (int) $ppoints < -2 || (int) $ppoints > 2) {
                                print "<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_INVALID_INPUT . "</div>\n";
                                return false;
                            }
                            // posted id
                            $pid = $kdata['entryid'];
                            if (!is_numeric($pid)) {
                                print "<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_INVALID_INPUT . "</div>\n";
                                return false;
                            }
                            // posted IP
                            $pip = long2ip(ip2long($kdata['ip']));
                            if ($pip == -1 || $pip === FALSE) {
                                print "<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_INVALID_INPUT . "</div>\n";
                                return false;
                            }
                            // posted user agent (need a better validator, I think)
                            $puser_agent = $kdata['user_agent'];
                            if (serendipity_db_escape_string($puser_agent) != $puser_agent) {
                                print "<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_INVALID_INPUT . "</div>\n";
                                return false;
                            }
                            // posted vote time
                            $pvotetime = $kdata['votetime'];
                            $unixsecs = date('U', $kdata['votetime']);
                            if ($pvotetime != $unixsecs) {
                                print "<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_INVALID_INPUT . "</div>\n";
                                return false;
                            }
                            // Remove karma from entry?
                            if ($serendipity['POST']['delete_button']) {
                                // Fetch vote total for the entry IDs
                                $q = 'SELECT k.*
                                    FROM ' . $serendipity['dbPrefix'] . 'karma   AS k
                                    WHERE k.entryid IN (' . $pid . ') GROUP BY k.entryid';
                                $sql = serendipity_db_query($q);
                                if (is_array($sql)) {
                                    $karma = $sql[0];
                                    $update = sprintf("UPDATE {$serendipity['dbPrefix']}karma\n                                        SET points   = %s,\n                                        votes    = %s\n                                        WHERE entryid  = %s", serendipity_db_escape_string($karma['points'] - $ppoints), serendipity_db_escape_string($karma['votes'] - 1), serendipity_db_escape_string($pid));
                                    $updated = serendipity_db_query($update);
                                    if ($updated != 1) {
                                        printf("<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_REMOVE_ERROR . "</div>\n", $pid);
                                        // Don't delete from karma log if we couldn't take away the points
                                        continue;
                                    }
                                } else {
                                    // This will only happen if someone is messing with the karma table or submit data
                                    printf("<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_UPDATE_ERROR . "</div>", $pid);
                                    continue;
                                }
                            }
                            // Remove vote from log (approved or deleted, doesn't matter)
                            $del = sprintf("DELETE FROM {$serendipity['dbPrefix']}karmalog\n                                WHERE entryid = %s AND ip = '%s' AND user_agent LIKE '%%%s%%' AND votetime = %s LIMIT 1", serendipity_db_escape_string($pid), serendipity_db_escape_string($pip), serendipity_db_escape_string($puser_agent), serendipity_db_escape_string($pvotetime));
                            $deleted = serendipity_db_query($del);
                            // User feedback
                            if ($deleted == 1) {
                                if ($serendipity['POST']['delete_button']) {
                                    printf("<div class='serendipityAdminMsgSuccess'>" . PLUGIN_KARMA_REMOVED_POINTS . "</div>\n", $ppoints, $pid);
                                } else {
                                    printf("<div class='serendipityAdminMsgSuccess'>" . PLUGIN_KARMA_APPROVED_POINTS . "</div>\n", $ppoints, $pid);
                                }
                            } else {
                                printf("<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_REMOVE_ERROR . "</div>\n", $pid);
                            }
                        }
                    }
                    // URL; expected to be event_display and karmalog, respectively
                    $url = '?serendipity[adminModule]=' . htmlspecialchars($serendipity['GET']['adminModule']) . '&serendipity[adminAction]=' . htmlspecialchars($serendipity['GET']['adminAction']);
                    // Filters
                    print "\n<form action='' method='get' name='karmafilters' id='karmafilters'>\n  <input type='hidden' name='serendipity[adminModule]' value='{$serendipity['GET']['adminModule']}' />\n  <input type='hidden' name='serendipity[adminAction]' value='{$serendipity['GET']['adminAction']}' />\n<table class='serendipity_admin_filters' width='100%'>\n<tr>\n  <td colspan='4' class='serendipity_admin_filters_headline'><strong>" . FILTERS . "</strong></td>\n</tr>\n<tr>\n  <td>User Agent:</td>\n  <td><input class='input_textbox' type='text' name='serendipity[filter][user_agent]' size='15' value='" . htmlspecialchars($serendipity['GET']['filter']['user_agent']) . "' /></td>\n  <td>" . IP . "</td>\n  <td><input class='input_textbox' type='text' name='serendipity[filter][ip]' size='15' value='" . htmlspecialchars($serendipity['GET']['filter']['ip']) . "' /></td>\n</tr>\n<tr>\n  <td>Entry ID:</td>\n  <td><input class='input_textbox' type='text' name='serendipity[filter][entryid]' size='15' value='" . htmlspecialchars($serendipity['GET']['filter']['entryid']) . "' /></td>\n  <td>Entry title:</td>\n  <td><input class='input_textbox' type='text' name='serendipity[filter][title]' size='30' value='" . htmlspecialchars($serendipity['GET']['filter']['title']) . "' /></td>\n</tr>\n</table>\n";
                    // Set all filters into $and and $searchString
                    if (!empty($serendipity['GET']['filter']['entryid'])) {
                        $val = $serendipity['GET']['filter']['entryid'];
                        $and .= "AND l.entryid = '" . serendipity_db_escape_string($val) . "'";
                        $searchString .= "&amp;serendipity['filter']['entryid']=" . htmlspecialchars($val);
                    }
                    if (!empty($serendipity['GET']['filter']['ip'])) {
                        $val = $serendipity['GET']['filter']['ip'];
                        $and .= "AND l.ip = '" . serendipity_db_escape_string($val) . "'";
                        $searchString .= "&amp;serendipity['filter']['ip']=" . htmlspecialchars($val);
                    }
                    if (!empty($serendipity['GET']['filter']['user_agent'])) {
                        $val = $serendipity['GET']['filter']['user_agent'];
                        $and .= "AND l.user_agent LIKE '%" . serendipity_db_escape_string($val) . "%'";
                        $searchString .= "&amp;serendipity['filter']['user_agent']=" . htmlspecialchars($val);
                    }
                    if (!empty($serendipity['GET']['filter']['title'])) {
                        $val = $serendipity['GET']['filter']['title'];
                        $and .= "AND e.title LIKE '%" . serendipity_db_escape_string($val) . "%'";
                        $searchString .= "&amp;serendipity['filter']['title']=" . htmlspecialchars($val);
                    }
                    // Sorting (controls go after filtering controls in form above)
                    $sort_order = array('votetime' => DATE, 'user_agent' => USER_AGENT, 'title' => TITLE, 'entryid' => 'ID');
                    if (empty($serendipity['GET']['sort']['ordermode']) || $serendipity['GET']['sort']['ordermode'] != 'ASC') {
                        $desc = true;
                        $serendipity['GET']['sort']['ordermode'] = 'DESC';
                    }
                    if (!empty($serendipity['GET']['sort']['order']) && !empty($sort_order[$serendipity['GET']['sort']['order']])) {
                        $curr_order = $serendipity['GET']['sort']['order'];
                        $orderby = serendipity_db_escape_string($curr_order . ' ' . $serendipity['GET']['sort']['ordermode']);
                    } else {
                        $curr_order = 'votetime';
                        $orderby = 'votetime ' . serendipity_db_escape_string($serendipity['GET']['sort']['ordermode']);
                    }
                    print "\n<div>" . SORT_BY . "\n<select name='serendipity[sort][order]'>\n";
                    foreach ($sort_order as $order => $val) {
                        print "\n  <option value='{$order}'" . ($curr_order == $order ? " selected='selected'" : '') . ">{$val}</option>\n";
                    }
                    print "\n</select>\n<select name='serendipity[sort][ordermode]'>\n  <option value='DESC'" . ($desc ? "selected='selected'" : '') . ">" . SORT_ORDER_DESC . "</option>\n  <option value='ASC'" . ($desc ? '' : "selected='selected'") . ">" . SORT_ORDER_ASC . "</option>\n</select>\n</div>\n<input type='submit' name='submit' value=' - " . GO . " - ' class='serendipityPrettyButton input_button' /> \n</form>\n";
                    // Paging (partly ripped from include/admin/comments.inc.php)
                    $commentsPerPage = (int) (!empty($serendipity['GET']['filter']['perpage']) ? $serendipity['GET']['filter']['perpage'] : 25);
                    $sql = serendipity_db_query("SELECT COUNT(*) AS total FROM {$serendipity['dbPrefix']}karmalog l WHERE 1 = 1 " . $and, true);
                    $totalVotes = $sql['total'];
                    $pages = $commentsPerPage == COMMENTS_FILTER_ALL ? 1 : ceil($totalVotes / (int) $commentsPerPage);
                    $page = (int) $serendipity['GET']['page'];
                    if ($page == 0 || $page > $pages) {
                        $page = 1;
                    }
                    if ($page > 1) {
                        $linkPrevious = $url . '&amp;serendipity[page]=' . ($page - 1) . $searchString;
                    }
                    if ($pages > $page) {
                        $linkNext = $url . '&amp;serendipity[page]=' . ($page + 1) . $searchString;
                    }
                    if ($commentsPerPage == COMMENTS_FILTER_ALL) {
                        $limit = '';
                    } else {
                        $limit = serendipity_db_limit_sql(serendipity_db_limit(($page - 1) * (int) $commentsPerPage, (int) $commentsPerPage));
                    }
                    // Variables for display
                    if ($linkPrevious) {
                        $linkPrevious = '<a href="' . $linkPrevious . '" class="serendipityIconLink"><img src="' . serendipity_getTemplateFile('admin/img/previous.png') . '" /></a>';
                    } else {
                        $linkPrevious = '&nbsp;';
                    }
                    if ($linkNext) {
                        $linkNext = '<a href="' . $linkNext . '" class="serendipityIconLinkRight"><img src="' . serendipity_getTemplateFile('admin/img/next.png') . '" /></a>';
                    } else {
                        $linkNext = '&nbsp;';
                    }
                    $paging = sprintf(PAGE_BROWSE_COMMENTS, $page, $pages, $totalVotes);
                    // Retrieve the next batch of karma votes
                    // [entryid, points, ip, user_agent, votetime]
                    $sql = serendipity_db_query("SELECT l.entryid AS entryid, l.points AS points, l.ip AS ip, l.user_agent AS user_agent, l.votetime AS votetime, e.title AS title FROM {$serendipity['dbPrefix']}karmalog l\n                        LEFT JOIN {$serendipity['dbPrefix']}entries e ON (e.id = l.entryid)\n                        WHERE 1 = 1 " . $and . "\n                        ORDER BY {$orderby} {$limit}");
                    // Start the form for display and deleting
                    if (is_array($sql)) {
                        print "<form action='' method='post' name='formMultiDelete' id='formMultiDelete'>\n" . serendipity_setFormToken() . "\n<script type='text/javascript'>\nfunction invertSelection() {\n    var f = document.formMultiDelete;\n    for (var i = 0; i < f.elements.length; i++) {\n        if( f.elements[i].type == 'checkbox' ) {\n            f.elements[i].checked = !(f.elements[i].checked);\n        }\n    }\n}\n</script>\n";
                        // Print the header paging table
                        print "\n<table width='100%' style='border-collapse: collapse;'>\n  <tr>\n  <td align='left'>{$linkPrevious}</td>\n  <td align='center'>{$paging}</td>\n  <td align='right'>{$linkNext}</td>\n  </tr>\n</table>\n";
                        // Start the vote table
                        print "\n<table class='karmalog' width='100%'>\n";
                        // Print each vote
                        $i = 0;
                        foreach ($sql as $vote) {
                            $i++;
                            // entryid, title, points, ip, user_agent, votetime
                            $entrylink = serendipity_archiveURL($vote['entryid'], $vote['title'], 'serendipityHTTPPath', true);
                            $entryFilterHtml = "<a class='serendipityIconLink' href='{$url}&serendipity[filter][entryid]={$vote['entryid']}'><img src='" . serendipity_getTemplateFile('admin/img/zoom.png') . "' /></a>";
                            $ipFilterHtml = "<a class='serendipityIconLink' href='{$url}&serendipity[filter][ip]={$vote['ip']}'><img src='" . serendipity_getTemplateFile('admin/img/zoom.png') . "' /></a>";
                            $timestr = strftime('%H:%M:%S<br />%n%a %b %d %Y', $vote['votetime']);
                            $cssClass = 'serendipity_admin_list_item serendipity_admin_list_item_';
                            $cssClass .= $i % 2 == 0 ? 'even' : 'uneven';
                            $barClass = str_replace(array('.', ' '), array('_', '_'), $this->image_name);
                            $barHtml = $this->createRatingBar(null, $vote['points'], 1, $barClass);
                            $barHtml = sprintf($barHtml, 'what', $vote['points'], '1');
                            print "\n  <tr class='{$cssClass}'>\n    <td rowspan='2' width='20' align='center'>\n      <input class='input_checkbox' type='checkbox' name='serendipity[delete][{$i}]' value='{$i}' tabindex='{$i}' />\n      <input type='hidden' name='serendipity[karmalog{$i}][points]' value='{$vote['points']}' />\n      <input type='hidden' name='serendipity[karmalog{$i}][entryid]' value='{$vote['entryid']}' />\n      <input type='hidden' name='serendipity[karmalog{$i}][votetime]' value='{$vote['votetime']}' />\n      <input type='hidden' name='serendipity[karmalog{$i}][ip]' value='{$vote['ip']}' />\n      <input type='hidden' name='serendipity[karmalog{$i}][user_agent]' value='{$vote['user_agent']}' />\n    </td>\n    <td>{$barHtml}</td>\n    <td colspan='2'><a href='{$entrylink}' title='{$vote['entryid']}' alt='{$vote['title']}'>{$vote['title']}</a> {$entryFilterHtml}</td>\n  </tr>\n  <tr class='{$cssClass}'>\n    <td>{$timestr}</td>\n    <td>{$vote['ip']} {$ipFilterHtml}</td>\n    <td>{$vote['user_agent']}</td>\n  </tr>\n";
                        }
                        // End the vote table
                        print "\n                            </table>\n                            ";
                        if (is_array($sql)) {
                            print "\n<input type='button' name='toggle' value='" . INVERT_SELECTIONS . "' onclick='invertSelection()' class='serendipityPrettyButton input_button' /> \n<input class='serendipityPrettyButton input_button' type='submit' value='" . PLUGIN_KARMA_DELETE_VOTES . "' name='serendipity[delete_button]' />\n<input class='serendipityPrettyButton input_button' type='submit' value='" . PLUGIN_KARMA_APPROVE_VOTES . "' name='serendipity[approve_button]' />\n</form>\n";
                        }
                        // Print the footer paging table
                        print "\n<table width='100%' style='border-collapse: collapse;'>\n  <tr>\n  <td align='left'>{$linkPrevious}</td>\n  <td align='center'>{$paging}</td>\n  <td align='right'>{$linkNext}</td>\n  </tr>\n</table>\n";
                    } else {
                        print "\n<div class='serendipityAdminMsgNotice'>No entries to display.</div>\n";
                    }
                    return true;
                    break;
                default:
                    return false;
            }
            // End switch on event hooks
        } else {
            return false;
        }
    }
Esempio n. 12
0
        $template_loaded_config = NULL;
    }
}
if (is_array($template_config)) {
    serendipity_plugin_api::hook_event('backend_templates_configuration_top', $template_config);
    $data["has_config"] = true;
    if ($serendipity['POST']['adminAction'] == 'configure' && serendipity_checkFormToken()) {
        $storage = new template_option();
        $storage->import($template_config);
        foreach ($serendipity['POST']['template'] as $option => $value) {
            $storage->set_config($option, $value);
        }
        $data["adminAction"] = "configure";
        $data["save_time"] = sprintf(SETTINGS_SAVED_AT, serendipity_strftime('%H:%M:%S'));
    }
    $data["form_token"] = serendipity_setFormToken();
    include_once S9Y_INCLUDE_PATH . 'include/functions_plugins_admin.inc.php';
    $template_vars =& serendipity_loadThemeOptions($template_config);
    $template_options = new template_option();
    $template_options->import($template_config);
    $template_options->values =& $template_vars;
    $data["configuration"] = serendipity_plugin_config($template_options, $template_vars, $serendipity['template'], $serendipity['template'], $template_options->keys, true, true, true, true, 'template', $template_config_groups);
    serendipity_plugin_api::hook_event('backend_templates_configuration_bottom', $template_config);
} else {
    serendipity_plugin_api::hook_event('backend_templates_configuration_none', $template_config);
}
$i = 0;
$stack = array();
serendipity_plugin_api::hook_event('backend_templates_fetchlist', $stack);
$themes = serendipity_fetchTemplates();
$data['templates'] = array();
Esempio n. 13
0
        ?>
" alt="<?php 
        echo DELETE;
        ?>
" /><?php 
        echo DELETE;
        ?>
</a>
          <a target="_blank" onclick="cf = window.open(this.href, 'CommentForm', 'width=800,height=600,toolbar=no,scrollbars=1,scrollbars,resize=1,resizable=1'); cf.focus(); return false;" href="?serendipity[action]=admin&amp;serendipity[adminModule]=comments&amp;serendipity[adminAction]=reply&amp;serendipity[id]=<?php 
        echo $comment['id'];
        ?>
&amp;serendipity[entry_id]=<?php 
        echo $comment['entry_id'];
        ?>
&amp;serendipity[noBanner]=true&amp;serendipity[noSidebar]=true&amp;<?php 
        echo serendipity_setFormToken('url');
        ?>
" title="<?php 
        echo REPLY;
        ?>
" class="serendipityIconLink"><img src="<?php 
        echo serendipity_getTemplateFile('admin/img/user_editor.png');
        ?>
" alt="<?php 
        echo REPLY;
        ?>
" /><?php 
        echo REPLY;
        ?>
</a>
          <?php 
serendipity_smarty_init();
if (empty($serendipity['GET']['step']) && $serendipity['GET']['page'] < 1) {
    $media = array('GET_STRING' => serendipity_build_query($_GET), 'frameset' => true);
    $serendipity['smarty']->assign_by_ref('media', $media);
    $serendipity['smarty']->display(serendipity_getTemplateFile('admin/media_choose.tpl', 'serendipityPath'));
    return;
}
$import_vars = $serendipity['GET'];
unset($import_vars['step']);
unset($import_vars['only_path']);
$showFile = 'admin/media_choose.tpl';
$body_id = 'serendipityAdminBodyImageSelector';
if ($serendipity['GET']['step'] === 'tree') {
    $body_id = 'serendipityAdminBodyImageSelectorTree';
}
$media = array('body_id' => $body_id, 'only_path' => $serendipity['GET']['only_path'], 'css' => serendipity_rewriteURL('serendipity_admin.css'), 'css_tree' => serendipity_getTemplateFile('treeview/tree.css'), 'css_front' => serendipity_rewriteURL('serendipity.css'), 'token_url' => serendipity_setFormToken('url'), 'imgID' => (int) $serendipity['GET']['image'], 'from' => $serendipity['GET']['from'], 'GET_STRING' => serendipity_build_query($import_vars, 'serendipity', '&'), 'paths' => serendipity_getMediaPaths());
switch ($serendipity['GET']['step']) {
    case '1':
        if (isset($serendipity['GET']['adminAction'])) {
            // Embedded upload form
            if (!empty($serendipity['POST']['textarea'])) {
                $serendipity['GET']['textarea'] = $serendipity['POST']['textarea'];
            }
            if (!empty($serendipity['POST']['htmltarget'])) {
                $serendipity['GET']['htmltarget'] = $serendipity['POST']['htmltarget'];
            }
            if (!empty($serendipity['POST']['filename_only'])) {
                $serendipity['GET']['filename_only'] = $serendipity['POST']['filename_only'];
            }
            $image_selector_addvars = array('step' => 1, 'textarea' => !empty($serendipity['GET']['textarea']) ? $serendipity['GET']['textarea'] : '', 'htmltarget' => !empty($serendipity['GET']['htmltarget']) ? $serendipity['GET']['htmltarget'] : '', 'filename_only' => !empty($serendipity['GET']['filename_only']) ? $serendipity['GET']['filename_only'] : '');
            switch ($serendipity['GET']['adminAction']) {
    function event_hook($event, &$bag, &$eventData, $addData = null)
    {
        global $serendipity;
        $hooks =& $bag->get('event_hooks');
        if (isset($hooks[$event])) {
            switch ($event) {
                // called when admin sidebar is being "built"
                case 'backend_sidebar_entries_images':
                    ?>
<li class="serendipitySideBarMenuLink serendipitySideBarMenuMediaLinks"><a href="?serendipity[adminModule]=event_display&amp;serendipity[adminAction]=flickr">
                        <?php 
                    echo PLUGIN_EVENT_FLICKR_NAME;
                    ?>
</a></li><?php 
                    break;
                    // called when admin sidebar is been "drawn"
                // called when admin sidebar is been "drawn"
                case 'backend_sidebar_entries_event_display_flickr':
                    // he, is user allowed to import images ?!?
                    if (!serendipity_checkPermission('adminImagesAdd')) {
                        // TODO: add a message to the user ?!?
                        break;
                    }
                    // if method is POST, we must have a valid form token !
                    if ($_SERVER['REQUEST_METHOD'] == 'POST' && !serendipity_checkFormToken()) {
                        // TODO: add a message to the user ?!?
                        break;
                    }
                    ?>
                <?php 
                    echo PLUGIN_EVENT_FLICKR_IMPORT_BLAHBLAH;
                    ?>
                <script type="text/javascript">
                function flickr_showPage(p) {
                    var f = document.getElementById('flickr_uploadform');
                    f.elements['serendipity[flickr_page]'].value = p;
                    f.submit();
                }
                function flickr_doImport(url) {
                    var f = document.getElementById('flickr_uploadform');
                    f.elements['serendipity[adminModule]'].value = 'images';
                    f.elements['serendipity[adminAction]'].value = 'add';
                    f.elements['serendipity[imageurl]'].value = url;
                    f.submit();
                }
                function flickr_toggleExtended() {
                    var d = document.getElementById('flickr_extendedCriteria');
                    d.style.display = (d.style.display != '') ? '' : 'none';
                }
                </script>
                <h3><? echo PLUGIN_EVENT_FLICKR_IMPORT; ?></h3>
                <form action="?" method="POST" id="flickr_uploadform" enctype="multipart/form-data" onsubmit="">
                    <?php 
                    echo serendipity_setFormToken();
                    ?>
                    <?php 
                    // these two fields will only be used when an image has been chosen for dl
                    ?>
                    <input type="hidden" name="serendipity[imageurl]" value="" />
                    <input type="hidden" name="serendipity[imageimporttype]" value="image" />

                    <input type="hidden" name="serendipity[action]"      value="admin" />
                    <input type="hidden" name="serendipity[adminModule]" value="event_display" />
                    <input type="hidden" name="serendipity[adminAction]" value="flickr" />

                    <input type="hidden" name="serendipity[flickr_page]" value="1" />
                    Flickr username: <input class="input_textbox" name="serendipity[flickr_username]" value="<?php 
                    echo function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['POST']['flickr_username']) : htmlspecialchars($serendipity['POST']['flickr_username'], ENT_COMPAT, LANG_CHARSET);
                    ?>
" />
                    <input type="submit" value="<?php 
                    echo GO;
                    ?>
" class="serendipityPrettyButton input_button" /><br /><br />
                    <a style="border: 0pt none ; text-decoration: none;" href="#" onclick="flickr_toggleExtended(); return false"
                         title="<?php 
                    echo TOGGLE_OPTION;
                    ?>
">
                    <img border="0" src="<?php 
                    echo serendipity_getTemplateFile('img/plus.png');
                    ?>
" /> <?php 
                    echo TOGGLE_ALL;
                    ?>
</a>
                    <div id="flickr_extendedCriteria" <?php 
                    echo strlen($serendipity['POST']['flickr_username']) ? '' : 'style="display:none;"';
                    ?>
>
                        <p><?php 
                    echo PLUGIN_EVENT_FLICKR_TAGS;
                    ?>
 <input class="input_textbox" name="serendipity[flickr_tags]" value="<?php 
                    echo function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['POST']['flickr_tags']) : htmlspecialchars($serendipity['POST']['flickr_tags'], ENT_COMPAT, LANG_CHARSET);
                    ?>
" />
                        <?php 
                    echo PLUGIN_EVENT_FLICKR_KEYWORDS;
                    ?>
 <input class="input_textbox" name="serendipity[flickr_keywords]" value="<?php 
                    echo function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['POST']['flickr_keywords']) : htmlspecialchars($serendipity['POST']['flickr_keywords'], ENT_COMPAT, LANG_CHARSET);
                    ?>
" size="30" /></p>
                        <?php 
                    echo SORT_BY;
                    ?>
 <select id="flickr_sort" name="serendipity[flickr_sort]">
                        <option value=""></option>
                        <?
                            // See API for details (http://www.flickr.com/services/api/flickr.photos.search.html)
                            $flickr_goodSortOrders = array(
                                'date-posted-asc'=>'By date of post, ascending',
                                'date-posted-desc'=>'By date of post, descending',
                                'date-taken-asc'=>'By date of take, ascending',
                                'date-taken-desc'=>'By date of take, descending',
                                'interestingness-asc'=>'By interestingness, ascending',
                                'interestingness-desc'=>'By interestingness, ascending',
                                'relevance'=>'By revelance'
                            );

                            // compute sort order
                            $sortOrder = (isset($serendipity['POST']['flickr_keywords']) &&
                                array_key_exists($serendipity['POST']['flickr_keywords'], $flickr_goodSortOrders) ?
                                (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['POST']['flickr_keywords']) : htmlspecialchars($serendipity['POST']['flickr_keywords'], ENT_COMPAT, LANG_CHARSET)) : '');

                            // display possible options for sort order
                            foreach($flickr_goodSortOrders as $value => $description) {
                                echo '<option value="'.$value.'"';
                                if($sortOrder == $value) echo(' selected="true"');
                                echo '>'.$description.'</option>';
                            }
                        ?>
                        </select>
                    </div>
                </form>
                <?php 
                    // in the second step, we show latest photos (thumbs) for given username
                    if ($serendipity['POST']['adminAction'] == 'flickr') {
                        // make use of phpFlikr lib (http://www.phpflickr.com/)
                        require_once dirname(__FILE__) . '/phpFlickr/phpFlickr.php';
                        $f = new phpFlickr($this->get_config('api_key'));
                        $i = 0;
                        if (!empty($serendipity['POST']['flickr_username'])) {
                            // Find the NSID of the username inputted via the form
                            $nsid = $f->people_findByUsername($serendipity['POST']['flickr_username']);
                            // Get the friendly URL of the user's photos
                            $photos_url = $f->urls_getUserPhotos($nsid);
                            echo '<h4 style="margin-bottom: 0; padding-bottom: 0;">Photos of <em>';
                            echo (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['POST']['flickr_username']) : htmlspecialchars($serendipity['POST']['flickr_username'], ENT_COMPAT, LANG_CHARSET)) . '</em> at ';
                            echo '<a href="' . $photos_url . '" target="_blank">' . $photos_url . '</a></h4>';
                            // default page is number one
                            if (empty($serendipity['POST']['flickr_page']) || !is_numeric($serendipity['POST']['flickr_page'])) {
                                $serendipity['POST']['flickr_page'] = 1;
                            }
                            // make sure page is a number between 1 and 500 (range allowed by flickr API)
                            $serendipity['POST']['flickr_page'] = min(500, max(1, (int) $serendipity['POST']['flickr_page']));
                            echo '<h5 style="margin-top: 0; padding-top: 0;">Displaying page ' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['POST']['flickr_page']) : htmlspecialchars($serendipity['POST']['flickr_page'], ENT_COMPAT, LANG_CHARSET)) . '</h5>';
                            // Search is made depending on selected criterias
                            $searchCriteria = array();
                            // make sure sort order is non empty AND valid
                            if (isset($serendipity['POST']['flickr_sort']) && strlen(trim($serendipity['POST']['flickr_sort'])) && array_key_exists($serendipity['POST']['flickr_keywords'], $flickr_goodSortOrders)) {
                                $searchCriteria['sort'] = function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['POST']['flickr_sort']) : htmlspecialchars($serendipity['POST']['flickr_sort'], ENT_COMPAT, LANG_CHARSET);
                            }
                            // TODO: clean up tags of unwanted characters (keep only [a-zA-Z0-9_-])
                            if (isset($serendipity['POST']['flickr_tags']) && strlen(trim($serendipity['POST']['flickr_tags']))) {
                                $searchCriteria['tags'] = implode(',', explode(' ', function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['POST']['flickr_tags']) : htmlspecialchars($serendipity['POST']['flickr_tags'], ENT_COMPAT, LANG_CHARSET)));
                            }
                            // TODO: cleanup keywords
                            if (isset($serendipity['POST']['flickr_keywords']) && strlen(trim($serendipity['POST']['flickr_keywords']))) {
                                $searchCriteria['text'] = function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['POST']['flickr_keywords']) : htmlspecialchars($serendipity['POST']['flickr_keywords'], ENT_COMPAT, LANG_CHARSET);
                            }
                            if (count($searchCriteria)) {
                                // It seems the user wants an advanced search
                                $searchCriteria['user_id'] = $nsid;
                                $photos = $f->photos_search($searchCriteria);
                            } else {
                                // No extra criteria, get the user's next 12 public photos (+1 to show > next or not !)
                                $photos = $f->people_getPublicPhotos($nsid, NULL, 13, $serendipity['POST']['flickr_page']);
                                // Get user's tags (if any)
                                /*$tags = $f->tags_getListUser($nsid);
                                  if(is_array($tags['tags']['tag'])) {
                                      echo implode(',', $tags['tags']['tag']);
                                      echo "<br />\n";
                                  }*/
                            }
                            // Loop through the photos and output the html
                            foreach ($photos['photo'] as $photo) {
                                echo '<a title="Add to library" href="javascript:flickr_doImport(\'' . $f->buildPhotoURL($photo, 'Original') . '\');" ';
                                echo 'onclick="return confirm(\'Import this photo into the media library ?\');">';
                                echo '<img border="0" alt="' . $photo['title'] . '" src=' . $f->buildPhotoURL($photo, 'Square') . ' />';
                                echo '</a>';
                                // break before the 13th photo (if any)
                                if (++$i == 12) {
                                    break;
                                }
                                // If it reaches the sixth photo, insert a line break
                                if ($i % 6 == 0) {
                                    echo "<br />\n";
                                }
                            }
                            // end foreach
                            echo "<br />\n";
                            // navigate through pages of photos
                            if ($serendipity['POST']['flickr_page'] > 1) {
                                echo '<a href="javascript:flickr_showPage(' . (int) ($serendipity['POST']['flickr_page'] - 1) . ');">Previous</a>';
                            }
                            echo '&nbsp;&nbsp;';
                            if (count($photos['photo']) > 12) {
                                echo '<a href="javascript:flickr_showPage(' . (int) ($serendipity['POST']['flickr_page'] + 1) . ');">Next</a>';
                            }
                        }
                        // end if
                    }
                    // end if
                    return true;
                    break;
                default:
                    return false;
                    break;
            }
        } else {
            return false;
        }
    }
    function shownotes()
    {
        global $serendipity;
        if ($serendipity['version'][0] < 2) {
            echo '<h3>' . PLUGIN_ADMINNOTES_TITLE . '</h3>';
        } else {
            echo '<h2>' . PLUGIN_ADMINNOTES_TITLE . '</h2>';
        }
        if (!serendipity_db_bool($this->get_config('feedback')) && $serendipity['serendipityUserlevel'] < USERLEVEL_CHIEF) {
            return false;
        }
        switch ($_REQUEST['action']) {
            case 'edit':
                $entry = $this->getMyNotes((int) $_REQUEST['note']);
                $mode = 'update';
            case 'new':
                if (!isset($mode)) {
                    $mode = 'insert';
                }
                if (!is_array($entry)) {
                    $entry = array();
                }
                if ($_REQUEST['submit']) {
                    $valid_groups = serendipity_getAllGroups($serendipity['authorid']);
                    $targets = array();
                    if (is_array($_REQUEST['note_target'])) {
                        foreach ($_REQUEST['note_target'] as $groupid) {
                            $found = false;
                            foreach ($valid_groups as $group) {
                                if ($group['confkey'] == $groupid) {
                                    $found = true;
                                    break;
                                }
                            }
                            if ($found) {
                                $targets[] = (int) $groupid;
                            }
                        }
                    }
                    if ($mode == 'update') {
                        $noteid = (int) $_REQUEST['note'];
                        $q = serendipity_db_query("UPDATE {$serendipity['dbPrefix']}adminnotes\n                                                 SET authorid = {$serendipity['authorid']},\n                                                     subject = '" . serendipity_db_escape_string($_REQUEST['note_subject']) . "',\n                                                     body = '" . serendipity_db_escape_string($_REQUEST['note_body']) . "',\n                                                     notetype = '" . serendipity_db_escape_string($_REQUEST['note_notetype']) . "'\n                                               WHERE noteid = {$noteid}");
                        $q = serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}adminnotes_to_groups WHERE noteid = {$noteid}");
                        foreach ($targets as $target) {
                            $q = serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}adminnotes_to_groups (noteid, groupid) VALUES ({$noteid}, {$target})");
                        }
                        if (is_string($q)) {
                            echo $q . "<br />\n";
                        }
                    } else {
                        serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}adminnotes (authorid, notetime, subject, body, notetype) VALUES ('" . $serendipity['authorid'] . "', " . time() . ", '" . serendipity_db_escape_string($_REQUEST['note_subject']) . "', '" . serendipity_db_escape_string($_REQUEST['note_body']) . "', '" . serendipity_db_escape_string($_REQUEST['note_notetype']) . "')");
                        $noteid = serendipity_db_insert_id('adminnotes', 'noteid');
                        foreach ($targets as $target) {
                            serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}adminnotes_to_groups (noteid, groupid) VALUES ({$noteid}, {$target})");
                        }
                    }
                    if ($serendipity['version'][0] < 2) {
                        echo '<div class="serendipityAdminMsgSuccess"><img style="width: 22px; height: 22px; border: 0px; padding-right: 4px; vertical-align: middle" src="' . serendipity_getTemplateFile('admin/img/admin_msg_success.png') . '" alt="" />' . DONE . ': ' . sprintf(SETTINGS_SAVED_AT, serendipity_strftime('%H:%M:%S')) . '</div>';
                    } else {
                        echo '<span class="msg_success"><span class="icon-ok-circled"></span> ' . DONE . ': ' . sprintf(SETTINGS_SAVED_AT, serendipity_strftime('%H:%M:%S')) . '</span>';
                    }
                }
                echo '<p>' . PLUGIN_ADMINNOTES_FEEDBACK_INFO . '</p>';
                echo '<form action="?" method="post">';
                echo serendipity_setFormToken();
                echo '<input type="hidden" name="serendipity[adminModule]" value="event_display" />';
                echo '<input type="hidden" name="serendipity[adminAction]" value="adminnotes" />';
                echo '<input type="hidden" name="action" value="' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($_REQUEST['action']) : htmlspecialchars($_REQUEST['action'], ENT_COMPAT, LANG_CHARSET)) . '" />';
                echo '<input type="hidden" name="note" value="' . $entry['noteid'] . '" />';
                echo '<input type="hidden" name="note_notetype" value="note" />';
                if ($serendipity['version'][0] < 2) {
                    echo TITLE . '<br />';
                    echo '<input class="input_textbox" type="text" name="note_subject" value="' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['subject']) : htmlspecialchars($entry['subject'], ENT_COMPAT, LANG_CHARSET)) . '" /><br /><br />';
                } else {
                    echo '<div class="form_field">';
                    echo '<label for="note_subject" class="block_level">' . TITLE . '</label>';
                    echo '<input id="note_subject" type="text" name="note_subject" value="' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['subject']) : htmlspecialchars($entry['subject'], ENT_COMPAT, LANG_CHARSET)) . '">';
                    echo '</div>';
                }
                if ($serendipity['version'][0] < 2) {
                    echo USERCONF_GROUPS . '<br />';
                } else {
                    echo '<div class="form_multiselect">';
                    echo '<label for="note_target" class="block_level">' . USERCONF_GROUPS . '</label>';
                }
                $valid_groups = serendipity_getAllGroups($serendipity['authorid']);
                if (isset($_REQUEST['note_target'])) {
                    $selected = $_REQUEST['note_target'];
                } elseif ($mode == 'update') {
                    $sql = serendipity_db_query("SELECT * FROM {$serendipity['dbPrefix']}adminnotes_to_groups");
                    $selected = array();
                    foreach ($sql as $row) {
                        $selected[] = $row['groupid'];
                    }
                }
                echo '<select id="note_target" name="note_target[]" multiple="multiple" size="5">';
                foreach ($valid_groups as $group) {
                    # PRESELECT!
                    if (in_array($group['confkey'], (array) $selected) || count($selected) == 0) {
                        $is_selected = 'selected="selected"';
                    } else {
                        $is_selected = '';
                    }
                    echo '<option ' . $is_selected . ' value="' . $group['confkey'] . '">' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($group['confvalue']) : htmlspecialchars($group['confvalue'], ENT_COMPAT, LANG_CHARSET)) . '</option>' . "\n";
                }
                if ($serendipity['version'][0] < 2) {
                    echo '</select><br /><br />';
                } else {
                    echo '</select></div>';
                }
                if ($serendipity['version'][0] < 2) {
                    echo ENTRY_BODY . '<br />';
                } else {
                    echo '<div class="form_area">';
                    echo '<label for="note_body" class="block_level">' . ENTRY_BODY . '</label>';
                }
                echo '<textarea id="note_body" rows=10 cols=80 name="note_body">' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['body']) : htmlspecialchars($entry['body'], ENT_COMPAT, LANG_CHARSET)) . '</textarea>';
                if ($serendipity['version'][0] < 2) {
                    echo '<br /><br />';
                    echo '<input type="submit" name="submit" value="' . SAVE . '" class="serendipityPrettyButton input_button" />';
                } else {
                    echo '</div>';
                    echo '<div class="form_buttons"><input type="submit" name="submit" value="' . SAVE . '"></div>';
                }
                echo '</form>';
                break;
            case 'delete':
                $newLoc = '?' . serendipity_setFormToken('url') . '&amp;serendipity[adminModule]=event_display&amp;serendipity[adminAction]=adminnotes&amp;action=isdelete&amp;note=' . (int) $_REQUEST['note'];
                $entry = $this->getMyNotes((int) $_REQUEST['note']);
                if ($serendipity['version'][0] > 1) {
                    echo '<span class="msg_hint"><span class="icon-help-circled"></span> ';
                }
                printf(DELETE_SURE, $entry['noteid'] . ' - ' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['subject']) : htmlspecialchars($entry['subject'], ENT_COMPAT, LANG_CHARSET)));
                if ($serendipity['version'][0] > 1) {
                    echo '</span>';
                }
                if ($serendipity['version'][0] < 2) {
                    ?>
                    <br />
                    <br />
                    <div>
                        <a href="<?php 
                    echo function_exists('serendipity_specialchars') ? serendipity_specialchars($_SERVER["HTTP_REFERER"]) : htmlspecialchars($_SERVER["HTTP_REFERER"], ENT_COMPAT, LANG_CHARSET);
                    ?>
" class="serendipityPrettyButton"><?php 
                    echo NOT_REALLY;
                    ?>
</a>
                        <?php 
                    echo str_repeat('&nbsp;', 10);
                    ?>
                        <a href="<?php 
                    echo $newLoc;
                    ?>
" class="serendipityPrettyButton"><?php 
                    echo DUMP_IT;
                    ?>
</a>
                    </div>
<?php 
                } else {
                    ?>
                    <div class="form_buttons">
                        <a class="button_link state_submit" href="<?php 
                    echo $newLoc;
                    ?>
"><?php 
                    echo DUMP_IT;
                    ?>
</a>
                        <a class="button_link state_cancel" href="<?php 
                    echo function_exists('serendipity_specialchars') ? serendipity_specialchars($_SERVER["HTTP_REFERER"]) : htmlspecialchars($_SERVER["HTTP_REFERER"], ENT_COMPAT, LANG_CHARSET);
                    ?>
"><?php 
                    echo NOT_REALLY;
                    ?>
</a>
                    </div>
<?php 
                }
                break;
            case 'isdelete':
                if (!serendipity_checkFormToken()) {
                    break;
                }
                $entry = $this->getMyNotes((int) $_REQUEST['note']);
                if (isset($entry['noteid'])) {
                    serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}adminnotes           WHERE noteid = " . (int) $_REQUEST['note']);
                    serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}adminnotes_to_groups WHERE noteid = " . (int) $_REQUEST['note']);
                }
                if ($serendipity['version'][0] > 1) {
                    echo '<span class="msg_success"><span class="icon-ok-circled"></span> ';
                }
                printf(RIP_ENTRY, $entry['noteid'] . ' - ' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['subject']) : htmlspecialchars($entry['subject'], ENT_COMPAT, LANG_CHARSET)));
                if ($serendipity['version'][0] > 1) {
                    echo '</span>';
                }
                break;
            default:
                $notes = $this->getMyNotes(false);
                echo '<ol class="note_list plainList">';
                if (is_array($notes)) {
                    foreach ($notes as $note) {
                        if ($serendipity['version'][0] < 2) {
                            echo '<li><strong>' . $note['subject'] . '</strong> ' . POSTED_BY . ' ' . $note['realname'] . ' ' . ON . ' ' . serendipity_strftime(DATE_FORMAT_SHORT, $note['notetime']) . '<br />';
                            echo '<a class="serendipityPrettyButton" href="?serendipity[adminModule]=event_display&amp;serendipity[adminAction]=adminnotes&amp;action=edit&amp;note=' . $note['noteid'] . '">' . EDIT . '</a> ';
                            echo '<a class="serendipityPrettyButton" href="?serendipity[adminModule]=event_display&amp;serendipity[adminAction]=adminnotes&amp;action=delete&amp;note=' . $note['noteid'] . '">' . DELETE . '</a> ';
                            echo '<br /><br /></li>';
                        } else {
                            echo '<li><h3>' . $note['subject'] . '</h3><p>' . POSTED_BY . ' ' . $note['realname'] . ' ' . ON . ' ' . serendipity_strftime(DATE_FORMAT_SHORT, $note['notetime']) . '</p>';
                            echo '<div class="form_buttons"><a class="button_link state_submit" href="?serendipity[adminModule]=event_display&amp;serendipity[adminAction]=adminnotes&amp;action=edit&amp;note=' . $note['noteid'] . '">' . EDIT . '</a> ';
                            echo '<a class="button_link state_cancel" href="?serendipity[adminModule]=event_display&amp;serendipity[adminAction]=adminnotes&amp;action=delete&amp;note=' . $note['noteid'] . '">' . DELETE . '</a></div></li>';
                        }
                    }
                }
                echo '</ol>';
                if ($serendipity['version'][0] < 2) {
                    echo '<a class="serendipityPrettyButton" href="?serendipity[adminModule]=event_display&amp;serendipity[adminAction]=adminnotes&amp;action=new">' . NEW_ENTRY . '</a>';
                } else {
                    echo '<div class="form_buttons"><a class="button_link state_submit" href="?serendipity[adminModule]=event_display&amp;serendipity[adminAction]=adminnotes&amp;action=new">' . NEW_ENTRY . '</a></div>';
                }
                break;
        }
    }
/**
 * Show the list of plugins
 *
 * Shows a HTML list of all installed plugins, complete with config/delete/sort order options
 *
 * @access public
 * @param  boolean  Indicates if event plugins (TRUE) or sidebar plugins (FALSE) shall be shown
 * @return null
 */
function show_plugins($event_only = false, $sidebars = null)
{
    global $serendipity;
    $sql_filter = '';
    if (is_array($sidebars)) {
        foreach ($sidebars as $sidebar) {
            $up = strtoupper($sidebar);
            if ($sidebar == 'hide') {
                $opts[$sidebar] = HIDDEN;
            } elseif (defined('SIDEBAR_' . $up)) {
                $opts[$sidebar] = constant('SIDEBAR_' . $up);
            } elseif (defined($up)) {
                $opts[$sidebar] = constant($up);
            } else {
                $opts[$sidebar] = $up;
            }
            $sql_filter .= "AND placement != '" . serendipity_db_escape_string($sidebar) . "' ";
        }
    }
    if (!$event_only) {
        $sql = "SELECT * from {$serendipity['dbPrefix']}plugins\n                   WHERE placement != 'event'\n                     AND placement != 'eventh'\n                         " . $sql_filter;
        $invisible_plugins = serendipity_db_query($sql);
        if (is_array($invisible_plugins)) {
            $sidebars[] = 'NONE';
            $opts['NONE'] = NONE;
        }
    }
    $opts['event'] = PLUGIN_ACTIVE;
    $opts['eventh'] = PLUGIN_INACTIVE;
    $data['event_only'] = $event_only;
    if (!$event_only) {
        $data['is_first'] = true;
    }
    $data['serendipity_setFormToken'] = serendipity_setFormToken();
    $data['serendipity_setFormTokenUrl'] = serendipity_setFormToken('url');
    /* Block display the plugins per placement location. */
    if ($event_only) {
        $plugin_placements = array('event', 'eventh');
    } else {
        $plugin_placements = $sidebars;
    }
    $data['plugin_placements'] = $plugin_placements;
    static $users = array();
    if (empty($users)) {
        $users = serendipity_fetchUsers('', 'hidden');
    }
    $data['users'] = $users;
    $i = 0;
    foreach ($plugin_placements as $plugin_placement) {
        if (!$event_only && $plugin_placement == 'NONE') {
            $is_invisible = true;
        } else {
            $is_invisible = false;
        }
        $data['placement'][$plugin_placement]['ptitle'] = $ptitle = $opts[$plugin_placement];
        $data['placement'][$plugin_placement]['pid'] = $pid = $plugin_placement;
        if ($is_invisible) {
            $plugins = $invisible_plugins;
        } else {
            $plugins = serendipity_plugin_api::enum_plugins($plugin_placement);
        }
        if (!is_array($plugins)) {
            continue;
        }
        $sort_idx = 0;
        foreach ($plugins as $plugin_data) {
            $i++;
            $plugin =& serendipity_plugin_api::load_plugin($plugin_data['name'], $plugin_data['authorid']);
            $key = urlencode($plugin_data['name']);
            $css_key = 's9ycid' . str_replace('%', '-', $key);
            $is_plugin_owner = $plugin_data['authorid'] == $serendipity['authorid'] || serendipity_checkPermission('adminPluginsMaintainOthers');
            $is_plugin_editable = $is_plugin_owner || $plugin_data['authorid'] == '0';
            $cname = explode(':', $plugin_data['name']);
            if (!is_object($plugin)) {
                $name = $title = ERROR . '!';
                $desc = ERROR . ': ' . $plugin_data['name'];
                $can_configure = false;
            } else {
                /* query for its name, description and configuration data */
                $bag = new serendipity_property_bag();
                $plugin->introspect($bag);
                $name = serendipity_specialchars($bag->get('name'));
                $desc = '<details class="plugin_data">';
                $desc .= '<summary><var class="perm_name">' . $cname[0] . '</var></summary>';
                $desc .= '<div class="plugin_desc clearfix">' . serendipity_specialchars($bag->get('description')) . '</div>';
                $desc .= '<span class="block_level">' . VERSION . ': ' . $bag->get('version') . '</span>';
                $desc .= '</details>';
                $title = serendipity_plugin_api::get_plugin_title($plugin, '[' . $name . ']');
                if ($bag->is_set('configuration') && ($plugin->protected === FALSE || $plugin_data['authorid'] == '0' || $plugin_data['authorid'] == $serendipity['authorid'] || serendipity_checkPermission('adminPluginsMaintainOthers'))) {
                    $can_configure = true;
                } else {
                    $can_configure = false;
                }
            }
            if ($opts === null) {
                $opts = array('left' => LEFT, 'right' => RIGHT, 'hide' => HIDDEN);
            }
            $event_opts = array('event' => PLUGIN_ACTIVE, 'eventh' => PLUGIN_INACTIVE);
            if ($event_only) {
                $gopts = $event_opts;
            } else {
                $gopts = $opts;
            }
            $data['placement'][$plugin_placement]['plugin_data'][$i]['sort_idx'] = $sort_idx;
            $data['placement'][$plugin_placement]['plugin_data'][$i]['css_key'] = $css_key;
            $data['placement'][$plugin_placement]['plugin_data'][$i]['is_plugin_editable'] = $is_plugin_editable;
            $data['placement'][$plugin_placement]['plugin_data'][$i]['is_plugin_owner'] = $is_plugin_owner;
            $data['placement'][$plugin_placement]['plugin_data'][$i]['name'] = $plugin_data['name'];
            $data['placement'][$plugin_placement]['plugin_data'][$i]['authorid'] = $plugin_data['authorid'];
            $data['placement'][$plugin_placement]['plugin_data'][$i]['can_configure'] = $can_configure;
            $data['placement'][$plugin_placement]['plugin_data'][$i]['key'] = $key;
            $data['placement'][$plugin_placement]['plugin_data'][$i]['title'] = $title;
            $data['placement'][$plugin_placement]['plugin_data'][$i]['desc'] = $desc;
            $data['placement'][$plugin_placement]['plugin_data'][$i]['placement'] = $plugin_data['placement'];
            $data['placement'][$plugin_placement]['plugin_data'][$i]['gopts'] = $gopts;
            $sort_idx++;
        }
    }
    $data['total'] = $i;
    return serendipity_smarty_show('admin/show_plugins.fnc.tpl', $data);
}
function serendipity_smarty_setFormToken($params, &$smarty)
{
    if (isset($params['type'])) {
        return serendipity_setFormToken($params['type']);
    }
    return serendipity_setFormToken();
}
Esempio n. 19
0
        ?>
    <div class="serendipityAdminMsgSuccess"><img width="22px" height="22px" style="border: 0px; padding-right: 4px; vertical-align: middle" src="<?php 
        echo serendipity_getTemplateFile('admin/img/admin_msg_success.png');
        ?>
" alt="" /><?php 
        echo sprintf(MODIFIED_USER, htmlspecialchars($_POST['realname']));
        ?>
</div>
<?php 
    }
}
?>

<form action="?serendipity[adminModule]=personal&amp;serendipity[adminAction]=save" method="post">
<?php 
echo serendipity_setFormToken();
$template = serendipity_parseTemplate(S9Y_CONFIG_USERTEMPLATE);
$user = serendipity_fetchUsers($serendipity['authorid']);
$from = $user[0];
$from['groups'] = serendipity_getGroups($serendipity['authorid']);
unset($from['password']);
serendipity_printConfigTemplate($template, $from, true, false);
?>
    <div align="right"><input class="serendipityPrettyButton input_button" type="submit" name="SAVE"   value="<?php 
echo SAVE;
?>
" /></div>
</form>

<?php 
$add = array('internal' => true);
    function event_hook($event, &$bag, &$eventData, $addData = null)
    {
        global $serendipity;
        $hooks =& $bag->get('event_hooks');
        if (isset($hooks[$event])) {
            // Moved from above: only get image data if we're actually going to do something
            $this->set_valid_image_data();
            // Get dimensions of image, only if not text-only
            if ($this->image_name) {
                // Is this a single-image bar, or a single segment?
                $ratio = $this->image_width / $this->image_height;
                if ($ratio < $this->max_segment_ratio) {
                    // This is probably a single segment. Square segments
                    // will have a ratio of 0.3; long, flat segments won't
                    // get up to 1.0 unless they're 3 times as wide as they
                    // are tall; full-bar images with square segments will
                    // be 1.666; and full-bar images with tall, narrow
                    // segments will be greater than 1.0 unless they're
                    // nearly twice as high as they are wide.
                    $this->image_width = $this->image_width * 5;
                }
            }
            switch ($event) {
                //Javascript for ajax functionality
                case 'frontend_footer':
                    if ($this->get_config('ajax') == true) {
                        ?>
<script type="text/javascript">
/*<![CDATA[ */
ajaxloader = new Image();
ajaxloader.src = "<?php 
                        echo $serendipity['baseURL'];
                        ?>
plugins/serendipity_event_karma/img/ajax-loader.gif";
for (i=1;i<6;i++) {
    jQuery('.serendipity_karmaVoting_link'+i).click(function(event) {
        event.preventDefault();
        karmaId = jQuery(this).attr('href').match(/\[karmaId\]=([0-9]+)/);
        vote(jQuery(this).html(),karmaId[1]);
    });
}

function vote(karmaVote,karmaId) {
    // Send the data using post and put the results in place
    jQuery('#karma_vote'+karmaId).parent().children('.serendipity_karmaVoting_links').replaceWith('<div class="serendipity_karmaVoting_links ajaxloader"><img src="<?php 
                        echo $serendipity['baseURL'];
                        ?>
plugins/serendipity_event_karma/img/ajax-loader.gif" border="0" alt="ajax-loader" /></div>');
    jQuery.post("<?php 
                        echo $serendipity['baseURL'] . $serendipity['permalinkPluginPath'];
                        ?>
/karma-ajaxquery", { karmaVote: karmaVote, karmaId: karmaId }, function(data) {
        jQuery('#karma_vote'+karmaId).parent().replaceWith(data);
    });
}
/* ]]>*/
</script>
<?php 
                    }
                    // Hook for ajax calls
                // Hook for ajax calls
                case 'external_plugin':
                    $theUri = (string) str_replace('&amp;', '&', $eventData);
                    $uri_parts = explode('?', $theUri);
                    // Try to get request parameters from eventData name
                    if (!empty($uri_parts[1])) {
                        $reqs = explode('&', $uri_parts[1]);
                        foreach ($reqs as $id => $req) {
                            $val = explode('=', $req);
                            if (empty($_REQUEST[$val[0]])) {
                                $_REQUEST[$val[0]] = $val[1];
                            }
                        }
                    }
                    $parts = explode('_', $uri_parts[0]);
                    switch ($parts[0]) {
                        case 'karma-ajaxquery':
                            $this->performkarmaVote();
                            $q = "SELECT SUM(votes) AS votes, SUM(points) AS points, SUM(visits) AS visits\n                                    FROM " . $serendipity['dbPrefix'] . "karma\n                                   WHERE entryid = '" . (int) $_POST['karmaId'] . "';";
                            $sql = serendipity_db_query($q);
                            $track_clicks = serendipity_db_bool($this->get_config('visits_active', true));
                            $track_karma = serendipity_db_bool($this->get_config('karma_active', true));
                            $enough_votes = $track_karma && $sql[0]['votes'] >= $this->get_config('min_disp_votes', 0);
                            $enough_visits = $track_clicks && $sql[0]['visits'] >= $this->get_config('min_disp_visits', 0);
                            $textual_msg = true;
                            $textual_current = true;
                            $textual_visits = true;
                            if ($this->image_name != '0') {
                                $textual_msg = $this->get_config('textual_msg', 'true');
                                $textual_current = $this->get_config('textual_current', 'true');
                                $textual_visits = $this->get_config('textual_visits', 'true');
                            }
                            $temp = $this->karmaVoted((int) $_POST['karmaVote'], $sql[0]['points'], $sql[0]['votes']);
                            $myvote = $temp['myvote'];
                            $msg = $temp['msg'];
                            $bar = $temp['bar'];
                            $temp = $this->createkarmaBlock((int) $_POST['karmaId'], $textual_msg, $msg, $bar, $enough_votes, $textual_current, $enough_visits, $textual_visits, $sql[0]['points'], $sql[0]['votes']);
                            $karma_block = $temp['karma_block'];
                            $points = $temp['points'];
                            echo sprintf($karma_block, $myvote, $points, $sql[0]['votes'], $sql[0]['visits'], '');
                            break;
                    }
                    return true;
                    break;
                    // Early hook, before any page is displayed
                // Early hook, before any page is displayed
                case 'frontend_configure':
                    $this->performkarmaVote();
                    return true;
                    break;
                    // CSS generation hooks
                // CSS generation hooks
                case 'backend_header':
                    if ($serendipity['GET']['adminModule'] == 'event_display' && $serendipity['GET']['adminAction'] == 'karmalog' || $serendipity['GET']['adminModule'] == 'plugins') {
                        // Generate the CSS for the graphical rating bar selector
                        //
                        // The CSS appears to be generated in a completely
                        // different instance of Serendipity, as if index.php gets
                        // called separately for the CSS.
                        //
                        // Note that the css_backend hook adds properties to the
                        // serendipity_admin.css, but that file is *always*
                        // cached.  We use backend_header and add the CSS to the
                        // HEAD styles to make it dynamic. (Edit: with 2.0 this has changed)
                        // Get the CSS, set $this->image_name so we'll output the
                        // standard graphical CSS prologue if any images are found.
                        $this->createRatingSelector();
                        print "<style type='text/css'>\n";
                        $align = 'center';
                        $bg = $this->get_config('preview_bg', false);
                        if (!empty($bg)) {
                            if (strpos($bg, ';') !== false || strpos($bg, ',') !== false) {
                                $bg = 'red';
                            }
                            print "\n.serendipity_karmaVote_selectorTable {\n    background: {$bg};\n}\n";
                        }
                        print "\n.serendipityAdminContent .serendipity_karmaVoting_links {\n    margin: 5px;\n}\n";
                        if ($serendipity['version'][0] > 1) {
                            print "\n</style>\n";
                        }
                    }
                    if ($serendipity['version'][0] > 1) {
                        break;
                        return true;
                    }
                case 'css_backend':
                case 'css':
                    // Some CSS notes:
                    //
                    // .serendipity_karmaVoting is the class for the karma wrapper/container,
                    //      including the text explanations, messages, and rating bar.
                    //      (currently a div)
                    // .serendipity_karmaVoting a specifies the links for the text-mode
                    //      rating bar
                    // .serendipity_karmaError is the class for any text indicating an
                    //      error condition
                    // .serendipity_karmaSuccess is the class for any text indicating
                    //      successful operation
                    // .serendipity_karmaVoting_links is the container for the graphical
                    //      rating bar (currently an ol)
                    // .serendipity_karmaVoting_links a indicates the various voting links in
                    //      the graphical rating bar
                    // .serendipity_karmaVoting_current-rating is the class for the current
                    //      rating in the graphical rating bar
                    //  a.serendipity_karmaVoting_link1, _link2, etc are the classes applied
                    //      to the individual voting links
                    // Note that there are two possible template types: early
                    // templates that only handle the text rating bars, and
                    // newer templates that understand the graphical raters.
                    // We check for both types and act appropriately.
                    /*--JAM: Let's just skip this whole hassle
                      if (!$align) {
                          $align = $this->get_config('alignment', 'detect');
                      }
                      if ($align == 'detect') {
                      */
                    $align = $this->get_config('alignment');
                    // Try to let the template take care of it
                    if ($this->image_name == '0') {
                        // Text-only rating bar is used
                        if (strpos($eventData, '.serendipity_karmaVoting')) {
                            // Template is handling all our CSS
                            return true;
                        }
                    }
                    /* --JAM: else {
                               // Graphical rating bar is used
                               if (strpos($eventData, '.serendipity_karmaVoting_images')) {
                                   // Template is handling all our CSS
                                   return true;
                               }
                               // Check for old text-only templates
                               $pos = strpos($eventData, '.serendipity_karmaVoting');
                               while ($pos && ($align == 'detect')) {
                                   // Find text-align: in the current block
                                   $endpos = strpos($eventData, '}', $pos);
                                   if (!$endpos) {
                                       // Broken CSS
                                       break;
                                   }
                                   $alignpos = strpos($eventData, 'text-align:', $pos);
                                   // Can't check for comments, or I would.  Hope
                                   // the first is the correct one.
                                   if ($alignpos && $alignpos < $endpos) {
                                       $start = $alignpos + 11;
                                       $alignend = strpos($eventData, ';', $alignpos);
                                       if ($alignend)
                                       {
                                           // All valid.  Pull out the alignment.
                                           $len = $alignend - $start;
                                           $align = trim(substr($eventData, $start, $len));
                                       }
                                   }
                                   $pos = strpos($eventData, '.serendipity_karmaVoting', $endpos);
                               }
                               // I should have a valid alignment or 'detect' in $align now.
                           }
                       }
                       // If we couldn't detect the alignment, guess 'right'
                       if ($align == 'detect') {
                           $align = 'right';
                       }
                       --JAM: END COMMENT BLOCK */
                    if ($serendipity['version'][0] < 2 && $event == 'backend_header') {
                        print "<style type='text/css'>\n";
                    }
                    // Since errors might be printed at any time, always
                    // output the text-mode CSS
                    print <<<EOS
.serendipity_karmaVoting {
    text-align: {$align};
    font-size: 7pt;
    margin: 0px;
}

.serendipity_karmaVoting a {
    font-size: 7pt;
    text-decoration: none;
}

.serendipity_karmaVoting a:hover {
    color: green;
}

.serendipity_karmaError {
    color: #FF8000;
}
.serendipity_karmaSuccess {
    color: green;
}
EOS;
                    // Only output the image CSS if it's needed
                    if ($this->image_name != '0') {
                        $img = $serendipity['baseURL'] . "plugins/serendipity_event_karma/img/" . $this->image_name;
                        $h = $this->image_height / 3;
                        $w = $this->image_width;
                        switch ($align) {
                            case 'left':
                                $margin = '0px auto 0px 0px';
                                break;
                            case 'center':
                                $margin = '0px auto';
                                break;
                            case 'right':
                            default:
                                $margin = '0px 0px 0px auto';
                                break;
                        }
                        // The CSS here is lifted largely from
                        // http://komodomedia.com/blog/index.php/2007/01/20/css-star-rating-redux/
                        //
                        // Note, however that margin has been changed for
                        // multiple cases and all unitless measurements have
                        // been specified in pixels.  Additionally, measures
                        // have been taken to align the text.
                        print <<<END_IMG_CSS

.serendipity_karmaVoting_links,
.serendipity_karmaVoting_links a:hover,
.serendipity_karmaVoting_current-rating {
    background: url({$img}) left;
    font-size: 0;
}
.ajaxloader {
    background-image: none;
}
.serendipity_karmaVoting_links {
    position: relative;
    width: {$w}px;
    height: {$h}px;
    overflow: hidden;
    list-style: none;
    margin: {$margin};
    padding: 0;
    background-position: left top;
    text-align: center;
}
.serendipity_karmaVoting_links li {
   display: inline;
}
.serendipity_karmaVoting_links a ,
.serendipity_karmaVoting_current-rating {
    position:absolute;
    top: 0;
    left: 0;
    text-indent: -9000em;
    height: {$h}px;
    line-height: {$h}px;
    outline: none;
    overflow: hidden;
    border: none;
}
.serendipity_karmaVoting_links a:hover {
    background-position: left bottom;
}
.serendipity_karmaVoting_links a.serendipity_karmaVoting_link1 {
    width: 20%;
    z-index: 6;
}
.serendipity_karmaVoting_links a.serendipity_karmaVoting_link2 {
    width: 40%;
    z-index: 5;
}
.serendipity_karmaVoting_links a.serendipity_karmaVoting_link3 {
    width: 60%;
    z-index: 4;
}
.serendipity_karmaVoting_links a.serendipity_karmaVoting_link4 {
    width: 80%;
    z-index: 3;
}
.serendipity_karmaVoting_links a.serendipity_karmaVoting_link5 {
  width: 100%;
    z-index: 2;
}
.serendipity_karmaVoting_links .serendipity_karmaVoting_current-rating {
    z-index: 1;
    background-position: left center;
}

END_IMG_CSS;
                        // Add selector images CSS, if necessary
                        if (!empty($this->select_css)) {
                            print $this->select_css;
                        }
                    }
                    // End if image bar defined
                    if ($serendipity['version'][0] < 2 && $event == 'backend_header') {
                        print "\n</style>\n";
                    }
                    return true;
                    break;
                    //--TODO: Comment the functionality of this event hook.
                //--TODO: Comment the functionality of this event hook.
                case 'event_additional_statistics':
                    $sql = array();
                    $sql['visits_top'] = array('visits', 'DESC');
                    $sql['visits_bottom'] = array('visits', 'ASC');
                    $sql['votes_top'] = array('votes', 'DESC');
                    $sql['votes_bottom'] = array('votes', 'ASC');
                    $sql['points_top'] = array('points', 'DESC');
                    $sql['points_bottom'] = array('points', 'ASC');
                    foreach ($sql as $key => $rows) {
                        $q = "SELECT e.id,\n                                     e.title,\n                                     e.timestamp,\n                                     SUM(k.{$rows[0]}) AS no\n                                FROM {$serendipity['dbPrefix']}karma\n                                     AS k\n                                JOIN {$serendipity['dbPrefix']}entries\n                                     AS e\n                                  ON k.entryid = e.id\n                            WHERE k.{$rows[0]} IS NOT NULL AND k.{$rows[0]} != 0\n                            GROUP BY e.id, e.title, e.timestamp ORDER BY no {$rows[1]} LIMIT {$addData['maxitems']}";
                        $sql_rows = serendipity_db_query($q);
                        ?>
    <section>
        <h3><?php 
                        echo constant('PLUGIN_KARMA_STATISTICS_' . strtoupper($key));
                        ?>
</h3>

        <dl>
<?php 
                        if (is_array($sql_rows)) {
                            foreach ($sql_rows as $id => $row) {
                                ?>
            <dt><a href="<?php 
                                echo serendipity_archiveURL($row['id'], $row['title'], 'serendipityHTTPPath', true, array('timestamp' => $row['timestamp']));
                                ?>
"><?php 
                                echo function_exists('serendipity_specialchars') ? serendipity_specialchars($row['title']) : htmlspecialchars($row['title'], ENT_COMPAT, LANG_CHARSET);
                                ?>
</a></dt>
            <dd><?php 
                                echo $row['no'];
                                ?>
 <?php 
                                echo constant('PLUGIN_KARMA_STATISTICS_' . strtoupper($rows[0]) . '_NO');
                                ?>
</dd>
    <?php 
                            }
                        }
                        ?>
        </dl>
    </section>
<?php 
                    }
                    return true;
                    break;
                    // Add voting information to entries
                // Add voting information to entries
                case 'entry_display':
                    // Update database if necessary
                    if ($this->get_config('dbversion', 0) != PLUGIN_KARMA_DB_VERSION) {
                        $this->checkScheme();
                    }
                    // Find the ID of this entry
                    if (isset($serendipity['GET']['id'])) {
                        $entryid = (int) serendipity_db_escape_string($serendipity['GET']['id']);
                    } elseif (preg_match(PAT_COMMENTSUB, $_SERVER['REQUEST_URI'], $matches)) {
                        $entryid = (int) $matches[1];
                    } else {
                        $entryid = false;
                    }
                    // If we're actually reading the entry, not voting or editing it...
                    if ($entryid && empty($serendipity['GET']['adminAction']) && !$serendipity['GET']['karmaVote']) {
                        // Update the number of visits
                        // Are we supposed to track visits?
                        $track_clicks = serendipity_db_bool($this->get_config('visits_active', true)) && $this->track_clicks_allowed_by_user();
                        if ($track_clicks && $_SERVER['REQUEST_METHOD'] == 'GET') {
                            $sql = serendipity_db_query("UPDATE {$serendipity['dbPrefix']}karma \n                                    SET visits = visits + 1 \n                                  WHERE entryid = {$entryid}", true);
                            if (serendipity_db_affected_rows() < 1) {
                                serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}karma (entryid, points, votes, lastvote, visits) \n                                              VALUES ('{$entryid}', 0, 0, 0, 1)");
                            }
                        }
                    }
                    // Set a cookie to look for later, verifying that cookies are enabled
                    serendipity_setCookie('check', '1');
                    switch ($this->karmaVote) {
                        case 'nocookie':
                            // Users with no cookies won't be able to vote.
                            $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_NOCOOKIE . '</div>';
                            // Continue until output
                        // Continue until output
                        case 'timeout2':
                            if (!isset($msg)) {
                                $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_CLOSED . '</div>';
                            }
                            // Continue until output
                        // Continue until output
                        case 'timeout':
                            if (!isset($msg)) {
                                $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . sprintf(PLUGIN_KARMA_TIMEOUT, $this->karmaTimeOut) . '</div>';
                            }
                            // Continue until output
                        // Continue until output
                        case 'alreadyvoted':
                            if (!isset($msg)) {
                                $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_ALREADYVOTED . '</div>';
                            }
                            // Continue until output
                        // Continue until output
                        case 'invalid1':
                        case 'invalid2':
                        case 'invalid':
                            // Set message
                            if (!isset($msg)) {
                                $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_INVALID . '</div>';
                            }
                            // Continue until output
                            /* OUTPUT MESSAGE */
                            //--TODO: Shouldn't this work with the cache plugin, too?
                            if ($addData['extended']) {
                                $eventData[0]['exflag'] = 1;
                                $eventData[0]['add_footer'] .= $msg;
                            } else {
                                $elements = count($eventData);
                                // Find the right container to store our message in.
                                for ($i = 0; $i < $elements; $i++) {
                                    if ($eventData[$i]['id'] == $this->karmaId) {
                                        $eventData[$i]['add_footer'] .= $msg;
                                    }
                                }
                            }
                            break;
                        case 'voted':
                        default:
                            // If there's no data, there's no need to go on
                            if (!is_array($eventData)) {
                                return;
                            }
                            // Find out what the admin wants
                            $track_clicks = serendipity_db_bool($this->get_config('visits_active', true));
                            $track_karma = serendipity_db_bool($this->get_config('karma_active', true));
                            if (serendipity_db_bool($this->get_config('karma_active_registered', false))) {
                                if (!serendipity_userLoggedIn()) {
                                    $track_karma = false;
                                }
                            }
                            $track_exits = serendipity_db_bool($this->get_config('exits_active', true));
                            // Get the limits
                            $now = time();
                            $karmatime = $this->get_config('max_karmatime', 7);
                            $max_karmatime = $karmatime * 24 * 60 * 60;
                            // Accept infinite voting
                            if ($max_karmatime <= 0) {
                                $max_karmatime = $now;
                            }
                            //--TODO: Ensure that this works with the Custom Permalinks plugin
                            // (We've seen trouble; it votes correctly, but redirects to the front page)
                            $url = serendipity_currentURL(true);
                            // Voting is only allowed on entries.  Therefore voting URLs must be
                            // either single-entry URLs or summary URLs.  serendipity_currentURL
                            // converts them to an "ErrorDocument-URI", so we can focus on the
                            // query portion of the URI.
                            //
                            // Single-entry URLs should be well-defined.  They can be permalinks,
                            // of course; otherwise they're of the configured pattern.
                            //
                            // Summary URLs could be a little harder.  The summary pages that
                            // include entries are: frontpage, category, author, and archives.
                            // It's possible a plugin would show entries, but if that's the case
                            // we don't need to allow the user to vote on them.  Still, that's
                            // a lot of URLs to check for.
                            //
                            // Then there's the problem of the rest of the query.  It could
                            // include stuff we really want to keep around, like template
                            // overrides or something.  One can even add serendipity variables
                            // to the URL in extreme cases.
                            //
                            // It seems that canonicalizing the URL will be quite difficult.
                            // The only thing we can say for certain is that whatever the
                            // current URL is, it got us to this page, and we'd like to return
                            // to this page after we cast our vote.
                            // Remove any clutter from our previous voting activity
                            $url_parts = parse_url(serendipity_currentURL(true));
                            if (!empty($url_parts['query'])) {
                                $exclude = array('serendipity[karmaVote]', 'serendipity[karmaId]');
                                // I tried using parse_str, but it gave me very weird results
                                // with embedded arrays
                                //parse_str($url_parts['query'], $q_parts);
                                $q_parts = array();
                                // I don't know why this URL has been HTML encoded.  Oh well.
                                $pairs = explode('&amp;', $url_parts['query']);
                                foreach ($pairs as $pair) {
                                    $parts = explode('=', $pair);
                                    $q_parts[$parts[0]] = $parts[1];
                                }
                                foreach ($q_parts as $key => $value) {
                                    if (in_array($key, $exclude)) {
                                        $rm = preg_quote("{$key}={$value}");
                                        $url = preg_replace("@(&amp;|&)?{$rm}@", '', $url);
                                    }
                                }
                            }
                            if (substr($url, -1) != '?') {
                                $url .= '&amp;';
                            }
                            // Get the cookie data (past votes, etc)
                            $karma = isset($serendipity['COOKIE']['karmaVote']) ? unserialize($serendipity['COOKIE']['karmaVote']) : array();
                            // Get all required entry IDs, making keys match keys in eventData
                            $entries = array();
                            if ($addData['extended'] || $addData['preview']) {
                                // We're in extended or preview mode, we only need the current ID
                                $eventData[0]['exflag'] = 1;
                                $entries[0] = (int) $eventData[0]['id'];
                            } elseif (!serendipity_db_bool($this->get_config('extended_only', false))) {
                                // We're in overview mode, and we want rating bars for all the entry IDs
                                foreach (array_keys($eventData) as $key) {
                                    if (isset($eventData[$key]['id'])) {
                                        $entries[$key] = (int) $eventData[$key]['id'];
                                    }
                                }
                            }
                            // Fetch votes for all entry IDs. Store them in an array for later usage.
                            $q = 'SELECT k.entryid, SUM(votes) AS votes, SUM(points) AS points, SUM(visits) AS visits
                                    FROM ' . $serendipity['dbPrefix'] . 'karma   AS k
                                   WHERE k.entryid IN (' . implode(', ', $entries) . ') GROUP BY k.entryid';
                            $sql = serendipity_db_query($q);
                            $rows = array();
                            if ($sql && is_array($sql)) {
                                foreach ($sql as $row) {
                                    $rows[$row['entryid']] = array('votes' => $row['votes'], 'points' => $row['points'], 'visits' => $row['visits']);
                                }
                            }
                            $this->prepareExits($entries);
                            // Add karma block to the footer of each entry
                            //
                            // The entries array was populated, above, so its keys match the eventData array,
                            // and overview entries are skipped if "extended only" is enabled
                            foreach (array_keys($entries) as $i) {
                                // Get the statistics
                                $entryid = $eventData[$i]['id'];
                                $votes = !empty($rows[$entryid]['votes']) ? $rows[$entryid]['votes'] : 0;
                                $points = !empty($rows[$entryid]['points']) ? $rows[$entryid]['points'] : 0;
                                $visits = !empty($rows[$entryid]['visits']) ? $rows[$entryid]['visits'] : 0;
                                $enough_votes = $track_karma && $votes >= $this->get_config('min_disp_votes', 0);
                                $enough_visits = $track_clicks && $visits >= $this->get_config('min_disp_visits', 0);
                                $textual_msg = true;
                                $textual_current = true;
                                $textual_visits = true;
                                if ($this->image_name != '0') {
                                    $textual_msg = $this->get_config('textual_msg', 'true');
                                    $textual_current = $this->get_config('textual_current', 'true');
                                    $textual_visits = $this->get_config('textual_visits', 'true');
                                }
                                // Where's the footer?  Normally it would be
                                // in eventData[n]['add_footer'] but if the
                                // cache plugin is used, it's in
                                // eventData[n]['properties']['ep_cache_add_footer'].
                                // This method retrieves it either way.
                                $footer =& $this->getFieldReference('add_footer', $eventData[$i]);
                                // Depending on what existed, $footer could
                                // be referencing the cached version, the
                                // uncached version, or even a new empty
                                // string.  In particular, if $eventData[$i]
                                // has no properties, and no 'add_footer' key,
                                // $footer is referencing a new empty string,
                                // so adding a karma bar to $footer would do
                                // nothing.
                                //
                                // We could be referencing an empty uncached
                                // 'add_footer', but empty cache entries are
                                // never returned.
                                //
                                // Reference a footer that will be printed
                                if (empty($footer) && !isset($eventData[$i]['add_footer']) && is_array($eventData[$i])) {
                                    $eventData[$i]['add_footer'] = '';
                                    $footer =& $eventData[$i]['add_footer'];
                                    // It's still empty, but it's referencing
                                    // the right place.
                                }
                                if ($track_exits) {
                                    $footer .= $this->getExits($entryid, true);
                                }
                                // Pick the appropriate intro msg and rating bar
                                // No msg or bar if karma is disabled
                                if ($track_karma) {
                                    if (isset($karma[$entryid])) {
                                        // We already voted for this one
                                        $temp = $this->karmaVoted($karma[$entryid], $points, $votes);
                                        $myvote = $temp['myvote'];
                                        $msg = $temp['msg'];
                                        $bar = $temp['bar'];
                                    } elseif ($eventData[$i]['timestamp'] < $now - $max_karmatime) {
                                        // Too late to vote for this one
                                        $msg = '<div class="serendipity_karmaClosed">' . sprintf(PLUGIN_KARMA_CLOSED, $karmatime) . '</div>';
                                        // Just a current rating bar, if any
                                        $bar = $this->createRatingBar(null, $points, $votes);
                                    } else {
                                        // We can vote for this; make the whole voting block
                                        $rate_msg = $this->get_config('rate_msg', PLUGIN_KARMA_VOTETEXT);
                                        $msg = '<div class="serendipity_karmaVoting_text">' . $rate_msg . '</div>';
                                        // Full voting bar
                                        $bar = $this->createRatingBar($entryid, $points, $votes);
                                    }
                                }
                                // Create the karma block
                                $temp = $this->createkarmaBlock($entryid, $textual_msg, $msg, $bar, $enough_votes, $textual_current, $enough_visits, $textual_visits, $points, $votes);
                                $karma_block = $temp['karma_block'];
                                $points = $temp['points'];
                                /*
                                  print("<h3>--DEBUG: Karma block code:</h3>\n<pre>\n");
                                  print_r(htmlspecialchars($karma_block));
                                  print("\n</pre>\n");
                                */
                                // Substitute the % stuff and add it to the footer
                                $eventData[$i]['properties']['myvote'] = $myvote;
                                $eventData[$i]['properties']['points'] = $points;
                                $eventData[$i]['properties']['votes'] = $votes;
                                $eventData[$i]['properties']['visits'] = $visits;
                                $footer .= sprintf($karma_block, $myvote, $points, $votes, $visits, $url);
                            }
                            // foreach key in entries
                    }
                    // End switch on karma voting status
                    return true;
                    break;
                    // Display the Karma Log link on the sidebar
                // Display the Karma Log link on the sidebar
                case 'backend_sidebar_admin_appearance':
                    ?>
<li><a href="?serendipity[adminModule]=event_display&amp;serendipity[adminAction]=karmalog"><?php 
                    echo PLUGIN_KARMA_DISPLAY_LOG;
                    ?>
</a></li>
<?php 
                    return true;
                    break;
                    // Display the Karma Log!
                    //case 'external_plugin':
                // Display the Karma Log!
                //case 'external_plugin':
                case 'backend_sidebar_entries_event_display_karmalog':
                    // Print any stored messages
                    //foreach ($serendipity['karma_messages'] as $msg) {
                    //    print("<div class='serendipityAdminInfo'>$msg</div>\n");
                    //}
                    // Was I asked to process any votes?
                    if (($serendipity['POST']['delete_button'] || $serendipity['POST']['approve_button']) && sizeof($serendipity['POST']['delete']) != 0 && serendipity_checkFormToken()) {
                        foreach ($serendipity['POST']['delete'] as $d => $i) {
                            $kdata = $serendipity['POST']['karmalog' . $i];
                            // validate posted variables
                            // posted points
                            $ppoints = $kdata['points'];
                            if (!is_numeric($ppoints) || (int) $ppoints < -2 || (int) $ppoints > 2) {
                                print "<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_INVALID_INPUT . "</span>\n";
                                return false;
                            }
                            // posted id
                            $pid = $kdata['entryid'];
                            if (!is_numeric($pid)) {
                                print "<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_INVALID_INPUT . "</span>\n";
                                return false;
                            }
                            // posted IP
                            $pip = long2ip(ip2long($kdata['ip']));
                            if ($pip == -1 || $pip === FALSE) {
                                print "<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_INVALID_INPUT . "</span>\n";
                                return false;
                            }
                            // posted user agent (need a better validator, I think)
                            $puser_agent = $kdata['user_agent'];
                            if (serendipity_db_escape_string($puser_agent) != $puser_agent) {
                                print "<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_INVALID_INPUT . "</span>\n";
                                return false;
                            }
                            // posted vote time
                            $pvotetime = $kdata['votetime'];
                            $unixsecs = date('U', $kdata['votetime']);
                            if ($pvotetime != $unixsecs) {
                                print "<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_INVALID_INPUT . "</span>\n";
                                return false;
                            }
                            // Remove karma from entry?
                            if ($serendipity['POST']['delete_button']) {
                                // Fetch vote total for the entry IDs
                                $q = 'SELECT k.*
                                    FROM ' . $serendipity['dbPrefix'] . 'karma   AS k
                                    WHERE k.entryid IN (' . $pid . ') GROUP BY k.entryid';
                                $sql = serendipity_db_query($q);
                                if (is_array($sql)) {
                                    $karma = $sql[0];
                                    $update = sprintf("UPDATE {$serendipity['dbPrefix']}karma\n                                        SET points   = %s,\n                                        votes    = %s\n                                        WHERE entryid  = %s", serendipity_db_escape_string($karma['points'] - $ppoints), serendipity_db_escape_string($karma['votes'] - 1), serendipity_db_escape_string($pid));
                                    $updated = serendipity_db_query($update);
                                    if ($updated != 1) {
                                        printf("<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_REMOVE_ERROR . "</span>\n", $pid);
                                        // Don't delete from karma log if we couldn't take away the points
                                        continue;
                                    }
                                } else {
                                    // This will only happen if someone is messing with the karma table or submit data
                                    printf("<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_UPDATE_ERROR . "</span>", $pid);
                                    continue;
                                }
                            }
                            // Remove vote from log (approved or deleted, doesn't matter)
                            $del = sprintf("DELETE FROM {$serendipity['dbPrefix']}karmalog\n                                WHERE entryid = %s AND ip = '%s' AND user_agent LIKE '%%%s%%' AND votetime = %s LIMIT 1", serendipity_db_escape_string($pid), serendipity_db_escape_string($pip), serendipity_db_escape_string($puser_agent), serendipity_db_escape_string($pvotetime));
                            $deleted = serendipity_db_query($del);
                            // User feedback
                            if ($deleted == 1) {
                                if ($serendipity['POST']['delete_button']) {
                                    printf("<span class='msg_success'><span class='icon-ok-circled'></span> " . PLUGIN_KARMA_REMOVED_POINTS . "</span>\n", $ppoints, $pid);
                                } else {
                                    printf("<span class='msg_success'><span class='icon-ok-circled'></span> " . PLUGIN_KARMA_APPROVED_POINTS . "</span>\n", $ppoints, $pid);
                                }
                            } else {
                                printf("<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_REMOVE_ERROR . "</span>\n", $pid);
                            }
                        }
                    }
                    // URL; expected to be event_display and karmalog, respectively
                    $url = '?serendipity[adminModule]=' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['adminModule']) : htmlspecialchars($serendipity['GET']['adminModule'], ENT_COMPAT, LANG_CHARSET)) . '&serendipity[adminAction]=' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['adminAction']) : htmlspecialchars($serendipity['GET']['adminAction'], ENT_COMPAT, LANG_CHARSET));
                    // Filters
                    print "\n<h2>" . PLUGIN_KARMA_DISPLAY_LOG . "</h2>\n<form id='karmafilters' name='karmafilters' action='' method='get'>\n    <input name='serendipity[adminModule]' type='hidden' value='{$serendipity['GET']['adminModule']}'>\n    <input name='serendipity[adminAction]' type='hidden' value='{$serendipity['GET']['adminAction']}'>\n\n    <ul class='filters_toolbar clearfix plainList'>\n        <li><a class='button_link' href='#serendipity_admin_filters' title='" . FILTERS . "'><span class='icon-filter'></span><span class='visuallyhidden'> " . FILTERS . "</span></a></li>\n        <li><a class='button_link' href='#serendipity_admin_sort' title='" . SORT_ORDER . "'><span class='icon-sort'></span><span class='visuallyhidden'> " . SORT_ORDER . "</span></a></li>\n    </ul>\n\n    <fieldset id='serendipity_admin_filters' class='additional_info filter_pane'>\n        <legend><span class='visuallyhidden'>" . FILTERS . "</span></legend>\n\n        <div class='clearfix'>\n            <div class='form_field'>\n                <label for='serendipity_filter_useragent'>User Agent</label>\n                <input id='serendipity_filter_useragent' name='serendipity[filter][user_agent]' type='text' value='" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['filter']['user_agent']) : htmlspecialchars($serendipity['GET']['filter']['user_agent'], ENT_COMPAT, LANG_CHARSET)) . "'>\n            </div>\n\n            <div class='form_field'>\n                <label for='serendipity_filter_ip'>" . IP . "</label>\n                <input id='serendipity_filter_ip' name='serendipity[filter][ip]' type='text' value='" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['filter']['ip']) : htmlspecialchars($serendipity['GET']['filter']['ip'], ENT_COMPAT, LANG_CHARSET)) . "'>\n            </div>\n\n            <div class='form_field'>\n                <label for='serendipity_filter_entryid'>Entry ID</label>\n                <input id='serendipity_filter_entryid' name='serendipity[filter][entryid]' type='text' value='" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['filter']['entryid']) : htmlspecialchars($serendipity['GET']['filter']['entryid'], ENT_COMPAT, LANG_CHARSET)) . "'>\n            </div>\n\n            <div class='form_field'>\n                <label for='serendipity_filter_title'>Entry title</label>\n                <input id='serendipity_filter_title' name='serendipity[filter][title]' type='text' value='" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['filter']['title']) : htmlspecialchars($serendipity['GET']['filter']['title'], ENT_COMPAT, LANG_CHARSET)) . "'>\n            </div>\n        </div>\n\n        <div class='form_buttons'>\n            <input name='submit' type='submit' value='" . GO . "'>\n        </div>\n    </fieldset>\n";
                    // Set all filters into $and and $searchString
                    if (!empty($serendipity['GET']['filter']['entryid'])) {
                        $val = $serendipity['GET']['filter']['entryid'];
                        $and .= "AND l.entryid = '" . serendipity_db_escape_string($val) . "'";
                        $searchString .= "&amp;serendipity['filter']['entryid']=" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($val) : htmlspecialchars($val, ENT_COMPAT, LANG_CHARSET));
                    }
                    if (!empty($serendipity['GET']['filter']['ip'])) {
                        $val = $serendipity['GET']['filter']['ip'];
                        $and .= "AND l.ip = '" . serendipity_db_escape_string($val) . "'";
                        $searchString .= "&amp;serendipity['filter']['ip']=" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($val) : htmlspecialchars($val, ENT_COMPAT, LANG_CHARSET));
                    }
                    if (!empty($serendipity['GET']['filter']['user_agent'])) {
                        $val = $serendipity['GET']['filter']['user_agent'];
                        $and .= "AND l.user_agent LIKE '%" . serendipity_db_escape_string($val) . "%'";
                        $searchString .= "&amp;serendipity['filter']['user_agent']=" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($val) : htmlspecialchars($val, ENT_COMPAT, LANG_CHARSET));
                    }
                    if (!empty($serendipity['GET']['filter']['title'])) {
                        $val = $serendipity['GET']['filter']['title'];
                        $and .= "AND e.title LIKE '%" . serendipity_db_escape_string($val) . "%'";
                        $searchString .= "&amp;serendipity['filter']['title']=" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($val) : htmlspecialchars($val, ENT_COMPAT, LANG_CHARSET));
                    }
                    // Sorting (controls go after filtering controls in form above)
                    $sort_order = array('votetime' => DATE, 'user_agent' => USER_AGENT, 'title' => TITLE, 'entryid' => 'ID');
                    if (empty($serendipity['GET']['sort']['ordermode']) || $serendipity['GET']['sort']['ordermode'] != 'ASC') {
                        $desc = true;
                        $serendipity['GET']['sort']['ordermode'] = 'DESC';
                    }
                    if (!empty($serendipity['GET']['sort']['order']) && !empty($sort_order[$serendipity['GET']['sort']['order']])) {
                        $curr_order = $serendipity['GET']['sort']['order'];
                        $orderby = serendipity_db_escape_string($curr_order . ' ' . $serendipity['GET']['sort']['ordermode']);
                    } else {
                        $curr_order = 'votetime';
                        $orderby = 'votetime ' . serendipity_db_escape_string($serendipity['GET']['sort']['ordermode']);
                    }
                    print "\n    <fieldset id='serendipity_admin_sort' class='additional_info filter_pane'>\n        <legend><span class='visuallyhidden'>" . SORT_ORDER . "</span></legend>\n\n        <div class='clearfix'>\n            <div class='form_select'>\n                <label for='serendipity_sort_order'>" . SORT_BY . "</label>\n                <select id='serendipity_sort_order' name='serendipity[sort][order]'>\n";
                    foreach ($sort_order as $order => $val) {
                        print "\n  <option value='{$order}'" . ($curr_order == $order ? " selected='selected'" : '') . ">{$val}</option>\n";
                    }
                    print "\n                </select>\n            </div>\n            <div class='form_select'>\n                <label for='serendipity_sort_ordermode'>" . SORT_ORDER . "</label>\n                <select id='serendipity_sort_ordermode' name='serendipity[sort][ordermode]'>\n                    <option value='DESC'" . ($desc ? " selected='selected'" : '') . ">" . SORT_ORDER_DESC . "</option>\n                    <option value='ASC'" . ($desc ? '' : " selected='selected'") . ">" . SORT_ORDER_ASC . "</option>\n                </select>\n            </div>\n        </div>\n\n        <div class='form_buttons'>\n            <input name='submit' type='submit' value='" . GO . "'>\n        </div>\n    </fieldset>\n</form>\n";
                    // Paging (partly ripped from include/admin/comments.inc.php)
                    $commentsPerPage = (int) (!empty($serendipity['GET']['filter']['perpage']) ? $serendipity['GET']['filter']['perpage'] : 25);
                    $sql = serendipity_db_query("SELECT COUNT(*) AS total FROM {$serendipity['dbPrefix']}karmalog l WHERE 1 = 1 " . $and, true);
                    if (is_string($sql)) {
                        print "<span class='msg_error'><span class='icon-attention-circled'></span> " . $sql . "</span>\n";
                    }
                    $totalVotes = is_array($sql) && is_int($sql['total']) ? $sql['total'] : 0;
                    $pages = $commentsPerPage == COMMENTS_FILTER_ALL ? 1 : ceil($totalVotes / (int) $commentsPerPage);
                    $page = (int) $serendipity['GET']['page'];
                    if ($page == 0 || $page > $pages) {
                        $page = 1;
                    }
                    if ($page > 1) {
                        $linkPrevious = $url . '&amp;serendipity[page]=' . ($page - 1) . $searchString;
                    }
                    if ($pages > $page) {
                        $linkNext = $url . '&amp;serendipity[page]=' . ($page + 1) . $searchString;
                    }
                    if ($commentsPerPage == COMMENTS_FILTER_ALL) {
                        $limit = '';
                    } else {
                        $limit = serendipity_db_limit_sql(serendipity_db_limit(($page - 1) * (int) $commentsPerPage, (int) $commentsPerPage));
                    }
                    // Variables for display
                    if ($linkPrevious) {
                        $linkPrevious = '<a class="button_link" href="' . $linkPrevious . '" title="' . PREVIOUS . '"><span class="icon-left-dir"></span><span class="visuallyhidden"> ' . PREVIOUS . '</span></a>';
                    } else {
                        $linkPrevious = '<span class="visuallyhidden">' . NO_ENTRIES_TO_PRINT . '</span>';
                    }
                    if ($linkNext) {
                        $linkNext = '<a class="button_link" href="' . $linkNext . '" title="' . NEXT . '"><span class="visuallyhidden">' . NEXT . ' </span><span class="icon-right-dir"></span></a>';
                    } else {
                        $linkNext = '<span class="visuallyhidden">' . NO_ENTRIES_TO_PRINT . '</span>';
                    }
                    $paging = sprintf(PAGE_BROWSE_COMMENTS, $page, $pages, $totalVotes);
                    // Retrieve the next batch of karma votes
                    // [entryid, points, ip, user_agent, votetime]
                    $sql = serendipity_db_query("SELECT l.entryid AS entryid, l.points AS points, l.ip AS ip, l.user_agent AS user_agent, l.votetime AS votetime, e.title AS title FROM {$serendipity['dbPrefix']}karmalog l\n                        LEFT JOIN {$serendipity['dbPrefix']}entries e ON (e.id = l.entryid)\n                        WHERE 1 = 1 " . $and . "\n                        ORDER BY {$orderby} {$limit}");
                    // Start the form for display and deleting
                    if (is_array($sql)) {
                        print "<form action='' method='post' name='formMultiDelete' id='formMultiDelete'>\n" . serendipity_setFormToken();
                        // Start the vote table
                        print "\n<div class='clearfix karma_pane'>\n<ul id='karmalog' class='clearfix karmalog plainList zebra_list'>\n";
                        // Print each vote
                        $i = 0;
                        foreach ($sql as $vote) {
                            $i++;
                            // entryid, title, points, ip, user_agent, votetime
                            if (strlen($vote['title']) > 40) {
                                $votetitle = substr($vote['title'], 0, 40) . '&hellip;';
                            } else {
                                $votetitle = $vote['title'];
                            }
                            $entrylink = serendipity_archiveURL($vote['entryid'], $vote['title'], 'serendipityHTTPPath', true);
                            $entryFilterHtml = "<a class='button_link filter_karma' href='{$url}&serendipity[filter][entryid]={$vote['entryid']}' title='" . FILTERS . "'><span class='icon-filter'></span><span class='visuallyhidden'>" . FILTERS . "</span></a>";
                            $ipFilterHtml = "<a class='button_link filter_karma' href='{$url}&serendipity[filter][ip]={$vote['ip']}' title='" . FILTERS . "'><span class='icon-filter'></span><span class='visuallyhidden'>" . FILTERS . "</span></a>";
                            $timestr = strftime('%a %b %d %Y, %H:%M:%S', $vote['votetime']);
                            $cssClass = $i % 2 == 0 ? 'even' : 'odd';
                            $barClass = str_replace(array('.', ' '), array('_', '_'), $this->image_name);
                            $barHtml = $this->createRatingBar(null, $vote['points'], 1, $barClass);
                            $barHtml = sprintf($barHtml, 'what', $vote['points'], '1');
                            print "\n    <li id='karma_{$i}' class='{$cssClass} clearfix'>\n        <input type='hidden' name='serendipity[karmalog{$i}][points]' value='{$vote['points']}'>\n        <input type='hidden' name='serendipity[karmalog{$i}][entryid]' value='{$vote['entryid']}'>\n        <input type='hidden' name='serendipity[karmalog{$i}][votetime]' value='{$vote['votetime']}'>\n        <input type='hidden' name='serendipity[karmalog{$i}][ip]' value='{$vote['ip']}'>\n        <input type='hidden' name='serendipity[karmalog{$i}][user_agent]' value='{$vote['user_agent']}'>\n\n        <div class='form_check'>\n            <input id='multidelete_karma_{$i}' class='multidelete' type='checkbox' name='serendipity[delete][{$i}]' value='{$i}' data-multidelid='karma_{$i}'>\n            <label for='multidelete_karma_{$i}' class='visuallyhidden'>" . TOGGLE_SELECT . "</label>\n        </div>\n\n        <h4><a href='{$entrylink}' title='ID: {$vote['entryid']}'>{$votetitle}</a>\n            <button class='toggle_info button_link' type='button' data-href='#karma_data_{$i}'><span class='icon-info-circled'></span><span class='visuallyhidden'> " . MORE . "</span></button>\n            {$entryFilterHtml}\n        </h4>\n\n        {$barHtml}\n\n        <div id='karma_data_{$i}' class='additional_info'>\n            <dl class='clearfix comment_data'>\n                <dt>" . ON . "</dt>\n                <dd>{$timestr}</dd>\n                <dt>IP</dt>\n                <dd>{$vote['ip']} {$ipFilterHtml}</dd>\n                <dt><abbr title='User-Agent' lang='en'>UA</abbr></dt>\n                <dd>{$vote['user_agent']}</dd>\n            </dl>\n        </div>\n    </li>\n";
                        }
                        // End the vote table
                        print "\n                            </ul>\n                            ";
                        // Print the footer paging table
                        print "\n<nav class='pagination'>\n    <h3>{$paging}</h3>\n    <ul class='clearfix'>\n        <li class='prev'>{$linkPrevious}</li>\n        <li class='next'>{$linkNext}</li>\n    </ul>\n</nav>\n</div>\n";
                        if (is_array($sql)) {
                            print "\n<div class='form_buttons'>\n<input class='invert_selection' name='toggle' type='button' value='" . INVERT_SELECTIONS . "'> \n<input class='state_cancel' name='serendipity[delete_button]' type='submit' title='" . PLUGIN_KARMA_DELETE_VOTES . "' value='" . DELETE . "'>\n</div>\n</form>\n";
                        }
                    } else {
                        print "\n<span class='msg_notice'><span class='icon-info-circled'></span> No logs to display. You need to enable karma logging, if you want to see single votes displayed here.</span>\n";
                    }
                    return true;
                    break;
                default:
                    return false;
            }
            // End switch on event hooks
        } else {
            return false;
        }
    }
 function event_hook($event, &$bag, &$eventData, $addData = null)
 {
     global $serendipity;
     $debug = true;
     $hooks =& $bag->get('event_hooks');
     if (isset($hooks[$event])) {
         $captchas_ttl = $this->get_config('captchas_ttl', 7);
         $_captchas = $this->get_config('captchas', 'yes');
         $captchas = $_captchas !== 'no' && ($_captchas === 'yes' || $_captchas === 'scramble' || serendipity_db_bool($_captchas));
         // Check if the entry is older than the allowed amount of time. Enforce kaptchas if that is true
         // of if kaptchas are activated for every entry
         $show_captcha = $captchas && isset($eventData['timestamp']) && ($captchas_ttl < 1 || $eventData['timestamp'] < time() - $captchas_ttl * 60 * 60 * 24) ? true : false;
         // Plugins can override with custom captchas
         if (isset($serendipity['plugins']['disable_internal_captcha'])) {
             $show_captcha = false;
         }
         $forcemoderation = $this->get_config('forcemoderation', 60);
         $forcemoderation_treat = $this->get_config('forcemoderation_treat', 'moderate');
         $forcemoderationt = $this->get_config('forcemoderationt', 60);
         $forcemoderationt_treat = $this->get_config('forcemoderationt_treat', 'moderate');
         $links_moderate = $this->get_config('links_moderate', 10);
         $links_reject = $this->get_config('links_reject', 20);
         if (function_exists('imagettftext') && function_exists('imagejpeg')) {
             $max_char = 5;
             $min_char = 3;
             $use_gd = true;
         } else {
             $max_char = $min_char = 5;
             $use_gd = false;
         }
         switch ($event) {
             case 'fetchcomments':
                 if (is_array($eventData) && !$_SESSION['serendipityAuthedUser'] && serendipity_db_bool($this->get_config('hide_email', false))) {
                     // Will force emails to be not displayed in comments and RSS feed for comments. Will not apply to logged in admins (so not in the backend as well)
                     @reset($eventData);
                     while (list($idx, $comment) = each($eventData)) {
                         $eventData[$idx]['no_email'] = true;
                     }
                 }
                 break;
             case 'frontend_saveComment':
                 /*
                     $fp = fopen('/tmp/spamblock2.log', 'a');
                     fwrite($fp, date('Y-m-d H:i') . "\n" . print_r($eventData, true) . "\n" . print_r($addData, true) . "\n");
                     fclose($fp);
                 */
                 if (!is_array($eventData) || serendipity_db_bool($eventData['allow_comments'])) {
                     $this->checkScheme();
                     $serendipity['csuccess'] = 'true';
                     $logfile = $this->logfile = $this->get_config('logfile', $serendipity['serendipityPath'] . 'spamblock.log');
                     $required_fields = $this->get_config('required_fields', '');
                     $checkmail = $this->get_config('checkmail');
                     // Check CSRF [comments only, cannot be applied to trackbacks]
                     if ($addData['type'] == 'NORMAL' && serendipity_db_bool($this->get_config('csrf', true))) {
                         if (!serendipity_checkFormToken(false)) {
                             $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_CSRF_REASON, $addData);
                             $eventData = array('allow_comments' => false);
                             $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_CSRF_REASON;
                         }
                     }
                     // Check required fields
                     if ($addData['type'] == 'NORMAL' && !empty($required_fields)) {
                         $required_field_list = explode(',', $required_fields);
                         foreach ($required_field_list as $required_field) {
                             $required_field = trim($required_field);
                             if (empty($addData[$required_field])) {
                                 $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_REQUIRED_FIELD, $addData);
                                 $eventData = array('allow_comments' => false);
                                 $serendipity['messagestack']['comments'][] = sprintf(PLUGIN_EVENT_SPAMBLOCK_REASON_REQUIRED_FIELD, $required_field);
                                 return false;
                             }
                         }
                     }
                     /*
                     if ($addData['type'] != 'NORMAL' && empty($addData['name'])) {
                         $eventData = array('allow_coments' => false);
                         $this->log($logfile, $eventData['id'], 'INVALIDGARV', 'INVALIDGARV', $addData);
                         return false;
                     }
                     */
                     // Check whether to allow comments from registered authors
                     if (serendipity_userLoggedIn() && $this->inGroup()) {
                         return true;
                     }
                     // Check if the user has verified himself via email already.
                     if ($addData['type'] == 'NORMAL' && (string) $checkmail === 'verify_once') {
                         $auth = serendipity_db_query("SELECT *\n                                                            FROM {$serendipity['dbPrefix']}options\n                                                           WHERE okey  = 'mail_confirm'\n                                                             AND name  = '" . serendipity_db_escape_string($addData['email']) . "'\n                                                             AND value = '" . serendipity_db_escape_string($addData['name']) . "'", true);
                         if (!is_array($auth)) {
                             // Filter authors names, Filter URL, Filter Content, Filter Emails, Check for maximum number of links before rejecting
                             // moderate false
                             if (false === $this->wordfilter($logfile, $eventData, $wordmatch, $addData, true)) {
                                 // already there #$this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_FILTER_WORDS, $addData);
                                 // already there #$eventData = array('allow_comments' => false);
                                 // already there #$serendipity['messagestack']['emails'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
                                 return false;
                             } elseif (serendipity_db_bool($this->get_config('killswitch', false)) === true) {
                                 $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_KILLSWITCH, $addData);
                                 $eventData = array('allow_comments' => false);
                                 $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_KILLSWITCH;
                                 return false;
                             } else {
                                 $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_CHECKMAIL_VERIFICATION_MAIL, $addData);
                                 $eventData['moderate_comments'] = true;
                                 $eventData['status'] = 'confirm1';
                                 $serendipity['csuccess'] = 'moderate';
                                 $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_CHECKMAIL_VERIFICATION_MAIL;
                                 return false;
                             }
                         } else {
                             // User is allowed to post message, bypassing other checks as if he were logged in.
                             return true;
                         }
                     }
                     // Check if entry title is the same as comment body
                     if (serendipity_db_bool($this->get_config('entrytitle')) && trim($eventData['title']) == trim($addData['comment'])) {
                         $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_TITLE, $addData);
                         $eventData = array('allow_comments' => false);
                         $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
                         return false;
                     }
                     // Check for global emergency moderation
                     if (serendipity_db_bool($this->get_config('killswitch', false)) === true) {
                         $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_KILLSWITCH, $addData);
                         $eventData = array('allow_comments' => false);
                         $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_KILLSWITCH;
                         return false;
                     }
                     // Check for not allowing trackbacks/pingbacks/wfwcomments
                     if (($addData['type'] != 'NORMAL' || $addData['source'] == 'API') && $this->get_config('disable_api_comments', 'none') != 'none') {
                         if ($this->get_config('disable_api_comments') == 'reject') {
                             $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_API, $addData);
                             $eventData = array('allow_comments' => false);
                             $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_REASON_API;
                             return false;
                         } elseif ($this->get_config('disable_api_comments') == 'moderate') {
                             $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_REASON_API, $addData);
                             $eventData['moderate_comments'] = true;
                             $serendipity['csuccess'] = 'moderate';
                             $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_REASON_API;
                         }
                     }
                     // Check if sender ip is matching trackback/pingback ip (ip validation)
                     $trackback_ipvalidation_option = $this->get_config('trackback_ipvalidation', 'moderate');
                     if (($addData['type'] == 'TRACKBACK' || $addData['type'] == 'PINGBACK') && $trackback_ipvalidation_option != 'no') {
                         $this->IsHardcoreSpammer();
                         $exclude_urls = explode(';', $this->get_config('trackback_ipvalidation_url_exclude', $this->get_default_exclude_urls()));
                         $found_exclude_url = false;
                         foreach ($exclude_urls as $exclude_url) {
                             $exclude_url = trim($exclude_url);
                             if (empty($exclude_url)) {
                                 continue;
                             }
                             $found_exclude_url = preg_match('@' . $exclude_url . '@', $addData['url']);
                             if ($found_exclude_url) {
                                 break;
                             }
                         }
                         if (!$found_exclude_url) {
                             $parts = @parse_url($addData['url']);
                             $tipval_method = $trackback_ipvalidation_option == 'reject' ? 'REJECTED' : 'MODERATE';
                             // Getting host from url successfully?
                             if (!is_array($parts)) {
                                 // not a valid URL
                                 $this->log($logfile, $eventData['id'], $tipval_method, sprintf(PLUGIN_EVENT_SPAMBLOCK_REASON_IPVALIDATION, $addData['url'], '', ''), $addData);
                                 if ($trackback_ipvalidation_option == 'reject') {
                                     $eventData = array('allow_comments' => false);
                                     $serendipity['messagestack']['comments'][] = sprintf(PLUGIN_EVENT_SPAMBLOCK_REASON_IPVALIDATION, $addData['url']);
                                     return false;
                                 } else {
                                     $eventData['moderate_comments'] = true;
                                     $serendipity['csuccess'] = 'moderate';
                                     $serendipity['moderate_reason'] = sprintf(PLUGIN_EVENT_SPAMBLOCK_REASON_IPVALIDATION, $addData['url']);
                                 }
                             }
                             $trackback_ip = preg_replace('/[^0-9.]/', '', gethostbyname($parts['host']));
                             $sender_ip = preg_replace('/[^0-9.]/', '', $_SERVER['REMOTE_ADDR']);
                             $sender_ua = $debug ? ', ua="' . $_SERVER['HTTP_USER_AGENT'] . '"' : '';
                             // Is host ip and sender ip matching?
                             if ($trackback_ip != $sender_ip) {
                                 $this->log($logfile, $eventData['id'], $tipval_method, sprintf(PLUGIN_EVENT_SPAMBLOCK_REASON_IPVALIDATION, $parts['host'], $trackback_ip, $sender_ip . $sender_ua), $addData);
                                 if ($trackback_ipvalidation_option == 'reject') {
                                     $eventData = array('allow_comments' => false);
                                     $serendipity['messagestack']['comments'][] = sprintf(PLUGIN_EVENT_SPAMBLOCK_REASON_IPVALIDATION, $parts['host'], $trackback_ip, $sender_ip . $sender_ua);
                                     return false;
                                 } else {
                                     $eventData['moderate_comments'] = true;
                                     $serendipity['csuccess'] = 'moderate';
                                     $serendipity['moderate_reason'] = sprintf(PLUGIN_EVENT_SPAMBLOCK_REASON_IPVALIDATION, $parts['host'], $trackback_ip, $sender_ip . $sender_ua);
                                 }
                             }
                         }
                     }
                     // Filter Akismet Blacklist?
                     $akismet_apikey = $this->get_config('akismet');
                     $akismet = $this->get_config('akismet_filter');
                     if (!empty($akismet_apikey) && ($akismet == 'moderate' || $akismet == 'reject') && !isset($addData['skip_akismet'])) {
                         $spam = $this->getBlacklist('akismet.com', $akismet_apikey, $eventData, $addData);
                         if ($spam['is_spam'] !== false) {
                             $this->IsHardcoreSpammer();
                             if ($akismet == 'moderate') {
                                 $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_REASON_AKISMET_SPAMLIST . ': ' . $spam['message'], $addData);
                                 $eventData['moderate_comments'] = true;
                                 $serendipity['csuccess'] = 'moderate';
                                 $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY . ' (Akismet)';
                             } else {
                                 $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_AKISMET_SPAMLIST . ': ' . $spam['message'], $addData);
                                 $eventData = array('allow_comments' => false);
                                 $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
                                 return false;
                             }
                         }
                     }
                     // Check Trackback URLs?
                     if (($addData['type'] == 'TRACKBACK' || $addData['type'] == 'PINGBACK') && serendipity_db_bool($this->get_config('trackback_check_url'))) {
                         require_once S9Y_PEAR_PATH . 'HTTP/Request.php';
                         if (function_exists('serendipity_request_start')) {
                             serendipity_request_start();
                         }
                         $req = new HTTP_Request($addData['url'], array('allowRedirects' => true, 'maxRedirects' => 5, 'readTimeout' => array(5, 0)));
                         $is_valid = false;
                         if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
                             $is_valid = false;
                         } else {
                             $fdata = $req->getResponseBody();
                             // Check if the target page contains a link to our blog
                             if (preg_match('@' . preg_quote($serendipity['baseURL'], '@') . '@i', $fdata)) {
                                 $is_valid = true;
                             } else {
                                 $is_valid = false;
                             }
                         }
                         if (function_exists('serendipity_request_end')) {
                             serendipity_request_end();
                         }
                         if ($is_valid === false) {
                             $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_TRACKBACKURL, $addData);
                             $eventData = array('allow_comments' => false);
                             $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_REASON_TRACKBACKURL;
                             return false;
                         }
                     }
                     if (false === $this->wordfilter($logfile, $eventData, $wordmatch, $addData)) {
                         return false;
                     }
                     // Check for maximum number of links before rejecting
                     $link_count = substr_count(strtolower($addData['comment']), 'http://');
                     if ($links_reject > 0 && $link_count > $links_reject) {
                         $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_LINKS_REJECT, $addData);
                         $eventData = array('allow_comments' => false);
                         $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
                         return false;
                     }
                     // Captcha checking
                     if ($show_captcha && $addData['type'] == 'NORMAL') {
                         if (!isset($_SESSION['spamblock']['captcha']) || !isset($serendipity['POST']['captcha']) || strtolower($serendipity['POST']['captcha']) != strtolower($_SESSION['spamblock']['captcha'])) {
                             $this->log($logfile, $eventData['id'], 'REJECTED', sprintf(PLUGIN_EVENT_SPAMBLOCK_REASON_CAPTCHAS, $serendipity['POST']['captcha'], $_SESSION['spamblock']['captcha']), $addData);
                             $eventData = array('allow_comments' => false);
                             $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_CAPTCHAS;
                             return false;
                         } else {
                             // DEBUG
                             //                                $this->log($logfile, $eventData['id'], 'REJECTED', 'Captcha passed: ' . $serendipity['POST']['captcha'] . ' / ' . $_SESSION['spamblock']['captcha'] . ' // Source: ' . $_SERVER['REQUEST_URI'], $addData);
                         }
                     } else {
                         // DEBUG
                         //                            $this->log($logfile, $eventData['id'], 'REJECTED', 'Captcha not needed: ' . $serendipity['POST']['captcha'] . ' / ' . $_SESSION['spamblock']['captcha'] . ' // Source: ' . $_SERVER['REQUEST_URI'], $addData);
                     }
                     // Check for forced comment moderation (X days)
                     if ($addData['type'] == 'NORMAL' && $forcemoderation > 0 && $eventData['timestamp'] < time() - $forcemoderation * 60 * 60 * 24) {
                         $this->log($logfile, $eventData['id'], $forcemoderation_treat, PLUGIN_EVENT_SPAMBLOCK_REASON_FORCEMODERATION, $addData);
                         if ($forcemoderation_treat == 'reject') {
                             $eventData = array('allow_comments' => false);
                             $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_REASON_FORCEMODERATION;
                             return false;
                         } else {
                             $eventData['moderate_comments'] = true;
                             $serendipity['csuccess'] = 'moderate';
                             $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_REASON_FORCEMODERATION;
                         }
                     }
                     // Check for forced trackback moderation
                     if ($addData['type'] != 'NORMAL' && $forcemoderationt > 0 && $eventData['timestamp'] < time() - $forcemoderationt * 60 * 60 * 24) {
                         $this->log($logfile, $eventData['id'], $forcemoderationt_treat, PLUGIN_EVENT_SPAMBLOCK_REASON_FORCEMODERATION, $addData);
                         if ($forcemoderationt_treat == 'reject') {
                             $eventData = array('allow_comments' => false);
                             $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_REASON_FORCEMODERATION;
                             return false;
                         } else {
                             $eventData['moderate_comments'] = true;
                             $serendipity['csuccess'] = 'moderate';
                             $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_REASON_FORCEMODERATION;
                         }
                     }
                     // Check for maximum number of links before forcing moderation
                     if ($links_moderate > 0 && $link_count > $links_moderate) {
                         $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_LINKS_MODERATE, $addData);
                         $eventData['moderate_comments'] = true;
                         $serendipity['csuccess'] = 'moderate';
                         $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_REASON_LINKS_MODERATE;
                     }
                     // Check for identical comments. We allow to bypass trackbacks from our server to our own blog.
                     if ($this->get_config('bodyclone', true) === true && $_SERVER['REMOTE_ADDR'] != $_SERVER['SERVER_ADDR'] && $addData['type'] != 'PINGBACK') {
                         $query = "SELECT count(id) AS counter FROM {$serendipity['dbPrefix']}comments WHERE type = '" . $addData['type'] . "' AND body = '" . serendipity_db_escape_string($addData['comment']) . "'";
                         $row = serendipity_db_query($query, true);
                         if (is_array($row) && $row['counter'] > 0) {
                             $this->IsHardcoreSpammer();
                             $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_BODYCLONE, $addData);
                             $eventData = array('allow_comments' => false);
                             $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
                             return false;
                         }
                     }
                     // Check last IP
                     if ($addData['type'] == 'NORMAL' && $this->get_config('ipflood', 2) != 0) {
                         $query = "SELECT max(timestamp) AS last_post FROM {$serendipity['dbPrefix']}comments WHERE ip = '" . serendipity_db_escape_string($_SERVER['REMOTE_ADDR']) . "'";
                         $row = serendipity_db_query($query, true);
                         if (is_array($row) && $row['last_post'] > time() - $this->get_config('ipflood', 2) * 60) {
                             $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_IPFLOOD, $addData);
                             $eventData = array('allow_comments' => false);
                             $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_IP;
                             return false;
                         }
                     }
                     if ($addData['type'] == 'NORMAL' && (string) $checkmail === 'verify_always') {
                         $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_CHECKMAIL_VERIFICATION_MAIL, $addData);
                         $eventData['moderate_comments'] = true;
                         $eventData['status'] = 'confirm';
                         $serendipity['csuccess'] = 'moderate';
                         $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_CHECKMAIL_VERIFICATION_MAIL;
                         return false;
                     }
                     // Check invalid email
                     if ($addData['type'] == 'NORMAL' && serendipity_db_bool($this->get_config('checkmail', false))) {
                         if (!empty($addData['email']) && strstr($addData['email'], '@') === false) {
                             $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_CHECKMAIL, $addData);
                             $eventData = array('allow_comments' => false);
                             $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_REASON_CHECKMAIL;
                             return false;
                         }
                     }
                     if ($eventData['moderate_comments'] == true) {
                         return false;
                     }
                 }
                 return true;
                 break;
             case 'frontend_comment':
                 if (serendipity_db_bool($this->get_config('hide_email', false))) {
                     echo '<div class="serendipity_commentDirection serendipity_comment_spamblock">' . PLUGIN_EVENT_SPAMBLOCK_HIDE_EMAIL_NOTICE . '</div>';
                 }
                 if ((string) $this->get_config('checkmail') === 'verify_always' || (string) $this->get_config('checkmail') === 'verify_once') {
                     echo '<div class="serendipity_commentDirection serendipity_comment_spamblock">' . PLUGIN_EVENT_SPAMBLOCK_CHECKMAIL_VERIFICATION_INFO . '</div>';
                 }
                 if (serendipity_db_bool($this->get_config('csrf', true))) {
                     echo serendipity_setFormToken('form');
                 }
                 // Check whether to allow comments from registered authors
                 if (serendipity_userLoggedIn() && $this->inGroup()) {
                     return true;
                 }
                 if ($show_captcha) {
                     echo '<div class="serendipity_commentDirection serendipity_comment_captcha">';
                     if (!isset($serendipity['POST']['preview']) || strtolower($serendipity['POST']['captcha'] != strtolower($_SESSION['spamblock']['captcha']))) {
                         echo '<br />' . PLUGIN_EVENT_SPAMBLOCK_CAPTCHAS_USERDESC . '<br />';
                         echo $this->show_captcha($use_gd);
                         echo '<br />';
                         echo '<label for="captcha">' . PLUGIN_EVENT_SPAMBLOCK_CAPTCHAS_USERDESC3 . '</label><br /><input class="input_textbox" type="text" size="5" name="serendipity[captcha]" value="" id="captcha" />';
                     } elseif (isset($serendipity['POST']['captcha'])) {
                         echo '<input type="hidden" name="serendipity[captcha]" value="' . serendipity_specialchars($serendipity['POST']['captcha']) . '" />';
                     }
                     echo '</div>';
                 }
                 return true;
                 break;
             case 'external_plugin':
                 $parts = explode('_', (string) $eventData);
                 if (!empty($parts[1])) {
                     $param = (int) $parts[1];
                 } else {
                     $param = null;
                 }
                 $methods = array('captcha');
                 if (!in_array($parts[0], $methods)) {
                     return;
                 }
                 list($musec, $msec) = explode(' ', microtime());
                 $srand = (double) $msec + (double) $musec * 100000;
                 srand($srand);
                 mt_srand($srand);
                 $width = 120;
                 $height = 40;
                 $bgcolors = explode(',', $this->get_config('captcha_color', '255,255,255'));
                 $fontfiles = array('Vera.ttf', 'VeraSe.ttf', 'chumbly.ttf', '36daysago.ttf');
                 if ($use_gd) {
                     $strings = $this->random_string($max_char, $min_char);
                     $fontname = $fontfiles[array_rand($fontfiles)];
                     $font = $serendipity['serendipityPath'] . 'plugins/serendipity_event_spamblock/' . $fontname;
                     if (!file_exists($font)) {
                         // Search in shared plugin directory
                         $font = S9Y_INCLUDE_PATH . 'plugins/serendipity_event_spamblock/' . $fontname;
                     }
                     if (!file_exists($font)) {
                         die(PLUGIN_EVENT_SPAMBLOCK_ERROR_NOTTF);
                     }
                     header('Content-Type: image/jpeg');
                     $image = imagecreate($width, $height);
                     // recommended use of imagecreatetruecolor() returns a black backgroundcolor
                     $bgcol = imagecolorallocate($image, trim($bgcolors[0]), trim($bgcolors[1]), trim($bgcolors[2]));
                     // imagettftext($image, 10, 1, 1, 15, imagecolorallocate($image, 255, 255, 255), $font, 'String: ' . $string);
                     $pos_x = 5;
                     foreach ($strings as $idx => $charidx) {
                         $color = imagecolorallocate($image, mt_rand(50, 235), mt_rand(50, 235), mt_rand(50, 235));
                         $size = mt_rand(15, 21);
                         $angle = mt_rand(-20, 20);
                         $pos_y = ceil($height - mt_rand($size / 3, $size / 2));
                         imagettftext($image, $size, $angle, $pos_x, $pos_y, $color, $font, $this->chars[$charidx]);
                         $pos_x = $pos_x + $size + 2;
                     }
                     if ($_captchas === 'scramble') {
                         $line_diff = mt_rand(5, 15);
                         $pixel_col = imagecolorallocate($image, trim($bgcolors[0]) - mt_rand(10, 50), trim($bgcolors[1]) - mt_rand(10, 50), trim($bgcolors[2]) - mt_rand(10, 50));
                         for ($y = $line_diff; $y < $height; $y += $line_diff) {
                             $row_diff = mt_rand(5, 15);
                             for ($x = $row_diff; $x < $width; $x += $row_diff) {
                                 imagerectangle($image, $x, $y, $x + 1, $y + 1, $pixel_col);
                             }
                         }
                     }
                     imagejpeg($image, NULL, 90);
                     // NULL fixes https://bugs.php.net/bug.php?id=63920
                     imagedestroy($image);
                 } else {
                     header('Content-Type: image/png');
                     $output_char = strtolower($_SESSION['spamblock']['captcha'][$parts[1] - 1]);
                     $cap = $serendipity['serendipityPath'] . 'plugins/serendipity_event_spamblock/captcha_' . $output_char . '.png';
                     if (!file_exists($cap)) {
                         $cap = S9Y_INCLUDE_PATH . 'plugins/serendipity_event_spamblock/captcha_' . $output_char . '.png';
                     }
                     if (file_exists($cap)) {
                         echo file_get_contents($cap);
                     }
                 }
                 return true;
                 break;
             case 'backend_comments_top':
                 // Tell Akismet about spam or not spam
                 $tell_id = null;
                 if (isset($serendipity['GET']['spamIsSpam'])) {
                     $tell_spam = true;
                     $tell_id = $serendipity['GET']['spamIsSpam'];
                 }
                 if (isset($serendipity['GET']['spamNotSpam'])) {
                     $tell_spam = false;
                     $tell_id = $serendipity['GET']['spamNotSpam'];
                 }
                 if ($tell_id !== null) {
                     $akismet_apikey = $this->get_config('akismet');
                     $akismet = $this->get_config('akismet_filter');
                     if (!empty($akismet_apikey)) {
                         $this->tellAboutComment('akismet.com', $akismet_apikey, $tell_id, $tell_spam);
                     }
                 }
                 // Add Author to blacklist. If already filtered, it will be removed from the filter. (AKA "Toggle")
                 if (isset($serendipity['GET']['spamBlockAuthor'])) {
                     $item = $this->getComment('author', $serendipity['GET']['spamBlockAuthor']);
                     $items =& $this->checkFilter('authors', $item, true);
                     $this->set_config('contentfilter_authors', implode(';', $items));
                 }
                 // Add URL to blacklist. If already filtered, it will be removed from the filter. (AKA "Toggle")
                 if (isset($serendipity['GET']['spamBlockURL'])) {
                     $item = $this->getComment('url', $serendipity['GET']['spamBlockURL']);
                     $items =& $this->checkFilter('urls', $item, true);
                     $this->set_config('contentfilter_urls', implode(';', $items));
                 }
                 // Add E-mail to blacklist. If already filtered, it will be removed from the filter. (AKA "Toggle")
                 if (isset($serendipity['GET']['spamBlockEmail'])) {
                     $item = $this->getComment('email', $serendipity['GET']['spamBlockEmail']);
                     $items =& $this->checkFilter('emails', $item, true);
                     $this->set_config('contentfilter_emails', implode(';', $items));
                 }
                 echo '<a class="button_link" title="' . PLUGIN_EVENT_SPAMBLOCK_CONFIG . '" href="serendipity_admin.php?serendipity[adminModule]=plugins&amp;serendipity[plugin_to_conf]=' . $this->instance . '"><span class="icon-medkit"></span><span class="visuallyhidden"> ' . PLUGIN_EVENT_SPAMBLOCK_CONFIG . '</span></a>';
                 return true;
                 break;
             case 'backend_view_comment':
                 $author_is_filtered = $this->checkFilter('authors', $eventData['author']);
                 $clink = 'comment_' . $eventData['id'];
                 $randomString = '&amp;random=' . substr(sha1(rand()), 0, 10);
                 # the random string will force browser to reload the page,
                 # so the server knows who to block/unblock when clicking again on the same link,
                 # see http://stackoverflow.com/a/2573986/2508518, http://stackoverflow.com/a/14043346/2508518
                 $akismet_apikey = $this->get_config('akismet');
                 $akismet = $this->get_config('akismet_filter');
                 if (!empty($akismet_apikey)) {
                     $eventData['action_more'] .= ' <a class="button_link actions_extra" title="' . PLUGIN_EVENT_SPAMBLOCK_SPAM . '" href="serendipity_admin.php?serendipity[adminModule]=comments&amp;serendipity[spamIsSpam]=' . $eventData['id'] . $addData . '#' . $clink . '"><span class="icon-block"></span><span class="visuallyhidden"> ' . PLUGIN_EVENT_SPAMBLOCK_SPAM . '</span></a>';
                     $eventData['action_more'] .= ' <a class="button_link actions_extra" title="' . PLUGIN_EVENT_SPAMBLOCK_NOT_SPAM . '" href="serendipity_admin.php?serendipity[adminModule]=comments&amp;serendipity[spamNotSpam]=' . $eventData['id'] . $addData . '#' . $clink . '"><span class="icon-ok-circled"></span><span class="visuallyhidden"> ' . PLUGIN_EVENT_SPAMBLOCK_NOT_SPAM . '</span></a>';
                 }
                 $eventData['action_author'] .= ' <a class="button_link" title="' . ($author_is_filtered ? PLUGIN_EVENT_SPAMBLOCK_REMOVE_AUTHOR : PLUGIN_EVENT_SPAMBLOCK_ADD_AUTHOR) . '" href="serendipity_admin.php?serendipity[adminModule]=comments&amp;serendipity[spamBlockAuthor]=' . $eventData['id'] . $addData . $randomString . '#' . $clink . '"><span class="icon-' . ($author_is_filtered ? 'ok-circled' : 'block') . '"></span><span class="visuallyhidden"> ' . ($author_is_filtered ? PLUGIN_EVENT_SPAMBLOCK_REMOVE_AUTHOR : PLUGIN_EVENT_SPAMBLOCK_ADD_AUTHOR) . '</span></a>';
                 if (!empty($eventData['url'])) {
                     $url_is_filtered = $this->checkFilter('urls', $eventData['url']);
                     $eventData['action_url'] .= ' <a class="button_link" title="' . ($url_is_filtered ? PLUGIN_EVENT_SPAMBLOCK_REMOVE_URL : PLUGIN_EVENT_SPAMBLOCK_ADD_URL) . '" href="serendipity_admin.php?serendipity[adminModule]=comments&amp;serendipity[spamBlockURL]=' . $eventData['id'] . $addData . $randomString . '#' . $clink . '"><span class="icon-' . ($url_is_filtered ? 'ok-circled' : 'block') . '"></span><span class="visuallyhidden"> ' . ($url_is_filtered ? PLUGIN_EVENT_SPAMBLOCK_REMOVE_URL : PLUGIN_EVENT_SPAMBLOCK_ADD_URL) . '</span></a>';
                 }
                 if (!empty($eventData['email'])) {
                     $email_is_filtered = $this->checkFilter('emails', $eventData['email']);
                     $eventData['action_email'] .= ' <a class="button_link" title="' . ($email_is_filtered ? PLUGIN_EVENT_SPAMBLOCK_REMOVE_EMAIL : PLUGIN_EVENT_SPAMBLOCK_ADD_EMAIL) . '" href="serendipity_admin.php?serendipity[adminModule]=comments&amp;serendipity[spamBlockEmail]=' . $eventData['id'] . $addData . $randomString . '#' . $clink . '"><span class="icon-' . ($email_is_filtered ? 'ok-circled' : 'block') . '"></span><span class="visuallyhidden"> ' . ($email_is_filtered ? PLUGIN_EVENT_SPAMBLOCK_REMOVE_EMAIL : PLUGIN_EVENT_SPAMBLOCK_ADD_EMAIL) . '</span></a>';
                 }
                 return true;
                 break;
             case 'backend_sidebar_admin_appearance':
                 echo '<li><a href="serendipity_admin.php?serendipity[adminModule]=plugins&amp;serendipity[plugin_to_conf]=' . $this->instance . '">' . PLUGIN_EVENT_SPAMBLOCK_TITLE . '</a></li>';
                 return true;
                 break;
             default:
                 return false;
                 break;
         }
     } else {
         return false;
     }
 }
/**
 * Parses the configuration array and displays the configuration screen
 *
 * @access public
 * @param   array       Configuration superarray
 * @param   array       The previous values submitted by the user
 * @param   boolean     If true, no HTML FORM container will be emitted
 * @param   boolean     If true, the configuration sections will all be folded
 * @param   boolean     If true, the user can turn config sections on and off
 * @param   boolean     If true, the user can NOT display possibly dangerous options
 * @return null
 */
function serendipity_printConfigTemplate($config, $from = false, $noForm = false, $folded = true, $allowToggle = true, $showDangerous = false)
{
    global $serendipity;
    if ($allowToggle) {
        ?>
<script type="text/javascript" language="JavaScript">
function showConfig(id) {
    if (document.getElementById) {
        el = document.getElementById(id);
        if (el.style.display == 'none') {
            document.getElementById('option' + id).src = '<?php 
        echo serendipity_getTemplateFile('img/minus.png');
        ?>
';
            el.style.display = '';
        } else {
            document.getElementById('option' + id).src = '<?php 
        echo serendipity_getTemplateFile('img/plus.png');
        ?>
';
            el.style.display = 'none';
        }
    }
}

var state='<?php 
        echo $folded === true ? '' : 'none';
        ?>
';
function showConfigAll(count) {
    if (document.getElementById) {
        for (i = 1; i <= count; i++) {
            document.getElementById('el' + i).style.display = state;
            document.getElementById('optionel' + i).src = (state == '' ? '<?php 
        echo serendipity_getTemplateFile('img/minus.png');
        ?>
' : '<?php 
        echo serendipity_getTemplateFile('img/plus.png');
        ?>
');
        }

        if (state == '') {
            document.getElementById('optionall').src = '<?php 
        echo serendipity_getTemplateFile('img/minus.png');
        ?>
';
            state = 'none';
        } else {
            document.getElementById('optionall').src = '<?php 
        echo serendipity_getTemplateFile('img/plus.png');
        ?>
';
            state = '';
        }
    }
}
</script>

<?php 
    }
    if (!$noForm) {
        ?>
<form action="?" method="POST">
    <div>
        <input type="hidden" name="serendipity[adminModule]" value="installer" />
        <input type="hidden" name="installAction" value="check" />
        <?php 
        echo serendipity_setFormToken();
        ?>
        <br />
<?php 
    }
    if (sizeof($config) > 1 && $allowToggle) {
        ?>
        <div align="right">
            <a style="border:0; text-decoration: none" href="#" onClick="showConfigAll(<?php 
        echo sizeof($config);
        ?>
)" title="<?php 
        echo TOGGLE_ALL;
        ?>
"><img src="<?php 
        echo serendipity_getTemplateFile('img/' . ($folded === true ? 'plus' : 'minus') . '.png');
        ?>
" id="optionall" alt="+/-" border="0" />&nbsp;<?php 
        echo TOGGLE_ALL;
        ?>
</a></a><br />
        </div>
<?php 
    }
    $el_count = 0;
    foreach ($config as $category) {
        $el_count++;
        ?>
        <table width="100%" cellspacing="2">
<?php 
        if (sizeof($config) > 1) {
            ?>
            <tr>
                <th align="left" colspan="2" style="padding-left: 15px;">
<?php 
            if ($allowToggle) {
                ?>
                    <a style="border:0; text-decoration: none;" href="#" onClick="showConfig('el<?php 
                echo $el_count;
                ?>
'); return false" title="<?php 
                echo TOGGLE_OPTION;
                ?>
"><img src="<?php 
                echo serendipity_getTemplateFile('img/' . ($folded === true ? 'plus' : 'minus') . '.png');
                ?>
" id="optionel<?php 
                echo $el_count;
                ?>
" alt="+/-" border="0" />&nbsp;<?php 
                echo $category['title'];
                ?>
</a>
<?php 
            } else {
                ?>
                    <?php 
                echo $category['title'];
            }
            ?>
                </th>
            </tr>
<?php 
        }
        ?>
            <tr>
                <td>
                    <table width="100%" cellspacing="0" cellpadding="3" id="el<?php 
        echo $el_count;
        ?>
">
                        <tr>
                            <td style="padding-left: 20px;" colspan="2">
                                <?php 
        echo $category['description'];
        ?>
                            </td>
                        </tr>

<?php 
        foreach ($category['items'] as $item) {
            $value = $from[$item['var']];
            /* Calculate value if we are not installed, how clever :) */
            if ($from == false) {
                $value = serendipity_query_default($item['var'], $item['default']);
            }
            /* Check for installOnly flag */
            if (in_array('installOnly', $item['flags']) && IS_installed === true) {
                continue;
            }
            if (in_array('hideValue', $item['flags'])) {
                $value = '';
            }
            if (!$showDangerous && $item['view'] == 'dangerous') {
                continue;
            }
            if (in_array('config', $item['flags']) && isset($from['authorid'])) {
                $value = serendipity_get_user_config_var($item['var'], $from['authorid'], $item['default']);
            }
            if (in_array('parseDescription', $item['flags'])) {
                $item['description'] = serendipity_replaceEmbeddedConfigVars($item['description']);
            }
            if (in_array('probeDefault', $item['flags'])) {
                $item['default'] = serendipity_probeInstallation($item['var']);
            }
            if (in_array('ifEmpty', $item['flags']) && empty($value)) {
                $value = serendipity_query_default($item['var'], $item['default']);
            }
            ?>
                        <tr>
                            <td style="border-bottom: 1px #000000 solid" align="left" valign="top" width="75%">
                                <strong><?php 
            echo $item['title'];
            ?>
</strong>
                                <br />
                                <span style="color: #5E7A94; font-size: 8pt;"><?php 
            echo $item['description'];
            ?>
</span>
                            </td>
                            <td style="border-bottom: 1px #000000 solid; font-size: 8pt" align="left" valign="middle" width="25%">
                                <span style="white-space: nowrap"><?php 
            echo serendipity_guessInput($item['type'], $item['var'], $value, $item['default']);
            ?>
</span>
                            </td>
                        </tr>
<?php 
        }
        ?>
                    </table><br /><br />
                </td>
            </tr>
        </table>
<?php 
    }
    if ($folded && $allowToggle) {
        echo '<script type="text/javascript" language="JavaScript">';
        for ($i = 1; $i <= $el_count; $i++) {
            echo 'document.getElementById("el' . $i . '").style.display = "none";' . "\n";
        }
        echo '</script>';
    }
    if (!$noForm) {
        ?>
        <input type="submit" value="<?php 
        echo CHECK_N_SAVE;
        ?>
" class="serendipityPrettyButton input_button" />
    </div>
</form>
<?php 
    }
}
Esempio n. 23
0
/**
 * Shows the entry panel overview
 *
 * Shows a list of existing entries, with pagination and cookie-remember settings.
 *
 * @access public
 * @return null
 */
function serendipity_drawList()
{
    global $serendipity, $sort_order, $per_page;
    $filter_import = array('author', 'category', 'isdraft');
    $sort_import = array('perPage', 'ordermode', 'order');
    foreach ($filter_import as $f_import) {
        serendipity_restoreVar($serendipity['COOKIE']['entrylist_filter_' . $f_import], $serendipity['GET']['filter'][$f_import]);
        serendipity_JSsetCookie('entrylist_filter_' . $f_import, $serendipity['GET']['filter'][$f_import]);
    }
    foreach ($sort_import as $s_import) {
        serendipity_restoreVar($serendipity['COOKIE']['entrylist_sort_' . $s_import], $serendipity['GET']['sort'][$s_import]);
        serendipity_JSsetCookie('entrylist_sort_' . $s_import, $serendipity['GET']['sort'][$s_import]);
    }
    $perPage = !empty($serendipity['GET']['sort']['perPage']) ? $serendipity['GET']['sort']['perPage'] : $per_page[0];
    $page = (int) $serendipity['GET']['page'];
    $offSet = $perPage * $page;
    if (empty($serendipity['GET']['sort']['ordermode']) || $serendipity['GET']['sort']['ordermode'] != 'ASC') {
        $serendipity['GET']['sort']['ordermode'] = 'DESC';
    }
    if (!empty($serendipity['GET']['sort']['order']) && !empty($sort_order[$serendipity['GET']['sort']['order']])) {
        $orderby = serendipity_db_escape_string($serendipity['GET']['sort']['order'] . ' ' . $serendipity['GET']['sort']['ordermode']);
    } else {
        $orderby = 'timestamp ' . serendipity_db_escape_string($serendipity['GET']['sort']['ordermode']);
    }
    $filter = array();
    if (!empty($serendipity['GET']['filter']['author'])) {
        $filter[] = "e.authorid = '" . serendipity_db_escape_string($serendipity['GET']['filter']['author']) . "'";
    }
    if (!empty($serendipity['GET']['filter']['category'])) {
        $filter[] = "ec.categoryid = '" . serendipity_db_escape_string($serendipity['GET']['filter']['category']) . "'";
    }
    if (!empty($serendipity['GET']['filter']['isdraft'])) {
        if ($serendipity['GET']['filter']['isdraft'] == 'draft') {
            $filter[] = "e.isdraft = 'true'";
        } elseif ($serendipity['GET']['filter']['isdraft'] == 'publish') {
            $filter[] = "e.isdraft = 'false'";
        }
    }
    if (!empty($serendipity['GET']['filter']['body'])) {
        if ($serendipity['dbType'] == 'mysql') {
            $filter[] = "MATCH (title,body,extended) AGAINST ('" . serendipity_db_escape_string($serendipity['GET']['filter']['body']) . "')";
            $full = true;
        }
    }
    $filter_sql = implode(' AND ', $filter);
    // Fetch the entries
    $entries = serendipity_fetchEntries(false, false, serendipity_db_limit($offSet, $perPage + 1), true, false, $orderby, $filter_sql);
    ?>
<div class="serendipity_admin_list">
<form action="?" method="get">
    <input type="hidden" name="serendipity[action]"      value="admin"      />
    <input type="hidden" name="serendipity[adminModule]" value="entries"    />
    <input type="hidden" name="serendipity[adminAction]" value="editSelect" />
    <table width="100%" class="serendipity_admin_filters">
        <tr>
            <td class="serendipity_admin_filters_headline" colspan="6"><strong><?php 
    echo FILTERS;
    ?>
</strong> - <?php 
    echo FIND_ENTRIES;
    ?>
</td>
        </tr>
        <tr>
            <td valign="top" width="80"><?php 
    echo AUTHOR;
    ?>
</td>
            <td valign="top">
                <select name="serendipity[filter][author]">
                    <option value="">--</option>
<?php 
    $users = serendipity_fetchUsers('', null, true);
    if (is_array($users)) {
        foreach ($users as $user) {
            if (isset($user['artcount']) && $user['artcount'] < 1) {
                continue;
            }
            echo '<option value="' . $user['authorid'] . '" ' . (isset($serendipity['GET']['filter']['author']) && $serendipity['GET']['filter']['author'] == $user['authorid'] ? 'selected="selected"' : '') . '>' . htmlspecialchars($user['realname']) . '</option>' . "\n";
        }
    }
    ?>
              </select> <select name="serendipity[filter][isdraft]">
                    <option value="all"><?php 
    echo COMMENTS_FILTER_ALL;
    ?>
</option>
                    <option value="draft"   <?php 
    echo isset($serendipity['GET']['filter']['isdraft']) && $serendipity['GET']['filter']['isdraft'] == 'draft' ? 'selected="selected"' : '';
    ?>
><?php 
    echo DRAFT;
    ?>
</option>
                    <option value="publish" <?php 
    echo isset($serendipity['GET']['filter']['isdraft']) && $serendipity['GET']['filter']['isdraft'] == 'publish' ? 'selected="selected"' : '';
    ?>
><?php 
    echo PUBLISH;
    ?>
</option>
                </select>
            </td>
            <td valign="top" width="80"><?php 
    echo CATEGORY;
    ?>
</td>
            <td valign="top">
                <select name="serendipity[filter][category]">
                    <option value="">--</option>
<?php 
    $categories = serendipity_fetchCategories();
    $categories = serendipity_walkRecursive($categories, 'categoryid', 'parentid', VIEWMODE_THREADED);
    foreach ($categories as $cat) {
        echo '<option value="' . $cat['categoryid'] . '"' . ($serendipity['GET']['filter']['category'] == $cat['categoryid'] ? ' selected="selected"' : '') . '>' . str_repeat('&nbsp;', $cat['depth']) . htmlspecialchars($cat['category_name']) . '</option>' . "\n";
    }
    ?>
              </select>
            </td>
            <td valign="top" width="80"><?php 
    echo CONTENT;
    ?>
</td>
            <td valign="top"><input class="input_textbox" size="10" type="text" name="serendipity[filter][body]" value="<?php 
    echo isset($serendipity['GET']['filter']['body']) ? htmlspecialchars($serendipity['GET']['filter']['body']) : '';
    ?>
" /></td>
        </tr>
        <tr>
            <td class="serendipity_admin_filters_headline" colspan="6"><strong><?php 
    echo SORT_ORDER;
    ?>
</strong></td>
        </tr>
        <tr>
            <td>
                <?php 
    echo SORT_BY;
    ?>
            </td>
            <td>
                <select name="serendipity[sort][order]">
<?php 
    foreach ($sort_order as $so_key => $so_val) {
        echo '<option value="' . $so_key . '" ' . (isset($serendipity['GET']['sort']['order']) && $serendipity['GET']['sort']['order'] == $so_key ? 'selected="selected"' : '') . '>' . $so_val . '</option>' . "\n";
    }
    ?>
              </select>
            </td>
            <td><?php 
    echo SORT_ORDER;
    ?>
</td>
            <td>
                <select name="serendipity[sort][ordermode]">
                    <option value="DESC" <?php 
    echo isset($serendipity['GET']['sort']['ordermode']) && $serendipity['GET']['sort']['ordermode'] == 'DESC' ? 'selected="selected"' : '';
    ?>
><?php 
    echo SORT_ORDER_DESC;
    ?>
</option>
                    <option value="ASC" <?php 
    echo isset($serendipity['GET']['sort']['ordermode']) && $serendipity['GET']['sort']['ordermode'] == 'ASC' ? 'selected="selected"' : '';
    ?>
><?php 
    echo SORT_ORDER_ASC;
    ?>
</option>
                </select>
            </td>
            <td><?php 
    echo ENTRIES_PER_PAGE;
    ?>
</td>
            <td>
                <select name="serendipity[sort][perPage]">
<?php 
    foreach ($per_page as $per_page_nr) {
        echo '<option value="' . $per_page_nr . '"   ' . (isset($serendipity['GET']['sort']['perPage']) && $serendipity['GET']['sort']['perPage'] == $per_page_nr ? 'selected="selected"' : '') . '>' . $per_page_nr . '</option>' . "\n";
    }
    ?>
                </select>
            </td>
        </tr>
        <tr>
            <td align="right" colspan="6"><input type="submit" name="go" value="<?php 
    echo GO;
    ?>
" class="serendipityPrettyButton input_button" /></td>
        </tr>
    </table>
    </form>

    <table class="serendipity_admin_list" cellpadding="5" width="100%">
<?php 
    if (is_array($entries)) {
        $count = count($entries);
        $qString = '?serendipity[adminModule]=entries&amp;serendipity[adminAction]=editSelect';
        foreach ((array) $serendipity['GET']['sort'] as $k => $v) {
            $qString .= '&amp;serendipity[sort][' . $k . ']=' . $v;
        }
        foreach ((array) $serendipity['GET']['filter'] as $k => $v) {
            $qString .= '&amp;serendipity[filter][' . $k . ']=' . $v;
        }
        $linkPrevious = $qString . '&amp;serendipity[page]=' . ($page - 1);
        $linkNext = $qString . '&amp;serendipity[page]=' . ($page + 1);
        ?>
        <tr>
            <td>
                <?php 
        if ($offSet > 0) {
            ?>
                    <a href="<?php 
            echo $linkPrevious;
            ?>
" class="serendipityIconLink"><img src="<?php 
            echo serendipity_getTemplateFile('admin/img/previous.png');
            ?>
" /><?php 
            echo PREVIOUS;
            ?>
</a>
                <?php 
        }
        ?>
            </td>
            <td align="right">
                <?php 
        if ($count > $perPage) {
            ?>
                    <a href="<?php 
            echo $linkNext;
            ?>
" class="serendipityIconLinkRight"><?php 
            echo NEXT;
            ?>
<img src="<?php 
            echo serendipity_getTemplateFile('admin/img/next.png');
            ?>
" /></a>
                <?php 
        }
        ?>
            </td>
        </tr>
    </table>
    <script type="text/javascript">
    function invertSelection() {
        var f = document.formMultiDelete;
        for (var i = 0; i < f.elements.length; i++) {
            if (f.elements[i].type == 'checkbox') {
                f.elements[i].checked = !(f.elements[i].checked);
            }
        }
    }
    </script>
    <form action="?" method="post" name="formMultiDelete" id="formMultiDelete">
        <?php 
        echo serendipity_setFormToken();
        ?>
        <input type="hidden" name="serendipity[action]" value="admin" />
        <input type="hidden" name="serendipity[adminModule]" value="entries" />
        <input type="hidden" name="serendipity[adminAction]" value="multidelete" />
<?php 
        // Print the entries
        $rows = 0;
        foreach ($entries as $entry) {
            $rows++;
            if ($rows > $perPage) {
                continue;
            }
            // Find out if the entry has been modified later than 30 minutes after creation
            if ($entry['timestamp'] <= $entry['last_modified'] - 60 * 30) {
                $lm = '<a href="#" title="' . LAST_UPDATED . ': ' . serendipity_formatTime(DATE_FORMAT_SHORT, $entry['last_modified']) . '" onclick="alert(this.title)"><img src="' . serendipity_getTemplateFile('admin/img/clock.png') . '" alt="*" style="border: 0px none ; vertical-align: bottom;" /></a>';
            } else {
                $lm = '';
            }
            if (!$serendipity['showFutureEntries'] && $entry['timestamp'] >= serendipity_serverOffsetHour()) {
                $entry_pre = '<a href="#" title="' . ENTRY_PUBLISHED_FUTURE . '" onclick="alert(this.title)"><img src="' . serendipity_getTemplateFile('admin/img/clock_future.png') . '" alt="*" style="border: 0px none ; vertical-align: bottom;" /></a> ';
            } else {
                $entry_pre = '';
            }
            if (serendipity_db_bool($entry['properties']['ep_is_sticky'])) {
                $entry_pre .= ' ' . STICKY_POSTINGS . ': ';
            }
            if (serendipity_db_bool($entry['isdraft'])) {
                $entry_pre .= ' ' . DRAFT . ': ';
            }
            ?>
<!--            <div class="serendipity_admin_list_item serendipity_admin_list_item_<?php 
            echo $rows % 2 ? 'even' : 'uneven';
            ?>
"> -->
            <div class="serendipity_admin_list_item serendipity_admin_list_item_<?php 
            echo $rows % 2 ? 'even' : 'uneven';
            ?>
">

                <table width="100%" cellspacing="0" cellpadding="3">
                    <tr>
                        <td>
                            <strong><?php 
            echo $entry_pre;
            ?>
<a href="?serendipity[action]=admin&amp;serendipity[adminModule]=entries&amp;serendipity[adminAction]=edit&amp;serendipity[id]=<?php 
            echo $entry['id'];
            ?>
" title="#<?php 
            echo $entry['id'];
            ?>
"><?php 
            echo serendipity_truncateString(htmlspecialchars($entry['title']), 50);
            ?>
</a></strong>
                        </td>
                        <td align="right">
                            <?php 
            echo serendipity_formatTime(DATE_FORMAT_SHORT, $entry['timestamp']) . ' ' . $lm;
            ?>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <?php 
            echo POSTED_BY . ' ' . htmlspecialchars($entry['author']);
            if (count($entry['categories'])) {
                echo ' ' . IN . ' ';
                $cats = array();
                foreach ($entry['categories'] as $cat) {
                    $caturl = serendipity_categoryURL($cat);
                    $cats[] = '<a href="' . $caturl . '">' . htmlspecialchars($cat['category_name']) . '</a>';
                }
                echo implode(', ', $cats);
            }
            $entry['link'] = serendipity_archiveURL($entry['id'], $entry['title'], 'serendipityHTTPPath', true, array('timestamp' => $entry['timestamp']));
            $entry['preview_link'] = '?serendipity[noBanner]=true&amp;serendipity[noSidebar]=true&amp;serendipity[action]=admin&amp;serendipity[adminModule]=entries&amp;serendipity[adminAction]=preview&amp;serendipity[id]=' . $entry['id'];
            ?>

                        </td>
                        <td align="right">
                            <?php 
            if (serendipity_db_bool($entry['isdraft']) || !$serendipity['showFutureEntries'] && $entry['timestamp'] >= serendipity_serverOffsetHour()) {
                ?>
                            <a target="_blank" href="<?php 
                echo $entry['preview_link'];
                ?>
" title="<?php 
                echo PREVIEW . ' #' . $entry['id'];
                ?>
" class="serendipityIconLink"><img src="<?php 
                echo serendipity_getTemplateFile('admin/img/zoom.png');
                ?>
" alt="<?php 
                echo PREVIEW;
                ?>
" /><?php 
                echo PREVIEW;
                ?>
</a>
                            <?php 
            } else {
                ?>
                            <a target="_blank" href="<?php 
                echo $entry['link'];
                ?>
" title="<?php 
                echo VIEW . ' #' . $entry['id'];
                ?>
" class="serendipityIconLink"><img src="<?php 
                echo serendipity_getTemplateFile('admin/img/zoom.png');
                ?>
" alt="<?php 
                echo VIEW;
                ?>
" /><?php 
                echo VIEW;
                ?>
</a>
                            <?php 
            }
            ?>
                            <a href="?serendipity[action]=admin&amp;serendipity[adminModule]=entries&amp;serendipity[adminAction]=edit&amp;serendipity[id]=<?php 
            echo $entry['id'];
            ?>
" title="<?php 
            echo EDIT . ' #' . $entry['id'];
            ?>
" class="serendipityIconLink"><img src="<?php 
            echo serendipity_getTemplateFile('admin/img/edit.png');
            ?>
" alt="<?php 
            echo EDIT;
            ?>
" /><?php 
            echo EDIT;
            ?>
</a>
                            <a href="?<?php 
            echo serendipity_setFormToken('url');
            ?>
&amp;serendipity[action]=admin&amp;serendipity[adminModule]=entries&amp;serendipity[adminAction]=delete&amp;serendipity[id]=<?php 
            echo $entry['id'];
            ?>
" title="<?php 
            echo DELETE . ' #' . $entry['id'];
            ?>
" class="serendipityIconLink"><img src="<?php 
            echo serendipity_getTemplateFile('admin/img/delete.png');
            ?>
" alt="<?php 
            echo DELETE;
            ?>
" /><?php 
            echo DELETE;
            ?>
</a>
                            <input class="input_checkbox" type="checkbox" name="serendipity[multiDelete][]" value="<?php 
            echo $entry['id'];
            ?>
" />
                        </td>
                    </tr>
                </table>
            </div>
<?php 
        }
        // end entries output
        ?>
        <table class="serendipity_admin_list" cellpadding="5" width="100%">
            <tr>
                <td>
                    <?php 
        if ($offSet > 0) {
            ?>
                        <a href="<?php 
            echo $linkPrevious;
            ?>
" class="serendipityIconLink"><img src="<?php 
            echo serendipity_getTemplateFile('admin/img/previous.png');
            ?>
" /><?php 
            echo PREVIOUS;
            ?>
</a>
                    <?php 
        }
        ?>
                </td>
                <td align="right">
                    <?php 
        if ($count > $perPage) {
            ?>
                        <a href="<?php 
            echo $linkNext;
            ?>
" class="serendipityIconLinkRight"><?php 
            echo NEXT;
            ?>
<img src="<?php 
            echo serendipity_getTemplateFile('admin/img/next.png');
            ?>
" /></a>
                    <?php 
        }
        ?>
                </td>
            </tr>
        </table>

        <table class="serendipity_admin_list" cellpadding="0" width="100%">
            <tr>
                <td align="right">
                    <input type="button" name="toggle" value="<?php 
        echo INVERT_SELECTIONS;
        ?>
" onclick="invertSelection()" class="serendipityPrettyButton input_button" />
                    <input type="submit" name="toggle" value="<?php 
        echo DELETE_SELECTED_ENTRIES;
        ?>
" class="serendipityPrettyButton input_button" />
                </td>
            </tr>
        </table>
        </form>

        <div class="serendipity_admin_list_item serendipity_admin_list_item_<?php 
        echo ($rows + 1) % 2 ? 'even' : 'uneven';
        ?>
">
            <table width="100%" cellspacing="0" cellpadding="3">
                    <tr>
                        <td>
                            <form action="?" method="get">
                                <input type="hidden" name="serendipity[action]"      value="admin"      />
                                <input type="hidden" name="serendipity[adminModule]" value="entries"    />
                                <input type="hidden" name="serendipity[adminAction]" value="editSelect" />
                            <?php 
        echo EDIT_ENTRY;
        ?>
: #<input class="input_textbox" type="text" size="3" name="serendipity[id]" /> <input type="submit" name="serendipity[editSubmit]" value="<?php 
        echo GO;
        ?>
" class="serendipityPrettyButton input_button" />
                            </form>
                        </td>
                    </tr>
            </table>
        </div>
 <?php 
    } else {
        // We've got nothing
        ?>
        <tr>
            <td align="center" class="serendipityAdminMsgNote">
                <img style="width: 22px; height: 22px; border: 0px; padding-right: 4px; vertical-align: middle" src="<?php 
        echo serendipity_getTemplateFile('admin/img/admin_msg_note.png');
        ?>
" alt="" />
                <?php 
        echo NO_ENTRIES_TO_PRINT;
        ?>
            </td>
        </tr>
    </table>
<?php 
    }
    ?>
</div>
<?php 
}
/**
 * Parses the configuration array and displays the configuration screen
 *
 * @access public
 * @param   array       Configuration superarray
 * @param   array       The previous values submitted by the user
 * @param   boolean     If true, no HTML FORM container will be emitted
 * @param   boolean     If true, the configuration sections will all be folded
 * @param   boolean     If true, the user can turn config sections on and off
 * @param   boolean     If true, the user can NOT display possibly dangerous options
 * @return null
 */
function serendipity_printConfigTemplate($config, $from = false, $noForm = false, $folded = true, $allowToggle = true, $showDangerous = false)
{
    global $serendipity;
    $data = array();
    $data['noForm'] = $noForm;
    $data['formToken'] = serendipity_setFormToken();
    $data['allowToggle'] = $allowToggle;
    foreach ($config as &$category) {
        foreach ($category['items'] as &$item) {
            $value = $from[$item['var']];
            /* Calculate value if we are not installed, how clever :) */
            if ($from == false) {
                $value = serendipity_query_default($item['var'], $item['default']);
            }
            /* Check for installOnly flag */
            if (in_array('installOnly', $item['flags']) && IS_installed === true) {
                continue;
            }
            if (in_array('hideValue', $item['flags'])) {
                $value = '';
            }
            if (!$showDangerous && $item['view'] == 'dangerous') {
                continue;
            }
            if (in_array('config', $item['flags']) && isset($from['authorid'])) {
                $value = serendipity_get_user_config_var($item['var'], $from['authorid'], $item['default']);
            }
            if (in_array('parseDescription', $item['flags'])) {
                $item['description'] = serendipity_replaceEmbeddedConfigVars($item['description']);
            }
            if (in_array('probeDefault', $item['flags'])) {
                $item['default'] = serendipity_probeInstallation($item['var']);
            }
            if (in_array('ifEmpty', $item['flags']) && empty($value)) {
                $value = serendipity_query_default($item['var'], $item['default']);
            }
            $item['guessedInput'] = serendipity_guessInput($item['type'], $item['var'], $value, $item['default']);
        }
    }
    $data['config'] = $config;
    return serendipity_smarty_show('admin/config_template.tpl', $data);
}