CakePHP 3.0 在 non-empty 字段上抛出 'field required' 错误
CakePHP 3.0 throwing 'field required' error on non-empty field
我的 CakePHP 3.0 站点在不应该抛出错误时遇到问题。我正在构建一个 "Add Page" 表单,如下所示:
echo $this->Form->create($newpage);
echo $this->Form->control('title');
echo $this->Form->control('content');
echo $this->Form->button('Save');
echo $this->Form->end();
标题和内容为必填项。提交表单后,'title' 用于生成一个页面 'name',该页面目前只是小写的标题并删除了空格(因此 "About Us" 的名称为 "aboutus").此名称也被保存,但必须是唯一的(例如,如果您有标题为 "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']);
}
但是,当我尝试提交页面时,即使我输入了标题,标题字段也会显示 "This field is required"。事实上,它不会让我在不输入标题的情况下提交表单(弹出一条消息说 "Fill out this field"),但随后它会抛出错误。
谁能看出我做错了什么?
代码库看起来不错。但是,这可能不是明显的行为: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]
);
}
我的 CakePHP 3.0 站点在不应该抛出错误时遇到问题。我正在构建一个 "Add Page" 表单,如下所示:
echo $this->Form->create($newpage);
echo $this->Form->control('title');
echo $this->Form->control('content');
echo $this->Form->button('Save');
echo $this->Form->end();
标题和内容为必填项。提交表单后,'title' 用于生成一个页面 'name',该页面目前只是小写的标题并删除了空格(因此 "About Us" 的名称为 "aboutus").此名称也被保存,但必须是唯一的(例如,如果您有标题为 "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']);
}
但是,当我尝试提交页面时,即使我输入了标题,标题字段也会显示 "This field is required"。事实上,它不会让我在不输入标题的情况下提交表单(弹出一条消息说 "Fill out this field"),但随后它会抛出错误。
谁能看出我做错了什么?
代码库看起来不错。但是,这可能不是明显的行为: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]
);
}