Task #1052 - Automatic integration of plugin

Plugin management
This commit is contained in:
Dany De Bontridder 2014-11-18 01:34:05 +01:00
parent c7dd53c0f6
commit f8c4c1d0e7
4 changed files with 275 additions and 6 deletions

154
include/cfgplugin.inc.php Normal file
View file

@ -0,0 +1,154 @@
<?php
/*
* This file is part of PhpCompta.
*
* PhpCompta 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; either version 2 of the License, or
* (at your option) any later version.
*
* PhpCompta 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 PhpCompta; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// Copyright (2014) Author Dany De Bontridder <dany@alchimerys.be>
if ( ! defined ('ALLOWED') ) die('Appel direct ne sont pas permis');
require_once 'class_extension.php';
/**
* @file
* @brief Automatic installation of plugins and activation
*/
global $cn;
/******************************************************************************
* Scan the plugin folder and file in each subfolder a property file and
* store them into an array a_plugin
******************************************************************************
*/
$dirscan=scandir('../include/ext/');
$nb_dirscan=count($dirscan);
$a_plugin=array();
for ($e=0;$e<$nb_dirscan;$e++) {
if ($dirscan[$e] != '.' && $dirscan[$e]!='..' && is_dir('../include/ext/'.$dirscan[$e])) {
$dir_plugin=$dirscan[$e];
if (file_exists('../include/ext/'.$dir_plugin.'/plugin.xml')) {
$extension=Extension::read_definition('../include/ext/'.$dir_plugin.'/plugin.xml');
for ($i=0;$i<count($extension);$i++)
{
$a_plugin[]=clone $extension[$i];
}
}
}
}
$nb_plugin=count($a_plugin);
/**
* available profiles
*/
$a_profile=$cn->get_array('select p_id,p_name from profile where p_id > 0 order by p_name');
$nb_profile=count($a_profile);
/******************************************************************************
* save
******************************************************************************/
if ( isset ($_POST['save_plugin'])){
// retrieve array of plugin
$plugin=HtmlInput::default_value_post('plugin', array());
// for each extension
for ($i=0;$i<$nb_plugin;$i++) {
$code=$a_plugin[$i]->me_code;
// for each profile
for ($e=0;$e<$nb_profile;$e++)
{
$profile=$a_profile[$e]['p_id'];
if ( isset ($plugin[$code][$profile])) {
// insert or update into db
$count = $cn->get_value("select count(*) from menu_ref where me_code=$1", array($code));
if ( $count == 0 ) {
$a_plugin[$i]->insert();
}
$a_plugin[$i]->insert_profile_menu($profile,'EXT');
} else {
// delete
$a_plugin[$i]->remove_from_profile_menu ($profile);
}
}
}
}
/******************************************************************************
* Display the Plugin and for each profile were it is installed or not
******************************************************************************/
?>
<div class="content">
<?php echo _('Nombre de plugins trouvés')." ".$nb_plugin; ?>
<form method="post">
<table class="result">
<tr>
<th><?php echo _('Extension')?></th>
<th><?php echo _('Menu')?></th>
<th><?php echo _('Description')?></th>
<th><?php echo _('Chemin')?></th>
<th><?php echo _('Disponible')?></th>
</tr>
<?php for ($e=0;$e<$nb_plugin;$e++) :
//-----
$a_profile=$cn->get_array("select distinct
p_id,p_name,
(select count(*) from profile_menu as a where a.p_id=b.p_id and me_code=$1 )+
(select count(*) from menu_ref as c join profile_menu as d on (d.me_code=c.me_code) where d.p_id=b.p_id and me_file=$2 ) as cnt
from profile as b
where p_id > 0
order by p_name",array($a_plugin[$e]->me_code,$a_plugin[$e]->me_file));
$class=($e%2==0)?'odd':'even';
?>
<tr class="<?php echo $class?>">
<td>
<?php echo h($a_plugin[$e]->me_code); ?>
</td>
<td>
<?php echo h($a_plugin[$e]->me_menu); ?>
</td>
<td>
<?php echo h($a_plugin[$e]->me_description); ?>
</td>
<td>
<?php echo h($a_plugin[$e]->me_file); ?>
</td>
<td>
<?php
for ($w=0;$w<$nb_profile;$w++) :
?>
<span style="display:block">
<?php
$a=new ICheckBox('plugin['.$a_plugin[$e]->me_code.']['.$a_profile[$w]['p_id'].']');
if ($a_profile[$w]['cnt']>0) $a->selected=true;
echo $a->input();
echo $a_profile[$w]['p_name'];
?>
</span>
<?php
endfor;
?>
</td>
</tr>
<?php endfor; ?>
</table>
<?php echo HtmlInput::submit('save_plugin', _('Valider')); ?>
</form>
</div>

View file

@ -36,6 +36,9 @@
* - filepath (extension.ex_file)
*/
require_once 'class_menu_ref_sql.php';
include_once 'class_profile_sql.php';
require_once 'class_menu_ref.php';
require_once 'class_profile_menu.php';
class Extension extends Menu_Ref_sql
{
@ -96,6 +99,53 @@ class Extension extends Menu_Ref_sql
}
Extension::check_plugin_version();
}
/**
* insert into the table profile_menu for the given profile id and depending
* of the module $p_module
* @global type $cn
* @param type $p_id profile.p_id
* @param type $p_module menu_ref.me_code
* @throws Exception 10 : profile absent 20 module absent
*/
function insert_profile_menu($p_id=1,$p_module='EXT')
{
global $cn;
//profile exists ?
$profile=new Profile_sql($cn,$p_id);
if ( $profile->p_id != $p_id) {
throw new Exception(_('Profil inexistant'),10);
}
// Menu exists
$module=new Menu_Ref($cn,$p_module);
if ($module->me_code==null) {
throw new Exception(_('Module inexistant'),20);
}
$profil_menu=new Profile_Menu($cn);
$profil_menu->me_code=$this->me_code;
$profil_menu->me_code_dep=$p_module;
$profil_menu->p_type_display='S';
$profil_menu->p_id=$p_id;
$cnt=$profil_menu->count(' where p_id=$1 and me_code = $2',array($p_id,$this->me_code));
if ( $cnt==0) {
$profil_menu->insert();
}
}
function remove_from_profile_menu($p_id)
{
global $cn;
$cn->exec_sql('delete from profile_menu where (me_code = $1 or me_code in (select me_code from menu_ref where me_file=$2)) and p_id=$3',array($this->me_code,$this->me_file,$p_id));
}
/**
* Insert a plugin into the given profile, by default always insert into EXT
*
* @param type $p_id profile.p_id
* @throws Exception if duplicate or error db
*/
function insert_plugin()
{
try
@ -109,11 +159,6 @@ class Extension extends Menu_Ref_sql
throw new Exception("Doublon");
$this->me_type = 'PL';
$this->insert();
/**
* insert into default profile
*/
$this->cn->exec_sql("insert into profile_menu(me_code,me_code_dep,p_type_display,p_id)
values ($1,$2,$3,$4)",array($this->me_code,'EXT','S',1));
$this->cn->commit();
}
catch (Exception $exc)
@ -181,5 +226,69 @@ class Extension extends Menu_Ref_sql
}
}
}
/**
* Check that the xml contains all the needed information to change them into
* a extension, the exception code is 0 if the element is optional
* @brief Check XML.
* @param SimpleXMLElement $xml
* @throws Exception
*/
function check_xml(SimpleXMLElement $xml)
{
try {
if ( !isset ($xml->plugin)) throw new Exception(_('Manque plugin'),1);
$nb_plugin=count($xml->plugin);
for ($i=0;$i<$nb_plugin;$i++)
{
if ( !isset ($xml->plugin[$i]->name)) throw new Exception(_('Manque nom'),1);
if ( !isset ($xml->plugin[$i]->description)) throw new Exception(_('Manque description'),0);
if ( !isset ($xml->plugin[$i]->code)) throw new Exception(_('Manque code'),1);
if ( !isset ($xml->plugin[$i]->author)) throw new Exception(_('Manque auteur'),0);
if ( !isset ($xml->plugin[$i]->root)) throw new Exception(_('Manque répertoire racine'),1);
if ( !isset ($xml->plugin[$i]->file)) throw new Exception(_('Manque fichier à inclure'),1);
}
} catch (Exception $ex) {
throw $ex;
}
}
/**
* Parse a XML file to complete an array of extension objects
* @brief Create extension from XML.
* @param type $p_file filename
* @return array of Extension
*/
static function read_definition($p_file)
{
global $cn;
$dom=new DomDocument('1.0');
$dom->load($p_file);
$xml=simplexml_import_dom($dom);
$nb_plugin=count($xml->plugin);
$a_extension=array();
for ($i=0;$i<$nb_plugin;$i++)
{
$extension=new Extension($cn);
try {
$extension->check_xml($xml);
} catch (Exception $ex) {
echo_warning($e->getMessage());
if ( $ex->getCode()==1) {
continue;
}
}
$extension->me_file=trim($xml->plugin[$i]->root).'/'.trim($xml->plugin[$i]->file);
$extension->me_code=trim($xml->plugin[$i]->code);
$extension->me_description=(isset ($xml->plugin[$i]->description))?$xml->plugin[$i]->description:"";
$extension->me_description_etendue=($xml->plugin[$i]->author)?$xml->plugin[$i]->author:"";
$extension->me_type='PL';
$extension->me_menu=$xml->plugin[$i]->name;
$extension->me_parameter='plugin_code='.trim($xml->plugin[$i]->code);
$a_extension[]=clone $extension;
}
return $a_extension;
}
}

