我在zfcAdmin和BjyAuthorize中集成自定义模块时遇到验证问题。
我的表单类:
...
$formOptions = $this->settings->getFormSettings();
foreach ($formOptions as $field){
if (isset($field['field']))
$this->add($field['field']);
}
...
我的过滤器类:
$formOptions = $this->settings->getFormSettings();
foreach ($formOptions as $filter){
if (isset($filter['filter']))
$this->add($filter['filter']);
}
...
从配置文件中检索字段,过滤器和其他选项。
基本上一切正常:可以从db添加,编辑或删除表单数据。 zfcAdmin模块安装后也没问题上升。使用'site / mymodule'路由和'site / admin / mymodule'路由一切正常:我仍然可以从db添加,编辑和删除项目。
问题在于:我需要一些表单元素(在这种特殊情况下为Select)只能由管理员编辑/查看。 (我可以为管理员编写一个新的控制器/实体类'ad hoc',但我想对整个站点使用相同的代码。)
我安装并配置了bjyoungblood / BjyAuthorize模块:它允许我只向管理员显示一些表单元素/字段,但是当我处于编辑模式时,会显示一个表单验证错误:“值是必需的,不能为空“
这里是代码:
//view/mymodule/mymodule/update.phtml
<div id="page" style="margin-top: 50px;">
<?php if (isset($this->messages) && count($this->messages) > 0 ): ?>
<?php foreach ($this->messages as $msg): ?>
<div class="alert alert-<?php echo $this->escapeHtmlAttr($msg['type']); ?>">
<?php if (isset($msg['icon'])) echo '<i class="'.$this->escapeHtmlAttr($msg['icon']).'"></i> '; ?><?php echo $this->escapeHtml($msg['message']); ?>
</div>
<?php endforeach; ?>
<?php endif; ?>
<?php
$title = 'Edit Item';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
$form = $this->form;
$form->setAttribute('action', $this->url($this->route . 'mymodule/update', array('action' => 'update', 'id' => $this->id )));
$form->prepare();
$form->setAttribute('method', 'post');
$input = $form->getInputFilter();
?>
<?php echo $this->form()->openTag($form) ?>
<dl class="zend_form">
<?php foreach ($form as $element): ?>
<?php
//CHECK USER PRIVILEDGES
$elName = $element->getName();
$elResource = isset($this->form_options[$elName]['auth']) ? $this->form_options[$elName]['auth']['resource'] : "userresource";
$elPrivilege = isset($this->form_options[$elName]['auth']) ? $this->form_options[$elName]['auth']['privilege'] : "view";
//SHOW THE ELEMENT IF ALLOWED
if($this->isAllowed($elResource, $elPrivilege)):
?>
<?php if ($element->getLabel() != null): ?>
<dt><?php echo $this->formLabel($element) ?></dt>
<?php endif ?>
<?php if ($element instanceof Zend\Form\Element\Button): ?>
<dd><?php echo $this->formButton($element) ?></dd>
<?php elseif ($element instanceof Zend\Form\Element\Select): ?>
<dd><?php echo $this->formSelect($element) . $this->formElementErrors($element) ?></dd>
<?php else: ?>
<dd><?php echo $this->formInput($element) . $this->formElementErrors($element) ?></dd>
<?php endif ?>
<?php else: ?>
<?php
?>
<?php endif ?>
<?php endforeach ?>
</dl>
<?php echo $this->form()->closeTag() ?>
</div>
<div class="clear-both"></div>
我的控制器操作
//controller
public function updateAction(){
$messages = array();
$id = (int)$this->getEvent()->getRouteMatch()->getParam('id');
$form = $this->getServiceLocator()->get('FormItemService');
$itemMapper = $this->getItemMapper();
$item = $itemMapper->findById($id);
$form->bind($item);
$request = $this->getRequest();
if($request->isPost()){
$form->setData($request->getPost());
if ($form->isValid()) {
die('c');//never here
$service = $this->getServiceLocator()->get('mymodule\Service\Item');
if ( $service->save($form->getData()) )
{
$messages[] = array(
'type' => 'success',
'icon' => 'icon-ok-sign',
'message' => 'Your profile has been updated successfully!',
);
}
else
{
$messages[] = array(
'type' => 'error',
'icon' => 'icon-remove-sign',
'message' => 'Profile update failed! See error messages below for more details.',
);
}
}else{
var_dump($form->getMessages());//Value is required and can't be empty
}
}
return array(
'messages' => $messages,
'form' => $form,
'id' => $id,
'form_options' => $this->getServiceLocator()->get('mymodule_module_options')->getFormSettings(),
'route' => $this->checkRoute($this->getEvent()->getRouteMatch()->getmatchedRouteName())
);
}
如果不允许用户查看资源,则不会回显该元素。所以$ request-&gt; getPost()没有该表单元素的值,并且isValid()返回错误。
有没有人解决过类似的问题,或者有人能指出我正确的方向吗? 感谢
答案 0 :(得分:2)
问题是您没有在FormFilter类中进行任何安全检查,您可以在其中定义必填字段。
$ form-&gt; isValid()函数根据这些过滤元素检查发布的数据。因此,在视图中阻止“回声字段”是不够的,您仍然需要将安全检查应用于过滤器元素。
答案 1 :(得分:0)
另一种方法是为前端制作两个表单,为管理员制作一个表单。由于管理员将拥有相同的字段和一个额外的选择字段,因此您可以将管理表单扩展为前端字段。 E.g。
class myForm
{
public function __construct(...)
{
// add fields and set validators
}
}
,管理员表格可以是:
class MyAdminForm extends myForm
{
public function __construct(...)
{
parent::__construct(...);
// add the extra field and extra validator
}
}
这样即使您编辑前端表单(或验证器),后端也始终是最新的。
希望这有助于:),
斯托