Version 0.9 ()
------------------------------------------------------------------------
+ * Templates can now be handled via Spartacus (garvinhicking)
+
+ * Plugin Manager: Improve Spartacus interface and include plugin
+ categories (garvinhicking)
+
* Support different WYSIWYG editors via new plugin hooks. TinyMCE
plugin available. (garvinhicking)
that within templates you can still use the $CONST shortcut
(garvinhicking)
- * Pagination of plugins to install to save memory allocation if many
- plugins are downloaded (garvinhicking)
-
* Added new event hook to the trackback sending facility so that
plugins like serendipity_event_trackback (additional_plugins)
can send trackbacks to Blogs without RDF-metadata (garvinhicking)
include_once S9Y_INCLUDE_PATH . 'include/plugin_api.inc.php';
include_once S9Y_INCLUDE_PATH . 'include/plugin_internal.inc.php';
+function serendipity_groupname($group) {
+ if (defined('PLUGIN_GROUP_' . $group)) {
+ return constant('PLUGIN_GROUP_' . $group);
+ } else {
+ return $group;
+ }
+}
+
function serendipity_pluginListSort($x, $y) {
- return strnatcasecmp($x['name'] . ' - ' . $x['desc'], $y['name'] . ' - ' . $y['desc']);
+ return strnatcasecmp($x['name'] . ' - ' . $x['description'], $y['name'] . ' - ' . $y['description']);
}
function show_plugins($event_only = false)
foreach($select AS $select_value => $select_desc) {
$id = htmlspecialchars($config_item . $select_value);
?>
- <option value="<?php echo $select_value; ?>" <?php echo ($select_value == $hvalue ? 'selected="selected"' : ''); ?> title="<?php echo htmlspecialchars($select_desc); ?>" />
+ <option value="<?php echo $select_value; ?>" <?php echo ($select_value == $hvalue ? 'selected="selected"' : ''); ?> title="<?php echo htmlspecialchars($select_desc); ?>">
<?php echo htmlspecialchars($select_desc); ?>
</option>
<?php
<?php } else { ?>
<h2><?php echo SIDEBAR_PLUGINS ?></h2>
<?php } ?>
-<?php echo SELECT_A_PLUGIN_TO_ADD; ?>
-<br />
<br />
<?php
- $foreignPlugins = array();
+ $foreignPlugins = $pluginstack = $errorstack = array();
serendipity_plugin_api::hook_event('backend_plugins_fetchlist', $foreignPlugins);
-?>
-<table cellspacing="0" cellpadding="0" border="0" width="100%">
- <tr>
- <td><strong>Plugin</strong></td>
- <td width="100" align="center"><strong>Action</strong></td>
- </tr>
-<?php
- $plugin_navigation = '';
+ $pluginstack = array_merge($foreignPlugins['pluginstack'], $pluginstack);
+ $errorstack = array_merge($foreignPlugins['errorstack'], $errorstack);
- if (count($foreignPlugins) > 0) {
- $pluginstack = $foreignPlugins['pluginstack'];
- $errorstack = $foreignPlugins['errorstack'];
- } else {
- $pluginsPerPage = 45;
- $currentPage = (int)(!empty($serendipity['GET']['page']) ? $serendipity['GET']['page'] : 1);
- $countStart = ($currentPage-1) * $pluginsPerPage;
- $countEnd = ($currentPage) * $pluginsPerPage;
-
- $plugins = serendipity_plugin_api::get_installed_plugins();
-
- $errorstack = $pluginstack = array();
- $classes = serendipity_plugin_api::enum_plugin_classes(($serendipity['GET']['type'] == 'event'));
- // TODO: With pagination of the plugins we cannot get the localized title of the plugins before sorting it.
- // This means we get a weird order of the plugins. We need to find a way
- // to do the sorting on the real plugin name WITHOUT loading ALL dozen plugins
- usort($classes, 'serendipity_pluginListSort');
-
- $maxPage = ceil(count($classes)/$pluginsPerPage);
- $plugin_navigation = '<tr><td colspan="2" align="center">' . sprintf(PAGE_BROWSE_PLUGINS, $currentPage, $maxPage, count($classes)) . '<br />';
- $plugin_pages = array();
- for ($i = 1; $i <= $maxPage; $i++) {
- $plugin_page = '';
- if ($i == $currentPage) {
- $plugin_page .= '<strong>';
- }
+ $plugins = serendipity_plugin_api::get_installed_plugins();
+ $classes = serendipity_plugin_api::enum_plugin_classes(($serendipity['GET']['type'] == 'event'));
+ usort($classes, 'serendipity_pluginListSort');
- $plugin_page .= '<a href="?serendipity[adminModule]=plugins&serendipity[adminAction]=addnew&serendipity[type]=' . $serendipity['GET']['type'] . '&serendipity[page]=' . $i . '">' . $i . '</a>';
+ $counter = 0;
+ foreach ($classes as $class_data) {
- if ($i == $currentPage) {
- $plugin_page .= '</strong>';
- }
-
- $plugin_pages[] = $plugin_page;
- }
- $plugin_navigation .= implode(' | ', $plugin_pages);
-
- echo $plugin_navigation;
+ $pluginFile = serendipity_plugin_api::probePlugin($class_data['name'], $class_data['classname'], $class_data['pluginPath']);
+ $plugin =& serendipity_plugin_api::getPluginInfo($pluginFile, $class_data, $serendipity['GET']['type']);
- $counter = 0;
- foreach ($classes as $class_data) {
+ if (is_object($plugin)) {
+ // Object is returned when a plugin could not be cached.
+ $bag = new serendipity_property_bag;
+ $plugin->introspect($bag);
+ $props = serendipity_plugin_api::setPluginInfo($plugin, $pluginFile, $bag, $class_data);
$counter++;
-
- if ($counter < $countStart || $counter > $countEnd) {
- continue;
- }
-
- $plugin =& serendipity_plugin_api::load_plugin($class_data['name'], null, $class_data['pluginPath']);
- if (is_object($plugin)) {
- $bag = new serendipity_property_bag;
- $plugin->introspect($bag);
- $pluginstack[] = array('plugin_class' => $class_data['name'],
- 'class_name' => get_class($plugin),
- 'name' => $bag->get('name'),
- 'desc' => $bag->get('description'),
- 'installable' => !($bag->get('stackable') === false && in_array($class_data['name'], $plugins)),
- 'author' => $bag->get('author'),
- 'version' => $bag->get('version'),
- 'requirements' => $bag->get('requirements'),
- 'website' => $bag->get('website'),
- 'pluginPath' => $class_data['pluginPath']);
- } else {
- $errorstack[] = $class_data['name'];
+ } elseif (is_array($plugin)) {
+ // Array is returned if a plugin could be fetched from info cache
+ $props = $plugin;
+ } else {
+ $props = false;
+ }
+
+ if (is_array($props)) {
+ $props['installable'] = !($props['stackable'] === false && in_array($class_data['true_name'], $plugins));
+ $props['requirements'] = unserialize($props['requirements']);
+
+ $pluginstack[$class_data['true_name']] = $props;
+ } else {
+ // False is returned if a plugin could not be instantiated
+ $errorstack[] = $class_data['true_name'];
+ }
+ }
+
+ usort($pluginstack, 'serendipity_pluginListSort');
+ $pluggroups = array();
+ $pluggroups[''] = array();
+ foreach($pluginstack AS $plugname => $plugdata) {
+ if (is_array($plugdata['groups'])) {
+ foreach($plugdata['groups'] AS $group) {
+ $pluggroups[$group][] = $plugdata;
}
+ } else {
+ $pluggroups[''][] = $plugdata;
}
}
+ ksort($pluggroups);
- usort($pluginstack, 'serendipity_pluginListSort');
foreach($errorstack as $e_idx => $e_name) {
echo ERROR . ': ' . $e_name . '<br />';
}
-
- foreach ($pluginstack as $plug) {
- $jsLine = " onmouseout=\"document.getElementById('serendipity_plugin_". $plug['class_name'] ."').className='';\"";
- $jsLine .= " onmouseover=\"document.getElementById('serendipity_plugin_". $plug['class_name'] ."').className='serendipity_admin_list_item_uneven';\"";
-
- $pluginInfo = $notice = array();
- if (!empty($plug['author'])) {
- $pluginInfo[] = AUTHOR . ': ' . $plug['author'];
- }
-
- if (!empty($plug['version'])) {
- $pluginInfo[] = VERSION . ': ' . $plug['version'];
- }
-
- if (!empty($plug['upgrade_version'])) {
- $pluginInfo[] = sprintf(UPGRADE_TO_VERSION, $plug['upgrade_version']);
- }
-
- if (!isset($plug['customURI'])) {
- $plug['customURI'] = '';
- }
-
- if ( !empty($plug['requirements']['serendipity']) && version_compare($plug['requirements']['serendipity'], serendipity_getCoreVersion($serendipity['version']), '>') ) {
- $notice['requirements_failures'][] = 's9y ' . $plug['requirements']['serendipity'];
- }
-
- if ( !empty($plug['requirements']['php']) && version_compare($plug['requirements']['php'], phpversion(), '>') ) {
- $notice['requirements_failures'][] = 'PHP ' . $plug['requirements']['php'];
- }
-
- /* Enable after Smarty 2.6.7 upgrade.
- * TODO: How can we get current Smarty version here? $smarty is not created!
- if ( !empty($plug['requirements']['smarty']) && version_compare($plug['requirements']['smarty'], '2.6.7', '>') ) {
- $notice['requirements_failures'][] = 'Smarty: ' . $plug['requirements']['smarty'];
- }
- */
-
- if (count($notice['requirements_failures']) > 0) {
- $plug['requirements_fail'] = true;
+?>
+<table cellspacing="0" cellpadding="0" border="0" width="100%">
+<?php
+ $available_groups = array_keys($pluggroups);
+ foreach($pluggroups AS $pluggroup => $groupstack) {
+ if (empty($pluggroup)) {
+ ?>
+ <tr>
+ <td colspan="2" class="serendipity_pluginlist_header">
+ <form action="serendipity_admin.php" method="get">
+ <input type="hidden" name="serendipity[adminModule]" value="plugins" />
+ <input type="hidden" name="serendipity[adminAction]" value="addnew" />
+ <input type="hidden" name="serendipity[type]" value="<?php echo htmlspecialchars($serendipity['GET']['type']); ?>" />
+ <?php echo FILTERS; ?>: <select name="serendipity[only_group]">
+ <?php foreach((array)$available_groups AS $available_group) {
+ ?>
+ <option value="<?php echo $available_group; ?>" <?php echo ($serendipity['GET']['only_group'] == $available_group ? 'selected="selected"' : ''); ?>><?php echo serendipity_groupname($available_group); ?>
+ <?php } ?>
+ </select>
+ <input type="submit" value="<?php echo GO; ?>" />
+ </form>
+ </td>
+ </tr>
+ <?php
+ if (!empty($serendipity['GET']['only_group'])) {
+ continue;
+ }
+ } elseif (!empty($serendipity['GET']['only_group']) && $pluggroup != $serendipity['GET']['only_group']) {
+ continue;
+ } else {
+ ?>
+ <tr>
+ <td colspan="2" class="serendipity_pluginlist_section"><strong><?php echo serendipity_groupname($pluggroup); ?></strong></td>
+ </tr>
+ <?php
}
+?>
+ <tr>
+ <td><strong>Plugin</strong></td>
+ <td width="100" align="center"><strong>Action</strong></td>
+ </tr>
+<?php
+ foreach ($groupstack as $plug) {
+ $jsLine = " onmouseout=\"document.getElementById('serendipity_plugin_". $plug['class_name'] ."').className='';\"";
+ $jsLine .= " onmouseover=\"document.getElementById('serendipity_plugin_". $plug['class_name'] ."').className='serendipity_admin_list_item_uneven';\"";
+
+ $pluginInfo = $notice = array();
+ if (!empty($plug['author'])) {
+ $pluginInfo[] = AUTHOR . ': ' . $plug['author'];
+ }
+
+ if (!empty($plug['version'])) {
+ $pluginInfo[] = VERSION . ': ' . $plug['version'];
+ }
+
+ if (!empty($plug['upgrade_version']) && $plug['upgrade_version'] != $plug['version']) {
+ $pluginInfo[] = sprintf(UPGRADE_TO_VERSION, $plug['upgrade_version']);
+ }
+
+ if (!empty($plug['pluginlocation']) && $plug['pluginlocation'] != 'local') {
+ $pluginInfo[] = '(' . htmlspecialchars($plug['pluginlocation']) . ')';
+ $installimage = serendipity_getTemplateFile('admin/img/install_now_' . strtolower($plug['pluginlocation']) . '.png');
+ } else {
+ $installimage = serendipity_getTemplateFile('admin/img/install_now.png');
+ }
+
+ if (!isset($plug['customURI'])) {
+ $plug['customURI'] = '';
+ }
+
+ if ( !empty($plug['requirements']['serendipity']) && version_compare($plug['requirements']['serendipity'], serendipity_getCoreVersion($serendipity['version']), '>') ) {
+ $notice['requirements_failures'][] = 's9y ' . $plug['requirements']['serendipity'];
+ }
+
+ if ( !empty($plug['requirements']['php']) && version_compare($plug['requirements']['php'], phpversion(), '>') ) {
+ $notice['requirements_failures'][] = 'PHP ' . $plug['requirements']['php'];
+ }
+
+ /* Enable after Smarty 2.6.7 upgrade.
+ * TODO: How can we get current Smarty version here? $smarty is not created!
+ if ( !empty($plug['requirements']['smarty']) && version_compare($plug['requirements']['smarty'], '2.6.7', '>') ) {
+ $notice['requirements_failures'][] = 'Smarty: ' . $plug['requirements']['smarty'];
+ }
+ */
+
+ if (count($notice['requirements_failures']) > 0) {
+ $plug['requirements_fail'] = true;
+ }
?>
<tr id="serendipity_plugin_<?php echo $plug['class_name']; ?>">
<?php } elseif ( $plug['upgradable'] == true ) { ?>
<a href="?serendipity[adminModule]=plugins&serendipity[pluginPath]=<?php echo $plug['pluginPath']; ?>&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&serendipity[pluginPath]=<?php echo $plug['pluginPath']; ?>&serendipity[install_plugin]=<?php echo $plug['plugin_class'] . $plug['customURI'] ?>"><img src="<?php echo serendipity_getTemplateFile('admin/img/install_now.png') ?>" title="<?php echo INSTALL ?>" alt="<?php echo INSTALL ?>" border="0"></a>
+ <a href="?serendipity[adminModule]=plugins&serendipity[pluginPath]=<?php echo $plug['pluginPath']; ?>&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 } ?>
</td>
</tr>
<tr>
- <td style="padding-left: 10px"><?php echo $plug['desc'] ?></td>
+ <td style="padding-left: 10px"><?php echo $plug['description'] ?></td>
</tr>
-<?php if (count($pluginInfo) > 0) { ?>
+<?php if (count($pluginInfo) > 0) { ?>
<tr>
<td style="padding-left: 10px; font-size: x-small"><?php echo implode('; ', $pluginInfo); ?></td>
</tr>
-<?php } ?>
+<?php } ?>
</table>
</td>
</tr>
<?php
+ }
}
-
- echo $plugin_navigation;
?>
</table>
}
if ($serendipity['GET']['adminAction'] == 'install' ) {
+ serendipity_plugin_api::hook_event('backend_templates_fetchtemplate', $serendipity);
+
$themeInfo = serendipity_fetchTemplateInfo($serendipity['GET']['theme']);
serendipity_set_config_var('template', $serendipity['GET']['theme']);
<?php echo SELECT_TEMPLATE; ?>
+<br /><br />
<?php
$i = 0;
- foreach (serendipity_fetchTemplates() as $theme) {
+ $stack = array();
+ serendipity_plugin_api::hook_event('backend_templates_fetchlist', $stack);
+ $themes = serendipity_fetchTemplates();
+ foreach($themes AS $theme) {
+ $stack[$theme] = serendipity_fetchTemplateInfo($theme);
+ }
+ ksort($stack);
+
+ foreach ($stack as $theme => $info) {
$i++;
- $info = serendipity_fetchTemplateInfo($theme);
/* Sorry, but we don't display engines */
if ( strtolower($info['engine']) == 'yes' ) {
if (file_exists($serendipity['serendipityPath'] . $serendipity['templatePath'] . $theme . '/preview.png')) {
$preview = '<img src="' . $serendipity['templatePath'] . $theme . '/preview.png" width="100" style="border: 1px #000000 solid" />';
+ } elseif (!empty($info['previewURL'])) {
+ $preview = '<img src="' . $info['previewURL'] . '" width="100" style="border: 1px #000000 solid" />';
} else {
$preview = ' ';
}
+
+ if (empty($info['customURI'])) {
+ $info['customURI'] = '';
+ }
$unmetRequirements = array();
if ( isset($info['require serendipity']) && version_compare($info['require serendipity'], serendipity_getCoreVersion($serendipity['version']), '>') ) {
if ( $serendipity['template'] != $theme ) {
if ( !sizeof($unmetRequirements) ) {
?>
- <a href="?serendipity[adminModule]=templates&serendipity[adminAction]=install&serendipity[theme]=<?php echo $theme ?>"><img src="<?php echo serendipity_getTemplateFile('admin/img/install_now.png') ?>" alt="<?php echo SET_AS_TEMPLATE ?>" title="<?php echo SET_AS_TEMPLATE ?>" border="0" /></a>
+ <a href="?serendipity[adminModule]=templates&serendipity[adminAction]=install&serendipity[theme]=<?php echo $theme . $info['customURI']; ?>"><img src="<?php echo serendipity_getTemplateFile('admin/img/install_now' . $info['customIcon'] . '.png') ?>" alt="<?php echo SET_AS_TEMPLATE ?>" title="<?php echo SET_AS_TEMPLATE ?>" border="0" /></a>
<?php } else { ?>
<span style="color: #cccccc"><?php echo sprintf(UNMET_REQUIREMENTS, implode(', ', $unmetRequirements)); ?></span>
<?php
}
-function serendipity_traversePath($basedir, $dir='', $onlyDirs=true, $pattern = NULL, $depth = 1) {
+function serendipity_traversePath($basedir, $dir='', $onlyDirs=true, $pattern = NULL, $depth = 1, $max_depth = null) {
$dh = @opendir($basedir . '/' . $dir);
);
}
}
- if ( is_dir($basedir . '/' . $dir . '/' . $file) ) {
- $files = array_merge($files, serendipity_traversePath($basedir, $dir . '/' . basename($file) . '/', $onlyDirs, $pattern, ($depth+1)));
+ if ( is_dir($basedir . '/' . $dir . '/' . $file) && ($max_depth === null || $depth < $max_depth)) {
+ $files = array_merge($files, serendipity_traversePath($basedir, $dir . '/' . basename($file) . '/', $onlyDirs, $pattern, ($depth+1), $max_depth));
}
}
}
if ($p == 'serendipity_plugin' && $class_name != 'serendipity_event' && (!$event_only || is_null($event_only))) {
$classes[$class_name] = array('name' => '@' . $class_name,
+ 'type' => 'internal_event',
+ 'true_name' => $class_name,
'pluginPath' => '');
} elseif ($p == 'serendipity_event' && $class_name != 'serendipity_event' && ($event_only || is_null($event_only))) {
$classes[$class_name] = array('name' => '@' . $class_name,
+ 'type' => 'internal_plugin',
+ 'true_name' => $class_name,
'pluginPath' => '');
}
}
if ($f{0} == '.' || $f == 'CVS' || !is_dir($ppath . '/' . $f)) {
continue;
}
-
+
$subd = opendir($ppath . '/' . $f);
if (!$subd) {
continue;
}
// Instead of only looking for directories, search for files within subdirectories
+ $final_loop = false;
while (($subf = readdir($subd)) !== false) {
+
if ($subf{0} == '.' || $subf == 'CVS') {
continue;
}
- if (is_dir($ppath . '/' . $f . '/' . $subf) && $maindir != $ppath . '/' . $f) {
+ if (!$final_loop && is_dir($ppath . '/' . $f . '/' . $subf) && $maindir != $ppath . '/' . $f) {
// Search for another level of subdirectories
serendipity_plugin_api::traverse_plugin_dir($ppath . '/' . $f, $classes, $event_only, $f . '/');
+ // We can break after that operation because the current directory has been fully checked already.
+ $final_loop = true;
}
if (!preg_match('@^[^_]+_(event|plugin)_.+\.php$@i', $subf)) {
continue;
}
+ $class_name = str_replace('.php', '', $subf);
// If an external plugin/event already exists as internal, remove the internal reference because its redundant
- if (isset($classes['@' . $subf])) {
- unset($classes['@' . $subf]);
+ if (isset($classes['@' . $class_name])) {
+ unset($classes['@' . $class_name]);
}
// A local plugin will be preferred over general plugins [used when calling this function the second time]
- if (isset($classes[$subf])) {
- unset($classes[$subf]);
+ if (isset($classes[$class_name])) {
+ unset($classes[$class_name]);
}
if (!is_null($event_only) && $event_only && !serendipity_plugin_api::is_event_plugin($subf)) {
continue;
}
- $class_name = str_replace('.php', '', $subf);
$classes[$class_name] = array('name' => $class_name,
+ 'true_name' => $class_name,
+ 'type' => 'additional_plugin',
'pluginPath' => $maindir . $f);
}
+ closedir($subd);
}
+ closedir($d);
}
}
if (empty($pluginPath)) {
$pluginPath = $name;
}
+
+ $file = false;
// First try the local path, and then (if existing) a shared library repository ...
if (file_exists($serendipity['serendipityPath'] . 'plugins/' . $pluginPath . '/' . $name . '.php')) {
- include_once $serendipity['serendipityPath'] . 'plugins/' . $pluginPath . '/' . $name . '.php';
+ $file = $serendipity['serendipityPath'] . 'plugins/' . $pluginPath . '/' . $name . '.php';
} elseif (file_exists(S9Y_INCLUDE_PATH . 'plugins/' . $pluginPath . '/' . $name . '.php')) {
- include_once S9Y_INCLUDE_PATH . 'plugins/' . $pluginPath . '/' . $name . '.php';
+ $file = S9Y_INCLUDE_PATH . 'plugins/' . $pluginPath . '/' . $name . '.php';
}
+
+ return $file;
}
- /* Creates an instance of a named plugin */
- function &load_plugin($instance_id, $authorid = null, $pluginPath = '')
- {
- global $serendipity;
-
+ function getClassByInstanceID($instance_id, &$is_internal) {
$instance = explode(':', $instance_id);
$name = $instance[0];
if ($name{0} == '@') {
$class_name = substr($name, 1);
} else {
+ $class_name =& $name;
+ }
+
+ return $class_name;
+ }
+
+ /* Probes for the plugin filename */
+ function probePlugin($instance_id, &$class_name, &$pluginPath) {
+ global $serendipity;
+
+ $filename = false;
+ $is_internal = false;
+
+ $class_name = serendipity_plugin_api::getClassByInstanceID($instance_id, $is_internal);
+
+ if (!$is_internal) {
/* plugin from the plugins/ dir */
- serendipity_plugin_api::includePlugin($name, $pluginPath);
- if (!class_exists($name) && empty($pluginPath)) {
+ $filename = serendipity_plugin_api::includePlugin($class_name, $pluginPath);
+ if (empty($filename) && !empty($instance_id)) {
$sql = "SELECT path from {$serendipity['dbPrefix']}plugins WHERE name = '" . $instance_id . "'";
$plugdata = serendipity_db_query($sql, true, 'both', false, false, false, true);
if (is_array($plugdata) && isset($plugdata[0])) {
}
if (empty($pluginPath)) {
- $pluginPath = $name;
+ $pluginPath = $class_name;
}
- serendipity_plugin_api::includePlugin($name, $pluginPath);
+ $filename = serendipity_plugin_api::includePlugin($class_name, $pluginPath);
}
- if (!class_exists($name)) {
+ if (empty($filename)) {
return false;
}
+ }
- $class_name =& $name;
+ return $filename;
+ }
+
+ /* Creates an instance of a named plugin */
+ function &load_plugin($instance_id, $authorid = null, $pluginPath = '', $pluginFile = null) {
+ global $serendipity;
+
+ if ($pluginFile === null) {
+ $class_name = '';
+ $pluginFile = serendipity_plugin_api::probePlugin($instance_id, $class_name, $pluginPath);
+ } else {
+ $is_internal = false;
+ $class_name = serendipity_plugin_api::getClassByInstanceID($instance_id, $is_internal);
+ }
+
+ if (!class_exists($class_name) && !empty($pluginFile)) {
+ include_once($pluginFile);
}
+ if (!class_exists($class_name)) {
+ return false;
+ }
+
$p =& new $class_name($instance_id);
if (!is_null($authorid)) {
$p->serendipity_owner = $authorid;
return $p;
}
+ function &getPluginInfo(&$pluginFile, &$class_data, $type) {
+ global $serendipity;
+
+ static $pluginlist = null;
+
+ if ($pluginlist === null) {
+ $data = serendipity_db_query("SELECT p.*,
+ pc.category
+ FROM {$serendipity['dbPrefix']}pluginlist AS p
+ LEFT OUTER JOIN {$serendipity['dbPrefix']}plugincategories AS pc
+ ON pc.class_name = p.class_name
+ WHERE p.pluginlocation = 'local' AND
+ p.plugintype = '" . serendipity_db_escape_string($type) . "'");
+ if (is_array($data)) {
+ foreach($data AS $p) {
+ if (!isset($pluginlist[$p['plugin_file']])) {
+ $pluginlist[$p['plugin_file']] = $p;
+ }
+
+ $pluginlist[$p['plugin_file']]['groups'][] = $p['category'];
+ }
+ }
+ }
+
+ if (is_array($pluginlist[$pluginFile])) {
+ $data = $pluginlist[$pluginFile];
+ if ((int)filemtime($pluginFile) == (int)$data['last_modified']) {
+ $data['stackable'] = serendipity_db_bool($data['stackable']);
+
+ $plugin = $data;
+ return $plugin;
+ }
+ }
+
+ $plugin =& serendipity_plugin_api::load_plugin($class_data['name'], null, $class_data['pluginPath'], $pluginFile);
+
+ return $plugin;
+ }
+
+ function &setPluginInfo(&$plugin, &$pluginFile, &$bag, &$class_data, $pluginlocation = 'local') {
+ global $serendipity;
+
+ serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}pluginlist WHERE plugin_file = '" . serendipity_db_escape_string($pluginFile) . "' AND pluginlocation = '" . serendipity_db_escape_string($pluginlocation) . "'");
+
+ if (is_object($plugin)) {
+ $data = array(
+ 'class_name' => get_class($plugin),
+ 'stackable' => $bag->get('stackable'),
+ 'name' => $bag->get('name'),
+ 'description' => $bag->get('description'),
+ 'author' => $bag->get('author'),
+ 'version' => $bag->get('version'),
+ 'upgrade_version' => $bag->get('version'),
+ 'requirements' => serialize($bag->get('requirements')),
+ 'website' => $bag->get('website'),
+ 'plugin_class' => $class_data['name'],
+ 'pluginPath' => $class_data['pluginPath'],
+ 'plugin_file' => $pluginFile,
+ 'pluginlocation' => $pluginlocation,
+ 'plugintype' => $serendipity['GET']['type'],
+ 'last_modified' => filemtime($pluginFile)
+ );
+ $groups = $bag->get('groups');
+ } elseif (is_array($plugin)) {
+ $data = $plugin;
+ $groups = $data['groups'];
+ unset($data['installable']);
+ unset($data['true_name']);
+ unset($data['customURI']);
+ unset($data['groups']);
+ $data['requirements'] = serialize($data['requirements']);
+ }
+
+ serendipity_db_insert('pluginlist', $data);
+
+ serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}plugincategories WHERE class_name = '" . serendipity_db_escape_string($data['class_name']) . "'");
+ foreach((array)$groups AS $group) {
+ if (empty($group)) {
+ continue;
+ }
+
+ $cat = array(
+ 'class_name' => $data['class_name'],
+ 'category' => $group
+ );
+ serendipity_db_insert('plugincategories', $cat);
+ }
+
+ $data['groups'] = $groups;
+
+ return $data;
+ }
+
function update_plugin_placement($name, $placement, $order=null)
{
global $serendipity;
$propbag->add('stackable', false);
$propbag->add('author', 'Serendipity Team');
$propbag->add('version', '1.0');
+ $propbag->add('groups', array('FRONTEND_VIEWS'));
}
function introspect_config_item($name, &$propbag)
$propbag->add('stackable', false);
$propbag->add('author', 'Serendipity Team');
$propbag->add('version', '1.0');
+ $propbag->add('groups', array('FRONTEND_ENTRY_RELATED'));
}
function generate_content(&$title)
$propbag->add('author', 'Serendipity Team');
$propbag->add('version', '1.0');
$propbag->add('configuration', array('frequency', 'count'));
+ $propbag->add('groups', array('FRONTEND_VIEWS'));
}
function introspect_config_item($name, &$propbag)
$propbag->add('author', 'Serendipity Team');
$propbag->add('version', '1.0');
$propbag->add('configuration', array('limit', 'use_links', 'interval'));
+ $propbag->add('groups', array('STATISTICS'));
}
function introspect_config_item($name, &$propbag)
$propbag->add('author', 'Serendipity Team');
$propbag->add('version', '1.0');
$propbag->add('configuration', array('limit', 'use_links', 'interval'));
+ $propbag->add('groups', array('STATISTICS'));
}
function introspect_config_item($name, &$propbag)
'fb_img',
)
);
+ $propbag->add('groups', array('FRONTEND_VIEWS'));
}
function introspect_config_item($name, &$propbag)
$propbag->add('author', 'Serendipity Team');
$propbag->add('version', '1.0');
$propbag->add('configuration', array('https'));
+ $propbag->add('groups', array('FRONTEND_FEATURES'));
}
function generate_content(&$title)
$propbag->add('configuration', array(
'image',
'text'));
+ $propbag->add('groups', array('FRONTEND_VIEWS'));
}
function introspect_config_item($name, &$propbag)
'show_where'
)
);
+ $propbag->add('groups', array('FRONTEND_VIEWS'));
$this->protected = TRUE; // If set to TRUE, only allows the owner of the plugin to modify its configuration
}
$propbag->add('author', 'Serendipity Team');
$propbag->add('version', '1.0');
$propbag->add('configuration', array('authorid', 'image', 'sort_order', 'sort_method', 'allow_select'));
+ $propbag->add('groups', array('FRONTEND_VIEWS'));
}
function introspect_config_item($name, &$propbag)
include_once(S9Y_INCLUDE_PATH . 'include/compat.inc.php');
// The version string
-$serendipity['version'] = '0.9-alpha3';
+$serendipity['version'] = '0.9-alpha4';
// Name of folder for the default theme
$serendipity['defaultTemplate'] = 'default';
CREATE INDEX ple_idx ON {PREFIX}permalinks (entry_id);
CREATE INDEX plt_idx ON {PREFIX}permalinks (type);
CREATE INDEX plcomb_idx ON {PREFIX}permalinks (permalink, type);
+
+create table {PREFIX}plugincategories (
+ class_name varchar(250) default null,
+ category varchar(250) default null
+);
+
+CREATE INDEX plugincat_idx ON {PREFIX}plugincategories(class_name, category);
+
+create table {PREFIX}pluginlist (
+ plugin_file varchar(255) NOT NULL default '',
+ class_name varchar(255) NOT NULL default '',
+ plugin_class varchar(255) NOT NULL default '',
+ pluginPath varchar(255) NOT NULL default '',
+ name varchar(255) NOT NULL default '',
+ description text NOT NULL,
+ version varchar(12) NOT NULL default '',
+ upgrade_version varchar(12) NOT NULL default '',
+ plugintype varchar(255) NOT NULL default '',
+ pluginlocation varchar(255) NOT NULL default '',
+ stackable int(1) NOT NULL default '0',
+ author varchar(255) NOT NULL default '',
+ requirements text NOT NULL,
+ website varchar(255) NOT NULL default '',
+ last_modified int(11) NOT NULL default '0'
+);
+
+CREATE INDEX pluginlist_f_idx ON {PREFIX}pluginlist(plugin_file);
+CREATE INDEX pluginlist_cn_idx ON {PREFIX}pluginlist(class_name);
+CREATE INDEX pluginlist_pt_idx ON {PREFIX}pluginlist(plugintype);
+CREATE INDEX pluginlist_pl_idx ON {PREFIX}pluginlist(pluginlocation);
--- /dev/null
+create table {PREFIX}plugincategories (
+ class_name varchar(250) default null,
+ category varchar(250) default null
+);
+
+CREATE INDEX plugincat_idx ON {PREFIX}plugincategories(class_name, category);
+
+create table {PREFIX}pluginlist (
+ plugin_file varchar(255) NOT NULL default '',
+ class_name varchar(255) NOT NULL default '',
+ plugin_class varchar(255) NOT NULL default '',
+ pluginPath varchar(255) NOT NULL default '',
+ name varchar(255) NOT NULL default '',
+ description text NOT NULL,
+ version varchar(12) NOT NULL default '',
+ upgrade_version varchar(12) NOT NULL default '',
+ plugintype varchar(255) NOT NULL default '',
+ pluginlocation varchar(255) NOT NULL default '',
+ stackable int(1) NOT NULL default '0',
+ author varchar(255) NOT NULL default '',
+ requirements text NOT NULL,
+ website varchar(255) NOT NULL default '',
+ last_modified int(11) NOT NULL default '0'
+);
+
+CREATE INDEX pluginlist_f_idx ON {PREFIX}pluginlist(plugin_file);
+CREATE INDEX pluginlist_cn_idx ON {PREFIX}pluginlist(class_name);
+CREATE INDEX pluginlist_pt_idx ON {PREFIX}pluginlist(plugintype);
+CREATE INDEX pluginlist_pl_idx ON {PREFIX}pluginlist(pluginlocation);
.direction_rtl {
direction: rtl;
}
+
+.serendipity_pluginlist_header {
+ height: 30px;
+ background-color: white;
+ color: black;
+ vertical-align: middle;
+ padding: 10px 0px 5px 10px;
+}
+
+.serendipity_pluginlist_section {
+ height: 50px;
+ border: 1px solid black;
+ background-color: #E0E0E0;
+ color: black;
+ vertical-align: middle;
+ padding: 10px 0px 5px 10px;
+}
\ No newline at end of file