PageRenderTime 27ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/admin/tools/tools_webftp.php

http://github.com/FSB/Fire-Soft-Board-2
PHP | 555 lines | 373 code | 60 blank | 122 comment | 65 complexity | 0d87de2059fbe6b5f14bbedad17fd893 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. * Page generant un webftp.
  12. * Il est possible d'acceder directement aux fichiers du forum afin de les supprimer / editer, ou bien d'en uploader
  13. * de nouveaux. On peut trier les fichiers, changer les droits, etc ...
  14. */
  15. class Fsb_frame_child extends Fsb_admin_frame
  16. {
  17. /**
  18. * Fichiers recuperes dans un tableau
  19. *
  20. * @var array
  21. */
  22. public $data = array();
  23. /**
  24. * Dossier courant
  25. *
  26. * @var string
  27. */
  28. public $dir;
  29. /**
  30. * Nom du fichier courant
  31. *
  32. * @var string
  33. */
  34. public $filename;
  35. /**
  36. * Mode
  37. *
  38. * @var string
  39. */
  40. public $mode;
  41. /**
  42. * Classement des fichiers
  43. *
  44. * @var string
  45. */
  46. public $order;
  47. /**
  48. * Sens du classement des fichiers
  49. *
  50. * @var string
  51. */
  52. public $order_direction;
  53. /**
  54. * Les fichiers editables
  55. *
  56. * @var array
  57. */
  58. public $edit_file = array('php', 'php3', 'php4', 'php5', 'htm', 'html', 'tpl', 'txt', 'css', 'js', 'xml', 'rss', 'htaccess');
  59. /**
  60. * Constructeur
  61. */
  62. public function main()
  63. {
  64. // On recupere les arguments de la page
  65. $this->dir = htmlspecialchars(Http::request('dir'));
  66. if ($this->dir == null)
  67. {
  68. $this->dir = '';
  69. }
  70. $this->dir = str_replace('../', '', $this->dir);
  71. $this->filename = htmlspecialchars(Http::request('file'));
  72. if ($this->filename != null)
  73. {
  74. $ary = explode('.', $this->filename);
  75. if (!file_exists(ROOT . $this->dir . $this->filename) || ($this->mode == 'edit' && !in_array($ary[count($ary) - 1], $this->edit_file)))
  76. {
  77. Display::message('adm_webftp_file_not_exists');
  78. }
  79. unset($ary);
  80. }
  81. $this->order = htmlspecialchars(Http::request('order'));
  82. if ($this->order == null)
  83. {
  84. $this->order = 'type';
  85. }
  86. $this->order_direction = htmlspecialchars(Http::request('order_direction'));
  87. if ($this->order_direction == null)
  88. {
  89. $this->order_direction = 'asc';
  90. }
  91. $this->mode = Http::request('mode');
  92. $call = new Call($this);
  93. $call->post(array(
  94. 'submit_upload' => ':upload_file',
  95. 'submit_chmod' => ':chmod_file',
  96. 'submit_edit' => ':submit_edit_file',
  97. ));
  98. $call->functions(array(
  99. 'mode' => array(
  100. 'highlight_php' => 'page_php_highlight',
  101. 'codepress' => 'page_codepress',
  102. 'delete' => 'page_delete_file',
  103. 'edit' => 'edit_file',
  104. 'default' => 'webftp_list_file',
  105. ),
  106. ));
  107. }
  108. /**
  109. * Affiche les fichiers du repertoire courant
  110. */
  111. public function webftp_list_file()
  112. {
  113. Fsb::$tpl->set_switch('webftp_list');
  114. Fsb::$tpl->set_vars(array(
  115. 'CURRENT_DIR' => stripslashes($this->dir),
  116. 'USE_FTP' => (Fsb::$cfg->get('ftp_default')) ? true : false,
  117. 'U_ACTION' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir),
  118. 'U_WEBFTP_NAME' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir . '&amp;order=name&amp;order_direction=' . (($this->order == 'name') ? (($this->order_direction == 'asc') ? 'desc' : 'asc') : 'asc')),
  119. 'U_WEBFTP_TYPE' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir . '&amp;order=type&amp;order_direction=' . (($this->order == 'type') ? (($this->order_direction == 'asc') ? 'desc' : 'asc') : 'asc')),
  120. 'U_WEBFTP_SIZE' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir . '&amp;order=size&amp;order_direction=' . (($this->order == 'size') ? (($this->order_direction == 'asc') ? 'desc' : 'asc') : 'asc')),
  121. 'U_WEBFTP_PERMS' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir . '&amp;order=perms&amp;order_direction=' . (($this->order == 'perms') ? (($this->order_direction == 'asc') ? 'desc' : 'asc') : 'asc')),
  122. 'U_WEBFTP_DATE' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir . '&amp;order=date&amp;order_direction=' . (($this->order == 'date') ? (($this->order_direction == 'asc') ? 'desc' : 'asc') : 'asc')),
  123. ));
  124. // On recupere les fichiers du repertoire dans un tableau avec leurs donnees (date, permissiones, extension, etc ...)
  125. $fd = opendir(ROOT . $this->dir);
  126. while ($file = readdir($fd))
  127. {
  128. if ($file != '.' && $file != '..')
  129. {
  130. $ary = explode('.', $file);
  131. $ext = $ary[count($ary) - 1];
  132. unset($ary);
  133. $is_dir = is_dir(ROOT . $this->dir . $file);
  134. $this->data[] = array(
  135. 'name' => $file,
  136. 'type' => ($is_dir) ? null : $ext,
  137. 'size' => ($is_dir) ? (($this->order_direction == 'asc') ? (pow(2, 32) - 1) : 0) : filesize(ROOT . $this->dir . $file),
  138. 'perms' => $this->get_perms(fileperms(ROOT . $this->dir . $file)),
  139. 'date' => filemtime(ROOT . $this->dir . $file),
  140. 'is_dir' => $is_dir,
  141. );
  142. }
  143. }
  144. // On trie les donnees si besoin
  145. usort($this->data, array($this, 'order_file'));
  146. // Retour vers dossier precedent, et retour vers la racine du forum
  147. foreach (array('root' => '~/', 'back' => '../') AS $key => $value)
  148. {
  149. Fsb::$tpl->set_blocks('file', array(
  150. 'NAME' => $value,
  151. 'TYPE' => Fsb::$session->lang('adm_webftp_dir'),
  152. 'SIZE' => '---',
  153. 'DATE' => '---',
  154. 'PERMS' => '---',
  155. 'IMG_TYPE' => 'adm_tpl/img/dir.gif',
  156. 'CAN_EDIT' => false,
  157. 'CAN_DELETE' => false,
  158. 'U_DIR' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . (($key == 'back') ? dirname($this->dir) : '') . '/&amp;order=' . $this->order . '&amp;order_direction=' . $this->order_direction),
  159. ));
  160. }
  161. // On affiche les fichiers ligne par ligne
  162. foreach ($this->data AS $value)
  163. {
  164. // Lien vers le fichier
  165. if ($value['is_dir'])
  166. {
  167. $u_dir = sid('index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir . $value['name'] . '/&amp;order=' . $this->order . '&amp;order_direction=' . $this->order_direction);
  168. }
  169. else if (preg_match('#^php[0-9]?$#i', $value['type']) && function_exists('highlight_file'))
  170. {
  171. $u_dir = sid('index.' . PHPEXT . '?p=tools_webftp&amp;mode=highlight_php&amp;dir=' . $this->dir . '&amp;phpfile=' . $value['name']);
  172. }
  173. else
  174. {
  175. $u_dir = ROOT . $this->dir . $value['name'];
  176. }
  177. Fsb::$tpl->set_blocks('file', array(
  178. 'ACTION_NAME' => $this->dir . $value['name'],
  179. 'NAME' => $value['name'],
  180. 'TYPE' => ($value['type'] == null) ? Fsb::$session->lang('adm_webftp_dir') : sprintf(Fsb::$session->lang('adm_webftp_file'), strtoupper($value['type'])),
  181. 'SIZE' => ($value['is_dir']) ? '---' : convert_size($value['size']),
  182. 'PERMS' => $value['perms'],
  183. 'DATE' => date('d/m/Y H:i:s', $value['date']),
  184. 'IMG_TYPE' => (($value['is_dir']) ? 'adm_tpl/img/dir.gif' : 'adm_tpl/img/' . $this->get_type_img($value['type']) . '.gif'),
  185. 'CAN_EDIT' => (in_array($value['type'], $this->edit_file)) ? true : false,
  186. 'CAN_DELETE' => true,
  187. 'U_DIR' => $u_dir,
  188. 'U_EDIT' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;mode=edit&amp;dir=' . $this->dir . '&amp;file=' . $value['name']),
  189. 'U_DELETE' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;mode=delete&amp;dir=' . $this->dir . '&amp;file=' . $value['name']),
  190. ));
  191. }
  192. }
  193. /**
  194. * Converti des permissions (octal) en permissions symboliques (rwx)
  195. * http://fr.php.net/manual/fr/function.fileperms.php
  196. *
  197. * @param int $perms permissions en octal
  198. * @return string permission symbolique
  199. */
  200. public function get_perms($perms)
  201. {
  202. if (($perms & 0xC000) == 0xC000)
  203. {
  204. // Socket
  205. $info = 's';
  206. }
  207. elseif (($perms & 0xA000) == 0xA000)
  208. {
  209. // Lien symbolique
  210. $info = 'l';
  211. }
  212. elseif (($perms & 0x8000) == 0x8000)
  213. {
  214. // Regulier
  215. $info = '-';
  216. }
  217. elseif (($perms & 0x6000) == 0x6000)
  218. {
  219. // Block special
  220. $info = 'b';
  221. }
  222. elseif (($perms & 0x4000) == 0x4000)
  223. {
  224. // Dossier
  225. $info = 'd';
  226. }
  227. elseif (($perms & 0x2000) == 0x2000)
  228. {
  229. // Caractere special
  230. $info = 'c';
  231. }
  232. elseif (($perms & 0x1000) == 0x1000)
  233. {
  234. // FIFO pipe
  235. $info = 'p';
  236. }
  237. else
  238. {
  239. // Inconnu
  240. $info = 'u';
  241. }
  242. // Proprietaire
  243. $info .= (($perms & 0x0100) ? 'r' : '-');
  244. $info .= (($perms & 0x0080) ? 'w' : '-');
  245. $info .= (($perms & 0x0040) ?
  246. (($perms & 0x0800) ? 's' : 'x' ) :
  247. (($perms & 0x0800) ? 'S' : '-'));
  248. // Groupe
  249. $info .= (($perms & 0x0020) ? 'r' : '-');
  250. $info .= (($perms & 0x0010) ? 'w' : '-');
  251. $info .= (($perms & 0x0008) ?
  252. (($perms & 0x0400) ? 's' : 'x' ) :
  253. (($perms & 0x0400) ? 'S' : '-'));
  254. // Tous
  255. $info .= (($perms & 0x0004) ? 'r' : '-');
  256. $info .= (($perms & 0x0002) ? 'w' : '-');
  257. $info .= (($perms & 0x0001) ?
  258. (($perms & 0x0200) ? 't' : 'x' ) :
  259. (($perms & 0x0200) ? 'T' : '-'));
  260. return ($info);
  261. }
  262. /**
  263. * Callback usort()
  264. * Tri le tableau de fichiers
  265. *
  266. * @param array $a Fichier A
  267. * @param array $b Fichier B
  268. * @return int
  269. */
  270. public function order_file($a, $b)
  271. {
  272. if ($this->order_direction == 'desc')
  273. {
  274. $result = strcmp($a[$this->order], $b[$this->order]);
  275. if ($result == 0)
  276. {
  277. return (($a['name'] > $b['name']) ? 1 : -1);
  278. }
  279. else
  280. {
  281. return (($a[$this->order] < $b[$this->order]) ? 1 : -1);
  282. }
  283. }
  284. else
  285. {
  286. $result = strcmp($a[$this->order], $b[$this->order]);
  287. if ($result == 0)
  288. {
  289. return (($a['name'] > $b['name']) ? 1 : -1);
  290. }
  291. else
  292. {
  293. return (($a[$this->order] > $b[$this->order]) ? 1 : -1);
  294. }
  295. }
  296. }
  297. /*
  298. ** Upload un fichier sur le serveur
  299. */
  300. public function upload_file()
  301. {
  302. $upload = new Upload('upload_file');
  303. $upload->allow_ext(true);
  304. $upload->store(ROOT . $this->dir);
  305. }
  306. /**
  307. * Chmod un ou plusieurs fichiers
  308. */
  309. public function chmod_file()
  310. {
  311. // Instance de la classe File
  312. $file = File::factory(Http::request('use_ftp', 'post'));
  313. $action = Http::request('action', 'post');
  314. if (!is_array($action))
  315. {
  316. $action = array();
  317. }
  318. $chmod = Http::request('chmod_files', 'post');
  319. if (strlen($chmod) == 3)
  320. {
  321. $chmod = '0' . $chmod;
  322. }
  323. foreach ($action AS $f)
  324. {
  325. if (file_exists(ROOT . $f))
  326. {
  327. $file->chmod($f, octdec($chmod));
  328. }
  329. }
  330. Http::redirect('index.' . PHPEXT . '?p=tools_webftp&dir=' . $this->dir);
  331. }
  332. /**
  333. * Page d'edition d'un fichier
  334. */
  335. public function edit_file()
  336. {
  337. $ext = get_file_data($this->filename, 'extension');
  338. if (!in_array($ext, $this->edit_file))
  339. {
  340. Display::message('adm_webftp_bad_ext');
  341. }
  342. Fsb::$tpl->set_switch('webftp_edit');
  343. Fsb::$tpl->set_vars(array(
  344. 'FILENAME' => sprintf(Fsb::$session->lang('adm_webftp_edit_file'), ROOT . $this->dir . $this->filename),
  345. 'CONTENT_FILE' => htmlspecialchars(file_get_contents(ROOT . $this->dir . $this->filename)),
  346. 'USE_FTP' => (Fsb::$cfg->get('ftp_default')) ? true : false,
  347. 'U_CODEPRESS' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;mode=codepress&amp;dir=' . $this->dir . '&amp;file=' . $this->filename),
  348. 'U_ACTION' => sid('index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir . '&amp;file=' . $this->filename),
  349. ));
  350. }
  351. /**
  352. * Sauvegarde les modifications dans le fichier lors de l'edition
  353. */
  354. public function submit_edit_file()
  355. {
  356. // Instance de la classe File
  357. $file = File::factory(Http::request('use_ftp', 'post'));
  358. $content = Http::request('content_file', 'post');
  359. $file->write($this->dir . $this->filename, $content);
  360. Log::add(Log::ADMIN, 'webftp_log_edit', $this->dir . $this->filename);
  361. Display::message('adm_webftp_well_edit', 'index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir, 'tools_webftp');
  362. }
  363. /**
  364. * Page de suppression d'un fichier (ou d'un dossier)
  365. */
  366. public function page_delete_file()
  367. {
  368. if (check_confirm())
  369. {
  370. $this->delete_file(ROOT . $this->dir . $this->filename);
  371. Log::add(Log::ADMIN, 'webftp_log_delete', ROOT . $this->dir . $this->filename);
  372. Display::message('adm_webftp_well_delete', 'index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir, 'tools_webftp');
  373. }
  374. else if (Http::request('confirm_no', 'post'))
  375. {
  376. Http::redirect('index.' . PHPEXT . '?p=tools_webftp&amp;dir=' . $this->dir);
  377. }
  378. else
  379. {
  380. Display::confirmation(sprintf(Fsb::$session->lang('adm_webftp_confirm_delete'), $this->dir . $this->filename), 'index.' . PHPEXT . '?p=tools_webftp&amp;mode=delete&amp;dir=' . $this->dir . '&amp;file=' . $this->filename);
  381. }
  382. }
  383. /**
  384. * Supprimer recursivement un dossier si besoin
  385. *
  386. * @param string $file Fichier à supprimer
  387. */
  388. public function delete_file($file)
  389. {
  390. $tmp = basename($file);
  391. if ($tmp[0] == '.')
  392. {
  393. return ;
  394. }
  395. if (is_dir($file))
  396. {
  397. $fd = opendir($file);
  398. while ($current_file = readdir($fd))
  399. {
  400. $this->delete_file($file . '/' . $current_file);
  401. }
  402. }
  403. else
  404. {
  405. if (is_writable($file))
  406. {
  407. @unlink($file);
  408. }
  409. }
  410. }
  411. /**
  412. * Renvoie le type de fichier pour la petite icone le symbolisant
  413. *
  414. * @param string $ext Extension du fichier
  415. * @return string Type du fichier
  416. */
  417. public function get_type_img($ext)
  418. {
  419. switch (strtolower($ext))
  420. {
  421. case 'gif' :
  422. case 'jpg' :
  423. case 'png' :
  424. case 'bmp' :
  425. return ('img');
  426. case 'html' :
  427. case 'htm' :
  428. return ('html');
  429. case 'zip' :
  430. case 'rar' :
  431. case 'gz' :
  432. case 'tgz' :
  433. case 'bz2' :
  434. return ('zip');
  435. case 'pdf' :
  436. return ('pdf');
  437. default :
  438. return ('txt');
  439. }
  440. }
  441. /**
  442. * Affiche le contenu d'un fichier PHP
  443. */
  444. public function page_php_highlight()
  445. {
  446. $phpfile = Http::request('phpfile');
  447. if (file_exists(ROOT . $this->dir . $phpfile))
  448. {
  449. highlight_file(ROOT . $this->dir . $phpfile);
  450. }
  451. exit;
  452. }
  453. /**
  454. * Charge le contenu d'un fichier pour l'afficher d'editeur Codepress
  455. */
  456. public function page_codepress()
  457. {
  458. $ext = get_file_data($this->filename, 'extension');
  459. if (!in_array($ext, $this->edit_file))
  460. {
  461. Display::message('adm_webftp_bad_ext');
  462. }
  463. // Language d'affichage pour CodePress
  464. switch ($ext)
  465. {
  466. case 'php' :
  467. case 'php3' :
  468. case 'php4' :
  469. case 'php5' :
  470. case 'php6' :
  471. $language = 'php';
  472. break;
  473. case 'js' :
  474. $language = 'javascript';
  475. break;
  476. case 'css' :
  477. $language = 'css';
  478. break;
  479. case 'html' :
  480. case 'tpl' :
  481. case 'xml' :
  482. $language = 'html';
  483. break;
  484. default :
  485. $language = 'text';
  486. break;
  487. }
  488. Fsb::$tpl->set_file('codepress.html');
  489. Fsb::$tpl->set_vars(array(
  490. 'CODEPRESS_CONTENT' => htmlspecialchars(file_get_contents(ROOT . $this->dir . $this->filename)),
  491. 'CODEPRESS_LANGUAGE' => $language,
  492. ));
  493. }
  494. }
  495. /* EOF */