1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/pluxml_ynh.git synced 2024-09-03 20:16:02 +02:00
pluxml_ynh/sources/core/lib/class.plx.plugins.php

585 lines
18 KiB
PHP
Raw Normal View History

2014-11-12 22:01:48 +01:00
<?php
/**
* Classe plxPlugins responsable de la gestion des plugins
*
* @package PLX
* @author Stephane F
**/
class plxPlugins {
public $aHooks=array(); # tableau de tous les hooks des plugins à executer
public $aPlugins=array(); #tableau contenant les plugins
public $default_lang; # langue par defaut utilisée par PluXml
/**
* Constructeur de la classe plxPlugins
*
* @param default_lang langue par défaut utilisée par PluXml
* @return null
* @author Stephane F
**/
public function __construct($default_lang='') {
$this->default_lang=$default_lang;
}
/**
* Méthode qui renvoit une instance d'un plugin
*
* @param plugName nom du plugin
* @return object object de type plxPlugin / false en cas d'erreur
* @return null
* @author Stephane F
**/
public function getInstance($plugName) {
$filename = PLX_PLUGINS.$plugName.'/'.$plugName.'.php';
if(is_file($filename)) {
include_once($filename);
if (class_exists($plugName)) {
return new $plugName($this->default_lang);
}
}
return false;
}
/**
* Méthode qui charge le fichier plugins.xml
*
* @return null
* @author Stephane F
**/
public function loadPlugins() {
if(!is_file(path('XMLFILE_PLUGINS'))) return;
# Mise en place du parseur XML
$data = implode('',file(path('XMLFILE_PLUGINS')));
$parser = xml_parser_create(PLX_CHARSET);
xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
xml_parse_into_struct($parser,$data,$values,$iTags);
xml_parser_free($parser);
# On verifie qu'il existe des tags "plugin"
if(isset($iTags['plugin'])) {
# On compte le nombre de tags "plugin"
$nb = sizeof($iTags['plugin']);
# On boucle sur $nb
for($i = 0; $i < $nb; $i++) {
$name = $values[$iTags['plugin'][$i] ]['attributes']['name'];
if($instance=$this->getInstance($name)) {
$this->aPlugins[$name] = $instance;
$this->aHooks = array_merge_recursive($this->aHooks, $instance->getHooks());
}
}
}
}
/**
* Méthode qui execute les hooks des plugins
*
* @param hookname nom du hook à appliquer
* @param parms parametre ou liste de paramètres sous forme de array
* @return null
* @author Stephane F
**/
public function callHook($hookName, $parms=null) {
if(isset($this->aHooks[$hookName])) {
ob_start();
foreach($this->aHooks[$hookName] as $callback) {
$return = $this->aPlugins[$callback['class']]->$callback['method']($parms);
}
if(isset($return))
return array('?>'.ob_get_clean().'<?php ', $return);
else
return '?>'.ob_get_clean().'<?php ';
}
}
/**
* Méthode qui récupère les infos des plugins actifs
*
* @return null
* @author Stephane F
**/
public function getInfos() {
foreach($this->aPlugins as $plugName => $plugInstance) {
$plugInstance->getInfos();
}
}
/**
* Méthode qui renvoie la liste des plugins inactifs
*
* @return array liste des plugins inactifs
* @author Stephane F
**/
public function getInactivePlugins() {
$aPlugins = array();
$dirs = plxGlob::getInstance(PLX_PLUGINS, true);
if(sizeof($dirs->aFiles)>0) {
foreach($dirs->aFiles as $plugName) {
if(!isset($this->aPlugins[$plugName]) AND $plugInstance=$this->getInstance($plugName)) {
$plugInstance->getInfos();
$aPlugins[$plugName] = $plugInstance;
}
}
}
ksort($aPlugins);
return $aPlugins;
}
/**
* Méthode qui sauvegarde le fichier plugins.xml et qui génère les fichiers admin.css et site.css des plugins
*
* @param content array content $_POST
* @return boolean resultat de la sauvegarde / TRUE = ok
* @author Stephane F
**/
public function saveConfig($content) {
# activation des plugins
if(isset($content['selection']) AND $content['selection']=='activate') {
foreach($content['chkAction'] as $idx => $plugName) {
if($plugInstance = $this->getInstance($plugName)) {
if(method_exists($plugName, 'OnActivate'))
$plugInstance->OnActivate();
$this->aPlugins[$plugName] = $plugInstance;
}
}
}
# désactivation des plugins
elseif(isset($content['selection']) AND $content['selection']=='deactivate') {
foreach($content['chkAction'] as $idx => $plugName) {
if($plugInstance = $this->aPlugins[$plugName]) {
if(method_exists($plugName, 'OnDeActivate'))
$plugInstance->OnDeActivate();
unset($this->aPlugins[$plugName]);
}
}
}
# suppression des plugins
elseif(isset($content['selection']) AND $content['selection']=='delete') {
foreach($content['chkAction'] as $idx => $plugName) {
if($this->deleteDir(realpath(PLX_PLUGINS.$plugName))) {
# suppression fichier de config du plugin
if(is_file(PLX_ROOT.PLX_CONFIG_PATH.'plugins/'.$plugName.'.xml'))
unlink(PLX_ROOT.PLX_CONFIG_PATH.'plugins/'.$plugName.'.xml');
# suppression fichier site.css du plugin
if(is_file(PLX_ROOT.PLX_CONFIG_PATH.'plugins/'.$plugName.'.site.css'))
unlink(PLX_ROOT.PLX_CONFIG_PATH.'plugins/'.$plugName.'.site.css');
# suppression fichier admin.css du plugin
if(is_file(PLX_ROOT.PLX_CONFIG_PATH.'plugins/'.$plugName.'.admin.css'))
unlink(PLX_ROOT.PLX_CONFIG_PATH.'plugins/'.$plugName.'.admin.css');
unset($this->aPlugins[$plugName]);
}
}
}
# tri des plugins par ordre de chargement
elseif(isset($content['update'])) {
$aPlugins = array();
asort($content['plugOrdre']);
foreach($content['plugOrdre'] as $plugName => $idx) {
$aPlugins[$plugName] = $this->aPlugins[$plugName];
}
$this->aPlugins = $aPlugins;
}
# génération du cache css des plugins
$this->cssCache('site');
$this->cssCache('admin');
# Début du fichier XML
$xml = "<?xml version='1.0' encoding='".PLX_CHARSET."'?>\n";
$xml .= "<document>\n";
foreach($this->aPlugins as $k=>$v) {
$xml .= "\t<plugin name=\"$k\"></plugin>\n";
}
$xml .= "</document>";
# On écrit le fichier
if(plxUtils::write($xml,path('XMLFILE_PLUGINS')))
return plxMsg::Info(L_SAVE_SUCCESSFUL);
else
return plxMsg::Error(L_SAVE_ERR.' '.path('XMLFILE_PLUGINS'));
}
/**
* Méthode récursive qui supprime tous les dossiers et les fichiers d'un répertoire
*
* @param deldir répertoire de suppression
* @return boolean résultat de la suppression
* @author Stephane F
**/
public function deleteDir($deldir) { #fonction récursive
if(is_dir($deldir) AND !is_link($deldir)) {
if($dh = opendir($deldir)) {
while(FALSE !== ($file = readdir($dh))) {
if($file != '.' AND $file != '..') {
$this->deleteDir(($deldir!='' ? $deldir.'/' : '').$file);
}
}
closedir($dh);
}
return rmdir($deldir);
}
return unlink($deldir);
}
/**
* Méthode qui génère le fichier css admin.css ou site.css
*
* @param type type du fichier (admin|site)
* @return boolean vrai si cache généré
* @author Stephane F
**/
public function cssCache($type) {
$cache = '';
foreach($this->aPlugins as $plugName => $plugInstance) {
$filename = PLX_ROOT.PLX_CONFIG_PATH.'plugins/'.$plugName.'.'.$type.'.css';
if(is_file($filename)) {
$cache .= trim(file_get_contents($filename));
} else {
$filename = PLX_PLUGINS.$plugName.'/css/'.$type.'.css';
if(is_file($filename)) {
$cache .= trim(file_get_contents($filename));
}
}
}
if(is_file(PLX_PLUGINS.$type.'.css'))
unlink(PLX_PLUGINS.$type.'.css');
if($cache!='') {
return plxUtils::write(plxUtils::minify($cache), PLX_PLUGINS.$type.'.css');
}
return true;
}
}
/**
* Classe plxPlugin destiné à créer un plugin
*
* @package PLX
* @author Stephane F
**/
class plxPlugin {
protected $aInfos=array(); # tableau des infos sur le plugins venant du fichier infos.xml
protected $aParams=array(); # tableau des paramètres sur le plugins venant du fichier parameters.xml
protected $aHooks=array(); # tableau des hooks du plugin
protected $aLang=array(); # tableau contenant les clés de traduction de la langue courante de PluXml
protected $plug=array(); # tableau contenant des infos diverses pour le fonctionnement du plugin
protected $adminProfil=''; # profil(s) utilisateur(s) autorisé(s) à acceder à la page admin.php du plugin
protected $configProfil=''; # profil(s) utilisateur(s) autorisé(s) à acceder à la page config.php du plugin
public $default_lang=DEFAULT_LANG; # langue par defaut de PluXml
public $adminMenu=false; # infos de customisation du menu pour accèder à la page admin.php du plugin
/**
* Constructeur de la classe plxPlugin
*
* @param default_lang langue par défaut utilisée par PluXml
* @return null
* @author Stephane F
**/
public function __construct($default_lang='') {
$this->default_lang = $default_lang;
$plugName= get_class($this);
$this->plug = array(
'dir' => PLX_PLUGINS,
'name' => $plugName,
'filename' => PLX_PLUGINS.$plugName.'/'.$plugName.'.php',
'parameters.xml'=> PLX_ROOT.PLX_CONFIG_PATH.'plugins/'.$plugName.'.xml',
'infos.xml' => PLX_PLUGINS.$plugName.'/infos.xml'
);
$this->aLang = $this->loadLang(PLX_PLUGINS.$plugName.'/lang/'.$this->default_lang.'.php');
$this->loadParams();
if(defined('PLX_ADMIN'))
$this->getInfos();
}
/**
* Méthode qui renvoit le(s) profil(s) utilisateur(s) autorisé(s) à acceder à la page admin.php du plugin
*
* @return string profil(s) utilisateur(s)
* @author Stephane F
**/
public function getAdminProfil() {
return $this->adminProfil;
}
/**
* Méthode qui mémorise le(s) profil(s) utilisateur(s) autorisé(s) à acceder à la page admin.php du plugin
*
* @param profil profil(s) (PROFIL_ADMIN, PROFIL_MANAGER, PROFIL_MODERATOR, PROFIL_EDITOR, PROFIL_WRITER)
* @return null
* @author Stephane F
**/
public function setAdminProfil($profil) {
$this->adminProfil=func_get_args();
}
/**
* Méthode qui permet de personnaliser le menu qui permet d'acceder à la page admin.php du plugin
*
* @param title titre du menu
* @param position position du menu dans la sidebar
* @param caption légende du menu (balise title du lien)
* @return null
* @author Stephane F
**/
public function setAdminMenu($title='', $position='', $caption='') {
$this->adminMenu = array(
'title'=>$title,
'position'=>($position==''?false:$position),
'caption'=>($caption==''?$title:$caption)
);
}
/**
* Méthode qui renvoit le(s) profil(s) utilisateur(s) autorisé(s) à accéder à la page config.php du plugin
*
* @return string profil(s) utilisateur(s)
* @author Stephane F
**/
public function getConfigProfil() {
return $this->configProfil;
}
/**
* Méthode qui mémorise le(s) profil(s) utilisateur(s) autorisé(s) à accéder à la page config.php du plugin
*
* @param profil profil(s) (PROFIL_ADMIN, PROFIL_MANAGER, PROFIL_MODERATOR, PROFIL_EDITOR, PROFIL_WRITER)
* @return null
* @author Stephane F
**/
public function setConfigProfil($profil) {
$this->configProfil=func_get_args();
}
/**
* Méthode qui retourne les hooks définis dans le plugin
*
* @return array tableau des hooks du plugin
* @author Stephane F
**/
public function getHooks() {
return $this->aHooks;
}
/**
* Méthode qui charge le fichier de langue par défaut du plugin
*
* @param filename fichier de langue à charger
* @return array tableau contenant les clés de traduction
* @author Stephane F
**/
public function loadLang($filename) {
if(!is_file($filename)) return;
include($filename);
return $LANG;
}
/**
* Méthode qui affiche une clé de traduction dans la langue par défaut de PluXml
*
* @param key clé de traduction à récuperer
* @return stdio
* @author Stephane F
**/
public function lang($key='') {
if(isset($this->aLang[$key]))
echo $this->aLang[$key];
else
echo $key;
}
/**
* Méthode qui retourne une clé de traduction dans la langue par défaut de PluXml
*
* @param key clé de traduction à récuperer
* @return string clé de traduite
* @author Stephane F
**/
public function getLang($key='') {
if(isset($this->aLang[$key]))
return $this->aLang[$key];
else
return $key;
}
/**
* Méthode qui charge le fichier des parametres du plugin parameters.xml
*
* @return null
* @author Stephane F
**/
public function loadParams() {
if(!is_file($this->plug['parameters.xml'])) return;
# Mise en place du parseur XML
$data = implode('',file($this->plug['parameters.xml']));
$parser = xml_parser_create(PLX_CHARSET);
xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
xml_parse_into_struct($parser,$data,$values,$iTags);
xml_parser_free($parser);
# On verifie qu'il existe des tags "parameter"
if(isset($iTags['parameter'])) {
# On compte le nombre de tags "parameter"
$nb = sizeof($iTags['parameter']);
# On boucle sur $nb
for($i = 0; $i < $nb; $i++) {
if(isset($values[$iTags['parameter'][$i]]['attributes']['name'])) {
$name=$values[$iTags['parameter'][$i]]['attributes']['name'];
$type=isset($values[$iTags['parameter'][$i]]['attributes']['type'])?$values[$iTags['parameter'][$i]]['attributes']['type']:'numeric';
$value=isset($values[$iTags['parameter'][$i]]['value'])?$value=$values[$iTags['parameter'][$i]]['value']:'';
$this->aParams[$name] = array(
'type' => $type,
'value' => $value
);
}
}
}
}
/**
* Méthode qui sauvegarde le fichier des parametres du plugin parameters.xml
*
* @return boolean resultat de la sauvegarde / TRUE = ok
* @author Stephane F
**/
public function saveParams() {
# Début du fichier XML
$xml = "<?xml version='1.0' encoding='".PLX_CHARSET."'?>\n";
$xml .= "<document>\n";
foreach($this->aParams as $k=>$v) {
switch($v['type']) {
case 'numeric':
$xml .= "\t<parameter name=\"$k\" type=\"".$v['type']."\">".intval($v['value'])."</parameter>\n";
break;
case 'string':
$xml .= "\t<parameter name=\"$k\" type=\"".$v['type']."\">".plxUtils::cdataCheck(plxUtils::strCheck($v['value']))."</parameter>\n";
break;
case 'cdata':
$xml .= "\t<parameter name=\"$k\" type=\"".$v['type']."\"><![CDATA[".plxUtils::cdataCheck($v['value'])."]]></parameter>\n";
break;
}
}
$xml .= "</document>";
# On écrit le fichier
if(plxUtils::write($xml,$this->plug['parameters.xml'])) {
# suppression ancien fichier parameters.xml s'il existe encore (5.1.7+)
if(file_exists($this->plug['dir'].$this->plug['name'].'/parameters.xml'))
unlink($this->plug['dir'].$this->plug['name'].'/parameters.xml');
return plxMsg::Info(L_SAVE_SUCCESSFUL);
}
else
return plxMsg::Error(L_SAVE_ERR.' '.$this->plug['parameters.xml']);
}
/**
* Méthode qui renvoie le tableau des paramètres
*
* @return array tableau aParams
* @author Stephane F
**/
public function getParams() {
if(sizeof($this->aParams)>0)
return $this->aParams;
else
return false;
}
/**
* Méthode qui renvoie la valeur d'un parametre du fichier parameters.xml
*
* @param param nom du parametre à recuperer
* @return string valeur du parametre
* @author Stephane F
**/
public function getParam($param) {
return (isset($this->aParams[$param])? $this->aParams[$param]['value']:'');
}
/**
* Méthode qui modifie la valeur d'un parametre du fichier parameters.xml
*
* @param param nom du parametre à recuperer
* @param value valeur du parametre
* @type type type du parametre (numeric, string, cdata)
* @return null
* @author Stephane F
**/
public function setParam($param, $value,$type='') {
if(in_array($type,array('numeric','string','cdata')))
$this->aParams[$param]['type']=$type;
if($this->aParams[$param]['type']=='numeric')
$this->aParams[$param]['value']=intval($value);
else
$this->aParams[$param]['value']=$value;
}
/**
* Méthode qui recupere les données du fichier infos.xml
*
* @return null
* @author Stephane F
**/
public function getInfos() {
if(!is_file($this->plug['infos.xml'])) return;
# Mise en place du parseur XML
$data = implode('',file($this->plug['infos.xml']));
$parser = xml_parser_create(PLX_CHARSET);
xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
xml_parse_into_struct($parser,$data,$values,$iTags);
xml_parser_free($parser);
$this->aInfos = array(
'title' => (isset($iTags['title']) AND isset($values[$iTags['title'][0]]['value']))?$values[$iTags['title'][0]]['value']:'',
'author' => (isset($iTags['author']) AND isset($values[$iTags['author'][0]]['value']))?$values[$iTags['author'][0]]['value']:'',
'version' => (isset($iTags['version']) AND isset($values[$iTags['version'][0]]['value']))?$values[$iTags['version'][0]]['value']:'',
'date' => (isset($iTags['date']) AND isset($values[$iTags['date'][0]]['value']))?$values[$iTags['date'][0]]['value']:'',
'site' => (isset($iTags['site']) AND isset($values[$iTags['site'][0]]['value']))?$values[$iTags['site'][0]]['value']:'',
'description' => (isset($iTags['description']) AND isset($values[$iTags['description'][0]]['value']))?$values[$iTags['description'][0]]['value']:'',
);
}
/**
* Méthode qui renvoie la valeur d'un parametre du fichier infos.xml
*
* @param param nom du parametre à recuperer
* @return string valeur de l'info
* @author Stephane F
**/
public function getInfo($param) {
return (isset($this->aInfos[$param])?$this->aInfos[$param]:'');
}
/**
* Méthode qui ajoute un hook à executer
*
* @param hookname nom du hook
* @param userfunction nom de la fonction du plugin à executer
* @return null
* @author Stephane F
**/
public function addHook($hookname, $userfunction) {
if(method_exists(get_class($this), $userfunction)) {
$this->aHooks[$hookname][]=array(
'class' => get_class($this),
'method' => $userfunction
);
}
}
}
?>