如何在Zend Framework 2和Doctrine中验证我的表单?

时间:2014-02-24 12:19:58

标签: zend-framework doctrine-orm doctrine zend-framework2 zend-form

所以我有一些实体,我想验证我的表格,我使用 Zend Framework 2 Doctrine Orm 更新感谢Notuser :现在我收到了这个错误:

Fatal error: Call to undefined method Zend\ServiceManager\ServiceManager::initForm() in C:\wamp2\www\test\module\Application\src\Application\Controller\BlogController.php

这是我的model.config.php:

'doctrine' => array(
    'driver' => array(
        'application_entities' => array(
            'class' =>'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
            'cache' => 'array',
            'paths' => array(__DIR__ . '/../src/Application/Entity')
        ),
        'application_forms' => array(
                'class' =>'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
                'cache' => 'array',
                'paths' => array(__DIR__ . '/../src/Application/Form')
        ),
        'application_inputs_filters' => array(
                'class' =>'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
                'cache' => 'array',
                'paths' => array(__DIR__ . '/../src/Application/InputFilter')
        ),

        'orm_default' => array(
            'drivers' => array(
                'Application\Entity' => 'application_entities',
                'Application\Form'   => 'application_forms',
                'Application\InputFilter'    => 'application_inputs_filters'
            )
        )
    )
),

这是我的控制器:

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Entity\Article;
use Application\Entity\Image;
use Application\Form\ArticleForm;

