Skip to content
Permalink
Browse files

* Add unused plugin detection

* Change wy to query tables to list all possibly non-matching tables

Please discuss in issue #317
  • Loading branch information...
garvinhicking committed Mar 18, 2015
1 parent 5632341 commit 90f8020894e477232b3f30091066b67549b80449
Showing with 248 additions and 10 deletions.
  1. +5 −0 docs/NEWS
  2. +208 −5 include/admin/maintenance.inc.php
  3. +35 −5 templates/2k11/admin/maintenance.inc.tpl
@@ -3,6 +3,11 @@
Version 2.1 ()
------------------------------------------------------------------------

* Maintenance section can list unused plugins and unused database
tables. Also, a new API property bag key "tables" has been
created so that plugins can indicate which tables they
create.

* Fix: the syndication plugin now always uses absolute links for
the subtome-button

@@ -33,13 +33,207 @@
}
$data['unusedTables'] = array();
$data['unusedPlugins'] = array();
$plugins = serendipity_plugin_api::get_installed_plugins();
$classes = serendipity_plugin_api::enum_plugin_classes(true);
$plugins = serendipity_plugin_api::get_installed_plugins();
$classes_event = serendipity_plugin_api::enum_plugin_classes(true);
$classes_sidebar = serendipity_plugin_api::enum_plugin_classes();
$classes = $classes_event + $classes_sidebar;
switch($serendipity['dbType']) {
case 'sqlite':
case 'sqlite3':
case 'sqlite3oo':
case 'pdo-sqlite':
$q = "SELECT tbl_name AS table_name FROM sqlite_master WHERE type = 'table'";
break;
case 'pdo-postgres':
case 'postgres':
$q = "SELECT table_name FROM information_schema.tables WHERE table_catalog = '{$serendipity['dbName']}'";
break;
case 'mysql':
case 'mysqli':
default:
$q = "SELECT table_name FROM information_schema.tables WHERE table_schema = '{$serendipity['dbName']}'";
break;
}
$tables = serendipity_db_query($q);
$core_tables = array(
$serendipity['dbPrefix'] . 'authors' => true,
$serendipity['dbPrefix'] . 'groups' => true,
$serendipity['dbPrefix'] . 'groupconfig' => true,
$serendipity['dbPrefix'] . 'authorgroups' => true,
$serendipity['dbPrefix'] . 'access' => true,
$serendipity['dbPrefix'] . 'comments' => true,
$serendipity['dbPrefix'] . 'entries' => true,
$serendipity['dbPrefix'] . 'references' => true,
$serendipity['dbPrefix'] . 'exits' => true,
$serendipity['dbPrefix'] . 'referrers' => true,
$serendipity['dbPrefix'] . 'config' => true,
$serendipity['dbPrefix'] . 'options' => true,
$serendipity['dbPrefix'] . 'suppress' => true,
$serendipity['dbPrefix'] . 'plugins' => true,
$serendipity['dbPrefix'] . 'category' => true,
$serendipity['dbPrefix'] . 'images' => true,
$serendipity['dbPrefix'] . 'entrycat' => true,
$serendipity['dbPrefix'] . 'entryproperties' => true,
$serendipity['dbPrefix'] . 'mediaproperties' => true,
$serendipity['dbPrefix'] . 'permalinks' => true,
$serendipity['dbPrefix'] . 'plugincategories' => true,
$serendipity['dbPrefix'] . 'pluginlist' => true,
);
$legacy_plugintables = array(
'serendipity_event_spamblock'
=> array($serendipity['dbPrefix'] . 'spamblocklog'),
'serendipity_event_staticpage'
=> array($serendipity['dbPrefix'] . 'staticpages',
$serendipity['dbPrefix'] . 'staticpages_types',
$serendipity['dbPrefix'] . 'staticpage_categorypage',
$serendipity['dbPrefix'] . 'staticpage_custom'),
'serendipity_event_freetag'
=> array($serendipity['dbPrefix'] . 'entrytags',
$serendipity['dbPrefix'] . 'tagkeywords'),
'serendipity_event_ljupdate'
=> array($serendipity['dbPrefix'] . 'lj_entries'),
'serendipity_event_trackback'
=> array($serendipity['dbPrefix'] . 'delayed_trackbacks'),
'serendipity_event_externalauth'
=> array($serendipity['dbPrefix'] . 'loginlog'),
'serendipity_event_photoblog'
=> array($serendipity['dbPrefix'] . 'photoblog'),
'serendipity_plugin_adduser'
=> array($serendipity['dbPrefix'] . 'pending_authors'),
'serendipity_event_linklist'
=> array($serendipity['dbPrefix'] . 'links',
$serendipity['dbPrefix'] . 'link_category'),
'serendipity_event_guestbook'
=> array($serendipity['dbPrefix'] . 'guestbook'),
'serendipity_event_mymood'
=> array($serendipity['dbPrefix'] . 'mymood'),
'serendipity_event_aggregator'
=> array($serendipity['dbPrefix'] . 'aggregator_feeds',
$serendipity['dbPrefix'] . 'aggregator_md5',
$serendipity['dbPrefix'] . 'aggregator_feedcat',
$serendipity['dbPrefix'] . 'aggregator_feedlist'),
'serendipity_event_todolist'
=> array($serendipity['dbPrefix'] . 'project_colors',
$serendipity['dbPrefix'] . 'percentagedone',
$serendipity['dbPrefix'] . 'project_category'),
'serendipity_plugin_pollbox'
=> array($serendipity['dbPrefix'] . 'polls',
$serendipity['dbPrefix'] . 'polls_options'),
'serendipity_event_userprofiles'
=> array($serendipity['dbPrefix'] . 'profiles'),
'serendipity_event_mycalendar'
=> array($serendipity['dbPrefix'] . 'mycalendar'),
'serendipity_event_xsstrust'
=> array($serendipity['dbPrefix'] . 'ethics'),
'serendipity_plugin_currently'
=> array($serendipity['dbPrefix'] . 'currently'),
'serendipity_event_includeentry'
=> array($serendipity['dbPrefix'] . 'staticblocks'),
'serendipity_event_categorytemplates'
=> array($serendipity['dbPrefix'] . 'categorytemplates'),
'serendipity_event_downloadmanager'
=> array($serendipity['dbPrefix'] . 'dma_downloadmanager_files',
$serendipity['dbPrefix'] . 'dma_downloadmanager_categories',
$serendipity['dbPrefix'] . 'dma_downloadmanager_categories_tmp'),
'serendipity_event_backup'
=> array($serendipity['dbPrefix'] . 'dma_sqlbackup',
$serendipity['dbPrefix'] . 'dma_htmlbackup'),
'serendipity_event_forum'
=> array($serendipity['dbPrefix'] . 'dma_forum_boards',
$serendipity['dbPrefix'] . 'dma_forum_threads',
$serendipity['dbPrefix'] . 'dma_forum_posts',
$serendipity['dbPrefix'] . 'dma_forum_uploads',
$serendipity['dbPrefix'] . 'dma_forum_users',
$serendipity['dbPrefix'] . 'dma_forum_uploads_tmp',
$serendipity['dbPrefix'] . 'dma_forum_threads_tmp'),
'serendipity_event_markread'
=> array($serendipity['dbPrefix'] . 'marked'),
'serendipity_event_forgotpassword'
=> array($serendipity['dbPrefix'] . 'forgotpassword'),
'serendipity_event_faq'
=> array($serendipity['dbPrefix'] . 'faqs',
$serendipity['dbPrefix'] . 'faq_categorys'),
'serendipity_event_versioning'
=> array($serendipity['dbPrefix'] . 'versioning'),
'serendipity_event_wikilinks'
=> array($serendipity['dbPrefix'] . 'wikireferences'),
'serendipity_event_quicklink'
=> array($serendipity['dbPrefix'] . 'quicklink'),
'serendipity_event_suggest'
=> array($serendipity['dbPrefix'] . 'suggestmails'),
'serendipity_event_cronjob'
=> array($serendipity['dbPrefix'] . 'cronjoblog'),
'serendipity_event_adminnotes'
=> array($serendipity['dbPrefix'] . 'adminnotes',
$serendipity['dbPrefix'] . 'adminnotes_to_groups'),
'serendipity_event_dejure'
=> array($serendipity['dbPrefix'] . 'dejure'),
'serendipity_event_openid'
=> array($serendipity['dbPrefix'] . 'openid_authors'),
'serendipity_plugin_twitter'
=> array($serendipity['dbPrefix'] . 'tweets',
$serendipity['dbPrefix'] . 'tweetbackhistory',
$serendipity['dbPrefix'] . 'tweetbackshorturls'),
'serendipity_event_twitter'
=> array($serendipity['dbPrefix'] . 'tweets',
$serendipity['dbPrefix'] . 'tweetbackhistory',
$serendipity['dbPrefix'] . 'tweetbackshorturls'),
'serendipity_event_linktrimmer'
=> array($serendipity['dbPrefix'] . 'linktrimmer'),
'serendipity_event_spamblock_bayes'
=> array($serendipity['dbPrefix'] . 'spamblock_bayes',
$serendipity['dbPrefix'] . 'spamblock_bayes_recycler'),
'serendipity_event_cal'
=> array($serendipity['dbPrefix'] . 'eventcal'),
'serendipity_event_karma'
=> array($serendipity['dbPrefix'] . 'karmalog',
$serendipity['dbPrefix'] . 'karma'),
'serendipity_event_oembed'
=> array($serendipity['dbPrefix'] . 'oembeds'),
'serendipity_event_realtimecomments'
=> array($serendipity['dbPrefix'] . 'rtcomments_comments'),
'serendipity_event_commentspice'
=> array($serendipity['dbPrefix'] . 'commentspice'),
'serendipity_event_facebook'
=> array($serendipity['dbPrefix'] . 'facebook'),
'serendipity_plugin_shoutbox'
=> array($serendipity['dbPrefix'] . 'shoutbox'),
'serendipity_event_statistics'
=> array($serendipity['dbPrefix'] . 'visitors',
$serendipity['dbPrefix'] . 'visitors_count',
$serendipity['dbPrefix'] . 'refs')
);
if (is_array($tables)) {
foreach($tables AS $table) {
// Filter: Only tables that match our own dbPrefix
if (!preg_match('/^' . preg_quote($serendipity['dbPrefix']) . '/', $table['table_name'])) {
continue;
}
// Filter: No core tables
if (isset($core_tables[$table['table_name']])) {
continue;
}
$data['unusedTables'][$table['table_name']] = $table['table_name'];
}
} else {
$data['unusedTablesError'] = $tables;
$data['unusedTablesQuery'] = $q;
}
foreach ($classes as $class_data) {
// we only want to show the tables not currently in use by plugins
if (! in_array($class_data['true_name'], $plugins)) {
if (in_array($class_data['true_name'], $plugins)) {
// Plugin is actively installed, keep associated tables.
$pluginFile = serendipity_plugin_api::probePlugin($class_data['name'], $class_data['classname'], $class_data['pluginPath']);
// spartacus is only set becasue getPluginInfo needs a type parameter
$plugin =& serendipity_plugin_api::getPluginInfo($pluginFile, $class_data, 'spartacus');
@@ -49,11 +243,20 @@
if ($bag->is_set('tables')) {
foreach ($bag->get('tables') AS $table => $definition) {
if ($table != 'version') {
$data['unusedTables'][] = $table;
unset($data['unusedTables'][$table]);
}
}
}
if ($legacy_plugintables[$class_data['true_name']]) {
foreach($legacy_plugintables[$class_data['true_name']] AS $idx => $table) {
unset($data['unusedTables'][$table]);
}
}
}
} else {
// Plugin is not installed.
$data['unusedPlugins'][] = $class_data['pluginPath'];
}
}
@@ -95,13 +95,43 @@
{/if}

