Zend Framework:需要三个值之一

发布于 2024-11-24 03:07:09 字数 2723 浏览 2 评论 0原文

对于我的学校项目,我正在开发一个数据库管理应用程序。 这是我的第一个真正的 Zend Framework 应用程序。

现在,现在,我已经根据需要设置了 3 个值,邮政编码、电子邮件和电话。 它们是这样需要的(示例):

        $mail = $this->createElement('text', 'mail');
    $mail->setLabel('E-mail:')
            ->setAttrib('size', 50)->addValidator('StringLength', false, array(6, 40))->addValidator('EmailAddress', true)
            ->setRequired(true);
        $telephone = $this->createElement('text', 'telephone');
    $telephone->setLabel('Telephone:')
            ->setAttrib('size', 50)->addValidator('StringLength', false, array(10, 10))
            ->setRequired(true);

我怎样才能只需要其中之一?

我正在使用 Zend_Form,也正在使用 Displaygroups。

有人知道我的程序的解决方案吗?也许使用数组?

预先感谢,

JorritK

更新

@brady.vitrano

好吧,我的代码的第一部分现在看起来像这样:

<?php

class Application_Form_Validate_ContactMethodSelected
extends Zend_Validate_Abstract
{
const INVALID = 'invalid';

protected $_messageTemplates = array(
    self::INVALID => 'Must select at least one contact method'
);

public function isValid($value, $context = array())
{
     // You need to use your element names, consider making these dynamic
    $checkFields = array('telefoon','mobiel','mail');
    // Check if all are empty
    foreach ( $checkFields as $field ) {
        if (isset($context[$field]) && !empty($context[$field])) {
            // Only one value needs to return true..skip the rest
            return true;
        }
    }

    // All were empty, set your own error message
    $this->_error(self::INVALID);
    return false;
}

}

