2

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?

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • possible duplicate of [Zend Validate PostCode in a Zend Form -> Validate depending on given country](http://stackoverflow.com/questions/5992569/zend-validate-postcode-in-a-zend-form-validate-depending-on-given-country) – Phil Nov 07 '11 at 06:40

2 Answers2

5

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"

Phil
  • 157,677
  • 23
  • 242
  • 245
1

I think this link may help you. Zend Form Edit and Zend_Validate_Db_NoRecordExists

You have to user Db no record exist but for edit you can specify the exclude attribute in validation.

Community
  • 1
  • 1
rkj
  • 8,067
  • 2
  • 27
  • 33