Проблема с behaviors

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Закрыто
AJleksey
Сообщения: 3
Зарегистрирован: 2014.09.19, 17:11

Проблема с behaviors

Сообщение AJleksey »

Есть модель:

Код: Выделить всё

class CatalogModels extends CActiveRecord
{
        public $ImageFile = null;

    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    public function tableName()
    {
        return 'catalog_models';
    }

    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('name, model_category_id, catalog_models_type_id', 'required'),
            array('catalog_models_type_id, model_category_id, catalog_models_type_id', 'numerical', 'integerOnly'=>true),
            array('name', 'length', 'max'=>255),
            array('created, modified, deleted', 'safe'),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('image_path', 'length', 'max' => 255, 'tooLong' => '{attribute} is too long (max {max} chars).', 'on' => 'upload'),
            array('image_path', 'file', 'types' => 'jpg,jpeg,gif,png', 'maxSize' => 1024 * 1024 * 2, 'tooLarge' => 'Size should be less then 2MB !!!', 'on' => 'upload'),
            array('id, name, model_category_id, created, modified, deleted, catalog_models_type_id, image_path', 'safe', 'on'=>'search'),
        );
    }

        public function behaviors() {
            return array(
                'ImageBehavior' => array(
                    'class' => 'ImageBehavior',
                    'imagePath' => 'catalog-models/'.$this->id.'/',
                    'imageField' => 'image_path',
                    'thumb' => true
                )
            );
        }    

....

    public function beforeSave() {

            if(($this->scenario=='insert' || $this->scenario=='update') && ($this->ImageFile = CUploadedFile::getInstance($this,'image_path'))) {
                $this->deleteDocument();
                $this->image_path = md5(rand()+time()).'.'.$this->ImageFile->getExtensionName();
            }
        
            return parent::beforeSave();
    }

    public function afterSave() {
        if (!file_exists($_SERVER['DOCUMENT_ROOT'].'/images/catalog-models/'.$this->id)) {
            mkdir($_SERVER['DOCUMENT_ROOT'].'/images/catalog-models/'.$this->id, 0755);
        }
        if (!file_exists($_SERVER['DOCUMENT_ROOT'].'/images/catalog-models/'.$this->id.'/full')) {
            mkdir($_SERVER['DOCUMENT_ROOT'].'/images/catalog-models/'.$this->id.'/full', 0755);
        }
        if (!file_exists($_SERVER['DOCUMENT_ROOT'].'/images/catalog-models/'.$this->id.'/thumb')) {
            mkdir($_SERVER['DOCUMENT_ROOT'].'/images/catalog-models/'.$this->id.'/thumb', 0755);
        }
        if(($this->scenario=='insert' || $this->scenario=='update') && ($this->ImageFile)) {
            $this->ImageFile->saveAs($this->ImageBehavior->getBaseImageUploadPath(). 'full/' .$this->image_path);
        }        
        return parent::afterSave();
    }

    public function deleteDocument(){
        $documentPath=$this->ImageBehavior->getBaseImageUploadPath(). '/full/' .$this->image_path;
        if(is_file($documentPath))
            unlink($documentPath);
        $documentPath=$this->ImageBehavior->getBaseImageUploadPath(). '/thumb/' .$this->image_path;
        if(is_file($documentPath))
            unlink($documentPath);
    }    
    

}

 

Вывод формы чуть ли не стандартный.

Из всей формы только вот это интересно

Код: Выделить всё

<?php
    $form=$this->beginWidget('booster.widgets.TbActiveForm',array(
        'id'=>'catalog-models-form',
        'enableAjaxValidation'=>false,
        'htmlOptions' => array('class' => 'well', 'enctype' => 'multipart/form-data'),
    ));
