PageRenderTime 58ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/models/common/common_file.php

https://github.com/laposa/onxshop
PHP | 1022 lines | 559 code | 152 blank | 311 comment | 60 complexity | ef2bf0584ceacc5c8bdecee34a3ad758 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * class common_file
  4. *
  5. * Copyright (c) 2009-2014 Laposa Ltd (http://laposa.co.uk)
  6. * Licensed under the New BSD License. See the file LICENSE.txt for details.
  7. *
  8. */
  9. class common_file extends Onxshop_Model {
  10. /**
  11. * PRIMARY KEY
  12. * @access private
  13. */
  14. var $id;
  15. /**
  16. * @access private
  17. */
  18. var $src;
  19. /**
  20. * @access private
  21. * e.g. main (default), teaser, RTE
  22. */
  23. var $role;
  24. /**
  25. * NOT NULL REFERENCES common_node(id) ON UPDATE CASCADE ON DELETE CASCADE
  26. * @access private
  27. */
  28. var $node_id;
  29. /**
  30. * @access private
  31. */
  32. var $title;
  33. /**
  34. * @access private
  35. */
  36. var $description;
  37. /**
  38. * @access private
  39. */
  40. var $priority;
  41. /**
  42. * @access private
  43. */
  44. var $modified;
  45. /**
  46. * @access private
  47. */
  48. var $author;
  49. /**
  50. * @access private
  51. */
  52. var $customer_id;
  53. var $_metaData = array(
  54. 'id'=>array('label' => '', 'validation'=>'int', 'required'=>true),
  55. 'src'=>array('label' => '', 'validation'=>'string', 'required'=>true),
  56. 'role'=>array('label' => '', 'validation'=>'string', 'required'=>false),
  57. 'node_id'=>array('label' => '', 'validation'=>'int', 'required'=>true),
  58. 'title'=>array('label' => '', 'validation'=>'string', 'required'=>true),
  59. 'description'=>array('label' => '', 'validation'=>'string', 'required'=>false),
  60. 'priority'=>array('label' => '', 'validation'=>'int', 'required'=>false),
  61. 'modified'=>array('label' => '', 'validation'=>'datetime', 'required'=>true),
  62. 'author'=>array('label' => '', 'validation'=>'int', 'required'=>false),
  63. 'customer_id'=>array('label' => '', 'validation'=>'int', 'required'=>false),
  64. 'content'=>array('label' => '', 'validation'=>'int', 'required'=>false),
  65. 'other_data'=>array('label' => '', 'validation'=>'serialized', 'required'=>false),
  66. 'link_to_node_id'=>array('label' => '', 'validation'=>'int', 'required'=>false)
  67. );
  68. /**
  69. * create table sql
  70. *
  71. * @return string
  72. * SQL command for table creating
  73. */
  74. private function getCreateTableSql() {
  75. $sql = "
  76. CREATE TABLE common_file (
  77. id serial NOT NULL PRIMARY KEY,
  78. src varchar(255),
  79. role character varying(255),
  80. node_id int NOT NULL REFERENCES common_node ON UPDATE CASCADE ON DELETE CASCADE,
  81. title varchar(255) ,
  82. description text ,
  83. priority int DEFAULT 0 NOT NULL,
  84. modified timestamp(0) ,
  85. author int,
  86. customer_id integer REFERENCES client_customer ON UPDATE CASCADE ON DELETE RESTRICT,
  87. content text,
  88. other_data text,
  89. link_to_node_id integer
  90. );
  91. ";
  92. return $sql;
  93. }
  94. /**
  95. * get file detail
  96. *
  97. * @param integer $id
  98. * file ID
  99. *
  100. * @return array
  101. * file detail
  102. */
  103. public function getFileDetail($id) {
  104. if (!is_numeric($id)) return false;
  105. $file_detail = $this->detail($id);
  106. $file_detail = $this->populateAdditionalInfo($file_detail);
  107. return $file_detail;
  108. }
  109. /**
  110. * get detail alias to getFileDetail
  111. *
  112. * @param integer $id
  113. * file ID
  114. *
  115. * @return array
  116. * file detail
  117. */
  118. public function getDetail($id) {
  119. return $this->getFileDetail($id);
  120. }
  121. /**
  122. * update file
  123. *
  124. * @param array $data
  125. * file data
  126. *
  127. * @return bool
  128. * on error return false
  129. */
  130. public function updateFile($data) {
  131. if (!is_numeric($data['link_to_node_id'])) $data['link_to_node_id'] = 0;
  132. return $this->update($data);
  133. }
  134. /**
  135. * get additional info
  136. *
  137. * @param array $file_detail
  138. * file information
  139. *
  140. * @return array
  141. * extended file detail
  142. */
  143. public function populateAdditionalInfo($file_detail) {
  144. $full_path = ONXSHOP_PROJECT_DIR . $file_detail['src'];
  145. $file_detail['file_path_encoded'] = $this->encode_file_path($full_path);
  146. if (file_exists($full_path)) {
  147. $file_detail['info'] = $this->getFileInfo($full_path);
  148. } else {
  149. msg("File $full_path", 'error', 1);
  150. }
  151. if (preg_match('/^image/', $file_detail['info']['mime-type'])) {
  152. $file_detail['imagesize'] = $this->getImageSize($full_path);
  153. }
  154. return $file_detail;
  155. }
  156. /**
  157. * list files
  158. *
  159. * @param integer $node_id
  160. * ID of node with files
  161. *
  162. * @param string $priority
  163. * sorting part of SQL
  164. *
  165. * @param string $role
  166. * role name or false for all
  167. *
  168. * @return array
  169. * list of files
  170. */
  171. function listFiles($node_id , $priority = "priority DESC, id ASC", $role = false, $limit = '') {
  172. $result = array();
  173. if (is_numeric($node_id)) {
  174. if ($role) {
  175. $files = $this->listing("node_id = $node_id AND role = '$role'", $priority, $limit);
  176. } else {
  177. $files = $this->listing("node_id = $node_id", $priority, $limit);
  178. }
  179. } else {
  180. msg("File->listFiles: node_id is not numeric", 'error');
  181. }
  182. foreach ($files as $file_detail) {
  183. $file_detail = $this->populateAdditionalInfo($file_detail);
  184. $result[] = $file_detail;
  185. }
  186. return $result;
  187. }
  188. /**
  189. * get file link
  190. *
  191. * @param string $src
  192. * src of file
  193. *
  194. * @return array
  195. * files with this src
  196. */
  197. function getFileLink($src) {
  198. $file_list = $this->listing("src='$src'");
  199. return $file_list;
  200. }
  201. /**
  202. * insert file
  203. *
  204. * @param array $file
  205. * information of file for insert
  206. *
  207. * @return integer
  208. * ID of inserted file or false
  209. */
  210. function insertFile($file = array()) {
  211. $src = ONXSHOP_PROJECT_DIR . $file['src'];
  212. if (is_readable($src)) {
  213. if (!is_numeric($file['priority'])) $file['priority'] = 0;
  214. $file['modified'] = date('c');
  215. if (!is_numeric($file['author'])) $file['author'] = 0; // deprecated as of Onxshop 1.7
  216. if (!is_numeric($file['customer_id'])) $file['customer_id'] = (int) $_SESSION['client']['customer']['id'];
  217. if ($id = $this->insert($file)) {
  218. msg('File Inserted', 'ok', 2);
  219. return $id;
  220. } else {
  221. msg("Can't insert file $src", 'error');
  222. return false;
  223. }
  224. } else {
  225. msg("$src does not exists!", 'error');
  226. return false;
  227. }
  228. }
  229. /**
  230. * Copy single uploaded file
  231. * return string filename on success, array when file exists, otherwise false
  232. *
  233. * @param array $file
  234. * information of uploaded file
  235. *
  236. * @param string $save_dir
  237. * directory for save file
  238. *
  239. * @param unknown_type $overwrite
  240. * not used
  241. *
  242. * @return mixed
  243. * string returned when upload to the save_dir was successfull
  244. * array returned when saved to temporary folder with saved file information
  245. * false returned on failure
  246. */
  247. function getSingleUpload($file = array(), $save_dir, $overwrite = 0) {
  248. $upload_file = $file['tmp_name'];
  249. $safe_filename = $this->nameToSafe($file['name']);
  250. $save_file = $save_dir . $safe_filename;
  251. $save_file_full = ONXSHOP_PROJECT_DIR . $save_file;
  252. $save_dir_full = ONXSHOP_PROJECT_DIR . $save_dir;
  253. if (!file_exists($save_dir_full)) {
  254. if (!mkdir($save_dir_full)) {
  255. msg("common_file.getSingleUpload(): Cannot create folder $save_dir_full", 'error');
  256. }
  257. }
  258. if (is_uploaded_file($upload_file)) {
  259. if (file_exists($save_file_full)) {
  260. msg("File '$save_file_full' already exists!", 'error');
  261. $temp_file = "var/tmp/$safe_filename";
  262. msg("Saving as $temp_file", 'ok', 2);
  263. if (copy($upload_file, ONXSHOP_PROJECT_DIR . $temp_file)) {
  264. //array type for result (indicates overwrite)
  265. $result = array( 'filename'=> $safe_filename, 'save_dir'=> $save_dir, "temp_file"=>$temp_file);
  266. return $result;
  267. } else {
  268. msg("common_file.getSingleUpload(): Cannot copy $upload_file to temp location " . ONXSHOP_PROJECT_DIR . $temp_file, 'error');
  269. return false;
  270. }
  271. } else {
  272. if (copy($upload_file, $save_file_full)) {
  273. msg("File '$save_file_full' saved.", 'ok', 2);
  274. //chmod($save_file_full, 0666);
  275. //string type for result
  276. return $save_file;
  277. } else {
  278. msg("common_file.getSingleUpload(): Cannot copy $upload_file to $save_file_full", 'error');
  279. return false;
  280. }
  281. }
  282. } else {
  283. msg(" File '$upload_file' not saved.", "error");
  284. return false;
  285. }
  286. }
  287. /**
  288. * safe filename convertor
  289. *
  290. * @param string $name
  291. * original file name
  292. *
  293. * @param integer $maxlen
  294. * maximal file name length
  295. *
  296. * @return string
  297. * converted file name
  298. */
  299. static function nameToSafe($name, $maxlen=250) {
  300. $name = self::recodeUTF8ToAscii($name);
  301. return preg_replace('/[^a-zA-Z0-9._-]/', '_', $name);
  302. }
  303. /**
  304. * duplicated function from common_uri_mapping
  305. *
  306. * @param string $string
  307. * text in UTF8 encoding
  308. *
  309. * @return string
  310. * text recoded into ASCII
  311. */
  312. static function recodeUTF8ToAscii($string) {
  313. //recode to ASCII
  314. if (function_exists("recode_string")) {
  315. $string = recode_string("utf-8..flat", trim($string));
  316. } else {
  317. //msg($fullpath, 'ok', 2);
  318. //$fullpath = iconv("UTF-8", "ASCII//TRANSLIT", trim($fullpath));
  319. //$fullpath = utf2ascii(trim($fullpath));
  320. $string = mb_convert_encoding($string,"HTML-ENTITIES","UTF-8");
  321. $string = preg_replace('/\&(.)[^;]*;/', "\\1", $string);
  322. //msg($fullpath, 'ok', 2);
  323. }
  324. return $string;
  325. }
  326. /**
  327. * Ovewrite file
  328. *
  329. * @param string $filename
  330. * destination file name
  331. *
  332. * @param string $save_dir
  333. * destination directory
  334. *
  335. * @param string $temp_file
  336. * source file name
  337. *
  338. * @return boolean
  339. * is file copied successfully?
  340. */
  341. function overwriteFile($filename, $save_dir, $temp_file) {
  342. $result = $this->_overwriteFile($filename, $save_dir, $temp_file);
  343. if ($result) {
  344. $thumbnails_dir = ONXSHOP_PROJECT_DIR . "var/thumbnails/";
  345. $sizes = scandir($thumbnails_dir);
  346. foreach ($sizes as $size) {
  347. if (preg_match("/^[0-9]*x?([0-9]*)?$/", $size)) {
  348. $file_full_path = $thumbnails_dir . "$size/" . md5($save_dir . $filename);
  349. // get all files starting with the filename (i.e. including params method, gravity, fill)
  350. foreach (glob($file_full_path . "*") as $filename_to_delete) {
  351. if (file_exists($filename_to_delete) && is_file($filename_to_delete)) {
  352. if (unlink($filename_to_delete)) msg("Deleted $filename_to_delete", 'ok', 2);
  353. else msg("common_file.overwriteFile(): Cannot delete $filename_to_delete");
  354. } else {
  355. msg("File $filename_to_delete was found by glob(), but it's not a valid file", 'error');
  356. }
  357. }
  358. }
  359. }
  360. return $result;
  361. } else {
  362. msg("Cannot overwrite file $filename, please check file permissions on the server", 'error');
  363. return false;
  364. }
  365. }
  366. /**
  367. * Overwrite existing file on the filesystem
  368. *
  369. * @param string $filename
  370. * destination file name
  371. *
  372. * @param string $save_dir
  373. * destination directory
  374. *
  375. * @param string $temp_file
  376. * source file name
  377. *
  378. * @return boolean
  379. * is file copied successfully?
  380. */
  381. function _overwriteFile($filename, $save_dir, $temp_file) {
  382. //$src_file_full = ONXSHOP_PROJECT_DIR . "var/tmp/" . $filename;
  383. $src_file_full = ONXSHOP_PROJECT_DIR . $temp_file;
  384. $save_file_full = ONXSHOP_PROJECT_DIR . $save_dir . $filename;
  385. if (copy($src_file_full, $save_file_full)) {
  386. if (is_readable($save_file_full)) return true;
  387. else return false;
  388. } else {
  389. return false;
  390. }
  391. }
  392. /**
  393. * Unlink File from database
  394. *
  395. * @param integer $id
  396. * ID of file
  397. *
  398. * @return boolean
  399. * unlinked successfully?
  400. */
  401. function unlinkFile( $id ) {
  402. $file = $this->detail($id);
  403. if ($this->delete($id)) {
  404. msg("File ID $id has been unlinked from the database", 'ok', 2);
  405. return true;
  406. } else {
  407. msg("Deletion of file ID $id from the database has failed", 'error');
  408. return false;
  409. }
  410. }
  411. /**
  412. * remove file from the filesystem
  413. *
  414. * @param string $file
  415. * file name
  416. *
  417. * @return boolean
  418. * deleted successfully?
  419. */
  420. function deleteFile( $file ) {
  421. $file_full_path = ONXSHOP_PROJECT_DIR . $file;
  422. if (file_exists($file_full_path)) {
  423. if (is_dir($file_full_path)) {
  424. if (rmdir($file_full_path)) msg("Directory has been removed");
  425. else msg("Can't remove directory", "error");
  426. } else {
  427. //check if it's not used from other records
  428. $relations_list = $this->getRelations($file);
  429. if ($relations_list['count'] === 0) {
  430. msg("File $file has been deleted from database", 'ok', 2);
  431. if (unlink($file_full_path)) msg("File $file_full_path has been deleted from filesystem", 'ok', 2);
  432. else return false;
  433. msg("File $file has been deleted successfully", 'ok', 2);
  434. return true;
  435. } else {
  436. msg("Can't delete. File $file is in use.", 'error');
  437. return false;
  438. }
  439. }
  440. } else {
  441. msg("Can't delete. File doesn't exists.", 'error');
  442. return false;
  443. }
  444. }
  445. /**
  446. * rm() -- Vigorously erase files and directories.
  447. *
  448. * @param $fileglob mixed If string, must be a file name (foo.txt), glob pattern (*.txt), or directory name.
  449. * If array, must be an array of file names, glob patterns, or directories.
  450. *
  451. * @return boolean
  452. * erased successfully?
  453. */
  454. function rm($fileglob) {
  455. if (is_string($fileglob)) {
  456. if (is_file($fileglob)) {
  457. return unlink($fileglob);
  458. } else if (is_dir($fileglob)) {
  459. $ok = $this->rm("$fileglob/*");
  460. if (! $ok) {
  461. return false;
  462. }
  463. return $this->unlinkRecursive($fileglob);
  464. } else {
  465. $matching = glob($fileglob);
  466. if ($matching === false) {
  467. trigger_error(sprintf('No files match supplied glob %s', $fileglob), E_USER_WARNING);
  468. return false;
  469. }
  470. $rcs = array_map(array($this, 'rm'), $matching);
  471. if (in_array(false, $rcs)) {
  472. return false;
  473. }
  474. }
  475. } else if (is_array($fileglob)) {
  476. $rcs = array_map(array($this, 'rm'), $fileglob);
  477. if (in_array(false, $rcs)) {
  478. return false;
  479. }
  480. } else {
  481. trigger_error('Param #1 must be filename or glob pattern, or array of filenames or glob patterns', E_USER_ERROR);
  482. return false;
  483. }
  484. return true;
  485. }
  486. /**
  487. * Recursively delete a directory
  488. *
  489. * @param string $dir Directory name
  490. * @param boolean $deleteRootToo Delete specified top-level directory as well
  491. *
  492. * @return boolean
  493. * erased successfully?
  494. */
  495. function unlinkRecursive($dir, $deleteRootToo = true) {
  496. if(!$dh = opendir($dir))
  497. {
  498. return; //TODO: return false?
  499. }
  500. while (false !== ($obj = readdir($dh)))
  501. {
  502. if($obj == '.' || $obj == '..')
  503. {
  504. continue;
  505. }
  506. if (!unlink($dir . '/' . $obj))
  507. {
  508. $this->unlinkRecursive($dir.'/'.$obj, true);
  509. }
  510. }
  511. closedir($dh);
  512. if ($deleteRootToo)
  513. {
  514. rmdir($dir);
  515. }
  516. return true;
  517. }
  518. /**
  519. * Find where the file is used
  520. *
  521. * @param string $file
  522. * file src
  523. *
  524. * @return array
  525. * file using places list
  526. */
  527. function getRelations($file) {
  528. require_once('models/common/common_file.php');
  529. $CommonFile = new common_file();
  530. $file_list['file'] = $CommonFile->getFileLink($file);
  531. require_once('models/common/common_image.php');
  532. $CommonImage = new common_image();
  533. $file_list['node'] = $CommonImage->getFileLink($file);
  534. require_once('models/ecommerce/ecommerce_product_image.php');
  535. $ProductImage = new ecommerce_product_image();
  536. $file_list['product'] = $ProductImage->getFileLink($file);
  537. require_once('models/ecommerce/ecommerce_product_variety_image.php');
  538. $ProductVarietyImage = new ecommerce_product_variety_image();
  539. $file_list['product_variety'] = $ProductVarietyImage->getFileLink($file);
  540. require_once('models/common/common_taxonomy_label_image.php');
  541. $TaxonomyImage = new common_taxonomy_label_image();
  542. $file_list['taxonomy'] = $TaxonomyImage->getFileLink($file);
  543. require_once('models/ecommerce/ecommerce_recipe_image.php');
  544. $RecipeImage = new ecommerce_recipe_image();
  545. $file_list['recipe'] = $RecipeImage->getFileLink($file);
  546. require_once('models/ecommerce/ecommerce_store_image.php');
  547. $StoreImage = new ecommerce_store_image();
  548. $file_list['store'] = $StoreImage->getFileLink($file);
  549. require_once('models/education/education_survey_image.php');
  550. $SurveyImage = new education_survey_image();
  551. $file_list['survey'] = $SurveyImage->getFileLink($file);
  552. $file_list['count'] = count($file_list['file']) + count($file_list['node']) +
  553. count($file_list['product']) + count($file_list['product_variety']) +
  554. count($file_list['taxonomy']) + count($file_list['recipe']) +
  555. count($file_list['store']) + count($file_list['survey']);
  556. return $file_list;
  557. }
  558. /**
  559. * Get detailed file info
  560. *
  561. * @param string $fp
  562. * file name
  563. *
  564. * @return array
  565. * file info
  566. */
  567. function getFileInfo($fp, $extra_detail = false) {
  568. $file_info['modified'] = strftime("%c", filemtime($fp));
  569. $file_info['mime-type'] = local_exec("file -bi " . escapeshellarg($fp));
  570. $file_info['type-detail'] = local_exec("file -b " . escapeshellarg($fp));
  571. $file_info['file_path'] = str_replace(ONXSHOP_PROJECT_DIR . 'var/files/', '', $fp);
  572. $file_info['size'] = $this->resize_bytes(filesize($fp));
  573. if ($extra_detail) {
  574. if (trim($file_info['mime-type']) == 'application/pdf') {
  575. $file_info['extra-detail'] = local_exec("pdfinfo " . escapeshellarg($fp));
  576. } else if (preg_match("/^image/", $file_info['mime-type'])) {
  577. $file_info['extra-detail'] = local_exec("identify " . escapeshellarg($fp));
  578. }
  579. }
  580. //find filename
  581. $file_path_segments = explode('/', $fp);
  582. $file_info['filename'] = $file_path_segments[count($file_path_segments)-1];
  583. return $file_info;
  584. }
  585. /**
  586. * encode file path to base64
  587. *
  588. * @param string $string
  589. * input text
  590. *
  591. * @return string
  592. * encoded text
  593. */
  594. function encode_file_path($string) {
  595. return str_replace('=', '_XXX_', base64_encode($string));
  596. }
  597. /**
  598. * decode file path from base64
  599. *
  600. * @param string $string
  601. * input text
  602. *
  603. * @return string
  604. * encoded text
  605. */
  606. function decode_file_path($string) {
  607. return base64_decode(str_replace('_XXX_', '=', $string));
  608. }
  609. /**
  610. * function for replace of bin/csv_from_fs
  611. * use the php glob() function
  612. *
  613. * @param string $directory
  614. * start directory
  615. *
  616. * @param string $type
  617. * type of items (default '' for all, 'f' for files, 'd' for directories)
  618. *
  619. * @param boolean $recursive
  620. * walk into subdirectories?
  621. *
  622. * @return string
  623. * files information formatted as from bin/csv_from_fs
  624. */
  625. private function csv_from_glob($directory, $type = '', $recursive = true) {
  626. $path[] = "$directory/*";
  627. $out = array();
  628. while(count($path) != 0) {
  629. $v = array_shift($path);
  630. foreach(glob($v) as $item) {
  631. if( ($type == '') || (($type == 'f') && (filetype($item) == 'file')) || (($type == 'd') && (filetype($item) == 'dir')) ) {
  632. $out[] = $this->getFileFindFormat($item);
  633. }
  634. if ($recursive && is_dir($item)) {
  635. $path[] = $item . '/*';
  636. }
  637. }
  638. }
  639. sort($out);
  640. $text = '';
  641. foreach ($out as $line) {
  642. $text .= "$line\n";
  643. }
  644. return $text;
  645. }
  646. /**
  647. * get file information in find format "%h/%f;%h;%f;%s;%c"
  648. *
  649. * @param string $file
  650. * file name with path
  651. *
  652. * @return string
  653. * formatted file informations
  654. */
  655. private function getFileFindFormat($file) {
  656. $fpath = "./$file";
  657. $path_parts = pathinfo($fpath);
  658. $dirname = $path_parts['dirname'];
  659. $basename = $path_parts['basename'];
  660. $filesize = filesize($fpath);
  661. $filectime = gmdate('D M j H:i:s Y', filectime($fpath));
  662. return "$fpath;$dirname;$basename;$filesize;$filectime";
  663. }
  664. /**
  665. * get file list using unix file command
  666. * TODO: use PHP glob() instead
  667. *
  668. * @param string $directory
  669. * from this directory
  670. *
  671. * @param string $attrs
  672. * files attributes
  673. *
  674. * @param integer $display_hidden
  675. * with hidden files (1) or not (0)
  676. *
  677. * @return mixed
  678. * files array or false
  679. */
  680. function getFlatArrayFromFs($directory, $attrs = '', $display_hidden = 0) {
  681. //FIND2GLOB PATCH: function getFlatArrayFromFs($directory, $type = '', $recursive = true, $display_hidden = 0) {
  682. msg("calling getFlatArrayFromFs($directory)", 'ok', 3);
  683. if (!file_exists($directory)) {
  684. msg("Directory $directory does not exists!", 'error');
  685. return false;
  686. }
  687. $csv_list = local_exec("csv_from_fs " . escapeshellarg($directory) . " " . escapeshellarg($attrs));
  688. //FIND2GLOB PATCH: $csv_list = $this->csv_from_glob($directory, $type, $recursive);
  689. $csv_list = str_replace(rtrim($directory, '/'), '', $csv_list);
  690. $csv_array = explode("\n", $csv_list);
  691. $basename = '/' . basename($directory) . '/';
  692. foreach ($csv_array as $c) {
  693. $x = explode(';', $c);
  694. //dont populate base directory
  695. if ($x[0] != $basename) $csv[] = $x;
  696. }
  697. array_pop($csv);
  698. foreach ($csv as $c) {
  699. $l['id'] = ltrim($c[0], '/');
  700. $l['parent'] = ltrim($c[1], '/');
  701. $l['name'] = $c[2];
  702. $l['title'] = $c[2];
  703. if (is_dir($directory . $l['id'])) $l['node_group'] = 'folder';
  704. else $l['node_group'] = 'file';
  705. $l['publish'] = 1;
  706. $l['size'] = $this->resize_bytes($c[3]);
  707. $l['modified'] = str_replace('.0000000000', '', $c[4]); //remove seconds fraction
  708. if ($display_hidden) {
  709. $csvf[] = $l;
  710. } else {
  711. // don't display hidden files files beginning with "."
  712. if (!preg_match("/^\./", $l['name'])) $csvf[] = $l;
  713. }
  714. }
  715. if (!is_array($csvf)) $csvf = array();
  716. return $csvf;
  717. }
  718. /**
  719. * get joined list of files from ONXSHOP_DIR and ONXSHOP_PROJECT_DIR
  720. *
  721. * @param string $directory
  722. * from this subdirectory
  723. *
  724. * @return array
  725. * merged files list
  726. */
  727. function getFlatArrayFromFsJoin ($directory) {
  728. $global_templates_dir = ONXSHOP_DIR . $directory;
  729. $global_templates = $this->getFlatArrayFromFs($global_templates_dir);
  730. $application_templates_dir = ONXSHOP_PROJECT_DIR . $directory;
  731. if (is_dir($application_templates_dir)) $application_templates = $this->getFlatArrayFromFs($application_templates_dir);
  732. else $application_templates = array();
  733. //merge
  734. $templates1 = array_merge($application_templates, $global_templates);
  735. //remove duplicates
  736. $ids = array();
  737. foreach ($templates1 as $t) {
  738. if (!in_array($t['id'], $ids)) {
  739. $ids[] = $t['id'];
  740. $templates[] = $t;
  741. }
  742. }
  743. return $templates;
  744. }
  745. /**
  746. * Get File List from file system
  747. *
  748. * @param string $directory
  749. * from this directory
  750. *
  751. * @param string $attrs
  752. * files attributes
  753. *
  754. * @return mixed
  755. * files array or false
  756. */
  757. function getTree($directory, $type = '') {
  758. $list = $this->getFlatArrayFromFs($directory, $type);
  759. return $list;
  760. }
  761. /**
  762. * byte format
  763. *
  764. * @param integer $size
  765. * size in numeric format
  766. *
  767. * @return string
  768. * text representation of input size
  769. */
  770. function resize_bytes($size) {
  771. $count = 0;
  772. $format = array("B","KB","MB","GB","TB","PB","EB","ZB","YB");
  773. while(($size/1024)>1 && $count<8)
  774. {
  775. $size=$size/1024;
  776. $count++;
  777. }
  778. $return = number_format($size,0,'','.')." ".$format[$count];
  779. return $return;
  780. }
  781. /**
  782. * get image size
  783. *
  784. * @param string $file
  785. * file name
  786. *
  787. * @return mixed
  788. * array with image dimensions, or false if not found
  789. */
  790. static function getImageSize($file) {
  791. if (is_readable($file)) {
  792. $size = getimagesize($file);
  793. if ($size) {
  794. $result['width'] = $size[0];
  795. $result['height'] = $size[1];
  796. $result['proportion'] = $result['width']/$result['height'];
  797. msg("Image has size {$result['width']}x{$result['height']}. Ratio of image sides is {$result['proportion']}", 'ok', 3);
  798. return $result;
  799. } else {
  800. msg("common_image.getImageSize(): $files is not an image", 'error', 1);
  801. return false;
  802. }
  803. } else {
  804. msg("common_image.getImageSize(): $file isn't readable", 'error');
  805. return false;
  806. }
  807. }
  808. }