diff --git a/QuickForm2/Container.php b/QuickForm2/Container.php index f7d48280..ef5fa1c9 100644 --- a/QuickForm2/Container.php +++ b/QuickForm2/Container.php @@ -419,6 +419,37 @@ protected function validate() } return $valid; } + + /** + * Appends an element to the container, creating it first + * + * The element will be created via {@link HTML_QuickForm2_Factory::createElement()} + * and then added via the {@link appendChild()} method. + * The element type is deduced from the method name. Camelcases will be + * converted to underscores and lowercased. + * This is a convenience method to reduce typing. + * + * @param mixed Element name + * @param array Element-specific data + * @param mixed Element attributes + * @return HTML_QuickForm2_Node Added element + * @throws HTML_QuickForm2_InvalidArgumentException + * @throws HTML_QuickForm2_NotFoundException + */ + public function __call($m, $a) + { + if (preg_match('/^(add)([A-Z0-9][a-zA-Z0-9]+)$/', $m, $match)) { + if ($match[1] == 'add') { + $type = strtolower(preg_replace('/([a-z])([A-Z])/','\1_\2', + preg_replace('/([A-Z]+)([A-Z])/','\1_\2', $match[2]))); + $name = isset($a[0]) ? $a[0] : null; + $data = isset($a[1]) ? $a[1] : array(); + $attr = isset($a[2]) ? $a[2] : null; + return $this->addElement($type, $name, $data, $attr); + } + } + trigger_error("Fatal error: Call to undefined method ".get_class($this)."::".$m."()", E_USER_ERROR); + } } /** diff --git a/tests/QuickForm2/AllTests.php b/tests/QuickForm2/AllTests.php index 4cda8fe7..bc98e694 100644 --- a/tests/QuickForm2/AllTests.php +++ b/tests/QuickForm2/AllTests.php @@ -56,6 +56,7 @@ require_once dirname(__FILE__) . '/ElementTest.php'; require_once dirname(__FILE__) . '/Element/AllTests.php'; require_once dirname(__FILE__) . '/ContainerTest.php'; +require_once dirname(__FILE__) . '/ContainerOverloadTest.php'; require_once dirname(__FILE__) . '/Container/AllTests.php'; require_once dirname(__FILE__) . '/DataSource/AllTests.php'; require_once dirname(__FILE__) . '/RuleTest.php'; @@ -75,6 +76,7 @@ public static function suite() $suite->addTestSuite('HTML_QuickForm2_NodeTest'); $suite->addTestSuite('HTML_QuickForm2_ElementTest'); $suite->addTestSuite('HTML_QuickForm2_ContainerTest'); + $suite->addTestSuite('HTML_QuickForm2_ContainerOverloadTest'); $suite->addTestSuite('HTML_QuickForm2_RuleTest'); $suite->addTest(QuickForm2_Element_AllTests::suite()); $suite->addTest(QuickForm2_Container_AllTests::suite()); diff --git a/tests/QuickForm2/ContainerOverloadTest.php b/tests/QuickForm2/ContainerOverloadTest.php new file mode 100644 index 00000000..63dd26cc --- /dev/null +++ b/tests/QuickForm2/ContainerOverloadTest.php @@ -0,0 +1,106 @@ +, + * Bertrand Mansion + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The names of the authors may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @category HTML + * @package HTML_QuickForm2 + * @author Alexey Borzov + * @author Bertrand Mansion + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id$ + * @link http://pear.php.net/package/HTML_QuickForm2 + */ + +/** + * Container class + */ +require_once 'HTML/QuickForm2/Container.php'; + +/** + * Base class for "scalar" elements + */ +require_once 'HTML/QuickForm2/Element.php'; + +/** + * Base class for "checkbox" elements, used in tests + */ +require_once 'HTML/QuickForm2/Element/InputCheckbox.php'; + +/** + * PHPUnit2 Test Case + */ +require_once 'PHPUnit/Framework/TestCase.php'; + + +/** + * Unit test for HTML_QuickForm2_Container overloaded methods + */ +class HTML_QuickForm2_ContainerOverloadTest extends PHPUnit_Framework_TestCase +{ + public function testAddElements() + { + $c = new HTML_QuickForm2_ContainerImpl('cCOT1'); + $el1 = $c->addText('eCOT1', array('label' => 'Label'), array('size' => 30)); + $this->assertSame($el1, $c->getElementById('eCOT1-0')); + + $f = $c->addFieldset('fCOT1', array('label' => 'Fieldset')); + $el2 = $f->addTextarea('eCOT2'); + $this->assertSame($el2, $c->getElementById('eCOT2-0')); + } + + + public function testAddElementsWithBracketsInName() + { + $c = new HTML_QuickForm2_ContainerImpl('cCOT0'); + $el1 = $c->addCheckbox('chCOT[]'); + $el2 = $c->addCheckbox('chCOT[]'); + $this->assertSame($el1, $c->getElementById('chCOT-0-0')); + $this->assertSame($el2, $c->getElementById('chCOT-1-0')); + } + + + public function testAddUnknownType() + { + $c = new HTML_QuickForm2_ContainerImpl('cCOT2'); + try { + $c->addUnknown('uCOT1'); + } catch (HTML_QuickForm2_InvalidArgumentException $e) { + $this->assertEquals("Element type 'unknown' is not known", $e->getMessage()); + return; + } + $this->fail('Expected HTML_QuickForm2_InvalidArgumentException was not thrown'); + } +} +?> \ No newline at end of file