Setting read-only property

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

Setting read-only property

Сообщение abutan »

Здравствуйте всем.
Возникла такая проблема, что не могу даже понять что от меня надо то.
Вот одна модель

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

namespace app\fond\entities;


use yii\db\ActiveRecord;
use yii\web\UploadedFile;
use yiidreamteam\upload\ImageUploadBehavior;

/**
 * @property \yii\web\UploadedFile file
 * @property int $id [int(11)]
 * @property int $slider_id [int(11)]
 * @property int $sort [int(11)]
 */
class Slide extends ActiveRecord
{
    public static function create(UploadedFile $file): self
    {
        $slide = new static();
        $slide->file = $file;

        return $slide;
    }

    public function setSort($sort)
    {
        $this->sort = $sort;
    }

    public function isEqualTo($id)
    {
        return $this->id == $id;
    }

    public function attributeLabels() {
        return [
            'file' => 'Слайды',
        ];
    }

    public static function tableName() {
        return '{{%slider_photo}}';
    }

    public function behaviors() {
        return [
            [
                'class' => ImageUploadBehavior::className(),
                'attribute' => 'file',
                'createThumbsOnRequest' => TRUE,
                'filePath' => '@webroot/files/slider/origin/[[attribute_slider_id]]/[[id]].[[extension]]',
                'fileUrl' => '@web/files/slider/origin/[[attribute_slider_id]]/[[id]].[[extension]]',
                'thumbPath' => '@webroot/files/slider/cache/[[attribute_slider_id]]/[[profile]]/[[id]].[[extension]]',
                'thumbUrl' => '@web/files/slider/cache/[[attribute_slider_id]]/[[profile]]/[[id]].[[extension]]',
                'thumbs' => [
                    'admin' => ['width' => 330, 'height' => 100],
                ],
            ],
        ];
    }
}
Вот вторая модель

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

<?php

namespace app\fond\entities;


use lhs\Yii2SaveRelationsBehavior\SaveRelationsBehavior;
use yii\db\ActiveRecord;
use yii\web\UploadedFile;

/**
 * @property string $name [varchar(255)]
 * @property int $id [int(11)]
 * @property Slide[] $images
 */
class Slider extends ActiveRecord
{
    public static function create($name): self
    {
        $slider = new static();
        $slider->name = $name;

        return $slider;
    }

    public function edit($name)
    {
        $this->name = $name;
    }

    public function attributeLabels() {
        return [
            'name' => 'Название слайдера',
        ];
    }

    public static function tableName() {
        return '{{%slider}}';
    }

    ##################

    public function addSlide(UploadedFile $file)
    {
        $slides = $this->images;
        $slides[] = Slide::create($file);
        $this->updateSlides($slides);
    }

    public function removeSlide($id)
    {
        $slides = $this->images;
        foreach ($slides as $i => $slide){
            if ($slide->isEqualTo($id)){
                unset($slides[$i]);
                $this->updateSlides($slides);
                return;
            }
        }
        throw new \DomainException('Слайд не найден');
    }

    public function removeSlides()
    {
        $this->update([]);
    }

    public function moveSlideUp($id)
    {
        $slides = $this->images;
        foreach ($slides as $i => $slide){
            if ($slide->isEqualTo($id)){
                if ($prev = $slides[$i - 1] ?? NULL){
                    $slides[$i - 1] = $slide;
                    $slides[$i] = $prev;
                    $this->updateSlides($slides);
                }
                return;
            }
        }
        throw new \DomainException('Слайд не найден');
    }

    public function moveSlideDown($id)
    {
        $slides = $this->images;
        foreach ($slides as $i => $slide){
            if ($slide->isEqualTo($id)){
                if ($next = $slides[$i + 1] ?? NULL){
                    $slides[$i + 1] = $slide;
                    $slides[$i] = $next;
                    $this->updateSlides($slides);
                }
                return;
            }
        }
        throw new \DomainException('Слайд не найден');
    }

    private function updateSlides(array $slides)
    {
        foreach ($slides as $i => $slide){
            $slide->setSort($i);
        }
        $this->images = $slides;
    }

    ##################

    public function getImages()
    {
        $this->hasMany(Slide::className(), ['slider_id' => 'id'])->orderBy('sort');
    }

    public function behaviors()
    {
        return [
            [
                'class' => SaveRelationsBehavior::className(),
                'relations' => [
                    'images',
                ],
            ],
        ];
    }

    public function transactions()
    {
        return [
            self::SCENARIO_DEFAULT => self::OP_ALL,
        ];
    }

    public function beforeDelete()
    {
        if (parent::beforeDelete()) {
            foreach ($this->images as $slide){
                $slide->delete();
            }
            return TRUE;
        }
        return FALSE;
    }
}
Они связаны между собой через один ко многим getImages().
Ну там дальше формы создаю, вывожу в админку и в итоге получаю
Invalid Call – yii\base\InvalidCallException
Setting read-only property: app\fond\entities\Slider::images

1. in /var/www/euro.dev/vendor/yiisoft/yii2/base/Component.php at line 198
189190191192193194195196197198199200201202203204205206207

$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name)) {
$behavior->$name = $value;
return;
}
}

if (method_exists($this, 'get' . $name)) {
throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
}

throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
}

/**
* Checks if a property is set, i.e. defined and not null.
* This method will check in the following order and act accordingly:
*

2. in /var/www/euro.dev/vendor/yiisoft/yii2/db/BaseActiveRecord.php at line 305 – yii\base\Component::__set('images', [app\fond\entities\Slide])
3. in /var/www/euro.dev/fond/entities/Slider.php at line 104 – yii\db\BaseActiveRecord::__set('images', [app\fond\entities\Slide])
9899100101102103104105106107108109110


private function updateSlides(array $slides)
{
foreach ($slides as $i => $slide){
$slide->setSort($i);
}
$this->images = $slides;
}

##################

public function getImages()
{

4. in /var/www/euro.dev/fond/entities/Slider.php at line 46 – app\fond\entities\Slider::updateSlides([app\fond\entities\Slide])
40414243444546474849505152

##################

public function addSlide(UploadedFile $file)
{
$slides = $this->images;
$slides[] = Slide::create($file);
$this->updateSlides($slides);
}
Подскажите пожалуйста что же это значит. Я никак не могу понять в какую сторону мне вообще смотреть.
Заранее благодарен.
WalpeR
Сообщения: 64
Зарегистрирован: 2016.08.29, 17:21

Re: Setting read-only property

Сообщение WalpeR »

$this->images - это связь, она только для чтения. Что-то совсем не хочется разбирать что там, но так делать нельзя. Если нужно добавить, то нужно линковать http://stuff.cebe.cc/yii2docs-ru/guide- ... -relations
abutan
Сообщения: 31
Зарегистрирован: 2016.11.13, 17:26

Re: Setting read-only property

Сообщение abutan »

Ой спасибо за внимание .
Только зря вы меня так. Все там правильно со связями .
Это просто я такой баран.
Ошибка вот

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

 public function getImages()
    {
        $this->hasMany(Slide::className(), ['slider_id' => 'id'])->orderBy('sort');
    }
а надо

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

 public function getImages()
    {
       return $this->hasMany(Slide::className(), ['slider_id' => 'id'])->orderBy('sort');
    }
А все давай быстрей, быстрей, клиент же ждет.)))
Ответить