View file

@ -46,6 +46,7 @@ if ( isset($_POST['save_plugin']))
$plugin->me_description=$me_description;
$plugin->me_parameter='plugin_code='.$me_code;
$plugin->insert_plugin();
$plugin->insert_profile_module();
}
/**
* if post update then we update
@ -138,7 +139,7 @@ if ( $iselect->selected != '')
{
$sql="where me_type='".sql_string($_REQUEST['p_type'])."' ";
}
$menu=new Menu_Ref_sql();
$menu=new Menu_Ref_sql($cn);
$ret=$menu->seek($sql.$order);
?>
<fieldset><legend>Recherche</legend>

View file

@ -24,6 +24,11 @@ INSERT INTO menu_ref(me_code, me_menu, me_file, me_type,me_description_etendue
insert into profile_menu(me_code,p_id,p_type_display,pm_default,me_code_dep,p_order) values ('ANCKEY',1,'E',0,'ANC',15);
insert into profile_menu(me_code,p_id,p_type_display,pm_default,me_code_dep,p_order) values ('ANCKEY',2,'E',0,'ANC',15);
INSERT INTO menu_ref(me_code, me_menu, me_file, me_type,me_description_etendue)VALUES ('CFGPLUGIN', 'Configuration extension', 'cfgplugin.inc.php','ME','Permet d''installer et d''activer facilement des extensions');
insert into profile_menu(me_code,p_id,p_type_display,pm_default,me_code_dep,p_order) values ('CFGPLUGIN',1,'E',0,'PARAM',15);
insert into profile_menu(me_code,p_id,p_type_display,pm_default,me_code_dep,p_order) values ('CFGPLUGIN',2,'E',0,'PARAM',15);
create table key_distribution (
kd_id serial primary key,
kd_name text,