【问题标题】:How to save images in cakephp 3.4.0 with cakephp-upload while being immutable如何在不可变的情况下使用 cakephp-upload 在 cakephp 3.4.0 中保存图像
【发布时间】:2019-12-24 19:09:18
【问题描述】:

我正在处理my cakephp project 我目前正在从 3.3.16 升级到 3.4.0

该项目使用cakephp-upload plugin 保存图像。 上传插件需要一个现有的实体来附加一个文件。在取消设置以保存用户之前,对请求进行了修改以获取头像。

我知道这不是修改请求的好习惯,但代码是这样编写的。 使用 3.4.0 版本中的不可变对象,它不再可能了。但我不知道如何正确地做到这一点。

这是my unit-test给出的错误信息, 由vendor/bin/phpunit --filter testAdd tests/TestCase/Controller/Api/V1/UsersControllerTest.php运行:

There was 1 failure:

1) App\Test\TestCase\Controller\Api\V1\UsersControllerTest::testAdd
Failed asserting that file "/home/comptoir/Comptoir-srv/webroot/img/files/Users/photo/5/avatar/correctAvatarLogo.jpg" exists.

/home/comptoir/Comptoir-srv/tests/TestCase/Controller/Api/V1/UsersControllerTest.php:208

这里是the actual code

public function add()
    {
        if (!empty($this->request->data)) {
            $user = $this->Users->newEntity($this->request->data);
        } else {
            $user = $this->Users->newEntity();
        }

        $message = "";
        // Get the avatar before unset it to save the user.
        // The Upload plugin need an existing entity to attach a file to it.

        if ($this->request->is('post')) {
            if (isset($this->request->data['photo']) && !$user->errors()) {
                $avatar = $this->request->data['photo'];
                $this->request->data['photo'] = "";
            }

            $user = $this->Users->patchEntity($user, $this->request->data);

            if ($this->Users->save($user)) {
                $user = $this->Users->get($user->id, ['contain' => []]);

                isset($avatar) ? $this->request->data['photo'] = $avatar : null;

                $user = $this->Users->patchEntity($user, $this->request->data);

                if ($this->Users->save($user)) {
                    $message = "Success";
                    $this->Flash->success(__d("Forms", "Your are registred on the Comptoir du Libre, welcome !"));
                    if (!$this->request->is('json')) {
                        $this->Auth->setUser($this->Auth->identify());
                        $this->redirect([
                            "prefix" => false,
                            "controller" => "Pages",
                            "language" => $this->request->param("language")
                        ]);
                    }
                } else {
                    $message = "Error";
                }
            } else {
                $message = "Error";
                $this->Flash->error(__d("Forms", "Your registration failed, please follow rules in red."));
            }

            $message == "Error" ? $this->set('errors', $user->errors()) : null;
        }


        $this->ValidationRules->config('tableRegistry', "Users");
        $rules = $this->ValidationRules->get();
        $userTypes = $this->Users->UserTypes->find('list', ['limit' => 200]);
        $this->set(compact('user', 'userTypes', 'rules', 'message'));
        $this->set('_serialize', ['user', 'userTypes', 'rules', 'message', 'errors']);
    }

有谁知道如何尊重不可变规则?

【问题讨论】:

    标签: cakephp cakephp-3.4


    【解决方案1】:

    你的前提是错误的。

    上传插件需要一个现有的实体来附加一个文件

    这实际上是不正确的,在创建新记录的同时上传文件可以正常工作。您的控制器中不需要这些东西,应该可以通过一次基本保存来处理它,即您应该调查您遇到的问题并修复它。

    但是看看你的测试,它应该无论如何都会失败,因为你传递的文件数据是无效的,它既不是实际上传的文件,is_uploaded_file() 将返回true,用户数据也不能定义临时文件路径和错误代码,即如果测试按原样通过,您没有正确验证数据。接受此类数据是一个安全漏洞,它可能允许各种攻击,从路径遍历到任意文件注入!

    理想情况下,您的整个上传验证和写入功能将支持\Psr\Http\Message\UploadedFileInterface 对象,这将允许通过将该类的实例传递到测试数据中进行非常简单的测试,这可能是值得为插件推荐的东西。如果没有这样的功能,您的第二个最佳选择可能是在发出测试请求之前修改表的验证规则,以便跳过is_uploaded_file(),或者您正在切换到通过 HTTP 的集成测试,而不是在 CakePHP 中的模拟.

    【讨论】:

      猜你喜欢
      • 2014-06-07
      • 1970-01-01
      • 1970-01-01
      • 2011-12-22
      • 1970-01-01
      • 1970-01-01
      • 2018-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多