【问题标题】:CakePHP 3.0 throwing 'field required' error on non-empty fieldCakePHP 3.0 在非空字段上抛出“需要字段”错误
【发布时间】:2018-08-25 11:57:29
【问题描述】:

我的 CakePHP 3.0 网站在不应该抛出错误时遇到了困难。我正在构建一个“添加页面”表单,如下所示:

echo $this->Form->create($newpage);
echo $this->Form->control('title');
echo $this->Form->control('content');
echo $this->Form->button('Save');
echo $this->Form->end();

标题和内容为必填项。提交表单后,“标题”用于生成页面“名称”,该页面当前只是小写的标题并删除了空格(因此“关于我们”将具有名称“关于我们”)。此名称也会被保存,但必须是唯一的(例如,如果您有标题为“No Space”和“NOSpace”的页面,即使标题是唯一的,它们也会以“nospace”结尾)。

我在PagesTable.php中有如下验证规则:

public function validationDefault(Validator $validator)
{
    $validator = new Validator();

    $validator
        ->requirePresence('title','content')
        ->lengthBetween('title', [0, 50])
        ->add(
            'name',
            ['unique' => [
                'rule' => 'validateUnique',
                'provider' => 'table',
                'message' => 'Not unique']
            ]
            );

    return $validator;

}

表单被提交给控制器,其中包含:

public function add($mainpage_id = null) {
    $newpage = $this->Pages->newEntity();

    if ($this->request->is('post')) {
        $newpage = $this->Pages->patchEntity($newpage, $this->request->data);
        // Get page name by removing spaces from title
        $name = strtolower(str_replace(' \'\"', '', $newpage->title));
        // Get navigation order by getting number of current siblings, and adding 1
        $siblings = $this->Pages->find('all')
                                ->where(['parent_id' => $newpage->parent_id])
                                ->count();
        $nav_order = $siblings + 1;
        $newpage = $this->Pages->patchEntity($newpage, ['name' => $name, 'nav_order' => $nav_order]);
        if ($newpage->errors()) {
            $errors = $newpage->errors();
            if(isset($errors['name'])) {
                $this->Flash->error('The title you have entered is too similar to one that already exists. To avoid confusion, please choose a different title.');
            }else {
                $this->Flash->error('Please correct errors below');
            }
        }else {
            $this->Pages->save($newpage);
            $page_id = $newpage->id;
            $this->Flash->success('Page created');
            return $this->redirect('/admin/pages/index');
            exit;
        }
    }

    $this->set(compact('newpage'));
    $this->set('_serialize', ['newpage']);
}

但是,当我尝试提交页面时,即使我输入了标题,我也会在标题字段中看到“此字段为必填项”。实际上,它不会让我在不输入标题的情况下提交表单(弹出一条消息说“填写此字段”),但是它会抛出错误。

谁能看出我做错了什么?

【问题讨论】:

  • patchEntity后,检查title字段是否设置了任何值...
  • $_accessible 可能有问题?
  • 从修复requirePresence() call开始,它不会将多个字段作为单独的参数。
  • 谢谢,我已经解决了这个问题。

标签: validation cakephp cakephp-3.0


【解决方案1】:

代码库看起来不错。但是,这可能不是明显的行为:calling patch entity method validate the passed patch data。 所以你的补丁第一次在这里验证:

$newpage = $this->Pages->patchEntity($newpage, $this->request->data);

第二次在这里验证:

$newpage = $this->Pages->patchEntity($newpage, ['name' => $name, 'nav_order' => $nav_order]);

并且由于第二个补丁没有标题,因此验证器说它错过了。要解决此问题,您需要使用所有数据运行一次补丁,即:

    $data = $this->request->data();
    // Get page name by removing spaces from title
    $data['name'] = strtolower(str_replace(' \'\"', '', $data['title']));
    // Get navigation order by getting number of current siblings, and adding 1
    $siblings = $this->Pages->find('all')
                            ->where(['parent_id' => $data['parent_id']])
                            ->count();
    $data['nav_order'] = $siblings + 1;
    $newpage = $this->Pages->patchEntity($newpage, $data);

希望你理解这个想法,它会有所帮助。

更新:刚刚注意到请求中可能没有 parent_id...您可以将此逻辑移动到 PagesTabe 中的 afterSave 回调中:

public function afterSave(Event $event, EntityInterface $entity) {
    $siblings = $this->count()
        ->where(['parend_id '=> $entity->parent_id]);
    // updateAll won't trigger the same hook again
    $this->updateAll(
            ['nav_order' => ++$siblings],
            ['id' => $entity->id]
    );
}

【讨论】:

  • (我已经在表单的选择字段中有 parent_id,只是在我试图解决这个问题时将其删除以使事情变得更容易。但是知道 afterSave 回调真的很有用;我没有t 在文档中发现了这一点。)
  • 如果您从请求中获得 parent_id - 最好将其留在控制器中。不要忘记为它添加验证 - 可能是isNumber
  • 我就是这么想的。谢谢!
  • 我在 2 个 patchEntities 上遇到了类似的问题 - 第一个我使用了 $this->getRequest()->getData(),第二个我正在修补一些自定义数据。我通过对 getData() 和我的自定义数据数组进行数组合并来解决这个问题。因此只需要一个补丁(因此需要验证)。
猜你喜欢
  • 1970-01-01
  • 2022-01-03
  • 2018-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多