2013-04-01 43 views
1

我面临将自定义模块集成到zfcAdmin和BjyAuthorize中的验证问题。zf2表单验证(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']); 
} 
... 

字段,过滤器和其他选项从配置文件检索。

基本上一切工作正常:表单数据可以添加,编辑或从数据库中删除。 也是在zfcAdmin模块安装后没有问题上升。一切工作正常使用'site/mymodule'路线和'网站/管理员/ mymodule'路线:我仍然可以添加,编辑和删除数据库中的项目。

这里的问题:我需要一些表单元素(一个选择在这种特殊情况下)只能由管理员编辑/查看。 (我可以为管理员编写一个新的控制器/实体类'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>&nbsp;'; ?><?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-> getPost()对该表单元素没有任何值,并且isValid()返回一个错误。

有没有人解决了类似的问题,或任何人都可以指向正确的方向吗? 谢谢

+0

此博客是值得一读,尤其是在确认团组HTTP最后一节://www.michaelgallego。fr/blog/2012/07/04/new-zendform-features-explained/ – Crisp

回答

2

问题是,你不要在你的FormFilter类中进行任何安全检查,在那里你定义了你需要的字段。

$ form-> isValid()函数根据这些过滤元素检查发布的数据。因此,仅仅阻止视图中的“回显字段”是不够的,您仍然需要将安全检查应用于过滤元素。

+0

也许我没有完全理解你的话,但是你的帖子指出了我的解决方案:基本上,我将ACL检查从视图脚本移动到了Form和过滤器类。谢谢 – IamFraz

0

另一种方法是为前端和管理员制作两种形式。由于管理员将具有相同的字段和一个额外的选择字段,因此可以使管理员表单扩展前端。例如。

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 
    } 
} 

在即使编辑前端的形式(或验证)后端将永远是最新的方式。

希望这有助于:),

斯托扬

+0

感谢您的提示。我啧啧称赞,理想情况下,这不是我要找的。字段可以增加,如访问级别 – IamFraz