Skip to content

Commit

Permalink
Merge pull request #440 from hung202028/Fix-Deprecated-Creation-Dynam…
Browse files Browse the repository at this point in the history
…ic-zfBreakChainOnFailure

Fix PHP Deprecated: Creation of dynamic property $zfBreakChainOnFailure from Zend_Form_Element
  • Loading branch information
develart-projects authored Oct 15, 2024
2 parents 98b1405 + 0d5e9d5 commit 1b174a2
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 28 deletions.
65 changes: 49 additions & 16 deletions library/Zend/Form/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ class Zend_Form_Element implements Zend_Validate_Interface
*/
protected $_validators = [];

/**
* Flags to break validation chain on failure.
* @var array
*/
protected $_validatorBreakChainOnFailures = [];

/**
* Array of un-initialized validators
* @var array
Expand Down Expand Up @@ -330,13 +336,13 @@ public function loadDefaultDecorators()
$decorators = $this->getDecorators();
if (empty($decorators)) {
$this->addDecorator('ViewHelper')
->addDecorator('Errors')
->addDecorator('Description', ['tag' => 'p', 'class' => 'description'])
->addDecorator('HtmlTag', [
'tag' => 'dd',
'id' => ['callback' => [get_class($this), 'resolveElementId']]
])
->addDecorator('Label', ['tag' => 'dt']);
->addDecorator('Errors')
->addDecorator('Description', ['tag' => 'p', 'class' => 'description'])
->addDecorator('HtmlTag', [
'tag' => 'dd',
'id' => ['callback' => [get_class($this), 'resolveElementId']]
])
->addDecorator('Label', ['tag' => 'dt']);
}
return $this;
}
Expand Down Expand Up @@ -1224,17 +1230,15 @@ public function addValidator($validator, $breakChainOnFailure = false, $options
{
if ($validator instanceof Zend_Validate_Interface) {
$name = get_class($validator);

if (!isset($validator->zfBreakChainOnFailure)) {
$validator->zfBreakChainOnFailure = $breakChainOnFailure;
}
$this->_validatorBreakChainOnFailures[$name] = $breakChainOnFailure;
} elseif (is_string($validator)) {
$name = $validator;
$validator = [
'validator' => $validator,
'breakChainOnFailure' => $breakChainOnFailure,
'options' => $options,
];
$this->_validatorBreakChainOnFailures[$name] = $breakChainOnFailure;
} else {
require_once 'Zend/Form/Exception.php';
throw new Zend_Form_Exception('Invalid validator provided to addValidator; must be string or Zend_Validate_Interface');
Expand All @@ -1256,9 +1260,18 @@ public function addValidators(array $validators)
{
foreach ($validators as $validatorInfo) {
if (is_string($validatorInfo)) {
$this->addValidator($validatorInfo);
if (isset($this->_validatorBreakChainOnFailures[$validatorInfo])) {
$this->addValidator($validatorInfo, $this->_validatorBreakChainOnFailures[$validatorInfo]);
} else {
$this->addValidator($validatorInfo);
}
} elseif ($validatorInfo instanceof Zend_Validate_Interface) {
$this->addValidator($validatorInfo);
$className = get_class($validatorInfo);
if (isset($this->_validatorBreakChainOnFailures[$className])) {
$this->addValidator($validatorInfo, $this->_validatorBreakChainOnFailures[$className]);
} else {
$this->addValidator($validatorInfo);
}
} elseif (is_array($validatorInfo)) {
$argc = count($validatorInfo);
$breakChainOnFailure = false;
Expand Down Expand Up @@ -1368,6 +1381,7 @@ public function removeValidator($name)
{
if (isset($this->_validators[$name])) {
unset($this->_validators[$name]);
$this->_removeBreakChainOnFailure($name);
} else {
$len = strlen($name);
foreach (array_keys($this->_validators) as $validator) {
Expand All @@ -1376,6 +1390,7 @@ public function removeValidator($name)
}
if (0 === substr_compare($validator, $name, -$len, $len, true)) {
unset($this->_validators[$validator]);
$this->_removeBreakChainOnFailure($validator);
break;
}
}
Expand All @@ -1392,6 +1407,7 @@ public function removeValidator($name)
public function clearValidators()
{
$this->_validators = [];
$this->_validatorBreakChainOnFailures = [];
return $this;
}

Expand Down Expand Up @@ -1428,7 +1444,9 @@ public function isValid($value, $context = null)
$validators = $this->getValidators();
$notEmpty = ['validator' => 'NotEmpty', 'breakChainOnFailure' => true];
array_unshift($validators, $notEmpty);
$this->setValidators($validators);

$this->_validators = [];
$this->addValidators($validators);
}

// Find the correct translator. Zend_Validate_Abstract::getDefaultTranslator()
Expand Down Expand Up @@ -1507,7 +1525,8 @@ public function isValid($value, $context = null)
$this->_messages = array_merge($this->_messages, $messages);
$this->_errors = array_merge($this->_errors, $errors);

if ($validator->zfBreakChainOnFailure) {
$breakChainFailure = isset($this->_validatorBreakChainOnFailures[$key]) ? $this->_validatorBreakChainOnFailures[$key] : false;
if ($breakChainFailure) {
break;
}
}
Expand Down Expand Up @@ -2096,6 +2115,7 @@ public function removeDecorator($name)
public function clearDecorators()
{
$this->_decorators = [];
$this->_validatorBreakChainOnFailures = [];
return $this;
}

Expand Down Expand Up @@ -2244,7 +2264,8 @@ protected function _loadValidator(array $validator)
$instance->setMessage($messages);
}
}
$instance->zfBreakChainOnFailure = $validator['breakChainOnFailure'];

$this->_validatorBreakChainOnFailures[get_class($instance)] = $validator['breakChainOnFailure'];

if ($origName != $name) {
$validatorNames = array_keys($this->_validators);
Expand Down Expand Up @@ -2352,4 +2373,16 @@ protected function _hasErrorMessages()
{
return !empty($this->_errorMessages);
}

/**
* Remove breakChainOnFailure from this validator
* @param string $validator
* @return void
*/
protected function _removeBreakChainOnFailure(string $validator)
{
if (isset($this->_validatorBreakChainOnFailures[$validator])) {
unset($this->_validatorBreakChainOnFailures[$validator]);
}
}
}
36 changes: 24 additions & 12 deletions tests/Zend/Form/ElementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ protected function tear_down()
{
}

