PageRenderTime 94ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/ckeditor/filemanager/connectors/php/filemanager.class.php

http://github.com/sebtools/Neptune
PHP | 775 lines | 586 code | 148 blank | 41 comment | 155 complexity | 26328fa1868d091f8bec61c7b3ed30fd MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, AGPL-3.0
  1. <?php
  2. /**
  3. * Filemanager PHP class
  4. *
  5. * filemanager.class.php
  6. * class for the filemanager.php connector
  7. *
  8. * @license MIT License
  9. * @author Riaan Los <mail (at) riaanlos (dot) nl>
  10. * @author Simon Georget <simon (at) linea21 (dot) com>
  11. * @copyright Authors
  12. */
  13. class Filemanager {
  14. protected $config = array();
  15. protected $language = array();
  16. protected $get = array();
  17. protected $post = array();
  18. protected $properties = array();
  19. protected $item = array();
  20. protected $languages = array();
  21. protected $root = '';
  22. protected $doc_root = '';
  23. protected $dynamic_fileroot = '';
  24. protected $logger = false;
  25. protected $logfile = '/tmp/filemanager.log';
  26. public function __construct($extraConfig = '') {
  27. $content = file_get_contents("../../scripts/filemanager.config.js");
  28. $config = json_decode($content, true);
  29. $this->config = $config;
  30. // override config options if needed
  31. if(!empty($extraConfig)) {
  32. $this->setup($extraConfig);
  33. }
  34. $this->root = dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR;
  35. $this->properties = array(
  36. 'Date Created'=>null,
  37. 'Date Modified'=>null,
  38. 'Height'=>null,
  39. 'Width'=>null,
  40. 'Size'=>null
  41. );
  42. // Log actions or not?
  43. if ($this->config['options']['logger'] == true ) {
  44. if(isset($this->config['options']['logfile'])) {
  45. $this->logfile = $this->config['options']['logfile'];
  46. }
  47. $this->enableLog();
  48. }
  49. // if fileRoot is set manually, $this->doc_root takes fileRoot value
  50. // for security check in isValidPath() method
  51. // else it takes $_SERVER['DOCUMENT_ROOT'] default value
  52. if ($this->config['options']['fileRoot'] !== false ) {
  53. if($this->config['options']['serverRoot'] === true) {
  54. $this->doc_root = $_SERVER['DOCUMENT_ROOT'];
  55. } else {
  56. $this->doc_root = $this->config['options']['fileRoot'];
  57. }
  58. } else {
  59. $this->doc_root = $_SERVER['DOCUMENT_ROOT'];
  60. }
  61. $this->__log(__METHOD__ . ' $this->doc_root value ' . $this->doc_root);
  62. $this->setParams();
  63. $this->availableLanguages();
  64. $this->loadLanguageFile();
  65. }
  66. // $extraconfig should be formatted as json config array.
  67. public function setup($extraconfig) {
  68. $this->config = array_merge_recursive($this->config, $extraconfig);
  69. }
  70. // allow Filemanager to be used with dynamic folders
  71. public function setFileRoot($path) {
  72. if($this->config['options']['serverRoot'] === true) {
  73. $this->doc_root = $_SERVER['DOCUMENT_ROOT']. '/'. $path;
  74. } else {
  75. $this->doc_root = $path;
  76. }
  77. // necessary for retrieving path when set dynamically with $fm->setFileRoot() method
  78. $this->dynamic_fileroot = str_replace($_SERVER['DOCUMENT_ROOT'], '', $this->doc_root);
  79. $this->__log(__METHOD__ . ' $this->doc_root value overwritten : ' . $this->doc_root);
  80. $this->__log(__METHOD__ . ' $this->dynamic_fileroot value ' . $this->dynamic_fileroot);
  81. }
  82. public function error($string,$textarea=false) {
  83. $array = array(
  84. 'Error'=>$string,
  85. 'Code'=>'-1',
  86. 'Properties'=>$this->properties
  87. );
  88. $this->__log( __METHOD__ . ' - error message : ' . $string);
  89. if($textarea) {
  90. echo '<textarea>' . json_encode($array) . '</textarea>';
  91. } else {
  92. echo json_encode($array);
  93. }
  94. die();
  95. }
  96. public function lang($string) {
  97. if(isset($this->language[$string]) && $this->language[$string]!='') {
  98. return $this->language[$string];
  99. } else {
  100. return 'Language string error on ' . $string;
  101. }
  102. }
  103. public function getvar($var) {
  104. if(!isset($_GET[$var]) || $_GET[$var]=='') {
  105. $this->error(sprintf($this->lang('INVALID_VAR'),$var));
  106. } else {
  107. $this->get[$var] = $this->sanitize($_GET[$var]);
  108. return true;
  109. }
  110. }
  111. public function postvar($var) {
  112. if(!isset($_POST[$var]) || $_POST[$var]=='') {
  113. $this->error(sprintf($this->lang('INVALID_VAR'),$var));
  114. } else {
  115. $this->post[$var] = $_POST[$var];
  116. return true;
  117. }
  118. }
  119. public function getinfo() {
  120. $this->item = array();
  121. $this->item['properties'] = $this->properties;
  122. $this->get_file_info();
  123. // handle path when set dynamically with $fm->setFileRoot() method
  124. if($this->dynamic_fileroot != '') {
  125. $path = $this->dynamic_fileroot. $this->get['path'];
  126. $path = preg_replace('~/+~', '/', $path); // remove multiple slashes
  127. } else {
  128. $path = $this->get['path'];
  129. }
  130. $array = array(
  131. 'Path'=> $path,
  132. 'Filename'=>$this->item['filename'],
  133. 'File Type'=>$this->item['filetype'],
  134. 'Preview'=>$this->item['preview'],
  135. 'Properties'=>$this->item['properties'],
  136. 'Error'=>"",
  137. 'Code'=>0
  138. );
  139. return $array;
  140. }
  141. public function getfolder() {
  142. $array = array();
  143. $filesDir = array();
  144. $current_path = $this->getFullPath();
  145. if(!$this->isValidPath($current_path)) {
  146. $this->error("No way.");
  147. }
  148. if(!is_dir($current_path)) {
  149. $this->error(sprintf($this->lang('DIRECTORY_NOT_EXIST'),$this->get['path']));
  150. }
  151. if(!$handle = opendir($current_path)) {
  152. $this->error(sprintf($this->lang('UNABLE_TO_OPEN_DIRECTORY'),$this->get['path']));
  153. } else {
  154. while (false !== ($file = readdir($handle))) {
  155. if($file != "." && $file != "..") {
  156. array_push($filesDir, $file);
  157. }
  158. }
  159. closedir($handle);
  160. // By default
  161. // Sorting files by name ('default' or 'NAME_DESC' cases from $this->config['options']['fileSorting']
  162. natcasesort($filesDir);
  163. foreach($filesDir as $file) {
  164. if(is_dir($current_path . $file)) {
  165. if(!in_array($file, $this->config['exclude']['unallowed_dirs']) && !preg_match( $this->config['exclude']['unallowed_dirs_REGEXP'], $file)) {
  166. $array[$this->get['path'] . $file .'/'] = array(
  167. 'Path'=> $this->get['path'] . $file .'/',
  168. 'Filename'=>$file,
  169. 'File Type'=>'dir',
  170. 'Preview'=> $this->config['icons']['path'] . $this->config['icons']['directory'],
  171. 'Properties'=>array(
  172. 'Date Created'=> date($this->config['options']['dateFormat'], filectime($this->getFullPath($this->get['path'] . $file .'/'))),
  173. 'Date Modified'=> date($this->config['options']['dateFormat'], filemtime($this->getFullPath($this->get['path'] . $file .'/'))),
  174. 'filemtime'=> filemtime($this->getFullPath($this->get['path'] . $file .'/')),
  175. 'Height'=>null,
  176. 'Width'=>null,
  177. 'Size'=>null
  178. ),
  179. 'Error'=>"",
  180. 'Code'=>0
  181. );
  182. }
  183. } else if (!in_array($file, $this->config['exclude']['unallowed_files']) && !preg_match( $this->config['exclude']['unallowed_files_REGEXP'], $file)) {
  184. $this->item = array();
  185. $this->item['properties'] = $this->properties;
  186. $this->get_file_info($this->get['path'] . $file);
  187. if(!isset($this->params['type']) || (isset($this->params['type']) && strtolower($this->params['type'])=='images' && in_array(strtolower($this->item['filetype']),$this->config['images']['imagesExt']))) {
  188. if($this->config['upload']['imagesOnly']== false || ($this->config['upload']['imagesOnly']== true && in_array(strtolower($this->item['filetype']),$this->config['images']['imagesExt']))) {
  189. $array[$this->get['path'] . $file] = array(
  190. 'Path'=>$this->get['path'] . $file,
  191. 'Filename'=>$this->item['filename'],
  192. 'File Type'=>$this->item['filetype'],
  193. 'Preview'=>$this->item['preview'],
  194. 'Properties'=>$this->item['properties'],
  195. 'Error'=>"",
  196. 'Code'=>0
  197. );
  198. }
  199. }
  200. }
  201. }
  202. }
  203. $array = $this->sortFiles($array);
  204. return $array;
  205. }
  206. public function rename() {
  207. $suffix='';
  208. if(substr($this->get['old'],-1,1)=='/') {
  209. $this->get['old'] = substr($this->get['old'],0,(strlen($this->get['old'])-1));
  210. $suffix='/';
  211. }
  212. $tmp = explode('/',$this->get['old']);
  213. $filename = $tmp[(sizeof($tmp)-1)];
  214. $path = str_replace('/' . $filename,'',$this->get['old']);
  215. $new_file = $this->getFullPath($path . '/' . $this->get['new']). $suffix;
  216. $old_file = $this->getFullPath($this->get['old']) . $suffix;
  217. if(!$this->isValidPath($old_file)) {
  218. $this->error("No way.");
  219. }
  220. $this->__log(__METHOD__ . ' - renaming '. $old_file. ' to ' . $new_file);
  221. if(file_exists ($new_file)) {
  222. if($suffix=='/' && is_dir($new_file)) {
  223. $this->error(sprintf($this->lang('DIRECTORY_ALREADY_EXISTS'),$this->get['new']));
  224. }
  225. if($suffix=='' && is_file($new_file)) {
  226. $this->error(sprintf($this->lang('FILE_ALREADY_EXISTS'),$this->get['new']));
  227. }
  228. }
  229. if(!rename($old_file,$new_file)) {
  230. if(is_dir($old_file)) {
  231. $this->error(sprintf($this->lang('ERROR_RENAMING_DIRECTORY'),$filename,$this->get['new']));
  232. } else {
  233. $this->error(sprintf($this->lang('ERROR_RENAMING_FILE'),$filename,$this->get['new']));
  234. }
  235. }
  236. $array = array(
  237. 'Error'=>"",
  238. 'Code'=>0,
  239. 'Old Path'=>$this->get['old'],
  240. 'Old Name'=>$filename,
  241. 'New Path'=>$path . '/' . $this->get['new'].$suffix,
  242. 'New Name'=>$this->get['new']
  243. );
  244. return $array;
  245. }
  246. public function delete() {
  247. $current_path = $this->getFullPath();
  248. if(!$this->isValidPath($current_path)) {
  249. $this->error("No way.");
  250. }
  251. if(is_dir($current_path)) {
  252. $this->unlinkRecursive($current_path);
  253. $array = array(
  254. 'Error'=>"",
  255. 'Code'=>0,
  256. 'Path'=>$this->get['path']
  257. );
  258. $this->__log(__METHOD__ . ' - deleting folder '. $current_path);
  259. return $array;
  260. } else if(file_exists($current_path)) {
  261. unlink($current_path);
  262. $array = array(
  263. 'Error'=>"",
  264. 'Code'=>0,
  265. 'Path'=>$this->get['path']
  266. );
  267. $this->__log(__METHOD__ . ' - deleting file '. $current_path);
  268. return $array;
  269. } else {
  270. $this->error(sprintf($this->lang('INVALID_DIRECTORY_OR_FILE')));
  271. }
  272. }
  273. public function add() {
  274. $this->setParams();
  275. if(!isset($_FILES['newfile']) || !is_uploaded_file($_FILES['newfile']['tmp_name'])) {
  276. $this->error(sprintf($this->lang('INVALID_FILE_UPLOAD')),true);
  277. }
  278. // we determine max upload size if not set
  279. if($this->config['upload']['fileSizeLimit'] == 'auto') {
  280. $this->config['upload']['fileSizeLimit'] = $this->getMaxUploadFileSize();
  281. }
  282. if($_FILES['newfile']['size'] > ($this->config['upload']['fileSizeLimit'] * 1024 * 1024)) {
  283. $this->error(sprintf($this->lang('UPLOAD_FILES_SMALLER_THAN'),$this->config['upload']['size'] . 'Mb'),true);
  284. }
  285. if($this->config['upload']['imagesOnly'] || (isset($this->params['type']) && strtolower($this->params['type'])=='images')) {
  286. if(!($size = @getimagesize($_FILES['newfile']['tmp_name']))){
  287. $this->error(sprintf($this->lang('UPLOAD_IMAGES_ONLY')),true);
  288. }
  289. if(!in_array($size[2], array(1, 2, 3, 7, 8))) {
  290. $this->error(sprintf($this->lang('UPLOAD_IMAGES_TYPE_JPEG_GIF_PNG')),true);
  291. }
  292. }
  293. $_FILES['newfile']['name'] = $this->cleanString($_FILES['newfile']['name'],array('.','-'));
  294. $current_path = $this->getFullPath($this->post['currentpath']);
  295. if(!$this->isValidPath($current_path)) {
  296. $this->error("No way.");
  297. }
  298. if(!$this->config['upload']['overwrite']) {
  299. $_FILES['newfile']['name'] = $this->checkFilename($current_path,$_FILES['newfile']['name']);
  300. }
  301. move_uploaded_file($_FILES['newfile']['tmp_name'], $current_path . $_FILES['newfile']['name']);
  302. chmod($current_path . $_FILES['newfile']['name'], 0644);
  303. $response = array(
  304. 'Path'=>$this->post['currentpath'],
  305. 'Name'=>$_FILES['newfile']['name'],
  306. 'Error'=>"",
  307. 'Code'=>0
  308. );
  309. $this->__log(__METHOD__ . ' - adding file '. $_FILES['newfile']['name']. ' into '. $current_path);
  310. echo '<textarea>' . json_encode($response) . '</textarea>';
  311. die();
  312. }
  313. public function addfolder() {
  314. $current_path = $this->getFullPath();
  315. if(!$this->isValidPath($current_path)) {
  316. $this->error("No way.");
  317. }
  318. if(is_dir($current_path . $this->get['name'])) {
  319. $this->error(sprintf($this->lang('DIRECTORY_ALREADY_EXISTS'),$this->get['name']));
  320. }
  321. $newdir = $this->cleanString($this->get['name']);
  322. if(!mkdir($current_path . $newdir,0755)) {
  323. $this->error(sprintf($this->lang('UNABLE_TO_CREATE_DIRECTORY'),$newdir));
  324. }
  325. $array = array(
  326. 'Parent'=>$this->get['path'],
  327. 'Name'=>$this->get['name'],
  328. 'Error'=>"",
  329. 'Code'=>0
  330. );
  331. $this->__log(__METHOD__ . ' - adding folder '. $current_path . $newdir);
  332. return $array;
  333. }
  334. public function download() {
  335. $current_path = $this->getFullPath();
  336. if(!$this->isValidPath($current_path)) {
  337. $this->error("No way.");
  338. }
  339. if(isset($this->get['path']) && file_exists($current_path)) {
  340. header("Content-type: application/force-download");
  341. header('Content-Disposition: inline; filename="' . basename($current_path) . '"');
  342. header("Content-Transfer-Encoding: Binary");
  343. header("Content-length: ".filesize($current_path));
  344. header('Content-Type: application/octet-stream');
  345. header('Content-Disposition: attachment; filename="' . basename($current_path) . '"');
  346. readfile($current_path);
  347. $this->__log(__METHOD__ . ' - downloading '. $current_path);
  348. exit();
  349. } else {
  350. $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'),$current_path));
  351. }
  352. }
  353. public function preview() {
  354. $current_path = $this->getFullPath();
  355. if(isset($this->get['path']) && file_exists($current_path)) {
  356. header("Content-type: image/" .$ext = pathinfo($current_path, PATHINFO_EXTENSION));
  357. header("Content-Transfer-Encoding: Binary");
  358. header("Content-length: ".filesize($current_path));
  359. header('Content-Disposition: inline; filename="' . basename($current_path) . '"');
  360. readfile($current_path);
  361. $this->__log(__METHOD__ . ' - previewing '. $current_path);
  362. exit();
  363. } else {
  364. $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'),$current_path));
  365. }
  366. }
  367. public function getMaxUploadFileSize() {
  368. $max_upload = (int) ini_get('upload_max_filesize');
  369. $max_post = (int) ini_get('post_max_size');
  370. $memory_limit = (int) ini_get('memory_limit');
  371. $upload_mb = min($max_upload, $max_post, $memory_limit);
  372. $this->__log(__METHOD__ . ' - max upload file size is '. $upload_mb. 'Mb');
  373. return $upload_mb;
  374. }
  375. private function setParams() {
  376. $tmp = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/');
  377. $tmp = explode('?',$tmp);
  378. $params = array();
  379. if(isset($tmp[1]) && $tmp[1]!='') {
  380. $params_tmp = explode('&',$tmp[1]);
  381. if(is_array($params_tmp)) {
  382. foreach($params_tmp as $value) {
  383. $tmp = explode('=',$value);
  384. if(isset($tmp[0]) && $tmp[0]!='' && isset($tmp[1]) && $tmp[1]!='') {
  385. $params[$tmp[0]] = $tmp[1];
  386. }
  387. }
  388. }
  389. }
  390. $this->params = $params;
  391. }
  392. private function get_file_info($path='',$return=array()) {
  393. // DO NOT rawurlencode() since $current_path it
  394. // is used for displaying name file
  395. if($path=='') {
  396. $current_path = $this->get['path'];
  397. } else {
  398. $current_path = $path;
  399. }
  400. $tmp = explode('/',$current_path);
  401. $this->item['filename'] = $tmp[(sizeof($tmp)-1)];
  402. $tmp = explode('.',$this->item['filename']);
  403. $this->item['filetype'] = $tmp[(sizeof($tmp)-1)];
  404. $this->item['filemtime'] = filemtime($this->getFullPath($current_path));
  405. $this->item['filectime'] = filectime($this->getFullPath($current_path));
  406. $this->item['preview'] = $this->config['icons']['path'] . $this->config['icons']['default'];
  407. if(is_dir($current_path)) {
  408. $this->item['preview'] = $this->config['icons']['path'] . $this->config['icons']['directory'];
  409. } else if(in_array(strtolower($this->item['filetype']),$this->config['images']['imagesExt'])) {
  410. // svg should not be previewed as raster formats images
  411. if($this->item['filetype'] == 'svg') {
  412. $this->item['preview'] = $current_path;
  413. } else {
  414. $this->item['preview'] = 'connectors/php/filemanager.php?mode=preview&path='. rawurlencode($current_path);
  415. }
  416. //if(isset($get['getsize']) && $get['getsize']=='true') {
  417. $this->item['properties']['Size'] = filesize($this->getFullPath($current_path));
  418. if ($this->item['properties']['Size']) {
  419. list($width, $height, $type, $attr) = getimagesize($this->getFullPath($current_path));
  420. } else {
  421. $this->item['properties']['Size'] = 0;
  422. list($width, $height) = array(0, 0);
  423. }
  424. $this->item['properties']['Height'] = $height;
  425. $this->item['properties']['Width'] = $width;
  426. $this->item['properties']['Size'] = filesize($this->getFullPath($current_path));
  427. //}
  428. } else if(file_exists($this->root . $this->config['icons']['path'] . strtolower($this->item['filetype']) . '.png')) {
  429. $this->item['preview'] = $this->config['icons']['path'] . strtolower($this->item['filetype']) . '.png';
  430. $this->item['properties']['Size'] = filesize($this->getFullPath($current_path));
  431. if (!$this->item['properties']['Size']) $this->item['properties']['Size'] = 0;
  432. }
  433. $this->item['properties']['Date Modified'] = date($this->config['options']['dateFormat'], $this->item['filemtime']);
  434. $this->item['properties']['filemtime'] = filemtime($this->getFullPath($current_path));
  435. //$return['properties']['Date Created'] = $this->config['options']['dateFormat'], $return['filectime']); // PHP cannot get create timestamp
  436. }
  437. private function getFullPath($path = '') {
  438. if($path == '') {
  439. if(isset($this->get['path'])) $path = $this->get['path'];
  440. }
  441. // $this->__log(__METHOD_. " given path : " . $this->get['path']);
  442. // $this->__log(__METHOD_. " doc_root value : " . $this->doc_root);
  443. // $this->__log(__METHOD_. " dynamic_fileroot value : " . $this->dynamic_fileroot);
  444. if($this->config['options']['fileRoot'] !== false) {
  445. $full_path = $this->doc_root . rawurldecode(str_replace ( $this->doc_root , '' , $path));
  446. if($this->dynamic_fileroot != '') {
  447. $full_path = $this->doc_root . rawurldecode(str_replace ( $this->dynamic_fileroot , '' , $path));
  448. }
  449. } else {
  450. $full_path = $this->doc_root . rawurldecode($path);
  451. }
  452. $full_path = str_replace("//", "/", $full_path);
  453. // $this->__log(__METHOD_. " returned path : " . $full_path);
  454. return $full_path;
  455. }
  456. private function sortFiles($array) {
  457. // handle 'NAME_ASC'
  458. if($this->config['options']['fileSorting'] == 'NAME_ASC') {
  459. $array = array_reverse($array);
  460. }
  461. // handle 'TYPE_ASC' and 'TYPE_DESC'
  462. if(strpos($this->config['options']['fileSorting'], 'TYPE_') !== false || $this->config['options']['fileSorting'] == 'default') {
  463. $a = array();
  464. $b = array();
  465. foreach ($array as $key=>$item){
  466. if(strcmp($item["File Type"], "dir") == 0) {
  467. $a[$key]=$item;
  468. }else{
  469. $b[$key]=$item;
  470. }
  471. }
  472. if($this->config['options']['fileSorting'] == 'TYPE_ASC') {
  473. $array = array_merge($a, $b);
  474. }
  475. if($this->config['options']['fileSorting'] == 'TYPE_DESC' || $this->config['options']['fileSorting'] == 'default') {
  476. $array = array_merge($b, $a);
  477. }
  478. }
  479. // handle 'MODIFIED_ASC' and 'MODIFIED_DESC'
  480. if(strpos($this->config['options']['fileSorting'], 'MODIFIED_') !== false) {
  481. $modified_order_array = array(); // new array as a column to sort collector
  482. foreach ($array as $item) {
  483. $modified_order_array[] = $item['Properties']['filemtime'];
  484. }
  485. if($this->config['options']['fileSorting'] == 'MODIFIED_ASC') {
  486. array_multisort($modified_order_array, SORT_ASC, $array);
  487. }
  488. if($this->config['options']['fileSorting'] == 'MODIFIED_DESC') {
  489. array_multisort($modified_order_array, SORT_DESC, $array);
  490. }
  491. return $array;
  492. }
  493. return $array;
  494. }
  495. private function isValidPath($path) {
  496. // @todo remove debug message
  497. // $this->__log('compare : ' .$this->getFullPath(). '($this->getFullPath()) and ' . $path . '(path)');
  498. // $this->__log('strncmp() retruned value : ' .strncmp($path, $this->getFullPath(), strlen($this->getFullPath())));
  499. return !strncmp($path, $this->getFullPath(), strlen($this->getFullPath()));
  500. }
  501. private function unlinkRecursive($dir,$deleteRootToo=true) {
  502. if(!$dh = @opendir($dir)) {
  503. return;
  504. }
  505. while (false !== ($obj = readdir($dh))) {
  506. if($obj == '.' || $obj == '..') {
  507. continue;
  508. }
  509. if (!@unlink($dir . '/' . $obj)) {
  510. $this->unlinkRecursive($dir.'/'.$obj, true);
  511. }
  512. }
  513. closedir($dh);
  514. if ($deleteRootToo) {
  515. @rmdir($dir);
  516. }
  517. return;
  518. }
  519. private function cleanString($string, $allowed = array()) {
  520. $allow = null;
  521. if (!empty($allowed)) {
  522. foreach ($allowed as $value) {
  523. $allow .= "\\$value";
  524. }
  525. }
  526. $mapping = array(
  527. 'Š'=>'S', 'š'=>'s', 'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c',
  528. 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
  529. 'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
  530. 'Õ'=>'O', 'Ö'=>'O', 'Ő'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ű'=>'U', 'Ý'=>'Y',
  531. 'Þ'=>'B', 'ß'=>'Ss','à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c',
  532. 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n',
  533. 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ő'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'ű'=>'u',
  534. 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r', ' '=>'_', "'"=>'_', '/'=>''
  535. );
  536. if (is_array($string)) {
  537. $cleaned = array();
  538. foreach ($string as $key => $clean) {
  539. $clean = strtr($clean, $mapping);
  540. if($this->config['options']['chars_only_latin'] == true) {
  541. $clean = preg_replace("/[^{$allow}_a-zA-Z0-9]/u", '', $clean);
  542. // $clean = preg_replace("/[^{$allow}_a-zA-Z0-9\x{0430}-\x{044F}\x{0410}-\x{042F}]/u", '', $clean); // allow only latin alphabet with cyrillic
  543. }
  544. $cleaned[$key] = preg_replace('/[_]+/', '_', $clean); // remove double underscore
  545. }
  546. } else {
  547. $string = strtr($string, $mapping);
  548. if($this->config['options']['chars_only_latin'] == true) {
  549. $clean = preg_replace("/[^{$allow}_a-zA-Z0-9]/u", '', $string);
  550. // $clean = preg_replace("/[^{$allow}_a-zA-Z0-9\x{0430}-\x{044F}\x{0410}-\x{042F}]/u", '', $string); // allow only latin alphabet with cyrillic
  551. }
  552. $cleaned = preg_replace('/[_]+/', '_', $string); // remove double underscore
  553. }
  554. return $cleaned;
  555. }
  556. private function sanitize($var) {
  557. $sanitized = strip_tags($var);
  558. $sanitized = str_replace('http://', '', $sanitized);
  559. $sanitized = str_replace('https://', '', $sanitized);
  560. $sanitized = str_replace('../', '', $sanitized);
  561. return $sanitized;
  562. }
  563. private function checkFilename($path,$filename,$i='') {
  564. if(!file_exists($path . $filename)) {
  565. return $filename;
  566. } else {
  567. $_i = $i;
  568. $tmp = explode(/*$this->config['upload']['suffix'] . */$i . '.',$filename);
  569. if($i=='') {
  570. $i=1;
  571. } else {
  572. $i++;
  573. }
  574. $filename = str_replace($_i . '.' . $tmp[(sizeof($tmp)-1)],$i . '.' . $tmp[(sizeof($tmp)-1)],$filename);
  575. return $this->checkFilename($path,$filename,$i);
  576. }
  577. }
  578. private function loadLanguageFile() {
  579. // we load langCode var passed into URL if present and if exists
  580. // else, we use default configuration var
  581. $lang = $this->config['options']['culture'];
  582. if(isset($this->params['langCode']) && in_array($this->params['langCode'], $this->languages)) $lang = $this->params['langCode'];
  583. if(file_exists($this->root. 'scripts/languages/'.$lang.'.js')) {
  584. $stream =file_get_contents($this->root. 'scripts/languages/'.$lang.'.js');
  585. $this->language = json_decode($stream, true);
  586. } else {
  587. $stream =file_get_contents($this->root. 'scripts/languages/'.$lang.'.js');
  588. $this->language = json_decode($stream, true);
  589. }
  590. }
  591. private function availableLanguages() {
  592. if ($handle = opendir($this->root.'/scripts/languages/')) {
  593. while (false !== ($file = readdir($handle))) {
  594. if ($file != "." && $file != "..") {
  595. array_push($this->languages, pathinfo($file, PATHINFO_FILENAME));
  596. }
  597. }
  598. closedir($handle);
  599. }
  600. }
  601. private function __log($msg) {
  602. if($this->logger == true) {
  603. $fp = fopen($this->logfile, "a");
  604. $str = "[" . date("d/m/Y h:i:s", mktime()) . "] " . $msg;
  605. fwrite($fp, $str . PHP_EOL);
  606. fclose($fp);
  607. }
  608. }
  609. public function enableLog($logfile = '') {
  610. $this->logger = true;
  611. if($logfile != '') {
  612. $this->logfile = $logfile;
  613. }
  614. $this->__log(__METHOD__ . ' - Log enabled (in '. $this->logfile. ' file)');
  615. }
  616. public function disableLog() {
  617. $this->logger = false;
  618. $this->__log(__METHOD__ . ' - Log disabled');
  619. }
  620. }
  621. ?>