PageRenderTime 82ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/core/lib/class.plx.motor.php

https://github.com/flagos/Personal-page
PHP | 951 lines | 603 code | 68 blank | 280 comment | 114 complexity | ff74957f6e8264075f9d0acf2466e962 MD5 | raw file
  1. <?php
  2. /**
  3. * Classe plxMotor responsable du traitement global du script
  4. *
  5. * @package PLX
  6. * @author Anthony GUÉRIN, Florent MONTHEL, Stéphane F
  7. **/
  8. class plxMotor {
  9. public $version = false; # Version de PluXml
  10. public $start = false; # Microtime du debut de l'execution de PluXml
  11. public $get = false; # Donnees variable GET
  12. public $racine = false; # Url de PluXml
  13. public $path_url = false; # chemin de l'url du site
  14. public $style = false; # Dossier contenant le thème
  15. public $tri; # Tri d'affichage des articles
  16. public $tri_coms; # Tri d'affichage des commentaires
  17. public $bypage = false; # Pagination des articles
  18. public $page = 1; # Numéro de la page
  19. public $motif = false; # Motif de recherche
  20. public $mode = false; # Mode de traitement
  21. public $template = false; # template d'affichage
  22. public $cible = false; # Article, categorie ou page statique cible
  23. public $aConf = array(); # Tableau de configuration
  24. public $aCats = array(); # Tableau de toutes les catégories
  25. public $aStats = array(); # Tableau de toutes les pages statiques
  26. public $aTags = array(); # Tableau des tags
  27. public $aUsers = array(); #Tableau des utilisateurs
  28. public $plxGlob_arts = null; # Objet plxGlob des articles
  29. public $plxGlob_coms = null; # Objet plxGlob des commentaires
  30. public $plxRecord_arts = null; # Objet plxRecord des articles
  31. public $plxRecord_arts_size = 0; # Nombre d'articles total
  32. public $plxRecord_coms = null; # Objet plxRecord des commentaires
  33. public $plxCapcha = null; # Objet plxCapcha
  34. public $plxErreur = null; # Objet plxErreur
  35. public $plxPlugins = null; # Objet plxPlugins
  36. /**
  37. * Constructeur qui initialise certaines variables de classe
  38. * et qui lance le traitement initial
  39. *
  40. * @param filename emplacement du fichier XML de configuration
  41. * @return null
  42. * @author Anthony GUÉRIN, Florent MONTHEL, Stéphane F
  43. **/
  44. public function __construct($filename) {
  45. # Version de PluXml
  46. if(!is_readable(PLX_ROOT.'version')) {
  47. header('Content-Type: text/plain charset=UTF-8');
  48. printf(L_FILE_VERSION_REQUIRED, PLX_ROOT);
  49. exit;
  50. }
  51. $f = file(PLX_ROOT.'version');
  52. $this->version = $f['0'];
  53. # Traitement initial
  54. $this->start = plxDate::microtime();
  55. $this->get = plxUtils::getGets();
  56. # On parse le fichier de configuration
  57. $this->getConfiguration($filename);
  58. # On vérifie s'il faut faire une mise à jour
  59. if((!isset($this->aConf['version']) OR $this->version!=$this->aConf['version']) AND !defined('PLX_UPDATER')) {
  60. header('Location: '.PLX_ROOT.'update/index.php');
  61. exit;
  62. }
  63. # Chargement des variables
  64. $this->style = $this->aConf['style'];
  65. $this->racine = $this->aConf['racine'];
  66. $this->bypage = $this->aConf['bypage'];
  67. $this->tri = $this->aConf['tri'];
  68. $this->tri_coms = $this->aConf['tri_coms'];
  69. # On récupère le chemin de l'url
  70. $var = parse_url($this->racine);
  71. $this->path_url = str_replace(ltrim($var['path'], '\/'), '', ltrim($_SERVER['REQUEST_URI'], '\/'));
  72. # Traitement des plugins
  73. $this->plxPlugins = new plxPlugins(PLX_ROOT.$this->aConf['plugins'], $this->aConf['default_lang']);
  74. $this->plxPlugins->loadPlugins();
  75. # Traitement sur les répertoires des articles et des commentaires
  76. $this->plxGlob_arts = plxGlob::getInstance(PLX_ROOT.$this->aConf['racine_articles']);
  77. $this->plxGlob_coms = plxGlob::getInstance(PLX_ROOT.$this->aConf['racine_commentaires']);
  78. # Récupération des données dans les autres fichiers xml
  79. $this->getCategories(PLX_ROOT.$this->aConf['categories']);
  80. $this->getStatiques(PLX_ROOT.$this->aConf['statiques']);
  81. $this->getTags(PLX_ROOT.$this->aConf['tags']);
  82. $this->getUsers(PLX_ROOT.$this->aConf['users']);
  83. # Hook plugins
  84. eval($this->plxPlugins->callHook('plxMotorConstruct'));
  85. }
  86. /**
  87. * Méthode qui effectue une analyse de la situation et détermine
  88. * le mode à appliquer. Cette méthode alimente ensuite les variables
  89. * de classe adéquates
  90. *
  91. * @param mode mode du moteur à appliquer
  92. * @param motif motif de recherche à appliquer
  93. * @param bypage pagination (nombre d'articles) à appliquer
  94. * @return null
  95. * @author Anthony GUÉRIN, Florent MONTHEL, Stéphane F
  96. **/
  97. public function prechauffage($mode='',$motif='',$bypage='') {
  98. # Hook plugins
  99. if(eval($this->plxPlugins->callHook('plxMotorPreChauffageBegin'))) return;
  100. if($mode != '' AND $motif != '') {
  101. $this->mode = $mode; # Mode
  102. $this->motif = $motif; # Motif de recherche
  103. $this->bypage = $bypage; # Nombre d'article par page
  104. $this->template = $mode.'.php';
  105. }
  106. elseif($this->get AND preg_match('/^preview\/?/',$this->get) AND isset($_SESSION['preview'])) {
  107. $this->mode = 'preview';
  108. $this->template = 'article.php';
  109. if($this->aConf['capcha'] == 1) # On cree notre objet capcha si besoin est
  110. $this->plxCapcha = new plxCapcha();
  111. }
  112. elseif($this->get AND preg_match('/^404\/?/',$this->get)) {
  113. $this->plxErreur = new plxErreur(L_DOCUMENT_NOT_FOUND);
  114. $this->mode = 'erreur';
  115. $this->template = 'erreur.php';
  116. }
  117. elseif($this->get AND preg_match('/^article([0-9]+)\//',$this->get,$capture)) {
  118. $this->mode = 'article'; # Mode article
  119. $this->template = 'article.php';
  120. $this->cible = str_pad($capture[1],4,'0',STR_PAD_LEFT); # On complete sur 4 caracteres
  121. $this->motif = '/^'.$this->cible.'.([0-9,|home]*).[0-9]{3}.[0-9]{12}.[a-z0-9-]+.xml$/'; # Motif de recherche
  122. $this->bypage = NULL; # Pas de pagination pour ce mode bien sur
  123. if($this->aConf['capcha'] == 1) # On cree notre objet capcha si besoin est
  124. $this->plxCapcha = new plxCapcha();
  125. }
  126. elseif($this->get AND preg_match('/^categorie([0-9]+)\//',$this->get,$capture)) {
  127. $this->mode = 'categorie'; # Mode categorie
  128. $this->cible = str_pad($capture[1],3,'0',STR_PAD_LEFT); # On complete sur 3 caracteres
  129. $this->motif = '/^[0-9]{4}.[home|0-9,]*'.$this->cible.'[0-9,]*.[0-9]{3}.[0-9]{12}.[a-z0-9-]+.xml$/'; # Motif de recherche
  130. if(!empty($this->aCats[ $this->cible ])) {
  131. $this->template = $this->aCats[ $this->cible ]['template'];
  132. $this->tri = $this->aCats[ $this->cible ]['tri']; # Recuperation du tri des articles
  133. # On a une pagination particuliere pour la categorie (bypage != 0)
  134. if($this->aCats[ $this->cible ]['bypage'] > 0)
  135. $this->bypage = $this->aCats[ $this->cible ]['bypage'];
  136. }
  137. else $this->template = 'erreur.php';
  138. }
  139. elseif($this->get AND preg_match('/^static([0-9]+)\//',$this->get,$capture)) {
  140. $this->mode = 'static'; # Mode static
  141. $this->cible = str_pad($capture[1],3,'0',STR_PAD_LEFT); # On complete sur 3 caracteres
  142. $this->bypage = NULL; # Pas de pagination pour ce mode bien sur ;)
  143. $this->template = isset($this->aStats[ $this->cible ]) ? $this->aStats[ $this->cible ]['template'] : 'erreur.php';
  144. }
  145. elseif($this->get AND preg_match('/^(telechargement|download)\/(.+)$/',$this->get,$capture)) {
  146. $this->mode = 'telechargement'; # Mode telechargement
  147. $this->cible = $capture[2];
  148. $this->bypage = NULL; # Pas de pagination pour ce mode bien sur ;)
  149. }
  150. elseif($this->get AND preg_match('/^tag\/([a-z0-9-]+)/',$this->get,$capture)) {
  151. $this->mode = 'tags'; # Affichage en mode home
  152. $this->template = 'tags.php';
  153. $this->cible = $capture[1];
  154. $ids = array();
  155. $time = @date('YmdHi');
  156. foreach($this->aTags as $idart => $tag) {
  157. if($tag['date']<=$time) {
  158. $tags = array_map("trim", explode(',', $tag['tags']));
  159. $tags = array_map(array('plxUtils', 'title2url'), $tags);
  160. if(in_array($this->cible, $tags)) {
  161. if(!isset($ids[$idart])) $ids[$idart] = $idart;
  162. }
  163. }
  164. }
  165. if(sizeof($ids)==0) {
  166. $this->plxErreur = new plxErreur(L_ARTICLE_NO_TAG);
  167. $this->mode = "erreur";
  168. $this->template = "erreur.php";
  169. } else {
  170. $this->motif = '/('.implode('|', $ids).').[home|0-9,]*.[0-9]{3}.[0-9]{12}.[a-z0-9-]+.xml$/';
  171. $this->bypage = $this->aConf['bypage']; # Nombre d'article par page
  172. }
  173. }
  174. elseif($this->get AND preg_match('/^archives\/([0-9]{4})[\/]?([0-9]{2})?[\/]?([0-9]{2})?/',$this->get,$capture)) {
  175. $this->mode = 'archives';
  176. $this->template = 'archives.php';
  177. $this->bypage = $this->aConf['bypage_archives'];
  178. $search = $this->cible = $capture[1];
  179. if(!empty($capture[2])) $search = $this->cible .= $capture[2];
  180. else $search = $this->cible . '[0-9]{2}';
  181. if(!empty($capture[3])) $search = $this->cible .= $capture[3];
  182. else $search = $this->cible . '[0-9]{2}';
  183. $this->motif = '/^[0-9]{4}.[home|0-9,]*.[0-9]{3}.'.$search.'[0-9]{4}.[a-z0-9-]+.xml$/';
  184. }
  185. elseif(!$this->get AND !defined('PLX_BLOG') AND $this->aConf['homestatic']!='' AND $this->aStats[$this->aConf['homestatic']]['active']) {
  186. $this->mode = 'static'; # Mode static
  187. $this->cible = $this->aConf['homestatic'];
  188. $this->template = $this->aStats[ $this->cible ]['template'];
  189. $this->bypage = NULL; # Pas de pagination pour ce mode bien sur ;)
  190. }
  191. else {
  192. $this->mode = 'home';
  193. $this->template = 'home.php';
  194. $this->bypage = $this->aConf['bypage']; # Nombre d'article par page
  195. # On regarde si on a des articles en mode "home"
  196. if($this->plxGlob_arts->query('/^[0-9]{4}.(home[0-9,]*).[0-9]{3}.[0-9]{12}.[a-z0-9-]+.xml$/')) {
  197. $this->motif = '/^[0-9]{4}.(home[0-9,]*).[0-9]{3}.[0-9]{12}.[a-z0-9-]+.xml$/';
  198. } else { # Sinon on recupere tous les articles
  199. $this->motif = '/^[0-9]{4}.[0-9,]*.[0-9]{3}.[0-9]{12}.[a-z0-9-]+.xml$/';
  200. }
  201. }
  202. # Hook plugins
  203. eval($this->plxPlugins->callHook('plxMotorPreChauffageEnd'));
  204. }
  205. /**
  206. * Méthode qui effectue le traitement selon le mode du moteur
  207. *
  208. * @return null
  209. * @author Florent MONTHEL, Stephane F
  210. **/
  211. public function demarrage() {
  212. # Hook plugins
  213. if(eval($this->plxPlugins->callHook('plxMotorDemarrageBegin'))) return;
  214. if($this->mode == 'home' OR $this->mode == 'categorie' OR $this->mode == 'archives' OR $this->mode == 'tags') {
  215. if($this->mode == 'categorie' AND empty($this->aCats[ $this->cible ])) { # Catégorie inexistante
  216. $this->plxErreur = new plxErreur(L_UNKNOWN_CATEGORY);
  217. $this->mode = 'erreur';
  218. return;
  219. }
  220. $this->getPage(); # Recuperation de la page
  221. if(!$this->getArticles()) { # Aucun article
  222. $this->plxErreur = new plxErreur(L_NO_ARTICLE_PAGE);
  223. $this->mode = 'erreur';
  224. $this->template = 'erreur.php';
  225. return;
  226. }
  227. }
  228. elseif($this->mode == 'preview') {
  229. $this->mode='article';
  230. $this->plxRecord_arts = new plxRecord($_SESSION['preview']);
  231. $this->template=$this->plxRecord_arts->f('template');
  232. return;
  233. }
  234. elseif($this->mode == 'article') {
  235. if(!$this->getArticles()) { # Aucun article
  236. $this->plxErreur = new plxErreur(L_UNKNOWN_ARTICLE);
  237. $this->mode = 'erreur';
  238. $this->template = 'erreur.php';
  239. return;
  240. }
  241. # On a validé le formulaire commentaire
  242. if(!empty($_POST) AND $this->plxRecord_arts->f('allow_com') AND $this->aConf['allow_com']) {
  243. # On récupère le retour de la création
  244. $retour = $this->newCommentaire($this->cible,plxUtils::unSlash($_POST));
  245. # Url de l'article
  246. $url = $this->urlRewrite('?article'.intval($this->plxRecord_arts->f('numero')).'/'.$this->plxRecord_arts->f('url'));
  247. eval($this->plxPlugins->callHook('plxMotorDemarrageNewCommentaire'));
  248. if($retour[0] == 'c') { # Le commentaire a été publié
  249. header('Location: '.$url.'/#'.$retour);
  250. } elseif($retour == 'mod') { # Le commentaire est en modération
  251. $_SESSION['msgcom'] = L_COM_IN_MODERATION;
  252. header('Location: '.$url.'/#form');
  253. } else {
  254. $_SESSION['msgcom'] = $retour;
  255. $_SESSION['msg']['name'] = plxUtils::unSlash($_POST['name']);
  256. $_SESSION['msg']['site'] = plxUtils::unSlash($_POST['site']);
  257. $_SESSION['msg']['mail'] = plxUtils::unSlash($_POST['mail']);
  258. $_SESSION['msg']['content'] = plxUtils::unSlash($_POST['content']);
  259. eval($this->plxPlugins->callHook('plxMotorDemarrageCommentSessionMessage'));
  260. header('Location: '.$url.'/#form');
  261. }
  262. exit;
  263. }
  264. # Récupération des commentaires
  265. $this->getCommentaires('/^'.$this->cible.'.[0-9]{10}-[0-9]+.xml$/',$this->mapTri($this->tri_coms));
  266. $this->template=$this->plxRecord_arts->f('template');
  267. }
  268. elseif($this->mode == 'static') {
  269. # On va verifier que la page existe vraiment
  270. if(!isset($this->aStats[ $this->cible ]) OR intval($this->aStats[ $this->cible ]['active']) != 1) {
  271. $this->plxErreur = new plxErreur(L_UNKNOWN_STATIC);
  272. $this->mode = 'erreur';
  273. $this->template = 'erreur.php';
  274. return;
  275. }
  276. }
  277. elseif($this->mode == 'telechargement') {
  278. # On va verifier que la page existe vraiment
  279. if(!$this->sendTelechargement($this->cible)) {
  280. $this->plxErreur = new plxErreur(L_DOCUMENT_NOT_FOUND);
  281. $this->mode = 'erreur';
  282. $this->template = 'erreur.php';
  283. return;
  284. }
  285. }
  286. # Hook plugins
  287. eval($this->plxPlugins->callHook('plxMotorDemarrageEnd'));
  288. }
  289. /**
  290. * Méthode qui parse le fichier de configuration et alimente
  291. * le tableau aConf
  292. *
  293. * @param filename emplacement du fichier XML de configuration
  294. * @return null
  295. * @author Anthony GUÉRIN, Florent MONTHEL, Stéphane F
  296. **/
  297. public function getConfiguration($filename) {
  298. # Mise en place du parseur XML
  299. $data = implode('',file($filename));
  300. $parser = xml_parser_create(PLX_CHARSET);
  301. xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
  302. xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
  303. xml_parse_into_struct($parser,$data,$values,$iTags);
  304. xml_parser_free($parser);
  305. # On verifie qu'il existe des tags "parametre"
  306. if(isset($iTags['parametre'])) {
  307. # On compte le nombre de tags "parametre"
  308. $nb = sizeof($iTags['parametre']);
  309. # On boucle sur $nb
  310. for($i = 0; $i < $nb; $i++) {
  311. if(isset($values[ $iTags['parametre'][$i] ]['value'])) # On a une valeur pour ce parametre
  312. $this->aConf[ $values[ $iTags['parametre'][$i] ]['attributes']['name'] ] = $values[ $iTags['parametre'][$i] ]['value'];
  313. else # On n'a pas de valeur
  314. $this->aConf[ $values[ $iTags['parametre'][$i] ]['attributes']['name'] ] = '';
  315. }
  316. }
  317. # On gère la non regression en cas d'ajout de paramètres sur une version de pluxml déjà installée
  318. if(!isset($this->aConf['tri_coms'])) $this->aConf['tri_coms'] = $this->aConf['tri'];
  319. if(!isset($this->aConf['bypage_admin_coms'])) $this->aConf['bypage_admin_coms'] = 10;
  320. if(!isset($this->aConf['bypage_archives'])) $this->aConf['bypage_archives'] = 5;
  321. if(!isset($this->aConf['userfolders'])) $this->aConf['userfolders'] = 0;
  322. if(!isset($this->aConf['tags'])) $this->aConf['tags'] = 'data/configuration/tags.xml';
  323. if(!isset($this->aConf['users'])) $this->aConf['users'] = 'data/configuration/users.xml';
  324. if(!isset($this->aConf['plugins'])) $this->aConf['plugins'] = 'data/configuration/plugins.xml';
  325. if(!isset($this->aConf['meta_description'])) $this->aConf['meta_description'] = '';
  326. if(!isset($this->aConf['meta_keywords'])) $this->aConf['meta_keywords'] = '';
  327. if(!isset($this->aConf['default_lang'])) $this->aConf['default_lang'] = DEFAULT_LANG;
  328. }
  329. /**
  330. * Méthode qui parse le fichier des catégories et alimente
  331. * le tableau aCats
  332. *
  333. * @param filename emplacement du fichier XML des catégories
  334. * @return null
  335. * @author Stéphane F
  336. **/
  337. public function getCategories($filename) {
  338. if(!is_file($filename)) return;
  339. # Mise en place du parseur XML
  340. $data = implode('',file($filename));
  341. $parser = xml_parser_create(PLX_CHARSET);
  342. xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
  343. xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
  344. xml_parse_into_struct($parser,$data,$values,$iTags);
  345. xml_parser_free($parser);
  346. if(isset($iTags['categorie']) AND isset($iTags['name'])) {
  347. $nb = sizeof($iTags['name']);
  348. $size=ceil(sizeof($iTags['categorie'])/$nb);
  349. for($i=0;$i<$nb;$i++) {
  350. $attributes = $values[$iTags['categorie'][$i*$size]]['attributes'];
  351. $number = $attributes['number'];
  352. # Recuperation du nom de la catégorie
  353. $this->aCats[$number]['name'] = isset($iTags['name'][$i])?$values[$iTags['name'][$i]]['value']:'';
  354. # Recuperation du nom de la description
  355. $this->aCats[$number]['description'] = isset($iTags['description'][$i])?$values[$iTags['description'][$i]]['value']:'';
  356. # Recuperation du meta description
  357. $this->aCats[$number]['meta_description'] = isset($iTags['meta_description'][$i])?$values[$iTags['meta_description'][$i]]['value']:'';
  358. # Recuperation du meta keywords
  359. $this->aCats[$number]['meta_keywords'] = isset($iTags['meta_keywords'][$i])?$values[$iTags['meta_keywords'][$i]]['value']:'';
  360. # Recuperation de l'url de la categorie
  361. $this->aCats[$number ]['url']=strtolower($attributes['url']);
  362. # Recuperation du tri de la categorie si besoin est
  363. $this->aCats[$number ]['tri']=isset($attributes['tri'])?$attributes['tri']:$this->aConf['tri'];
  364. # Recuperation du nb d'articles par page de la categorie si besoin est
  365. $this->aCats[$number ]['bypage']=isset($attributes['bypage'])?$attributes['bypage']:$this->bypage;
  366. # Recuperation du fichier template
  367. $this->aCats[$number ]['template']=isset($attributes['template'])?$attributes['template']:'categorie.php';
  368. # Récuperation état affichage de la catégorie dans le menu
  369. $this->aCats[$number ]['menu']=isset($attributes['menu'])?$attributes['menu']:'oui';
  370. # Recuperation du nombre d'article de la categorie
  371. $motif = '/^[0-9]{4}.[home,|0-9,]*'.$number.'[0-9,]*.[0-9]{3}.[0-9]{12}.[A-Za-z0-9-]+.xml$/';
  372. $arts = $this->plxGlob_arts->query($motif);
  373. $this->aCats[$number]['articles'] = ($arts?sizeof($arts):0);
  374. # Hook plugins
  375. eval($this->plxPlugins->callHook('plxMotorGetCategories'));
  376. }
  377. }
  378. }
  379. /**
  380. * Méthode qui parse le fichier des pages statiques et alimente
  381. * le tableau aStats
  382. *
  383. * @param filename emplacement du fichier XML des pages statiques
  384. * @return null
  385. * @author Stéphane F
  386. **/
  387. public function getStatiques($filename) {
  388. if(!is_file($filename)) return;
  389. # Mise en place du parseur XML
  390. $data = implode('',file($filename));
  391. $parser = xml_parser_create(PLX_CHARSET);
  392. xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
  393. xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
  394. xml_parse_into_struct($parser,$data,$values,$iTags);
  395. xml_parser_free($parser);
  396. if(isset($iTags['statique']) AND isset($iTags['name'])) {
  397. $nb = sizeof($iTags['name']);
  398. $size=ceil(sizeof($iTags['statique'])/$nb);
  399. for($i=0;$i<$nb;$i++) {
  400. $attributes = $values[$iTags['statique'][$i*$size]]['attributes'];
  401. $number = $attributes['number'];
  402. # Recuperation du nom de la page statique
  403. $this->aStats[$number]['name'] = isset($iTags['name'][$i])?$values[$iTags['name'][$i]]['value']:'';
  404. # Recuperation du meta description
  405. $this->aStats[$number]['meta_description'] = isset($iTags['meta_description'][$i])?$values[$iTags['meta_description'][$i]]['value']:'';
  406. # Recuperation du meta keywords
  407. $this->aStats[$number]['meta_keywords'] = isset($iTags['meta_keywords'][$i])?$values[$iTags['meta_keywords'][$i]]['value']:'';
  408. # Recuperation du groupe de la page statique
  409. $this->aStats[$number]['group'] = isset($iTags['group'][$i])?$values[$iTags['group'][$i]]['value']:'';
  410. # Recuperation de l'url de la page statique
  411. $this->aStats[$number]['url'] = strtolower($attributes['url']);
  412. # Recuperation de l'etat de la page
  413. $this->aStats[$number]['active'] = intval($attributes['active']);
  414. # On affiche la page statique dans le menu ?
  415. $this->aStats[$number]['menu'] = isset($attributes['menu'])?$attributes['menu']:'oui';
  416. # recuperation du fichier template
  417. $this->aStats[$number]['template'] = isset($attributes['template'])?$attributes['template']:'static.php';
  418. # On verifie que la page statique existe bien
  419. $file = PLX_ROOT.$this->aConf['racine_statiques'].$number.'.'.$attributes['url'].'.php';
  420. # On test si le fichier est lisible
  421. $this->aStats[$number]['readable'] = (is_readable($file) ? 1 : 0);
  422. # Hook plugins
  423. eval($this->plxPlugins->callHook('plxMotorGetStatiques'));
  424. }
  425. }
  426. }
  427. /**
  428. * Méthode qui parse le fichier des utilisateurs
  429. *
  430. * @param filename emplacement du fichier XML des passwd
  431. * @return array tableau des utilisateurs
  432. * @author Stephane F
  433. **/
  434. public function getUsers($filename) {
  435. if(!is_file($filename)) return;
  436. # Mise en place du parseur XML
  437. $data = implode('',file($filename));
  438. $parser = xml_parser_create(PLX_CHARSET);
  439. xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
  440. xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
  441. xml_parse_into_struct($parser,$data,$values,$iTags);
  442. xml_parser_free($parser);
  443. if(isset($iTags['user']) AND isset($iTags['login'])) {
  444. $nb = sizeof($iTags['login']);
  445. $size=ceil(sizeof($iTags['user'])/$nb);
  446. # On boucle sur $nb
  447. for($i = 0; $i < $nb; $i++) {
  448. $attributes = $values[$iTags['user'][$i*$size]]['attributes'];
  449. $number = $attributes['number'];
  450. $this->aUsers[$number]['active'] = $attributes['active'];
  451. $this->aUsers[$number]['delete'] = $attributes['delete'];
  452. $this->aUsers[$number]['profil'] = $attributes['profil'];
  453. $this->aUsers[$number]['login'] = isset($iTags['login'][$i])?$values[ $iTags['login'][$i]]['value']:'';
  454. $this->aUsers[$number]['name'] = isset($iTags['name'][$i])?$values[ $iTags['name'][$i]]['value']:'';
  455. $this->aUsers[$number]['password'] = isset($iTags['password'][$i])?$values[$iTags['password'][$i] ]['value']:'';
  456. $this->aUsers[$number]['salt'] = isset($iTags['salt'][$i])?$values[$iTags['salt'][$i] ]['value']:'';
  457. $this->aUsers[$number]['infos'] = isset($iTags['infos'][$i])?$values[$iTags['infos'][$i]]['value']:'';
  458. $this->aUsers[$number]['email'] = isset($iTags['email'][$i])?$values[$iTags['email'][$i]]['value']:'';
  459. $lang = isset($iTags['lang'][$i]) ? $values[$iTags['lang'][$i]]['value'] : '';
  460. $this->aUsers[$number]['lang'] = $lang!='' ? $lang : $this->aConf['default_lang'];
  461. # Hook plugins
  462. eval($this->plxPlugins->callHook('plxMotorGetUsers'));
  463. }
  464. }
  465. }
  466. /**
  467. * Méthode qui selon le paramètre tri retourne sort ou rsort (tri PHP)
  468. *
  469. * @param tri asc ou desc
  470. * @return string
  471. * @author Stéphane F.
  472. **/
  473. protected function mapTri($tri) {
  474. if($tri=='desc')
  475. return 'rsort';
  476. elseif($tri=='asc')
  477. return 'sort';
  478. elseif($tri=='alpha')
  479. return 'alpha';
  480. else
  481. return 'rsort';
  482. }
  483. /**
  484. * Méthode qui récupère le numéro de la page active
  485. *
  486. * @return null
  487. * @author Anthony GUÉRIN, Florent MONTHEL, Stephane F
  488. **/
  489. protected function getPage() {
  490. # On check pour avoir le numero de page
  491. if(preg_match('/page([0-9]*)/',$this->get,$capture))
  492. $this->page = $capture[1];
  493. else
  494. $this->page = 1;
  495. }
  496. /**
  497. * Méthode qui récupere la liste des articles
  498. *
  499. * @param publi before, after ou all => on récupère tous les fichiers (date) ?
  500. * @return boolean vrai si articles trouvés, sinon faux
  501. * @author Stéphane F
  502. **/
  503. public function getArticles($publi='before') {
  504. # On fait notre traitement sur notre tri
  505. $ordre = $this->mapTri($this->tri);
  506. # On calcule la valeur start
  507. $start = $this->bypage*($this->page-1);
  508. # On recupere nos fichiers (tries) selon le motif, la pagination, la date de publication
  509. if($aFiles = $this->plxGlob_arts->query($this->motif,'art',$ordre,$start,$this->bypage,$publi)) {
  510. # on mémorise le nombre total d'articles trouvés
  511. foreach($aFiles as $k=>$v) # On parcourt tous les fichiers
  512. $array[$k] = $this->parseArticle(PLX_ROOT.$this->aConf['racine_articles'].$v);
  513. # On stocke les enregistrements dans un objet plxRecord
  514. $this->plxRecord_arts = new plxRecord($array);
  515. return true;
  516. }
  517. else return false;
  518. }
  519. /**
  520. * Méthode qui retourne les informations $output en analysant
  521. * le nom du fichier de l'article $filename
  522. *
  523. * @param filename fichier de l'article à traiter
  524. * @return array information à récupérer
  525. * @author Stephane F
  526. **/
  527. protected function artInfoFromFilename($filename) {
  528. # On effectue notre capture d'informations
  529. if(preg_match('/([0-9]{4}).([0-9,|home|draft]*).([0-9]{3}).([0-9]{12}).([a-z0-9-]+).xml$/',$filename,$capture)) {
  530. return array(
  531. 'artId' => $capture[1],
  532. 'catId' => $capture[2],
  533. 'usrId' => $capture[3],
  534. 'artDate' => $capture[4],
  535. 'artUrl' => $capture[5]
  536. );
  537. }
  538. }
  539. /**
  540. * Méthode qui parse l'article du fichier $filename
  541. *
  542. * @param filename fichier de l'article à parser
  543. * @return array
  544. * @author Anthony GUÉRIN, Florent MONTHEL, Stéphane F
  545. **/
  546. public function parseArticle($filename) {
  547. # Mise en place du parseur XML
  548. $data = implode('',file($filename));
  549. $parser = xml_parser_create(PLX_CHARSET);
  550. xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
  551. xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
  552. xml_parse_into_struct($parser,$data,$values,$iTags);
  553. xml_parser_free($parser);
  554. # Recuperation des valeurs de nos champs XML
  555. $art['title'] = trim($values[ $iTags['title'][0] ]['value']);
  556. $art['allow_com'] = trim($values[ $iTags['allow_com'][0] ]['value']);
  557. $art['template'] = (isset($iTags['template'])?trim($values[ $iTags['template'][0] ]['value']):'article.php');
  558. $art['chapo'] = (isset($values[ $iTags['chapo'][0] ]['value']))?trim($values[ $iTags['chapo'][0] ]['value']):'';
  559. $art['content'] = (isset($values[ $iTags['content'][0] ]['value']))?trim($values[ $iTags['content'][0] ]['value']):'';
  560. $art['tags'] = (isset($values[ $iTags['tags'][0] ]['value']))?trim($values[ $iTags['tags'][0] ]['value']):'';
  561. $art['meta_description'] = (isset($iTags['meta_description']))?trim($values[ $iTags['meta_description'][0] ]['value']):'';
  562. $art['meta_keywords'] = (isset($iTags['meta_keywords']))?trim($values[ $iTags['meta_keywords'][0] ]['value']):'';
  563. # Informations obtenues en analysant le nom du fichier
  564. $art['filename'] = $filename;
  565. $tmp = $this->artInfoFromFilename($filename);
  566. $art['numero'] = $tmp['artId'];
  567. $art['author'] = $tmp['usrId'];
  568. $art['categorie'] = $tmp['catId'];
  569. $art['url'] = $tmp['artUrl'];
  570. $art['date'] = plxDate::dateToIso($tmp['artDate'],$this->aConf['delta']);
  571. # On recupere le nombre de commentaires de cet article si besoin est
  572. if($this->mode != 'article') { # En mode article, on a cette information autrement
  573. $motif = '/^'.$art['numero'].'.[0-9]{10}.[0-9]+.xml$/';
  574. $art['nb_com'] = $this->getNbCommentaires($motif);
  575. }
  576. # Hook plugins
  577. eval($this->plxPlugins->callHook('plxMotorParseArticle'));
  578. # On retourne le tableau
  579. return $art;
  580. }
  581. /**
  582. * Méthode qui retourne le nombre de commentaires respectants le motif $motif et le paramètre $publi
  583. *
  584. * @param motif motif de recherche des commentaires
  585. * @param publi before, after ou all => on récupère tous les fichiers (date) ?
  586. * @return integer
  587. * @author Florent MONTHEL
  588. **/
  589. public function getNbCommentaires($motif,$publi='before') {
  590. if($coms = $this->plxGlob_coms->query($motif,'com','sort',0,false,$publi))
  591. return sizeof($coms);
  592. else
  593. return 0;
  594. }
  595. /**
  596. * Méthode qui retourne les informations $output en analysant
  597. * le nom du fichier du commentaire $filename
  598. *
  599. * @param filename fichier du commentaire à traiter
  600. * @return array information à récupérer
  601. * @author Stephane F
  602. **/
  603. protected function comInfoFromFilename($filename) {
  604. # On effectue notre capture d'informations
  605. if(preg_match('/(_?)([0-9]{4}).([0-9]{10})-([0-9])+.xml$/',$filename,$capture)) {
  606. return array(
  607. 'comStatus' => $capture[1],
  608. 'artId' => $capture[2],
  609. 'comDate' => $capture[3],
  610. 'comId' => $capture[3].'-'.$capture[4]
  611. );
  612. }
  613. }
  614. /**
  615. * Méthode qui parse le commentaire du fichier $filename
  616. *
  617. * @param filename fichier du commentaire à parser
  618. * @return array
  619. * @author Florent MONTHEL
  620. **/
  621. public function parseCommentaire($filename) {
  622. # Mise en place du parseur XML
  623. $data = implode('',file($filename));
  624. $parser = xml_parser_create(PLX_CHARSET);
  625. xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
  626. xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
  627. xml_parse_into_struct($parser,$data,$values,$iTags);
  628. xml_parser_free($parser);
  629. # Recuperation des valeurs de nos champs XML
  630. $com['author'] = trim($values[ $iTags['author'][0] ]['value']);
  631. if(isset($iTags['type']))
  632. $com['type'] = (isset($values[ $iTags['type'][0] ]['value']))?trim($values[ $iTags['type'][0] ]['value']):'normal';
  633. else
  634. $com['type'] = 'normal';
  635. $com['ip'] = (isset($values[ $iTags['ip'][0] ]['value']))?trim($values[ $iTags['ip'][0] ]['value']):'';
  636. $com['mail'] = (isset($values[ $iTags['mail'][0] ]['value']))?trim($values[ $iTags['mail'][0] ]['value']):'';
  637. $com['site'] = (isset($values[ $iTags['site'][0] ]['value']))?trim($values[ $iTags['site'][0] ]['value']):'';
  638. $com['content'] = trim($values[ $iTags['content'][0] ]['value']);
  639. # Informations obtenues en analysant le nom du fichier
  640. $tmp = $this->comInfoFromFilename($filename);
  641. $com['status'] = $tmp['comStatus'];
  642. $com['numero'] = $tmp['comId'];
  643. $com['article'] = $tmp['artId'];
  644. $com['date'] = plxDate::timestampToIso($tmp['comDate'],$this->aConf['delta']);
  645. # Hook plugins
  646. eval($this->plxPlugins->callHook('plxMotorParseCommentaire'));
  647. # On retourne le tableau
  648. return $com;
  649. }
  650. /**
  651. * Méthode qui enregistre dans un objet plxRecord tous les commentaires
  652. * respectant le motif $motif et la limite $limite
  653. *
  654. * @param motif motif de recherche des commentaires
  655. * @param ordre ordre du tri : sort ou rsort
  656. * @param start commencement
  657. * @param limite nombre de commentaires à retourner
  658. * @param publi before, after ou all => on récupère tous les fichiers (date) ?
  659. * @return null
  660. * @author Florent MONTHEL
  661. **/
  662. public function getCommentaires($motif,$ordre='sort',$start=0,$limite=false,$publi='before') {
  663. # On recupère les fichiers des commentaires
  664. $aFiles = $this->plxGlob_coms->query($motif,'com',$ordre,$start,$limite,$publi);
  665. if($aFiles) { # On a des fichiers
  666. foreach($aFiles as $k=>$v) # On parcourt tous les fichiers
  667. $array[ $k ] = $this->parseCommentaire(PLX_ROOT.$this->aConf['racine_commentaires'].$v);
  668. # On stocke les enregistrements dans un objet plxRecord
  669. $this->plxRecord_coms = new plxRecord($array);
  670. return true;
  671. }
  672. else return false;
  673. }
  674. /**
  675. * Méthode qui crée un nouveau commentaire pour l'article $artId
  676. *
  677. * @param artId identifiant de l'article en question
  678. * @param content tableau contenant les valeurs du nouveau commentaire
  679. * @return string
  680. * @author Florent MONTHEL, Stéphane F
  681. **/
  682. public function newCommentaire($artId,$content) {
  683. # Hook plugins
  684. if(eval($this->plxPlugins->callHook('plxMotorNewCommentaire'))) return;
  685. # On verifie que le capcha est correct
  686. if($this->aConf['capcha'] == 0 OR $content['rep2'] == sha1($content['rep'])) {
  687. if(!empty($content['name']) AND !empty($content['content'])) { # Les champs obligatoires sont remplis
  688. $comment=array();
  689. $comment['type'] = 'normal';
  690. $comment['author'] = plxUtils::strCheck(trim($content['name']));
  691. $comment['content'] = plxUtils::strCheck(trim($content['content']));
  692. # On verifie le mail
  693. $comment['mail'] = (plxUtils::checkMail(trim($content['mail'])))?trim($content['mail']):'';
  694. # On verifie le site
  695. $comment['site'] = (plxUtils::checkSite(trim($content['site'])))?trim($content['site']):'';
  696. # On recupere l'adresse IP du posteur
  697. $comment['ip'] = plxUtils::getIp();
  698. # On genere le nom du fichier selon l'existence ou non d'un fichier du meme nom
  699. $date = time();
  700. $i = 0;
  701. do { # On boucle en testant l'existence du fichier (cas de plusieurs commentaires/sec pour un article)
  702. $i++;
  703. if($this->aConf['mod_com']) # On modere le commentaire => underscore
  704. $comment['filename'] = PLX_ROOT.$this->aConf['racine_commentaires'].'_'.$artId.'.'.$date.'-'.$i.'.xml';
  705. else # On publie le commentaire directement
  706. $comment['filename'] = PLX_ROOT.$this->aConf['racine_commentaires'].$artId.'.'.$date.'-'.$i.'.xml';
  707. } while(file_exists($comment['filename']));
  708. # On peut creer le commentaire
  709. if($this->addCommentaire($comment)) { # Commentaire OK
  710. if($this->aConf['mod_com']) # En cours de moderation
  711. return 'mod';
  712. else # Commentaire publie directement, on retourne son identifiant
  713. return 'c'.$date.'-'.$i;
  714. } else { # Erreur lors de la création du commentaire
  715. return L_NEWCOMMENT_ERR;
  716. }
  717. } else { # Erreur de remplissage des champs obligatoires
  718. return L_NEWCOMMENT_FIELDS_REQUIRED;
  719. }
  720. } else { # Erreur de verification capcha
  721. return L_NEWCOMMENT_ERR_ANTISPAM;
  722. }
  723. }
  724. /**
  725. * Méthode qui crée physiquement le fichier XML du commentaire
  726. *
  727. * @param comment array avec les données du commentaire à ajouter
  728. * @return booléen
  729. * @author Anthony GUÉRIN, Florent MONTHEL et Stéphane F
  730. **/
  731. public function addCommentaire($content) {
  732. # Hook plugins
  733. if(eval($this->plxPlugins->callHook('plxMotorAddCommentaire'))) return;
  734. # On genere le contenu de notre fichier XML
  735. $xml = "<?xml version='1.0' encoding='".PLX_CHARSET."'?>\n";
  736. $xml .= "<comment>\n";
  737. $xml .= "\t<author><![CDATA[".plxUtils::cdataCheck($content['author'])."]]></author>\n";
  738. $xml .= "\t<type>".$content['type']."</type>\n";
  739. $xml .= "\t<ip>".$content['ip']."</ip>\n";
  740. $xml .= "\t<mail><![CDATA[".plxUtils::cdataCheck($content['mail'])."]]></mail>\n";
  741. $xml .= "\t<site><![CDATA[".plxUtils::cdataCheck($content['site'])."]]></site>\n";
  742. $xml .= "\t<content><![CDATA[".plxUtils::cdataCheck($content['content'])."]]></content>\n";
  743. # Hook plugins
  744. eval($this->plxPlugins->callHook('plxMotorAddCommentaireXml'));
  745. $xml .= "</comment>\n";
  746. # On ecrit ce contenu dans notre fichier XML
  747. return plxUtils::write($xml,$content['filename']);
  748. }
  749. /**
  750. * Méthode qui parse le fichier des tags et alimente
  751. * le tableau aTags
  752. *
  753. * @param filename emplacement du fichier XML contenant les tags
  754. * @return null
  755. * @author Stephane F.
  756. **/
  757. public function getTags($filename) {
  758. if(!is_file($filename)) return;
  759. # Mise en place du parseur XML
  760. $data = implode('',file($filename));
  761. $parser = xml_parser_create(PLX_CHARSET);
  762. xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
  763. xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
  764. xml_parse_into_struct($parser,$data,$values,$iTags);
  765. xml_parser_free($parser);
  766. $array = array();
  767. # On verifie qu'il existe des tags "file"
  768. if(isset($iTags['article'])) {
  769. # On compte le nombre de tags "file"
  770. $nb = sizeof($iTags['article']);
  771. # On boucle sur $nb
  772. for($i = 0; $i < $nb; $i++) {
  773. if(isset($values[ $iTags['article'][$i] ]['value']))
  774. $array[ $values[ $iTags['article'][$i] ]['attributes']['number'] ]['tags'] = trim($values[ $iTags['article'][$i] ]['value']);
  775. else
  776. $array[ $values[ $iTags['article'][$i] ]['attributes']['number'] ]['tags'] = '';
  777. $array[ $values[ $iTags['article'][$i] ]['attributes']['number'] ]['date'] = $values[ $iTags['article'][$i] ]['attributes']['date'];
  778. $array[ $values[ $iTags['article'][$i] ]['attributes']['number'] ]['active'] = $values[ $iTags['article'][$i] ]['attributes']['active'];
  779. }
  780. }
  781. # Mémorisation de la liste des tags
  782. $this->aTags = $array;
  783. }
  784. /**
  785. * Méthode qui lance le téléchargement d'un document
  786. *
  787. * @param cible cible de téléchargement cryptée
  788. * @return booleen
  789. * @author Stephane F. et Florent MONTHEL
  790. **/
  791. public function sendTelechargement($cible) {
  792. # On décrypte le nom du fichier
  793. $file = PLX_ROOT.$this->aConf['documents'].plxEncrypt::decryptId($cible);
  794. # Hook plugins
  795. if(eval($this->plxPlugins->callHook('plxMotorSendDownload'))) return;
  796. # On lance le téléchargement et on check le répertoire documents
  797. if(@file_exists($file) AND preg_match('#^'.str_replace('\\', '/', realpath(PLX_ROOT.$this->aConf['documents']).'#'), str_replace('\\', '/', realpath($file)))) {
  798. header('Content-Description: File Transfer');
  799. header('Content-Type: application/download');
  800. header('Content-Disposition: attachment; filename='.basename($file));
  801. header('Content-Transfer-Encoding: binary');
  802. header('Expires: 0');
  803. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  804. header('Pragma: no-cache');
  805. header('Content-Length: '.filesize($file));
  806. readfile($file);
  807. exit;
  808. } else { # On retourne false
  809. return false;
  810. }
  811. }
  812. /**
  813. * Méthode qui réécrit les urls pour supprimer le ?
  814. *
  815. * @param url url à réécrire
  816. * @return string url réécrite
  817. * @author Stéphane F
  818. **/
  819. public function urlRewrite($url='') {
  820. if($url=='') return $this->racine;
  821. preg_match('/^([0-9a-z\_\-\.\/]+)?[\?]?([0-9a-z\_\-\.\/]+)?[\#]?(.*)$/i', $url, $args);
  822. if($this->aConf['urlrewriting']) {
  823. $new_url = str_replace('index.php', '', $args[1]);
  824. $new_url = str_replace('feed.php', 'feed/', $new_url);
  825. $new_url .= !empty($args[2])?$args[2]:'';
  826. if(empty($new_url)) $new_url = $this->path_url;
  827. $new_url .= !empty($args[3])?'#'.$args[3]:'';
  828. return $this->racine.$new_url;
  829. } else {
  830. if(empty($args[1]) AND !empty($args[2])) $args[1] = 'index.php';
  831. $new_url = !empty($args[1])?$args[1]:$this->path_url;
  832. $new_url .= !empty($args[2])?'?'.$args[2]:'';
  833. $new_url .= !empty($args[3])?'#'.$args[3]:'';
  834. return $this->racine.$new_url;
  835. }
  836. }
  837. /**
  838. * Méthode qui comptabilise le nombre d'articles du site.
  839. *
  840. * @param select critere de recherche: draft, published, all, n° categories séparés par un |
  841. * @param userid filtre sur les articles d'un utilisateur donné
  842. * @return integer nombre d'articles
  843. * @scope global
  844. * @author Stephane F
  845. **/
  846. public function nbArticles($select='all', $userId='[0-9]{3}') {
  847. $nb = 0;
  848. if($select == 'all')
  849. $motif = '[home|draft|0-9,]*';
  850. elseif($select=='published')
  851. $motif = '[home|0-9,]*';
  852. elseif($select=='draft')
  853. $motif = '[\w,]*[draft][\w,]*';
  854. else
  855. $motif = $select;
  856. if($arts = $this->plxGlob_arts->query('/^[0-9]{4}.('.$motif.').'.$userId.'.[0-9]{12}.[a-z0-9-]+.xml$/'))
  857. $nb = sizeof($arts);
  858. return $nb;
  859. }
  860. /**
  861. * Méthode qui comptabilise le nombre de commentaires du site
  862. *
  863. * @param select critere de recherche: all, online, offline
  864. * @return integer nombre d'articles
  865. * @scope global
  866. * @author Stephane F
  867. **/
  868. public function nbComments($select='online') {
  869. $nb = 0;
  870. if($select == 'all')
  871. $motif = '/^_?[0-9]{4}.(.*).xml$/';
  872. elseif($select=='offline')
  873. $motif = '/^_[0-9]{4}.(.*).xml$/';
  874. elseif($select=='online')
  875. $motif = '/^[0-9]{4}.(.*).xml$/';
  876. else
  877. $motif = '/^_?'.$select.'.(.*).xml$/';
  878. if($coms = $this->plxGlob_coms->query($motif))
  879. $nb = sizeof($coms);
  880. return $nb;
  881. }
  882. }
  883. ?>