PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/main/class/class_procedure.php

http://github.com/FSB/Fire-Soft-Board-2
PHP | 560 lines | 339 code | 51 blank | 170 comment | 35 complexity | b3d903bdf7f23add1c8114c05ab5ff31 MD5 | raw file
  1. <?php
  2. /**
  3. * Fire-Soft-Board version 2
  4. *
  5. * @package FSB2
  6. * @author Genova <genova@fire-soft-board.com>
  7. * @version $Id$
  8. * @license http://opensource.org/licenses/gpl-2.0.php GNU GPL 2
  9. */
  10. /**
  11. * Parse et execute des procedures de moderation (decrites par du XML)
  12. */
  13. class Procedure extends Fsb_model
  14. {
  15. /**
  16. * Numero de l'instruction en cours
  17. *
  18. * @var int
  19. */
  20. private $line_number = 1;
  21. /**
  22. * Variables definies
  23. *
  24. * @var array
  25. */
  26. private $vars = array();
  27. /**
  28. * Contient la liste des instructions avec les parametres obligatoires
  29. *
  30. * @var array
  31. */
  32. private $fcts = array(
  33. 'var' => array('varname', 'value'),
  34. 'input' => array('explain', 'default'),
  35. 'lock' => array('topicID' => 'intval'),
  36. 'unlock' => array('topicID' => 'intval'),
  37. 'move' => array('topicID' => 'intval', 'forumID' => 'intval', 'trace'),
  38. 'delete_topic' => array('topicID' => 'intval'),
  39. 'delete_post' => array('postID' => 'intval'),
  40. 'warn' => array('warnType', 'warnUserID' => 'intval', 'toID' => 'intval', 'reason'),
  41. 'ban' => array('banType', 'banContent', 'reason', 'banLength' => 'intval'),
  42. 'send_mp' => array('fromID' => 'intval', 'toID' => 'intval', 'title', 'content'),
  43. 'send_post' => array('fromID' => 'intval', 'topicID' => 'intval', 'content'),
  44. 'redirect' => array('url'),
  45. 'global' => array('varname'),
  46. 'userdata' => array(),
  47. 'watch_topic' => array('topicID' => 'intval', 'watch'),
  48. );
  49. /**
  50. * Constructeur
  51. */
  52. public function __construct()
  53. {
  54. $this->set_var('this', array());
  55. }
  56. /**
  57. * Assigne une variable
  58. *
  59. * @param string $name Nom de la variable
  60. * @param string $value Valeur de la variable
  61. */
  62. public function set_var($name, $value = null)
  63. {
  64. $split = explode('.', $name);
  65. $count = count($split) - 1;
  66. $ref = &$this->vars;
  67. for ($i = 0; $i < $count; $i++)
  68. {
  69. if (!isset($ref[$split[$i]]))
  70. {
  71. $ref = array();
  72. }
  73. $ref = &$ref[$split[$i]];
  74. }
  75. $ref[$split[$i]] = $value;
  76. }
  77. /**
  78. * Parse et execute une procedure de moderation
  79. *
  80. * @param string $code Code XML a parser
  81. */
  82. public function parse($code)
  83. {
  84. // Chargement des variables
  85. if (isset($_POST['save']))
  86. {
  87. foreach ($_POST['save'] AS $k => $v)
  88. {
  89. $this->set_var($k, unserialize($v));
  90. }
  91. }
  92. // Parse XML de la procedure
  93. $xml = new Xml;
  94. $xml->load_content($code);
  95. foreach ($xml->document->function AS $line)
  96. {
  97. // Recuperation des arguments
  98. $argv = array();
  99. $function = $line->getAttribute('name');
  100. foreach ($line->children() AS $child)
  101. {
  102. $tagname = $child[0]->getTagName();
  103. if ($child[0]->hasChildren())
  104. {
  105. // Argument qui prendra le retour d'une fonction
  106. $sub_function = $child[0]->function[0]->getAttribute('name');
  107. $sub_argv = array();
  108. foreach ($child[0]->function[0]->children() AS $sub_child)
  109. {
  110. $sub_argv[$sub_child[0]->getTagName()] = $this->parse_vars($sub_child[0]->getData());
  111. }
  112. $argv[$tagname] = $this->call_method($sub_function, $sub_argv);
  113. }
  114. else
  115. {
  116. // Argument qui prendra une valeur
  117. $argv[$tagname] = $this->parse_vars($child[0]->getData());
  118. }
  119. }
  120. // Execution de la fonction
  121. $this->call_method($function, $argv);
  122. $this->line_number++;
  123. }
  124. }
  125. /**
  126. * Remplace les variables dans la chaine de caractere
  127. *
  128. * @param string $str
  129. * @return string
  130. */
  131. private function parse_vars($str)
  132. {
  133. preg_match_all('#\{([a-zA-Z0-9_\.]+)\}#i', $str, $match);
  134. $count = count($match[0]);
  135. for ($i = 0; $i < $count; $i++)
  136. {
  137. $split = explode('.', $match[1][$i]);
  138. $var = &$this->vars;
  139. foreach ($split AS $varname)
  140. {
  141. if (!isset($var[$varname]))
  142. {
  143. $this->error('La variable ' . $match[1][$i] . ' n\'existe pas');
  144. }
  145. $var = &$var[$varname];
  146. }
  147. $str = str_replace($match[0][$i], $var, $str);
  148. }
  149. return ($str);
  150. }
  151. /**
  152. * Affiche une erreur
  153. *
  154. * @param string $errstr
  155. */
  156. private function error($errstr)
  157. {
  158. die('<b>FSB Fatal error : <i>' . $errstr . '</i> a la ligne ' . $this->line_number . ' de la procedure<br />');
  159. }
  160. /**
  161. * Met les variables en champs caches
  162. *
  163. * @param array $node Liste de variables a sauver
  164. * @param string $varname
  165. */
  166. private function save_vars(&$node, $varname = '')
  167. {
  168. foreach ($node AS $k => $v)
  169. {
  170. if (is_array($v))
  171. {
  172. $this->save_vars($v, $varname . $k . '.');
  173. }
  174. else
  175. {
  176. Fsb::$tpl->set_blocks('hidden', array(
  177. 'NAME' => 'save[' . $varname . $k . ']',
  178. 'VALUE' => htmlspecialchars(serialize($v)),
  179. ));
  180. }
  181. }
  182. }
  183. /**
  184. * Met les variables GP en champs caches
  185. *
  186. * @param array $var
  187. * @param string $varname
  188. */
  189. private function save_gp_vars(&$var, $varname = '')
  190. {
  191. foreach ($var AS $k => $v)
  192. {
  193. if (is_array($v))
  194. {
  195. $this->save_gp_vars($v, (!$varname) ? $k : $varname . '[' . $k . ']');
  196. }
  197. else
  198. {
  199. Fsb::$tpl->set_blocks('hidden', array(
  200. 'NAME' => (!$varname) ? $k : $varname . '[' . $k . ']',
  201. 'VALUE' => htmlspecialchars($v),
  202. ));
  203. }
  204. }
  205. }
  206. /**
  207. * Appel une methode des procedures de moderation
  208. *
  209. * @param string $method Nom de la methode
  210. * @param array $argv Arguments
  211. * @return mixed
  212. */
  213. private function call_method($method, $argv)
  214. {
  215. // Existance de la methode
  216. $call = 'process_' . $method;
  217. if (!method_exists($this, $call) || !isset($this->fcts[$method]))
  218. {
  219. $this->error('La methode ' . $call . ' n\'existe pas');
  220. }
  221. // Verification des arguments
  222. foreach ($this->fcts[$method] AS $key => $value)
  223. {
  224. if (is_int($key))
  225. {
  226. if (!isset($argv[$value]))
  227. {
  228. $this->error('Il manque l\'argument ' . $value . ' pour la fonction ' . $method);
  229. }
  230. }
  231. else
  232. {
  233. if (!isset($argv[$key]))
  234. {
  235. $this->error('Il manque l\'argument ' . $key . ' pour la fonction ' . $method);
  236. }
  237. if (!function_exists($value))
  238. {
  239. $this->error('La fonction de filtre ' . $value . ' n\'existe pas');
  240. }
  241. $argv[$key] = $value($argv[$key]);
  242. }
  243. }
  244. return ($this->$call($argv));
  245. }
  246. /**
  247. * Transforme un pseudonyme en ID
  248. *
  249. * @param string $str
  250. * @return string
  251. */
  252. private function nickname_to_id($str)
  253. {
  254. if (!is_numeric($str))
  255. {
  256. $sql = 'SELECT u_id
  257. FROM ' . SQL_PREFIX . 'users
  258. WHERE u_nickname = \'' . Fsb::$db->escape($str) . '\'';
  259. return (Fsb::$db->get($sql, 'u_id'));
  260. }
  261. return ($str);
  262. }
  263. //
  264. // Fonctions utilisables dans les procedures
  265. //
  266. /**
  267. * Assigne une variable
  268. *
  269. * @param array $argv
  270. */
  271. private function process_var($argv)
  272. {
  273. $this->set_var($argv['varname'], $argv['value']);
  274. }
  275. /**
  276. * Affiche un formulaire et recupere la valeur de la variable
  277. *
  278. * @param array $argv
  279. */
  280. private function process_input($argv)
  281. {
  282. $identifier = 'submit_process_input_' . $this->line_number;
  283. if (Http::request($identifier, 'post'))
  284. {
  285. $value = Http::request($identifier . '_value', 'post');
  286. return ($value);
  287. }
  288. else
  289. {
  290. Fsb::$tpl->set_file('handler_process.html');
  291. if ($argv['type'] == 'textarea')
  292. {
  293. Fsb::$tpl->set_switch('input_textarea');
  294. }
  295. Fsb::$tpl->set_vars(array(
  296. 'PROCESS_TEXT' => $argv['explain'],
  297. 'DEFAULT_VALUE' => (isset($argv['default'])) ? $argv['default'] : '',
  298. 'INPUT_IDENTIFIER' => $identifier,
  299. ));
  300. // On met les variables actuelles en champs caches
  301. $this->save_vars($this->vars);
  302. $this->save_gp_vars($_POST);
  303. $this->save_gp_vars($_GET);
  304. Fsb::$frame->frame_footer();
  305. exit;
  306. }
  307. }
  308. /**
  309. * Verrouille un sujet
  310. *
  311. * @param array $argv
  312. */
  313. private function process_lock($argv)
  314. {
  315. Moderation::lock_topic($argv['topicID'], LOCK);
  316. }
  317. /**
  318. * Deverrouille un sujet
  319. *
  320. * @param array $argv
  321. */
  322. private function process_unlock($argv)
  323. {
  324. Moderation::lock_topic($argv['topicID'], UNLOCK);
  325. }
  326. /**
  327. * Envoie un message prive
  328. *
  329. * @param array $argv
  330. */
  331. private function process_send_mp($argv)
  332. {
  333. $argv['fromID'] = $this->nickname_to_id($argv['fromID']);
  334. $argv['toID'] = $this->nickname_to_id($argv['toID']);
  335. Send::send_mp($argv['fromID'], $argv['toID'], $argv['title'], $argv['content']);
  336. }
  337. /**
  338. * Redirige
  339. *
  340. * @param array $argv
  341. */
  342. private function process_redirect($argv)
  343. {
  344. // On log l'action de moderation, car la procedure fini la
  345. Log::add(Log::MODO, 'log_procedure', $this->name);
  346. Http::redirect($argv['url']);
  347. }
  348. /**
  349. * Ajoute un message au sujet
  350. *
  351. * @param array $argv
  352. */
  353. private function process_send_post($argv)
  354. {
  355. // Donnees du sujet
  356. $sql = 'SELECT f_id, t_title
  357. FROM ' . SQL_PREFIX . 'topics
  358. WHERE t_id = ' . $argv['topicID'];
  359. $topic_data = Fsb::$db->request($sql);
  360. // Donnees du membre
  361. if (intval($argv['fromID']) != Fsb::$session->id())
  362. {
  363. $sql = 'SELECT u_nickname
  364. FROM ' . SQL_PREFIX . 'users
  365. WHERE u_id = ' . $argv['fromID'];
  366. $user_data = Fsb::$db->request($sql);
  367. }
  368. else
  369. {
  370. $user_data = Fsb::$session->data;
  371. }
  372. // Contenu en XML
  373. $message = new Xml();
  374. $message->document->setTagName('root');
  375. $message_line = $message->document->createElement('line');
  376. $message_line->setAttribute('name', 'description');
  377. $message_line->setData(htmlspecialchars($argv['content']));
  378. $message->document->appendChild($message_line);
  379. Send::send_post($argv['fromID'], $argv['topicID'], $topic_data['f_id'], $message->document->asValidXML(), $user_data['u_nickname'], IS_APPROVED, 'classic', array(
  380. 't_title' => $topic_data['t_title'],
  381. ), false);
  382. }
  383. /**
  384. * Deplace un sujet
  385. *
  386. * @param array $argv
  387. */
  388. private function process_move($argv)
  389. {
  390. // Donnees du sujet
  391. $sql = 'SELECT f_id
  392. FROM ' . SQL_PREFIX . 'topics
  393. WHERE t_id = ' . $argv['topicID'];
  394. $topic_data = Fsb::$db->request($sql);
  395. Moderation::move_topics($argv['topicID'], $topic_data['f_id'], $argv['forumID'], ($argv['trace'] == 'true') ? true : false);
  396. }
  397. /**
  398. * Banissement
  399. *
  400. * @param array $argv
  401. */
  402. private function process_ban($argv)
  403. {
  404. Moderation::ban($argv['banType'], $argv['banContent'], $argv['reason'], $argv['banLength'], false);
  405. }
  406. /**
  407. * Donne un avertissement
  408. *
  409. * @param array $argv
  410. */
  411. private function process_warn($argv)
  412. {
  413. $argv['warnType'] = ($argv['warnType'] != 'less') ? 'more' : $argv['warnType'];
  414. // Donnees du membre
  415. $sql = 'SELECT u_id, u_warn_post, u_warn_read, u_total_warning
  416. FROM ' . SQL_PREFIX . 'users
  417. WHERE u_id = ' . $argv['toID'] . '
  418. AND u_id <> ' . VISITOR_ID;
  419. if ($to = Fsb::$db->request($sql))
  420. {
  421. if (($argv['warnType'] == 'more' && $to['u_total_warning'] < 5) || ($argv['warnType'] == 'less' && $to['u_total_warning'] > 0))
  422. {
  423. Moderation::warn_user($argv['warnType'], $argv['warnUserID'], $to['u_id'], $argv['reason'], $to['u_warn_post'], $to['u_warn_read'], array(
  424. 'post_check' => false,
  425. 'read_check' => false,
  426. ));
  427. }
  428. }
  429. }
  430. /**
  431. * Supprime un message
  432. *
  433. * @param array $argv
  434. */
  435. private function process_delete_post($argv)
  436. {
  437. Moderation::delete_posts('p_id = ' . $argv['postID']);
  438. }
  439. /**
  440. * Supprime un sujet
  441. *
  442. * @param array $argv
  443. */
  444. private function process_delete_topic($argv)
  445. {
  446. Moderation::delete_topics('t_id = ' . $argv['topicID']);
  447. }
  448. /**
  449. * Recupere les informations sur un utilisateur
  450. *
  451. * @param array $argv
  452. */
  453. private function process_userdata($argv)
  454. {
  455. $where = '';
  456. if (isset($argv['userID']))
  457. {
  458. $where = 'WHERE u_id = ' . $argv['userID'];
  459. }
  460. else if (isset($argv['username']))
  461. {
  462. $where = 'WHERE u_nickname = \'' . Fsb::$db->escape($argv['username']) . '\'';
  463. }
  464. $sql = 'SELECT *
  465. FROM ' . SQL_PREFIX . 'users
  466. ' . $where;
  467. $result = Fsb::$db->query($sql);
  468. $return = Fsb::$db->row($result);
  469. Fsb::$db->free($result);
  470. if (!$return)
  471. {
  472. Display::message('user_not_exists');
  473. }
  474. return ((isset($argv['return'])) ? $return[$argv['return']] : $return);
  475. }
  476. /**
  477. * Recupere le contenu d'une variable globale PHP
  478. *
  479. * @param array $argv
  480. */
  481. private function process_global()
  482. {
  483. return ($GLOBALS[$argv['varname']]);
  484. }
  485. /**
  486. * Surveille un sujet
  487. *
  488. * @param array $argv
  489. */
  490. private function process_watch_topic($argv)
  491. {
  492. if ($argv['watch'] == 'true')
  493. {
  494. Fsb::$db->insert('topics_notification', array(
  495. 't_id' => array($argv['topicID'], true),
  496. 'u_id' => array(Fsb::$session->id(), true),
  497. 'tn_status' => IS_NOT_NOTIFIED,
  498. ), 'REPLACE');
  499. }
  500. else
  501. {
  502. $sql = 'DELETE FROM ' . SQL_PREFIX . 'topics_notification
  503. WHERE t_id = ' . $argv['topicID'] . '
  504. AND u_id = ' . Fsb::$session->id();
  505. Fsb::$db->query($sql);
  506. }
  507. }
  508. }
  509. /* EOF */