Вход Регистрация
Файл: protected/extensions/SImageUploadBehavior/SImageUploadBehavior.php
Строк: 88
<?php

class SImageUploadBehavior extends CActiveRecordBehavior {
    
    public 
$fileAttribute;
    public 
$nameAttribute;
    public 
$folder 'public';
    
    public 
$imagesRequired;
    
    public function 
beforeSave($event) {
                
        if(!
$this->fileAttribute){
            throw new 
CHttpException(500,'"fileAttribute" должен быть установлен!');
        }
        if(!
$this->imagesRequired){
            throw new 
CHttpException(500,'"imagesRequired" должен(ны)быть установлен!');
        }
        
        
        
$model $this->getOwner();
        
$file CUploadedFile::getInstance($model$this->fileAttribute);
        
$fileAttribute $this->fileAttribute;
        
        
//Если файл не был загружен, поле с файлом обновлять не нужно.
        
if(is_null($file)){
            unset(
$model->image);
            return;
        }elseif(!
$model->isNewRecord && !empty($model->$fileAttribute)){
            
$this->deleteImages();
        }
        
        
//Имя будущего изображения
        
if($this->nameAttribute){
            
//Дата наслучай, если такое имя уже есть
            
$fileName =    $this->safeFileName($model->name).'.'.$file->getExtensionName();
        }else{
            
$fileName date('dMY_H-i-s').$this->safeFileName($file->getName()).'.'.$file->getExtensionName();
        }
        
        
        
$model->$fileAttribute $fileName;
        
        
Yii::import('ext.helpers.CArray');
        
Yii::import('ext.image.Image');
        
        if(!
is_array(reset($this->imagesRequired))){
            
$this->imagesRequired['fileName'] = $fileName;
            
$this->manipulate($file$this->imagesRequired);
        }
        else{
            foreach(
$this->imagesRequired as $imageRequired){
                
$imageRequired['fileName'] = $fileName;
                
$this->manipulate($file$imageRequired);
            }
        }
        
    }
    
//Абсолютный путь к изображеию
    
private static function getAbsolutePath($folder$fileName null){
        return
        
Yii::app()->basePath.'/../'.    //Путь к корню приложения
        
$folder.'/'.    //Папка из конфигурации
        
$fileName;
    }
    
    
//Получение ссылки на изображение
    
public function getImageUrl($image null){
        
$model $this->getOwner();
        if(!
is_array(reset($this->imagesRequired))){
            
$folder $this->imagesRequired['folder'];    
        }else{
            
$folder $this->imagesRequired[$image]['folder'];
        }
        
$fileAttribute $this->fileAttribute;
        return 
Yii::app()->baseUrl.'/'.$folder.'/'.$model->$fileAttribute;
    }
        
    
    
//Удаление всех копий файла для текущей модели
    
public function deleteImages(){
        
$fileAttribute $this->fileAttribute;
        
$model $this->getOwner();
        
        if(!
is_array(reset($this->imagesRequired))){
            
$imagePath self::getAbsolutePath($this->imagesRequired['folder'], $model->$fileAttribute);
            if(
file_exists($imagePath)) unlink($imagePath);
        }
        else{
            foreach(
$this->imagesRequired as $imageRequired){
                
$imagePath self::getAbsolutePath($imageRequired['folder'], $model->$fileAttribute);
                echo 
$imagePath;
                if(
file_exists($imagePath)) unlink($imagePath);                
            }
        }    
    }
    
    
//Создание изображения на основе параметров
    
private function manipulate($file$options){
        
//Первым делом валидация
        
$this->validateOptions($options);
        
        
$targetFolder $options['folder'];
        
$fileName $options['fileName'];

        
//Путь будущего изображения
        
$path self::getAbsolutePath($targetFolder ,$fileName);
        
        
//Если изменять размеры не нужно - просто сделаем копию изображения
        
if(isset($options['resize'])){
            if(
$options['resize'] === false){
                
copy($file->getTempName(), $path);
                return;
            }
        }
        
        
//Ширина и высота требуемого изображения
        
$targetWidth $options['width'];
        
$targetHeight $options['height'];
        
//Ширина и высота загруженного изображения
        
list($uploadedWidth$uploadedHeight) = getimagesize($file->getTempName());
        
        
//Если изменять размеры не нужно - просто сделаем копию изображения
        
if(isset($options['smartResize'])){
            if(
$options['smartResize'] === false){
                
//Если требуемое изображение больше загруженного, его не нужно изменять
                
if($targetWidth>$uploadedWidth && $targetHeight>$uploadedHeight){
                    
copy($file->getTempName(), $path);
                }
                else{
                    
//Изображение для манипуляции берется из временной папки
                    
$image = new Image($file->getTempName());
                    
//Манипуляция
                    
$image->resize($targetWidth$targetHeightImage::AUTO)->sharpen(1)->quality(95)->save($path);
                }
                return;
            }
        }

        
//Отношение сторон загруженного и требуемого изображения
        
$uploadedRatio $uploadedWidth/$uploadedHeight;
        
$targetRatio $targetWidth/$targetHeight;

        
//Сравниваем отношения и считаем координаты для кадрирования(если нарисовать на бумаге алгоритм становится очевидным :))
        
if($uploadedRatio>$targetRatio){
            
$cropHeight    $uploadedHeight;
            
$cropWidth    $uploadedHeight*$targetRatio;
            
$cropLeft    = ($uploadedWidth $uploadedHeight*$targetRatio)*0.5;
            
$cropTop    0;
        }
        else{
            
$cropHeight    $uploadedWidth/$targetRatio;
            
$cropWidth    $uploadedWidth;
            
$cropLeft    0;
            
$cropTop    = ($uploadedHeight $uploadedWidth/$targetRatio)*0.2;
        }
        
//Изображение для манипуляции берется из временной папки
        
$image = new Image($file->getTempName());
        
//Манипуляция
        
$image->crop($cropWidth$cropHeight$cropTop$cropLeft)
                ->
resize($targetWidth$targetHeightImage::NONE)
                ->
sharpen(1)->quality(95)->save($path);


    }
    
