plugins: first prototype version
git-svn-id: http://piwigo.org/svn/trunk@1578 68402e56-0260-453c-a942-63ccdbb3a9ee
This commit is contained in:
parent
9e770f68a3
commit
12182ddcfe
13 changed files with 459 additions and 14 deletions
|
@ -92,6 +92,7 @@ $template->assign_vars(
|
|||
'U_COMMENTS'=> $link_start.'comments',
|
||||
'U_RATING'=> $link_start.'rating',
|
||||
'U_CADDIE'=> $link_start.'element_set&cat=caddie',
|
||||
'U_PLUGINS'=> $link_start.'plugins',
|
||||
'U_TAGS'=> $link_start.'tags',
|
||||
'U_THUMBNAILS'=> $link_start.'thumbnail',
|
||||
'U_USERS'=> $link_start.'user_list',
|
||||
|
|
101
admin/include/functions_plugins.inc.php
Normal file
101
admin/include/functions_plugins.inc.php
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | PhpWebGallery - a PHP based picture gallery |
|
||||
// | Copyright (C) 2003-2006 PhpWebGallery Team - http://phpwebgallery.net |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | branch : BSF (Best So Far)
|
||||
// | file : $Id$
|
||||
// | last update : $Date$
|
||||
// | last modifier : $Author$
|
||||
// | revision : $Revision$
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
function get_plugins()
|
||||
{
|
||||
$plugins = array();
|
||||
|
||||
$dir = opendir(PHPWG_PLUGINS_PATH);
|
||||
while ($file = readdir($dir))
|
||||
{
|
||||
if ($file!='.' and $file!='..')
|
||||
{
|
||||
$path = PHPWG_PLUGINS_PATH.$file;
|
||||
if (is_dir($path) and !is_link($path)
|
||||
and preg_match('/^[a-zA-Z0-9-_]+$/', $file )
|
||||
and file_exists($path.'/index.php')
|
||||
)
|
||||
{
|
||||
$plugin = array('name'=>'?', 'version'=>'?', 'uri'=>'', 'description'=>'');
|
||||
$plg_data = implode( '', file($path.'/index.php') );
|
||||
|
||||
if ( preg_match("|Plugin Name: (.*)|i", $plg_data, $val) )
|
||||
{
|
||||
$plugin['name'] = trim( $val[1] );
|
||||
}
|
||||
if (preg_match("|Version: (.*)|i", $plg_data, $val))
|
||||
{
|
||||
$plugin['version'] = trim($val[1]);
|
||||
}
|
||||
if ( preg_match("|Plugin URI: (.*)|i", $plg_data, $val) )
|
||||
{
|
||||
$plugin['uri'] = $val[1];
|
||||
}
|
||||
if ( preg_match("|Description: (.*)|i", $plg_data, $val) )
|
||||
{
|
||||
$plugin['description'] = trim($val[1]);
|
||||
}
|
||||
$plugins[$file] = $plugin;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
function activate_plugin($plugin_name)
|
||||
{
|
||||
global $conf;
|
||||
$arr = get_active_plugins(false);
|
||||
array_push($arr, $plugin_name);
|
||||
if ($arr != array_unique($arr) )
|
||||
return false; // just added the same one
|
||||
$conf['active_plugins'] = implode(',', $arr);
|
||||
pwg_query('
|
||||
UPDATE '.CONFIG_TABLE.'
|
||||
SET value="'.$conf['active_plugins'].'"
|
||||
WHERE param="active_plugins"');
|
||||
return true;
|
||||
}
|
||||
|
||||
function deactivate_plugin($plugin_name)
|
||||
{
|
||||
global $conf;
|
||||
$arr = get_active_plugins(false);
|
||||
$idx = array_search($plugin_name, $arr);
|
||||
if ($idx!==false)
|
||||
{
|
||||
unset( $arr[$idx] );
|
||||
$conf['active_plugins'] = implode(',', $arr);
|
||||
pwg_query('
|
||||
UPDATE '.CONFIG_TABLE.'
|
||||
SET value="'.$conf['active_plugins'].'"
|
||||
WHERE param="active_plugins"');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
?>
|
94
admin/plugins.php
Normal file
94
admin/plugins.php
Normal file
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | PhpWebGallery - a PHP based picture gallery |
|
||||
// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
|
||||
// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | branch : BSF (Best So Far)
|
||||
// | file : $RCSfile$
|
||||
// | last update : $Date$
|
||||
// | last modifier : $Author$
|
||||
// | revision : $Revision$
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if( !defined("PHPWG_ROOT_PATH") )
|
||||
{
|
||||
die ("Hacking attempt!");
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions_plugins.inc.php');
|
||||
check_status(ACCESS_ADMINISTRATOR);
|
||||
|
||||
$my_base_url = PHPWG_ROOT_PATH.'admin.php?page=plugins';
|
||||
|
||||
if ( isset($_REQUEST['action']) and isset($_REQUEST['plugin']) )
|
||||
{
|
||||
if ( $_REQUEST['action']=='deactivate')
|
||||
{
|
||||
$result = deactivate_plugin( $_REQUEST['plugin'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = activate_plugin( $_REQUEST['plugin'] );
|
||||
}
|
||||
if ($result)
|
||||
{ // we need a redirect so that we really reload it
|
||||
redirect($my_base_url.'&'.$_REQUEST['action'].'='.$result);
|
||||
}
|
||||
else
|
||||
{
|
||||
array_push( $page['errors'], 'Plugin activation/deactivation error' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$active_plugins = get_active_plugins();
|
||||
$active_plugins = array_flip($active_plugins);
|
||||
|
||||
$plugins = get_plugins();
|
||||
|
||||
$template->set_filenames(array('plugins' => 'admin/plugins.tpl'));
|
||||
|
||||
if (count($plugins))
|
||||
{
|
||||
$template->assign_block_vars( 'plugins', array() );
|
||||
foreach( $plugins as $plugin_id => $plugin )
|
||||
{
|
||||
$action_url = $my_base_url.'&plugin='.$plugin_id;
|
||||
if ( isset( $active_plugins[$plugin_id] ) )
|
||||
{
|
||||
$action_url .= '&action=deactivate';
|
||||
$action_name = l10n('Deactivate');
|
||||
}
|
||||
else
|
||||
{
|
||||
$action_url .= '&action=activate';
|
||||
$action_name = l10n('Activate');
|
||||
}
|
||||
$template->assign_block_vars( 'plugins.plugin',
|
||||
array(
|
||||
'NAME' => $plugin['name'],
|
||||
'DESCRIPTION' => $plugin['description'],
|
||||
'L_ACTION' => $action_name,
|
||||
'U_ACTION' => $action_url,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
$template->assign_var_from_handle('ADMIN_CONTENT', 'plugins');
|
||||
?>
|
|
@ -158,6 +158,8 @@ if ($user['is_the_guest'])
|
|||
// template instance
|
||||
$template = new Template(PHPWG_ROOT_PATH.'template/'.$user['template'], $user['theme'] );
|
||||
|
||||
load_plugins();
|
||||
|
||||
if ($conf['gallery_locked'])
|
||||
{
|
||||
$header_msgs[] = $lang['gallery_locked_message'];
|
||||
|
@ -191,6 +193,7 @@ if ($conf['check_upgrade_feed']
|
|||
and defined('PHPWG_IN_UPGRADE')
|
||||
and PHPWG_IN_UPGRADE)
|
||||
{
|
||||
|
||||
// retrieve already applied upgrades
|
||||
$query = '
|
||||
SELECT id
|
||||
|
|
|
@ -521,4 +521,6 @@ $conf['email_admin_on_new_user']=false;
|
|||
// stored on user informations
|
||||
//$conf['default_admin_layout']='yoga/dark';
|
||||
|
||||
|
||||
$conf['disable_plugins']=false;
|
||||
?>
|
||||
|
|
|
@ -33,6 +33,7 @@ include_once( PHPWG_ROOT_PATH .'include/functions_group.inc.php' );
|
|||
include_once( PHPWG_ROOT_PATH .'include/functions_html.inc.php' );
|
||||
include_once( PHPWG_ROOT_PATH .'include/functions_tag.inc.php' );
|
||||
include_once( PHPWG_ROOT_PATH .'include/functions_url.inc.php' );
|
||||
include_once( PHPWG_ROOT_PATH .'include/functions_plugins.inc.php' );
|
||||
|
||||
//----------------------------------------------------------- generic functions
|
||||
|
||||
|
|
155
include/functions_plugins.inc.php
Normal file
155
include/functions_plugins.inc.php
Normal file
|
@ -0,0 +1,155 @@
|
|||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | PhpWebGallery - a PHP based picture gallery |
|
||||
// | Copyright (C) 2003-2006 PhpWebGallery Team - http://phpwebgallery.net |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | branch : BSF (Best So Far)
|
||||
// | file : $Id$
|
||||
// | last update : $Date$
|
||||
// | last modifier : $Author$
|
||||
// | revision : $Revision$
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/*
|
||||
Events and event handlers are the core of PhpWebGallery plugin management.
|
||||
Plugins are addons that are found in plugins subdirectory. If activated, PWG
|
||||
will include the index.php of each plugin.
|
||||
Events are triggered by PWG core code. Plugins (or even PWG itself) can
|
||||
register their functions to handle these events. An event is identified by a
|
||||
string.
|
||||
*/
|
||||
|
||||
define('PHPWG_PLUGINS_PATH',PHPWG_ROOT_PATH.'plugins/');
|
||||
|
||||
/* Register a event handler.
|
||||
* @param string $event the name of the event to listen to
|
||||
* @param mixed $func the function that will handle the event
|
||||
*/
|
||||
function add_event_handler($event, $func, $priority=50, $accepted_args=1)
|
||||
{
|
||||
global $pwg_event_handlers;
|
||||
|
||||
if ( isset($pwg_event_handlers[$event]["$priority"]) )
|
||||
{
|
||||
foreach($pwg_event_handlers[$event]["$priority"] as $handler)
|
||||
{
|
||||
if ( $handler['function'] == $func )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trigger_event('add_event_handler',
|
||||
array('event'=>$event, 'function'=>$func)
|
||||
);
|
||||
|
||||
$pwg_event_handlers[$event]["$priority"][] =
|
||||
array(
|
||||
'function'=>$func,
|
||||
'accepted_args'=>$accepted_args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function trigger_event($event, $data=null)
|
||||
{
|
||||
global $pwg_event_handlers;
|
||||
if ($event!='pre_trigger_event' and $event!='post_trigger_event')
|
||||
{// special case
|
||||
trigger_event('pre_trigger_event',
|
||||
array('event'=>$event, 'data'=>$data) );
|
||||
if ( !isset($pwg_event_handlers[$event]) )
|
||||
{
|
||||
trigger_event('post_trigger_event',
|
||||
array('event'=>$event, 'data'=>$data) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isset($pwg_event_handlers[$event]) )
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
$args = array_slice(func_get_args(), 2);
|
||||
|
||||
foreach ($pwg_event_handlers[$event] as $priority => $handlers)
|
||||
{
|
||||
if ( !is_null($handlers) )
|
||||
{
|
||||
foreach($handlers as $handler)
|
||||
{
|
||||
$all_args = array_merge( array($data), $args);
|
||||
$function_name = $handler['function'];
|
||||
$accepted_args = $handler['accepted_args'];
|
||||
|
||||
if ( $accepted_args == 1 )
|
||||
$the_args = array($data);
|
||||
elseif ( $accepted_args > 1 )
|
||||
$the_args = array_slice($all_args, 0, $accepted_args);
|
||||
elseif ( $accepted_args == 0 )
|
||||
$the_args = NULL;
|
||||
else
|
||||
$the_args = $all_args;
|
||||
|
||||
$data = call_user_func_array($function_name, $the_args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($event!='pre_trigger_event' and $event!='post_trigger_event')
|
||||
{
|
||||
trigger_event('post_trigger_event',
|
||||
array('event'=>$event, 'data'=>$data) );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function get_active_plugins($runtime = true)
|
||||
{
|
||||
global $conf;
|
||||
if ($conf['disable_plugins'] and $runtime)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
if (empty($conf['active_plugins']))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
return explode(',', $conf['active_plugins']);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function load_plugins()
|
||||
{
|
||||
$plugins = get_active_plugins();
|
||||
foreach( $plugins as $plugin)
|
||||
{
|
||||
if (!empty($plugin))
|
||||
{
|
||||
include_once( PHPWG_PLUGINS_PATH.$plugin.'/index.php' );
|
||||
}
|
||||
}
|
||||
trigger_event('plugins_loaded');
|
||||
}
|
||||
?>
|
|
@ -37,8 +37,9 @@ $template->assign_vars(
|
|||
$page['gallery_title'] : $conf['gallery_title'],
|
||||
|
||||
'PAGE_BANNER' =>
|
||||
isset($page['page_banner']) ?
|
||||
$page['page_banner'] : $conf['page_banner'],
|
||||
trigger_event('page_banner',
|
||||
isset($page['page_banner']) ?
|
||||
$page['page_banner'] : $conf['page_banner'] ),
|
||||
|
||||
'BODY_ID' =>
|
||||
isset($page['body_id']) ?
|
||||
|
@ -49,22 +50,22 @@ $template->assign_vars(
|
|||
'LANG'=>$lang_info['code'],
|
||||
'DIR'=>$lang_info['direction'],
|
||||
|
||||
'TAG_INPUT_ENABLED' =>
|
||||
'TAG_INPUT_ENABLED' =>
|
||||
((is_adviser()) ? 'disabled onclick="return false;"' : '')
|
||||
));
|
||||
|
||||
// refresh
|
||||
if ( isset( $refresh ) and intval($refresh) >= 0
|
||||
// refresh
|
||||
if ( isset( $refresh ) and intval($refresh) >= 0
|
||||
and isset( $url_link ) and isset( $redirect_msg ) )
|
||||
{
|
||||
$template->assign_vars(
|
||||
array(
|
||||
'U_REDIRECT_MSG' => $redirect_msg,
|
||||
'REFRESH_TIME' => $refresh,
|
||||
'U_REFRESH' => $url_link
|
||||
));
|
||||
$template->assign_block_vars('refresh', array());
|
||||
}
|
||||
{
|
||||
$template->assign_vars(
|
||||
array(
|
||||
'U_REDIRECT_MSG' => $redirect_msg,
|
||||
'REFRESH_TIME' => $refresh,
|
||||
'U_REFRESH' => $url_link
|
||||
));
|
||||
$template->assign_block_vars('refresh', array());
|
||||
}
|
||||
|
||||
header('Content-Type: text/html; charset='.$lang_info['charset']);
|
||||
$template->parse('header');
|
||||
|
|
|
@ -22,6 +22,7 @@ INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('page_banner','<h
|
|||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('history_admin','false','keep a history of administrator visits on your website');
|
||||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('history_guest','true','keep a history of guest visits on your website');
|
||||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('login_history','true','keep a history of user logins on your website');
|
||||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('active_plugins','','activated plugins');
|
||||
-- Notification by mail
|
||||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('nbm_send_mail_as','','Send mail as param value for notification by mail');
|
||||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('nbm_send_detailed_content','true','Send detailed content for notification by mail');
|
||||
|
|
47
install/db/32-database.php
Normal file
47
install/db/32-database.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | PhpWebGallery - a PHP based picture gallery |
|
||||
// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
|
||||
// | Copyright (C) 2003-2006 PhpWebGallery Team - http://phpwebgallery.net |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | branch : BSF (Best So Far)
|
||||
// | file : $RCSfile$
|
||||
// | last update : $Date: 2006-07-23 14:17:00 +0200 (dim, 23 jui 2006) $
|
||||
// | last modifier : $Author: nikrou $
|
||||
// | revision : $Revision: 1492 $
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
$upgrade_description = 'add active_plugins to config';
|
||||
|
||||
// add column auto_login_key
|
||||
$query = '
|
||||
INSERT INTO '.PREFIX_TABLE.'config (param,value,comment)
|
||||
VALUES (\'active_plugins\',\'\',\'activated plugins\')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
echo
|
||||
"\n"
|
||||
. $upgrade_description
|
||||
."\n"
|
||||
;
|
||||
?>
|
18
plugins/hello_world/index.php
Normal file
18
plugins/hello_world/index.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php /*
|
||||
Plugin Name: Hello World !
|
||||
Author: PhpWebGallery team
|
||||
Description: This example plugin changes the page banner for the administration page
|
||||
*/
|
||||
|
||||
add_event_handler('page_banner', 'hello_world_banner' );
|
||||
|
||||
function hello_world_banner($banner)
|
||||
{
|
||||
global $page;
|
||||
if ( isset($page['body_id']) and $page['body_id']=='theAdminPage')
|
||||
{
|
||||
return '<h1>Hello world from PhpWebGallery plugin!</h1>';
|
||||
}
|
||||
return $banner;
|
||||
}
|
||||
?>
|
|
@ -19,6 +19,7 @@
|
|||
<li><a href="{U_CAT_UPDATE}">{lang:update}</a></li>
|
||||
<li><a href="{U_MAINTENANCE}">{lang:Maintenance}</a></li>
|
||||
<li><a href="{U_NOTIFICATION_BY_MAIL}">{lang:nbm_item_notification}</a></li>
|
||||
<li><a href="{U_PLUGINS}">{lang:Plugins}</a></li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
|
20
template/yoga/admin/plugins.tpl
Normal file
20
template/yoga/admin/plugins.tpl
Normal file
|
@ -0,0 +1,20 @@
|
|||
<div class="titrePage">
|
||||
<h2>{lang:Plugins}</h2>
|
||||
</div>
|
||||
|
||||
<!-- BEGIN plugins -->
|
||||
<table>
|
||||
<thead><tr>
|
||||
<td>{lang:Name}</td>
|
||||
<td>{lang:Description}</td>
|
||||
<td>{lang:Action}</td>
|
||||
</tr></thead>
|
||||
<!-- BEGIN plugin -->
|
||||
<tr>
|
||||
<td>{plugins.plugin.NAME}</td>
|
||||
<td>{plugins.plugin.DESCRIPTION}</td>
|
||||
<td><a href="{plugins.plugin.U_ACTION}">{plugins.plugin.L_ACTION}</a></td>
|
||||
</tr>
|
||||
<!-- END plugin -->
|
||||
</table>
|
||||
<!-- END plugins -->
|
Loading…
Reference in a new issue