New 'sidebar' template configuration option. EXPERIMENTAL
authorgarvinhicking <garvinhicking>
Sun, 27 Aug 2006 20:44:55 +0000 (20:44 +0000)
committergarvinhicking <garvinhicking>
Sun, 27 Aug 2006 20:44:55 +0000 (20:44 +0000)
docs/NEWS
include/admin/plugins.inc.php
include/functions_plugins_admin.inc.php

index 553dfde6163e97abe1c9d9f9ddfa69cca9e945db..744a6f6ab13e1d058c5134a7330a7a6211000512 100644 (file)
--- a/docs/NEWS
+++ b/docs/NEWS
@@ -3,11 +3,29 @@
 Version 1.1-beta4 ()
 ------------------------------------------------------------------------
 
+    * Added possibility for templates to define the sidebars they use.
+      The template specifies this via the $template_config array in
+      the config.inc.php file of a template. It looks like this:
+       $template_config = array(
+         array(
+           'var'     => 'sidebars',
+           'title'   => 'Sidebars',
+           'type'    => 'string',
+           'default' => 'left,hide,right'
+         )
+       );
+      Note some things: Seperate the sidebar keys with a "," only -
+      do not use spaces. Also never use more than 6 characters for
+      the descriptors.
+      If you do not want to make it configurable, you can also use
+      the $serendipity['sidebars'] array to define the sidebars
+      that are available.
+
     * Made category-recursion show orphaned categories because of
       permission restrictions (garvinhicking)
 
     * Fix some markup functions in textile plugin (Matthias Leisi)
-    
+
     * Add Smarty function to show commentform (garvinhicking)
 
     * Group management now allows to disallow certain plugins or even
@@ -26,15 +44,15 @@ Version 1.1-beta3 ()
     * Fix a bug in the HTTP 304 Conditional GET RSS-Feed caching when
       the server timezone offset was not set to zero. Thanks to dand!
 
-    * Added ability to use HTTP Authentication to the blog. Can be 
-      triggered by submitting HTTP Auth credentials [only supported when 
-      the server runs with mod_php, not as CGI]. Authentication can be 
+    * Added ability to use HTTP Authentication to the blog. Can be
+      triggered by submitting HTTP Auth credentials [only supported when
+      the server runs with mod_php, not as CGI]. Authentication can be
       forced URLs with the "?http_auth=true" parameter, which
       will then send a "401 Unauthorized" header.
       If your server does not support mod_php, you can submit REQUEST
       variables: ?http_auth_user=XXX&http_auth_pw=YYY.
       Note that specifying username and password in the URI will lead
-      to password disclosure in HTTP logfiles. 
+      to password disclosure in HTTP logfiles.
       This feature is most importantly meant for RSS-feeds, to make
       RSS readers able to submit login credentials. (garvinhicking)
 
@@ -55,7 +73,7 @@ Version 1.1-beta1 (August 14th, 2006)
       by authors. New permalink structure:
        "/comments/[AUTHORNAME]/comments|trackbacks|comments_and_trackbacks/P[PAGENUMBER]/FROM [YYYY-MM-DD]/TO [YYYY-MM-DD]"
       Instead of /FROM and /TO you can also use /F and /T.
-      Instead of /FROM and /TO you can also specify /last_X, where X 
+      Instead of /FROM and /TO you can also specify /last_X, where X
       is the amount of past days to show comments for.
       (garvinhicking)
 
@@ -91,7 +109,7 @@ Version 1.1-beta1 (August 14th, 2006)
       Bottom line: Plugins that use "*plugin*.tpl" filenames or check
       via file_exists() on the returned variable are safe.
       (garvinhicking)
-      
+
     * Added arabic (sa) language by Way
 
     * Add patch to allow entryproperties plugin to define passwords for
@@ -123,14 +141,14 @@ Version 1.1-beta1 (August 14th, 2006)
 
     * Added experimental PHP-engine templating support, bypassing
       Smarty. Work in progress, mostly proof-of-concept. Might
-      be changed completely. Read instructions in the 
+      be changed completely. Read instructions in the
       include/template_api.inc.php file. Dedicated to Davey. ;)
       (garvinhicking)
 
     * Support to crop images from within the media database. Pick a
       picture in the MDB, go to the property section of that image
       and click on the "EDIT" link. (garvinhicking)
-      
+
         TODO:
             - Operate also on PNG, TIFF etc. (currently only JPEG!)
             - Support image magick (currently ony gdlib!)
@@ -139,14 +157,14 @@ Version 1.1-beta1 (August 14th, 2006)
             - Add options to only affect the images thumbnail instead
               of always saving the whole picture.
             - Internationalization!
-        
+
     * Move the DB charset option to serendipity_config_local.inc.php to
       issue propper DB connections instantly. (garvinhicking)
 
 Version 1.1-alpha6()
 ------------------------------------------------------------------------
 
-    * Use possibly existing local PEAR by default. Patch by Davey 
+    * Use possibly existing local PEAR by default. Patch by Davey
       (garvinhicking)
 
     * Add missing indices for the statistics visitor DB tables
@@ -160,7 +178,7 @@ Version 1.1-alpha6()
 
     * Fix bug #1494653: Non-Unique index constraint for 'exits' table.
       Thanks to Markus Brueckner! (garvinhicking)
-      
+
 Version 1.1-alpha5()
 ------------------------------------------------------------------------
 
@@ -294,7 +312,7 @@ Version 1.0.1 ()
 
    * Fix multi-authors view only showing first author (garvinhicking)
 
-   * Fix bug sending comment-notification mails to subscribed users 
+   * Fix bug sending comment-notification mails to subscribed users
      without an email address (garvinhicking)
 
    * Fixed icelandic language bug preventing upgrade (garvinhicking)
@@ -305,7 +323,7 @@ Version 1.0 (June 15th, 2006)
    * Insert logic for saving an entry that prevents the iframe for
      trackbacks/xml-rpc pings to save an entry multiple times upon
      failure. Many thanks to tharos from the Forums! (garvinhicking)
-             
+
    * Add smarty parameter $view which can be used to detect what kind
      of page is being displayed. One of: archives, entry, feed, admin,
      archives, plugin, categories, authors, search, css, start, 404
index ffe9a3435b1860bfaebb5b56cbfede5fe0342158..9ca17b792267b73bd7b10f69e89a64fc5023dcbb 100644 (file)
@@ -111,7 +111,7 @@ if (isset($_GET['serendipity']['plugin_to_conf'])) {
     echo "</ul>\n";
     ?>
     </div>
-<?php } elseif ( isset($_POST['SAVECONF']) ) { ?>
+<?php } elseif ( isset($_POST['SAVECONF'])) { ?>
     <div class="serendipityAdminMsgSuccess"><?php echo DONE .': '. sprintf(SETTINGS_SAVED_AT, serendipity_strftime('%H:%M:%S')); ?></div>
 <?php } ?>
 
