PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/application/classes/core/model/file.php

https://bitbucket.org/alameya/alameya_core
PHP | 485 lines | 289 code | 51 blank | 145 comment | 47 complexity | 9866f5693626b81e5db37feec5be46be MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. class Core_Model_File extends Model
  3. {
  4. private $files_path = '';
  5. private $controller = '';
  6. ###################################################################################################################################################
  7. ################################################## ОБЩИЙ ПЕРЕХОД ПО ПАПКАМ ########################################################################
  8. ###################################################################################################################################################
  9. function __construct($controller = null)
  10. {
  11. $this->controller = ($controller == null)? Request::current()->controller(): $controller;
  12. $this->files_path = "files/$this->controller/";
  13. }
  14. private function go_to($id)
  15. {
  16. if(!file_exists('files'))
  17. mkdir('files' , 0777); // пытаемся содать папку files если ее нет
  18. if(!chdir('files')) return false;
  19. if(!file_exists($this->controller))
  20. mkdir($this->controller, 0777); // пытаемся содать папку с названием контроллера
  21. if(!chdir($this->controller)) return false;
  22. if(!file_exists($id))
  23. mkdir($id , 0777);
  24. if(!chdir($id)) return false;
  25. return true;
  26. }
  27. private function go_out()
  28. {
  29. if (!chdir('../../../')) return false;
  30. return true;
  31. }
  32. private function crypt_filename($filename)
  33. {
  34. $temp_array = explode('.', $filename);
  35. $count = count($temp_array);
  36. if($count > 1)
  37. {
  38. return sha1($filename.$filename).'.'.$temp_array[$count - 1];
  39. }
  40. if($count == 1) // без расширения
  41. {
  42. return sha1($filename.$filename);
  43. }
  44. }
  45. public function get_allowed_types($files_type, $as_array = false)
  46. {
  47. if(!is_array($files_type))
  48. {
  49. switch($files_type)
  50. {
  51. case 'images':
  52. {
  53. $files_type_array = array( 'jpg','jpeg', 'png','bmp', 'gif');
  54. break;
  55. }
  56. case 'docs':
  57. {
  58. $files_type_array = array( 'doc','docx', 'xml','xsl', 'ppt');
  59. break;
  60. }
  61. default: // all
  62. {
  63. if ($as_array)return array();
  64. else return "*";
  65. }
  66. }
  67. }
  68. else
  69. {
  70. $files_type_array = $files_type;
  71. }
  72. $case_up_array = array();
  73. foreach($files_type_array as $item)
  74. {
  75. $case_up_array[] = strtoupper($item);
  76. }
  77. $allowed_types = array_merge($files_type_array , $case_up_array);
  78. if ($as_array)
  79. return $allowed_types;
  80. else return implode(',' , $allowed_types);
  81. }
  82. private function file_query($filename , $resource_id)
  83. {
  84. return DB::Select()
  85. ->from('files')
  86. ->where('filename' , '=' , $filename)
  87. ->where('controller' , '=' , $this->controller)
  88. ->where('resource_id' , '=' , $resource_id)
  89. ->as_object();
  90. }
  91. public function get_from_db($filename , $resource_id)
  92. {
  93. $query = $this->file_query($filename , $resource_id);
  94. return $query->execute()->current();
  95. }
  96. public function del_from_db($filename , $resource_id)
  97. {
  98. $query = DB::Delete('files');
  99. if(is_array($filename)) // удаление массива файлов
  100. {
  101. $query->where('filename' , 'IN' , $filename);
  102. }
  103. elseif($filename == 'all') // удаление всех файлов
  104. {
  105. // просто ниче не пишим :)
  106. }
  107. else // один файл
  108. {
  109. $query->where('filename' , '=' , $filename);
  110. }
  111. return $query->where('controller' , '=' , $this->controller)
  112. ->where('resource_id' , '=' , $resource_id)
  113. ->execute();
  114. }
  115. ###################################################################################################################################################
  116. ######################################################### ГЛАВНЫЕ ФУНКЦ?? #########################################################################
  117. ###################################################################################################################################################
  118. public function upload($id , $files_type = 'images' , $fieldname = 'userfile')
  119. {
  120. if($this->go_to($id))// проверка доступности либо создание каталога
  121. {
  122. $this->go_out();
  123. if(!count($_FILES))
  124. {
  125. // слишком большой размер файла
  126. return array('Ошибка загрузки файла, возможно слишком большой размер');
  127. }
  128. $post = Validation::factory( $_POST );
  129. $files_validation = Validation::factory($_FILES); // Инициализация
  130. $files_validation->rule( $fieldname , array( 'Upload', 'valid' ) )
  131. ->rule($fieldname, 'Upload::size', array(':value', '3M'));
  132. if(is_array($files_type))
  133. {
  134. $files_validation->rule( $fieldname , array( 'Upload', 'type' ) , array(':value', $files_type) );
  135. }
  136. elseif($files_type == 'images')
  137. {
  138. $files_validation->rule( $fieldname , array( 'Upload', 'type' ) , array(':value', self::get_allowed_types($files_type , 1)) );
  139. }
  140. elseif($files_type != 'all')
  141. {
  142. $files_validation->rule( $fieldname , array( 'Upload', 'type' ) , array(':value', array($files_type)) );
  143. }
  144. $file = &$_FILES[$fieldname];
  145. if ($files_validation->check())
  146. {
  147. $file['name'] = trim($file['name']);
  148. // по умолчанию если файл с таким именем пристутсвует на диске он будет перезаписан
  149. $this->del_from_db($file['name'] , $id); // попытка удаления из БД
  150. $t = array();
  151. preg_match('{\.(\w+)$}is' , $file['name'] , $t);
  152. $file['ext'] = &$t[1];
  153. $crypted_filename = $this->crypt_filename($file['name']);
  154. // физическое сохранение
  155. if (Upload::save($file , $crypted_filename ,$this->files_path.$id, 0777)) // если сохранение удается
  156. {
  157. // сохранение в БД
  158. $insert_array = array(
  159. 'filename' => $file['name'],
  160. 'real_name' => $crypted_filename ,
  161. 'controller' => $this->controller ,
  162. 'resource_id' => $id ,
  163. 'ext' => strtolower($file['ext'])
  164. );
  165. if($this->controller == 'users')$insert_array['default'] = 1;
  166. return DB::insert('files' , array_keys( $insert_array))
  167. ->values(array_values($insert_array))
  168. ->execute();
  169. }
  170. }
  171. return $files_validation->errors('files');
  172. }
  173. }
  174. public function get_default_image($resource_id )
  175. {
  176. // исключение для аватарок которые могут быть запрошены из любого контроллера
  177. $files_dir = $this->files_path.$resource_id."/";
  178. $file = DB::Select()
  179. ->from('files')
  180. ->where('default' , '=' , 1)
  181. ->where('controller' , '=' , $this->controller)
  182. ->where('resource_id' , '=' , $resource_id)
  183. ->where('ext' , 'IN' , $this->get_allowed_types('images' , 1))
  184. ->as_object()
  185. ->limit(1)
  186. ->execute()
  187. ->current();
  188. if(!$file )return false;
  189. if(!file_exists($files_dir.$file->real_name))
  190. {
  191. //$this->del_from_db($file->real_name , $resource_id);
  192. return false;
  193. }
  194. $file = $this->get_options($file);
  195. return $file;
  196. }
  197. private function get_options($file)
  198. {
  199. $files_dir = 'files/'.$file->controller.'/'.$file->resource_id.'/';
  200. $id = &$file->resource_id;
  201. $file->size = filesize($files_dir.$file->real_name);
  202. $bytes[0] = ' байт';
  203. $bytes[1] = ' Кб';
  204. $bytes[2] = ' Мб';
  205. $bytes[3] = ' Гб';
  206. $k = 0;
  207. while ($file->size /1024 > 1)
  208. {
  209. $file->size /= 1024 ;
  210. $k++;
  211. }
  212. $d = ($k > 1) ? 2 : 0;
  213. $file->size = sprintf (" %.".$d."f ".$bytes[$k] , $file->size);
  214. $file->short_path = $files_dir.$file->real_name;
  215. $file->path = URL::site().$file->short_path;
  216. $file->link = '<a href="'.$files_dir.urlencode($file->real_name).'" target="_blank">'.str_replace('_' , ' ' , $file->real_name).'</a>';
  217. if(in_array($file->ext , $this->get_allowed_types('images' , true)))
  218. {
  219. $file->preview = new stdClass();
  220. $file->preview->short_path = $this->get_preview($id , $file->real_name);
  221. $file->preview->path = URL::site().$file->preview->short_path;
  222. $file->preview->link = '<a href="'.$file->preview->path.'" target="_blank">'.str_replace('_' , ' ' , $file->real_name).'</a>';
  223. $file->preview->tag = '<img src="'.$file->preview->path.'"/>';
  224. $file->preview2 = new stdClass();
  225. $file->preview2->short_path = $this->get_preview($id , $file->real_name ,2);
  226. $file->preview2->path = URL::site().$file->preview2->short_path;
  227. $file->preview2->link = '<a href="'.$file->preview2->path.'" target="_blank">'.str_replace('_' , ' ' , $file->real_name).'</a>';
  228. $file->preview2->tag = '<img src="'.$file->preview2->path.'"/>';
  229. }
  230. return $file;
  231. }
  232. function get_files($id , $files_type = 'all' )
  233. {
  234. if(!is_numeric($id)) return array();
  235. $files_dir = $this->files_path.$id.'/';
  236. // разрешенные типы
  237. $allowed_types = $this->get_allowed_types($files_type);
  238. $files = DB::Select()
  239. ->from('files')
  240. ->where('controller' , '=' ,$this->controller)
  241. ->where('resource_id' , '=' , $id)
  242. ->order_by('priority' , "ASC")
  243. ->as_object()->execute()->as_array();
  244. // выборка файлов
  245. foreach($files as $i => $file)
  246. {
  247. if(!file_exists($files_dir.$file->real_name))
  248. {
  249. $this->del_from_db($file->real_name , $id);
  250. unset($files[$i]);
  251. continue;
  252. }
  253. $file = $this->get_options($file);
  254. }
  255. if (count($files) == 0) return array();
  256. return $files;
  257. }
  258. function get_preview($id , $file_name, $number = 1)
  259. {
  260. $file_path = "$this->files_path$id/$file_name";
  261. $preview_path = "$this->files_path$id/preview$number/$file_name";
  262. if(!file_exists($file_path)) return '';
  263. if(file_exists($preview_path)) return $preview_path; // если существует возвращаем путь
  264. if($this->go_to($id))
  265. {
  266. @mkdir("preview$number" , 0777);
  267. $this->go_out();
  268. $settings = new pref;
  269. $width = $settings->get_value($this->controller.'_preview'.$number.'_width');
  270. $height = $settings->get_value($this->controller.'_preview'.$number.'_height');
  271. $this->image = Image::factory($file_path);
  272. if($this->image->width > $width or $this->image->height > $height)
  273. $this->image->resize($width , $height);
  274. $this->image->save($preview_path);
  275. return $preview_path;
  276. }
  277. else return '';
  278. }
  279. public function delete($resorce_id , $filename)
  280. {
  281. // error_reporting(E_ALL ^ E_NOTICE);
  282. if(is_array($resorce_id))
  283. {
  284. foreach($resorce_id as $one_id)
  285. {
  286. $this->delete($one_id , 'all');
  287. }
  288. return true;
  289. }
  290. if(is_array($filename)) // удаление массива файлов
  291. {
  292. foreach($filename as $file)
  293. {
  294. $real_name = $this->crypt_filename($file);
  295. if(file_exists("$this->files_path$resorce_id/$real_name"))
  296. unlink("$this->files_path$resorce_id/$real_name");
  297. if(file_exists("$this->files_path$resorce_id/preview1/$real_name"))
  298. unlink("$this->files_path$resorce_id/preview1/$real_name");
  299. if(file_exists("$this->files_path$resorce_id/preview2/$real_name"))
  300. unlink("$this->files_path$resorce_id/preview2/$real_name");
  301. }
  302. }
  303. elseif($filename == 'all') // удаление всех файлов
  304. {
  305. $previews1 = glob("$this->files_path$resorce_id/preview1/*");
  306. if($previews1) // если != 0
  307. foreach($previews1 as $file)
  308. {
  309. if(file_exists($file))
  310. unlink($file);
  311. }
  312. $previews2 = glob("$this->files_path$resorce_id/preview2/*");
  313. if($previews2) // если != 0
  314. foreach($previews2 as $file)
  315. {
  316. if(file_exists($file))
  317. unlink($file);
  318. }
  319. $files = glob("$this->files_path$resorce_id/*.*");
  320. if($files)
  321. foreach($files as $file)
  322. {
  323. if(file_exists($file))
  324. unlink($file);
  325. }
  326. }
  327. else // один файл
  328. {
  329. $crypted_filename = $this->crypt_filename($filename);
  330. if(file_exists("$this->files_path$resorce_id/$crypted_filename"))
  331. unlink("$this->files_path$resorce_id/$crypted_filename");
  332. if(file_exists("$this->files_path$resorce_id/preview1/$crypted_filename"))
  333. unlink("$this->files_path$resorce_id/preview1/$crypted_filename");
  334. if(file_exists("$this->files_path$resorce_id/preview2/$crypted_filename"))
  335. unlink("$this->files_path$resorce_id/preview2/$crypted_filename");
  336. }
  337. // удаление из БД
  338. $this->del_from_db($filename , $resorce_id);
  339. // если каталог пуст удаляем его
  340. if(glob("$this->files_path$resorce_id/*.*") == false)
  341. {
  342. if(file_exists("$this->files_path$resorce_id/preview1/"))
  343. rmdir("$this->files_path$resorce_id/preview1");
  344. if(file_exists("$this->files_path$resorce_id/preview2/"))
  345. rmdir("$this->files_path$resorce_id/preview2");
  346. if(file_exists($this->files_path.$resorce_id))
  347. rmdir($this->files_path.$resorce_id);
  348. }
  349. return true;
  350. }
  351. public function copy($controller , $resource_from_id , $resource_to_id)
  352. {
  353. $files_dir = $this->files_path.$resource_from_id.'/';
  354. $files = DB::Select()
  355. ->from('files')
  356. ->where('controller' , '=' , $controller)
  357. ->where('resource_id' , '=' , $resource_from_id)
  358. ->execute()
  359. ->as_array();
  360. foreach($files as $i => $file)
  361. {
  362. if(!file_exists($files_dir.$file['real_name']))
  363. {
  364. $this->del_from_db($file['real_name'] , $resource_from_id);
  365. unset($files[$i]);
  366. continue;
  367. }
  368. if($this->go_to($resource_to_id))
  369. {
  370. $this->go_out();
  371. if(!@copy($this->files_path.$resource_from_id.'/'.$file['real_name'] , $this->files_path.$resource_to_id.'/'.$file['real_name']))
  372. {
  373. return false;
  374. }
  375. unset($file['id']);
  376. $file['resource_id'] = $resource_to_id;
  377. $result = DB::insert('files' , array_keys($file))
  378. ->values(array_values($file))
  379. ->execute();
  380. }
  381. }
  382. }
  383. public function sort($resource_id, $id_array)
  384. {
  385. foreach ($id_array as $i => $id)
  386. {
  387. DB::update('files')
  388. ->set(array('priority' => $i + 1))
  389. ->where('id' , '=' , (int)$id)
  390. ->where('resource_id' , '=' , (int)$resource_id)
  391. ->execute();
  392. }
  393. }
  394. // Функция принимает начальные значения $id , $data, $value
  395. // Если $id - массив то функция обновит все $id в указанном массиве
  396. // Если число тогда только 1 элемент
  397. // $data может быть как массивом ключей+значений,
  398. // так и ключом со значеним указанным в третьим параметре $value
  399. public function property_change($id ,$data , $value = null)
  400. {
  401. $query = DB::update('files');
  402. if(is_array($data))
  403. {
  404. $query->set($data);
  405. }
  406. else
  407. {
  408. $query->set(array($data => $value));
  409. }
  410. if(is_array($id))
  411. {
  412. $query->where('id' , 'IN' , $id);
  413. }
  414. else
  415. {
  416. $query->where('id' , '=' , $id);
  417. }
  418. $query->execute();
  419. return true;
  420. }
  421. }
  422. ?>