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

/includes/class_files.php

https://github.com/MightyGorgon/icy_phoenix
PHP | 1108 lines | 920 code | 55 blank | 133 comment | 72 complexity | 45dc5b8f4a0b897b73b69b3436f936c5 MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * @package Icy Phoenix
  5. * @version $Id$
  6. * @copyright (c) 2008 Icy Phoenix
  7. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  8. *
  9. */
  10. if (!defined('IN_ICYPHOENIX'))
  11. {
  12. die('Hacking attempt');
  13. }
  14. if (!defined('IP_ROOT_PATH')) define('IP_ROOT_PATH', './');
  15. if (!defined('MAIN_CACHE_FOLDER')) define('MAIN_CACHE_FOLDER', IP_ROOT_PATH . 'cache/');
  16. if (!defined('UPLOADS_CACHE_FOLDER')) define('UPLOADS_CACHE_FOLDER', MAIN_CACHE_FOLDER . 'uploads/');
  17. if (!defined('POSTED_IMAGES_PATH')) define('POSTED_IMAGES_PATH', IP_ROOT_PATH . 'files/images/');
  18. if (!defined('POSTED_IMAGES_THUMBS_PATH')) define('POSTED_IMAGES_THUMBS_PATH', IP_ROOT_PATH . 'files/thumbs/');
  19. if (!defined('POSTED_IMAGES_THUMBS_S_PATH')) define('POSTED_IMAGES_THUMBS_S_PATH', POSTED_IMAGES_THUMBS_PATH . 's/');
  20. /*
  21. */
  22. if (!defined('CHMOD_ALL')) define('CHMOD_ALL', 7);
  23. if (!defined('CHMOD_READ')) define('CHMOD_READ', 4);
  24. if (!defined('CHMOD_WRITE')) define('CHMOD_WRITE', 2);
  25. if (!defined('CHMOD_EXECUTE')) define('CHMOD_EXECUTE', 1);
  26. if (!defined('FILE_UPLOAD_NOT_UPLOADED')) define('FILE_UPLOAD_NOT_UPLOADED', 0);
  27. if (!defined('FILE_UPLOAD_UPLOADED')) define('FILE_UPLOAD_UPLOADED', 1);
  28. if (!defined('FILE_UPLOAD_ERROR')) define('FILE_UPLOAD_ERROR', 2);
  29. if (!defined('FILE_UPLOAD_TOO_BIG')) define('FILE_UPLOAD_TOO_BIG', 3);
  30. if (!defined('FILE_UPLOAD_TYPE_ERROR')) define('FILE_UPLOAD_TYPE_ERROR', 4);
  31. /**
  32. * Files management class
  33. */
  34. class class_files
  35. {
  36. var $files = array();
  37. var $files_list = array();
  38. var $cache_folder = '';
  39. var $uploads_folder = '';
  40. var $temp_folder = '';
  41. var $allowed_extensions = array();
  42. var $disallowed_extensions = array();
  43. var $files_to_skip = array();
  44. var $max_size = 128000;
  45. var $max_width = 600;
  46. var $max_height = 600;
  47. var $rand_seed = 9999;
  48. /**
  49. * Class initialization
  50. */
  51. function __construct()
  52. {
  53. $this->cache_folder = MAIN_CACHE_FOLDER;
  54. $this->uploads_folder = UPLOADS_CACHE_FOLDER;
  55. $this->temp_folder = $this->uploads_folder . time() . '/';
  56. $this->allowed_extensions = array('gif', 'jpeg', 'jpg', 'png');
  57. $this->disallowed_extensions = array('asp', 'php', 'htm', 'html');
  58. $this->files_to_skip = array('.', '..');
  59. }
  60. /*
  61. * Removes trailing slashes from path
  62. */
  63. function remove_trailing_slashes($dir)
  64. {
  65. while(substr($dir, -1, 1) == '/')
  66. {
  67. $dir = substr($dir, 0, -1);
  68. }
  69. return $dir;
  70. }
  71. /**
  72. * Return unique id
  73. * @param string $extra additional entropy
  74. */
  75. function unique_id($extra = 'mg')
  76. {
  77. $val = $this->rand_seed . microtime();
  78. $val = strtolower(md5($val));
  79. $this->rand_seed = md5($this->rand_seed . $val . $extra);
  80. return substr($val, 4, 16);
  81. }
  82. /**
  83. * Sanitizes a string to only lowercase letters, numbers and underscore
  84. */
  85. function clean_string($string, $lowercase = true)
  86. {
  87. $string = !empty($lowercase) ? preg_replace('/[^a-z0-9]+/', '_', strtolower($string)) : preg_replace('/[^A-Za-z0-9]+/', '_', $string);
  88. return $string;
  89. }
  90. /**
  91. * Sanitizes a string for JavaScript
  92. */
  93. function clean_string_js($string)
  94. {
  95. $string = str_replace(array("'", '/'), array("\'", '\/'), $string);
  96. return $string;
  97. }
  98. /**
  99. * Generates all file details
  100. */
  101. function get_file_details($file_name)
  102. {
  103. $file_details = array();
  104. $file_details = pathinfo($file_name);
  105. $file_details['clean_name'] = $this->clean_string($file_details['filename'], true) . (!empty($file_details['extension']) ? ('.' . $this->clean_string($file_details['extension'])) : '');
  106. return $file_details;
  107. }
  108. /*
  109. * Get only file extension
  110. */
  111. function get_file_extension($file_name)
  112. {
  113. return substr(strrchr($file_name, '.'), 1);
  114. }
  115. /**
  116. * Creates a temporary dir to be removed later after all processing
  117. */
  118. function create_temp_dir($dir_name = '')
  119. {
  120. $return = false;
  121. if (empty($dir_name))
  122. {
  123. $dir_name = time() . '_' . $this->unique_id();
  124. }
  125. $dir_name = $this->clean_string($dir_name, true);
  126. $dir_full_path = $this->uploads_folder . $dir_name;
  127. while(@is_dir($dir_full_path))
  128. {
  129. $dir_full_path = $this->uploads_folder . time() . '_' . $this->unique_id();
  130. }
  131. $creation_result = @mkdir($dir_full_path, 0666);
  132. if ($creation_result)
  133. {
  134. $this->temp_folder = $dir_full_path . '/';
  135. $return = $this->temp_folder;
  136. }
  137. return $return;
  138. }
  139. /**
  140. * Checks if a file already exists in a dir and in case generates a new filename
  141. */
  142. function generate_file_name($target_dir, $file_name)
  143. {
  144. $file_details = $this->get_file_details($file_name);
  145. if (!empty($target_dir))
  146. {
  147. $target_dir = $this->remove_trailing_slashes($target_dir) . '/';
  148. }
  149. $file_full_path = $target_dir . $file_details['clean_name'];
  150. while (@file_exists($file_full_path))
  151. {
  152. $file_full_path = $target_dir . $this->clean_string($file_details['filename'], true) . '_' . time() . '_' . str_pad(mt_rand(1, 999), 3, '0', STR_PAD_LEFT) . '.' . $this->clean_string($file_details['extension']);
  153. }
  154. return $file_full_path;
  155. }
  156. /*
  157. * Get directory information
  158. */
  159. function get_dirs_path($full_path)
  160. {
  161. $dirs_path = array();
  162. $path_parts[] = array();
  163. $file_path[] = array();
  164. $path_parts = pathinfo($full_path);
  165. $file_path = explode('/', $path_parts['dirname']);
  166. $dirs_path['indent'] = sizeof($file_path);
  167. $dirs_path['name'] = $path_parts['dirname'];
  168. $dirs_path['last_subfolder_indent'] = substr_count($full_path, '/') + 1;
  169. $dirs_path['last_subfolder_name'] = $file_path[$last_subfolder['indent'] - 1];
  170. return $dirs_path;
  171. }
  172. /*
  173. * Get parent subfolder info
  174. */
  175. function get_parent_subfolder($full_path)
  176. {
  177. $parent_subfolder = array();
  178. $path_parts[] = array();
  179. $file_path[] = array();
  180. $path_parts = pathinfo($full_path);
  181. $file_path = explode('/', $path_parts['dirname']);
  182. $parent_subfolder['indent'] = substr_count($full_path, '/');
  183. if (sizeof($file_path) >= 2)
  184. {
  185. $parent_subfolder['name'] = $file_path[$parent_subfolder['indent'] - 2] . '/';
  186. }
  187. elseif (sizeof($file_path) == 1)
  188. {
  189. $parent_subfolder['name'] = '';
  190. }
  191. else
  192. {
  193. $parent_subfolder['name'] = '../';
  194. }
  195. return $parent_subfolder;
  196. }
  197. /*
  198. * Write some content to a file
  199. */
  200. function file_output($file_name, $file_content, $flag = 'w')
  201. {
  202. /*
  203. 'r' Open for reading only; place the file pointer at the beginning of the file.
  204. 'r+' Open for reading and writing; place the file pointer at the beginning of the file.
  205. 'w' Open for writing only; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
  206. 'w+' Open for reading and writing; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
  207. 'a' Open for writing only; place the file pointer at the end of the file. If the file does not exist, attempt to create it.
  208. 'a+' Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it.
  209. 'x' Create and open for writing only; place the file pointer at the beginning of the file. If the file already exists, the fopen() call will fail by returning FALSE and generating an error of level E_WARNING. If the file does not exist, attempt to create it. This is equivalent to specifying O_EXCL|O_CREAT flags for the underlying open(2) system call.
  210. 'x+' Create and open for reading and writing; place the file pointer at the beginning of the file. If the file already exists, the fopen() call will fail by returning FALSE and generating an error of level E_WARNING. If the file does not exist, attempt to create it. This is equivalent to specifying O_EXCL|O_CREAT flags for the underlying open(2) system call.
  211. */
  212. $flags_array = array('r', 'r+', 'w', 'w+', 'a', 'a+', 'x', 'x+');
  213. $flag = (empty($flag) || !in_array($flag, $flags_array)) ? 'w' : $flag;
  214. $fp = @fopen($file_name, $flag);
  215. @flock($fp, LOCK_EX);
  216. @fwrite($fp, $file_content);
  217. @flock($fp, LOCK_UN);
  218. @fclose($fp);
  219. @chmod($file_name, 0777);
  220. return true;
  221. }
  222. /*
  223. * Create an array of directories
  224. */
  225. function create_dirs_array($dir, $list_subdirs = true)
  226. {
  227. if (empty($dir))
  228. {
  229. die('Provide a valid root dir');
  230. exit;
  231. }
  232. $dir = $this->remove_trailing_slashes($dir);
  233. $directory = @opendir($dir);
  234. $dirs_list = array();
  235. while (@$file = @readdir($directory))
  236. {
  237. if (!in_array($file, array('.', '..')))
  238. {
  239. if (@is_dir($dir . '/' . $file))
  240. {
  241. $dirs_list[$file] = $dir . '/' . $file;
  242. if ($list_subdirs == true)
  243. {
  244. $dirs_list[$file] = $this->create_dirs_array($dir . '/' . $file, $list_subdirs);
  245. ksort($dirs_list[$file]);
  246. }
  247. }
  248. }
  249. }
  250. @closedir($directory);
  251. ksort($dirs_list);
  252. return $dirs_list;
  253. }
  254. /*
  255. * Pars all subdirs in a path
  256. */
  257. function parse_sub_dirs($dirs, $path = '')
  258. {
  259. $subdirs_input_array = array();
  260. $subdirs_output_array = array();
  261. foreach ($dirs as $k => $v)
  262. {
  263. $subdirs_input_array[] = $path . $k;
  264. if (is_array($v))
  265. {
  266. $subdirs_input_array[] = $this->parse_sub_dirs($v, $path . $k . '/');
  267. }
  268. $subdirs_input_array[] = $path . $k;
  269. }
  270. $subdirs_output_array = $this->join_nested_arrays($subdirs_input_array);
  271. return $subdirs_output_array;
  272. }
  273. /*
  274. * Join nested arrays
  275. */
  276. function join_nested_arrays($input_array)
  277. {
  278. $output_array = array();
  279. $temp_array = array();
  280. while (list($k, $v) = each($input_array))
  281. {
  282. if (!is_array($v))
  283. {
  284. $output_array[] = $v;
  285. }
  286. else
  287. {
  288. $temp_array = $this->join_nested_arrays($v);
  289. foreach ($temp_array as $kk=> $vv)
  290. {
  291. if (!is_array($vv))
  292. {
  293. $output_array[] = $vv;
  294. }
  295. }
  296. }
  297. }
  298. return $output_array;
  299. }
  300. /*
  301. * List all files
  302. */
  303. function list_files($dir, $recursive = true, $allowed_extensions = false, $disallowed_extensions = false)
  304. {
  305. $dir = $this->remove_trailing_slashes($dir);
  306. $directory = @opendir($dir);
  307. $files_list = array();
  308. if (!empty($allowed_extensions))
  309. {
  310. $allowed_extensions = is_array($allowed_extensions) ? $allowed_extensions : array($allowed_extensions);
  311. $allowed_extensions = array_map('strtolower', $allowed_extensions);
  312. }
  313. if (!empty($disallowed_extensions))
  314. {
  315. $disallowed_extensions = is_array($disallowed_extensions) ? $disallowed_extensions : array($disallowed_extensions);
  316. $disallowed_extensions = array_map('strtolower', $disallowed_extensions);
  317. //$disallowed_extensions = array('ace', 'bak', 'bmp', 'css', 'gif', 'hl', 'htc', 'htm', 'html', 'ico', 'jar', 'jpeg', 'jpg', 'js', 'pak', 'png', 'rar', 'sql', 'swf', 'tpl', 'ttf', 'txt', 'wmv', 'zip');
  318. }
  319. while (@$file = @readdir($directory))
  320. {
  321. $full_path_file = $dir . '/' . $file;
  322. if (!in_array($file, array('.', '..')))
  323. {
  324. if (@is_dir($dir . '/' . $file))
  325. {
  326. if (!empty($recursive))
  327. {
  328. $files_list = array_merge($files_list, $this->list_files($full_path_file, $recursive, $allowed_extensions, $disallowed_extensions));
  329. }
  330. }
  331. else
  332. {
  333. $process_file = true;
  334. if (!empty($allowed_extensions) || !empty($disallowed_extensions))
  335. {
  336. $process_file = false;
  337. $file_details = $this->get_file_details($full_path_file);
  338. if (!empty($disallowed_extensions) && !in_array(strtolower($file_details['extension']), $disallowed_extensions))
  339. {
  340. $process_file = true;
  341. }
  342. if (!empty($file_details['extension']) && !empty($allowed_extensions) && in_array(strtolower($file_details['extension']), $allowed_extensions))
  343. {
  344. $process_file = true;
  345. }
  346. }
  347. if ($process_file)
  348. {
  349. $files_list[] = $full_path_file;
  350. }
  351. }
  352. }
  353. }
  354. @closedir($directory);
  355. sort($files_list);
  356. return $files_list;
  357. }
  358. /**
  359. * Creates an images list from a folder
  360. */
  361. function create_images_list($source_path, $allowed_image_types = '')
  362. {
  363. $allowed_image_types = empty($allowed_image_types) ? array('gif', 'jpg', 'jpeg', 'png') : (array) $allowed_image_types;
  364. // Re-define some keys for getimagesize
  365. // Defines the keys we want instead of 0, 1, 2, 3, 'bits', 'channels', and 'mime'.
  366. $image_data_keys = array(
  367. 'width',
  368. 'height',
  369. 'type',
  370. 'attr',
  371. 'bits',
  372. 'channels',
  373. 'mime'
  374. );
  375. // Assign useful values for the third index.
  376. $image_types = array(
  377. 1 => 'gif',
  378. 2 => 'jpg',
  379. 3 => 'png',
  380. 4 => 'swf',
  381. 5 => 'psd',
  382. 6 => 'bmp',
  383. 7 => 'tiff (intel byte order)',
  384. 8 => 'tiff (motorola byte order)',
  385. 9 => 'jpc',
  386. 10 => 'jp2',
  387. 11 => 'jpx',
  388. 12 => 'jb2',
  389. 13 => 'swc',
  390. 14 => 'iff',
  391. 15 => 'wbmp',
  392. 16 => 'xbm'
  393. );
  394. $images_list = array();
  395. if (@is_dir($source_path))
  396. {
  397. $files_list = $this->list_files($source_path, false, $allowed_image_types, false);
  398. foreach ($files_list as $image)
  399. {
  400. $temp = array();
  401. $data = array();
  402. $temp = @getimagesize($image);
  403. if(!empty($temp))
  404. {
  405. // Convert keys to numbers
  406. $temp = array_values($temp);
  407. // Make an array using values from $redefine_keys as keys and values from $temp as values.
  408. foreach ($temp as $k => $v)
  409. {
  410. $image_data[$image_data_keys[$k]] = $v;
  411. }
  412. // Convert the image type
  413. $image_data['type'] = $image_types[$image_data['type']];
  414. $process_image = (empty($image_data['width']) || empty($image_data['height']) || !in_array($image_data['type'], $allowed_image_types)) ? false : true;
  415. if ($process_image)
  416. {
  417. $image_size = @filesize($image);
  418. $images_list[] = array(
  419. 'src' => $image,
  420. 'width' => (int) $image_data['width'],
  421. 'height' => (int) $image_data['height'],
  422. 'type' => $image_data['type'],
  423. 'size' => (int) $image_size
  424. );
  425. }
  426. }
  427. }
  428. }
  429. return $images_list;
  430. }
  431. /*
  432. * Gets the number of files
  433. */
  434. function get_number_of_files($dir, $recursive = true, $allowed_extensions = false, $disallowed_extensions = false)
  435. {
  436. $dir = $this->remove_trailing_slashes($dir);
  437. if (empty($this->files_list))
  438. {
  439. $this->files_list = $this->list_files($dir, $recursive, $allowed_extensions, $disallowed_extensions);
  440. }
  441. $files_count = sizeof($this->files_list);
  442. return $files_count;
  443. }
  444. /*
  445. * Gets the dir size
  446. */
  447. function get_dir_size($dir, $recursive = true, $allowed_extensions = false, $disallowed_extensions = false)
  448. {
  449. $dir = $this->remove_trailing_slashes($dir);
  450. if (empty($this->files_list))
  451. {
  452. $this->files_list = $this->list_files($dir, $recursive, $allowed_extensions, $disallowed_extensions);
  453. }
  454. $dir_size = 0;
  455. foreach ($this->files_list as $file)
  456. {
  457. $dir_size += (int) @filesize($file);
  458. }
  459. return $dir_size;
  460. }
  461. /*
  462. * This function duplicates a folder with some options
  463. * $extensions: allowed extensions
  464. * $duplicate_subfolder: if set to true subfolders will be duplicated as well
  465. */
  466. function duplicate_folder($source_folder, $target_folder, $extensions, $duplicate_subfolder = true)
  467. {
  468. $source_folder = $this->remove_trailing_slashes($source_folder);
  469. $target_folder = $this->remove_trailing_slashes($target_folder);
  470. $new_source_folder = $source_folder;
  471. $new_target_folder = $target_folder;
  472. $directory = @opendir($source_folder);
  473. while (@$file = @readdir($directory))
  474. {
  475. $full_path_file = $source_folder . '/' . $file;
  476. if (!in_array($file, array('.', '..')))
  477. {
  478. if (@is_dir($full_path_file))
  479. {
  480. if ($duplicate_subfolder == true)
  481. {
  482. $new_source_folder = $source_folder . '/' . $file;
  483. $new_target_folder = $target_folder . '/' . $file;
  484. @mkdir($new_target_folder, 0777);
  485. //echo('<br />' . $new_source_folder . ' - ' . $new_target_folder);
  486. $this->duplicate_folder($new_source_folder, $new_target_folder, $extensions, $duplicate_subfolder);
  487. }
  488. }
  489. else
  490. {
  491. if (!@is_dir($target_folder))
  492. {
  493. @mkdir($target_folder, 0777);
  494. }
  495. $current_file_extension = $this->get_file_extension($file);
  496. if (empty($extensions) || (!is_array($extensions) && ($current_file_extension == $extensions)) || (is_array($extensions) && in_array($current_file_extension, $extensions)))
  497. {
  498. if (@file_exists($target_folder . '/' . $file))
  499. {
  500. @unlink($target_folder . '/' . $file);
  501. }
  502. @copy($source_folder . '/' . $file, $target_folder . '/' . $file);
  503. }
  504. }
  505. }
  506. }
  507. @closedir($directory);
  508. }
  509. /*
  510. * Duplicate an exact subfolder structure
  511. */
  512. function create_subfolders_structure($path, $chmod = 0777)
  513. {
  514. $tmp_paths = array();
  515. $tmp_paths = explode('/', $path);
  516. $recursive_path = '';
  517. for ($i = 0; $i < sizeof($tmp_paths); $i++)
  518. {
  519. if (!empty($tmp_paths[$i]))
  520. {
  521. $recursive_path = (!empty($recursive_path) ? ($recursive_path . '/') : '') . $tmp_paths[$i];
  522. if (!@is_dir($recursive_path))
  523. {
  524. @mkdir($recursive_path, $chmod);
  525. }
  526. }
  527. }
  528. return true;
  529. }
  530. /*
  531. * Compare files by size and time
  532. */
  533. function basic_compare_files($source_path, $target_path)
  534. {
  535. if (@is_dir($source_path) || !@file_exists($target_path))
  536. {
  537. return false;
  538. }
  539. $fs01 = @filesize($source_path);
  540. $fs02 = @filesize($target_path);
  541. //die("$fs01 - $fs02");
  542. $ft01 = @filemtime($source_path);
  543. $ft02 = @filemtime($target_path);
  544. //die("$ft01 - $ft02");
  545. if (($fs01 == $fs02) && ($ft01 == $ft02))
  546. {
  547. @unlink($target_path);
  548. return true;
  549. }
  550. return false;
  551. }
  552. /*
  553. * Remove files
  554. */
  555. function remove_files($dir, $include_types = false, $exclude_types = false)
  556. {
  557. $dir = $this->remove_trailing_slashes($dir);
  558. $include_types = empty($include_types) ? false : (is_array($include_types) ? $include_types : explode(',', $include_types));
  559. $exclude_types = empty($exclude_types) ? false : (is_array($exclude_types) ? $exclude_types : explode(',', $exclude_types));
  560. $files_to_skip = array('.', '..');
  561. $res = @opendir($dir);
  562. if($res === false) return;
  563. while(($file = @readdir($res)) !== false)
  564. {
  565. $remove_file = false;
  566. if(!in_array($file, $files_to_skip))
  567. {
  568. $file_full_path = $dir . '/' . $file;
  569. if(!@is_dir($file_full_path) && !@is_link($file_full_path))
  570. {
  571. $current_file_extension = $this->get_file_extension($file_full_path);
  572. if (empty($include_types) && empty($exclude_types))
  573. {
  574. $remove_file = true;
  575. }
  576. else
  577. {
  578. if (!empty($include_types) && !empty($exclude_types))
  579. {
  580. if (in_array($current_file_extension, $include_types) && !in_array($current_file_extension, $exclude_types))
  581. {
  582. $remove_file = true;
  583. }
  584. }
  585. else
  586. {
  587. if (!$remove_file && !empty($include_types) && in_array($current_file_extension, $include_types))
  588. {
  589. $remove_file = true;
  590. }
  591. if (!$remove_file && !empty($exclude_types) && !in_array($current_file_extension, $exclude_types))
  592. {
  593. $remove_file = true;
  594. }
  595. }
  596. }
  597. if ($remove_file)
  598. {
  599. @unlink($file_full_path);
  600. }
  601. }
  602. }
  603. }
  604. @closedir($res);
  605. }
  606. /**
  607. * Page Header
  608. */
  609. function simple_page_header($page_title)
  610. {
  611. echo('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . "\n");
  612. echo('<html>' . "\n");
  613. echo('<head>' . "\n");
  614. echo(' <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />' . "\n");
  615. echo(' <meta name="author" content="Mighty Gorgon" />' . "\n");
  616. echo(' <title>' . (!empty($page_title) ? $page_title : 'Icy Phoenix') . '</title>' . "\n");
  617. echo('</head>' . "\n");
  618. echo('<body>' . "\n");
  619. }
  620. /**
  621. * Page Footer
  622. */
  623. function simple_page_footer()
  624. {
  625. echo('</body>' . "\n");
  626. echo('</html>' . "\n");
  627. }
  628. /**
  629. * Explode any single-dimensional array into a full blown tree structure, based on the delimiters found in it's keys.
  630. *
  631. * @author Kevin van Zonneveld <kevin@vanzonneveld.net>
  632. * @author Lachlan Donald
  633. * @author Takkie
  634. * @copyright 2008 Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  635. * @license http://www.opensource.org/licenses/bsd-license.php New BSD Licence
  636. * @version SVN: Release: $Id: explodeTree.inc.php 89 2008-09-05 20:52:48Z kevin $
  637. * @link http://kevin.vanzonneveld.net/
  638. *
  639. * @param array $array
  640. * @param string $delimiter
  641. * @param boolean $baseval
  642. *
  643. * @return array
  644. */
  645. /*
  646. if(exec("find /etc/php5", $files))
  647. {
  648. // the $files array now holds the path as it's values, but we also want the paths as keys:
  649. $key_files = array_combine(array_values($files), array_values($files));
  650. // show the array
  651. print_r($key_files);
  652. }
  653. // let '/' be our delimiter
  654. $tree = explode_tree($key_files, "/");
  655. // show the array
  656. print_r($tree);
  657. // now the 3rd argument, the baseval, is true
  658. $tree = explode_tree($key_files, "/", true);
  659. */
  660. function explode_tree($array, $delimiter = '_', $baseval = false)
  661. {
  662. if(!is_array($array)) return false;
  663. $split_re = '/' . preg_quote($delimiter, '/') . '/';
  664. $return_array = array();
  665. foreach ($array as $key => $val)
  666. {
  667. // Get parent parts and the current leaf
  668. $parts = preg_split($split_re, $key, -1, PREG_SPLIT_NO_EMPTY);
  669. $leaf_part = array_pop($parts);
  670. // Build parent structure
  671. // Might be slow for really deep and large structures
  672. $parent_array = &$return_array;
  673. foreach ($parts as $part)
  674. {
  675. if (!isset($parent_array[$part]))
  676. {
  677. $parent_array[$part] = array();
  678. }
  679. elseif (!is_array($parent_array[$part]))
  680. {
  681. if ($baseval)
  682. {
  683. $parent_array[$part] = array('__base_val' => $parent_array[$part]);
  684. }
  685. else
  686. {
  687. $parent_array[$part] = array();
  688. }
  689. }
  690. $parent_array = &$parent_array[$part];
  691. }
  692. // Add the final part to the structure
  693. if (empty($parent_array[$leaf_part]))
  694. {
  695. $parent_array[$leaf_part] = $val;
  696. }
  697. elseif ($baseval && is_array($parent_array[$leaf_part]))
  698. {
  699. $parent_array[$leaf_part]['__base_val'] = $val;
  700. }
  701. }
  702. return $return_array;
  703. }
  704. function plot_tree($arr, $indent = 0, $mother_run = true)
  705. {
  706. if($mother_run)
  707. {
  708. // the beginning of plotTree. We're at rootlevel
  709. echo "start\n";
  710. }
  711. foreach($arr as $k => $v)
  712. {
  713. // skip the baseval thingy. Not a real node.
  714. if($k == '__base_val') continue;
  715. // determine the real value of this node.
  716. $show_val = ( is_array($v) ? $v['__base_val'] : $v );
  717. // show the indents
  718. echo str_repeat(' ', $indent);
  719. if($indent == 0)
  720. {
  721. // this is a root node. no parents
  722. echo 'O ';
  723. }
  724. elseif(is_array($v))
  725. {
  726. // this is a normal node. parents and children
  727. echo '+ ';
  728. }
  729. else
  730. {
  731. // this is a leaf node. no children
  732. echo '- ';
  733. }
  734. // show the actual node
  735. echo $k . ' (' . $show_val . ')' . "\n";
  736. if(is_array($v))
  737. {
  738. // this is what makes it recursive, rerun for childs
  739. $this->plot_tree($v, ($indent + 1), false);
  740. }
  741. }
  742. if($mother_run)
  743. {
  744. echo "end\n";
  745. }
  746. }
  747. function bytes_to_string($size, $precision = 2)
  748. {
  749. $sizes = array('YB', 'ZB', 'EB', 'PB', 'TB', 'GB', 'MB', 'KB', 'Bytes');
  750. $total = count($sizes);
  751. while($total-- && ($size > 1024)) $size /= 1024;
  752. return round($size, $precision) . " " . $sizes[$total];
  753. }
  754. /**
  755. * Global function for chmodding directories and files for internal use
  756. * This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions.
  757. * The function determines owner and group from common.php file and sets the same to the provided file. Permissions are mapped to the group, user always has rw(x) permission.
  758. * The function uses bit fields to build the permissions.
  759. * The function sets the appropiate execute bit on directories.
  760. *
  761. * Supported constants representing bit fields are:
  762. *
  763. * CHMOD_ALL - all permissions (7)
  764. * CHMOD_READ - read permission (4)
  765. * CHMOD_WRITE - write permission (2)
  766. * CHMOD_EXECUTE - execute permission (1)
  767. *
  768. * NOTE: The function uses POSIX extension and fileowner()/filegroup() functions. If any of them is disabled, this function tries to build proper permissions, by calling is_readable() and is_writable() functions.
  769. *
  770. * @param $filename The file/directory to be chmodded
  771. * @param $perms Permissions to set
  772. * @return true on success, otherwise false
  773. *
  774. * @author faw, phpBB Group
  775. */
  776. function ip_chmod($filename, $perms = CHMOD_READ)
  777. {
  778. // Return if the file no longer exists.
  779. if (!@file_exists($filename))
  780. {
  781. return false;
  782. }
  783. if (!function_exists('fileowner') || !function_exists('filegroup'))
  784. {
  785. $file_uid = $file_gid = false;
  786. $common_php_owner = $common_php_group = false;
  787. }
  788. else
  789. {
  790. // Determine owner/group of this file and the filename we want to change here
  791. $common_php_owner = fileowner(__FILE__);
  792. $common_php_group = filegroup(__FILE__);
  793. $file_uid = fileowner($filename);
  794. $file_gid = filegroup($filename);
  795. // Try to set the owner to the same common.php has
  796. if (($common_php_owner !== $file_uid) && ($common_php_owner !== false) && ($file_uid !== false))
  797. {
  798. // Will most likely not work
  799. if (@chown($filename, $common_php_owner));
  800. {
  801. clearstatcache();
  802. $file_uid = fileowner($filename);
  803. }
  804. }
  805. // Try to set the group to the same common.php has
  806. if (($common_php_group !== $file_gid) && ($common_php_group !== false) && ($file_gid !== false))
  807. {
  808. if (@chgrp($filename, $common_php_group));
  809. {
  810. clearstatcache();
  811. $file_gid = filegroup($filename);
  812. }
  813. }
  814. }
  815. // And the owner and the groups PHP is running under.
  816. $php_uid = (function_exists('posix_getuid')) ? @posix_getuid() : false;
  817. $php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false;
  818. // Who is PHP?
  819. if (($file_uid === false) || ($file_gid === false) || ($php_uid === false) || ($php_gids === false))
  820. {
  821. $php = NULL;
  822. }
  823. elseif (($file_uid == $php_uid) /* && ($common_php_owner !== false) && ($common_php_owner === $file_uid) */)
  824. {
  825. $php = 'owner';
  826. }
  827. elseif (in_array($file_gid, $php_gids))
  828. {
  829. $php = 'group';
  830. }
  831. else
  832. {
  833. $php = 'other';
  834. }
  835. // Owner always has read/write permission
  836. $owner = CHMOD_READ | CHMOD_WRITE;
  837. if (@is_dir($filename))
  838. {
  839. $owner |= CHMOD_EXECUTE;
  840. // Only add execute bit to the permission if the dir needs to be readable
  841. if ($perms & CHMOD_READ)
  842. {
  843. $perms |= CHMOD_EXECUTE;
  844. }
  845. }
  846. switch ($php)
  847. {
  848. case null:
  849. case 'owner':
  850. /*
  851. //ATTENTION: if php is owner or NULL we set it to group here. This is the most failsafe combination for the vast majority of server setups.
  852. $result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0));
  853. clearstatcache();
  854. if (!is_null($php) || (is_readable($filename) && is_writable($filename)))
  855. {
  856. break;
  857. }
  858. */
  859. case 'group':
  860. $result = @chmod($filename, ($owner << 6) + ($perms << 3) + (0 << 0));
  861. clearstatcache();
  862. if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))))
  863. {
  864. break;
  865. }
  866. case 'other':
  867. $result = @chmod($filename, ($owner << 6) + ($perms << 3) + ($perms << 0));
  868. clearstatcache();
  869. if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))))
  870. {
  871. break;
  872. }
  873. default:
  874. return false;
  875. break;
  876. }
  877. return $result;
  878. }
  879. /**
  880. * Recursive CHMOD re-set for files that cannot be handled via FTP because of different owner
  881. * Usage: $this->rchmod($dir, 0777, 0777);
  882. */
  883. function rchmod($resource, $dmod = 0666, $fmod = 0666)
  884. {
  885. $resource = $this->remove_trailing_slashes($resource);
  886. $files_to_skip = array('.', '..');
  887. if (@is_dir($resource))
  888. {
  889. $old = @umask(0000);
  890. @chmod($resource, $dmod);
  891. @umask($old);
  892. $res = @opendir($resource);
  893. if($res === false) return false;
  894. while(($file = @readdir($res)) !== false)
  895. {
  896. $filename = $resource . '/' . $file;
  897. if(!in_array($file, $files_to_skip) && !@is_link($filename))
  898. {
  899. if (@is_dir($filename))
  900. {
  901. $this->rchmod($filename, $dmod, $fmod);
  902. }
  903. else
  904. {
  905. $old = @umask(0000);
  906. @chmod($filename, $fmod);
  907. @umask($old);
  908. }
  909. }
  910. }
  911. @closedir($res);
  912. }
  913. else
  914. {
  915. $old = @umask(0000);
  916. @chmod($resource, $fmod);
  917. @umask($old);
  918. }
  919. }
  920. /*
  921. * Clean and remove temporary folder
  922. */
  923. function cleanup($dir, $files_to_skip = false, $self_remove = true, $recursive = true, $sub_remove = true)
  924. {
  925. $dir = $this->remove_trailing_slashes($dir);
  926. if (!empty($self_remove))
  927. {
  928. $files_to_skip = array('.', '..');
  929. $recursive = true;
  930. $sub_remove = true;
  931. }
  932. else
  933. {
  934. $files_to_skip = empty($files_to_skip) ? (array) $this->files_to_skip : array_merge((array) $this->files_to_skip, (array) $files_to_skip);
  935. $files_to_skip = array_unique(array_merge(array('.', '..'), (array) $files_to_skip));
  936. }
  937. $res = @opendir($dir);
  938. if($res === false) return false;
  939. while(($file = @readdir($res)) !== false)
  940. {
  941. $filename = $dir . '/' . $file;
  942. if(!in_array($file, $files_to_skip) && !@is_link($filename))
  943. {
  944. if(@is_dir($filename))
  945. {
  946. if (!empty($recursive))
  947. {
  948. $files_to_skip_recursive = !empty($sub_remove) ? array('.', '..') : $files_to_skip;
  949. $this->cleanup($filename, $files_to_skip_recursive, $self_remove, $recursive, $sub_remove);
  950. if (!empty($sub_remove))
  951. {
  952. $this->rchmod($filename);
  953. @rmdir($filename);
  954. }
  955. }
  956. }
  957. else
  958. {
  959. $this->rchmod($filename);
  960. @unlink($filename);
  961. }
  962. }
  963. }
  964. @closedir($res);
  965. if (!empty($self_remove))
  966. {
  967. $this->rchmod($dir);
  968. @rmdir($dir);
  969. }
  970. return true;
  971. }
  972. /*
  973. * Empty directory contents
  974. */
  975. function clear_dir($dir)
  976. {
  977. $files_to_skip = array('.', '..');
  978. $this->cleanup($dir, $files_to_skip, false, true, true);
  979. return true;
  980. }
  981. /*
  982. * Empty data folder preserving some core files
  983. */
  984. function empty_data_folder($dir)
  985. {
  986. $files_to_skip = array('.', '..', '.htaccess', 'index.html');
  987. $this->cleanup($dir, $files_to_skip, false, false, false);
  988. return true;
  989. }
  990. }
  991. ?>