{if 'siteConfiguration'|checkPermission || 'blogConfiguration'|checkPermission}
<br style="clear: both" />
<section id="maintenance_tables" class="equal_heights quick_list">
<h3>Unused Tables{* i18n *}</h3>
<ul>
{foreach $unusedTables as $unusedTable}
<li>{$unusedTable}</li>
{/foreach}
</ul>

{if $unusedTablesError}
<p>{* i18n *}The list of available tables could not be fetched from the database. Maybe you do not have the necessary database permissions.</p>
<pre>Query: $unusedTablesQuery</pre>
<pre>Error: $unusedTablesError</pre>
{else}
<p>{* i18n *}Here is a list of database tables that were created, but neither belong to the core of Serendipity nor to any active plugin. You might want to delete those database tables, but make sure that those tables are not used by custom plugins or you want to preserve old data. This list can contain tables that are currently used by custom plugins or those which do not use API methods to create tables.</p>

{if count($unusedTables) == 0}
<p>{* i18n *}(None)</p>
{else}
<ul>
{foreach $unusedTables as $unusedTable}
<li>{$unusedTable}</li>
{/foreach}
</ul>
{/if}
{/if}
</section>

<section id="maintenance_tables" class="equal_heights quick_list">
<h3>Unused Plugins{* i18n *}</h3>