class Application_Form_Nieuwkandidaat extends Zend_Form
{

public function init()
{
     $this->setMethod('post');
    $DB = Zend_Db_Table::getDefaultAdapter();


    $telefoon = $this->createElement('text', 'telefoon');
    $telefoon->setLabel('Telefoon:')
            ->setAttrib('size', 50)->addValidator('StringLength', false,array(10,10));
    $telefoon->addValidator(new Application_Form_Validate_ContactMethodSelected());
    $mobiel = $this->createElement('text', 'mobiel');
    $mobiel->setLabel('Mobiel:')
            ->setAttrib('size', 50)->addValidator('StringLength', false,array(10,10));
    $mobiel->addValidator(new Application_Form_Validate_ContactMethodSelected());
    $mail = $this->createElement('text', 'mail');
    $mail->setLabel('E-mail:')
            ->setAttrib('size', 50)->addValidator('StringLength', false,array(6,40))->addValidator('EmailAddress', true);
    $mail->addValidator(new Application_Form_Validate_ContactMethodSelected());

点击提交按钮后不会显示消息。我还应该改变什么?感谢您的帮助!

For my school project, I am working on a database management application.
It is my first real Zend Framework application.

Now, right now, I have set 3 values as required, postalcode, email and telephone.
They are required like this(Example):

        $mail = $this->createElement('text', 'mail');
    $mail->setLabel('E-mail:')
            ->setAttrib('size', 50)->addValidator('StringLength', false, array(6, 40))->addValidator('EmailAddress', true)
            ->setRequired(true);
        $telephone = $this->createElement('text', 'telephone');
    $telephone->setLabel('Telephone:')
            ->setAttrib('size', 50)->addValidator('StringLength', false, array(10, 10))
            ->setRequired(true);

How can I make only one of them required?

I am working with Zend_Form, and also working with Displaygroups.

Is there someone who knows a solution for my program? Maybe use an array?

Thanks in advance,

JorritK

UPDATE

@brady.vitrano

Ok, the first part of my code looks like this now:

<?php

class Application_Form_Validate_ContactMethodSelected
extends Zend_Validate_Abstract
{
const INVALID = 'invalid';

protected $_messageTemplates = array(
    self::INVALID => 'Must select at least one contact method'
);

public function isValid($value, $context = array())
{
     // You need to use your element names, consider making these dynamic
    $checkFields = array('telefoon','mobiel','mail');
    // Check if all are empty
    foreach ( $checkFields as $field ) {
        if (isset($context[$field]) && !empty($context[$field])) {
            // Only one value needs to return true..skip the rest
            return true;
        }
    }

    // All were empty, set your own error message
    $this->_error(self::INVALID);
    return false;
}

}

class Application_Form_Nieuwkandidaat extends Zend_Form
{

public function init()
{
     $this->setMethod('post');
    $DB = Zend_Db_Table::getDefaultAdapter();


    $telefoon = $this->createElement('text', 'telefoon');
    $telefoon->setLabel('Telefoon:')
            ->setAttrib('size', 50)->addValidator('StringLength', false,array(10,10));
    $telefoon->addValidator(new Application_Form_Validate_ContactMethodSelected());
    $mobiel = $this->createElement('text', 'mobiel');
    $mobiel->setLabel('Mobiel:')
            ->setAttrib('size', 50)->addValidator('StringLength', false,array(10,10));
    $mobiel->addValidator(new Application_Form_Validate_ContactMethodSelected());
    $mail = $this->createElement('text', 'mail');
    $mail->setLabel('E-mail:')
            ->setAttrib('size', 50)->addValidator('StringLength', false,array(6,40))->addValidator('EmailAddress', true);
    $mail->addValidator(new Application_Form_Validate_ContactMethodSelected());

It won't show the message after hitting the submit button. What more should I change? Thanks for helping!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

少钕鈤記 2024-12-01 03:07:09

一个值得考虑的好解决方案是为元素编写自定义验证器

在您的 isValid 方法中,您必须根据其他值的 $context 进行检查。类似于:

编辑

/** /library/Application/Form/Validate/ContactMethodSelected.php **/

class Application_Form_Validate_ContactMethodSelected 
    extends Zend_Validate_Abstract
{
    const INVALID = 'invalid';

    protected $_messageTemplates = array(
        self::INVALID => 'Must select at least one contact method'
    ); 

    public function isValid($value, $context = array())
    {
         // You need to use your element names, consider making these dynamic
        $checkFields = array('phone','email','address');
        // Check if all are empty
        foreach ( $checkFields as $field ) {
            if (isset($context[$field]) && !empty($context[$field])) {
                // Only one value needs to return true..skip the rest
                return true;
            }
        }

        // All were empty, set your own error message
        $this->_error(self::INVALID);
        return false;   
    }

}

现在,您必须告诉元素使用该验证器。因此,请对表单的 init() 方法进行更改。

 $mail->addValidator(new Application_Form_Validate_ContactMethodSelected());
 $telephone->addValidator(new Application_Form_Validate_ContactMethodSelected());

不要忘记:一旦您有了自己的自定义验证器,您就必须从每个元素中删除 isRequired()

EDIT2

您必须将自定义验证器设置为链中的第一个验证器,并在失败时中断。另外,您必须将 setAllowEmpty() 设置为 false。

$telefoon = $this->createElement('text', 'telefoon');
$telefoon->setLabel('Telefoon:')
        ->setAttrib('size', 50)->setAllowEmpty(false)
        ->addValidator(new Application_Form_Validate_ContactMethodSelected(),true)
        ->addValidator('StringLength', false,array(10,10));
$mobiel = $this->createElement('text', 'mobiel');
$mobiel->setLabel('Mobiel:')
        ->setAttrib('size', 50)->setAllowEmpty(false)
        ->addValidator(new Application_Form_Validate_ContactMethodSelected(),true)
        ->addValidator('StringLength', false,array(10,10));
$mail = $this->createElement('text', 'mail');
$mail->setLabel('E-mail:')
        ->setAttrib('size', 50)->setAllowEmpty(false)
        ->addValidator(new Application_Form_Validate_ContactMethodSelected(),true)
        ->addValidator('StringLength', false,array(6,40))->addValidator('EmailAddress', true);

接下来,您必须使用以下内容更新 isValid 方法:

public function isValid($value, $context = array())
{
    // You need to use your element names, consider making these dynamic
    $checkFields = array('telefoon','mobiel','mail');
    // Check if all are empty
    foreach ( $checkFields as $field ) {
    if (isset($context[$field]) && !empty($context[$field])) {

        if (!empty($value)) {
            // This is the element with content... validate as true
            return true;
        }
        // we are going to return false and no error
        // to break validation chain on other empty values
        // This is a quick hack, don't have time to invest in this
        return false;
        }
    }

    // All were empty, set your own error message
    $this->_error(self::INVALID);
    return false;
}

现在,您必须向使用此验证器的代码添加另一个条件。我们必须要求表单没有任何错误消息。

if ($form->isValid($_POST) || !count($form->getMessages())) {
    /** Valid, now you can process **/
} else {
    /** Not valid **/
}

A good solution to consider is to write a custom validator for the elements.

In your, isValid method you will have to check based on $context of other values. Something like:

EDIT

/** /library/Application/Form/Validate/ContactMethodSelected.php **/

class Application_Form_Validate_ContactMethodSelected 
    extends Zend_Validate_Abstract
{
    const INVALID = 'invalid';

    protected $_messageTemplates = array(
        self::INVALID => 'Must select at least one contact method'
    ); 

    public function isValid($value, $context = array())
    {
         // You need to use your element names, consider making these dynamic
        $checkFields = array('phone','email','address');
        // Check if all are empty
        foreach ( $checkFields as $field ) {
            if (isset($context[$field]) && !empty($context[$field])) {
                // Only one value needs to return true..skip the rest
                return true;
            }
        }

        // All were empty, set your own error message
        $this->_error(self::INVALID);
        return false;   
    }

}

Now, you have to tell the elements to use that validator. So, make changes in your forms init() method.

 $mail->addValidator(new Application_Form_Validate_ContactMethodSelected());
 $telephone->addValidator(new Application_Form_Validate_ContactMethodSelected());

Don't forget: Once you have your own custom validator, you will have to remove the isRequired() from each element.

EDIT2

You must set the custom validator as the first validator in the chain and break on failure. Also, you have to setAllowEmpty() to false.

$telefoon = $this->createElement('text', 'telefoon');
$telefoon->setLabel('Telefoon:')
        ->setAttrib('size', 50)->setAllowEmpty(false)
        ->addValidator(new Application_Form_Validate_ContactMethodSelected(),true)
        ->addValidator('StringLength', false,array(10,10));
$mobiel = $this->createElement('text', 'mobiel');
$mobiel->setLabel('Mobiel:')
        ->setAttrib('size', 50)->setAllowEmpty(false)
        ->addValidator(new Application_Form_Validate_ContactMethodSelected(),true)
        ->addValidator('StringLength', false,array(10,10));
$mail = $this->createElement('text', 'mail');
$mail->setLabel('E-mail:')
        ->setAttrib('size', 50)->setAllowEmpty(false)
        ->addValidator(new Application_Form_Validate_ContactMethodSelected(),true)
        ->addValidator('StringLength', false,array(6,40))->addValidator('EmailAddress', true);

Next, you will have to update the isValid method with the following:

public function isValid($value, $context = array())
{
    // You need to use your element names, consider making these dynamic
    $checkFields = array('telefoon','mobiel','mail');
    // Check if all are empty
    foreach ( $checkFields as $field ) {
    if (isset($context[$field]) && !empty($context[$field])) {

        if (!empty($value)) {
            // This is the element with content... validate as true
            return true;
        }
        // we are going to return false and no error
        // to break validation chain on other empty values
        // This is a quick hack, don't have time to invest in this
        return false;
        }
    }

    // All were empty, set your own error message
    $this->_error(self::INVALID);
    return false;
}

Now, you will have to add another condition to your code that uses this validator. We have to require that the form does not have any error messages.

if ($form->isValid($_POST) || !count($form->getMessages())) {
    /** Valid, now you can process **/
} else {
    /** Not valid **/
}
把时间冻结 2024-12-01 03:07:09

我认为最好的方法是最简单的方法。您不必编写任何自定义验证器。您只需在表单验证后检查所需值之一是否显示为非空,因为这样您就可以访问经过筛选和验证的表单值。

if ($form->isValid($_POST)) {

    // get filtered and validated form values
    $params = $form->getValues();

    // check if there is a selected contact method
    if (isContactMethodSelected ($params)) {
       // the form is Valid!

    } else {
       // not valid
    }


} else {
    // not valid
}

这是“isContactMethodSelected”方法。您只需将其添加到当前控制器类中即可。

private function isContactMethodSelected ($params) {

        // define array with the contact methods as they appear in the $params as keys
        $checkFields = array('telefoon','mobiel','mail');

        // check if there is at least one contact method selected
        foreach ($checkFields as $field) {
            if (isset($params[$field]) && !empty($params[$field])) {
                return true;
            }
        }

        return false;
    }

I think the best approach is the simplest one. You don't have to write any custom validators. You just have to check if one of the required values appears as not empty, after the form validation, because then you will have access to the filtered and validated form values.

if ($form->isValid($_POST)) {

    // get filtered and validated form values
    $params = $form->getValues();

    // check if there is a selected contact method
    if (isContactMethodSelected ($params)) {
       // the form is Valid!

    } else {
       // not valid
    }


} else {
    // not valid
}

Here is the "isContactMethodSelected" method. You could simply add it in the current controller class.

private function isContactMethodSelected ($params) {

        // define array with the contact methods as they appear in the $params as keys
        $checkFields = array('telefoon','mobiel','mail');

        // check if there is at least one contact method selected
        foreach ($checkFields as $field) {
            if (isset($params[$field]) && !empty($params[$field])) {
                return true;
            }
        }

        return false;
    }
骄傲 2024-12-01 03:07:09

我认为最简单、最快的解决方案是重写表单本身的 isValid 函数

class Application_Form_Nieuwkandidaat extends Zend_Form
{

    //...

    public function isValid($data)
    {
        $valid = parent::isValid($data);
        if ( ! $data['mail'] && ! $data['telephone'] && ! $data['postcode'] ){
            $this->addError('Please supply one of email, telephone or postcode');
            $valid = false;
        }
        return $valid;
    }

    //...

}

一个小函数,与表单相关,易于理解,不太可能失败,不太可能成为困难错误的来源。

I think that the simplest and quickest solution is to override the isValid function for the form itself

class Application_Form_Nieuwkandidaat extends Zend_Form
{

    //...

    public function isValid($data)
    {
        $valid = parent::isValid($data);
        if ( ! $data['mail'] && ! $data['telephone'] && ! $data['postcode'] ){
            $this->addError('Please supply one of email, telephone or postcode');
            $valid = false;
        }
        return $valid;
    }

    //...

}

One small function, ties in with the form, easy to understand, unlikely to fail, unlikely to be a source of difficult bugs.

廻憶裏菂餘溫 2024-12-01 03:07:09

去掉

$foo->setRequired();

按要求把不想设置的两个方法

$telephone->setLabel('Telephone:')
          ->setAttrib('size', 50)
          ->addValidator('StringLength', false, array(10, 10))
          ->setRequired(true);

....就变成了

$telephone->setLabel('Telephone:')
          ->setAttrib('size', 50)
          ->addValidator('StringLength', false, array(10, 10));

Remove the

$foo->setRequired();

method from the two that you don't want to set as required....

$telephone->setLabel('Telephone:')
          ->setAttrib('size', 50)
          ->addValidator('StringLength', false, array(10, 10))
          ->setRequired(true);

becomes

$telephone->setLabel('Telephone:')
          ->setAttrib('size', 50)
          ->addValidator('StringLength', false, array(10, 10));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文