/application/classes/core/model/file.php
PHP | 485 lines | 289 code | 51 blank | 145 comment | 47 complexity | 9866f5693626b81e5db37feec5be46be MD5 | raw file
Possible License(s): BSD-3-Clause
- <?php defined('SYSPATH') or die('No direct script access.');
- class Core_Model_File extends Model
- {
- private $files_path = '';
- private $controller = '';
- ###################################################################################################################################################
- ################################################## ОБЩИЙ ПЕРЕХОД ПО ПАПКАМ ########################################################################
- ###################################################################################################################################################
- function __construct($controller = null)
- {
-
- $this->controller = ($controller == null)? Request::current()->controller(): $controller;
- $this->files_path = "files/$this->controller/";
- }
- private function go_to($id)
- {
- if(!file_exists('files'))
- mkdir('files' , 0777); // пытаемся содать папку files если ее нет
-
- if(!chdir('files')) return false;
- if(!file_exists($this->controller))
- mkdir($this->controller, 0777); // пытаемся содать папку с названием контроллера
-
- if(!chdir($this->controller)) return false;
- if(!file_exists($id))
- mkdir($id , 0777);
- if(!chdir($id)) return false;
-
- return true;
- }
-
- private function go_out()
- {
- if (!chdir('../../../')) return false;
- return true;
- }
-
- private function crypt_filename($filename)
- {
- $temp_array = explode('.', $filename);
- $count = count($temp_array);
-
- if($count > 1)
- {
- return sha1($filename.$filename).'.'.$temp_array[$count - 1];
- }
- if($count == 1) // без расширения
- {
- return sha1($filename.$filename);
- }
-
- }
-
- public function get_allowed_types($files_type, $as_array = false)
- {
- if(!is_array($files_type))
- {
- switch($files_type)
- {
- case 'images':
- {
- $files_type_array = array( 'jpg','jpeg', 'png','bmp', 'gif');
- break;
- }
- case 'docs':
- {
- $files_type_array = array( 'doc','docx', 'xml','xsl', 'ppt');
- break;
- }
- default: // all
- {
- if ($as_array)return array();
- else return "*";
- }
- }
- }
- else
- {
- $files_type_array = $files_type;
- }
- $case_up_array = array();
- foreach($files_type_array as $item)
- {
- $case_up_array[] = strtoupper($item);
- }
- $allowed_types = array_merge($files_type_array , $case_up_array);
-
- if ($as_array)
- return $allowed_types;
- else return implode(',' , $allowed_types);
- }
-
- private function file_query($filename , $resource_id)
- {
- return DB::Select()
- ->from('files')
- ->where('filename' , '=' , $filename)
- ->where('controller' , '=' , $this->controller)
- ->where('resource_id' , '=' , $resource_id)
- ->as_object();
- }
-
-
- public function get_from_db($filename , $resource_id)
- {
- $query = $this->file_query($filename , $resource_id);
- return $query->execute()->current();
- }
-
- public function del_from_db($filename , $resource_id)
- {
-
- $query = DB::Delete('files');
-
- if(is_array($filename)) // удаление массива файлов
- {
- $query->where('filename' , 'IN' , $filename);
- }
- elseif($filename == 'all') // удаление всех файлов
- {
- // просто ниче не пишим :)
- }
- else // один файл
- {
- $query->where('filename' , '=' , $filename);
- }
- return $query->where('controller' , '=' , $this->controller)
- ->where('resource_id' , '=' , $resource_id)
- ->execute();
- }
-
- ###################################################################################################################################################
- ######################################################### ГЛАВНЫЕ ФУНКЦ�?�? #########################################################################
- ###################################################################################################################################################
- public function upload($id , $files_type = 'images' , $fieldname = 'userfile')
- {
- if($this->go_to($id))// проверка доступности либо создание каталога
- {
- $this->go_out();
- if(!count($_FILES))
- {
- // слишком большой размер файла
- return array('Ошибка загрузки файла, возможно слишком большой размер');
- }
- $post = Validation::factory( $_POST );
- $files_validation = Validation::factory($_FILES); // Инициализация
-
-
- $files_validation->rule( $fieldname , array( 'Upload', 'valid' ) )
- ->rule($fieldname, 'Upload::size', array(':value', '3M'));
- if(is_array($files_type))
- {
- $files_validation->rule( $fieldname , array( 'Upload', 'type' ) , array(':value', $files_type) );
- }
- elseif($files_type == 'images')
- {
- $files_validation->rule( $fieldname , array( 'Upload', 'type' ) , array(':value', self::get_allowed_types($files_type , 1)) );
- }
- elseif($files_type != 'all')
- {
- $files_validation->rule( $fieldname , array( 'Upload', 'type' ) , array(':value', array($files_type)) );
- }
- $file = &$_FILES[$fieldname];
- if ($files_validation->check())
- {
- $file['name'] = trim($file['name']);
- // по умолчанию если файл с таким именем пристутсвует на диске он будет перезаписан
- $this->del_from_db($file['name'] , $id); // попытка удаления из БД
- $t = array();
- preg_match('{\.(\w+)$}is' , $file['name'] , $t);
- $file['ext'] = &$t[1];
- $crypted_filename = $this->crypt_filename($file['name']);
- // физическое сохранение
- if (Upload::save($file , $crypted_filename ,$this->files_path.$id, 0777)) // если сохранение удается
- {
-
- // сохранение в БД
- $insert_array = array(
- 'filename' => $file['name'],
- 'real_name' => $crypted_filename ,
- 'controller' => $this->controller ,
- 'resource_id' => $id ,
- 'ext' => strtolower($file['ext'])
- );
- if($this->controller == 'users')$insert_array['default'] = 1;
- return DB::insert('files' , array_keys( $insert_array))
- ->values(array_values($insert_array))
- ->execute();
- }
- }
- return $files_validation->errors('files');
-
- }
- }
-
- public function get_default_image($resource_id )
- {
- // исключение для аватарок которые могут быть запрошены из любого контроллера
-
- $files_dir = $this->files_path.$resource_id."/";
- $file = DB::Select()
- ->from('files')
- ->where('default' , '=' , 1)
- ->where('controller' , '=' , $this->controller)
- ->where('resource_id' , '=' , $resource_id)
- ->where('ext' , 'IN' , $this->get_allowed_types('images' , 1))
- ->as_object()
- ->limit(1)
- ->execute()
- ->current();
-
- if(!$file )return false;
- if(!file_exists($files_dir.$file->real_name))
- {
- //$this->del_from_db($file->real_name , $resource_id);
- return false;
- }
- $file = $this->get_options($file);
-
- return $file;
- }
-
-
- private function get_options($file)
- {
-
- $files_dir = 'files/'.$file->controller.'/'.$file->resource_id.'/';
- $id = &$file->resource_id;
- $file->size = filesize($files_dir.$file->real_name);
- $bytes[0] = ' байт';
- $bytes[1] = ' Кб';
- $bytes[2] = ' Мб';
- $bytes[3] = ' Гб';
- $k = 0;
- while ($file->size /1024 > 1)
- {
- $file->size /= 1024 ;
- $k++;
- }
- $d = ($k > 1) ? 2 : 0;
- $file->size = sprintf (" %.".$d."f ".$bytes[$k] , $file->size);
-
- $file->short_path = $files_dir.$file->real_name;
- $file->path = URL::site().$file->short_path;
- $file->link = '<a href="'.$files_dir.urlencode($file->real_name).'" target="_blank">'.str_replace('_' , ' ' , $file->real_name).'</a>';
-
- if(in_array($file->ext , $this->get_allowed_types('images' , true)))
- {
- $file->preview = new stdClass();
-
- $file->preview->short_path = $this->get_preview($id , $file->real_name);
- $file->preview->path = URL::site().$file->preview->short_path;
- $file->preview->link = '<a href="'.$file->preview->path.'" target="_blank">'.str_replace('_' , ' ' , $file->real_name).'</a>';
- $file->preview->tag = '<img src="'.$file->preview->path.'"/>';
- $file->preview2 = new stdClass();
- $file->preview2->short_path = $this->get_preview($id , $file->real_name ,2);
- $file->preview2->path = URL::site().$file->preview2->short_path;
- $file->preview2->link = '<a href="'.$file->preview2->path.'" target="_blank">'.str_replace('_' , ' ' , $file->real_name).'</a>';
- $file->preview2->tag = '<img src="'.$file->preview2->path.'"/>';
- }
- return $file;
- }
- function get_files($id , $files_type = 'all' )
- {
- if(!is_numeric($id)) return array();
-
- $files_dir = $this->files_path.$id.'/';
- // разрешенные типы
-
- $allowed_types = $this->get_allowed_types($files_type);
- $files = DB::Select()
- ->from('files')
- ->where('controller' , '=' ,$this->controller)
- ->where('resource_id' , '=' , $id)
- ->order_by('priority' , "ASC")
- ->as_object()->execute()->as_array();
- // выборка файлов
-
-
- foreach($files as $i => $file)
- {
- if(!file_exists($files_dir.$file->real_name))
- {
- $this->del_from_db($file->real_name , $id);
- unset($files[$i]);
- continue;
- }
- $file = $this->get_options($file);
- }
- if (count($files) == 0) return array();
- return $files;
- }
-
- function get_preview($id , $file_name, $number = 1)
- {
- $file_path = "$this->files_path$id/$file_name";
- $preview_path = "$this->files_path$id/preview$number/$file_name";
-
- if(!file_exists($file_path)) return '';
- if(file_exists($preview_path)) return $preview_path; // если существует возвращаем путь
- if($this->go_to($id))
- {
- @mkdir("preview$number" , 0777);
- $this->go_out();
- $settings = new pref;
- $width = $settings->get_value($this->controller.'_preview'.$number.'_width');
- $height = $settings->get_value($this->controller.'_preview'.$number.'_height');
-
-
- $this->image = Image::factory($file_path);
- if($this->image->width > $width or $this->image->height > $height)
- $this->image->resize($width , $height);
- $this->image->save($preview_path);
- return $preview_path;
- }
- else return '';
- }
-
-
- public function delete($resorce_id , $filename)
- {
- // error_reporting(E_ALL ^ E_NOTICE);
- if(is_array($resorce_id))
- {
- foreach($resorce_id as $one_id)
- {
- $this->delete($one_id , 'all');
- }
- return true;
- }
- if(is_array($filename)) // удаление массива файлов
- {
- foreach($filename as $file)
- {
- $real_name = $this->crypt_filename($file);
- if(file_exists("$this->files_path$resorce_id/$real_name"))
- unlink("$this->files_path$resorce_id/$real_name");
- if(file_exists("$this->files_path$resorce_id/preview1/$real_name"))
- unlink("$this->files_path$resorce_id/preview1/$real_name");
- if(file_exists("$this->files_path$resorce_id/preview2/$real_name"))
- unlink("$this->files_path$resorce_id/preview2/$real_name");
- }
- }
- elseif($filename == 'all') // удаление всех файлов
- {
- $previews1 = glob("$this->files_path$resorce_id/preview1/*");
- if($previews1) // если != 0
- foreach($previews1 as $file)
- {
- if(file_exists($file))
- unlink($file);
- }
-
- $previews2 = glob("$this->files_path$resorce_id/preview2/*");
- if($previews2) // если != 0
- foreach($previews2 as $file)
- {
- if(file_exists($file))
- unlink($file);
- }
- $files = glob("$this->files_path$resorce_id/*.*");
- if($files)
- foreach($files as $file)
- {
- if(file_exists($file))
- unlink($file);
- }
- }
- else // один файл
- {
- $crypted_filename = $this->crypt_filename($filename);
- if(file_exists("$this->files_path$resorce_id/$crypted_filename"))
- unlink("$this->files_path$resorce_id/$crypted_filename");
- if(file_exists("$this->files_path$resorce_id/preview1/$crypted_filename"))
- unlink("$this->files_path$resorce_id/preview1/$crypted_filename");
- if(file_exists("$this->files_path$resorce_id/preview2/$crypted_filename"))
- unlink("$this->files_path$resorce_id/preview2/$crypted_filename");
- }
- // удаление из БД
- $this->del_from_db($filename , $resorce_id);
-
- // если каталог пуст удаляем его
- if(glob("$this->files_path$resorce_id/*.*") == false)
- {
- if(file_exists("$this->files_path$resorce_id/preview1/"))
- rmdir("$this->files_path$resorce_id/preview1");
- if(file_exists("$this->files_path$resorce_id/preview2/"))
- rmdir("$this->files_path$resorce_id/preview2");
- if(file_exists($this->files_path.$resorce_id))
- rmdir($this->files_path.$resorce_id);
- }
- return true;
- }
-
-
-
- public function copy($controller , $resource_from_id , $resource_to_id)
- {
- $files_dir = $this->files_path.$resource_from_id.'/';
- $files = DB::Select()
- ->from('files')
- ->where('controller' , '=' , $controller)
- ->where('resource_id' , '=' , $resource_from_id)
- ->execute()
- ->as_array();
- foreach($files as $i => $file)
- {
- if(!file_exists($files_dir.$file['real_name']))
- {
- $this->del_from_db($file['real_name'] , $resource_from_id);
- unset($files[$i]);
- continue;
- }
- if($this->go_to($resource_to_id))
- {
- $this->go_out();
- if(!@copy($this->files_path.$resource_from_id.'/'.$file['real_name'] , $this->files_path.$resource_to_id.'/'.$file['real_name']))
- {
- return false;
- }
- unset($file['id']);
- $file['resource_id'] = $resource_to_id;
- $result = DB::insert('files' , array_keys($file))
- ->values(array_values($file))
- ->execute();
- }
- }
- }
-
- public function sort($resource_id, $id_array)
- {
- foreach ($id_array as $i => $id)
- {
- DB::update('files')
- ->set(array('priority' => $i + 1))
- ->where('id' , '=' , (int)$id)
- ->where('resource_id' , '=' , (int)$resource_id)
- ->execute();
- }
- }
-
- // Функция принимает начальные значения $id , $data, $value
- // Если $id - массив то функция обновит все $id в указанном массиве
- // Если число тогда только 1 элемент
- // $data может быть как массивом ключей+значений,
- // так и ключом со значеним указанным в третьим параметре $value
- public function property_change($id ,$data , $value = null)
- {
- $query = DB::update('files');
- if(is_array($data))
- {
- $query->set($data);
- }
- else
- {
- $query->set(array($data => $value));
- }
- if(is_array($id))
- {
- $query->where('id' , 'IN' , $id);
- }
- else
- {
- $query->where('id' , '=' , $id);
- }
- $query->execute();
- return true;
- }
-
- }
- ?>