<p>{* i18n *}Here is a list of plugins files which exist in your plugins/ subdirectory and are currently not active and can be deleted if you no langer want these directories.</p>

{if count($unusedPlugins) == 0}
<p>{* i18n *}(None)</p>
{else}
<ul>
{foreach $unusedPlugins as $unusedPlugin}
<li>{$unusedPlugin}</li>
{/foreach}
</ul>
{/if}
</section>
{/if}

2 comments on commit 90f8020

@onli

This comment has been minimized.

Copy link
Member

replied Mar 19, 2015

Difficult to write that the right way. I am just not too happy with that :-/

That is a solution that would work now, and it seems like it will work nicely. But what I imagined we would have is a small api-field to register a table, and then a small piece of code to show when such a database table is still there but not used anymore (and of course in the core code to create and update the table, but that is a different story)

This is doing more, and it is not small anymore. I realize you proposed that in 5632341 but got no answer, sorry about that!
You remember probably that I was not too keen on the idea of the db cleanup, and maybe that is the same thing. But to show all tables that don't belong to s9y, that does not seem like it should be our work, and part of the core. There is already the prefix for that (I might miss something here).

$legacy_plugintables looks like a maintenance nightmare to me. I'd prefer if we'd say "to let users list your tables after the plugin is uninstalled, please use the plugin-API to create your database table". We could update some of the important ones ourselves - we will have to anyway, to have proper test-cases of the db-api - and then it would be immediately helpful as well for at least some plugins.

@garvinhicking

This comment has been minimized.

Copy link
Member Author

replied Mar 19, 2015

I'll continue the discussion in the issue.

Please sign in to comment.
You can’t perform that action at this time.