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().''.ob_get_clean().'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 = "\n"; $xml .= "\n"; foreach($this->aPlugins as $k=>$v) { $xml .= "\t\n"; } $xml .= ""; # 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 = "\n"; $xml .= "\n"; foreach($this->aParams as $k=>$v) { switch($v['type']) { case 'numeric': $xml .= "\t".intval($v['value'])."\n"; break; case 'string': $xml .= "\t".plxUtils::cdataCheck(plxUtils::strCheck($v['value']))."\n"; break; case 'cdata': $xml .= "\t\n"; break; } } $xml .= ""; # 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 ); } } } ?>