CakePHP доступ к загруженному файлу после проверки - PullRequest
0 голосов
/ 20 октября 2019

У меня есть поле 'снимок экрана', которое, когда я пытаюсь получить доступ к beforeSave , вызывает его пустое поле.

Что я делаю, так это доступ к данным $ на beforeMarshal обратный вызов и сохранение массива в настройках модели, затем я могу получить к нему доступ в поле beforeSave и установить для поля «screenshot» значение filename.ext, если move_uploaded_file равно true.

Thisэто текущий код:

Модель

// Using CakePHP 3.8.5
public function validationDefault(Validator $validator)
    {
        $validator
            ->allowEmptyFile('screenshot', 'update')
            ->uploadedFile('screenshot' , [
                'types' => ['image/jpeg', 'image/jpg', 'image/pjpeg'],
                'maxSize' => 1000000 // 1MB
            ]);

        return $validator;
    }

public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
    {
        if (isset($data['screenshot']) && $data['screenshot']['error'] === UPLOAD_ERR_OK) {
            $this->config([ 'file_array' => $data['screenshot'] ])
        }
    }

public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options)
{
    ...
    $file = $this->config([ 'file_array');
    if (move_uploaded_file($file['tmp_name'], $file_path)) {
        return true;
    } else {
        throw new Exception(__('Unable to move...'));
    }

}

Форма

<?= $this->Form->create($project, ['type' =>  'file']) ?>
<?= $this->Form->control('screenshot', ['type' => 'file', 'class' => 'form-control-file']) ?>
<?= $this->Form->button(__('Submit'), ['class' => 'btn btn-primary col-md-3 offset-md-9']) ?>
<?= $this->Form->end() ?>

Код, который я ожидална работу

public function validationDefault(Validator $validator)
    {
        $validator
            ->allowEmptyFile('screenshot', 'update')
            ->uploadedFile('screenshot' , [
                'types' => ['image/jpeg', 'image/jpg', 'image/pjpeg'],
                'maxSize' => 1000000 // 1MB
            ]);

        return $validator;
    }

public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options)
{
    ...
    $file = $entity->screenshot; // this is empty
    if (move_uploaded_file($file['tmp_name'], $file_path)) {
        return true;
    } else {
        throw new Exception(__('Unable to move...'));
    }

}

Почему $ entity-> screenshot пусто в BeforeSave?

Это правильный способ сделать это?

1 Ответ

0 голосов
/ 21 октября 2019

Во время сортировки (при исправлении / создании сущностей) CakePHP будет преобразовывать / преобразовывать входные данные в соответствии с типами базы данных , сопоставленными для полей.

Дляполе вашей базы данных screenshot, которое VARCHAR, будет \Cake\Database\Type\StringType, которое возвращает пустую строку для массивов . Причина в том, что этап маршаллинга не должен вызывать «сбоев», а в идеале создавать сущности с данными, совместимыми с соответствующими типами баз данных, которые могут быть окончательно проверены с помощью правил приложения при необходимости, для которого ошибки могут быть представлены пользователю так же легко, как и для правил валидации.

Два наиболее популярных способа обработки этого IMHO:

  • Использование другого имени поля для загрузки, такого, которое не сопоставлено с существующим столбцом базы данных, например что-то вроде screenshot_upload

  • Использование пользовательского типа базы данных для поля, которое не преобразует массив

Лично я предпочитаю первое.

...