How does one create a validator that depends on more than one value for Zend_Form?

I've got a form that has a single text field (for company):

class Cas_Form_Company extends Zend_Form
{

    public function init()
    {
        $this->addElement('hidden', 'id');
        $this->addElement('text', 'name', array('label' => 'Name'));
        $this->addElement('submit', 'submit', array('label' => 'Create'));

        $name = $this->getElement('name');
        $name->addValidator('stringLength', false, array(2,45));
        $name->addValidator(new Cas_Model_Validate_CompanyUnique());

        $this->setMethod('post');
        $this->setAction(Zend_Controller_Front::getInstance()->getBaseUrl() . '/Company/Submit');
    }

    public function SetFromExistingCompany(Cas_Model_Company $company)
    {
        $this->getElement('id')->setValue($company->GetId());
        $this->getElement('name')->setValue($company->GetName());
        $this->getElement('submit')->setLabel('Edit');
        $this->addElement('submit', 'delete', array('label' => 'Delete', 'value' => 'delete'));
    }

    public function Commit()
    {
        if (!$this->valid())
        {
            throw new Exception('Company form is not valid.');
        }

        $data = $this->getValues();
        if (empty($data['id']))
        {
            Cas_Model_Gateway_Company::FindOrCreateByName($data['name']);
        }
        else
        {
            $company = Cas_Model_Gateway_Company::FindById((int)$data['id']);
            $company->SetName($data['name']);
            Cas_Model_Gateway_Company::Commit($company);
        }
    }
}

I've also created a little validator which enforces that I want companies to have unique names:

class Cas_Model_Validate_CompanyUnique extends Zend_Validate_Abstract
{
    protected $_messageTemplates = array(
        'exists' => '\'%value%\' is already a company.'
    );

    /**
     * @param string $value
     * @return bool
     */
    public function isValid($value)
    {
        $this->_setValue($value);
        $company = Cas_Model_Gateway_Company::FindByName($value);
        if ($company)
        {
            $this->_error('exists');
            return false;
        }

        return true;
    }
}

Now, this works just fine for creating new companies. The problem comes in when I want to allow editing of companies. This is because for an edit operation, while the company name needs to be unique, a form containing the name already pertaining to the given ID isn't an edit at all (and therefore is valid). That is, the form is valid if either the name doesn't already exist in the database, or the name given matches the name already assigned to that ID.

However, writing this as a validator seems to be problematic, because the validator only gets the value it's working on -- not the ID in question.

How does one write a validator for this sort of thing?

Answers


You can use the poorly documented second $context argument to isValid().

See http://framework.zend.com/manual/en/zend.form.elements.html#zend.form.elements.validators and scroll down to the note "Validation Context"


Need Your Help

Trigger jquery mobile page transition from function

jquery jquery-mobile

Is it possible to navigate from one page to another using jquery mobile page transition?

jScrollPane theme with CSS

jquery css jquery-plugins jscrollpane jquery-jscrollpane

I want to apologize now for my bad english, i hope you will understand what i want:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.