class BlogController extends AbstractActionController
 {
   protected $_objectManager;

public function addAction()
{       
    $form = $this->getServiceLocator('Application\Form\ArticleForm');
    $form->initForm();
    $request = $this->getRequest();
    $form->setData($request->getPost());

    $article = new Article();
    if ($this->zfcUserAuthentication()->hasIdentity()) {
        if ($form->isValid()) 
        {
            $file = $this->params()->fromFiles('url');

            $adapter = new \Zend\File\Transfer\Adapter\Http();
            $adapter->setDestination('public/upload');
            if($adapter->receive($file['name'])){


                $article->setTitle($this->getRequest()->getPost('title'));
                $article->setDate(new \DateTime($this->getRequest()->getPost('date')));
                $article->setContent($this->getRequest()->getPost('content'));
                $article->setPublication($this->getRequest()->getPost('publication'));
                $image = new Image();
                $image->setUrl($file['name']);
                $image->setAlt($this->getRequest()->getPost('alt'));
                $article->setImage($image);

                $this->getObjectManager()->persist($article);
                $this->getObjectManager()->flush();
                $newId = $article->getId();

                return $this->redirect()->toRoute('blog');
            }

        }
    }
    else
    {
        return $this->redirect()->toRoute('user');
    }
    return new ViewModel(array('article' => $article));
}

这是我的ArticleForm:

class ArticleForm extends Form {

public function __construct()
{
    parent::__construct('UserEntry');

    $this->setAttribute('method', 'post');
    $this->setAttribute('enctype', 'multipart/form-data');
    $this->setAttribute('class', 'contact_form');
}

/**
 *
 */
public function initForm()
{
    $this->addFormFields(); //function where we added all fields

    $articleInputFilter = new ArticleInputFilter();
    $this->setInputFilter($articleInputFilter->getInputFilter()); //Asign input Filter to form
}

/**
 *
 */
protected function addFormFields()
{
    $this->addSubmit();
    $this->addTitle();
    $this->addContent();
    $this->addDate();
    $this->addPublication();
    $this->addImage();
}

/**
 *
 */
protected function addTitle()
{
    $this->add(array(
            'name' => 'title',
            'attributes' => array(
                    'type' => 'text',
            ),
            'options' => array(
                    'label' => _('Title')
            ),
    ));
}

/**
 *
 */
protected function addContent()
{
    $this->add(array(
            'name' => 'content',
            'attributes' => array(
                    'type' => 'text',
            ),
            'options' => array(
                    'label' => _('Content')
            ),
    ));
}

/**
 *
 */
protected function addDate()
{
    $this->add(array(
            'name' => 'date',
            'attributes' => array(
                    'type' => 'date',
            ),
            'options' => array(
                    'label' => _('Date'),
                    'id'    => 'datepicker',
            ),
    ));
}

/**
 *
 */
protected function addPublication()
{
    $this->add(array(
            'name' => 'publication',
            'attributes' => array(
                    'type' => 'checkbox',
            ),
            'options' => array(
                    'label' => _('Publication'),
                    'use_hidden_element' => true,
                    'checked_value' => 1,
                    'unchecked_value' => 'no',
            ),
    ));
}

/**
 *
 */
protected function addImage()
{
    $this->add(array(
            'name' => 'Image',
            'attributes' => array(
                    'type' => new ImageForm(),
            ),
            'options' => array(
                    'label' => _('Image')
            ),
    ));
}

/**
 *
 */
protected function addSubmit()
{
    $this->add(array(
            'name' => 'submit',
            'attributes' => array(
                    'type' => 'submit',
                    'value' => _('Add'),
                    'class' => 'submit',
            ),
    ));
}
}

最后这是我的ArticleInputFilter:

class ArticleInputFilter extends InputFilter implements InputFilterAwareInterface 
  {
/**
 * @var string
 */
public $title;

/**
 * @var int
 */
public $image;

/**
 * @var string
 */
public $content;

/**
 * @var Date
 */
public $date;

/**
 * @var Boolean
 */
public $publication;

/**
 * @param $data
 */
public function exchangeArray($data)
{
    $this->title     = (isset($data['title']))     ? $data['title']     : $this->title;
    $this->image     = (isset($data['image']))     ? $data['image']     :  $this->image;
    $this->content     = (isset($data['content']))     ? $data['content']     : $this->content;
    $this->publication   = (isset($data['publication']))       ? $data['publication']   :  $this->publication;
    $this->date      = (isset($data['date']))      ? $data['date']  :  $this->date;
}

/**
 * @param InputFilterInterface $inputFilter
 * @return void|InputFilterAwareInterface
 * @throws \Exception
 */
public function setInputFilter(InputFilterInterface $inputFilter)
{
    throw new \Exception("Not used");
}

/**
 * @return InputFilter|InputFilterInterface
 */
public function getInputFilter()
{
    if (!$this->inputFilter) {
        $inputFilter = new InputFilter();
        $factory     = new InputFactory();

        $inputFilter->add($factory->createInput(array(
                'name'     => 'title',
                'required' => true,
                'filters'  => array(
                        array('name' => 'StripTags'),
                        array('name' => 'StringTrim'),
                ),
                'validators' => array(
                        array(
                                'name'    => 'StringLength',
                                'options' => array(
                                        'encoding' => 'UTF-8',
                                        'min'      => 6,
                                        'max'      => 100,
                                ),
                        ),
                ),
        )));

        $inputFilter->add($factory->createInput(array(
                'name'     => 'content',
                'required' => true,
                'filters'  => array(
                        array('name' => 'StripTags'),
                        array('name' => 'StringTrim'),
                ),
                'validators' => array(
                        array(
                                'name'    => 'StringLength',
                                'options' => array(
                                        'encoding' => 'UTF-8',
                                        'min'      => 10,
                                ),
                        ),
                ),
        )));

        $inputFilter->add($factory->createInput(array(
                'name'     => 'publication',
                'required' => false,
        )));

        $inputFilter->add($factory->createInput(array(
                'name'     => 'date',
                'required' => true,
        )));

        $inputFilter->add($factory->createInput(array(
                'name'     => 'image',
                'required' => true,
        )));

        $this->inputFilter = $inputFilter;
    }

    return $this->inputFilter;
}
  }

我写的漏洞代码除了 ImageForm ImageInputFilter ,所以如果有人知道怎么做我会非常感激;)

2 个答案:

答案 0 :(得分:2)

在控制器中