@@ -196,7 +196,11 @@ if (isset($_GET['serendipity']['plugin_to_conf'])) {
     $pluggroups     = array();
     $pluggroups[''] = array();
     foreach($pluginstack AS $plugname => $plugdata) {
-        if (is_array($plugdata['groups'])) {
+        if ($serendipity['GET']['only_group'] == 'ALL') {
+            $pluggroups['ALL'][] = $plugdata;
+        } elseif ($serendipity['GET']['only_group'] == 'UPGRADE' && $plugdata['upgradable']) {
+            $pluggroups['UPGRADE'][] = $plugdata;
+        } elseif (is_array($plugdata['groups'])) {
             foreach($plugdata['groups'] AS $group) {
                 $pluggroups[$group][] = $plugdata;
             }
@@ -209,6 +213,10 @@ if (isset($_GET['serendipity']['plugin_to_conf'])) {
     foreach($errorstack as $e_idx => $e_name) {
         echo ERROR . ': ' . $e_name . '<br />';
     }
+
+    if ($serendipity['GET']['only_group'] == 'UPGRADE') {
+        serendipity_plugin_api::hook_event('backend_pluginlisting_header_upgrade', $pluggroups);
+    }
 ?>
 <table cellspacing="0" cellpadding="0" border="0" width="100%">
 <?php
@@ -228,6 +236,8 @@ if (isset($_GET['serendipity']['plugin_to_conf'])) {
                     ?>
                     <option value="<?php echo $available_group; ?>" <?php echo ($serendipity['GET']['only_group'] == $available_group ? 'selected="selected"' : ''); ?>><?php echo serendipity_groupname($available_group); ?>
             <?php } ?>
+                    <option value="ALL" <?php echo ($serendipity['GET']['only_group'] == 'ALL' ? 'selected="selected"' : ''); ?>><?php echo ALL_CATEGORIES; ?>
+                    <option value="UPGRADE" <?php echo ($serendipity['GET']['only_group'] == 'UPGRADE' ? 'selected="selected"' : ''); ?>><?php echo WORD_NEW; ?>
                 </select>
                 <input type="submit" value="<?php echo GO; ?>" />
             </form>
@@ -309,9 +319,9 @@ if (isset($_GET['serendipity']['plugin_to_conf'])) {
                         <?php if ( $plug['requirements_fail'] == true ) { ?>
                             <span style="color: #cccccc"><?php printf(UNMET_REQUIREMENTS, implode(', ', $notice['requirements_failures'])); ?></span>
                         <?php } elseif ( $plug['upgradable'] == true ) { ?>
-                            <a href="?serendipity[adminModule]=plugins&amp;serendipity[pluginPath]=<?php echo $plug['pluginPath']; ?>&amp;serendipity[install_plugin]=<?php echo $plug['plugin_class'] . $plug['customURI'] ?>"><img src="<?php echo serendipity_getTemplateFile('admin/img/upgrade_now.png') ?>" title="<?php echo UPGRADE ?>" alt="<?php echo UPGRADE ?>" border="0"></a>
+                            <a href="?serendipity[adminModule]=plugins&amp;serendipity[pluginPath]=<?php echo $plug['pluginPath']; ?>&amp;serendipity[install_plugin]=<?php echo $plug['plugin_class'] . $plug['customURI'] ?>"><img src="<?php echo serendipity_getTemplateFile('admin/img/upgrade_now.png') ?>" title="<?php echo UPGRADE ?>" alt="<?php echo UPGRADE ?>" border="0" /></a>
                         <?php } elseif ($plug['installable'] == true) { ?>
-                            <a href="?serendipity[adminModule]=plugins&amp;serendipity[pluginPath]=<?php echo $plug['pluginPath']; ?>&amp;serendipity[install_plugin]=<?php echo $plug['plugin_class'] . $plug['customURI'] ?>"><img src="<?php echo $installimage ?>" title="<?php echo INSTALL ?>" alt="<?php echo INSTALL ?>" border="0"></a>
+                            <a href="?serendipity[adminModule]=plugins&amp;serendipity[pluginPath]=<?php echo $plug['pluginPath']; ?>&amp;serendipity[install_plugin]=<?php echo $plug['plugin_class'] . $plug['customURI'] ?>"><img src="<?php echo $installimage ?>" title="<?php echo INSTALL ?>" alt="<?php echo INSTALL ?>" border="0" /></a>
                         <?php } else { ?>
                             <span style="color: #cccccc"><?php echo ALREADY_INSTALLED ?></span>
                         <?php } ?>
@@ -332,12 +342,67 @@ if (isset($_GET['serendipity']['plugin_to_conf'])) {
         }
     }
 ?>
+    <tr>
+        <td colspan="2" align="right"><?php printf(PLUGIN_AVAILABLE_COUNT, count($pluginstack)); ?></td>
+    </tr>
 </table>
 
 <?php
 } else {
     /* show general plugin list */
 
+    /* get sidebar locations */
+    serendipity_smarty_init();
+
+    if (is_array($template_config)) {
+        $template_vars =& serendipity_loadThemeOptions($template_config);
+    }
+
+    $col_assoc = array(
+        'event_col'  => 'event',
+        'eventh_col' => 'eventh'
+    );
+    if (isset($template_vars['sidebars'])) {
+        $sidebars = explode(',', $template_vars['sidebars']);
+    } elseif (isset($serendipity['sidebars'])) {
+        $sidebars = $serendipity['sidebars'];
+    } else {
+        $sidebars = array('left', 'hide', 'right');
+    }
+
+    foreach($sidebars AS $sidebar) {
+        $col_assoc[$sidebar . '_col'] = $sidebar;
+    }
+
+    /* preparse Javascript-generated input */
+    if (isset($_POST['SAVE']) && !empty($_POST['serendipity']['pluginorder'])) {
+        $parts = explode(':', $_POST['serendipity']['pluginorder']);
+
+        foreach($parts AS $sidepart) {
+            preg_match('@^(.+)\((.*)\)$@imsU', $sidepart, $matches);
+            if (!isset($col_assoc[$matches[1]])) {
+                continue;
+            }
+            $pluginsidelist = explode(',', $matches[2]);
+            foreach($pluginsidelist AS $pluginname) {
+                $pluginname = trim(urldecode(str_replace(array('s9ycid', '-'), array('', '%'), $pluginname)));
+
+                if (empty($pluginname)) {
+                    continue;
+                }
+                $serendipity['POST']['placement'][$pluginname] = $col_assoc[$matches[1]];
+                $new_order[] = $pluginname;
+
+            }
+        }
+
+        if (is_array($new_order)) {
+            foreach($new_order AS $new_order_pos => $order_plugin) {
+                serendipity_db_query("UPDATE {$serendipity['dbPrefix']}plugins SET sort_order = ". (int)$new_order_pos . " WHERE name='" . serendipity_db_escape_string($order_plugin) . "'");
+            }
+        }
+    }
+
     if (isset($_POST['SAVE']) && isset($_POST['serendipity']['placement']) && serendipity_checkFormToken()) {
         foreach ($_POST['serendipity']['placement'] as $plugin_name => $placement) {
             serendipity_plugin_api::update_plugin_placement(
@@ -399,20 +464,32 @@ if (isset($_GET['serendipity']['plugin_to_conf'])) {
         }
     }
 ?>
-    <?php echo BELOW_IS_A_LIST_OF_INSTALLED_PLUGINS ?>
-    <br />
+
+<?php if (isset($_POST['SAVE'])) { ?>
+    <div class="serendipityAdminMsgSuccess"><?php echo DONE .': '. sprintf(SETTINGS_SAVED_AT, serendipity_strftime('%H:%M:%S')); ?></div>
+<?php } ?>
+
+    <div><?php echo BELOW_IS_A_LIST_OF_INSTALLED_PLUGINS ?></div>
+<?php
+    if (!isset($serendipity['eyecandy']) || serendipity_db_bool($serendipity['eyecandy'])) {
+        echo '<script src="bundled-libs/dragdrop.js" type="text/javascript"></script>';
+        echo '<div class="warning js_warning"><em>' . PREFERENCE_USE_JS_WARNING . '</em></div>';
+    }
+
+    serendipity_plugin_api::hook_event('backend_pluginlisting_header', $serendipity['eyecandy']);
+?>
     <br />
 
     <h3><?php echo SIDEBAR_PLUGINS ?></h3>
-    <a href="?serendipity[adminModule]=plugins&amp;serendipity[adminAction]=addnew" class="serendipityIconLink"><img src="<?php echo serendipity_getTemplateFile('admin/img/install.png') ?>" style="border: 0px none ; vertical-align: middle; display: inline;" alt=""><?php echo sprintf(CLICK_HERE_TO_INSTALL_PLUGIN, SIDEBAR_PLUGIN) ?></a>
+    <a href="?serendipity[adminModule]=plugins&amp;serendipity[adminAction]=addnew" class="serendipityIconLink"><img src="<?php echo serendipity_getTemplateFile('admin/img/install.png') ?>" style="border: 0px none ; vertical-align: middle; display: inline;" alt="" /><?php echo sprintf(CLICK_HERE_TO_INSTALL_PLUGIN, SIDEBAR_PLUGIN) ?></a>
     <?php serendipity_plugin_api::hook_event('backend_plugins_sidebar_header', $serendipity); ?>
-    <?php show_plugins(false); ?>
+    <?php show_plugins(false, $sidebars); ?>
 
     <br />
     <br />
 
     <h3><?php echo EVENT_PLUGINS ?></h3>
-    <a href="?serendipity[adminModule]=plugins&amp;serendipity[adminAction]=addnew&amp;serendipity[type]=event" class="serendipityIconLink"><img src="<?php echo serendipity_getTemplateFile('admin/img/install.png') ?>" style="border: 0px none ; vertical-align: middle; display: inline;" alt=""><?php echo sprintf(CLICK_HERE_TO_INSTALL_PLUGIN, EVENT_PLUGIN) ?></a>
+    <a href="?serendipity[adminModule]=plugins&amp;serendipity[adminAction]=addnew&amp;serendipity[type]=event" class="serendipityIconLink"><img src="<?php echo serendipity_getTemplateFile('admin/img/install.png') ?>" style="border: 0px none ; vertical-align: middle; display: inline;" alt="" /><?php echo sprintf(CLICK_HERE_TO_INSTALL_PLUGIN, EVENT_PLUGIN) ?></a>
     <?php serendipity_plugin_api::hook_event('backend_plugins_event_header', $serendipity); ?>
     <?php show_plugins(true); ?>
 
index 44fefffc72a91622af17b81bed3cd492e95b5bcb..18885b4e088fb7bf34a7d4f46c8fde2d4c66102e 100644 (file)
-<?php # $Id: functions_entries.inc.php 435 2005-08-25 12:36:39Z garvinhicking $\r
-# Copyright (c) 2003-2005, Jannis Hermanns (on behalf the Serendipity Developer Team)\r
-# All rights reserved.  See LICENSE file for licensing details\r
-\r
-/**\r
- * Returns the name of a usergroup.\r
- *\r
- * If a special constant is defined for the name of the group, the name has been\r
- * internationalized. This applies to the Admin/Chief Editor/Editor group names,\r
- * which are different for each language. If such a constant is not present,\r
- * the simple name of the group will be returned.\r
- *\r
- * @access public\r
- * @param  string  name of the group\r
- * @return string  realname of the group\r
- */\r
-function serendipity_groupname($group) {\r
-    if (defined('PLUGIN_GROUP_' . $group)) {\r
-        return constant('PLUGIN_GROUP_' . $group);\r
-    } else {\r
-        return $group;\r
-    }\r
-}\r
-\r
-/**\r
- * Sort the pluginlist by case-insensitive string functions\r
- *\r
- * @access public\r
- * @param  array    Compared Plugin #1\r
- * @param  array    Compared Plugin #2\r
- * @return boolean  Return code for array comparison\r
- */\r
-function serendipity_pluginListSort($x, $y) {\r
-    return strnatcasecmp($x['name'] . ' - ' . $x['description'], $y['name'] . ' - ' . $y['description']);\r
-}\r
-\r
-/**\r
- * Show the list of plugins\r
- *\r
- * Shows a HTML list of all installed plugins, complete with config/delete/sort order options\r
- *\r
- * @access public\r
- * @param  boolean  Indicates if event plugins (TRUE) or sidebar plugins (FALSE) shall be shown\r
- * @return null\r
- */\r
-function show_plugins($event_only = false)\r
-{\r
-    global $serendipity;\r
-?>\r
-    <form action="?serendipity[adminModule]=plugins" method="post">\r
-        <?php echo serendipity_setFormToken(); ?>\r
-        <table border="0" cellpadding="5" cellspacing="0" width="100%">\r
-            <tr>\r
-                <td colspan="2">&nbsp;</td>\r
-                <td><strong><?php echo TITLE; ?></strong></td>\r
-                <td><strong><?php echo PERMISSIONS; ?></strong></td>\r
-<?php\r
-    if (!$event_only) {\r
-?>\r
-                <td colspan="3" align="center"><strong><?php echo PLACEMENT; ?></strong></td>\r
-<?php\r
-    } else {\r
-?>\r
-                <td colspan="2">&nbsp;</dd>\r
-<?php } ?>\r
-            </tr>\r
-<?php\r
-    $errors     = array();\r
-\r
-    /* Block display the plugins per placement location. */\r
-    if ($event_only) {\r
-        $plugin_placements = array('event');\r
-    } else {\r
-        $plugin_placements = array('left', 'right', 'hide');\r
-    }\r
-\r
-    foreach ($plugin_placements as $plugin_placement) {\r
-        $plugins = serendipity_plugin_api::enum_plugins($plugin_placement);\r
-\r
-        if (!is_array($plugins)) {\r
-            continue;\r
-        }\r
-\r
-        $sort_idx = 0;\r
-        foreach ($plugins as $plugin_data) {\r
-            $plugin =& serendipity_plugin_api::load_plugin($plugin_data['name'], $plugin_data['authorid']);\r
-            $key    = urlencode($plugin_data['name']);\r
-            $is_plugin_owner    = ($plugin_data['authorid'] == $serendipity['authorid'] || serendipity_checkPermission('adminPluginsMaintainOthers'));\r
-            $is_plugin_editable = ($is_plugin_owner || $plugin_data['authorid'] == '0');\r
-\r
-            if (!is_object($plugin)) {\r
-                $name = $title = ERROR . '!';\r
-                $desc          = ERROR . ': ' . $plugin_data['name'];\r
-                $can_configure = false;\r
-            } else {\r
-                /* query for its name, description and configuration data */\r
-\r
-                $bag = new serendipity_property_bag;\r
-                $plugin->introspect($bag);\r
-\r
-                $name  = htmlspecialchars($bag->get('name'));\r
-                $desc  = htmlspecialchars($bag->get('description'));\r
-                $desc .= '<br />' . VERSION  . ': <em>' . $bag->get('version') . '</em>';\r
-\r
-                $title = serendipity_plugin_api::get_plugin_title($plugin, '[' . $name . ']');\r
-\r
-                if ($bag->is_set('configuration') && ($plugin->protected === FALSE || $plugin_data['authorid'] == '0' || $plugin_data['authorid'] == $serendipity['authorid'] || serendipity_checkPermission('adminPluginsMaintainOthers'))) {\r
-                    $can_configure = true;\r
-                } else {\r
-                    $can_configure = false;\r
-                }\r
-            }\r
-\r
-            if ($event_only) {\r
-                $place = '<input type="hidden" name="serendipity[placement][' . $plugin_data['name'] . ']" value="event" />';\r
-                $event_only_uri = '&amp;serendipity[event_plugin]=true';\r
-            } else {\r
-                $place = placement_box('serendipity[placement][' . $plugin_data['name'] . ']', $plugin_data['placement'], $is_plugin_editable);\r
-                $event_only_uri = '';\r
-            }\r
-\r
-            /* Only display UP/DOWN links if there's somewhere for the plugin to go */\r
-            if ($sort_idx == 0) {\r
-                $moveup   = '&nbsp;';\r
-            } else {\r
-                $moveup   = '<a href="?' . serendipity_setFormToken('url') . '&amp;serendipity[adminModule]=plugins&amp;submit=move+up&amp;serendipity[plugin_to_move]=' . $key . $event_only_uri . '" style="border: 0"><img src="' . serendipity_getTemplateFile('admin/img/uparrow.png') .'" height="16" width="16" border="0" alt="' . UP . '" /></a>';\r
-            }\r
-\r
-            if ($sort_idx == (count($plugins)-1)) {\r
-                $movedown = '&nbsp;';\r
-            } else {\r
-                $movedown = ($moveup != '' ? '&nbsp;' : '') . '<a href="?' . serendipity_setFormToken('url') . '&amp;serendipity[adminModule]=plugins&amp;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>';\r
-            }\r
-?>\r
-            <tr>\r
-                <td style="border-bottom: 1px solid #000000">\r
-                    <div>\r
-                    <?php if ($is_plugin_editable) { ?>\r
-                        <input type="checkbox" name="serendipity[plugin_to_remove][]" value="<?php echo $plugin_data['name']; ?>" />\r
-                    <?php } else { ?>\r
-                        &nbsp;\r
-                    <?php } ?>\r
-                    </div>\r
-                </td>\r
-                <td style="border-bottom: 1px solid #000000" width="16">\r
-                <?php if ( $can_configure ) { ?>\r
-                    <a href="?serendipity[adminModule]=plugins&amp;serendipity[plugin_to_conf]=<?php echo $key ?>"><img src="<?php echo serendipity_getTemplateFile('admin/img/configure.png') ?>" style="border: 0; vertical-align: bottom;"></a>\r
-                <?php } else { ?>\r
-                    &nbsp;\r
-                <?php } ?>\r
-                </td>\r
-                <td style="border-bottom: 1px solid #000000"><strong>\r
-                <?php if ( $can_configure ) { ?>\r
-                    <a href="?serendipity[adminModule]=plugins&amp;serendipity[plugin_to_conf]=<?php echo $key ?>"><?php echo $title; ?></a>\r
-                <?php } else { ?>\r
-                    <?php echo $title; ?>\r
-                <?php } ?></strong><br />\r
-                    <div style="font-size: 8pt"><?php echo $desc; ?></div>\r
-                </td>\r
-                <td style="border-bottom: 1px solid #000000" nowrap="nowrap"><?php ownership($plugin_data['authorid'], $plugin_data['name'], $is_plugin_owner); ?></td>\r
-            <?php if ( !$event_only ) { ?>\r
-                <td style="border-bottom: 1px solid #000000" nowrap="nowrap"><?php echo $place ?></td>\r
-            <?php } ?>\r
-                <td style="border-bottom: 1px solid #000000"><?php echo $moveup ?></td>\r
-                <td style="border-bottom: 1px solid #000000"><?php echo $movedown ?></td>\r
-            </tr>\r
-<?php\r
-            $sort_idx++;\r
-        }\r
-    }\r
-?>\r
-        </table>\r
-        <br />\r
-        <div>\r
-            <input type="submit" name="REMOVE" title="<?php echo REMOVE_TICKED_PLUGINS; ?>"  value="<?php echo DELETE; ?>" class="serendipityPrettyButton" />\r
-            <input type="submit" name="SAVE"   title="<?php echo SAVE_CHANGES_TO_LAYOUT; ?>" value="<?php echo SAVE; ?>" class="serendipityPrettyButton" />\r
-        </div>\r
-</form>\r
-<?php\r
-}\r
-\r
-/**\r
- * Returns HTML code for the ownership column of the plugin listing\r
- *\r
- * Used by the function show_plugins()\r
- *\r
- * @access  private\r
- * @see     show_plugins()\r
- * @param   int     ID of the current user\r
- * @param   string  plugin name\r
- * @param   boolean Toggle whether the plugin belongs to the current author\r
- * @return  null\r
- */\r
-function ownership($authorid, $name, $is_plugin_owner = false) {\r
-    global $serendipity;\r
-\r
-    static $users = array();\r
-    if (empty($users)) {\r
-        $users = serendipity_fetchUsers();\r
-    }\r
-\r
-    if ($is_plugin_owner) {\r
-?>\r
-<select name="serendipity[ownership][<?php echo $name; ?>]">\r
-    <option value="0"><?php echo ALL_AUTHORS; ?></option>\r
-<?php\r
-    }\r
-\r
-    foreach($users AS $user) {\r
-        if (!$is_plugin_owner && $user['authorid'] == $authorid) {\r
-            $realname = htmlspecialchars($user['realname']);\r
-        } elseif ($is_plugin_owner) {\r
-?>\r
-    <option value="<?php echo $user['authorid']; ?>"<?php echo ($user['authorid'] == $authorid ? ' selected="selected"' : ''); ?>><?php echo htmlspecialchars($user['realname']); ?></option>\r
-<?php\r
-        }\r
-    }\r
-\r
-    if ($is_plugin_owner) {\r
-?>\r
-</select>\r
-<?php\r
-    } else {\r
-        echo (empty($realname) ? ALL_AUTHORS : $realname);\r
-    }\r
-}\r
-\r
-/**\r
- * Show a placement box on where to move a sidebar plugin to\r
- *\r
- * @access private\r
- * @see    show_plugins()\r
- * @param  string   plugin name\r
- * @param  string   current position of the plugin\r
- * @param  boolean  Toggle whether a plugin is editable (depends on authorid and permissions)\r
- * @return string   HTML code for placement select box\r
- */\r
-function placement_box($name, $val, $is_plugin_editable = false)\r
-{\r
-    static $opts = array(\r
-                    'left'  => LEFT,\r
-                    'right' => RIGHT,\r
-                    'hide'  => HIDDEN\r
-        );\r
-\r
-    $x = "\n<select name=\"$name\">\n";\r
-    foreach ($opts as $k => $v) {\r
-        if (!$is_plugin_editable && $k == 'hide') {\r
-            continue;\r
-        }\r
-\r
-        $x .= "    <option value=\"$k\"" . ($k == $val ? ' selected="selected"' : '') . ">$v</option>\n";\r
-    }\r
-    return $x . "</select>\n";\r
-}\r
-\r
-/**\r
- * Show a placement box on where to move a sidebar plugin to\r
- *\r
- * @access public\r
- * @param  object   A plugin object\r
- * @param  object   The plugins property bag object\r
- * @param  string   The name of the plugin\r
- * @param  string   The description of the plugin\r
- * @param  array    The property bag 'configuration' array, holding the array of config items.\r
- * @param  boolean  Shows the surrounding HTML table?\r
- * @param  boolean  Shows the FORM submit button?\r
- * @param  boolean  Shows a plugin's "example" method output?\r
- * @param  boolean  Spawn a plugins' configuration WYSIWYG items?\r
- * @param  string   The array index name of POSTed values ($serendipity['POST'][xxx])\r
- * @return boolean\r
- */\r
-function serendipity_plugin_config(&$plugin, &$bag, &$name, &$desc, &$config_names, $showTable = true, $showSubmit = true, $showExample = true, $spawnNuggets = true, $postKey = 'plugin') {\r
-    global $serendipity;\r
-\r
-    if ($showTable) {\r
-?>\r
-    <table id="serendipity_plugin_config" border="0" cellspacing="0" cellpadding="3" width="100%">\r
-<?php\r
-    }\r
-\r
-    $elcount = 0;\r
-    $htmlnugget = array();\r
-    foreach ($config_names as $config_item) {\r
-        $elcount++;\r
-        $cbag = new serendipity_property_bag;\r
-        $plugin->introspect_config_item($config_item, $cbag);\r
-\r
-        $cname      = htmlspecialchars($cbag->get('name'));\r
-        $cdesc      = htmlspecialchars($cbag->get('description'));\r
-        $value      = $plugin->get_config($config_item, 'unset');\r
-        $lang_direction = htmlspecialchars($cbag->get('lang_direction'));\r
-\r
-        if (empty($lang_direction)) {\r
-            $lang_direction = LANG_DIRECTION;\r
-        }\r
-\r
-        /* Apparently no value was set for this config item */\r
-        if ($value === 'unset') {\r
-            /* Try and the default value for the config item */\r
-            $value = $cbag->get('default');\r
-\r
-            /* Still, we don't have a value, try and get (bool)false - from an old plugin */\r
-            if ($value === '') {\r
-                $value = $plugin->get_config($config_item, false, true);\r
-            }\r
-        }\r
-        \r
-        if (isset($_POST['serendipity'][$postkey][$config_item])) {\r
-            if (is_array($_POST['serendipity'][$postkey][$config_item])) {\r
-                $hvalue = $_POST['serendipity'][$postkey][$config_item];\r
-                array_walk($hvalue, 'htmlspecialchars');\r
-            } else {\r
-                $hvalue = htmlspecialchars($_POST['serendipity'][$postkey][$config_item]);\r
-            }\r
-        } else {\r
-            $hvalue = htmlspecialchars($value);\r
-        }\r
-\r
-        $radio    = array();\r
-        $select   = array();\r
-        $per_row  = null;\r
-\r
-        $is_multi_select = false;\r
-        $ctype    = $cbag->get('type');\r
-        switch ($ctype) {\r
-            case 'seperator':\r
-?>\r
-        <tr>\r
-            <td colspan="2"><hr noshade="noshade" size="1" /></td>\r
-        </tr>\r
-<?php\r
-                break;\r
-\r
-            case 'multiselect':\r
-                $is_multi_select = true;\r
-\r
-            case 'select':\r
-                if (is_array($hvalue)) {\r
-                    $selected_options = $hvalue;\r
-                } elseif ($is_multi_select) {\r
-                    $selected_options = explode('^', $hvalue);\r
-                } else {\r
-                    $selected_options = array($hvalue => $hvalue);\r
-                }\r
-                \r
-                $pre_selected = (array)$cbag->get('select_preselected');\r
-                $select_size  = $cbag->get('select_size');\r
-                $select = $cbag->get('select_values');\r
-?>\r
-        <tr>\r
-            <td style="border-bottom: 1px solid #000000; vertical-align: top"><strong><?php echo $cname; ?></strong>\r
-<?php\r
-    if ($cdesc != '') {\r
-?>\r
-                <br><span  style="color: #5E7A94; font-size: 8pt;">&nbsp;<?php echo $cdesc; ?></span>\r
-<?php } ?>\r
-            </td>\r
-            <td style="border-bottom: 1px solid #000000; vertical-align: middle" width="250">\r
-                <div>\r
-                    <select class="direction_<?php echo $lang_direction; ?>" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]<?php echo ($is_multi_select ? '[]' : ''); ?>" <?php echo ($is_multi_select ? 'multiple="multiple"' : ''); ?> <?php echo ($is_multi_select && $select_size > 0 ? 'size="' . $select_size . '"' : ''); ?>>\r
-<?php\r
-                foreach($select AS $select_value => $select_desc) {\r
-                    $id = htmlspecialchars($config_item . $select_value);\r
-?>\r
-                        <option value="<?php echo $select_value; ?>" <?php echo ( (in_array($select_value, $selected_options) || in_array($select_value, $pre_selected) ) ? 'selected="selected"' : ''); ?> title="<?php echo htmlspecialchars($select_desc); ?>">\r
-                            <?php echo htmlspecialchars($select_desc); ?>\r
-                        </option>\r
-<?php\r
-                }\r
-?>\r
-                    </select>\r
-                </div>\r
-            </td>\r
-        </tr>\r
-<?php\r
-                break;\r
-\r
-            case 'tristate':\r
-                $per_row = 3;\r
-                $radio['value'][] = 'default';\r
-                $radio['desc'][]  = USE_DEFAULT;\r
-\r
-            case 'boolean':\r
-                $radio['value'][] = 'true';\r
-                $radio['desc'][]  = YES;\r
-\r
-                $radio['value'][] = 'false';\r
-                $radio['desc'][]  = NO;\r
-\r
-           case 'radio':\r
-                if (!count($radio) > 0) {\r
-                    $radio = $cbag->get('radio');\r
-                }\r
-\r
-                if (empty($per_row)) {\r
-                    $per_row = $cbag->get('radio_per_row');\r
-                    if (empty($per_row)) {\r
-                        $per_row = 2;\r
-                    }\r
-                }\r
-?>\r
-        <tr>\r
-            <td style="border-bottom: 1px solid #000000; vertical-align: top"><strong><?php echo $cname; ?></strong>\r
-<?php\r
-                if ($cdesc != '') {\r
-?>\r
-                <br /><span  style="color: #5E7A94; font-size: 8pt;">&nbsp;<?php echo $cdesc; ?></span>\r
-<?php\r
-                }\r
-?>\r
-            </td>\r
-            <td style="border-bottom: 1px solid #000000; vertical-align: middle;" width="250">\r
-<?php\r
-                $counter = 0;\r
-                foreach($radio['value'] AS $radio_index => $radio_value) {\r
-                    $id = htmlspecialchars($config_item . $radio_value);\r
-                    $counter++;\r
-                    $checked = "";\r
-\r
-                    if ($radio_value == 'true' && ($hvalue === '1' || $hvalue === 'true')) {\r
-                        $checked = " checked";\r
-                    } elseif ($radio_value == 'false' && ($hvalue === '' || $hvalue === 'false')) {\r
-                        $checked = " checked";\r
-                    } elseif ($radio_value == $hvalue) {\r
-                        $checked = " checked";\r
-                    }\r
-\r
-                    if ($counter == 1) {\r
-?>\r
-                <div>\r
-<?php\r
-                    }\r
-?>\r
-                    <input class="direction_<?php echo $lang_direction; ?>" type="radio" id="serendipity_plugin_<?php echo $id; ?>" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]" value="<?php echo $radio_value; ?>" <?php echo $checked ?> title="<?php echo htmlspecialchars($radio['desc'][$radio_index]); ?>" />\r
-                        <label for="serendipity_plugin_<?php echo $id; ?>"><?php echo htmlspecialchars($radio['desc'][$radio_index]); ?></label>\r
-<?php\r
-                    if ($counter == $per_row) {\r
-                        $counter = 0;\r
-?>\r
-                </div>\r
-<?php\r
-                    }\r
-                }\r
-?>\r
-            </td>\r
-        </tr>\r
-<?php\r
-                break;\r
-\r
-            case 'string':\r
-?>\r
-        <tr>\r
-            <td style="border-bottom: 1px solid #000000">\r
-                    <strong><?php echo $cname; ?></strong>\r
-                    <br><span style="color: #5E7A94; font-size: 8pt;">&nbsp;<?php echo $cdesc; ?></span>\r
-            </td>\r
-            <td style="border-bottom: 1px solid #000000" width="250">\r
-                <div>\r
-                    <input class="direction_<?php echo $lang_direction; ?>" type="text" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]" value="<?php echo $hvalue; ?>" size="30" />\r
-                </div>\r
-            </td>\r
-        </tr>\r
-<?php\r
-                break;\r
-\r
-            case 'html':\r
-            case 'text':\r
-?>\r
-        <tr>\r
-            <td colspan="2"><strong><?php echo $cname; ?></strong>\r
-                &nbsp;<span style="color: #5E7A94; font-size: 8pt;">&nbsp;<?php echo $cdesc; ?></span>\r
-            </td>\r
-        </tr>\r
-\r
-        <tr>\r
-            <td colspan="2">\r
-                <div>\r
-                    <textarea class="direction_<?php echo $lang_direction; ?>" style="width: 100%" id="nuggets<?php echo $elcount; ?>" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]" rows="20" cols="80"><?php echo $hvalue; ?></textarea>\r
-                </div>\r
-            </td>\r
-        </tr>\r
-<?php\r
-                if ($cbag->get('type') == 'html') {\r
-                    $htmlnugget[] = $elcount;\r
-                    serendipity_emit_htmlarea_code('nuggets', 'nuggets', true);\r
-                }\r
-                break;\r
-\r
-            case 'content':\r
-                ?><tr><td colspan="2"><?php echo $cbag->get('default'); ?></td></tr><?php\r
-                break;\r
-\r
-            case 'hidden':\r
-                ?><tr><td colspan="2"><input class="direction_<?php echo $lang_direction; ?>" type="hidden" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]" value="<?php echo $cbag->get('value'); ?>" /></td></tr><?php\r
-                break;\r
-            \r
-            default:\r
-                // Unknown configuration key. Let the plugin handle it.\r
-                $addData = func_get_args();\r
-                $eventData = array(\r
-                    'config_item' => $config_item,\r
-                    'cbag'        => $cbag,\r
-                    'plugin'      => $plugin,\r
-                    'value'       => $value,\r
-                    'bag'         => $bag,\r
-                    'postKey'     => $postKey\r
-                );\r
-                serendipity_plugin_api::hook_event('backend_pluginconfig_' . $ctype, $eventData, $addData);\r
-                break;\r
-        }\r
-    }\r
-\r
-    if ($showTable) {\r
-?>\r
-    </table>\r
-<br />\r
-<?php\r
-    }\r
-    \r
-    if ($showSubmit) { \r
-?>\r
-    <div style="padding-left: 20px">\r
-        <input type="submit" name="SAVECONF" value="<?php echo SAVE; ?>" class="serendipityPrettyButton" />\r
-    </div>\r
-<?php\r
-    }\r
-\r
-    if ($showExample && method_exists($plugin, 'example') ) {\r
-?>\r
-    <div>\r
-        <?php echo $plugin->example() ?>\r
-    </div>\r
-<?php\r
-    }\r
-\r
-    if ($spawnNuggets && isset($serendipity['wysiwyg']) && $serendipity['wysiwyg'] && count($htmlnugget) > 0) {\r
-        $ev = array('nuggets' => $htmlnugget, 'skip_nuggets' => false);\r
-        serendipity_plugin_api::hook_event('backend_wysiwyg_nuggets', $ev);\r
-\r
-        if ($ev['skip_nuggets'] === false) {\r
-?>\r
-    <script type="text/javascript">\r
-    function Spawnnugget() {\r
-        <?php foreach($htmlnugget AS $htmlnuggetid) { ?>\r
-        Spawnnuggets('<?php echo $htmlnuggetid; ?>');\r
-        <?php } ?>\r
-    }\r
-    </script>\r
-<?php\r
-        }\r
-    }\r
-    \r
-    return true;\r
-}\r
+<?php # $Id: functions_entries.inc.php 435 2005-08-25 12:36:39Z garvinhicking $
+# Copyright (c) 2003-2005, Jannis Hermanns (on behalf the Serendipity Developer Team)
+# All rights reserved.  See LICENSE file for licensing details
+
+
+if (defined('S9Y_FRAMEWORK_PLUGINS_ADMIN')) {
+    return;
+}
+@define('S9Y_FRAMEWORK_PLUGINS_ADMIN', true);
+
+/**
+ * Returns the name of a usergroup.
+ *
+ * If a special constant is defined for the name of the group, the name has been
+ * internationalized. This applies to the Admin/Chief Editor/Editor group names,
+ * which are different for each language. If such a constant is not present,
+ * the simple name of the group will be returned.
+ *
+ * @access public
+ * @param  string  name of the group
+ * @return string  realname of the group
+ */
+function serendipity_groupname($group) {
+    if (defined('PLUGIN_GROUP_' . $group)) {
+        return constant('PLUGIN_GROUP_' . $group);
+    } else {
+        return $group;
+    }
+}
+
+/**
+ * Sort the pluginlist by case-insensitive string functions
+ *
+ * @access public
+ * @param  array    Compared Plugin #1
+ * @param  array    Compared Plugin #2
+ * @return boolean  Return code for array comparison
+ */
+function serendipity_pluginListSort($x, $y) {
+    return strnatcasecmp($x['name'] . ' - ' . $x['description'], $y['name'] . ' - ' . $y['description']);
+}
+
+/**
+ * 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;
+
+    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;
+            }
+        }
+    }
+
+    $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) {
+        echo '<td class="pluginmanager_side">';
+        echo '<div class="heading">' . $opts[$plugin_placement] . '</div>';
+        echo '<ol id="' . $plugin_placement . '_col" class="pluginmanager_container">';
+        $plugins = serendipity_plugin_api::enum_plugins($plugin_placement);
+
+        if (!is_array($plugins)) {
+            continue;
+        }
+
+        $sort_idx = 0;
+        foreach ($plugins as $plugin_data) {
+            $total++;
+            $plugin  =& serendipity_plugin_api::load_plugin($plugin_data['name'], $plugin_data['authorid']);
+            $key     = urlencode($plugin_data['name']);
+            $css_key = 's9ycid' . str_replace('%', '-', $key);
+            $is_plugin_owner    = ($plugin_data['authorid'] == $serendipity['authorid'] || serendipity_checkPermission('adminPluginsMaintainOthers'));
+            $is_plugin_editable = ($is_plugin_owner || $plugin_data['authorid'] == '0');
+
+            if (!is_object($plugin)) {
+                $name = $title = ERROR . '!';
+                $desc          = ERROR . ': ' . $plugin_data['name'];
+                $can_configure = false;
+            } else {
+                /* query for its name, description and configuration data */
+
+                $bag = new serendipity_property_bag;
+                $plugin->introspect($bag);
+
+                $name  = htmlspecialchars($bag->get('name'));
+                $desc  = htmlspecialchars($bag->get('description'));
+                $desc .= '<br />' . VERSION  . ': <em>' . $bag->get('version') . '</em>';
+
+                $title = serendipity_plugin_api::get_plugin_title($plugin, '[' . $name . ']');
+
+                if ($bag->is_set('configuration') && ($plugin->protected === FALSE || $plugin_data['authorid'] == '0' || $plugin_data['authorid'] == $serendipity['authorid'] || serendipity_checkPermission('adminPluginsMaintainOthers'))) {
+                    $can_configure = true;
+                } else {
+                    $can_configure = false;
+                }
+            }
+
+            if ($event_only) {
+                $place = placement_box('serendipity[placement][' . $plugin_data['name'] . ']', $plugin_data['placement'], $is_plugin_editable, true, $opts);
+                $event_only_uri = '&amp;serendipity[event_plugin]=true';
+            } else {
+                $place = placement_box('serendipity[placement][' . $plugin_data['name'] . ']', $plugin_data['placement'], $is_plugin_editable, false, $opts);
+                $event_only_uri = '';
+            }
+
+            /* Only display UP/DOWN links if there's somewhere for the plugin to go */
+            if ($sort_idx == 0) {
+                $moveup   = '&nbsp;';
+            } else {
+                $moveup   = '<a href="?' . serendipity_setFormToken('url') . '&amp;serendipity[adminModule]=plugins&amp;submit=move+up&amp;serendipity[plugin_to_move]=' . $key . $event_only_uri . '" style="border: 0"><img src="' . serendipity_getTemplateFile('admin/img/uparrow.png') .'" height="16" width="16" border="0" alt="' . UP . '" /></a>';
+            }
+
+            if ($sort_idx == (count($plugins)-1)) {
+                $movedown = '&nbsp;';
+            } else {
+                $movedown = ($moveup != '' ? '&nbsp;' : '') . '<a href="?' . serendipity_setFormToken('url') . '&amp;serendipity[adminModule]=plugins&amp;submit=move+down&amp;serendipity[plugin_to_move]=' . $key . $event_only_uri . '" style="border: 0"><img src="' . serendipity_getTemplateFile('admin/img/downarrow.png') . '" height="16" width="16" alt="'. DOWN .'" border="0" /></a>';
+            }
+?>
+            <li class="pluginmanager_item_<?php echo ($sort_idx % 2 ? 'even' : 'uneven'); ?>" id="<?php echo $css_key; ?>">
+                <div id="g<?php echo $css_key; ?>" class="pluginmanager_grablet">
+                    <a href="#" id="grab<?php echo $css_key; ?>"></a>
+                </div>
+                <?php if ($is_plugin_editable) { ?>
+                    <input type="checkbox" name="serendipity[plugin_to_remove][]" value="<?php echo $plugin_data['name']; ?>" />
+                <?php } ?>
+
+                <?php if ( $can_configure ) { ?>
+                    <a class="pluginmanager_configure" href="?serendipity[adminModule]=plugins&amp;serendipity[plugin_to_conf]=<?php echo $key ?>"><img src="<?php echo serendipity_getTemplateFile('admin/img/configure.png') ?>" style="border: 0; vertical-align: bottom;" alt="[C]" /></a>
+                <?php } ?>
+
+                    <span class="pluginmanager_title">
+                <?php if ( $can_configure ) { ?>
+                    <a href="?serendipity[adminModule]=plugins&amp;serendipity[plugin_to_conf]=<?php echo $key ?>"><?php echo $title; ?></a>
+                <?php } else { ?>
+                    <?php echo $title; ?>
+                <?php } ?></span><br />
+                    <div class="pluginmanager_description" style="font-size: 8pt"><?php echo $desc; ?></div>
+                    <div class="pluginmanager_ownership"><?php ownership($plugin_data['authorid'], $plugin_data['name'], $is_plugin_owner); ?></div>
+                    <?php echo ($eyecandy ? '<noscript>' : ''); ?>
+                    <div class="pluginmanager_place"><?php echo $place; ?></div>
+                    <div class="pluginmanager_move"><?php echo $moveup ?> <?php echo $movedown ?></div>
+                    <?php echo ($eyecandy ? '</noscript>' : ''); ?>
+            </li>
+<?php
+            $sort_idx++;
+        }
+
+        echo '</ol></td>';
+    }
+
+?>
+        </tr>
+        <tr>
+            <td colspan="3" align="right"><?php printf(PLUGIN_AVAILABLE_COUNT, $total); ?></td>
+        </tr>
+        </table>
+        <br />
+        <div>
+            <input type="submit" name="REMOVE" title="<?php echo DELETE; ?>"  value="<?php echo REMOVE_TICKED_PLUGINS; ?>" class="serendipityPrettyButton" />
+            <input type="submit" name="SAVE"   title="<?php echo SAVE_CHANGES_TO_LAYOUT; ?>" value="<?php echo SAVE; ?>" class="serendipityPrettyButton" />
+        </div>
+</form>
+<?php
+}
+
+/**
+ * Returns HTML code for the ownership column of the plugin listing
+ *
+ * Used by the function show_plugins()
+ *
+ * @access  private
+ * @see     show_plugins()
+ * @param   int     ID of the current user
+ * @param   string  plugin name
+ * @param   boolean Toggle whether the plugin belongs to the current author
+ * @return  null
+ */
+function ownership($authorid, $name, $is_plugin_owner = false) {
+    global $serendipity;
+
+    static $users = array();
+    if (empty($users)) {
+        $users = serendipity_fetchUsers();
+    }
+
+    if ($is_plugin_owner) {
+?>
+<select name="serendipity[ownership][<?php echo $name; ?>]">
+    <option value="0"><?php echo ALL_AUTHORS; ?></option>
+<?php
+    }
+
+    foreach($users AS $user) {
+        if (!$is_plugin_owner && $user['authorid'] == $authorid) {
+            $realname = htmlspecialchars($user['realname']);
+        } elseif ($is_plugin_owner) {
+?>
+    <option value="<?php echo $user['authorid']; ?>"<?php echo ($user['authorid'] == $authorid ? ' selected="selected"' : ''); ?>><?php echo htmlspecialchars($user['realname']); ?></option>
+<?php
+        }
+    }
+
+    if ($is_plugin_owner) {
+?>
+</select>
+<?php
+    } else {
+        echo (empty($realname) ? ALL_AUTHORS : $realname);
+    }
+}
+
+/**
+ * Show a placement box on where to move a sidebar plugin to
+ *
+ * @access private
+ * @see    show_plugins()
+ * @param  string   plugin name
+ * @param  string   current position of the plugin
+ * @param  boolean  Toggle whether a plugin is editable (depends on authorid and permissions)
+ * @param  boolean  Toggle whether a plugin is an event plugin
+ * @return string   HTML code for placement select box
+ */
+function placement_box($name, $val, $is_plugin_editable = false, $is_event = false, $opts = null)
+{
+    if ($opts === null) {
+        $opts = array(
+            'left'  => LEFT,
+            'right' => RIGHT,
+            'hide'  => HIDDEN
+        );
+    }
+
+    static $event_opts = array(
+                    'event'     => PLUGIN_ACTIVE,
+                    'eventh' => PLUGIN_INACTIVE,
+    );
+
+    if ($is_event) {
+        $gopts =& $event_opts;
+    } else {
+        $gopts =& $opts;
+    }
+
+    $x = "\n<select name=\"$name\">\n";
+    foreach ($gopts as $k => $v) {
+        if (!$is_plugin_editable && $k == 'hide') {
+            continue;
+        }
+
+        $x .= "    <option value=\"$k\"" . ($k == $val ? ' selected="selected"' : '') . ">$v</option>\n";
+    }
+    return $x . "</select>\n";
+}
+
+/**
+ * Show a placement box on where to move a sidebar plugin to
+ *
+ * @access public
+ * @param  object   A plugin object
+ * @param  object   The plugins property bag object
+ * @param  string   The name of the plugin
+ * @param  string   The description of the plugin
+ * @param  array    The property bag 'configuration' array, holding the array of config items.
+ * @param  boolean  Shows the surrounding HTML table?
+ * @param  boolean  Shows the FORM submit button?
+ * @param  boolean  Shows a plugin's "example" method output?
+ * @param  boolean  Spawn a plugins' configuration WYSIWYG items?
+ * @param  string   The array index name of POSTed values ($serendipity['POST'][xxx])
+ * @return boolean
+ */
+function serendipity_plugin_config(&$plugin, &$bag, &$name, &$desc, &$config_names, $showTable = true, $showSubmit = true, $showExample = true, $spawnNuggets = true, $postKey = 'plugin') {
+    global $serendipity;
+
+    if ($showTable) {
+?>
+    <table id="serendipity_plugin_config" border="0" cellspacing="0" cellpadding="3" width="100%">
+<?php
+    }
+
+    $elcount = 0;
+    $htmlnugget = array();
+    foreach ($config_names as $config_item) {
+        $elcount++;
+        $cbag = new serendipity_property_bag;
+        $plugin->introspect_config_item($config_item, $cbag);
+
+        $cname      = htmlspecialchars($cbag->get('name'));
+        $cdesc      = htmlspecialchars($cbag->get('description'));
+        $value      = $plugin->get_config($config_item, 'unset');
+        $lang_direction = htmlspecialchars($cbag->get('lang_direction'));
+
+        if (empty($lang_direction)) {
+            $lang_direction = LANG_DIRECTION;
+        }
+
+        /* Apparently no value was set for this config item */
+        if ($value === 'unset') {
+            /* Try and the default value for the config item */
+            $value = $cbag->get('default');
+
+            /* Still, we don't have a value, try and get (bool)false - from an old plugin */
+            if ($value === '') {
+                $value = $plugin->get_config($config_item, false, true);
+            }
+        }
+
+        if (isset($_POST['serendipity'][$postkey][$config_item])) {
+            if (is_array($_POST['serendipity'][$postkey][$config_item])) {
+                $hvalue = $_POST['serendipity'][$postkey][$config_item];
+                array_walk($hvalue, 'htmlspecialchars');
+            } else {
+                $hvalue = htmlspecialchars($_POST['serendipity'][$postkey][$config_item]);
+            }
+        } else {
+            $hvalue = htmlspecialchars($value);
+        }
+
+        $radio    = array();
+        $select   = array();
+        $per_row  = null;
+
+        $is_multi_select = false;
+        $ctype    = $cbag->get('type');
+        switch ($ctype) {
+            case 'seperator':
+?>
+        <tr>
+            <td colspan="2"><hr noshade="noshade" size="1" /></td>
+        </tr>
+<?php
+                break;
+
+            case 'multiselect':
+                $is_multi_select = true;
+
+            case 'select':
+                if (is_array($hvalue)) {
+                    $selected_options = $hvalue;
+                } elseif ($is_multi_select) {
+                    $selected_options = explode('^', $hvalue);
+                } else {
+                    $selected_options = array($hvalue => $hvalue);
+                }
+
+                $pre_selected = (array)$cbag->get('select_preselected');
+                $select_size  = $cbag->get('select_size');
+                $select = $cbag->get('select_values');
+?>
+        <tr>
+            <td style="border-bottom: 1px solid #000000; vertical-align: top"><strong><?php echo $cname; ?></strong>
+<?php
+    if ($cdesc != '') {
+?>
+                <br><span  style="color: #5E7A94; font-size: 8pt;">&nbsp;<?php echo $cdesc; ?></span>
+<?php } ?>
+            </td>
+            <td style="border-bottom: 1px solid #000000; vertical-align: middle" width="250">
+                <div>
+                    <select class="direction_<?php echo $lang_direction; ?>" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]<?php echo ($is_multi_select ? '[]' : ''); ?>" <?php echo ($is_multi_select ? 'multiple="multiple"' : ''); ?> <?php echo ($is_multi_select && $select_size > 0 ? 'size="' . $select_size . '"' : ''); ?>>
+<?php
+                foreach($select AS $select_value => $select_desc) {
+                    $id = htmlspecialchars($config_item . $select_value);
+?>
+                        <option value="<?php echo $select_value; ?>" <?php echo ( (in_array($select_value, $selected_options) || in_array($select_value, $pre_selected) ) ? 'selected="selected"' : ''); ?> title="<?php echo htmlspecialchars($select_desc); ?>">
+                            <?php echo htmlspecialchars($select_desc); ?>
+                        </option>
+<?php
+                }
+?>
+                    </select>
+                </div>
+            </td>
+        </tr>
+<?php
+                break;
+
+            case 'tristate':
+                $per_row = 3;
+                $radio['value'][] = 'default';
+                $radio['desc'][]  = USE_DEFAULT;
+
+            case 'boolean':
+                $radio['value'][] = 'true';
+                $radio['desc'][]  = YES;
+
+                $radio['value'][] = 'false';
+                $radio['desc'][]  = NO;
+
+           case 'radio':
+                if (!count($radio) > 0) {
+                    $radio = $cbag->get('radio');
+                }
+
+                if (empty($per_row)) {
+                    $per_row = $cbag->get('radio_per_row');
+                    if (empty($per_row)) {
+                        $per_row = 2;
+                    }
+                }
+?>
+        <tr>
+            <td style="border-bottom: 1px solid #000000; vertical-align: top"><strong><?php echo $cname; ?></strong>
+<?php
+                if ($cdesc != '') {
+?>
+                <br /><span  style="color: #5E7A94; font-size: 8pt;">&nbsp;<?php echo $cdesc; ?></span>
+<?php
+                }
+?>
+            </td>
+            <td style="border-bottom: 1px solid #000000; vertical-align: middle;" width="250">
+<?php
+                $counter = 0;
+                foreach($radio['value'] AS $radio_index => $radio_value) {
+                    $id = htmlspecialchars($config_item . $radio_value);
+                    $counter++;
+                    $checked = "";
+
+                    if ($radio_value == 'true' && ($hvalue === '1' || $hvalue === 'true')) {
+                        $checked = " checked";
+                    } elseif ($radio_value == 'false' && ($hvalue === '' || $hvalue === 'false')) {
+                        $checked = " checked";
+                    } elseif ($radio_value == $hvalue) {
+                        $checked = " checked";
+                    }
+
+                    if ($counter == 1) {
+?>
+                <div>
+<?php
+                    }
+?>
+                    <input class="direction_<?php echo $lang_direction; ?>" type="radio" id="serendipity_plugin_<?php echo $id; ?>" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]" value="<?php echo $radio_value; ?>" <?php echo $checked ?> title="<?php echo htmlspecialchars($radio['desc'][$radio_index]); ?>" />
+                        <label for="serendipity_plugin_<?php echo $id; ?>"><?php echo htmlspecialchars($radio['desc'][$radio_index]); ?></label>
+<?php
+                    if ($counter == $per_row) {
+                        $counter = 0;
+?>
+                </div>
+<?php
+                    }
+                }
+?>
+            </td>
+        </tr>
+<?php
+                break;
+
+            case 'string':
+?>
+        <tr>
+            <td style="border-bottom: 1px solid #000000">
+                    <strong><?php echo $cname; ?></strong>
+                    <br><span style="color: #5E7A94; font-size: 8pt;">&nbsp;<?php echo $cdesc; ?></span>
+            </td>
+            <td style="border-bottom: 1px solid #000000" width="250">
+                <div>
+                    <input class="direction_<?php echo $lang_direction; ?>" type="text" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]" value="<?php echo $hvalue; ?>" size="30" />
+                </div>
+            </td>
+        </tr>
+<?php
+                break;
+
+            case 'html':
+            case 'text':
+?>
+        <tr>
+            <td colspan="2"><strong><?php echo $cname; ?></strong>
+                &nbsp;<span style="color: #5E7A94; font-size: 8pt;">&nbsp;<?php echo $cdesc; ?></span>
+            </td>
+        </tr>
+
+        <tr>
+            <td colspan="2">
+                <div>
+                    <textarea class="direction_<?php echo $lang_direction; ?>" style="width: 100%" id="nuggets<?php echo $elcount; ?>" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]" rows="20" cols="80"><?php echo $hvalue; ?></textarea>
+                </div>
+            </td>
+        </tr>
+<?php
+                if ($cbag->get('type') == 'html') {
+                    $htmlnugget[] = $elcount;
+                    serendipity_emit_htmlarea_code('nuggets', 'nuggets', true);
+                }
+                break;
+
+            case 'content':
+                ?><tr><td colspan="2"><?php echo $cbag->get('default'); ?></td></tr><?php
+                break;
+
+            case 'custom':
+                ?><tr><td colspan="2">
+                    <input type="hidden" id="config_<?php echo $postKey; ?>_<?php echo $config_item; ?>" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]" value="<?php echo $hvalue; ?>" size="30" />
+                    <?php echo $cbag->get('custom'); ?>
+                  </td></tr><?php
+                break;
+
+            case 'hidden':
+                ?><tr><td colspan="2"><input class="direction_<?php echo $lang_direction; ?>" type="hidden" name="serendipity[<?php echo $postKey; ?>][<?php echo $config_item; ?>]" value="<?php echo $cbag->get('value'); ?>" /></td></tr><?php
+                break;
+
+            default:
+                // Unknown configuration key. Let the plugin handle it.
+                $addData = func_get_args();
+                $eventData = array(
+                    'config_item' => $config_item,
+                    'cbag'        => $cbag,
+                    'plugin'      => $plugin,
+                    'value'       => $value,
+                    'bag'         => $bag,
+                    'postKey'     => $postKey
+                );
+                serendipity_plugin_api::hook_event('backend_pluginconfig_' . $ctype, $eventData, $addData);
+                break;
+        }
+    }
+
+    if ($showTable) {
+?>
+    </table>
+<br />
+<?php
+    }
+
+    if ($showSubmit) {
+?>
+    <div style="padding-left: 20px">
+        <input type="submit" name="SAVECONF" value="<?php echo SAVE; ?>" class="serendipityPrettyButton" />
+    </div>
+<?php
+    }
+
+    if ($showExample && method_exists($plugin, 'example') ) {
+?>
+    <div>
+        <?php echo $plugin->example() ?>
+    </div>
+<?php
+    }
+
+    if ($spawnNuggets && isset($serendipity['wysiwyg']) && $serendipity['wysiwyg'] && count($htmlnugget) > 0) {
+        $ev = array('nuggets' => $htmlnugget, 'skip_nuggets' => false);
+        serendipity_plugin_api::hook_event('backend_wysiwyg_nuggets', $ev);
+
+        if ($ev['skip_nuggets'] === false) {
+?>
+    <script type="text/javascript">
+    function Spawnnugget() {
+        <?php foreach($htmlnugget AS $htmlnuggetid) { ?>
+        Spawnnuggets('<?php echo $htmlnuggetid; ?>');
+        <?php } ?>
+    }
+    </script>
+<?php
+        }
+    }
+
+    return true;
+}