    public function 
beforeDelete($event)
  {
        
$this->deleteImages();
    }
    
    
//Валидация опций создаваемого изображения
    
private function validateOptions($options){
        if(!
is_array($options))
            throw new 
CHttpException(500,'Конфигурацией изображения должен быть массив');
        if(!isset(
$options['folder']))
            throw new 
CHttpException(500,'Папка для загрузки не установлена');
        if(isset(
$options['resize']) && $options['resize']===false) return;
        if(!isset(
$options['width']) || !isset($options['height']))
            throw new 
CHttpException(500,'Параметры изображений установлены неправильно');
    }

    
//У файлов должны быть безопасные имена
    
private function safeFileName($string) {
        
$converter = array(
            
'а' => 'a',   'б' => 'b',   'в' => 'v',
            
'г' => 'g',   'д' => 'd',   'е' => 'e',
            
'ё' => 'e',   'ж' => 'zh',  'з' => 'z',
            
'и' => 'i',   'й' => 'y',   'к' => 'k',
            
'л' => 'l',   'м' => 'm',   'н' => 'n',
            
'о' => 'o',   'п' => 'p',   'р' => 'r',
            
'с' => 's',   'т' => 't',   'у' => 'u',
            
'ф' => 'f',   'х' => 'h',   'ц' => 'c',
            
'ч' => 'ch',  'ш' => 'sh',  'щ' => 'sch',
            
'ь' => ''',  'ы' => 'y',   'ъ' => ''',
            
'э' => 'e',   'ю' => 'yu',  'я' => 'ya',

            
'А' => 'A',   'Б' => 'B',   'В' => 'V',
            
'Г' => 'G',   'Д' => 'D',   'Е' => 'E',
            
'Ё' => 'E',   'Ж' => 'Zh',  'З' => 'Z',
            
'И' => 'I',   'Й' => 'Y',   'К' => 'K',
            
'Л' => 'L',   'М' => 'M',   'Н' => 'N',
            
'О' => 'O',   'П' => 'P',   'Р' => 'R',
            
'С' => 'S',   'Т' => 'T',   'У' => 'U',
            
'Ф' => 'F',   'Х' => 'H',   'Ц' => 'C',
            
'Ч' => 'Ch',  'Ш' => 'Sh',  'Щ' => 'Sch',
            
'Ь' => ''',  'Ы' => 'Y',   'Ъ' => ''',
            
'Э' => 'E',   'Ю' => 'Yu',  'Я' => 'Ya',
        );
        
$str strtr($string$converter);
        
$str strtolower($str);
        
$str preg_replace('~[^-a-z0-9_]+~u''_'$str);
        
$str trim($str"-");

        return 
$str;
    }


}
Онлайн: 1
Реклама