From fe14630b7b92fbc818247bbf4d85f566f9de7e21 Mon Sep 17 00:00:00 2001 From: vahid sohrabloo Date: Sun, 12 Feb 2012 11:57:32 +0330 Subject: [PATCH 001/332] security fix in application - Prevent to create object from any controller name matched from router --- library/Zend/Mvc/Application.php | 36 ++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/library/Zend/Mvc/Application.php b/library/Zend/Mvc/Application.php index 9c89ff010d1..de991752bfa 100644 --- a/library/Zend/Mvc/Application.php +++ b/library/Zend/Mvc/Application.php @@ -261,15 +261,13 @@ public function dispatch(MvcEvent $e) $routeMatch = $e->getRouteMatch(); $controllerName = $routeMatch->getParam('controller', 'not-found'); - - try { - $controller = $locator->get($controllerName); - } catch (ClassNotFoundException $exception) { + $im=$locator->instanceManager(); + if(!$im->hasAlias($controllerName)) + { + $error = clone $e; $error->setError(static::ERROR_CONTROLLER_NOT_FOUND) - ->setController($controllerName) - ->setParam('exception', $exception); - + ->setController($controllerName); $results = $events->trigger('dispatch.error', $error); if (count($results)) { $return = $results->last(); @@ -279,11 +277,14 @@ public function dispatch(MvcEvent $e) goto complete; } - if (!$controller instanceof Dispatchable) { + $controllerClass=$im->getClassFromAlias($controllerName); + $reflection = new \ReflectionClass($controllerClass); + if(!$reflection->implementsInterface('Zend\Stdlib\Dispatchable')) + { $error = clone $e; $error->setError(static::ERROR_CONTROLLER_INVALID) ->setController($controllerName) - ->setControllerClass(get_class($controller)); + ->setControllerClass($controllerClass); $results = $events->trigger('dispatch.error', $error); if (count($results)) { @@ -293,6 +294,23 @@ public function dispatch(MvcEvent $e) } goto complete; } + + try { + $controller = $locator->get($controllerName); + } catch (ClassNotFoundException $exception) { + $error = clone $e; + $error->setError(static::ERROR_CONTROLLER_NOT_FOUND) + ->setController($controllerName) + ->setParam('exception', $exception); + + $results = $events->trigger('dispatch.error', $error); + if (count($results)) { + $return = $results->last(); + } else { + $return = $error->getParams(); + } + goto complete; + } if ($controller instanceof LocatorAware) { $controller->setLocator($locator); From 4eb333b0139148834daa746e3012f19f2e595684 Mon Sep 17 00:00:00 2001 From: Chris Testroet Date: Tue, 26 Jun 2012 15:23:37 -0700 Subject: [PATCH 002/332] Added Math\BigInteger::abs() --- .../Math/BigInteger/Adapter/AdapterInterface.php | 8 ++++++++ library/Zend/Math/BigInteger/Adapter/Bcmath.php | 14 ++++++++++++++ library/Zend/Math/BigInteger/Adapter/Gmp.php | 12 ++++++++++++ tests/Zend/Math/BigInteger/Adapter/BcmathTest.php | 6 ++++++ tests/Zend/Math/BigInteger/Adapter/GmpTest.php | 5 +++++ 5 files changed, 45 insertions(+) diff --git a/library/Zend/Math/BigInteger/Adapter/AdapterInterface.php b/library/Zend/Math/BigInteger/Adapter/AdapterInterface.php index 9c61913cfd4..5f438f5bba0 100644 --- a/library/Zend/Math/BigInteger/Adapter/AdapterInterface.php +++ b/library/Zend/Math/BigInteger/Adapter/AdapterInterface.php @@ -85,6 +85,14 @@ public function pow($operand, $exp); */ public function sqrt($operand); + /** + * Get absolute value of a big integer + * + * @param string $operand + * @return string + */ + public function abs($operand); + /** * Get modulus of a big integer * diff --git a/library/Zend/Math/BigInteger/Adapter/Bcmath.php b/library/Zend/Math/BigInteger/Adapter/Bcmath.php index 1114091a856..30c21ebb9c6 100644 --- a/library/Zend/Math/BigInteger/Adapter/Bcmath.php +++ b/library/Zend/Math/BigInteger/Adapter/Bcmath.php @@ -157,6 +157,20 @@ public function sqrt($operand) return bcsqrt($operand); } + /** + * Get absolute value of a big integer + * + * @param string $operand + * @return string + */ + public function abs($operand) + { + if ('-' == $operand[0]) { + return substr($operand, 1); + } + return $operand; + } + /** * Get modulus of a big integer * diff --git a/library/Zend/Math/BigInteger/Adapter/Gmp.php b/library/Zend/Math/BigInteger/Adapter/Gmp.php index af91878ef67..200352c1a2c 100644 --- a/library/Zend/Math/BigInteger/Adapter/Gmp.php +++ b/library/Zend/Math/BigInteger/Adapter/Gmp.php @@ -138,6 +138,18 @@ public function sqrt($operand) return gmp_strval($result); } + /** + * Get absolute value of a big integer + * + * @param string $operand + * @return string + */ + public function abs($operand) + { + $result = gmp_abs($operand); + return gmp_strval($result); + } + /** * Get modulus of a big integer * diff --git a/tests/Zend/Math/BigInteger/Adapter/BcmathTest.php b/tests/Zend/Math/BigInteger/Adapter/BcmathTest.php index d63d4686aad..ae6bf0fb4b6 100644 --- a/tests/Zend/Math/BigInteger/Adapter/BcmathTest.php +++ b/tests/Zend/Math/BigInteger/Adapter/BcmathTest.php @@ -146,6 +146,12 @@ public function testSqrt() $this->assertEquals('2', $this->adapter->sqrt('4')); } + public function testAbs() + { + $this->assertSame('1152921504606847103.14159', $this->adapter->abs('1152921504606847103.14159')); + $this->assertSame('1152921504606847103.14159', $this->adapter->abs('-1152921504606847103.14159')); + } + public function testIntegerToBinaryConversion() { // zero diff --git a/tests/Zend/Math/BigInteger/Adapter/GmpTest.php b/tests/Zend/Math/BigInteger/Adapter/GmpTest.php index 7666a0ff4be..e67eb1a26e0 100644 --- a/tests/Zend/Math/BigInteger/Adapter/GmpTest.php +++ b/tests/Zend/Math/BigInteger/Adapter/GmpTest.php @@ -151,6 +151,11 @@ public function testSqrt() $this->assertEquals('2', $this->adapter->sqrt('4')); } + public function testAbs() + { + $this->assertSame('1152921504606847103.14159', $this->adapter->abs('1152921504606847103.14159')); + $this->assertSame('1152921504606847103.14159', $this->adapter->abs('-1152921504606847103.14159')); + } public function testIntegerToBinaryConversion() { From 70582b7ba4b5fde05bf92927f393ab50342607db Mon Sep 17 00:00:00 2001 From: Chris Testroet Date: Tue, 26 Jun 2012 18:34:00 -0700 Subject: [PATCH 003/332] Use only integers in the tests --- tests/Zend/Math/BigInteger/Adapter/BcmathTest.php | 4 ++-- tests/Zend/Math/BigInteger/Adapter/GmpTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Zend/Math/BigInteger/Adapter/BcmathTest.php b/tests/Zend/Math/BigInteger/Adapter/BcmathTest.php index ae6bf0fb4b6..f3226b63b46 100644 --- a/tests/Zend/Math/BigInteger/Adapter/BcmathTest.php +++ b/tests/Zend/Math/BigInteger/Adapter/BcmathTest.php @@ -148,8 +148,8 @@ public function testSqrt() public function testAbs() { - $this->assertSame('1152921504606847103.14159', $this->adapter->abs('1152921504606847103.14159')); - $this->assertSame('1152921504606847103.14159', $this->adapter->abs('-1152921504606847103.14159')); + $this->assertSame('1152921504606847103', $this->adapter->abs('1152921504606847103')); + $this->assertSame('1152921504606847103', $this->adapter->abs('-1152921504606847103')); } public function testIntegerToBinaryConversion() diff --git a/tests/Zend/Math/BigInteger/Adapter/GmpTest.php b/tests/Zend/Math/BigInteger/Adapter/GmpTest.php index e67eb1a26e0..05a70a4dee3 100644 --- a/tests/Zend/Math/BigInteger/Adapter/GmpTest.php +++ b/tests/Zend/Math/BigInteger/Adapter/GmpTest.php @@ -153,8 +153,8 @@ public function testSqrt() public function testAbs() { - $this->assertSame('1152921504606847103.14159', $this->adapter->abs('1152921504606847103.14159')); - $this->assertSame('1152921504606847103.14159', $this->adapter->abs('-1152921504606847103.14159')); + $this->assertSame('1152921504606847103', $this->adapter->abs('1152921504606847103')); + $this->assertSame('1152921504606847103', $this->adapter->abs('-1152921504606847103')); } public function testIntegerToBinaryConversion() From eeae5fb9917e1f3a77521143fba1507c03d38d29 Mon Sep 17 00:00:00 2001 From: Chris Testroet Date: Thu, 28 Jun 2012 14:24:50 -0700 Subject: [PATCH 004/332] Added tests Platform\Postgresql --- .../Db/Adapter/Platform/PostgresqlTest.php | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 tests/Zend/Db/Adapter/Platform/PostgresqlTest.php diff --git a/tests/Zend/Db/Adapter/Platform/PostgresqlTest.php b/tests/Zend/Db/Adapter/Platform/PostgresqlTest.php new file mode 100644 index 00000000000..0b5702e3126 --- /dev/null +++ b/tests/Zend/Db/Adapter/Platform/PostgresqlTest.php @@ -0,0 +1,109 @@ +platform = new Postgresql; + } + + /** + * Tears down the fixture, for example, closes a network connection. + * This method is called after a test is executed. + */ + protected function tearDown() + { + } + + /** + * @covers Zend\Db\Adapter\Platform\Postgresql::getName + */ + public function testGetName() + { + $this->assertEquals('PostgreSQL', $this->platform->getName()); + } + + /** + * @covers Zend\Db\Adapter\Platform\Postgresql::getQuoteIdentifierSymbol + */ + public function testGetQuoteIdentifierSymbol() + { + $this->assertEquals('"', $this->platform->getQuoteIdentifierSymbol()); + } + + /** + * @covers Zend\Db\Adapter\Platform\Postgresql::quoteIdentifier + */ + public function testQuoteIdentifier() + { + $this->assertEquals('"identifier"', $this->platform->quoteIdentifier('identifier')); + } + + /** + * @covers Zend\Db\Adapter\Platform\Postgresql::quoteIdentifierChain + */ + public function testQuoteIdentifierChain() + { + $this->assertEquals('"identifier"', $this->platform->quoteIdentifierChain('identifier')); + $this->assertEquals('"identifier"', $this->platform->quoteIdentifierChain(array('identifier'))); + $this->assertEquals('"schema"."identifier"', $this->platform->quoteIdentifierChain(array('schema','identifier'))); + } + + /** + * @covers Zend\Db\Adapter\Platform\Postgresql::getQuoteValueSymbol + */ + public function testGetQuoteValueSymbol() + { + $this->assertEquals("'", $this->platform->getQuoteValueSymbol()); + } + + /** + * @covers Zend\Db\Adapter\Platform\Postgresql::quoteValue + */ + public function testQuoteValue() + { + $this->assertEquals("'value'", $this->platform->quoteValue('value')); + } + + /** + * @covers Zend\Db\Adapter\Platform\Postgresql::quoteValueList + */ + public function testQuoteValueList() + { + $this->assertEquals("'Foo O\\'Bar'", $this->platform->quoteValueList("Foo O'Bar")); + $this->assertEquals("'Foo O\\'Bar'", $this->platform->quoteValueList(array("Foo O'Bar"))); + $this->assertEquals("'value', 'Foo O\\'Bar'", $this->platform->quoteValueList(array('value',"Foo O'Bar"))); + } + + /** + * @covers Zend\Db\Adapter\Platform\Postgresql::getIdentifierSeparator + */ + public function testGetIdentifierSeparator() + { + $this->assertEquals('.', $this->platform->getIdentifierSeparator()); + } + + /** + * @covers Zend\Db\Adapter\Platform\Postgresql::quoteIdentifierInFragment + */ + public function testQuoteIdentifierInFragment() + { + $this->assertEquals('"foo"."bar"', $this->platform->quoteIdentifierInFragment('foo.bar')); + $this->assertEquals('"foo" as "bar"', $this->platform->quoteIdentifierInFragment('foo as bar')); + } +} From 6e31afeb0abbfb53e2f3f64b927aed5e64790e4c Mon Sep 17 00:00:00 2001 From: Ben Scholzen Date: Mon, 2 Jul 2012 12:52:28 +0200 Subject: [PATCH 005/332] Make date formatting helper more user friendly --- library/Zend/I18n/View/Helper/DateFormat.php | 70 ++++++++++++++++---- 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/library/Zend/I18n/View/Helper/DateFormat.php b/library/Zend/I18n/View/Helper/DateFormat.php index a870bcde362..c2c2c250ec8 100644 --- a/library/Zend/I18n/View/Helper/DateFormat.php +++ b/library/Zend/I18n/View/Helper/DateFormat.php @@ -23,6 +23,7 @@ use DateTime; use IntlDateFormatter; +use Locale; use Zend\View\Helper\AbstractHelper; use Zend\I18n\Exception; @@ -37,6 +38,13 @@ */ class DateFormat extends AbstractHelper { + /** + * Timezone to use. + * + * @var string + */ + protected $timezone; + /** * Formatter instances. * @@ -44,6 +52,30 @@ class DateFormat extends AbstractHelper */ protected $formatters = array(); + /** + * Set timezone to use instead of the default. + * + * @param string $timezone + */ + public function setTimezone($timezone) + { + $this->timezone = (string) $timezone; + + foreach ($this->formatters as $formatter) { + $formatter->setTimeZoneId($this->timezone); + } + } + + /** + * Get a new timezone. + * + * @return string|null + */ + public function getTimezone() + { + return $this->timezone; + } + /** * Add a formatter. * @@ -61,27 +93,39 @@ public function addFormatter($name, IntlDateFormatter $formatter) * Format a date. * * @param DateTime|integer|array $date - * @param string $formatterName + * @param integer $dateType + * @param integer $timeType + * @param string $locale * @return string * @throws Exception\RuntimeException */ - public function __invoke($date, $formatterName) - { - if (!isset($this->formatters[$formatterName])) { - throw new Exception\RuntimeException(sprintf( - 'No formatter with name %s found', - $formatterName - )); + public function __invoke( + $date, + $dateType = IntlDateFormatter::NONE, + $timeType = IntlDateFormatter::NONE, + $locale = null + ) { + if ($locale === null) { + $locale = Locale::getDefault(); + } + + $timezone = $this->getTimezone(); + $formatterId = md5($dateType . "\0" . $timeType . "\0" . $locale); + + if (!isset($this->formatters[$formatterId])) { + $this->formatters[$formatterId] = new IntlDateFormatter( + $locale, + $dateType, + $timeType, + $timezone + ); } // DateTime support for IntlDateFormatter::format() was only added in 5.3.4 - if ($date instanceof DateTime - && version_compare(PHP_VERSION, '5.3.4', '<')) - { + if ($date instanceof DateTime && version_compare(PHP_VERSION, '5.3.4', '<')) { $date = $date->getTimestamp(); } - return $this->formatters[$formatterName] - ->format($date); + return $this->formatters[$formatterId]->format($date); } } From 39dbb0ca7de7cfdcde2fc83be871af34955f35ea Mon Sep 17 00:00:00 2001 From: Ben Scholzen Date: Mon, 2 Jul 2012 13:23:19 +0200 Subject: [PATCH 006/332] Removed old addFormatter method --- library/Zend/I18n/View/Helper/DateFormat.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/library/Zend/I18n/View/Helper/DateFormat.php b/library/Zend/I18n/View/Helper/DateFormat.php index c2c2c250ec8..055eafa91b6 100644 --- a/library/Zend/I18n/View/Helper/DateFormat.php +++ b/library/Zend/I18n/View/Helper/DateFormat.php @@ -76,19 +76,6 @@ public function getTimezone() return $this->timezone; } - /** - * Add a formatter. - * - * @param string $name - * @param IntlDateFormatter $formatter - * @return DateFormat - */ - public function addFormatter($name, IntlDateFormatter $formatter) - { - $this->formatters[$name] = $formatter; - return $this; - } - /** * Format a date. * From 189e6f66fb6086213eb7b37b6a29f23c056e0cdd Mon Sep 17 00:00:00 2001 From: Ben Scholzen Date: Mon, 2 Jul 2012 13:35:31 +0200 Subject: [PATCH 007/332] Add locale setter and getter for DateFormat helper --- library/Zend/I18n/View/Helper/DateFormat.php | 35 ++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/library/Zend/I18n/View/Helper/DateFormat.php b/library/Zend/I18n/View/Helper/DateFormat.php index 055eafa91b6..9c45e62d840 100644 --- a/library/Zend/I18n/View/Helper/DateFormat.php +++ b/library/Zend/I18n/View/Helper/DateFormat.php @@ -38,6 +38,13 @@ */ class DateFormat extends AbstractHelper { + /** + * Locale to use instead of the default. + * + * @var string + */ + protected $locale; + /** * Timezone to use. * @@ -67,7 +74,7 @@ public function setTimezone($timezone) } /** - * Get a new timezone. + * Get the timezone to use. * * @return string|null */ @@ -76,6 +83,30 @@ public function getTimezone() return $this->timezone; } + /** + * Set locale to use instead of the default. + * + * @param string $locale + */ + public function setlocale($locale) + { + $this->locale = (string) $locale; + } + + /** + * Get the locale to use. + * + * @return string|null + */ + public function getlocale() + { + if ($this->locale === null) { + $this->locale = Locale::getDefault(); + } + + return $this->locale; + } + /** * Format a date. * @@ -93,7 +124,7 @@ public function __invoke( $locale = null ) { if ($locale === null) { - $locale = Locale::getDefault(); + $locale = $this->getlocale(); } $timezone = $this->getTimezone(); From a6d8d664caa000457cafdad97ecdc1abf262b5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michae=CC=88l=20Gallego?= Date: Mon, 2 Jul 2012 21:15:31 +0200 Subject: [PATCH 008/332] Options --- library/Zend/Form/Element.php | 67 +++++++++- library/Zend/Form/Element/Captcha.php | 30 +++-- library/Zend/Form/Element/Collection.php | 140 ++++++++++++-------- library/Zend/Form/ElementInterface.php | 8 ++ library/Zend/Form/Factory.php | 9 +- library/Zend/Form/View/Helper/FormLabel.php | 2 +- library/Zend/Form/View/Helper/FormRow.php | 2 +- 7 files changed, 186 insertions(+), 72 deletions(-) diff --git a/library/Zend/Form/Element.php b/library/Zend/Form/Element.php index 965ee19359a..0ff4ec4bba7 100644 --- a/library/Zend/Form/Element.php +++ b/library/Zend/Form/Element.php @@ -21,6 +21,7 @@ namespace Zend\Form; use Traversable; +use Zend\Stdlib\ArrayUtils; /** * @category Zend @@ -35,6 +36,11 @@ class Element implements ElementInterface */ protected $attributes = array(); + /** + * @var string + */ + protected $label; + /** * @var array Validation error messages */ @@ -42,15 +48,19 @@ class Element implements ElementInterface /** - * Constructor - * - * @param null|string|int $name Optional name for the element + * @param null|int|string $name Optional name for the element + * @param array $options Optional options for the element + * @throws Exception\InvalidArgumentException */ - public function __construct($name = null) + public function __construct($name = null, $options = array()) { if (null !== $name) { $this->setName($name); } + + if (!empty($options)) { + $this->setOptions($options); + } } /** @@ -75,6 +85,30 @@ public function getName() return $this->getAttribute('name'); } + /** + * Set options for an element + * + * @param array|\Traversable $options + * @return Element|ElementInterface + * @throws Exception\InvalidArgumentException + */ + public function setOptions($options) + { + if ($options instanceof Traversable) { + $options = ArrayUtils::iteratorToArray($options); + } elseif (!is_array($options)) { + throw new Exception\InvalidArgumentException( + 'The options parameter must be an array or a Traversable' + ); + } + + if (isset($options['label'])) { + $this->setLabel($options['label']); + } + + return $this; + } + /** * Set a single element attribute * @@ -157,6 +191,31 @@ public function clearAttributes() $this->attributes = array(); } + /** + * Set the label used for this element + * + * @param $label + * @return Element + */ + public function setLabel($label) + { + if (is_string($label)) { + $this->label = $label; + } + + return $this; + } + + /** + * Retrieve the label used for this element + * + * @return string + */ + public function getLabel() + { + return $this->label; + } + /** * Set a list of messages to report when validation fails * diff --git a/library/Zend/Form/Element/Captcha.php b/library/Zend/Form/Element/Captcha.php index 6973856ac69..55850f4f030 100644 --- a/library/Zend/Form/Element/Captcha.php +++ b/library/Zend/Form/Element/Captcha.php @@ -37,19 +37,26 @@ class Captcha extends Element implements InputProviderInterface { /** - * Set a single element attribute + * @var \Zend\Captcha\AdapterInterface + */ + protected $captcha; + + /** + * Accepted options for Captcha: + * - captcha: a valid Zend\Captcha\AdapterInterface * - * @param string $key - * @param mixed $value - * @return Element + * @param array|\Traversable $options + * @return Captcha */ - public function setAttribute($key, $value) + public function setOptions($options) { - if ('captcha' == strtolower($key)) { - $this->setCaptcha($value); - return $this; + parent::setOptions($options); + + if (isset($options['captcha'])) { + $this->setCaptcha($options['captcha']); } - return parent::setAttribute($key, $value); + + return $this; } /** @@ -69,7 +76,8 @@ public function setCaptcha($captcha) (is_object($captcha) ? get_class($captcha) : gettype($captcha)) )); } - $this->attributes['captcha'] = $captcha; + $this->captcha = $captcha; + return $this; } @@ -80,7 +88,7 @@ public function setCaptcha($captcha) */ public function getCaptcha() { - return $this->getAttribute('captcha'); + return $this->captcha; } /** diff --git a/library/Zend/Form/Element/Collection.php b/library/Zend/Form/Element/Collection.php index 441c72f5ca4..854e87427fd 100644 --- a/library/Zend/Form/Element/Collection.php +++ b/library/Zend/Form/Element/Collection.php @@ -45,45 +45,77 @@ class Collection extends Fieldset implements InputFilterProviderInterface const DEFAULT_TEMPLATE_PLACEHOLDER = '__index__'; /** - * Constructor + * Element used in the collection + * + * @var ElementInterface */ - public function __construct() - { - $this->setCount(1); - $this->setAllowAdd(true); - $this->setTemplatePlaceholder(self::DEFAULT_TEMPLATE_PLACEHOLDER); + protected $targetElement; + + /** + * Initial count of target element + * + * @var int + */ + protected $count = 1; + + /** + * Are new elements allowed to be added dynamically ? + * + * @var bool + */ + protected $allowAdd = true; + + /** + * Is the template generated ? + * + * @var bool + */ + protected $shouldCreateTemplate = false; + + /** + * Placeholder used in template content for making your life easier with JavaScript + * + * @var string + */ + protected $templatePlaceholder = self::DEFAULT_TEMPLATE_PLACEHOLDER; - parent::__construct(); - } /** - * Set a single element attribute + * Accepted options for Collection: + * - targetElement: an array or element used in the collection + * - count: number of times the element is added initially + * - allowAdd: if set to true, elements can be added to the form dynamically (using JavaScript) + * - shouldCreateTemplate: if set to true, a template is generated (inside a ) + * - templatePlaceholder: placeholder used in the data template * - * @param string $key - * @param mixed $value - * @return Element|ElementInterface + * @param array|\Traversable $options + * @return Collection */ - public function setAttribute($key, $value) + public function setOptions($options) { - switch(strtolower($key)) { - case 'count': - $this->setCount($value); - return $this; - case 'targetelement': - $this->setTargetElement($value); - return $this; - case 'allowadd': - $this->setAllowAdd($value); - return $this; - case 'shouldcreatetemplate': - $this->setShouldCreateTemplate($value); - return $this; - case 'templateplaceholder': - $this->setTemplatePlaceholder($value); - return $this; + parent::setOptions($options); + + if (isset($options['target_element'])) { + $this->setTargetElement($options['target_element']); + } + + if (isset($options['count'])) { + $this->setCount($options['count']); } - return parent::setAttribute($key, $value); + if (isset($options['allow_add'])) { + $this->setAllowAdd($options['allow_add']); + } + + if (isset($options['should_create_template'])) { + $this->setShouldCreateTemplate($options['should_create_template']); + } + + if (isset($options['template_placeholder'])) { + $this->setTemplatePlaceholder($options['template_placeholder']); + } + + return $this; } /** @@ -93,9 +125,9 @@ public function setAttribute($key, $value) */ public function populateValues($data) { - $count = $this->getCount(); + $count = $this->count; - if ($this->getTargetElement() instanceof FieldsetInterface) { + if ($this->targetElement instanceof FieldsetInterface) { foreach ($data as $key => $value) { if ($count > 0) { $this->fieldsets[$key]->populateValues($value); @@ -118,9 +150,9 @@ public function populateValues($data) } // If there are still data, this means that elements or fieldsets were dynamically added. If allowed by the user, add them - if (!empty($data) && $this->getAllowAdd()) { + if (!empty($data) && $this->allowAdd) { foreach ($data as $key => $value) { - $elementOrFieldset = clone $this->getTargetElement(); + $elementOrFieldset = clone $this->targetElement; $elementOrFieldset->setName($key); if ($elementOrFieldset instanceof FieldsetInterface) { @@ -142,7 +174,7 @@ public function populateValues($data) */ public function setCount($count) { - $this->attributes['count'] = $count > 0 ? $count : 0; + $this->count = $count > 0 ? $count : 0; return $this; } @@ -153,7 +185,7 @@ public function setCount($count) */ public function getCount() { - return $this->getAttribute('count'); + return $this->count; } /** @@ -181,7 +213,7 @@ public function setTargetElement($elementOrFieldset) )); } - $this->attributes['targetElement'] = $elementOrFieldset; + $this->targetElement = $elementOrFieldset; return $this; } @@ -193,7 +225,7 @@ public function setTargetElement($elementOrFieldset) */ public function getTargetElement() { - return $this->getAttribute('targetElement'); + return $this->targetElement; } /** @@ -204,7 +236,7 @@ public function getTargetElement() */ public function setAllowAdd($allowAdd) { - $this->attributes['allowAdd'] = (bool)$allowAdd; + $this->allowAdd = (bool)$allowAdd; return $this; } @@ -215,7 +247,7 @@ public function setAllowAdd($allowAdd) */ public function getAllowAdd() { - return $this->getAttribute('allowAdd'); + return $this->allowAdd; } /** @@ -226,10 +258,10 @@ public function getAllowAdd() */ public function setShouldCreateTemplate($shouldCreateTemplate) { - $this->attributes['shouldCreateTemplate'] = (bool)$shouldCreateTemplate; + $this->shouldCreateTemplate = (bool)$shouldCreateTemplate; // If it doesn't exist yet, create it - if ($shouldCreateTemplate && !$this->has($this->getTemplatePlaceholder())) { + if ($shouldCreateTemplate) { $this->addTemplateElement(); } @@ -243,7 +275,7 @@ public function setShouldCreateTemplate($shouldCreateTemplate) */ public function shouldCreateTemplate() { - return $this->getAttribute('shouldCreateTemplate'); + return $this->shouldCreateTemplate; } /** @@ -255,7 +287,7 @@ public function shouldCreateTemplate() public function setTemplatePlaceholder($templatePlaceholder) { if (is_string($templatePlaceholder)) { - $this->attributes['templatePlaceholder'] = $templatePlaceholder; + $this->templatePlaceholder = $templatePlaceholder; } return $this; @@ -268,7 +300,7 @@ public function setTemplatePlaceholder($templatePlaceholder) */ public function getTemplatePlaceholder() { - return $this->attributes['templatePlaceholder']; + return $this->templatePlaceholder; } /** @@ -278,16 +310,16 @@ public function getTemplatePlaceholder() */ protected function prepareCollection() { - if ($this->getTargetElement() !== null) { - for ($i = 0 ; $i != $this->getCount() ; ++$i) { - $elementOrFieldset = clone $this->getTargetElement(); + if ($this->targetElement !== null) { + for ($i = 0 ; $i != $this->count ; ++$i) { + $elementOrFieldset = clone $this->targetElement; $elementOrFieldset->setName($i); $this->add($elementOrFieldset); } // If a template is wanted, we add a "dummy" element - if ($this->shouldCreateTemplate()) { + if ($this->shouldCreateTemplate) { $this->addTemplateElement(); } } @@ -300,9 +332,9 @@ protected function prepareCollection() */ protected function addTemplateElement() { - if ($this->getTargetElement() !== null) { - $elementOrFieldset = clone $this->getTargetElement(); - $elementOrFieldset->setName($this->getTemplatePlaceholder()); + if ($this->targetElement !== null) { + $elementOrFieldset = clone $this->targetElement; + $elementOrFieldset->setName($this->templatePlaceholder); $this->add($elementOrFieldset); } @@ -318,9 +350,9 @@ protected function addTemplateElement() public function getInputFilterSpecification() { // Ignore any template - if ($this->shouldCreateTemplate()) { + if ($this->shouldCreateTemplate) { return array( - $this->getTemplatePlaceholder() => array( + $this->templatePlaceholder => array( 'required' => false ) ); diff --git a/library/Zend/Form/ElementInterface.php b/library/Zend/Form/ElementInterface.php index ecb948d9462..4c17d2862e0 100644 --- a/library/Zend/Form/ElementInterface.php +++ b/library/Zend/Form/ElementInterface.php @@ -46,6 +46,14 @@ public function setName($name); */ public function getName(); + /** + * Set options for an element + * + * @param array|\Traversable $options + * @return ElementInterface + */ + public function setOptions($options); + /** * Set a single element attribute * diff --git a/library/Zend/Form/Factory.php b/library/Zend/Form/Factory.php index 44eb62c9725..8e12c264a0a 100644 --- a/library/Zend/Form/Factory.php +++ b/library/Zend/Form/Factory.php @@ -124,6 +124,7 @@ public function create($spec) * Specification can contain any of the following: * - type: the Element class to use; defaults to \Zend\Form\Element * - name: what name to provide the element, if any + * - options: an array, Traversable, or ArrayAccess object of element options * - attributes: an array, Traversable, or ArrayAccess object of element * attributes to assign * @@ -138,6 +139,7 @@ public function createElement($spec) $type = isset($spec['type']) ? $spec['type'] : 'Zend\Form\Element'; $name = isset($spec['name']) ? $spec['name'] : null; + $options = isset($spec['options']) ? $spec['options'] : null; $attributes = isset($spec['attributes']) ? $spec['attributes'] : null; $element = new $type(); @@ -149,10 +151,14 @@ public function createElement($spec) )); } - if ($name) { + if (!empty($name)) { $element->setName($name); } + if (is_array($options) || $options instanceof Traversable || $options instanceof ArrayAccess) { + $element->setOptions($options); + } + if (is_array($attributes) || $attributes instanceof Traversable || $attributes instanceof ArrayAccess) { $element->setAttributes($attributes); } @@ -166,6 +172,7 @@ public function createElement($spec) * Specification can contain any of the following: * - type: the Fieldset class to use; defaults to \Zend\Form\Fieldset * - name: what name to provide the fieldset, if any + * - options: an array, Traversable, or ArrayAccess object of element options * - attributes: an array, Traversable, or ArrayAccess object of element * attributes to assign * - elements: an array or Traversable object where each entry is an array diff --git a/library/Zend/Form/View/Helper/FormLabel.php b/library/Zend/Form/View/Helper/FormLabel.php index 6a0ac65977b..d0308a040d0 100644 --- a/library/Zend/Form/View/Helper/FormLabel.php +++ b/library/Zend/Form/View/Helper/FormLabel.php @@ -114,7 +114,7 @@ public function __invoke(ElementInterface $element = null, $labelContent = null, $openTag = $this->openTag($element); $label = false; if (null === $labelContent || null !== $position) { - $label = $element->getAttribute('label'); + $label = $element->getLabel(); if (null === $label) { throw new Exception\DomainException(sprintf( '%s expects either label content as the second argument, or that the element provided has a label attribute; neither found', diff --git a/library/Zend/Form/View/Helper/FormRow.php b/library/Zend/Form/View/Helper/FormRow.php index 30deab11f05..41f4420b39d 100644 --- a/library/Zend/Form/View/Helper/FormRow.php +++ b/library/Zend/Form/View/Helper/FormRow.php @@ -77,7 +77,7 @@ public function render(ElementInterface $element) $labelHelper = $this->getLabelHelper(); $elementHelper = $this->getElementHelper(); $elementErrorsHelper = $this->getElementErrorsHelper(); - $label = $element->getAttribute('label'); + $label = $element->getLabel(); $elementString = $elementHelper->render($element); $elementErrors = $elementErrorsHelper->render($element); From 19a4ceadada1b6348cb7ec81c1b15eb84403b0e4 Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Mon, 2 Jul 2012 15:20:15 -0400 Subject: [PATCH 009/332] [i18n] Iban and PostCode validators --- library/Zend/{ => I18n}/Validator/Iban.php | 47 +- library/Zend/I18n/Validator/PostCode.php | 405 ++++++++++++++++++ library/Zend/Validator/PostCode.php | 227 ---------- .../Zend/Validator/ValidatorPluginManager.php | 8 +- tests/Zend/{ => I18n}/Validator/IbanTest.php | 44 +- .../{ => I18n}/Validator/PostCodeTest.php | 69 ++- 6 files changed, 482 insertions(+), 318 deletions(-) rename library/Zend/{ => I18n}/Validator/Iban.php (88%) create mode 100644 library/Zend/I18n/Validator/PostCode.php delete mode 100644 library/Zend/Validator/PostCode.php rename tests/Zend/{ => I18n}/Validator/IbanTest.php (68%) rename tests/Zend/{ => I18n}/Validator/PostCodeTest.php (76%) diff --git a/library/Zend/Validator/Iban.php b/library/Zend/I18n/Validator/Iban.php similarity index 88% rename from library/Zend/Validator/Iban.php rename to library/Zend/I18n/Validator/Iban.php index f4119f9dd82..b48be40b93c 100644 --- a/library/Zend/Validator/Iban.php +++ b/library/Zend/I18n/Validator/Iban.php @@ -18,11 +18,13 @@ * @license http://framework.zend.com/license/new-bsd New BSD License */ -namespace Zend\Validator; +namespace Zend\I18n\Validator; use Traversable; -use Zend\Locale\Locale; +use Locale; use Zend\Stdlib\ArrayUtils; +use Zend\Validator\AbstractValidator; +use Zend\Validator\Exception; /** * Validates IBAN Numbers (International Bank Account Numbers) @@ -52,7 +54,7 @@ class Iban extends AbstractValidator /** * Optional locale * - * @var string|Locale|null + * @var string|null */ protected $locale; @@ -112,19 +114,14 @@ public function __construct($options = null) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); + } elseif (!is_array($options)) { + $options = func_get_args(); + $temp['locale'] = array_shift($options); + $options = $temp; } - if (is_array($options)) { - if (array_key_exists('locale', $options)) { - $options = $options['locale']; - unset($options['locale']); - } else { - $options = null; - } - } - - if ($options !== null) { - $this->setLocale($options); + if (array_key_exists('locale', $options)) { + $this->setLocale($options['locale']); } parent::__construct($options); @@ -133,7 +130,7 @@ public function __construct($options = null) /** * Returns the locale option * - * @return string|Locale|null + * @return string|null */ public function getLocale() { @@ -143,19 +140,12 @@ public function getLocale() /** * Sets the locale option * - * @param string|Locale $locale + * @param string|null $locale * @return Iban provides a fluent interface * @throws Exception\InvalidArgumentException */ public function setLocale($locale = null) { - if ($locale !== false) { - $locale = Locale::findLocale($locale); - if (strlen($locale) < 4) { - throw new Exception\InvalidArgumentException('Region must be given for IBAN validation'); - } - } - $this->locale = $locale; return $this; } @@ -168,14 +158,21 @@ public function setLocale($locale = null) */ public function isValid($value) { + if (!is_string($value)) { + $this->error(self::INVALID); + return false; + } + $value = strtoupper($value); $this->setValue($value); if (empty($this->locale)) { $region = substr($value, 0, 2); } else { - $region = new Locale($this->locale); - $region = $region->getRegion(); + $region = Locale::getRegion($this->locale); + if ('' === $region) { + throw new Exception\InvalidArgumentException("Invalid locale string given"); + } } if (!array_key_exists($region, $this->ibanregex)) { diff --git a/library/Zend/I18n/Validator/PostCode.php b/library/Zend/I18n/Validator/PostCode.php new file mode 100644 index 00000000000..d5bfc77f807 --- /dev/null +++ b/library/Zend/I18n/Validator/PostCode.php @@ -0,0 +1,405 @@ + "Invalid type given. String or integer expected", + self::NO_MATCH => "The input does not appear to be a postal code", + self::SERVICE => "The input does not appear to be a postal code", + self::SERVICEFAILURE => "An exception has been raised while validating the input.", + ); + + /** + * Optional Locale to use + * + * @var string|null + */ + protected $locale; + + /** + * Optional Manual postal code format + * + * @var string|null + */ + protected $format; + + /** + * Optional Service callback for additional validation + * + * @var mixed|null + */ + protected $service; + + /** + * Postal Code regexes by territory + * + * @var array + */ + protected $postCodeRegex = array( + 'GB' => 'GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}', + 'JE' => 'JE\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}', + 'GG' => 'GY\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}', + 'IM' => 'IM\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}', + 'US' => '\d{5}([ \-]\d{4})?', + 'CA' => '[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ ]?\d[ABCEGHJ-NPRSTV-Z]\d', + 'DE' => '\d{5}', + 'JP' => '\d{3}-\d{4}', + 'FR' => '\d{2}[ ]?\d{3}', + 'AU' => '\d{4}', + 'IT' => '\d{5}', + 'CH' => '\d{4}', + 'AT' => '\d{4}', + 'ES' => '\d{5}', + 'NL' => '\d{4}[ ]?[A-Z]{2}', + 'BE' => '\d{4}', + 'DK' => '\d{4}', + 'SE' => '\d{3}[ ]?\d{2}', + 'NO' => '\d{4}', + 'BR' => '\d{5}[\-]?\d{3}', + 'PT' => '\d{4}([\-]\d{3})?', + 'FI' => '\d{5}', + 'AX' => '22\d{3}', + 'KR' => '\d{3}[\-]\d{3}', + 'CN' => '\d{6}', + 'TW' => '\d{3}(\d{2})?', + 'SG' => '\d{6}', + 'DZ' => '\d{5}', + 'AD' => 'AD\d{3}', + 'AR' => '([A-HJ-NP-Z])?\d{4}([A-Z]{3})?', + 'AM' => '(37)?\d{4}', + 'AZ' => '\d{4}', + 'BH' => '((1[0-2]|[2-9])\d{2})?', + 'BD' => '\d{4}', + 'BB' => '(BB\d{5})?', + 'BY' => '\d{6}', + 'BM' => '[A-Z]{2}[ ]?[A-Z0-9]{2}', + 'BA' => '\d{5}', + 'IO' => 'BBND 1ZZ', + 'BN' => '[A-Z]{2}[ ]?\d{4}', + 'BG' => '\d{4}', + 'KH' => '\d{5}', + 'CV' => '\d{4}', + 'CL' => '\d{7}', + 'CR' => '\d{4,5}|\d{3}-\d{4}', + 'HR' => '\d{5}', + 'CY' => '\d{4}', + 'CZ' => '\d{3}[ ]?\d{2}', + 'DO' => '\d{5}', + 'EC' => '([A-Z]\d{4}[A-Z]|(?:[A-Z]{2})?\d{6})?', + 'EG' => '\d{5}', + 'EE' => '\d{5}', + 'FO' => '\d{3}', + 'GE' => '\d{4}', + 'GR' => '\d{3}[ ]?\d{2}', + 'GL' => '39\d{2}', + 'GT' => '\d{5}', + 'HT' => '\d{4}', + 'HN' => '(?:\d{5})?', + 'HU' => '\d{4}', + 'IS' => '\d{3}', + 'IN' => '\d{6}', + 'ID' => '\d{5}', + 'IE' => '((D|DUBLIN)?([1-9]|6[wW]|1[0-8]|2[024]))?', + 'IL' => '\d{5}', + 'JO' => '\d{5}', + 'KZ' => '\d{6}', + 'KE' => '\d{5}', + 'KW' => '\d{5}', + 'LA' => '\d{5}', + 'LV' => '\d{4}', + 'LB' => '(\d{4}([ ]?\d{4})?)?', + 'LI' => '(948[5-9])|(949[0-7])', + 'LT' => '\d{5}', + 'LU' => '\d{4}', + 'MK' => '\d{4}', + 'MY' => '\d{5}', + 'MV' => '\d{5}', + 'MT' => '[A-Z]{3}[ ]?\d{2,4}', + 'MU' => '(\d{3}[A-Z]{2}\d{3})?', + 'MX' => '\d{5}', + 'MD' => '\d{4}', + 'MC' => '980\d{2}', + 'MA' => '\d{5}', + 'NP' => '\d{5}', + 'NZ' => '\d{4}', + 'NI' => '((\d{4}-)?\d{3}-\d{3}(-\d{1})?)?', + 'NG' => '(\d{6})?', + 'OM' => '(PC )?\d{3}', + 'PK' => '\d{5}', + 'PY' => '\d{4}', + 'PH' => '\d{4}', + 'PL' => '\d{2}-\d{3}', + 'PR' => '00[679]\d{2}([ \-]\d{4})?', + 'RO' => '\d{6}', + 'RU' => '\d{6}', + 'SM' => '4789\d', + 'SA' => '\d{5}', + 'SN' => '\d{5}', + 'SK' => '\d{3}[ ]?\d{2}', + 'SI' => '\d{4}', + 'ZA' => '\d{4}', + 'LK' => '\d{5}', + 'TJ' => '\d{6}', + 'TH' => '\d{5}', + 'TN' => '\d{4}', + 'TR' => '\d{5}', + 'TM' => '\d{6}', + 'UA' => '\d{5}', + 'UY' => '\d{5}', + 'UZ' => '\d{6}', + 'VA' => '00120', + 'VE' => '\d{4}', + 'ZM' => '\d{5}', + 'AS' => '96799', + 'CC' => '6799', + 'CK' => '\d{4}', + 'RS' => '\d{6}', + 'ME' => '8\d{4}', + 'CS' => '\d{5}', + 'YU' => '\d{5}', + 'CX' => '6798', + 'ET' => '\d{4}', + 'FK' => 'FIQQ 1ZZ', + 'NF' => '2899', + 'FM' => '(9694[1-4])([ \-]\d{4})?', + 'GF' => '9[78]3\d{2}', + 'GN' => '\d{3}', + 'GP' => '9[78][01]\d{2}', + 'GS' => 'SIQQ 1ZZ', + 'GU' => '969[123]\d([ \-]\d{4})?', + 'GW' => '\d{4}', + 'HM' => '\d{4}', + 'IQ' => '\d{5}', + 'KG' => '\d{6}', + 'LR' => '\d{4}', + 'LS' => '\d{3}', + 'MG' => '\d{3}', + 'MH' => '969[67]\d([ \-]\d{4})?', + 'MN' => '\d{6}', + 'MP' => '9695[012]([ \-]\d{4})?', + 'MQ' => '9[78]2\d{2}', + 'NC' => '988\d{2}', + 'NE' => '\d{4}', + 'VI' => '008(([0-4]\d)|(5[01]))([ \-]\d{4})?', + 'PF' => '987\d{2}', + 'PG' => '\d{3}', + 'PM' => '9[78]5\d{2}', + 'PN' => 'PCRN 1ZZ', + 'PW' => '96940', + 'RE' => '9[78]4\d{2}', + 'SH' => '(ASCN|STHL) 1ZZ', + 'SJ' => '\d{4}', + 'SO' => '\d{5}', + 'SZ' => '[HLMS]\d{3}', + 'TC' => 'TKCA 1ZZ', + 'WF' => '986\d{2}', + 'YT' => '976\d{2}', + ); + + /** + * Constructor for the PostCode validator + * + * Accepts a string locale and/or "format". + * + * @param string|array|Traversable $options + */ + public function __construct($options = array()) + { + if ($options instanceof Traversable) { + $options = ArrayUtils::iteratorToArray($options); + } elseif (!is_array($options)) { + $options = func_get_args(); + $temp['locale'] = array_shift($options); + $options = $temp; + } + + if (array_key_exists('locale', $options)) { + $this->setLocale($options['locale']); + } else { + $this->setLocale(Locale::getDefault()); + } + if (array_key_exists('format', $options)) { + $this->setFormat($options['format']); + } + if (array_key_exists('service', $options)) { + $this->setService($options['service']); + } + + parent::__construct($options); + } + + /** + * Returns the set locale + * + * @return string|null The set locale + */ + public function getLocale() + { + return $this->locale; + } + + /** + * Sets the locale to use + * + * @param string|null $locale + * @return PostCode Provides fluid interface + */ + public function setLocale($locale) + { + $this->locale = $locale; + return $this; + } + + /** + * Returns the set postal code format + * + * @return string|null + */ + public function getFormat() + { + return $this->format; + } + + /** + * Sets a self defined postal format as regex + * + * @param string $format + * @return PostCode Provides fluid interface + */ + public function setFormat($format) + { + $this->format = $format; + return $this; + } + + /** + * Returns the actual set service + * + * @return mixed|null + */ + public function getService() + { + return $this->service; + } + + /** + * Sets a new callback for service validation + * + * @param mixed $service + * @return PostCode Provides fluid interface + */ + public function setService($service) + { + $this->service = $service; + return $this; + } + + /** + * Returns true if and only if $value is a valid postalcode + * + * @param string $value + * @return boolean + * @throws Exception\InvalidArgumentException + */ + public function isValid($value) + { + if (!is_string($value) && !is_int($value)) { + $this->error(self::INVALID); + return false; + } + + $this->setValue($value); + + $service = $this->getService(); + $locale = $this->getLocale(); + $format = $this->getFormat(); + if ((null === $format || '' === $format) && !empty($locale)) { + $region = Locale::getRegion($locale); + if ('' === $region) { + throw new Exception\InvalidArgumentException("Invalid locale string given"); + } + if (isset($this->postCodeRegex[$region])) { + $format = $this->postCodeRegex[$region]; + } + } + if (null === $format || '' === $format) { + throw new Exception\InvalidArgumentException("A postcode-format string has to be given for validation"); + } + + if ($format[0] !== '/') { + $format = '/^' . $format; + } + if ($format[strlen($format) - 1] !== '/') { + $format .= '$/'; + } + + if (!empty($service)) { + if (!is_callable($service)) { + throw new Exception\InvalidArgumentException('Invalid callback given'); + } + + try { + $callback = new Callback($service); + $callback->setOptions(array( + 'format' => $format, + 'locale' => $locale, + )); + if (!$callback->isValid($value)) { + $this->error(self::SERVICE, $value); + return false; + } + } catch (\Exception $e) { + $this->error(self::SERVICEFAILURE, $value); + return false; + } + } + + if (!preg_match($format, $value)) { + $this->error(self::NO_MATCH); + return false; + } + + return true; + } +} diff --git a/library/Zend/Validator/PostCode.php b/library/Zend/Validator/PostCode.php deleted file mode 100644 index a0e9887843b..00000000000 --- a/library/Zend/Validator/PostCode.php +++ /dev/null @@ -1,227 +0,0 @@ - "Invalid type given. String or integer expected", - self::NO_MATCH => "The input does not appear to be a postal code", - self::SERVICE => "The input does not appear to be a postal code", - self::SERVICEFAILURE => "An exception has been raised while validating the input.", - ); - - /** - * Options for this validator - * - * @var array - */ - protected $options = array( - 'service'=> null, // Service callback for additional validation - 'format' => null, // Manual postal code format - 'locale' => null, // Locale to use - ); - - /** - * Constructor for the integer validator - * - * Accepts either a string locale, a Zend_Locale object, or an array or - * Zend_Config object containing the keys "locale" and/or "format". - * - * @param string|\Zend\Locale\Locale|array|\Traversable $options - * @throws Exception\InvalidArgumentException On empty format - */ - public function __construct($options = null) - { - if (!empty($options) - && ($options instanceof Locale\Locale || is_string($options)) - ) { - // Received Locale object or string locale - $this->setLocale($options); - } - - parent::__construct($options); - $format = $this->getFormat(); - if (empty($format)) { - throw new Exception\InvalidArgumentException("A postcode-format string has to be given for validation"); - } - } - - /** - * Returns the set locale - * - * @return string|\Zend\Locale\Locale The set locale - */ - public function getLocale() - { - return $this->options['locale']; - } - - /** - * Sets the locale to use - * - * @param string|\Zend\Locale\Locale $locale - * @throws Exception\InvalidArgumentException On unrecognised region or on not detected format - * @return PostCode Provides fluid interface - */ - public function setLocale($locale = null) - { - $this->options['locale'] = Locale\Locale::findLocale($locale); - $locale = new Locale\Locale($this->getLocale()); - $region = $locale->getRegion(); - if (empty($region)) { - throw new Exception\InvalidArgumentException("Unable to detect a region for the locale '$locale'"); - } - - $format = Locale\Locale::getTranslation( - $locale->getRegion(), - 'postaltoterritory', - $this->getLocale() - ); - - if (empty($format)) { - throw new Exception\InvalidArgumentException("Unable to detect a postcode format for the region '{$locale->getRegion()}'"); - } - - $this->setFormat($format); - return $this; - } - - /** - * Returns the set postal code format - * - * @return string - */ - public function getFormat() - { - return $this->options['format']; - } - - /** - * Sets a self defined postal format as regex - * - * @param string $format - * @throws Exception\InvalidArgumentException On empty format - * @return PostCode Provides fluid interface - */ - public function setFormat($format) - { - if (empty($format) || !is_string($format)) { - throw new Exception\InvalidArgumentException("A postcode-format string has to be given for validation"); - } - - if ($format[0] !== '/') { - $format = '/^' . $format; - } - - if ($format[strlen($format) - 1] !== '/') { - $format .= '$/'; - } - - $this->options['format'] = $format; - return $this; - } - - /** - * Returns the actual set service - * - * @return callback - */ - public function getService() - { - return $this->options['service']; - } - - /** - * Sets a new callback for service validation - * - * @param string|array $service - * @return PostCode - * @throws Exception\InvalidArgumentException - */ - public function setService($service) - { - if (!is_callable($service)) { - throw new Exception\InvalidArgumentException('Invalid callback given'); - } - - $this->options['service'] = $service; - return $this; - } - - /** - * Returns true if and only if $value is a valid postalcode - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $this->setValue($value); - if (!is_string($value) && !is_int($value)) { - $this->error(self::INVALID); - return false; - } - - $service = $this->getService(); - if (!empty($service)) { - try { - $callback = new Callback($service); - $callback->setOptions(array( - 'format' => $this->options['format'], - 'locale' => $this->options['locale'], - )); - if (!$callback->isValid($value)) { - $this->error(self::SERVICE, $value); - return false; - } - } catch (\Exception $e) { - $this->error(self::SERVICEFAILURE, $value); - return false; - } - } - - $format = $this->getFormat(); - if (!preg_match($format, $value)) { - $this->error(self::NO_MATCH); - return false; - } - - return true; - } -} diff --git a/library/Zend/Validator/ValidatorPluginManager.php b/library/Zend/Validator/ValidatorPluginManager.php index e3a6c92ff7d..8edde26b276 100644 --- a/library/Zend/Validator/ValidatorPluginManager.php +++ b/library/Zend/Validator/ValidatorPluginManager.php @@ -32,7 +32,7 @@ class ValidatorPluginManager extends AbstractPluginManager { /** * Default set of validators - * + * * @var array */ protected $invokableClasses = array( @@ -99,7 +99,6 @@ class ValidatorPluginManager extends AbstractPluginManager 'greaterthan' => 'Zend\Validator\GreaterThan', 'hex' => 'Zend\Validator\Hex', 'hostname' => 'Zend\Validator\Hostname', - 'iban' => 'Zend\Validator\Iban', 'identical' => 'Zend\Validator\Identical', 'inarray' => 'Zend\Validator\InArray', 'int' => 'Zend\Validator\Int', @@ -107,7 +106,6 @@ class ValidatorPluginManager extends AbstractPluginManager 'isbn' => 'Zend\Validator\Isbn', 'lessthan' => 'Zend\Validator\LessThan', 'notempty' => 'Zend\Validator\NotEmpty', - 'postcode' => 'Zend\Validator\PostCode', 'regex' => 'Zend\Validator\Regex', 'sitemapchangefreq' => 'Zend\Validator\Sitemap\Changefreq', 'sitemaplastmod' => 'Zend\Validator\Sitemap\Lastmod', @@ -121,8 +119,8 @@ class ValidatorPluginManager extends AbstractPluginManager * Validate the plugin * * Checks that the validator loaded is an instance of ValidatorInterface. - * - * @param mixed $plugin + * + * @param mixed $plugin * @return void * @throws Exception\RuntimeException if invalid */ diff --git a/tests/Zend/Validator/IbanTest.php b/tests/Zend/I18n/Validator/IbanTest.php similarity index 68% rename from tests/Zend/Validator/IbanTest.php rename to tests/Zend/I18n/Validator/IbanTest.php index 2fb8f16b363..10eeb15bde9 100644 --- a/tests/Zend/Validator/IbanTest.php +++ b/tests/Zend/I18n/Validator/IbanTest.php @@ -19,9 +19,9 @@ * @license http://framework.zend.com/license/new-bsd New BSD License */ -namespace ZendTest\Validator; +namespace ZendTest\I18n\Validator; -use Zend\Validator\Iban; +use Zend\I18n\Validator\Iban as IbanValidator; /** * @category Zend @@ -33,47 +33,47 @@ */ class IbanTest extends \PHPUnit_Framework_TestCase { + public function ibanDataProvider() + { + return array( + array('AD1200012030200359100100', true), + array('AT611904300234573201', true), + array('AT61 1904 3002 3457 3201', false), + array('AD1200012030200354100100', false), + ); + } /** * Ensures that the validator follows expected behavior * + * @dataProvider ibanDataProvider * @return void */ - public function testBasic() + public function testBasic($iban, $expected) { - $validator = new Iban(); - $valuesExpected = array( - 'AD1200012030200359100100' => true, - 'AT611904300234573201' => true, - 'AT61 1904 3002 3457 3201' => false, - 'AD1200012030200354100100' => false, - ); - foreach ($valuesExpected as $input => $result) { - $this->assertEquals($result, $validator->isValid($input), - "'$input' expected to be " . ($result ? '' : 'in') . 'valid'); - } + $validator = new IbanValidator(); + $this->assertEquals($expected, $validator->isValid($iban)); } public function testSettingAndGettingLocale() { - $validator = new Iban(); + $validator = new IbanValidator(); $validator->setLocale('de_DE'); $this->assertEquals('de_DE', $validator->getLocale()); - $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'IBAN validation'); - $validator->setLocale('de_QA'); - + $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'Invalid locale string given'); + $validator->setLocale('foobar')->isValid('AD1200012030200354100100'); } public function testInstanceWithLocale() { - $validator = new Iban('de_AT'); + $validator = new IbanValidator('de_AT'); $this->assertTrue($validator->isValid('AT611904300234573201')); } public function testIbanNotSupported() { - $validator = new Iban('en_US'); + $validator = new IbanValidator('en_US'); $this->assertFalse($validator->isValid('AT611904300234573201')); } @@ -82,13 +82,13 @@ public function testIbanNotSupported() */ public function testIbanDetectionWithoutLocale() { - $validator = new Iban(false); + $validator = new IbanValidator(false); $this->assertTrue($validator->isValid('AT611904300234573201')); } public function testEqualsMessageTemplates() { - $validator = new Iban(); + $validator = new IbanValidator(); $this->assertAttributeEquals($validator->getOption('messageTemplates'), 'messageTemplates', $validator); } diff --git a/tests/Zend/Validator/PostCodeTest.php b/tests/Zend/I18n/Validator/PostCodeTest.php similarity index 76% rename from tests/Zend/Validator/PostCodeTest.php rename to tests/Zend/I18n/Validator/PostCodeTest.php index 6f7b40c06cf..278cd7cd584 100644 --- a/tests/Zend/Validator/PostCodeTest.php +++ b/tests/Zend/I18n/Validator/PostCodeTest.php @@ -19,9 +19,9 @@ * @license http://framework.zend.com/license/new-bsd New BSD License */ -namespace ZendTest\Validator; +namespace ZendTest\I18n\Validator; -use Zend\Validator\PostCode; +use Zend\I18n\Validator\PostCode as PostCodeValidator; /** * @category Zend @@ -45,34 +45,35 @@ class PostCodeTest extends \PHPUnit_Framework_TestCase */ public function setUp() { - $this->validator = new PostCode('de_AT'); + $this->validator = new PostCodeValidator('de_AT'); + } + + public function postCodesDataProvider() + { + return array( + array('2292', true), + array('1000', true), + array('0000', true), + array('12345', false), + array(1234, true), + array(9821, true), + array('21A4', false), + array('ABCD', false), + array(true, false), + array('AT-2292', false), + array(1.56, false), + ); } /** * Ensures that the validator follows expected behavior * + * @dataProvider postCodesDataProvider * @return void */ - public function testBasic() + public function testBasic($postCode, $expected) { - $valuesExpected = array( - array('2292', true), - array('1000', true), - array('0000', true), - array('12345', false), - array(1234, true), - array(9821, true), - array('21A4', false), - array('ABCD', false), - array(true, false), - array('AT-2292', false), - array(1.56, false) - ); - - foreach ($valuesExpected as $element) { - $this->assertEquals($element[1], $this->validator->isValid($element[0]), - 'Test failed with ' . var_export($element, 1)); - } + $this->assertEquals($expected, $this->validator->isValid($postCode)); } /** @@ -90,8 +91,8 @@ public function testGetMessages() */ public function testSettingLocalesWithoutRegion() { - $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'Unable to detect a region'); - $this->validator->setLocale('de'); + $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'Invalid locale string given'); + $this->validator->setLocale('de')->isValid('1000'); } /** @@ -99,8 +100,8 @@ public function testSettingLocalesWithoutRegion() */ public function testSettingLocalesWithoutPostalCodes() { - $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'Unable to detect a postcode format'); - $this->validator->setLocale('gez_ER'); + $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'A postcode-format string has to be given for validation'); + $this->validator->setLocale('gez_ER')->isValid('1000'); } /** @@ -117,28 +118,19 @@ public function testGettingLocale() public function testSetGetFormat() { $this->validator->setFormat('\d{1}'); - $this->assertEquals('/^\d{1}$/', $this->validator->getFormat()); - - $this->validator->setFormat('/^\d{1}'); - $this->assertEquals('/^\d{1}$/', $this->validator->getFormat()); - - $this->validator->setFormat('/^\d{1}$/'); - $this->assertEquals('/^\d{1}$/', $this->validator->getFormat()); - - $this->validator->setFormat('\d{1}$/'); - $this->assertEquals('/^\d{1}$/', $this->validator->getFormat()); + $this->assertEquals('\d{1}', $this->validator->getFormat()); } public function testSetGetFormatThrowsExceptionOnNullFormat() { $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'A postcode-format string has to be given'); - $this->validator->setFormat(null); + $this->validator->setLocale(null)->setFormat(null)->isValid('1000'); } public function testSetGetFormatThrowsExceptionOnEmptyFormat() { $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'A postcode-format string has to be given'); - $this->validator->setFormat(''); + $this->validator->setLocale(null)->setFormat('')->isValid('1000'); } /** @@ -151,7 +143,6 @@ public function testErrorMessageText() $this->assertContains('not appear to be a postal code', $message['postcodeNoMatch']); } - /** * Test service class with invalid validation * From fcc3d418a705f12afa2b3af4bb857f49f0e6b55a Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Mon, 2 Jul 2012 17:04:41 -0400 Subject: [PATCH 010/332] [i18n] Iban/PostCode validator changes from code review --- library/Zend/I18n/Validator/Iban.php | 16 ++++++---------- library/Zend/I18n/Validator/PostCode.php | 14 +++++--------- tests/Zend/I18n/Validator/IbanTest.php | 8 ++++---- tests/Zend/I18n/Validator/PostCodeTest.php | 4 ++-- 4 files changed, 17 insertions(+), 25 deletions(-) diff --git a/library/Zend/I18n/Validator/Iban.php b/library/Zend/I18n/Validator/Iban.php index b48be40b93c..ee18f9d9fc5 100644 --- a/library/Zend/I18n/Validator/Iban.php +++ b/library/Zend/I18n/Validator/Iban.php @@ -63,7 +63,7 @@ class Iban extends AbstractValidator * * @var array */ - protected $ibanregex = array( + protected static $ibanRegex = array( 'AD' => '/^AD[0-9]{2}[0-9]{8}[A-Z0-9]{12}$/', 'AT' => '/^AT[0-9]{2}[0-9]{5}[0-9]{11}$/', 'BA' => '/^BA[0-9]{2}[0-9]{6}[0-9]{10}$/', @@ -108,16 +108,12 @@ class Iban extends AbstractValidator /** * Sets validator options * - * @param null|string|Locale|array|Traversable $options OPTIONAL + * @param array|Traversable $options OPTIONAL */ - public function __construct($options = null) + public function __construct($options = array()) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); - } elseif (!is_array($options)) { - $options = func_get_args(); - $temp['locale'] = array_shift($options); - $options = $temp; } if (array_key_exists('locale', $options)) { @@ -171,17 +167,17 @@ public function isValid($value) } else { $region = Locale::getRegion($this->locale); if ('' === $region) { - throw new Exception\InvalidArgumentException("Invalid locale string given"); + throw new Exception\InvalidArgumentException("Locale must contain a region"); } } - if (!array_key_exists($region, $this->ibanregex)) { + if (!array_key_exists($region, self::$ibanRegex)) { $this->setValue($region); $this->error(self::NOTSUPPORTED); return false; } - if (!preg_match($this->ibanregex[$region], $value)) { + if (!preg_match(self::$ibanRegex[$region], $value)) { $this->error(self::FALSEFORMAT); return false; } diff --git a/library/Zend/I18n/Validator/PostCode.php b/library/Zend/I18n/Validator/PostCode.php index d5bfc77f807..3f0999d3c4d 100644 --- a/library/Zend/I18n/Validator/PostCode.php +++ b/library/Zend/I18n/Validator/PostCode.php @@ -76,7 +76,7 @@ class PostCode extends AbstractValidator * * @var array */ - protected $postCodeRegex = array( + protected static $postCodeRegex = array( 'GB' => 'GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}', 'JE' => 'JE\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}', 'GG' => 'GY\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}', @@ -242,16 +242,12 @@ class PostCode extends AbstractValidator * * Accepts a string locale and/or "format". * - * @param string|array|Traversable $options + * @param array|Traversable $options */ public function __construct($options = array()) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); - } elseif (!is_array($options)) { - $options = func_get_args(); - $temp['locale'] = array_shift($options); - $options = $temp; } if (array_key_exists('locale', $options)) { @@ -357,10 +353,10 @@ public function isValid($value) if ((null === $format || '' === $format) && !empty($locale)) { $region = Locale::getRegion($locale); if ('' === $region) { - throw new Exception\InvalidArgumentException("Invalid locale string given"); + throw new Exception\InvalidArgumentException("Locale must contain a region"); } - if (isset($this->postCodeRegex[$region])) { - $format = $this->postCodeRegex[$region]; + if (isset(self::$postCodeRegex[$region])) { + $format = self::$postCodeRegex[$region]; } } if (null === $format || '' === $format) { diff --git a/tests/Zend/I18n/Validator/IbanTest.php b/tests/Zend/I18n/Validator/IbanTest.php index 10eeb15bde9..232a36c2337 100644 --- a/tests/Zend/I18n/Validator/IbanTest.php +++ b/tests/Zend/I18n/Validator/IbanTest.php @@ -61,19 +61,19 @@ public function testSettingAndGettingLocale() $validator->setLocale('de_DE'); $this->assertEquals('de_DE', $validator->getLocale()); - $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'Invalid locale string given'); + $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'Locale must contain a region'); $validator->setLocale('foobar')->isValid('AD1200012030200354100100'); } public function testInstanceWithLocale() { - $validator = new IbanValidator('de_AT'); + $validator = new IbanValidator(array('locale' => 'de_AT')); $this->assertTrue($validator->isValid('AT611904300234573201')); } public function testIbanNotSupported() { - $validator = new IbanValidator('en_US'); + $validator = new IbanValidator(array('locale' => 'en_US')); $this->assertFalse($validator->isValid('AT611904300234573201')); } @@ -82,7 +82,7 @@ public function testIbanNotSupported() */ public function testIbanDetectionWithoutLocale() { - $validator = new IbanValidator(false); + $validator = new IbanValidator(); $this->assertTrue($validator->isValid('AT611904300234573201')); } diff --git a/tests/Zend/I18n/Validator/PostCodeTest.php b/tests/Zend/I18n/Validator/PostCodeTest.php index 278cd7cd584..59433efa0b8 100644 --- a/tests/Zend/I18n/Validator/PostCodeTest.php +++ b/tests/Zend/I18n/Validator/PostCodeTest.php @@ -45,7 +45,7 @@ class PostCodeTest extends \PHPUnit_Framework_TestCase */ public function setUp() { - $this->validator = new PostCodeValidator('de_AT'); + $this->validator = new PostCodeValidator(array('locale' => 'de_AT')); } public function postCodesDataProvider() @@ -91,7 +91,7 @@ public function testGetMessages() */ public function testSettingLocalesWithoutRegion() { - $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'Invalid locale string given'); + $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'Locale must contain a region'); $this->validator->setLocale('de')->isValid('1000'); } From 79034540b8f938cfc315edbb20fbf3d67ee7a219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michae=CC=88l=20Gallego?= Date: Mon, 2 Jul 2012 23:24:22 +0200 Subject: [PATCH 011/332] Form refactored to use options instead of attributes where it makes sense --- library/Zend/Form/Element.php | 41 ++++- library/Zend/Form/Element/Collection.php | 38 +++- library/Zend/Form/Element/MultiCheckbox.php | 163 ++++++++++++++++++ library/Zend/Form/Element/Radio.php | 34 ++++ library/Zend/Form/Fieldset.php | 24 +-- .../Form/View/Helper/Captcha/AbstractWord.php | 53 +++--- .../Zend/Form/View/Helper/Captcha/Dumb.php | 8 +- .../Zend/Form/View/Helper/Captcha/Figlet.php | 8 +- .../Zend/Form/View/Helper/Captcha/Image.php | 8 +- .../Form/View/Helper/Captcha/ReCaptcha.php | 31 ++-- library/Zend/Form/View/Helper/FormCaptcha.php | 16 +- .../Zend/Form/View/Helper/FormCollection.php | 32 ++-- library/Zend/Form/View/Helper/FormElement.php | 15 +- library/Zend/Form/View/Helper/FormInput.php | 22 +-- library/Zend/Form/View/Helper/FormLabel.php | 12 +- .../Form/View/Helper/FormMultiCheckbox.php | 49 +++--- library/Zend/Form/View/Helper/FormRow.php | 24 +-- tests/Zend/Form/Element/CaptchaTest.php | 10 +- tests/Zend/Form/TestAsset/AddressFieldset.php | 11 +- tests/Zend/Form/TestAsset/BasicFieldset.php | 7 +- tests/Zend/Form/TestAsset/CityFieldset.php | 22 +-- tests/Zend/Form/TestAsset/CountryFieldset.php | 16 +- tests/Zend/Form/TestAsset/FormCollection.php | 4 +- tests/Zend/Form/TestAsset/NestedFieldset.php | 8 +- .../Form/View/Helper/Captcha/DumbTest.php | 8 +- .../Form/View/Helper/Captcha/FigletTest.php | 8 +- .../Form/View/Helper/Captcha/ImageTest.php | 8 +- .../View/Helper/Captcha/ReCaptchaTest.php | 8 +- .../Zend/Form/View/Helper/FormCaptchaTest.php | 14 +- .../Zend/Form/View/Helper/FormElementTest.php | 9 +- tests/Zend/Form/View/Helper/FormLabelTest.php | 6 +- .../View/Helper/FormMultiCheckboxTest.php | 15 +- tests/Zend/Form/View/Helper/FormRadioTest.php | 14 +- tests/Zend/Form/View/Helper/FormRowTest.php | 12 +- 34 files changed, 492 insertions(+), 266 deletions(-) create mode 100644 library/Zend/Form/Element/MultiCheckbox.php create mode 100644 library/Zend/Form/Element/Radio.php diff --git a/library/Zend/Form/Element.php b/library/Zend/Form/Element.php index 0ff4ec4bba7..460733eeef5 100644 --- a/library/Zend/Form/Element.php +++ b/library/Zend/Form/Element.php @@ -41,6 +41,11 @@ class Element implements ElementInterface */ protected $label; + /** + * @var array + */ + protected $labelAttributes; + /** * @var array Validation error messages */ @@ -74,7 +79,7 @@ public function setName($name) $this->setAttribute('name', $name); return $this; } - + /** * Get value for name * @@ -86,7 +91,9 @@ public function getName() } /** - * Set options for an element + * Set options for an element. Accepted options are: + * - label: label to associate with the element + * - label_attributes: attributes to use when the label is rendered * * @param array|\Traversable $options * @return Element|ElementInterface @@ -106,6 +113,10 @@ public function setOptions($options) $this->setLabel($options['label']); } + if (isset($options['label_attributes'])) { + $this->setRowLabelAttributes($options['label_attributes']); + } + return $this; } @@ -183,7 +194,7 @@ public function getAttributes() /** * Clear all attributes - * + * * @return void */ public function clearAttributes() @@ -216,6 +227,28 @@ public function getLabel() return $this->label; } + /** + * Set the attributes to use with the label + * + * @param array $labelAttributes + * @return Element + */ + public function setLabelAttributes(array $labelAttributes) + { + $this->labelAttributes = $labelAttributes; + return $this; + } + + /** + * Get the attributes to use with the label + * + * @return array + */ + public function getLabelAttributes() + { + return $this->labelAttributes; + } + /** * Set a list of messages to report when validation fails * @@ -241,7 +274,7 @@ public function setMessages($messages) * Get validation error messages, if any. * * Returns a list of validation failure messages, if any. - * + * * @return array|Traversable */ public function getMessages() diff --git a/library/Zend/Form/Element/Collection.php b/library/Zend/Form/Element/Collection.php index 854e87427fd..a3d55fce40f 100644 --- a/library/Zend/Form/Element/Collection.php +++ b/library/Zend/Form/Element/Collection.php @@ -29,6 +29,7 @@ use Zend\Form\FieldsetInterface; use Zend\Form\Form; use Zend\InputFilter\InputFilterProviderInterface; +use Zend\Stdlib\PriorityQueue; /** * @category Zend @@ -152,7 +153,7 @@ public function populateValues($data) // If there are still data, this means that elements or fieldsets were dynamically added. If allowed by the user, add them if (!empty($data) && $this->allowAdd) { foreach ($data as $key => $value) { - $elementOrFieldset = clone $this->targetElement; + $elementOrFieldset = $this->createNewTargetElementInstance(); $elementOrFieldset->setName($key); if ($elementOrFieldset instanceof FieldsetInterface) { @@ -312,7 +313,7 @@ protected function prepareCollection() { if ($this->targetElement !== null) { for ($i = 0 ; $i != $this->count ; ++$i) { - $elementOrFieldset = clone $this->targetElement; + $elementOrFieldset = $this->createNewTargetElementInstance(); $elementOrFieldset->setName($i); $this->add($elementOrFieldset); @@ -333,7 +334,7 @@ protected function prepareCollection() protected function addTemplateElement() { if ($this->targetElement !== null) { - $elementOrFieldset = clone $this->targetElement; + $elementOrFieldset = $this->createNewTargetElementInstance(); $elementOrFieldset->setName($this->templatePlaceholder); $this->add($elementOrFieldset); } @@ -341,6 +342,35 @@ protected function addTemplateElement() return $this; } + /** + * Create a deep clone of a new target element + */ + protected function createNewTargetElementInstance() + { + // If targetElement is a fieldset, make a deep clone of it + if ($this->targetElement instanceof FieldsetInterface) { + /** @var Fieldset $targetElement */ + $targetElement = $this->targetElement; + $targetElement->iterator = new PriorityQueue(); + + foreach ($targetElement->byName as $key => $value) { + $value = clone $value; + $targetElement->byName[$key] = $value; + $targetElement->iterator->insert($value); + + if ($value instanceof FieldsetInterface) { + $targetElement->fieldsets[$key] = $value; + } elseif ($value instanceof ElementInterface) { + $targetElement->elements[$key] = $value; + } + } + + return $targetElement; + } + + return clone $this->targetElement; + } + /** * Should return an array specification compatible with * {@link Zend\InputFilter\Factory::createInputFilter()}. @@ -360,4 +390,4 @@ public function getInputFilterSpecification() return array(); } -} \ No newline at end of file +} diff --git a/library/Zend/Form/Element/MultiCheckbox.php b/library/Zend/Form/Element/MultiCheckbox.php new file mode 100644 index 00000000000..a70d8fc76dc --- /dev/null +++ b/library/Zend/Form/Element/MultiCheckbox.php @@ -0,0 +1,163 @@ +setUseHiddenElement($options['use_hidden_element']); + } + + if (isset($options['unchecked_value'])) { + $this->setUncheckedValue($options['unchecked_value']); + } + + if (isset($options['label_attributes'])) { + $this->setLabelAttributes($options['label_attributes']); + } + + return $this; + } + + /** + * Do we render hidden element? + * + * @param bool $useHiddenElement + * @return MultiCheckbox + */ + public function setUseHiddenElement($useHiddenElement) + { + $this->useHiddenElement = (bool)$useHiddenElement; + return $this; + } + + /** + * Do we render hidden element? + * + * @return bool + */ + public function useHiddenElement() + { + return $this->useHiddenElement; + } + + /** + * Set the value to use when checkbox is unchecked + * + * @param $uncheckedValue + * @return MultiCheckbox + */ + public function setUncheckedValue($uncheckedValue) + { + $this->uncheckedValue = $uncheckedValue; + return $this; + } + + /** + * Get the value to use when checkbox is unchecked + * + * @return string + */ + public function getUncheckedValue() + { + return $this->uncheckedValue; + } + + /** + * Set the label attributes + * + * @param array $labelAttributes + * @return MultiCheckbox + */ + public function setLabelAttributes(array $labelAttributes) + { + $this->labelAttributes = $labelAttributes; + return $this; + } + + /** + * Get the label attributes + * + * @return array + */ + public function getLabelAttributes() + { + return $this->labelAttributes; + } + + /** + * Provide default input rules for this element + * + * Attaches the captcha as a validator. + * + * @return array + */ + public function getInputSpecification() + { + $spec = array( + 'name' => $this->getName(), + 'required' => true + ); + + return $spec; + } +} diff --git a/library/Zend/Form/Element/Radio.php b/library/Zend/Form/Element/Radio.php new file mode 100644 index 00000000000..3b10ccc7bb7 --- /dev/null +++ b/library/Zend/Form/Element/Radio.php @@ -0,0 +1,34 @@ +getName(); - if ((null === $name || '' === $name) + if ((null === $name || '' === $name) && (!array_key_exists('name', $flags) || $flags['name'] === '') ) { throw new Exception\InvalidArgumentException(sprintf( @@ -404,28 +404,6 @@ public function getIterator() return $this->iterator; } - /** - * Make a deep clone of the object - * - * @return void - */ - public function __clone() - { - $this->iterator = new PriorityQueue(); - - foreach ($this->byName as $key => $value) { - $value = clone $value; - $this->byName[$key] = $value; - $this->iterator->insert($value); - - if ($value instanceof FieldsetInterface) { - $this->fieldsets[$key] = $value; - } elseif ($value instanceof ElementInterface) { - $this->elements[$key] = $value; - } - } - } - /** * Set the object used by the hydrator * diff --git a/library/Zend/Form/View/Helper/Captcha/AbstractWord.php b/library/Zend/Form/View/Helper/Captcha/AbstractWord.php index 30ad8dabbdf..e11d4481c88 100644 --- a/library/Zend/Form/View/Helper/Captcha/AbstractWord.php +++ b/library/Zend/Form/View/Helper/Captcha/AbstractWord.php @@ -39,8 +39,19 @@ abstract class AbstractWord extends FormInput const CAPTCHA_APPEND = 'append'; const CAPTCHA_PREPEND = 'prepend'; + /** + * @var FormInput + */ protected $inputHelper; + + /** + * @var string + */ protected $captchaPosition = self::CAPTCHA_APPEND; + + /** + * @var string + */ protected $separator = ''; /** @@ -64,7 +75,7 @@ public function setCaptchaPosition($captchaPosition) $this->captchaPosition = $captchaPosition; return $this; } - + /** * Get position of captcha * @@ -86,7 +97,7 @@ public function setSeparator($separator) $this->separator = (string) $separator; return $this; } - + /** * Get separator for captcha and inputs * @@ -105,14 +116,14 @@ public function getSeparator() * - Text input for entering captcha value (name[input]) * * More specific renderers will consume this and render it. - * - * @param ElementInterface $element + * + * @param ElementInterface $element * @return string */ protected function renderCaptchaInputs(ElementInterface $element) { $name = $element->getName(); - if (empty($name)) { + if ($name === '') { throw new Exception\DomainException(sprintf( '%s requires that the element has an assigned name; none discovered', __METHOD__ @@ -120,19 +131,15 @@ protected function renderCaptchaInputs(ElementInterface $element) } $attributes = $element->getAttributes(); + $captcha = $element->getCaptcha(); - if (!isset($attributes['captcha']) - || !$attributes['captcha'] instanceof CaptchaAdapter - ) { + if ($captcha === null || !$captcha instanceof CaptchaAdapter) { throw new Exception\DomainException(sprintf( '%s requires that the element has a "captcha" attribute implementing Zend\Captcha\AdapterInterface; none found', __METHOD__ )); } - $captcha = $attributes['captcha']; - unset($attributes['captcha']); - $hidden = $this->renderCaptchaHidden($captcha, $attributes); $input = $this->renderCaptchaInput($captcha, $attributes); $separator = $this->getSeparator(); @@ -144,8 +151,8 @@ protected function renderCaptchaInputs(ElementInterface $element) * Invoke helper as functor * * Proxies to {@link render()}. - * - * @param ElementInterface $element + * + * @param ElementInterface $element * @return string */ public function __invoke(ElementInterface $element = null) @@ -159,9 +166,9 @@ public function __invoke(ElementInterface $element = null) /** * Render the hidden input with the captcha identifier - * - * @param CaptchaAdapter $captcha - * @param array $attributes + * + * @param CaptchaAdapter $captcha + * @param array $attributes * @return string */ protected function renderCaptchaHidden(CaptchaAdapter $captcha, array $attributes) @@ -177,8 +184,8 @@ protected function renderCaptchaHidden(CaptchaAdapter $captcha, array $attribute } $closingBracket = $this->getInlineClosingBracket(); $hidden = sprintf( - 'createAttributesString($attributes), + 'createAttributesString($attributes), $closingBracket ); return $hidden; @@ -186,9 +193,9 @@ protected function renderCaptchaHidden(CaptchaAdapter $captcha, array $attribute /** * Render the input for capturing the captcha value from the client - * - * @param CaptchaAdapter $captcha - * @param array $attributes + * + * @param CaptchaAdapter $captcha + * @param array $attributes * @return string */ protected function renderCaptchaInput(CaptchaAdapter $captcha, array $attributes) @@ -200,8 +207,8 @@ protected function renderCaptchaInput(CaptchaAdapter $captcha, array $attributes } $closingBracket = $this->getInlineClosingBracket(); $input = sprintf( - 'createAttributesString($attributes), + 'createAttributesString($attributes), $closingBracket ); return $input; diff --git a/library/Zend/Form/View/Helper/Captcha/Dumb.php b/library/Zend/Form/View/Helper/Captcha/Dumb.php index 4998659ee4f..3a7aac29660 100644 --- a/library/Zend/Form/View/Helper/Captcha/Dumb.php +++ b/library/Zend/Form/View/Helper/Captcha/Dumb.php @@ -42,17 +42,15 @@ class Dumb extends AbstractWord */ public function render(ElementInterface $element) { - $attributes = $element->getAttributes(); + $captcha = $element->getCaptcha(); - if (!isset($attributes['captcha']) - || !$attributes['captcha'] instanceof CaptchaAdapter - ) { + if ($captcha === null || !$captcha instanceof CaptchaAdapter) { throw new Exception\DomainException(sprintf( '%s requires that the element has a "captcha" attribute of type Zend\Captcha\Dumb; none found', __METHOD__ )); } - $captcha = $attributes['captcha']; + $captcha->generate(); $label = sprintf( diff --git a/library/Zend/Form/View/Helper/Captcha/Figlet.php b/library/Zend/Form/View/Helper/Captcha/Figlet.php index de9bf92b781..0547cb327ec 100644 --- a/library/Zend/Form/View/Helper/Captcha/Figlet.php +++ b/library/Zend/Form/View/Helper/Captcha/Figlet.php @@ -42,17 +42,15 @@ class Figlet extends AbstractWord */ public function render(ElementInterface $element) { - $attributes = $element->getAttributes(); + $captcha = $element->getCaptcha(); - if (!isset($attributes['captcha']) - || !$attributes['captcha'] instanceof CaptchaAdapter - ) { + if ($captcha === null || !$captcha instanceof CaptchaAdapter) { throw new Exception\DomainException(sprintf( '%s requires that the element has a "captcha" attribute of type Zend\Captcha\Figlet; none found', __METHOD__ )); } - $captcha = $attributes['captcha']; + $captcha->generate(); $figlet = sprintf( diff --git a/library/Zend/Form/View/Helper/Captcha/Image.php b/library/Zend/Form/View/Helper/Captcha/Image.php index ddab9559925..3a4f576ffe2 100644 --- a/library/Zend/Form/View/Helper/Captcha/Image.php +++ b/library/Zend/Form/View/Helper/Captcha/Image.php @@ -42,17 +42,15 @@ class Image extends AbstractWord */ public function render(ElementInterface $element) { - $attributes = $element->getAttributes(); + $captcha = $element->getCaptcha(); - if (!isset($attributes['captcha']) - || !$attributes['captcha'] instanceof CaptchaAdapter - ) { + if ($captcha === null || !$captcha instanceof CaptchaAdapter) { throw new Exception\DomainException(sprintf( '%s requires that the element has a "captcha" attribute of type Zend\Captcha\Image; none found', __METHOD__ )); } - $captcha = $attributes['captcha']; + $captcha->generate(); $imgAttributes = array( diff --git a/library/Zend/Form/View/Helper/Captcha/ReCaptcha.php b/library/Zend/Form/View/Helper/Captcha/ReCaptcha.php index 0387250e233..e912b079452 100644 --- a/library/Zend/Form/View/Helper/Captcha/ReCaptcha.php +++ b/library/Zend/Form/View/Helper/Captcha/ReCaptcha.php @@ -39,24 +39,21 @@ class ReCaptcha extends FormInput /** * Render ReCaptcha form elements * - * @param ElementInterface $element + * @param ElementInterface $element * @return string */ public function render(ElementInterface $element) { $attributes = $element->getAttributes(); - if (!isset($attributes['captcha']) - || !$attributes['captcha'] instanceof CaptchaAdapter - ) { + $captcha = $element->getCaptcha(); + + if ($captcha === null || !$captcha instanceof CaptchaAdapter) { throw new Exception\DomainException(sprintf( '%s requires that the element has a "captcha" attribute implementing Zend\Captcha\AdapterInterface; none found', __METHOD__ )); } - $captcha = $attributes['captcha']; - unset($attributes['captcha']); - $name = $element->getName(); $id = isset($attributes['id']) ? $attributes['id'] : $name; $challengeName = empty($name) ? 'recaptcha_challenge_field' : $name . '[recaptcha_challenge_field]'; @@ -75,8 +72,8 @@ public function render(ElementInterface $element) * Invoke helper as functor * * Proxies to {@link render()}. - * - * @param ElementInterface $element + * + * @param ElementInterface $element * @return string */ public function __invoke(ElementInterface $element = null) @@ -90,11 +87,11 @@ public function __invoke(ElementInterface $element = null) /** * Render hidden input elements for the challenge and response - * - * @param string $challengeName - * @param string $challengeId - * @param string $responseName - * @param string $responseId + * + * @param string $challengeName + * @param string $challengeId + * @param string $responseName + * @param string $responseId * @return string */ protected function renderHiddenInput($challengeName, $challengeId, $responseName, $responseId) @@ -119,9 +116,9 @@ protected function renderHiddenInput($challengeName, $challengeId, $responseName /** * Create the JS events used to bind the challenge and response values to the submitted form. - * - * @param string $challengeId - * @param string $responseId + * + * @param string $challengeId + * @param string $responseId * @return string */ protected function renderJsEvents($challengeId, $responseId) diff --git a/library/Zend/Form/View/Helper/FormCaptcha.php b/library/Zend/Form/View/Helper/FormCaptcha.php index d70161e92c4..39adaa577f6 100644 --- a/library/Zend/Form/View/Helper/FormCaptcha.php +++ b/library/Zend/Form/View/Helper/FormCaptcha.php @@ -37,24 +37,22 @@ class FormCaptcha extends AbstractHelper { /** * Render a form captcha for an element - * - * @param ElementInterface $element + * + * @param ElementInterface $element * @return string * @throws Exception\DomainException if the element does not compose a captcha, or the renderer does not implement plugin() */ public function render(ElementInterface $element) { - $attributes = $element->getAttributes(); - if (!isset($attributes['captcha']) - || !$attributes['captcha'] instanceof CaptchaAdapter - ) { + $captcha = $element->getCaptcha(); + + if ($captcha === null || !$captcha instanceof CaptchaAdapter) { throw new Exception\DomainException(sprintf( '%s requires that the element has a "captcha" attribute implementing Zend\Captcha\AdapterInterface; none found', __METHOD__ )); } - $captcha = $attributes['captcha']; $helper = $captcha->getHelperName(); $renderer = $this->getView(); @@ -73,8 +71,8 @@ public function render(ElementInterface $element) * Invoke helper as functor * * Proxies to {@link render()}. - * - * @param ElementInterface $element + * + * @param ElementInterface $element * @return string|FormCaptcha */ public function __invoke(ElementInterface $element) diff --git a/library/Zend/Form/View/Helper/FormCollection.php b/library/Zend/Form/View/Helper/FormCollection.php index 2244b5ee7b9..3778c26807c 100644 --- a/library/Zend/Form/View/Helper/FormCollection.php +++ b/library/Zend/Form/View/Helper/FormCollection.php @@ -23,6 +23,7 @@ use Zend\Form\Element; use Zend\Form\ElementInterface; +use Zend\Form\Element\Collection as CollectionElement; use Zend\Form\FieldsetInterface; /** @@ -63,22 +64,23 @@ public function render(ElementInterface $element) $markup = ''; $templateMarkup = ''; - $attributes = $element->getAttributes(); $escapeHelper = $this->getEscapeHelper(); $rowHelper = $this->getRowHelper(); - if (isset($attributes['shouldCreateTemplate']) && $attributes['shouldCreateTemplate'] === true) { - $templatePlaceholder = $attributes['templatePlaceholder']; - $elementOrFieldset = $element->get($templatePlaceholder); + if ($element instanceof CollectionElement) { + if ($element->shouldCreateTemplate()) { + $templatePlaceholder = $element->getTemplatePlaceholder(); + $elementOrFieldset = $element->get($templatePlaceholder); - if ($elementOrFieldset instanceof FieldsetInterface) { - $templateMarkup .= $this->render($elementOrFieldset); - } elseif ($elementOrFieldset instanceof ElementInterface) { - $templateMarkup .= $rowHelper($elementOrFieldset); - } + if ($elementOrFieldset instanceof FieldsetInterface) { + $templateMarkup .= $this->render($elementOrFieldset); + } elseif ($elementOrFieldset instanceof ElementInterface) { + $templateMarkup .= $rowHelper($elementOrFieldset); + } - // Remove it as we don't want to draw it multiple times - $element->remove($templatePlaceholder); + // Remove it as we don't want to draw it multiple times + $element->remove($templatePlaceholder); + } } foreach($element->getIterator() as $elementOrFieldset) { @@ -99,8 +101,10 @@ public function render(ElementInterface $element) // Every collection is wrapped by a fieldset if needed if ($this->shouldWrap) { - if (isset($attributes['label'])) { - $label = $escapeHelper($attributes['label']); + $label = $element->getLabel(); + + if ($label !== '') { + $label = $escapeHelper($label); $markup = sprintf( '
%s%s
', @@ -176,4 +180,4 @@ protected function getRowHelper() return $this->rowHelper; } -} \ No newline at end of file +} diff --git a/library/Zend/Form/View/Helper/FormElement.php b/library/Zend/Form/View/Helper/FormElement.php index 1fb87865763..1b59023a1cd 100644 --- a/library/Zend/Form/View/Helper/FormElement.php +++ b/library/Zend/Form/View/Helper/FormElement.php @@ -39,8 +39,8 @@ class FormElement extends BaseAbstractHelper * * Introspects the element type and attributes to determine which * helper to utilize when rendering. - * - * @param ElementInterface $element + * + * @param ElementInterface $element * @return string */ public function render(ElementInterface $element) @@ -68,12 +68,6 @@ public function render(ElementInterface $element) $type = $element->getAttribute('type'); $options = $element->getAttribute('options'); - $captcha = $element->getAttribute('captcha'); - - if (!empty($captcha)) { - $helper = $renderer->plugin('form_captcha'); - return $helper($element); - } if (is_array($options) && $type == 'radio') { $helper = $renderer->plugin('form_radio'); @@ -100,7 +94,6 @@ public function render(ElementInterface $element) return $helper($element); } - $helper = $renderer->plugin('form_input'); return $helper($element); } @@ -109,8 +102,8 @@ public function render(ElementInterface $element) * Invoke helper as function * * Proxies to {@link render()}. - * - * @param ElementInterface|null $element + * + * @param ElementInterface|null $element * @return string|FormElement */ public function __invoke(ElementInterface $element = null) diff --git a/library/Zend/Form/View/Helper/FormInput.php b/library/Zend/Form/View/Helper/FormInput.php index baf75eab33f..71857c98e45 100644 --- a/library/Zend/Form/View/Helper/FormInput.php +++ b/library/Zend/Form/View/Helper/FormInput.php @@ -73,7 +73,7 @@ class FormInput extends AbstractHelper /** * Valid values for the input type - * + * * @var array */ protected $validTypes = array( @@ -105,14 +105,14 @@ class FormInput extends AbstractHelper /** * Render a form element from the provided $element - * - * @param ElementInterface $element + * + * @param ElementInterface $element * @return string */ public function render(ElementInterface $element) { - $name = $element->getName(); - if (strlen($name) === 0) { + $name = $element->getName(); + if ($name === null || $name === '') { throw new Exception\DomainException(sprintf( '%s requires that the element has an assigned name; none discovered', __METHOD__ @@ -124,8 +124,8 @@ public function render(ElementInterface $element) $attributes['type'] = $this->getType($element); return sprintf( - 'createAttributesString($attributes), + 'createAttributesString($attributes), $this->getInlineClosingBracket() ); } @@ -134,8 +134,8 @@ public function render(ElementInterface $element) * Invoke helper as functor * * Proxies to {@link render()}. - * - * @param ElementInterface|null $element + * + * @param ElementInterface|null $element * @return string|FormInput */ public function __invoke(ElementInterface $element = null) @@ -149,8 +149,8 @@ public function __invoke(ElementInterface $element = null) /** * Determine input type to use - * - * @param ElementInterface $element + * + * @param ElementInterface $element * @return string */ protected function getType(ElementInterface $element) diff --git a/library/Zend/Form/View/Helper/FormLabel.php b/library/Zend/Form/View/Helper/FormLabel.php index d0308a040d0..8a80bbe11a7 100644 --- a/library/Zend/Form/View/Helper/FormLabel.php +++ b/library/Zend/Form/View/Helper/FormLabel.php @@ -79,7 +79,13 @@ public function openTag($attributesOrElement = null) )); } + $labelAttributes = $attributesOrElement->getLabelAttributes(); $attributes = array('for' => $id); + + if (!empty($labelAttributes)) { + $attributes = array_merge($labelAttributes, $attributes); + } + $attributes = $this->createAttributesString($attributes); return sprintf('', $markup); $this->assertContains('for="foo"', $markup); diff --git a/tests/Zend/Form/View/Helper/FormMultiCheckboxTest.php b/tests/Zend/Form/View/Helper/FormMultiCheckboxTest.php index 1067d72dea9..2d633d0a628 100644 --- a/tests/Zend/Form/View/Helper/FormMultiCheckboxTest.php +++ b/tests/Zend/Form/View/Helper/FormMultiCheckboxTest.php @@ -21,7 +21,7 @@ namespace ZendTest\Form\View\Helper; -use Zend\Form\Element; +use Zend\Form\Element\MultiCheckbox as MultiCheckboxElement; use Zend\Form\View\Helper\FormMultiCheckbox as FormMultiCheckboxHelper; /** @@ -41,7 +41,7 @@ public function setUp() public function getElement() { - $element = new Element('foo'); + $element = new MultiCheckboxElement('foo'); $options = array( 'This is the first label' => 'value1', 'This is the second label' => 'value2', @@ -53,14 +53,14 @@ public function getElement() public function getElementWithOptionSpec() { - $element = new Element('foo'); + $element = new MultiCheckboxElement('foo'); $options = array( 'This is the first label' => 'value1', 'This is the second label' => array( 'value' => 'value2', 'label' => 'This is the second label (overridden)', 'disabled' => false, - 'labelAttributes' => array('class' => 'label-class'), + 'label_attributes' => array('class' => 'label-class'), 'attributes' => array('class' => 'input-class'), ), 'This is the third label' => 'value3', @@ -119,8 +119,8 @@ public function testUsesOptionsAttributeWithOptionSpecToGenerateCheckBoxes() public function testGenerateCheckBoxesAndHiddenElement() { $element = $this->getElement(); - $element->setAttribute('useHiddenElement', true); - $element->setAttribute('uncheckedValue', 'none'); + $element->setUseHiddenElement(true); + $element->setUncheckedValue('none'); $options = $element->getAttribute('options'); $markup = $this->helper->render($element); @@ -187,8 +187,7 @@ public function testAllowsSpecifyingLabelAttributes() public function testAllowsSpecifyingLabelAttributesInElementAttributes() { $element = $this->getElement(); - $element->setAttribute('labelAttributes', array('class' => 'checkbox')); - + $element->setLabelAttributes(array('class' => 'checkbox')); $markup = $this->helper->render($element); $this->assertEquals(3, substr_count($markup, '