1

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」ルートと「site/admin/mymodule」ルートの両方を使用して、すべてが正常に機能します。db からアイテムを追加、編集、および削除できます。

ここで問題: 管理者のみが編集/表示できるフォーム要素 (この場合は Select) が必要です。(管理者用に新しいコントローラー/エンティティ クラス「アドホック」を作成できますが、サイト全体で同じコードを使用したいと考えています。)

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() によってエラーが返されます。

誰かが同様の問題を解決しましたか、誰かが私を正しい方向に向けることができますか? ありがとう

4

2 に答える 2

2

問題は、必須フィールドを定義する FormFilter クラスでセキュリティ チェックを行わないことです。

$form->isValid() 関数は、投稿されたデータをそれらのフィルター要素に対してチェックします。したがって、ビュー内の「エコー フィールド」を防止するだけでは十分ではありません。フィルター要素にセキュリティ チェックを適用する必要があります。

于 2013-04-02T07:08:58.710 に答える
0

もう 1 つの方法は、フロント エンド用と管理者用の 2 つのフォームを作成することです。管理者用のフォームには同じフィールドと追加の選択フィールドが 1 つあるため、管理者フォームをフロント エンドのフォームに拡張することができます。例えば

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

そうすれば、フロント エンド フォーム (またはバリデータ) を編集しても、バック エンドは常に最新の状態になります。

お役に立てれば :)、

ストヤン

于 2013-04-02T08:26:51.843 に答える