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&serendipity[adminModule]=entries&serendipity[adminAction]=edit&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&serendipity[adminModule]=entries&serendipity[adminAction]=delete&serendipity[id]=' . $eventData[$i]['id'] . '&' . 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&serendipity[adminModule]=entries&serendipity[adminAction]=edit&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&serendipity[noSidebar]=true&serendipity[action]=admin&serendipity[adminModule]=entries&serendipity[adminAction]=preview&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']; ?> &<?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&serendipity[adminModule]=entries&serendipity[adminAction]=edit&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 = '&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 = ' '; } else { $moveup = '<a href="?' . serendipity_setFormToken('url') . '&serendipity[adminModule]=plugins&submit=move+up&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 = ' '; } else { $movedown = ($moveup != '' ? ' ' : '') . '<a href="?' . serendipity_setFormToken('url') . '&serendipity[adminModule]=plugins&submit=move+down&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&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&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(' ', $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; }
$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(' ', $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>'; }
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> </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('&', $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("@(&|&)?{$rm}@", '', $url); } } } if (substr($url, -1) != '?') { $url .= '&'; } // 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&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 .= "&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 .= "&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 .= "&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 .= "&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 . '&serendipity[page]=' . ($page - 1) . $searchString; } if ($pages > $page) { $linkNext = $url . '&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 = ' '; } if ($linkNext) { $linkNext = '<a href="' . $linkNext . '" class="serendipityIconLinkRight"><img src="' . serendipity_getTemplateFile('admin/img/next.png') . '" /></a>'; } else { $linkNext = ' '; } $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; } }
$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();
?> " 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&serendipity[adminModule]=comments&serendipity[adminAction]=reply&serendipity[id]=<?php echo $comment['id']; ?> &serendipity[entry_id]=<?php echo $comment['entry_id']; ?> &serendipity[noBanner]=true&serendipity[noSidebar]=true&<?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&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 ' '; 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') . '&serendipity[adminModule]=event_display&serendipity[adminAction]=adminnotes&action=isdelete&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(' ', 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&serendipity[adminAction]=adminnotes&action=edit&note=' . $note['noteid'] . '">' . EDIT . '</a> '; echo '<a class="serendipityPrettyButton" href="?serendipity[adminModule]=event_display&serendipity[adminAction]=adminnotes&action=delete&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&serendipity[adminAction]=adminnotes&action=edit&note=' . $note['noteid'] . '">' . EDIT . '</a> '; echo '<a class="button_link state_cancel" href="?serendipity[adminModule]=event_display&serendipity[adminAction]=adminnotes&action=delete&note=' . $note['noteid'] . '">' . DELETE . '</a></div></li>'; } } } echo '</ol>'; if ($serendipity['version'][0] < 2) { echo '<a class="serendipityPrettyButton" href="?serendipity[adminModule]=event_display&serendipity[adminAction]=adminnotes&action=new">' . NEW_ENTRY . '</a>'; } else { echo '<div class="form_buttons"><a class="button_link state_submit" href="?serendipity[adminModule]=event_display&serendipity[adminAction]=adminnotes&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(); }
?> <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&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('&', '&', $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('&', $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("@(&|&)?{$rm}@", '', $url); } } } if (substr($url, -1) != '?') { $url .= '&'; } // 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&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 .= "&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 .= "&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 .= "&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 .= "&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 . '&serendipity[page]=' . ($page - 1) . $searchString; } if ($pages > $page) { $linkNext = $url . '&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) . '…'; } 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&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 = '&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&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&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&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&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&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&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" /> <?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" /> <?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 } }
/** * 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(' ', $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&serendipity[adminAction]=editSelect'; foreach ((array) $serendipity['GET']['sort'] as $k => $v) { $qString .= '&serendipity[sort][' . $k . ']=' . $v; } foreach ((array) $serendipity['GET']['filter'] as $k => $v) { $qString .= '&serendipity[filter][' . $k . ']=' . $v; } $linkPrevious = $qString . '&serendipity[page]=' . ($page - 1); $linkNext = $qString . '&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&serendipity[adminModule]=entries&serendipity[adminAction]=edit&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&serendipity[noSidebar]=true&serendipity[action]=admin&serendipity[adminModule]=entries&serendipity[adminAction]=preview&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&serendipity[adminModule]=entries&serendipity[adminAction]=edit&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'); ?> &serendipity[action]=admin&serendipity[adminModule]=entries&serendipity[adminAction]=delete&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); }