protected function isBreakChainOnFailure(Zend_Form_Element $element, string $validator)
{
$reflection = new ReflectionClass($element);
$property = $reflection->getProperty('_validatorBreakChainOnFailures');
$property->setAccessible(true);
$breakChainOnFailures = $property->getValue($element);

return isset($breakChainOnFailures[$validator]) ? $breakChainOnFailures[$validator] : false;
}

public function getView()
{
$view = new Zend_View();
Expand Down Expand Up @@ -325,7 +335,7 @@ public function testIsValidInsertsNotEmptyValidatorWhenElementIsRequiredByDefaul
$this->assertFalse($this->element->isValid(''));
$validator = $this->element->getValidator('NotEmpty');
$this->assertTrue($validator instanceof Zend_Validate_NotEmpty);
$this->assertTrue($validator->zfBreakChainOnFailure);
$this->assertTrue($this->isBreakChainOnFailure($this->element, get_class($validator)));
}

/**
Expand All @@ -344,9 +354,9 @@ public function testBreakChainOnFailureFlagsForExistingValidatorsRemainSetWhenNo
$form->isValid(['username' => '#']);

$validator = $username->getValidator('stringLength');
$this->assertTrue($validator->zfBreakChainOnFailure);
$this->assertTrue($this->isBreakChainOnFailure($username, get_class($validator)));
$validator = $username->getValidator('regex');
$this->assertTrue($validator->zfBreakChainOnFailure);
$this->assertTrue($this->isBreakChainOnFailure($username, get_class($validator)));
}

public function testAutoInsertNotEmptyValidatorFlagTrueByDefault()
Expand Down Expand Up @@ -702,7 +712,7 @@ public function testCanAddSingleValidatorAsString()
$this->element->addValidator('digits');
$validator = $this->element->getValidator('digits');
$this->assertTrue($validator instanceof Zend_Validate_Digits, var_export($validator, 1));
$this->assertFalse($validator->zfBreakChainOnFailure);
$this->assertFalse($this->isBreakChainOnFailure($this->element, get_class($validator)));
}

public function testCanNotRetrieveSingleValidatorRegisteredAsStringUsingClassName()
Expand All @@ -722,7 +732,8 @@ public function testCanAddSingleValidatorAsValidatorObject()
$this->element->addValidator($validator);
$test = $this->element->getValidator('Zend_Validate_Digits');
$this->assertSame($validator, $test);
$this->assertFalse($validator->zfBreakChainOnFailure);
$this->assertFalse($this->isBreakChainOnFailure($this->element, get_class($validator)));
$this->assertFalse($this->isBreakChainOnFailure($this->element, get_class($test)));
}

public function testOptionsAreCastToArrayWhenAddingValidator()
Expand Down Expand Up @@ -750,7 +761,8 @@ public function testCanRetrieveSingleValidatorRegisteredAsValidatorObjectUsingSh
$this->element->addValidator($validator);
$test = $this->element->getValidator('digits');
$this->assertSame($validator, $test);
$this->assertFalse($validator->zfBreakChainOnFailure);
$this->assertFalse($this->isBreakChainOnFailure($this->element, get_class($validator)));
$this->assertFalse($this->isBreakChainOnFailure($this->element, get_class($test)));
}

public function testRetrievingNamedValidatorShouldNotReorderValidators()
Expand Down Expand Up @@ -1736,10 +1748,10 @@ public function testSetOptionsSetsArrayOfArrayValidators()
$this->element->setOptions($options);
$validator = $this->element->getValidator('notEmpty');
$this->assertTrue($validator instanceof Zend_Validate_NotEmpty);
$this->assertTrue($validator->zfBreakChainOnFailure);
$this->assertTrue($this->isBreakChainOnFailure($this->element, get_class($validator)));
$validator = $this->element->getValidator('digits');
$this->assertTrue($validator instanceof Zend_Validate_Digits);
$this->assertTrue($validator->zfBreakChainOnFailure);
$this->assertTrue($this->isBreakChainOnFailure($this->element, get_class($validator)));
}

public function testSetOptionsSetsArrayOfAssociativeArrayValidators()
Expand All @@ -1762,10 +1774,10 @@ public function testSetOptionsSetsArrayOfAssociativeArrayValidators()
$this->element->setOptions($options);
$validator = $this->element->getValidator('notEmpty');
$this->assertTrue($validator instanceof Zend_Validate_NotEmpty);
$this->assertTrue($validator->zfBreakChainOnFailure);
$this->assertTrue($this->isBreakChainOnFailure($this->element, get_class($validator)));
$validator = $this->element->getValidator('digits');
$this->assertTrue($validator instanceof Zend_Validate_Digits);
$this->assertTrue($validator->zfBreakChainOnFailure);
$this->assertTrue($this->isBreakChainOnFailure($this->element, get_class($validator)));
}

public function testSetOptionsSetsArrayOfStringFilters()
Expand Down Expand Up @@ -2225,9 +2237,9 @@ public function testValidatorByUsingStringNotation()
$form->isValid(['username' => '#']);

$validator = $username->getValidator('stringLength');
$this->assertTrue($validator->zfBreakChainOnFailure);
$this->assertTrue($this->isBreakChainOnFailure($username, get_class($validator)));
$validator = $username->getValidator('regex');
$this->assertTrue($validator->zfBreakChainOnFailure);
$this->assertTrue($this->isBreakChainOnFailure($username, get_class($validator)));
}

/**
Expand Down

0 comments on commit 1b174a2

Please sign in to comment.