?>
....
    <?php if($model->image_path): ?>
        <p><?php echo CHtml::encode($model->image_path); ?></p>
    <?php endif; ?>
    
    <?php
        if($model->image_path){
            echo CHtml::image($model->ImageBehavior->getImageUrl(), '', array('class'=>'img-thumbnail'));
            echo CHtml::image($model->ImageBehavior->getImageThumbUrl(), '', array('class'=>'img-thumbnail'));
        }
        echo $form->fileFieldGroup($model, 'image_path',
                        array(
                            'wrapperHtmlOptions' => array(
                                'class' => 'col-sm-5',
                                ),
                            )
        );
    ?>
....

Суть Проблемы.
Перед сохранение записи в $ImageFile сохраняется изображение, с этим всё хорошо, запись сохранилась дальше начинается afterSave()
Категории он создаёт, всё хорошо.

Дальше идёт попытка сохранения файла по пути полученного из поведения

Код: Выделить всё

$this->ImageFile->saveAs($this->ImageBehavior->getBaseImageUploadPath(). 'full/' .$this->image_path);
 
и я получаю

Код: Выделить всё

move_uploaded_file(D:/OpenServer/domains/yiibooser-local/images/catalog-models//full/image_name.jpg): failed to open stream: No such file or directory 
 
Сайм путь передаётся в поведение

Код: Выделить всё

'imagePath' => 'catalog-models/'.$this->id.'/',
 
И теряет он $this->id

Вопрос. Почему, и как это вылечить.
HQ0
Сообщения: 182
Зарегистрирован: 2012.10.17, 17:21

Re: Проблема с behaviors

Сообщение HQ0 »

Файл не перемещается -- скорее всего нет папки такой.

ИД теряется, потому что и нет никакого id на момент когда срабатывает метод. В самом поведении ставь/заменяй/подменяй.
Аватара пользователя
iAchilles
Сообщения: 41
Зарегистрирован: 2014.09.11, 19:44

Re: Проблема с behaviors

Сообщение iAchilles »

Вы передаете $this->id, как часть, которая участвует в формировании пути к изображению. Когда вы создаете экземпляр класса с помощью оператора new метод CActiveRecord::attachBehaviors() вызывается в методе конструкторе класса, и на этот момент путь который указан в качестве параметра для поведения НЕ МОЖЕТ содержать значение id, поскольку его на этот момент и НЕ СУЩЕСТВУЕТ.
AJleksey
Сообщения: 3
Зарегистрирован: 2014.09.19, 17:11

Re: Проблема с behaviors

Сообщение AJleksey »

iAchilles писал(а):Вы передаете $this->id, как часть, которая участвует в формировании пути к изображению. Когда вы создаете экземпляр класса с помощью оператора new метод CActiveRecord::attachBehaviors() вызывается в методе конструкторе класса, и на этот момент путь который указан в качестве параметра для поведения НЕ МОЖЕТ содержать значение id, поскольку его на этот момент и НЕ СУЩЕСТВУЕТ.
А можно как то обновить значения поведения в afterShave()?
Аватара пользователя
iAchilles
Сообщения: 41
Зарегистрирован: 2014.09.11, 19:44

Re: Проблема с behaviors

Сообщение iAchilles »

AJleksey писал(а): А можно как то обновить значения поведения в afterShave()?
Да:

Код: Выделить всё

protected function afterSave()
{
      $ds = DIRECTORY_SEPARATOR;
      $this->ImageBehavior->imagePath = 'catalog-models' . $ds . $this->id . $ds;
      parent::afterSave()
}
AJleksey
Сообщения: 3
Зарегистрирован: 2014.09.19, 17:11

Re: Проблема с behaviors

Сообщение AJleksey »

iAchilles писал(а):
AJleksey писал(а): А можно как то обновить значения поведения в afterShave()?
Да:

Код: Выделить всё

protected function afterSave()
{
      $ds = DIRECTORY_SEPARATOR;
      $this->ImageBehavior->imagePath = 'catalog-models' . $ds . $this->id . $ds;
      parent::afterSave()
} 
Спасибо!
Закрыто