$form = $this->getServiceLocator('Application\Form\BlogForm");//don't forger to add Application\Form\BlogForm to module.config.php and check your namespace
        $form->initForm();//explained further

        /** @var \Zend\Http\Request $request */
        $request = $this->getRequest();//whole request fo @var for further using
        if ($request->isPost()) { //there is something in post
            $form->setData($request->getPost()); //data from post is added for further validation
            if ($form->isValid()) { //Form is Valid lets save form
                $files = $request->getFiles()->toArray(); //array witch files use var_dump($files);die; to show structure

                $article = new Article();
                $article->setTitle($request->getPost('title'));
                ...
                if(!empty($files)&&$files['image']['error']==0) {
                    $article->setImage($functionToCreateImageEntityFromFile(($files['image']));
                }
                ...
                $this->getObjectManager()->persist($article);
                $this->getObjectManager()->flush();
                $newId = $article->getId();

                return $this->redirect()->toRoute('blog');
            }
            //form is not valid so you can display form with Errors
        } //there is no post so you can display clean form

接下来让我们采取以下形式: (这是我的建议)

namespace Application\Form; //check your namespace

use Zend\Form\Form;
use Application\InputFilter\BlogInputFilter; //check your namespace

class BlogForm extends Form {

    public function __construct()
    {
        parent::__construct('UserEntry');

        $this->setAttribute('method', 'post');
        $this->setAttribute('enctype', 'multipart/form-data');
    }

    /**
     *
     */
    public function initForm()
    {
        $this->addFormFields(); //function where we added all fields

        $blogInputFilter = new BlogInputFilter(); //Input Filter for Validation
        $this->setInputFilter($BlogInputFilter->getInputFilter()); //Asign input Filter to form
    }

    /**
     *
     */
    protected function addFormFields()
    {
            $this->addSubmit();
            $this->addTitle();
            $this->addImage();
            ...//add more here
    }

    /**
     *
     */
    protected function addTitle()
    {
        $this->add(array(
            'name' => 'title',
            'attributes' => array(
                'type' => 'text',
                'id' => 'title',
                'class' => 'text'
            ),
            'options' => array(
                'label' => _('Title') //it's only for multilang you can put here any string
            ),
        ));
    }

    /**
     *
     */
    protected function addImage()
    {
        $this->add(array(
            'name' => 'image',
            'attributes' => array(
                'type'  => 'file',
                'id' => 'image'
            ),
            'options' => array(
                'label' => _('Image'),
            ),
        ));
    }

    /**
     *
     */
    protected function addSubmit()
    {
        $this->add(array(
            'name' => 'submit',
            'attributes' => array(
                'type' => 'submit',
                'value' => _('Save'),
                'class' => 're',
            ),
        ));
    }
}

现在是InputFilter的时间

namespace Application\InputFilter;//check your namespace

use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;

class BlogInputFilter implements InputFilterAwareInterface
{
    /**
     * @var int
     */
    public $title;

    /**
     * @var string
     */
    public $image;

    //add all fields

    /**
     * @param $data
     */
    public function exchangeArray($data)
    {
        $this->title     = (isset($data['title']))     ? $data['title']     : $this->title;
        $this->image = (isset($data['image'])) ? $data['image'] :  $this->image;
        //add fields
    }

    /**
     * @param InputFilterInterface $inputFilter
     * @return void|InputFilterAwareInterface
     * @throws \Exception
     */
    public function setInputFilter(InputFilterInterface $inputFilter)
    {
        throw new \Exception("Not used");
    }

    /**
     * @return InputFilter|InputFilterInterface
     */
    public function getInputFilter()
    {
        if (!$this->inputFilter) {
            $inputFilter = new InputFilter();
            $factory     = new InputFactory();

            $inputFilter->add($factory->createInput(array(
                'name'     => 'title',
                'required' => true,//required field
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name'    => 'StringLength',
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 1,
                            'max'      => 100,//limit from 1 to 100 chars
                        ),
                    ),
                ),
            )));

            $this->inputFilter = $inputFilter;
        }

        return $this->inputFilter;
    }
}

阅读:

表格:http://framework.zend.com/manual/2.0/en/modules/zend.form.quick-start.html#factory-backed-form-extension

ImputFilter:http://framework.zend.com/manual/2.0/en/modules/zend.input-filter.intro.html

文件上传:找不到好的教程

module.config.php应该有这样的键:

 'service_manager' => array(
    'invokables' => array(
        'Application\Form\ArticleForm' => 'Application\Form\ArticleForm',
    ),
),

由于您使用ServiceLocator,因此无需添加Application \ Form \ ArticleForm

答案 1 :(得分:0)

这是你的问题:

$form = $this->getServiceLocator('Application\Form\ArticleForm');
$form->initForm();

应该是:

$form = $this->getServiceLocator()->get('Application\Form\ArticleForm');
$form->initForm();

您编写它的方式,括号内容将被忽略,它变为:

$form = $this->getServiceLocator()

这就是为什么在调用initForm()时会出现“未定义的方法:ServiceManager :: initForm()”错误。